isodoc 2.0.2 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|