isodoc 2.0.2 → 2.0.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/lib/isodoc/convert.rb +36 -18
- data/lib/isodoc/function/inline.rb +24 -13
- data/lib/isodoc/function/references.rb +18 -6
- data/lib/isodoc/html_function/html.rb +6 -0
- data/lib/isodoc/i18n.rb +20 -7
- data/lib/isodoc/metadata.rb +1 -1
- data/lib/isodoc/metadata_contributor.rb +1 -1
- data/lib/isodoc/presentation_function/bibdata.rb +26 -9
- data/lib/isodoc/presentation_function/block.rb +24 -0
- data/lib/isodoc/presentation_function/image.rb +3 -4
- data/lib/isodoc/presentation_function/inline.rb +118 -76
- data/lib/isodoc/presentation_function/math.rb +1 -0
- data/lib/isodoc/presentation_function/xrefs.rb +100 -0
- data/lib/isodoc/presentation_xml_convert.rb +1 -0
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/body.rb +11 -1
- data/lib/isodoc/word_function/postprocess.rb +4 -6
- data/lib/isodoc/word_function/postprocess_cover.rb +82 -1
- data/lib/isodoc/xref/xref_anchor.rb +1 -0
- data/lib/isodoc/xref/xref_gen.rb +2 -1
- data/lib/isodoc/xref/xref_sect_gen.rb +14 -8
- data/lib/isodoc/xslfo_convert.rb +19 -19
- data/lib/isodoc-yaml/i18n-ar.yaml +11 -0
- data/lib/isodoc-yaml/i18n-de.yaml +11 -0
- data/lib/isodoc-yaml/i18n-en.yaml +11 -0
- data/lib/isodoc-yaml/i18n-es.yaml +11 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +11 -0
- data/lib/isodoc-yaml/i18n-ru.yaml +11 -0
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +11 -0
- data/spec/isodoc/blocks_spec.rb +13 -77
- data/spec/isodoc/inline_spec.rb +565 -22
- data/spec/isodoc/metadata_spec.rb +1 -1
- data/spec/isodoc/postproc_spec.rb +466 -2
- data/spec/isodoc/presentation_xml_spec.rb +380 -78
- data/spec/isodoc/ref_spec.rb +96 -11
- data/spec/isodoc/section_spec.rb +1 -2
- data/spec/isodoc/table_spec.rb +1 -1
- data/spec/isodoc/terms_spec.rb +8 -8
- data/spec/isodoc/xref_spec.rb +71 -1190
- data/spec/isodoc/xslfo_convert_spec.rb +12 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1cd1a1265557222ad7684ab50c08fd55d8cc92b46a3997a298f61c0e8b151bc
|
4
|
+
data.tar.gz: 394d232d1f1b9e9b4d138df36b555b090b923c96a3f848e7a88cd9d72a3e173a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38809fca460021e23cdebe0beb21ba510e59120edba915a760ccbe5248cb73381b0694c0842cfd8bedc00f7d45298765281a36a84ad6bd4283e608f80424f67d
|
7
|
+
data.tar.gz: d2ea4b7bb2b0f461ff511da937a9e1ee359321bb228eba89c9ad2808b1e39c92b39af45100503be594c94f74fea0d0571641314f22e0cef645e91c7555e014b5
|
data/lib/isodoc/convert.rb
CHANGED
@@ -40,6 +40,9 @@ module IsoDoc
|
|
40
40
|
# every 40-odd chars
|
41
41
|
# sectionsplit: split up HTML output on sections
|
42
42
|
# bare: do not insert any prefatory material (coverpage, boilerplate)
|
43
|
+
# tocfigures: add ToC for figures
|
44
|
+
# toctables: add ToC for tables
|
45
|
+
# tocrecommendations: add ToC for rcommendations
|
43
46
|
def initialize(options)
|
44
47
|
@libdir ||= File.dirname(__FILE__) # rubocop:disable Lint/DisjunctiveAssignmentInConstructor
|
45
48
|
options.merge!(default_fonts(options)) do |_, old, new|
|
@@ -50,25 +53,14 @@ module IsoDoc
|
|
50
53
|
@options = options
|
51
54
|
@files_to_delete = []
|
52
55
|
@tempfile_cache = []
|
53
|
-
@htmlstylesheet_name = options[:htmlstylesheet]
|
54
|
-
@wordstylesheet_name = options[:wordstylesheet]
|
55
|
-
@htmlstylesheet_override_name = options[:htmlstylesheet_override]
|
56
|
-
@wordstylesheet_override_name = options[:wordstylesheet_override]
|
57
|
-
@standardstylesheet_name = options[:standardstylesheet]
|
58
56
|
@sourcefilename = options[:sourcefilename]
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@htmlintropage = options[:htmlintropage]
|
63
|
-
@wordintropage = options[:wordintropage]
|
57
|
+
init_stylesheets(options)
|
58
|
+
init_covers(options)
|
59
|
+
init_toc(options)
|
64
60
|
@normalfontsize = options[:normalfontsize]
|
65
61
|
@smallerfontsize = options[:smallerfontsize]
|
66
62
|
@monospacefontsize = options[:monospacefontsize]
|
67
63
|
@footnotefontsize = options[:footnotefontsize]
|
68
|
-
@scripts = options[:scripts] ||
|
69
|
-
File.join(File.dirname(__FILE__), "base_style", "scripts.html")
|
70
|
-
@scripts_pdf = options[:scripts_pdf]
|
71
|
-
@scripts_override = options[:scripts_override]
|
72
64
|
@i18nyaml = options[:i18nyaml]
|
73
65
|
@ulstyle = options[:ulstyle]
|
74
66
|
@olstyle = options[:olstyle]
|
@@ -96,10 +88,6 @@ module IsoDoc
|
|
96
88
|
@script = options[:script] || "Latn"
|
97
89
|
@maxwidth = 1200
|
98
90
|
@maxheight = 800
|
99
|
-
@wordToClevels = options[:doctoclevels].to_i
|
100
|
-
@wordToClevels = 2 if @wordToClevels.zero?
|
101
|
-
@htmlToClevels = options[:htmltoclevels].to_i
|
102
|
-
@htmlToClevels = 2 if @htmlToClevels.zero?
|
103
91
|
@bookmarks_allocated = { "X" => true }
|
104
92
|
@fn_bookmarks = {}
|
105
93
|
@baseassetpath = options[:baseassetpath]
|
@@ -108,6 +96,36 @@ module IsoDoc
|
|
108
96
|
@tmpfilesdir_suffix = tmpfilesdir_suffix
|
109
97
|
end
|
110
98
|
|
99
|
+
def init_covers(options)
|
100
|
+
@header = options[:header]
|
101
|
+
@htmlcoverpage = options[:htmlcoverpage]
|
102
|
+
@wordcoverpage = options[:wordcoverpage]
|
103
|
+
@htmlintropage = options[:htmlintropage]
|
104
|
+
@wordintropage = options[:wordintropage]
|
105
|
+
@scripts = options[:scripts] ||
|
106
|
+
File.join(File.dirname(__FILE__), "base_style", "scripts.html")
|
107
|
+
@scripts_pdf = options[:scripts_pdf]
|
108
|
+
@scripts_override = options[:scripts_override]
|
109
|
+
end
|
110
|
+
|
111
|
+
def init_stylesheets(options)
|
112
|
+
@htmlstylesheet_name = options[:htmlstylesheet]
|
113
|
+
@wordstylesheet_name = options[:wordstylesheet]
|
114
|
+
@htmlstylesheet_override_name = options[:htmlstylesheet_override]
|
115
|
+
@wordstylesheet_override_name = options[:wordstylesheet_override]
|
116
|
+
@standardstylesheet_name = options[:standardstylesheet]
|
117
|
+
end
|
118
|
+
|
119
|
+
def init_toc(options)
|
120
|
+
@wordToClevels = options[:doctoclevels].to_i
|
121
|
+
@wordToClevels = 2 if @wordToClevels.zero?
|
122
|
+
@htmlToClevels = options[:htmltoclevels].to_i
|
123
|
+
@htmlToClevels = 2 if @htmlToClevels.zero?
|
124
|
+
@tocfigures = options[:tocfigures]
|
125
|
+
@toctables = options[:toctables]
|
126
|
+
@tocrecommendations = options[:tocrecommendations]
|
127
|
+
end
|
128
|
+
|
111
129
|
def tmpimagedir_suffix
|
112
130
|
"_#{SecureRandom.hex(8)}_images"
|
113
131
|
end
|
@@ -34,30 +34,41 @@ module IsoDoc
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def suffix_url(url)
|
37
|
-
return url if %r{^https
|
37
|
+
return url if url.nil? || %r{^https?://|^#}.match?(url)
|
38
38
|
return url unless File.extname(url).empty?
|
39
39
|
|
40
40
|
url.sub(/#{File.extname(url)}$/, ".html")
|
41
41
|
end
|
42
42
|
|
43
43
|
def eref_target(node)
|
44
|
-
|
45
|
-
|
44
|
+
url = suffix_url(eref_url(node["bibitemid"]))
|
45
|
+
anchor = node&.at(ns(".//locality[@type = 'anchor']"))
|
46
|
+
return url if url.nil? || /^#/.match?(url) || !anchor
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
"#{url}##{anchor.text.strip}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def eref_url(bibitemid)
|
52
|
+
return nil if @bibitems.nil? || @bibitems[bibitemid].nil?
|
53
|
+
|
54
|
+
if url = @bibitems[bibitemid].at(ns("./uri[@type = 'citation']"))
|
55
|
+
url.text
|
56
|
+
elsif @bibitems[bibitemid]["hidden"] == "true"
|
57
|
+
@bibitems[bibitemid]&.at(ns("./uri"))&.text
|
58
|
+
else "##{bibitemid}"
|
59
|
+
end
|
51
60
|
end
|
52
61
|
|
53
62
|
def eref_parse(node, out)
|
54
|
-
href = eref_target(node)
|
55
|
-
|
56
|
-
|
57
|
-
|
63
|
+
if href = eref_target(node)
|
64
|
+
if node["type"] == "footnote"
|
65
|
+
out.sup do |s|
|
66
|
+
s.a(**{ href: href }) { |l| no_locality_parse(node, l) }
|
67
|
+
end
|
68
|
+
else
|
69
|
+
out.a(**{ href: href }) { |l| no_locality_parse(node, l) }
|
58
70
|
end
|
59
|
-
else
|
60
|
-
out.a(**{ href: href }) { |l| no_locality_parse(node, l) }
|
71
|
+
else no_locality_parse(node, out)
|
61
72
|
end
|
62
73
|
end
|
63
74
|
|
@@ -49,10 +49,14 @@ module IsoDoc
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def pref_ref_code(bib)
|
52
|
-
bib.
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
ret = bib.xpath(ns("./docidentifier[@primary = 'true']"))
|
53
|
+
ret.empty? and
|
54
|
+
ret = bib.at(ns("./docidentifier[not(@type = 'DOI' or "\
|
55
|
+
"@type = 'metanorma' "\
|
56
|
+
"or @type = 'metanorma-ordinal' or "\
|
57
|
+
"@type = 'ISSN' or @type = 'ISBN' or "\
|
58
|
+
"@type = 'rfc-anchor')]"))
|
59
|
+
ret
|
56
60
|
end
|
57
61
|
|
58
62
|
# returns [metanorma, non-metanorma, DOI/ISSN/ISBN] identifiers
|
@@ -78,10 +82,18 @@ module IsoDoc
|
|
78
82
|
num
|
79
83
|
end
|
80
84
|
|
81
|
-
def
|
85
|
+
def unbracket1(ident)
|
82
86
|
ident&.text&.sub(/^\[/, "")&.sub(/\]$/, "")
|
83
87
|
end
|
84
88
|
|
89
|
+
def unbracket(ident)
|
90
|
+
if ident.respond_to?(:size)
|
91
|
+
ident.map { |x| unbracket1(x) }.join(" / ")
|
92
|
+
else
|
93
|
+
unbracket1(ident)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
85
97
|
def render_identifier(ident)
|
86
98
|
{ metanorma: bracket_if_num(ident[0]),
|
87
99
|
sdo: unbracket(ident[1]),
|
@@ -106,7 +118,7 @@ module IsoDoc
|
|
106
118
|
date_note = bib.at(ns("./note[@type = 'Unpublished-Status']"))
|
107
119
|
return if date_note.nil?
|
108
120
|
|
109
|
-
date_note.children
|
121
|
+
date_note.children = "<p>#{date_note.content}</p>"
|
110
122
|
footnote_parse(date_note, ref)
|
111
123
|
end
|
112
124
|
|
@@ -128,6 +128,12 @@ module IsoDoc
|
|
128
128
|
|
129
129
|
def table_long_strings_cleanup(docxml); end
|
130
130
|
|
131
|
+
def table_attrs(node)
|
132
|
+
ret = super
|
133
|
+
node.at(ns("./colgroup")) and ret[:style] += "table-layout:fixed;"
|
134
|
+
ret
|
135
|
+
end
|
136
|
+
|
131
137
|
def image_parse(node, out, caption)
|
132
138
|
if svg = node.at("./m:svg", "m" => "http://www.w3.org/2000/svg")
|
133
139
|
svg_parse(svg, out)
|
data/lib/isodoc/i18n.rb
CHANGED
@@ -104,15 +104,28 @@ module IsoDoc
|
|
104
104
|
xml.to_xml.gsub(/<b>/, "").gsub("</b>", "").gsub(/<\?[^>]+>/, "")
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
(
|
112
|
-
(
|
113
|
-
|
107
|
+
def boolean_conj(list, conn)
|
108
|
+
case list.size
|
109
|
+
when 0 then ""
|
110
|
+
when 1 then list.first
|
111
|
+
when 2 then @labels["binary_#{conn}"].sub(/%1/, list[0])
|
112
|
+
.sub(/%2/, list[1])
|
113
|
+
else
|
114
|
+
@labels["multiple_#{conn}"]
|
115
|
+
.sub(/%1/, l10n(list[0..-2].join(", "), @lang, @script))
|
116
|
+
.sub(/%2/, list[-1])
|
117
|
+
end
|
114
118
|
end
|
115
119
|
|
120
|
+
# def multiple_and(names, andword)
|
121
|
+
# return "" if names.empty?
|
122
|
+
# return names[0] if names.length == 1
|
123
|
+
#
|
124
|
+
# (names.length == 2) &&
|
125
|
+
# (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
|
126
|
+
# l10n(names[0..-2].join(", ") + " #{andword} #{names[-1]}", @lang, @script)
|
127
|
+
# end
|
128
|
+
|
116
129
|
include Function::Utils
|
117
130
|
# module_function :l10n
|
118
131
|
end
|
data/lib/isodoc/metadata.rb
CHANGED
@@ -75,7 +75,7 @@ module IsoDoc
|
|
75
75
|
def agency(xml)
|
76
76
|
agency, publisher = agency1(xml)
|
77
77
|
set(:agency, agency.sub(%r{/$}, ""))
|
78
|
-
set(:publisher, @i18n.
|
78
|
+
set(:publisher, @i18n.boolean_conj(publisher, "and"))
|
79
79
|
agency_addr(xml)
|
80
80
|
end
|
81
81
|
|
@@ -1,15 +1,30 @@
|
|
1
1
|
module IsoDoc
|
2
2
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
3
3
|
def bibdata(docxml)
|
4
|
+
toc_metadata(docxml)
|
4
5
|
docid_prefixes(docxml)
|
5
6
|
a = bibdata_current(docxml) or return
|
6
7
|
address_precompose(a)
|
7
8
|
bibdata_i18n(a)
|
8
9
|
a.next =
|
9
|
-
"<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join
|
10
|
+
"<localized-strings>#{i8n_name(trim_hash(@i18n.get), '').join}"\
|
10
11
|
"</localized-strings>"
|
11
12
|
end
|
12
13
|
|
14
|
+
def toc_metadata(docxml)
|
15
|
+
return unless @tocfigures || @toctables || @tocrecommendations
|
16
|
+
|
17
|
+
ins = docxml.at(ns("//misc-container")) ||
|
18
|
+
docxml.at(ns("//bibdata")).after("<misc-container/>").next_element
|
19
|
+
@tocfigures and
|
20
|
+
ins << "<toc type='figure'><title>#{@i18n.toc_figures}</title></toc>"
|
21
|
+
@toctables and
|
22
|
+
ins << "<toc type='table'><title>#{@i18n.toc_tables}</title></toc>"
|
23
|
+
@tocfigures and
|
24
|
+
ins << "<toc type='recommendation'><title>#{@i18n.toc_recommendations}"\
|
25
|
+
"</title></toc>"
|
26
|
+
end
|
27
|
+
|
13
28
|
def address_precompose(bib)
|
14
29
|
bib.xpath(ns("//bibdata//address")).each do |b|
|
15
30
|
next if b.at(ns("./formattedAddress"))
|
@@ -66,8 +81,9 @@ module IsoDoc
|
|
66
81
|
end
|
67
82
|
|
68
83
|
def i8n_name(hash, pref)
|
69
|
-
|
70
|
-
|
84
|
+
case hash
|
85
|
+
when Hash then i8n_name1(hash, pref)
|
86
|
+
when Array
|
71
87
|
hash.reject { |a| blank?(a) }.each_with_object([])
|
72
88
|
.with_index do |(v1, g), i|
|
73
89
|
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
@@ -78,8 +94,9 @@ module IsoDoc
|
|
78
94
|
|
79
95
|
def i8n_name1(hash, pref)
|
80
96
|
hash.reject { |_k, v| blank?(v) }.each_with_object([]) do |(k, v), g|
|
81
|
-
|
82
|
-
|
97
|
+
case v
|
98
|
+
when Hash then i8n_name(v, i18n_safe(k)).each { |x| g << x }
|
99
|
+
when Array
|
83
100
|
v.reject { |a| blank?(a) }.each_with_index do |v1, i|
|
84
101
|
i8n_name(v1, "#{i18n_safe(k)}.#{i}").each { |x| g << x }
|
85
102
|
end
|
@@ -109,11 +126,11 @@ module IsoDoc
|
|
109
126
|
hash.each_with_object({}) do |(k, v), g|
|
110
127
|
next if blank?(v)
|
111
128
|
|
112
|
-
g[k] =
|
113
|
-
|
129
|
+
g[k] = case v
|
130
|
+
when Hash then trim_hash1(hash[k])
|
131
|
+
when Array
|
114
132
|
hash[k].map { |a| trim_hash1(a) }.reject { |a| blank?(a) }
|
115
|
-
else
|
116
|
-
v
|
133
|
+
else v
|
117
134
|
end
|
118
135
|
end
|
119
136
|
end
|
@@ -135,5 +135,29 @@ module IsoDoc
|
|
135
135
|
elem.xpath(ns("./description")).each { |a| a.replace(a.children) }
|
136
136
|
elem.replace(elem.children)
|
137
137
|
end
|
138
|
+
|
139
|
+
def ol(docxml)
|
140
|
+
docxml.xpath(ns("//ol")).each do |f|
|
141
|
+
ol1(f)
|
142
|
+
end
|
143
|
+
@xrefs.list_anchor_names(docxml.xpath(ns(@xrefs.sections_xpath)))
|
144
|
+
end
|
145
|
+
|
146
|
+
# We don't really want users to specify type of ordered list;
|
147
|
+
# we will use by default a fixed hierarchy as practiced by ISO (though not
|
148
|
+
# fully spelled out): a) 1) i) A) I)
|
149
|
+
def ol_depth(node)
|
150
|
+
depth = node.ancestors("ul, ol").size + 1
|
151
|
+
type = :alphabet
|
152
|
+
type = :arabic if [2, 7].include? depth
|
153
|
+
type = :roman if [3, 8].include? depth
|
154
|
+
type = :alphabet_upper if [4, 9].include? depth
|
155
|
+
type = :roman_upper if [5, 10].include? depth
|
156
|
+
type
|
157
|
+
end
|
158
|
+
|
159
|
+
def ol1(elem)
|
160
|
+
elem["type"] ||= ol_depth(elem).to_s
|
161
|
+
end
|
138
162
|
end
|
139
163
|
end
|
@@ -65,15 +65,14 @@ module IsoDoc
|
|
65
65
|
uri = svg_to_emf_uri(node)
|
66
66
|
ret = svg_to_emf_filename(uri)
|
67
67
|
File.exists?(ret) and return ret
|
68
|
-
exe = inkscape_installed? or
|
68
|
+
exe = inkscape_installed? or raise "Inkscape missing in PATH, unable" \
|
69
|
+
"to convert EMF to SVG. Aborting."
|
69
70
|
uri = Metanorma::Utils::external_path uri
|
70
71
|
exe = Metanorma::Utils::external_path exe
|
71
72
|
system(%(#{exe} --export-type="emf" #{uri})) and
|
72
73
|
return Metanorma::Utils::datauri(ret)
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
nil
|
75
|
+
raise %(Fail on #{exe} --export-type="emf" #{uri})
|
77
76
|
end
|
78
77
|
|
79
78
|
def svg_to_emf_uri(node)
|
@@ -1,56 +1,8 @@
|
|
1
1
|
require "metanorma-utils"
|
2
|
+
require_relative "xrefs"
|
2
3
|
|
3
4
|
module IsoDoc
|
4
5
|
class PresentationXMLConvert < ::IsoDoc::Convert
|
5
|
-
def prefix_container(container, linkend, _target)
|
6
|
-
l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
|
7
|
-
end
|
8
|
-
|
9
|
-
def anchor_value(id)
|
10
|
-
@xrefs.anchor(id, :value) || @xrefs.anchor(id, :label) ||
|
11
|
-
@xrefs.anchor(id, :xref)
|
12
|
-
end
|
13
|
-
|
14
|
-
def anchor_linkend(node, linkend)
|
15
|
-
if node["citeas"].nil? && node["bibitemid"]
|
16
|
-
return @xrefs.anchor(node["bibitemid"], :xref) || "???"
|
17
|
-
elsif node["target"] && node["droploc"]
|
18
|
-
return anchor_value(node["target"]) || "???"
|
19
|
-
elsif node["target"] && !/.#./.match(node["target"])
|
20
|
-
linkend = anchor_linkend1(node)
|
21
|
-
end
|
22
|
-
|
23
|
-
linkend || "???"
|
24
|
-
end
|
25
|
-
|
26
|
-
def anchor_linkend1(node)
|
27
|
-
linkend = @xrefs.anchor(node["target"], :xref)
|
28
|
-
container = @xrefs.anchor(node["target"], :container, false)
|
29
|
-
(container && get_note_container_id(node) != container &&
|
30
|
-
@xrefs.get[node["target"]]) and
|
31
|
-
linkend = prefix_container(container, linkend, node["target"])
|
32
|
-
capitalise_xref(node, linkend, anchor_value(node["target"]))
|
33
|
-
end
|
34
|
-
|
35
|
-
def capitalise_xref(node, linkend, label)
|
36
|
-
linktext = linkend.gsub(/<[^>]+>/, "")
|
37
|
-
(label && !label.empty? && /^#{Regexp.escape(label)}/.match?(linktext)) ||
|
38
|
-
linktext[0, 1].match?(/\p{Upper}/) and return linkend
|
39
|
-
node["case"] and
|
40
|
-
return Common::case_with_markup(linkend, node["case"], @script)
|
41
|
-
|
42
|
-
capitalise_xref1(node, linkend)
|
43
|
-
end
|
44
|
-
|
45
|
-
def capitalise_xref1(node, linkend)
|
46
|
-
prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
|
47
|
-
node.xpath("./preceding::text()")
|
48
|
-
if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
|
49
|
-
Common::case_with_markup(linkend, "capital", @script)
|
50
|
-
else linkend
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
6
|
def nearest_block_parent(node)
|
55
7
|
until %w(p title td th name formula li dt dd sourcecode pre)
|
56
8
|
.include?(node.name)
|
@@ -61,7 +13,7 @@ module IsoDoc
|
|
61
13
|
|
62
14
|
def non_locality_elems(node)
|
63
15
|
node.children.reject do |c|
|
64
|
-
%w{locality localityStack}.include? c.name
|
16
|
+
%w{locality localityStack location}.include? c.name
|
65
17
|
end
|
66
18
|
end
|
67
19
|
|
@@ -69,7 +21,8 @@ module IsoDoc
|
|
69
21
|
c1 = non_locality_elems(node).select { |c| !c.text? || /\S/.match(c) }
|
70
22
|
return unless c1.empty?
|
71
23
|
|
72
|
-
link = anchor_linkend(node, docid_l10n(node["target"] ||
|
24
|
+
link = anchor_linkend(node, docid_l10n(node["target"] ||
|
25
|
+
expand_citeas(node["citeas"])))
|
73
26
|
link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
|
74
27
|
link, node)
|
75
28
|
non_locality_elems(node).each(&:remove)
|
@@ -78,54 +31,143 @@ module IsoDoc
|
|
78
31
|
# so not <origin bibitemid="ISO7301" citeas="ISO 7301">
|
79
32
|
# <locality type="section"><reference>3.1</reference></locality></origin>
|
80
33
|
|
34
|
+
def expand_citeas(text)
|
35
|
+
text.nil? and return text
|
36
|
+
HTMLEntities.new.decode(text.gsub(/&#x/, "&#"))
|
37
|
+
end
|
38
|
+
|
81
39
|
def eref_localities(refs, target, node)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
40
|
+
if can_conflate_eref_rendering?(refs)
|
41
|
+
l10n(", #{eref_localities_conflated(refs, target, node)}")
|
42
|
+
else
|
43
|
+
ret = resolve_eref_connectives(eref_locality_stacks(refs, target, node))
|
44
|
+
l10n(ret.join)
|
87
45
|
end
|
88
|
-
ret
|
89
46
|
end
|
90
47
|
|
91
|
-
def
|
48
|
+
def eref_localities_conflated(refs, target, node)
|
49
|
+
droploc = node["droploc"]
|
50
|
+
node["droploc"] = true
|
51
|
+
ret = resolve_eref_connectives(eref_locality_stacks(refs, target,
|
52
|
+
node))
|
53
|
+
node["droploc"] = droploc
|
54
|
+
eref_localities1(target,
|
55
|
+
refs.first.at(ns("./locality/@type")).text,
|
56
|
+
l10n(ret[1..-1].join), nil, node, @lang)
|
57
|
+
end
|
58
|
+
|
59
|
+
def can_conflate_eref_rendering?(refs)
|
60
|
+
(refs.size > 1 &&
|
61
|
+
refs.all? { |r| r.name == "localityStack" } &&
|
62
|
+
refs.all? { |r| r.xpath(ns("./locality")).size == 1 }) or return false
|
63
|
+
|
64
|
+
first = refs.first.at(ns("./locality/@type")).text
|
65
|
+
refs.all? do |r|
|
66
|
+
r.at(ns("./locality/@type")).text == first
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def resolve_eref_connectives(locs)
|
71
|
+
locs = resolve_comma_connectives(locs)
|
72
|
+
locs = resolve_to_connectives(locs)
|
73
|
+
return locs if locs.size < 3
|
74
|
+
|
75
|
+
locs = locs.each_slice(2).with_object([]) do |a, m|
|
76
|
+
m << { conn: a[0], target: a[1] }
|
77
|
+
end
|
78
|
+
[", ", combine_conn(locs)]
|
79
|
+
end
|
80
|
+
|
81
|
+
def resolve_comma_connectives(locs)
|
82
|
+
locs1 = []
|
83
|
+
add = ""
|
84
|
+
until locs.empty?
|
85
|
+
if [", ", " "].include?(locs[1])
|
86
|
+
add += locs[0..2].join
|
87
|
+
locs.shift(3)
|
88
|
+
else
|
89
|
+
locs1 << add unless add.empty?
|
90
|
+
add = ""
|
91
|
+
locs1 << locs.shift
|
92
|
+
end
|
93
|
+
end
|
94
|
+
locs1 << add unless add.empty?
|
95
|
+
locs1
|
96
|
+
end
|
97
|
+
|
98
|
+
def resolve_to_connectives(locs)
|
99
|
+
locs1 = []
|
100
|
+
until locs.empty?
|
101
|
+
if locs[1] == "to"
|
102
|
+
locs1 << @i18n.chain_to.sub(/%1/, locs[0]).sub(/%2/, locs[2])
|
103
|
+
locs.shift(3)
|
104
|
+
else locs1 << locs.shift
|
105
|
+
end
|
106
|
+
end
|
107
|
+
locs1
|
108
|
+
end
|
109
|
+
|
110
|
+
def eref_locality_stacks(refs, target, node)
|
111
|
+
ret = refs.each_with_index.with_object([]) do |(r, i), m|
|
112
|
+
added = eref_locality_stack(r, i, target, node)
|
113
|
+
added.empty? and next
|
114
|
+
added.each { |a| m << a }
|
115
|
+
next if i == refs.size - 1
|
116
|
+
|
117
|
+
m << if r&.next_element&.name == "localityStack"
|
118
|
+
r.next_element["connective"]
|
119
|
+
else locality_delimiter(r)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
ret.empty? ? ret : [", "] + ret
|
123
|
+
end
|
124
|
+
|
125
|
+
def eref_locality_stack(ref, idx, target, node)
|
126
|
+
ret = []
|
92
127
|
if ref.name == "localityStack"
|
93
128
|
ref.elements.each_with_index do |rr, j|
|
94
|
-
|
95
|
-
|
129
|
+
l = eref_localities0(rr, j, target, node) or next
|
130
|
+
|
131
|
+
ret << l
|
132
|
+
ret << locality_delimiter(rr) unless j == ref.elements.size - 1
|
96
133
|
end
|
97
|
-
else
|
134
|
+
else
|
135
|
+
l = eref_localities0(ref, idx, target, node) and ret << l
|
98
136
|
end
|
99
137
|
ret
|
100
138
|
end
|
101
139
|
|
102
|
-
def
|
103
|
-
|
140
|
+
def locality_delimiter(_loc)
|
141
|
+
", "
|
142
|
+
end
|
143
|
+
|
144
|
+
def eref_localities0(ref, _idx, target, node)
|
145
|
+
if ref["type"] == "whole" then @i18n.wholeoftext
|
104
146
|
else
|
105
|
-
eref_localities1(target, ref["type"],
|
106
|
-
ref
|
147
|
+
eref_localities1(target, ref["type"],
|
148
|
+
ref&.at(ns("./referenceFrom"))&.text,
|
149
|
+
ref&.at(ns("./referenceTo"))&.text, node, @lang)
|
107
150
|
end
|
108
151
|
end
|
109
152
|
|
110
153
|
# TODO: move to localization file
|
111
|
-
def eref_localities1_zh(_target, type, from, upto, node
|
112
|
-
ret = "
|
113
|
-
ret += "–#{upto
|
114
|
-
loc = (
|
154
|
+
def eref_localities1_zh(_target, type, from, upto, node)
|
155
|
+
ret = "第#{from}" if from
|
156
|
+
ret += "–#{upto}" if upto
|
157
|
+
loc = eref_locality_populate(type, node)
|
115
158
|
ret += " #{loc}" unless node["droploc"] == "true"
|
116
159
|
ret
|
117
160
|
end
|
118
161
|
|
119
162
|
# TODO: move to localization file
|
120
|
-
def eref_localities1(target, type, from, upto,
|
121
|
-
return
|
163
|
+
def eref_localities1(target, type, from, upto, node, lang = "en")
|
164
|
+
return nil if type == "anchor"
|
122
165
|
|
123
166
|
lang == "zh" and
|
124
|
-
return l10n(eref_localities1_zh(target, type, from, upto, node
|
125
|
-
ret =
|
126
|
-
ret +=
|
127
|
-
ret += "
|
128
|
-
ret += "–#{upto.text}" if upto
|
167
|
+
return l10n(eref_localities1_zh(target, type, from, upto, node))
|
168
|
+
ret = eref_locality_populate(type, node)
|
169
|
+
ret += " #{from}" if from
|
170
|
+
ret += "–#{upto}" if upto
|
129
171
|
l10n(ret)
|
130
172
|
end
|
131
173
|
|