isodoc 1.2.4 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +69 -0
- data/README.adoc +1 -3
- data/isodoc.gemspec +3 -1
- data/lib/isodoc-yaml/i18n-en.yaml +1 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +8 -7
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
- data/lib/isodoc/base_style/all.css +5 -1
- data/lib/isodoc/base_style/blocks.scss +2 -2
- data/lib/isodoc/base_style/reset.css +5 -1
- data/lib/isodoc/base_style/reset.scss +6 -1
- data/lib/isodoc/base_style/typography.scss +1 -1
- data/lib/isodoc/convert.rb +12 -97
- data/lib/isodoc/css.rb +95 -0
- data/lib/isodoc/function/inline.rb +0 -33
- data/lib/isodoc/function/lists.rb +2 -1
- data/lib/isodoc/function/references.rb +8 -13
- data/lib/isodoc/function/to_word_html.rb +2 -2
- data/lib/isodoc/html_function/postprocess.rb +12 -3
- data/lib/isodoc/i18n.rb +23 -51
- data/lib/isodoc/metadata.rb +44 -111
- data/lib/isodoc/metadata_contributor.rb +90 -0
- data/lib/isodoc/metadata_date.rb +11 -0
- data/lib/isodoc/presentation_function/bibdata.rb +96 -0
- data/lib/isodoc/presentation_function/block.rb +14 -9
- data/lib/isodoc/presentation_function/inline.rb +151 -34
- data/lib/isodoc/presentation_xml_convert.rb +6 -0
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_convert.rb +0 -20
- data/lib/isodoc/word_function/body.rb +12 -0
- data/lib/isodoc/word_function/postprocess.rb +1 -1
- data/lib/isodoc/xref/xref_anchor.rb +8 -3
- data/lib/isodoc/xref/xref_counter.rb +20 -9
- data/lib/isodoc/xref/xref_gen.rb +4 -4
- data/lib/isodoc/xref/xref_sect_gen.rb +1 -1
- data/lib/isodoc/xslfo_convert.rb +6 -1
- data/spec/assets/html.scss +14 -0
- data/spec/assets/i18n.yaml +22 -5
- data/spec/isodoc/blocks_spec.rb +100 -221
- data/spec/isodoc/footnotes_spec.rb +4 -5
- data/spec/isodoc/i18n_spec.rb +89 -16
- data/spec/isodoc/inline_spec.rb +185 -163
- data/spec/isodoc/lists_spec.rb +1 -1
- data/spec/isodoc/metadata_spec.rb +69 -19
- data/spec/isodoc/postproc_spec.rb +33 -8
- data/spec/isodoc/presentation_xml_spec.rb +584 -1
- data/spec/isodoc/ref_spec.rb +328 -10
- data/spec/isodoc/section_spec.rb +9 -9
- data/spec/isodoc/table_spec.rb +1 -1
- data/spec/isodoc/terms_spec.rb +1 -1
- data/spec/isodoc/xref_spec.rb +35 -35
- data/spec/spec_helper.rb +6 -0
- metadata +36 -7
- data/.github/workflows/macos.yml +0 -42
- data/.github/workflows/ubuntu.yml +0 -62
- data/.github/workflows/windows.yml +0 -44
@@ -0,0 +1,90 @@
|
|
1
|
+
module IsoDoc
|
2
|
+
class Metadata
|
3
|
+
def extract_person_names(authors)
|
4
|
+
authors.reduce([]) do |ret, a|
|
5
|
+
if a.at(ns('./name/completename'))
|
6
|
+
ret << a.at(ns('./name/completename')).text
|
7
|
+
else
|
8
|
+
fn = []
|
9
|
+
forenames = a.xpath(ns('./name/forename'))
|
10
|
+
forenames.each { |f| fn << f.text }
|
11
|
+
surname = a&.at(ns('./name/surname'))&.text
|
12
|
+
ret << fn.join(' ') + ' ' + surname
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def extract_person_affiliations(authors)
|
18
|
+
authors.reduce([]) do |m, a|
|
19
|
+
name = a&.at(ns('./affiliation/organization/name'))&.text
|
20
|
+
location = a&.at(ns('./affiliation/organization/address/'\
|
21
|
+
'formattedAddress'))&.text
|
22
|
+
m << (!name.nil? && !location.nil? ? "#{name}, #{location}" :
|
23
|
+
(name || location || ''))
|
24
|
+
m
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def extract_person_names_affiliations(authors)
|
29
|
+
names = extract_person_names(authors)
|
30
|
+
affils = extract_person_affiliations(authors)
|
31
|
+
ret = {}
|
32
|
+
affils.each_with_index do |a, i|
|
33
|
+
ret[a] ||= []
|
34
|
+
ret[a] << names[i]
|
35
|
+
end
|
36
|
+
ret
|
37
|
+
end
|
38
|
+
|
39
|
+
def personal_authors(isoxml)
|
40
|
+
authors = isoxml.xpath(ns("//bibdata/contributor[role/@type = 'author' "\
|
41
|
+
"or xmlns:role/@type = 'editor']/person"))
|
42
|
+
set(:authors, extract_person_names(authors))
|
43
|
+
set(:authors_affiliations, extract_person_names_affiliations(authors))
|
44
|
+
end
|
45
|
+
|
46
|
+
def author(xml, _out)
|
47
|
+
personal_authors(xml)
|
48
|
+
agency(xml)
|
49
|
+
end
|
50
|
+
|
51
|
+
def iso?(org)
|
52
|
+
name = org&.at(ns('./name'))&.text
|
53
|
+
abbrev = org&.at(ns('./abbreviation'))&.text
|
54
|
+
(abbrev == 'ISO' ||
|
55
|
+
name == 'International Organization for Standardization')
|
56
|
+
end
|
57
|
+
|
58
|
+
def agency1(xml)
|
59
|
+
agency = ''
|
60
|
+
publisher = []
|
61
|
+
xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
|
62
|
+
'organization')).each do |org|
|
63
|
+
name = org&.at(ns('./name'))&.text
|
64
|
+
agency1 = org&.at(ns('./abbreviation'))&.text || name
|
65
|
+
publisher << name if name
|
66
|
+
agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
|
67
|
+
end
|
68
|
+
[agency, publisher]
|
69
|
+
end
|
70
|
+
|
71
|
+
def agency(xml)
|
72
|
+
agency, publisher = agency1(xml)
|
73
|
+
set(:agency, agency.sub(%r{/$}, ''))
|
74
|
+
set(:publisher, @i18n.multiple_and(publisher, @labels['and']))
|
75
|
+
agency_addr(xml)
|
76
|
+
end
|
77
|
+
|
78
|
+
def agency_addr(xml)
|
79
|
+
a = xml.at(ns("//bibdata/contributor[xmlns:role/@type = 'publisher'][1]/"\
|
80
|
+
"organization")) or return
|
81
|
+
n = a.at(ns("./subdivision")) and set(:subdivision, n.text)
|
82
|
+
n = a.at(ns("./address/formattedAddress")) and
|
83
|
+
set(:pub_address, n.children.to_xml)
|
84
|
+
n = a.at(ns("./phone[not(@type = 'fax')]")) and set(:pub_phone, n.text)
|
85
|
+
n = a.at(ns("./phone[@type = 'fax']")) and set(:pub_fax, n.text)
|
86
|
+
n = a.at(ns("./email")) and set(:pub_email, n.text)
|
87
|
+
n = a.at(ns("./uri")) and set(:pub_uri, n.text)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/isodoc/metadata_date.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module IsoDoc
|
2
2
|
class Metadata
|
3
|
+
DATETYPES = %w{published accessed created implemented obsoleted confirmed
|
4
|
+
updated issued received transmitted copied unchanged
|
5
|
+
circulated vote-started
|
6
|
+
vote-ended}.freeze
|
7
|
+
|
3
8
|
def months
|
4
9
|
{
|
5
10
|
"01": @labels["month_january"],
|
@@ -35,5 +40,11 @@ module IsoDoc
|
|
35
40
|
Date.parse(isodate).strftime("%B %d, %Y")
|
36
41
|
end
|
37
42
|
end
|
43
|
+
|
44
|
+
def bibdate(isoxml, _out)
|
45
|
+
isoxml.xpath(ns('//bibdata/date')).each do |d|
|
46
|
+
set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
|
47
|
+
end
|
48
|
+
end
|
38
49
|
end
|
39
50
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module IsoDoc
|
2
|
+
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
|
+
def bibdata(docxml)
|
4
|
+
a = bibdata_current(docxml) or return
|
5
|
+
bibdata_i18n(a)
|
6
|
+
a.next =
|
7
|
+
"<localized-strings>#{i8n_name(trim_hash(@i18n.get), "").join("")}"\
|
8
|
+
"</localized-strings>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def bibdata_current(docxml)
|
12
|
+
a = docxml.at(ns("//bibdata")) or return
|
13
|
+
a.xpath(ns("./language")).each do |l|
|
14
|
+
l.text == @lang and l["current"] = "true"
|
15
|
+
end
|
16
|
+
a.xpath(ns("./script")).each do |l|
|
17
|
+
l.text == @script and l["current"] = "true"
|
18
|
+
end
|
19
|
+
a
|
20
|
+
end
|
21
|
+
|
22
|
+
def bibdata_i18n(b)
|
23
|
+
hash_translate(b, @i18n.get["doctype_dict"], "./ext/doctype")
|
24
|
+
hash_translate(b, @i18n.get["stage_dict"], "./status/stage")
|
25
|
+
hash_translate(b, @i18n.get["substage_dict"], "./status/substage")
|
26
|
+
end
|
27
|
+
|
28
|
+
def hash_translate(bibdata, hash, xpath, lang = @lang)
|
29
|
+
x = bibdata.at(ns(xpath)) or return
|
30
|
+
x["language"] = ""
|
31
|
+
hash.is_a? Hash or return
|
32
|
+
hash[x.text] or return
|
33
|
+
x.next = x.dup
|
34
|
+
x.next["language"] = lang
|
35
|
+
x.next.children = hash[x.text]
|
36
|
+
end
|
37
|
+
|
38
|
+
def i18n_tag(k, v)
|
39
|
+
"<localized-string key='#{k}' language='#{@lang}'>#{v}</localized-string>"
|
40
|
+
end
|
41
|
+
|
42
|
+
def i18n_safe(k)
|
43
|
+
k.to_s.gsub(/\s|\./, "_")
|
44
|
+
end
|
45
|
+
|
46
|
+
def i8n_name(h, pref)
|
47
|
+
if h.is_a? Hash then i8n_name1(h, pref)
|
48
|
+
elsif h.is_a? Array
|
49
|
+
h.reject { |a| blank?(a) }.each_with_object([]).
|
50
|
+
with_index do |(v1, g), i|
|
51
|
+
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
52
|
+
end
|
53
|
+
else [i18n_tag(pref, h)]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def i8n_name1(h, pref)
|
58
|
+
h.reject { |k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
|
59
|
+
if v.is_a? Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
|
60
|
+
elsif v.is_a? Array
|
61
|
+
v.reject { |a| blank?(a) }.each_with_index do |v1, i|
|
62
|
+
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
63
|
+
end
|
64
|
+
else
|
65
|
+
g << i18n_tag("#{pref}#{pref.empty? ? "" : "."}#{i18n_safe(k)}", v)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#https://stackoverflow.com/a/31822406
|
71
|
+
def blank?(v)
|
72
|
+
v.nil? || v.respond_to?(:empty?) && v.empty?
|
73
|
+
end
|
74
|
+
|
75
|
+
def trim_hash(h)
|
76
|
+
loop do
|
77
|
+
h_new = trim_hash1(h)
|
78
|
+
break h if h==h_new
|
79
|
+
h = h_new
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def trim_hash1(h)
|
84
|
+
return h unless h.is_a? Hash
|
85
|
+
h.each_with_object({}) do |(k,v), g|
|
86
|
+
next if blank?(v)
|
87
|
+
g[k] = if v.is_a? Hash then trim_hash1(h[k])
|
88
|
+
elsif v.is_a? Array
|
89
|
+
h[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
|
90
|
+
else
|
91
|
+
v
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module IsoDoc
|
2
2
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
|
+
def lower2cap(s)
|
4
|
+
return s if /^[[:upper:]][[:upper:]]/.match(s)
|
5
|
+
s.capitalize
|
6
|
+
end
|
7
|
+
|
3
8
|
def figure(docxml)
|
4
9
|
docxml.xpath(ns("//figure")).each do |f|
|
5
10
|
figure1(f)
|
@@ -12,7 +17,7 @@ module IsoDoc
|
|
12
17
|
return if labelled_ancestor(f) && f.ancestors("figure").empty?
|
13
18
|
return if f.at(ns("./figure")) and !f.at(ns("./name"))
|
14
19
|
lbl = @xrefs.anchor(f['id'], :label, false) or return
|
15
|
-
prefix_name(f, " — ", l10n("#{@i18n.figure} #{lbl}"), "name")
|
20
|
+
prefix_name(f, " — ", l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
|
16
21
|
end
|
17
22
|
|
18
23
|
def prefix_name(f, delim, number, elem)
|
@@ -36,7 +41,7 @@ module IsoDoc
|
|
36
41
|
return if labelled_ancestor(f)
|
37
42
|
return unless f.ancestors("example").empty?
|
38
43
|
lbl = @xrefs.anchor(f['id'], :label, false) or return
|
39
|
-
prefix_name(f, " — ", l10n("#{@i18n.figure} #{lbl}"), "name")
|
44
|
+
prefix_name(f, " — ", l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
|
40
45
|
end
|
41
46
|
|
42
47
|
def formula(docxml)
|
@@ -65,7 +70,7 @@ module IsoDoc
|
|
65
70
|
|
66
71
|
def example1(f)
|
67
72
|
n = @xrefs.get[f["id"]]
|
68
|
-
lbl = (n.nil? || n[:label].nil? || n[:label].empty?) ? @i18n.example
|
73
|
+
lbl = (n.nil? || n[:label].nil? || n[:label].empty?) ? @i18n.example:
|
69
74
|
l10n("#{@i18n.example} #{n[:label]}")
|
70
75
|
prefix_name(f, " — ", lbl, "name")
|
71
76
|
end
|
@@ -81,7 +86,7 @@ module IsoDoc
|
|
81
86
|
return if f.parent.name == "bibitem"
|
82
87
|
n = @xrefs.get[f["id"]]
|
83
88
|
lbl = (@i18n.note if n.nil? || n[:label].nil? || n[:label].empty?) ?
|
84
|
-
@i18n.note
|
89
|
+
@i18n.note: l10n("#{@i18n.note} #{n[:label]}")
|
85
90
|
prefix_name(f, "", lbl, "name")
|
86
91
|
end
|
87
92
|
|
@@ -94,24 +99,24 @@ module IsoDoc
|
|
94
99
|
# introduce name element
|
95
100
|
def termnote1(f)
|
96
101
|
lbl = l10n(@xrefs.anchor(f['id'], :label) || '???')
|
97
|
-
prefix_name(f, "", lbl, "name")
|
102
|
+
prefix_name(f, "", lower2cap(lbl), "name")
|
98
103
|
end
|
99
104
|
|
100
105
|
def recommendation(docxml)
|
101
106
|
docxml.xpath(ns("//recommendation")).each do |f|
|
102
|
-
recommendation1(f, @i18n.recommendation)
|
107
|
+
recommendation1(f, lower2cap(@i18n.recommendation))
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
106
111
|
def requirement(docxml)
|
107
112
|
docxml.xpath(ns("//requirement")).each do |f|
|
108
|
-
recommendation1(f, @i18n.requirement)
|
113
|
+
recommendation1(f, lower2cap(@i18n.requirement))
|
109
114
|
end
|
110
115
|
end
|
111
116
|
|
112
117
|
def permission(docxml)
|
113
118
|
docxml.xpath(ns("//permission")).each do |f|
|
114
|
-
recommendation1(f, @i18n.permission)
|
119
|
+
recommendation1(f, lower2cap(@i18n.permission))
|
115
120
|
end
|
116
121
|
end
|
117
122
|
|
@@ -132,7 +137,7 @@ module IsoDoc
|
|
132
137
|
return if labelled_ancestor(f)
|
133
138
|
return if f["unnumbered"] && !f.at(ns("./name"))
|
134
139
|
n = @xrefs.anchor(f['id'], :label, false)
|
135
|
-
prefix_name(f, " — ", l10n("#{@i18n.table} #{n}"), "name")
|
140
|
+
prefix_name(f, " — ", l10n("#{lower2cap @i18n.table} #{n}"), "name")
|
136
141
|
end
|
137
142
|
|
138
143
|
# we use this to eliminate the semantic amend blocks from rendering
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "twitter_cldr"
|
2
|
+
|
1
3
|
module IsoDoc
|
2
4
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
5
|
def prefix_container(container, linkend, _target)
|
@@ -7,17 +9,25 @@ module IsoDoc
|
|
7
9
|
def anchor_linkend(node, linkend)
|
8
10
|
if node["citeas"].nil? && node["bibitemid"]
|
9
11
|
return @xrefs.anchor(node["bibitemid"] ,:xref) || "???"
|
12
|
+
elsif node["target"] && node["droploc"]
|
13
|
+
return @xrefs.anchor(node["target"], :value) ||
|
14
|
+
@xrefs.anchor(node["target"], :label) ||
|
15
|
+
@xrefs.anchor(node["target"], :xref) || "???"
|
10
16
|
elsif node["target"] && !/.#./.match(node["target"])
|
11
|
-
linkend =
|
12
|
-
container = @xrefs.anchor(node["target"], :container, false)
|
13
|
-
(container && get_note_container_id(node) != container &&
|
14
|
-
@xrefs.get[node["target"]]) &&
|
15
|
-
linkend = prefix_container(container, linkend, node["target"])
|
16
|
-
linkend = capitalise_xref(node, linkend)
|
17
|
+
linkend = anchor_linkend1(node)
|
17
18
|
end
|
18
19
|
linkend || "???"
|
19
20
|
end
|
20
21
|
|
22
|
+
def anchor_linkend1(node)
|
23
|
+
linkend = @xrefs.anchor(node["target"], :xref)
|
24
|
+
container = @xrefs.anchor(node["target"], :container, false)
|
25
|
+
(container && get_note_container_id(node) != container &&
|
26
|
+
@xrefs.get[node["target"]]) &&
|
27
|
+
linkend = prefix_container(container, linkend, node["target"])
|
28
|
+
capitalise_xref(node, linkend)
|
29
|
+
end
|
30
|
+
|
21
31
|
def capitalise_xref(node, linkend)
|
22
32
|
return linkend unless %w(Latn Cyrl Grek).include? @script
|
23
33
|
return linkend&.capitalize if node["case"] == "capital"
|
@@ -30,7 +40,7 @@ module IsoDoc
|
|
30
40
|
end
|
31
41
|
|
32
42
|
def nearest_block_parent(node)
|
33
|
-
until %w(p title td th name formula
|
43
|
+
until %w(p title td th name formula
|
34
44
|
li dt dd sourcecode pre).include?(node.name)
|
35
45
|
node = node.parent
|
36
46
|
end
|
@@ -43,13 +53,13 @@ module IsoDoc
|
|
43
53
|
end
|
44
54
|
end
|
45
55
|
|
46
|
-
def get_linkend(
|
47
|
-
contents = non_locality_elems(
|
56
|
+
def get_linkend(n)
|
57
|
+
contents = non_locality_elems(n).select { |c| !c.text? || /\S/.match(c) }
|
48
58
|
return unless contents.empty?
|
49
|
-
link = anchor_linkend(
|
50
|
-
link += eref_localities(
|
51
|
-
non_locality_elems(
|
52
|
-
|
59
|
+
link = anchor_linkend(n, docid_l10n(n["target"] || n["citeas"]))
|
60
|
+
link += eref_localities(n.xpath(ns("./locality | ./localityStack")), link)
|
61
|
+
non_locality_elems(n).each { |n| n.remove }
|
62
|
+
n.add_child(link)
|
53
63
|
end
|
54
64
|
# so not <origin bibitemid="ISO7301" citeas="ISO 7301">
|
55
65
|
# <locality type="section"><reference>3.1</reference></locality></origin>
|
@@ -59,14 +69,19 @@ module IsoDoc
|
|
59
69
|
refs.each_with_index do |r, i|
|
60
70
|
delim = ","
|
61
71
|
delim = ";" if r.name == "localityStack" && i>0
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
72
|
+
ret = eref_locality_stack(r, i, target, delim, ret)
|
73
|
+
end
|
74
|
+
ret
|
75
|
+
end
|
76
|
+
|
77
|
+
def eref_locality_stack(r, i, target, delim, ret)
|
78
|
+
if r.name == "localityStack"
|
79
|
+
r.elements.each_with_index do |rr, j|
|
80
|
+
ret += eref_localities0(rr, j, target, delim)
|
81
|
+
delim = ","
|
69
82
|
end
|
83
|
+
else
|
84
|
+
ret += eref_localities0(r, i, target, delim)
|
70
85
|
end
|
71
86
|
ret
|
72
87
|
end
|
@@ -79,7 +94,7 @@ module IsoDoc
|
|
79
94
|
end
|
80
95
|
end
|
81
96
|
|
82
|
-
|
97
|
+
# TODO: move to localization file
|
83
98
|
def eref_localities1_zh(target, type, from, to, delim)
|
84
99
|
ret = "#{delim} 第#{from.text}" if from
|
85
100
|
ret += "–#{to.text}" if to
|
@@ -91,7 +106,8 @@ module IsoDoc
|
|
91
106
|
# TODO: move to localization file
|
92
107
|
def eref_localities1(target, type, from, to, delim, lang = "en")
|
93
108
|
return "" if type == "anchor"
|
94
|
-
|
109
|
+
lang == "zh" and
|
110
|
+
return l10n(eref_localities1_zh(target, type, from, to, delim))
|
95
111
|
ret = delim
|
96
112
|
loc = @i18n.locality[type] || type.sub(/^locality:/, "").capitalize
|
97
113
|
ret += " #{loc}"
|
@@ -101,31 +117,132 @@ module IsoDoc
|
|
101
117
|
end
|
102
118
|
|
103
119
|
def xref(docxml)
|
104
|
-
docxml.xpath(ns("//xref")).each
|
105
|
-
xref1(f)
|
106
|
-
end
|
120
|
+
docxml.xpath(ns("//xref")).each { |f| xref1(f) }
|
107
121
|
end
|
108
122
|
|
109
123
|
def eref(docxml)
|
110
|
-
docxml.xpath(ns("//eref")).each
|
111
|
-
xref1(f)
|
112
|
-
end
|
124
|
+
docxml.xpath(ns("//eref")).each { |f| xref1(f) }
|
113
125
|
end
|
114
126
|
|
115
127
|
def origin(docxml)
|
116
|
-
docxml.xpath(ns("//origin[not(termref)]")).each
|
117
|
-
xref1(f)
|
118
|
-
end
|
128
|
+
docxml.xpath(ns("//origin[not(termref)]")).each { |f| xref1(f) }
|
119
129
|
end
|
120
130
|
|
121
131
|
def quotesource(docxml)
|
122
|
-
docxml.xpath(ns("//quote/source")).each
|
123
|
-
xref1(f)
|
124
|
-
end
|
132
|
+
docxml.xpath(ns("//quote/source")).each { |f| xref1(f) }
|
125
133
|
end
|
126
134
|
|
127
135
|
def xref1(f)
|
128
136
|
get_linkend(f)
|
129
137
|
end
|
138
|
+
|
139
|
+
def concept(docxml)
|
140
|
+
docxml.xpath(ns("//concept")).each { |f| concept1(f) }
|
141
|
+
end
|
142
|
+
|
143
|
+
def concept1(node)
|
144
|
+
content = node.first_element_child.children.select do |c|
|
145
|
+
!%w{locality localityStack}.include? c.name
|
146
|
+
end.select { |c| !c.text? || /\S/.match(c) }
|
147
|
+
node.replace content.empty? ?
|
148
|
+
@i18n.term_defined_in.sub(/%/, node.first_element_child.to_xml) :
|
149
|
+
"<em>#{node.children.to_xml}</em>"
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
|
154
|
+
|
155
|
+
def mathml(docxml)
|
156
|
+
locale = twitter_cldr_localiser()
|
157
|
+
docxml.xpath("//m:math", MATHML).each do |f|
|
158
|
+
mathml1(f, locale)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# symbols is merged into
|
163
|
+
# TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
|
164
|
+
def localize_maths(f, locale)
|
165
|
+
f.xpath(".//m:mn", MATHML).each do |x|
|
166
|
+
num = /\./.match(x.text) ? x.text.to_f : x.text.to_i
|
167
|
+
precision = /\./.match(x.text) ? x.text.sub(/^.*\./, "").size : 0
|
168
|
+
x.children = localized_number(num, locale, precision)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# By itself twiiter cldr does not support fraction part digits grouping
|
173
|
+
# and custom delimeter, will decorate fraction part manually
|
174
|
+
def localized_number(num, locale, precision)
|
175
|
+
localized = precision == 0 ? num.localize(locale).to_s :
|
176
|
+
num.localize(locale).to_decimal.to_s(:precision => precision)
|
177
|
+
twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
|
178
|
+
return localized unless twitter_cldr_reader_symbols[:decimal]
|
179
|
+
integer, fraction = localized.split(twitter_cldr_reader_symbols[:decimal])
|
180
|
+
return localized if fraction.nil? || fraction.length.zero?
|
181
|
+
[integer, decorate_fraction_part(fraction, locale)].
|
182
|
+
join(twitter_cldr_reader_symbols[:decimal])
|
183
|
+
end
|
184
|
+
|
185
|
+
def decorate_fraction_part(fract, locale)
|
186
|
+
result = []
|
187
|
+
twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
|
188
|
+
fract = fract.slice(0..(twitter_cldr_reader_symbols[:precision] || -1))
|
189
|
+
fr_group_digits = twitter_cldr_reader_symbols[:fraction_group_digits] || 1
|
190
|
+
until fract.empty?
|
191
|
+
result.push(fract.slice!(0, fr_group_digits))
|
192
|
+
end
|
193
|
+
result.join(twitter_cldr_reader_symbols[:fraction_group].to_s)
|
194
|
+
end
|
195
|
+
|
196
|
+
def twitter_cldr_localiser_symbols
|
197
|
+
{}
|
198
|
+
end
|
199
|
+
|
200
|
+
def twitter_cldr_reader(locale)
|
201
|
+
num = TwitterCldr::DataReaders::NumberDataReader.new(locale)
|
202
|
+
num.symbols.merge!(twitter_cldr_localiser_symbols)
|
203
|
+
end
|
204
|
+
|
205
|
+
def twitter_cldr_localiser()
|
206
|
+
locale = TwitterCldr.supported_locale?(@lang.to_sym) ? @lang.to_sym : :en
|
207
|
+
twitter_cldr_reader(locale)
|
208
|
+
locale
|
209
|
+
end
|
210
|
+
|
211
|
+
def mathml1(f, locale)
|
212
|
+
localize_maths(f, locale)
|
213
|
+
return unless f.elements.size == 1 && f.elements.first.name == "mn"
|
214
|
+
f.replace(f.at("./m:mn", MATHML).children)
|
215
|
+
end
|
216
|
+
|
217
|
+
def variant(docxml)
|
218
|
+
docxml.xpath(ns("//variant")).each { |f| variant1(f) }
|
219
|
+
docxml.xpath(ns("//variant[@remove = 'true']")).each { |f| f.remove }
|
220
|
+
docxml.xpath(ns("//variant")).each do |v|
|
221
|
+
next unless v&.next&.name == "variant"
|
222
|
+
v.next = "/"
|
223
|
+
end
|
224
|
+
docxml.xpath(ns("//variant")).each { |f| f.replace(f.children) }
|
225
|
+
end
|
226
|
+
|
227
|
+
def variant1(node)
|
228
|
+
if (!node["lang"] || node["lang"] == @lang) &&
|
229
|
+
(!node["script"] || node["script"] == @script)
|
230
|
+
elsif found_matching_variant_sibling(node)
|
231
|
+
node["remove"] = "true"
|
232
|
+
else
|
233
|
+
#return unless !node.at("./preceding-sibling::xmlns:variant")
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def found_matching_variant_sibling(node)
|
238
|
+
prev = node.xpath("./preceding-sibling::xmlns:variant")
|
239
|
+
foll = node.xpath("./following-sibling::xmlns:variant")
|
240
|
+
found = false
|
241
|
+
(prev + foll).each do |n|
|
242
|
+
found = true if n["lang"] == @lang &&
|
243
|
+
(!n["script"] || n["script"] == @script)
|
244
|
+
end
|
245
|
+
found
|
246
|
+
end
|
130
247
|
end
|
131
248
|
end
|