isodoc 1.6.0 → 1.6.5
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 +2 -12
- data/.hound.yml +3 -1
- data/.rubocop.yml +4 -8
- data/Rakefile +2 -2
- data/bin/rspec +1 -2
- data/isodoc.gemspec +4 -3
- data/lib/isodoc-yaml/i18n-ar.yaml +152 -0
- data/lib/isodoc-yaml/i18n-de.yaml +149 -0
- data/lib/isodoc-yaml/i18n-en.yaml +1 -0
- data/lib/isodoc-yaml/i18n-es.yaml +151 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +1 -0
- data/lib/isodoc-yaml/i18n-ru.yaml +154 -0
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
- data/lib/isodoc.rb +0 -2
- data/lib/isodoc/common.rb +2 -0
- data/lib/isodoc/convert.rb +10 -4
- data/lib/isodoc/css.rb +30 -26
- data/lib/isodoc/function/blocks.rb +26 -8
- data/lib/isodoc/function/blocks_example_note.rb +2 -2
- data/lib/isodoc/function/cleanup.rb +53 -45
- data/lib/isodoc/function/form.rb +51 -0
- data/lib/isodoc/function/inline.rb +8 -7
- data/lib/isodoc/function/references.rb +71 -77
- data/lib/isodoc/function/section.rb +28 -16
- data/lib/isodoc/function/table.rb +22 -22
- data/lib/isodoc/function/terms.rb +6 -7
- data/lib/isodoc/function/to_word_html.rb +19 -25
- data/lib/isodoc/function/utils.rb +180 -160
- data/lib/isodoc/gem_tasks.rb +36 -38
- data/lib/isodoc/headlesshtml_convert.rb +8 -7
- data/lib/isodoc/html_convert.rb +10 -4
- data/lib/isodoc/html_function/comments.rb +14 -12
- data/lib/isodoc/html_function/footnotes.rb +14 -7
- data/lib/isodoc/html_function/form.rb +62 -0
- data/lib/isodoc/html_function/html.rb +30 -26
- data/lib/isodoc/html_function/postprocess.rb +191 -226
- data/lib/isodoc/html_function/postprocess_footnotes.rb +59 -0
- data/lib/isodoc/html_function/sectionsplit.rb +230 -0
- data/lib/isodoc/i18n.rb +33 -31
- data/lib/isodoc/metadata.rb +22 -20
- data/lib/isodoc/metadata_contributor.rb +31 -28
- data/lib/isodoc/pdf_convert.rb +11 -13
- data/lib/isodoc/presentation_function/bibdata.rb +54 -30
- data/lib/isodoc/presentation_function/block.rb +17 -8
- data/lib/isodoc/presentation_function/inline.rb +72 -120
- data/lib/isodoc/presentation_function/math.rb +84 -0
- data/lib/isodoc/presentation_function/section.rb +55 -19
- data/lib/isodoc/presentation_xml_convert.rb +2 -0
- data/lib/isodoc/sassc_importer.rb +1 -1
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/body.rb +28 -24
- data/lib/isodoc/word_function/footnotes.rb +22 -15
- data/lib/isodoc/word_function/postprocess.rb +50 -36
- data/lib/isodoc/xref.rb +11 -10
- data/lib/isodoc/xref/xref_counter.rb +32 -17
- data/lib/isodoc/xref/xref_gen.rb +33 -21
- data/lib/isodoc/xref/xref_gen_seq.rb +60 -35
- data/lib/isodoc/xref/xref_sect_gen.rb +37 -35
- data/spec/assets/scripts_override.html +3 -0
- data/spec/isodoc/blocks_spec.rb +2258 -2622
- data/spec/isodoc/cleanup_spec.rb +1103 -1107
- data/spec/isodoc/form_spec.rb +156 -0
- data/spec/isodoc/i18n_spec.rb +802 -917
- data/spec/isodoc/inline_spec.rb +1105 -921
- data/spec/isodoc/lists_spec.rb +316 -315
- data/spec/isodoc/metadata_spec.rb +384 -379
- data/spec/isodoc/postproc_spec.rb +1783 -1549
- data/spec/isodoc/presentation_xml_spec.rb +355 -278
- data/spec/isodoc/ref_spec.rb +718 -723
- data/spec/isodoc/section_spec.rb +216 -199
- data/spec/isodoc/sectionsplit_spec.rb +190 -0
- data/spec/isodoc/table_spec.rb +41 -42
- data/spec/isodoc/terms_spec.rb +84 -84
- data/spec/isodoc/xref_spec.rb +1024 -930
- metadata +33 -7
@@ -2,26 +2,29 @@ module IsoDoc
|
|
2
2
|
class Metadata
|
3
3
|
def extract_person_names(authors)
|
4
4
|
authors.reduce([]) do |ret, a|
|
5
|
-
if a.at(ns(
|
6
|
-
ret << a.at(ns(
|
5
|
+
if a.at(ns("./name/completename"))
|
6
|
+
ret << a.at(ns("./name/completename")).text
|
7
7
|
else
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ret << fn.join(' ') + ' ' + surname
|
8
|
+
forenames = a.xpath(ns("./name/forename"))
|
9
|
+
fn = forenames.each_with_object([]) { |f, m| m << f.text }
|
10
|
+
surname = a&.at(ns("./name/surname"))&.text
|
11
|
+
ret << "#{fn.join(' ')} #{surname}"
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
def extract_person_affiliations(authors)
|
18
17
|
authors.reduce([]) do |m, a|
|
19
|
-
name = a&.at(ns(
|
20
|
-
subdivs = a&.xpath(ns(
|
21
|
-
name and subdivs and !subdivs.empty? and
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
name = a&.at(ns("./affiliation/organization/name"))&.text
|
19
|
+
subdivs = a&.xpath(ns("./affiliation/organization/subdivision"))&.map(&:text)&.join(", ")
|
20
|
+
name and subdivs and !subdivs.empty? and
|
21
|
+
name = l10n("#{name}, #{subdivs}", @lang, @script)
|
22
|
+
location = a&.at(ns("./affiliation/organization/address/formattedAddress"))&.text
|
23
|
+
m << (if !name.nil? && !location.nil?
|
24
|
+
l10n("#{name}, #{location}", @lang, @script)
|
25
|
+
else
|
26
|
+
(name || location || "")
|
27
|
+
end)
|
25
28
|
m
|
26
29
|
end
|
27
30
|
end
|
@@ -50,19 +53,19 @@ module IsoDoc
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def iso?(org)
|
53
|
-
name = org&.at(ns(
|
54
|
-
abbrev = org&.at(ns(
|
55
|
-
(abbrev ==
|
56
|
-
name ==
|
56
|
+
name = org&.at(ns("./name"))&.text
|
57
|
+
abbrev = org&.at(ns("./abbreviation"))&.text
|
58
|
+
(abbrev == "ISO" ||
|
59
|
+
name == "International Organization for Standardization")
|
57
60
|
end
|
58
61
|
|
59
62
|
def agency1(xml)
|
60
|
-
agency =
|
63
|
+
agency = ""
|
61
64
|
publisher = []
|
62
65
|
xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
|
63
|
-
|
64
|
-
name = org&.at(ns(
|
65
|
-
agency1 = org&.at(ns(
|
66
|
+
"organization")).each do |org|
|
67
|
+
name = org&.at(ns("./name"))&.text
|
68
|
+
agency1 = org&.at(ns("./abbreviation"))&.text || name
|
66
69
|
publisher << name if name
|
67
70
|
agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
|
68
71
|
end
|
@@ -71,21 +74,21 @@ module IsoDoc
|
|
71
74
|
|
72
75
|
def agency(xml)
|
73
76
|
agency, publisher = agency1(xml)
|
74
|
-
set(:agency, agency.sub(%r{/$},
|
75
|
-
set(:publisher, @i18n.multiple_and(publisher, @labels[
|
77
|
+
set(:agency, agency.sub(%r{/$}, ""))
|
78
|
+
set(:publisher, @i18n.multiple_and(publisher, @labels["and"]))
|
76
79
|
agency_addr(xml)
|
77
80
|
end
|
78
81
|
|
79
82
|
def agency_addr(xml)
|
80
83
|
a = xml.at(ns("//bibdata/contributor[xmlns:role/@type = 'publisher'][1]/"\
|
81
84
|
"organization")) or return
|
82
|
-
|
85
|
+
{ subdivision: "./subdivision", pub_phone: "./phone[not(@type = 'fax')]",
|
86
|
+
pub_fax: "./phone[@type = 'fax']", pub_email: "./email",
|
87
|
+
pub_uri: "./uri" }.each do |k, v|
|
88
|
+
n = a.at(ns(v)) and set(k, n.text)
|
89
|
+
end
|
83
90
|
n = a.at(ns("./address/formattedAddress")) and
|
84
91
|
set(:pub_address, n.children.to_xml)
|
85
|
-
n = a.at(ns("./phone[not(@type = 'fax')]")) and set(:pub_phone, n.text)
|
86
|
-
n = a.at(ns("./phone[@type = 'fax']")) and set(:pub_fax, n.text)
|
87
|
-
n = a.at(ns("./email")) and set(:pub_email, n.text)
|
88
|
-
n = a.at(ns("./uri")) and set(:pub_uri, n.text)
|
89
92
|
end
|
90
93
|
end
|
91
94
|
end
|
data/lib/isodoc/pdf_convert.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
require_relative "html_function/comments
|
2
|
-
require_relative "html_function/footnotes
|
3
|
-
require_relative "html_function/html
|
1
|
+
require_relative "html_function/comments"
|
2
|
+
require_relative "html_function/footnotes"
|
3
|
+
require_relative "html_function/html"
|
4
4
|
require "metanorma"
|
5
5
|
|
6
6
|
module IsoDoc
|
7
7
|
class PdfConvert < ::IsoDoc::Convert
|
8
|
-
|
9
8
|
include HtmlFunction::Comments
|
10
9
|
include HtmlFunction::Footnotes
|
11
10
|
include HtmlFunction::Html
|
@@ -13,6 +12,8 @@ module IsoDoc
|
|
13
12
|
def initialize(options)
|
14
13
|
@standardstylesheet = nil
|
15
14
|
super
|
15
|
+
@format = :pdf
|
16
|
+
@suffix = "pdf"
|
16
17
|
@scripts = @scripts_pdf if @scripts_pdf
|
17
18
|
@maxwidth = 500
|
18
19
|
@maxheight = 800
|
@@ -22,22 +23,19 @@ module IsoDoc
|
|
22
23
|
"_pdfimages"
|
23
24
|
end
|
24
25
|
|
25
|
-
def initialize(options)
|
26
|
-
@format = :pdf
|
27
|
-
@suffix = "pdf"
|
28
|
-
super
|
29
|
-
end
|
30
|
-
|
31
26
|
def convert(input_filename, file = nil, debug = false, output_filename = nil)
|
32
27
|
file = File.read(input_filename, encoding: "utf-8") if file.nil?
|
33
28
|
@openmathdelim, @closemathdelim = extract_delims(file)
|
34
29
|
docxml, filename, dir = convert_init(file, input_filename, debug)
|
35
30
|
result = convert1(docxml, filename, dir)
|
36
31
|
return result if debug
|
37
|
-
|
32
|
+
|
33
|
+
postprocess(result, "#{filename}.tmp.html", dir)
|
38
34
|
FileUtils.rm_rf dir
|
39
|
-
::Metanorma::Output::Pdf.new.convert(
|
40
|
-
|
35
|
+
::Metanorma::Output::Pdf.new.convert(
|
36
|
+
"#{filename}.tmp.html",
|
37
|
+
output_filename || "#{filename}.#{@suffix}",
|
38
|
+
)
|
41
39
|
FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
|
42
40
|
end
|
43
41
|
|
@@ -2,12 +2,32 @@ module IsoDoc
|
|
2
2
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
3
|
def bibdata(docxml)
|
4
4
|
a = bibdata_current(docxml) or return
|
5
|
+
address_precompose(a)
|
5
6
|
bibdata_i18n(a)
|
6
7
|
a.next =
|
7
|
-
"<localized-strings>#{i8n_name(trim_hash(@i18n.get),
|
8
|
+
"<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join('')}"\
|
8
9
|
"</localized-strings>"
|
9
10
|
end
|
10
11
|
|
12
|
+
def address_precompose(bib)
|
13
|
+
bib.xpath(ns("//bibdata//address")).each do |b|
|
14
|
+
next if b.at(ns("./formattedAddress"))
|
15
|
+
|
16
|
+
x = address_precompose1(b)
|
17
|
+
b.children = "<formattedAddress>#{x}</formattedAddress>"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def address_precompose1(addr)
|
22
|
+
ret = []
|
23
|
+
addr.xpath(ns("./street")).each { |s| ret << s.children.to_xml }
|
24
|
+
a = addr.at(ns("./city")) and ret << a.children.to_xml
|
25
|
+
addr.xpath(ns("./state")).each { |s| ret << s.children.to_xml }
|
26
|
+
a = addr.at(ns("./country")) and ret << a.children.to_xml
|
27
|
+
a = addr.at(ns("./postcode")) and ret[-1] += " #{a.children.to_xml}"
|
28
|
+
ret.join("<br/>")
|
29
|
+
end
|
30
|
+
|
11
31
|
def bibdata_current(docxml)
|
12
32
|
a = docxml.at(ns("//bibdata")) or return
|
13
33
|
a.xpath(ns("./language")).each do |l|
|
@@ -19,10 +39,10 @@ module IsoDoc
|
|
19
39
|
a
|
20
40
|
end
|
21
41
|
|
22
|
-
def bibdata_i18n(
|
23
|
-
hash_translate(
|
24
|
-
hash_translate(
|
25
|
-
hash_translate(
|
42
|
+
def bibdata_i18n(bib)
|
43
|
+
hash_translate(bib, @i18n.get["doctype_dict"], "./ext/doctype")
|
44
|
+
hash_translate(bib, @i18n.get["stage_dict"], "./status/stage")
|
45
|
+
hash_translate(bib, @i18n.get["substage_dict"], "./status/substage")
|
26
46
|
end
|
27
47
|
|
28
48
|
def hash_translate(bibdata, hash, xpath, lang = @lang)
|
@@ -35,58 +55,62 @@ module IsoDoc
|
|
35
55
|
x.next.children = hash[x.text]
|
36
56
|
end
|
37
57
|
|
38
|
-
def i18n_tag(
|
39
|
-
"<localized-string key='#{
|
58
|
+
def i18n_tag(key, value)
|
59
|
+
"<localized-string key='#{key}' language='#{@lang}'>#{value}"\
|
60
|
+
"</localized-string>"
|
40
61
|
end
|
41
62
|
|
42
|
-
def i18n_safe(
|
43
|
-
|
63
|
+
def i18n_safe(key)
|
64
|
+
key.to_s.gsub(/\s|\./, "_")
|
44
65
|
end
|
45
66
|
|
46
|
-
def i8n_name(
|
47
|
-
if
|
48
|
-
elsif
|
49
|
-
|
50
|
-
with_index do |(v1, g), i|
|
67
|
+
def i8n_name(hash, pref)
|
68
|
+
if hash.is_a? Hash then i8n_name1(hash, pref)
|
69
|
+
elsif hash.is_a? Array
|
70
|
+
hash.reject { |a| blank?(a) }.each_with_object([])
|
71
|
+
.with_index do |(v1, g), i|
|
51
72
|
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
52
73
|
end
|
53
|
-
else [i18n_tag(pref,
|
74
|
+
else [i18n_tag(pref, hash)]
|
54
75
|
end
|
55
76
|
end
|
56
77
|
|
57
|
-
def i8n_name1(
|
58
|
-
|
78
|
+
def i8n_name1(hash, pref)
|
79
|
+
hash.reject { |_k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
|
59
80
|
if v.is_a? Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
|
60
81
|
elsif v.is_a? Array
|
61
82
|
v.reject { |a| blank?(a) }.each_with_index do |v1, i|
|
62
83
|
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
63
84
|
end
|
64
85
|
else
|
65
|
-
g << i18n_tag("#{pref}#{pref.empty? ?
|
86
|
+
g << i18n_tag("#{pref}#{pref.empty? ? '' : '.'}#{i18n_safe(k)}", v)
|
66
87
|
end
|
67
88
|
end
|
68
89
|
end
|
69
90
|
|
70
|
-
#https://stackoverflow.com/a/31822406
|
71
|
-
def blank?(
|
72
|
-
|
91
|
+
# https://stackoverflow.com/a/31822406
|
92
|
+
def blank?(elem)
|
93
|
+
elem.nil? || elem.respond_to?(:empty?) && elem.empty?
|
73
94
|
end
|
74
95
|
|
75
|
-
def trim_hash(
|
96
|
+
def trim_hash(hash)
|
76
97
|
loop do
|
77
|
-
h_new = trim_hash1(
|
78
|
-
break
|
79
|
-
|
98
|
+
h_new = trim_hash1(hash)
|
99
|
+
break hash if hash == h_new
|
100
|
+
|
101
|
+
hash = h_new
|
80
102
|
end
|
81
103
|
end
|
82
104
|
|
83
|
-
def trim_hash1(
|
84
|
-
return
|
85
|
-
|
105
|
+
def trim_hash1(hash)
|
106
|
+
return hash unless hash.is_a? Hash
|
107
|
+
|
108
|
+
hash.each_with_object({}) do |(k, v), g|
|
86
109
|
next if blank?(v)
|
87
|
-
|
110
|
+
|
111
|
+
g[k] = if v.is_a? Hash then trim_hash1(hash[k])
|
88
112
|
elsif v.is_a? Array
|
89
|
-
|
113
|
+
hash[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
|
90
114
|
else
|
91
115
|
v
|
92
116
|
end
|
@@ -3,7 +3,8 @@ require "base64"
|
|
3
3
|
module IsoDoc
|
4
4
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
5
5
|
def lower2cap(s)
|
6
|
-
return s if /^[[:upper:]][[:upper:]]/.match(s)
|
6
|
+
return s if /^[[:upper:]][[:upper:]]/.match?(s)
|
7
|
+
|
7
8
|
s.capitalize
|
8
9
|
end
|
9
10
|
|
@@ -19,8 +20,10 @@ module IsoDoc
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def svg_extract(f)
|
22
|
-
return unless %r{^data:image/svg\+xml;base64,}.match(f["src"])
|
23
|
-
|
23
|
+
return unless %r{^data:image/svg\+xml;base64,}.match?(f["src"])
|
24
|
+
|
25
|
+
svg = Base64.strict_decode64(f["src"]
|
26
|
+
.sub(%r{^data:image/svg\+xml;base64,}, ""))
|
24
27
|
f.replace(svg.sub(/<\?xml[^>]*>/, ""))
|
25
28
|
end
|
26
29
|
|
@@ -28,12 +31,15 @@ module IsoDoc
|
|
28
31
|
return sourcecode1(f) if f["class"] == "pseudocode" || f["type"] == "pseudocode"
|
29
32
|
return if labelled_ancestor(f) && f.ancestors("figure").empty?
|
30
33
|
return if f.at(ns("./figure")) and !f.at(ns("./name"))
|
34
|
+
|
31
35
|
lbl = @xrefs.anchor(f['id'], :label, false) or return
|
32
|
-
prefix_name(f, " — ",
|
36
|
+
prefix_name(f, " — ",
|
37
|
+
l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
|
33
38
|
end
|
34
39
|
|
35
40
|
def prefix_name(f, delim, number, elem)
|
36
41
|
return if number.nil? || number.empty?
|
42
|
+
|
37
43
|
unless name = f.at(ns("./#{elem}"))
|
38
44
|
f.children.empty? and f.add_child("<#{elem}></#{elem}>") or
|
39
45
|
f.children.first.previous = "<#{elem}></#{elem}>"
|
@@ -52,6 +58,7 @@ module IsoDoc
|
|
52
58
|
def sourcecode1(f)
|
53
59
|
return if labelled_ancestor(f)
|
54
60
|
return unless f.ancestors("example").empty?
|
61
|
+
|
55
62
|
lbl = @xrefs.anchor(f['id'], :label, false) or return
|
56
63
|
prefix_name(f, " — ", l10n("#{lower2cap @i18n.figure} #{lbl}"), "name")
|
57
64
|
end
|
@@ -96,6 +103,7 @@ module IsoDoc
|
|
96
103
|
# introduce name element
|
97
104
|
def note1(f)
|
98
105
|
return if f.parent.name == "bibitem"
|
106
|
+
|
99
107
|
n = @xrefs.get[f["id"]]
|
100
108
|
lbl = (@i18n.note if n.nil? || n[:label].nil? || n[:label].empty?) ?
|
101
109
|
@i18n.note: l10n("#{@i18n.note} #{n[:label]}")
|
@@ -110,7 +118,7 @@ module IsoDoc
|
|
110
118
|
|
111
119
|
# introduce name element
|
112
120
|
def termnote1(f)
|
113
|
-
lbl = l10n(@xrefs.anchor(f[
|
121
|
+
lbl = l10n(@xrefs.anchor(f["id"], :label) || "???")
|
114
122
|
prefix_name(f, "", lower2cap(lbl), "name")
|
115
123
|
end
|
116
124
|
|
@@ -134,7 +142,7 @@ module IsoDoc
|
|
134
142
|
|
135
143
|
# introduce name element
|
136
144
|
def recommendation1(f, type)
|
137
|
-
n = @xrefs.anchor(f[
|
145
|
+
n = @xrefs.anchor(f["id"], :label, false)
|
138
146
|
lbl = (n.nil? ? type : l10n("#{type} #{n}"))
|
139
147
|
prefix_name(f, "", lbl, "name")
|
140
148
|
end
|
@@ -148,7 +156,8 @@ module IsoDoc
|
|
148
156
|
def table1(f)
|
149
157
|
return if labelled_ancestor(f)
|
150
158
|
return if f["unnumbered"] && !f.at(ns("./name"))
|
151
|
-
|
159
|
+
|
160
|
+
n = @xrefs.anchor(f["id"], :label, false)
|
152
161
|
prefix_name(f, " — ", l10n("#{lower2cap @i18n.table} #{n}"), "name")
|
153
162
|
end
|
154
163
|
|
@@ -160,7 +169,7 @@ module IsoDoc
|
|
160
169
|
end
|
161
170
|
|
162
171
|
def amend1(f)
|
163
|
-
f.xpath(ns("./autonumber")).each
|
172
|
+
f.xpath(ns("./autonumber")).each(&:remove)
|
164
173
|
f.xpath(ns("./newcontent")).each { |a| a.name = "quote" }
|
165
174
|
f.xpath(ns("./description")).each { |a| a.replace(a.children) }
|
166
175
|
f.replace(f.children)
|
@@ -1,28 +1,28 @@
|
|
1
|
-
require "twitter_cldr"
|
2
|
-
require "bigdecimal"
|
3
|
-
|
4
1
|
module IsoDoc
|
5
2
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
6
3
|
def prefix_container(container, linkend, _target)
|
7
|
-
l10n(@xrefs.anchor(container, :xref)
|
4
|
+
l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
|
8
5
|
end
|
9
6
|
|
10
7
|
def anchor_linkend(node, linkend)
|
11
8
|
if node["citeas"].nil? && node["bibitemid"]
|
12
|
-
return @xrefs.anchor(node["bibitemid"]
|
9
|
+
return @xrefs.anchor(node["bibitemid"], :xref) || "???"
|
13
10
|
elsif node["target"] && node["droploc"]
|
14
|
-
return @xrefs.anchor(node["target"], :value) ||
|
15
|
-
|
11
|
+
return @xrefs.anchor(node["target"], :value) ||
|
12
|
+
@xrefs.anchor(node["target"], :label) ||
|
13
|
+
@xrefs.anchor(node["target"], :xref) || "???"
|
16
14
|
elsif node["target"] && !/.#./.match(node["target"])
|
17
15
|
linkend = anchor_linkend1(node)
|
18
16
|
end
|
17
|
+
|
19
18
|
linkend || "???"
|
20
19
|
end
|
21
20
|
|
22
21
|
def anchor_linkend1(node)
|
23
22
|
linkend = @xrefs.anchor(node["target"], :xref)
|
24
23
|
container = @xrefs.anchor(node["target"], :container, false)
|
25
|
-
(container && get_note_container_id(node) != container &&
|
24
|
+
(container && get_note_container_id(node) != container &&
|
25
|
+
@xrefs.get[node["target"]]) and
|
26
26
|
linkend = prefix_container(container, linkend, node["target"])
|
27
27
|
capitalise_xref(node, linkend)
|
28
28
|
end
|
@@ -31,90 +31,104 @@ module IsoDoc
|
|
31
31
|
return linkend unless %w(Latn Cyrl Grek).include? @script
|
32
32
|
return linkend&.capitalize if node["case"] == "capital"
|
33
33
|
return linkend&.downcase if node["case"] == "lowercase"
|
34
|
-
return linkend if linkend[0,1].match(/\p{Upper}/)
|
34
|
+
return linkend if linkend[0, 1].match?(/\p{Upper}/)
|
35
|
+
|
36
|
+
capitalise_xref1(node, linkend)
|
37
|
+
end
|
38
|
+
|
39
|
+
def capitalise_xref1(node, linkend)
|
35
40
|
prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
|
36
41
|
node.xpath("./preceding::text()")
|
37
|
-
|
42
|
+
if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
|
43
|
+
linkend&.capitalize
|
44
|
+
else linkend
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def nearest_block_parent(node)
|
41
|
-
until %w(p title td th name formula li dt dd sourcecode pre)
|
49
|
+
until %w(p title td th name formula li dt dd sourcecode pre)
|
50
|
+
.include?(node.name)
|
42
51
|
node = node.parent
|
43
52
|
end
|
44
53
|
node
|
45
54
|
end
|
46
55
|
|
47
56
|
def non_locality_elems(node)
|
48
|
-
node.children.
|
49
|
-
|
57
|
+
node.children.reject do |c|
|
58
|
+
%w{locality localityStack}.include? c.name
|
50
59
|
end
|
51
60
|
end
|
52
61
|
|
53
62
|
def get_linkend(node)
|
54
|
-
|
55
|
-
return unless
|
63
|
+
c1 = non_locality_elems(node).select { |c| !c.text? || /\S/.match(c) }
|
64
|
+
return unless c1.empty?
|
65
|
+
|
56
66
|
link = anchor_linkend(node, docid_l10n(node["target"] || node["citeas"]))
|
57
|
-
link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
|
58
|
-
|
67
|
+
link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
|
68
|
+
link, node)
|
69
|
+
non_locality_elems(node).each(&:remove)
|
59
70
|
node.add_child(link)
|
60
71
|
end
|
61
72
|
# so not <origin bibitemid="ISO7301" citeas="ISO 7301">
|
62
73
|
# <locality type="section"><reference>3.1</reference></locality></origin>
|
63
74
|
|
64
|
-
def eref_localities(refs, target,
|
75
|
+
def eref_localities(refs, target, node)
|
65
76
|
ret = ""
|
66
77
|
refs.each_with_index do |r, i|
|
67
78
|
delim = ","
|
68
|
-
delim = ";" if r.name == "localityStack" && i
|
69
|
-
ret = eref_locality_stack(r, i, target, delim, ret,
|
79
|
+
delim = ";" if r.name == "localityStack" && i.positive?
|
80
|
+
ret = eref_locality_stack(r, i, target, delim, ret, node)
|
70
81
|
end
|
71
82
|
ret
|
72
83
|
end
|
73
84
|
|
74
|
-
def eref_locality_stack(
|
75
|
-
if
|
76
|
-
|
77
|
-
ret += eref_localities0(rr, j, target, delim,
|
85
|
+
def eref_locality_stack(ref, idx, target, delim, ret, node)
|
86
|
+
if ref.name == "localityStack"
|
87
|
+
ref.elements.each_with_index do |rr, j|
|
88
|
+
ret += eref_localities0(rr, j, target, delim, node)
|
78
89
|
delim = ","
|
79
90
|
end
|
80
91
|
else
|
81
|
-
ret += eref_localities0(
|
92
|
+
ret += eref_localities0(ref, idx, target, delim, node)
|
82
93
|
end
|
83
94
|
ret
|
84
95
|
end
|
85
96
|
|
86
|
-
def eref_localities0(
|
87
|
-
if
|
97
|
+
def eref_localities0(ref, _idx, target, delim, node)
|
98
|
+
if ref["type"] == "whole" then l10n("#{delim} #{@i18n.wholeoftext}")
|
88
99
|
else
|
89
|
-
eref_localities1(target,
|
90
|
-
|
100
|
+
eref_localities1(target, ref["type"], ref.at(ns("./referenceFrom")),
|
101
|
+
ref.at(ns("./referenceTo")), delim, node, @lang)
|
91
102
|
end
|
92
103
|
end
|
93
104
|
|
94
105
|
# TODO: move to localization file
|
95
|
-
def eref_localities1_zh(
|
106
|
+
def eref_localities1_zh(_target, type, from, upto, node, delim)
|
96
107
|
ret = "#{delim} 第#{from.text}" if from
|
97
|
-
ret += "–#{
|
98
|
-
loc = (@i18n.locality[type] || type.sub(/^locality:/, "").capitalize
|
99
|
-
ret += " #{loc}" unless
|
108
|
+
ret += "–#{upto.text}" if upto
|
109
|
+
loc = (@i18n.locality[type] || type.sub(/^locality:/, "").capitalize)
|
110
|
+
ret += " #{loc}" unless node["droploc"] == "true"
|
100
111
|
ret
|
101
112
|
end
|
102
113
|
|
103
114
|
# TODO: move to localization file
|
104
|
-
def eref_localities1(target, type, from,
|
115
|
+
def eref_localities1(target, type, from, upto, delim, node, lang = "en")
|
105
116
|
return "" if type == "anchor"
|
106
|
-
|
117
|
+
|
118
|
+
lang == "zh" and
|
119
|
+
return l10n(eref_localities1_zh(target, type, from, upto, node, delim))
|
107
120
|
ret = delim
|
108
|
-
ret += eref_locality_populate(type,
|
121
|
+
ret += eref_locality_populate(type, node)
|
109
122
|
ret += " #{from.text}" if from
|
110
|
-
ret += "–#{
|
123
|
+
ret += "–#{upto.text}" if upto
|
111
124
|
l10n(ret)
|
112
125
|
end
|
113
126
|
|
114
|
-
def eref_locality_populate(type,
|
115
|
-
return "" if
|
127
|
+
def eref_locality_populate(type, node)
|
128
|
+
return "" if node["droploc"] == "true"
|
129
|
+
|
116
130
|
loc = @i18n.locality[type] || type.sub(/^locality:/, "")
|
117
|
-
loc = case
|
131
|
+
loc = case node["case"]
|
118
132
|
when "capital" then loc.capitalize
|
119
133
|
when "lowercase" then loc.downcase
|
120
134
|
else
|
@@ -139,8 +153,8 @@ module IsoDoc
|
|
139
153
|
docxml.xpath(ns("//quote/source")).each { |f| xref1(f) }
|
140
154
|
end
|
141
155
|
|
142
|
-
def xref1(
|
143
|
-
get_linkend(
|
156
|
+
def xref1(node)
|
157
|
+
get_linkend(node)
|
144
158
|
end
|
145
159
|
|
146
160
|
def concept(docxml)
|
@@ -148,107 +162,45 @@ module IsoDoc
|
|
148
162
|
end
|
149
163
|
|
150
164
|
def concept1(node)
|
151
|
-
content = node.first_element_child.children.
|
152
|
-
|
165
|
+
content = node.first_element_child.children.reject do |c|
|
166
|
+
%w{locality localityStack}.include? c.name
|
153
167
|
end.select { |c| !c.text? || /\S/.match(c) }
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
|
161
|
-
|
162
|
-
def mathml(docxml)
|
163
|
-
locale = twitter_cldr_localiser()
|
164
|
-
docxml.xpath("//m:math", MATHML).each do |f|
|
165
|
-
mathml1(f, locale)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# symbols is merged into
|
170
|
-
# TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
|
171
|
-
def localize_maths(f, locale)
|
172
|
-
f.xpath(".//m:mn", MATHML).each do |x|
|
173
|
-
num = BigDecimal(x.text)
|
174
|
-
precision = /\./.match(x.text) ? x.text.sub(/^.*\./, "").size : 0
|
175
|
-
x.children = localized_number(num, locale, precision)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
# By itself twitter-cldr does not support fraction part digits grouping
|
180
|
-
# and custom delimeter, will decorate fraction part manually
|
181
|
-
def localized_number(num, locale, precision)
|
182
|
-
localized = (precision == 0) ? num.localize(locale).to_s :
|
183
|
-
num.localize(locale).to_decimal.to_s(:precision => precision)
|
184
|
-
twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
|
185
|
-
return localized unless twitter_cldr_reader_symbols[:decimal]
|
186
|
-
integer, fraction = localized.split(twitter_cldr_reader_symbols[:decimal])
|
187
|
-
return localized if fraction.nil? || fraction.length.zero?
|
188
|
-
[integer, decorate_fraction_part(fraction, locale)].join(twitter_cldr_reader_symbols[:decimal])
|
189
|
-
end
|
190
|
-
|
191
|
-
def decorate_fraction_part(fract, locale)
|
192
|
-
result = []
|
193
|
-
twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
|
194
|
-
fract = fract.slice(0..(twitter_cldr_reader_symbols[:precision] || -1))
|
195
|
-
fr_group_digits = twitter_cldr_reader_symbols[:fraction_group_digits] || 1
|
196
|
-
until fract.empty?
|
197
|
-
result.push(fract.slice!(0, fr_group_digits))
|
198
|
-
end
|
199
|
-
result.join(twitter_cldr_reader_symbols[:fraction_group].to_s)
|
200
|
-
end
|
201
|
-
|
202
|
-
def twitter_cldr_localiser_symbols
|
203
|
-
{}
|
204
|
-
end
|
205
|
-
|
206
|
-
def twitter_cldr_reader(locale)
|
207
|
-
num = TwitterCldr::DataReaders::NumberDataReader.new(locale)
|
208
|
-
num.symbols.merge!(twitter_cldr_localiser_symbols)
|
209
|
-
end
|
210
|
-
|
211
|
-
def twitter_cldr_localiser()
|
212
|
-
locale = TwitterCldr.supported_locale?(@lang.to_sym) ? @lang.to_sym : :en
|
213
|
-
twitter_cldr_reader(locale)
|
214
|
-
locale
|
215
|
-
end
|
216
|
-
|
217
|
-
def mathml1(f, locale)
|
218
|
-
localize_maths(f, locale)
|
219
|
-
return unless f.elements.size == 1 && f.elements.first.name == "mn"
|
220
|
-
if f.parent.name == "stem"
|
221
|
-
f.parent.replace(f.at("./m:mn", MATHML).children)
|
222
|
-
else
|
223
|
-
f.replace(f.at("./m:mn", MATHML).children)
|
224
|
-
end
|
168
|
+
n = if content.empty?
|
169
|
+
@i18n.term_defined_in.sub(/%/, node.first_element_child.to_xml)
|
170
|
+
else
|
171
|
+
"<em>#{node.children.to_xml}</em>"
|
172
|
+
end
|
173
|
+
node.replace(n)
|
225
174
|
end
|
226
175
|
|
227
176
|
def variant(docxml)
|
228
177
|
docxml.xpath(ns("//variant")).each { |f| variant1(f) }
|
229
|
-
docxml.xpath(ns("//variant[@remove = 'true']")).each
|
178
|
+
docxml.xpath(ns("//variant[@remove = 'true']")).each(&:remove)
|
230
179
|
docxml.xpath(ns("//variant")).each do |v|
|
231
180
|
next unless v&.next&.name == "variant"
|
181
|
+
|
232
182
|
v.next = "/"
|
233
183
|
end
|
234
184
|
docxml.xpath(ns("//variant")).each { |f| f.replace(f.children) }
|
235
185
|
end
|
236
186
|
|
237
187
|
def variant1(node)
|
238
|
-
if (!node["lang"] || node["lang"] == @lang) &&
|
188
|
+
if (!node["lang"] || node["lang"] == @lang) &&
|
189
|
+
(!node["script"] || node["script"] == @script)
|
239
190
|
elsif found_matching_variant_sibling(node)
|
240
191
|
node["remove"] = "true"
|
241
|
-
else
|
242
|
-
#return unless !node.at("./preceding-sibling::xmlns:variant")
|
243
192
|
end
|
244
193
|
end
|
245
194
|
|
195
|
+
private
|
196
|
+
|
246
197
|
def found_matching_variant_sibling(node)
|
247
198
|
prev = node.xpath("./preceding-sibling::xmlns:variant")
|
248
199
|
foll = node.xpath("./following-sibling::xmlns:variant")
|
249
200
|
found = false
|
250
201
|
(prev + foll).each do |n|
|
251
|
-
found = true if n["lang"] == @lang &&
|
202
|
+
found = true if n["lang"] == @lang &&
|
203
|
+
(!n["script"] || n["script"] == @script)
|
252
204
|
end
|
253
205
|
found
|
254
206
|
end
|