metanorma 1.6.5 → 1.6.7
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/metanorma/collection_fileparse.rb +127 -142
- data/lib/metanorma/collection_fileprocess.rb +77 -0
- data/lib/metanorma/collection_manifest.rb +7 -3
- data/lib/metanorma/collection_render_utils.rb +61 -4
- data/lib/metanorma/collection_renderer.rb +4 -1
- data/lib/metanorma/compile_options.rb +3 -15
- data/lib/metanorma/files_lookup.rb +10 -15
- data/lib/metanorma/files_lookup_sectionsplit.rb +19 -5
- data/lib/metanorma/fontist_utils.rb +15 -6
- data/lib/metanorma/sectionsplit.rb +24 -10
- data/lib/metanorma/sectionsplit_links.rb +110 -37
- data/lib/metanorma/util.rb +9 -0
- data/lib/metanorma/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da01eef341e191e1e5feb7181afa5341ec66ff9b81792aace74bdcfc58a9690e
|
4
|
+
data.tar.gz: 36ab1f699a49b800cbeef67950e595f8306980b0406d8d0227d8570bf4581abc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c3a0595febda908e72b2e1075e8ac54955c00fbcbedb06a312f19f162c08de69f54ff0db365c76eece70743b0ffea5b68f67cce4e95e2b5c9261236b895e63a
|
7
|
+
data.tar.gz: a8065d8df08ade6c95ec184dd0d428c09aab5aadab74b0198280a95e9263c3794135b72139039cd7306168d26c8dc99daee8fc4ef869de4d3413b93c8929869d
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Metanorma
|
2
2
|
# XML collection renderer
|
3
3
|
class CollectionRenderer
|
4
|
-
# @param bib [Nokogiri::XML::Element]
|
5
|
-
# @param identifier [String]
|
6
4
|
def update_bibitem(bib, identifier)
|
7
5
|
docid = get_bibitem_docid(bib, identifier) or return
|
8
6
|
newbib = dup_bibitem(docid, bib)
|
@@ -14,77 +12,90 @@ module Metanorma
|
|
14
12
|
bib.replace(newbib)
|
15
13
|
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def docid_prefix(docid)
|
30
|
-
type = docid["type"]
|
31
|
-
type == "metanorma-collection" and type = nil
|
32
|
-
@c.decode(@isodoc
|
33
|
-
.docid_prefix(type, docid.children.to_xml)).gsub(/\s/, " ")
|
34
|
-
end
|
35
|
-
|
36
|
-
def dup_bibitem(docid, bib)
|
37
|
-
newbib = @files.get(docid, :bibdata).dup
|
38
|
-
newbib.name = "bibitem"
|
39
|
-
newbib["hidden"] = "true"
|
40
|
-
newbib&.at("./*[local-name() = 'ext']")&.remove
|
41
|
-
newbib["id"] = bib["id"]
|
42
|
-
newbib
|
43
|
-
end
|
44
|
-
|
45
|
-
# Resolves direct links to other files in collection
|
46
|
-
# (repo(current-metanorma-collection/x),
|
47
|
-
# and indirect links to other files in collection
|
48
|
-
# (bibitem[@type = 'internal'] pointing to a file anchor
|
49
|
-
# in another file in the collection)
|
15
|
+
# Resolves references to other files in the collection. Three routines:
|
16
|
+
# 1. Eref to a document that has been split into multiple documents
|
17
|
+
# (sectionsplit) are resolved to direct eref to the split document
|
18
|
+
# 2. Indirect erefs to a file anchor in an unknwon file in the collection
|
19
|
+
# (bibitem[@type = 'internal'] ) are resolved to direct eref to the
|
20
|
+
# containing document
|
21
|
+
# 3. Direct erefs to other files in collection
|
22
|
+
# (repo(current-metanorma-collection/x) are resolved to hyperlinks
|
50
23
|
# @param file [String] XML content
|
51
24
|
# @param identifier [String] docid
|
52
25
|
# @param internal_refs [Hash{String=>Hash{String=>String}] schema name to
|
53
26
|
# anchor to filename
|
54
27
|
# @return [String] XML content
|
55
|
-
def update_xrefs(file,
|
28
|
+
def update_xrefs(file, docid, internal_refs)
|
56
29
|
docxml = file.is_a?(String) ? Nokogiri::XML(file, &:huge) : file
|
57
30
|
supply_repo_ids(docxml)
|
58
|
-
update_indirect_refs_to_docs(docxml, internal_refs)
|
59
|
-
|
60
|
-
@
|
61
|
-
update_direct_refs_to_docs(docxml,
|
31
|
+
@nested or update_indirect_refs_to_docs(docxml, docid, internal_refs)
|
32
|
+
@files.add_document_suffix(docid, docxml)
|
33
|
+
@nested or update_sectionsplit_refs_to_docs(docxml, internal_refs)
|
34
|
+
update_direct_refs_to_docs(docxml, docid)
|
62
35
|
hide_refs(docxml)
|
63
|
-
@files.get(
|
64
|
-
svgmap_resolve(datauri_encode(docxml), ids)
|
36
|
+
@files.get(docid, :sectionsplit_output) and eref2link(docxml)
|
37
|
+
svgmap_resolve(datauri_encode(docxml), @files.get(docid, :ids))
|
65
38
|
docxml.to_xml
|
66
39
|
end
|
67
40
|
|
41
|
+
def update_sectionsplit_refs_to_docs(docxml, internal_refs)
|
42
|
+
Util::gather_citeases(docxml).each do |k, v|
|
43
|
+
(@files.get(k) && @files.get(k, :sectionsplit)) or next
|
44
|
+
opts = { key: @files.get(k, :indirect_key),
|
45
|
+
source_suffix: docxml.root["document_suffix"],
|
46
|
+
target_suffix: @files.get(k, :document_suffix) }
|
47
|
+
refs = v.each_with_object({}) do |eref, m|
|
48
|
+
update_sectionsplit_eref_to_doc(eref, internal_refs, m, opts)
|
49
|
+
end
|
50
|
+
add_hidden_bibliography(docxml, refs)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_sectionsplit_eref_to_doc(eref, internal_refs, doclist, opts)
|
55
|
+
a = eref.at(ns("./localityStack/locality[@type = 'anchor']/" \
|
56
|
+
"referenceFrom")) or return
|
57
|
+
doc = internal_refs[opts[:key]]["#{a.text}_#{opts[:target_suffix]}"]
|
58
|
+
bibitemid = Metanorma::Utils::to_ncname("#{doc}_#{opts[:source_suffix]}")
|
59
|
+
eref["bibitemid"] = bibitemid
|
60
|
+
doclist[bibitemid] ||= doc
|
61
|
+
doclist
|
62
|
+
end
|
63
|
+
|
64
|
+
def new_hidden_ref(xmldoc)
|
65
|
+
ins = xmldoc.at(ns("bibliography")) or
|
66
|
+
xmldoc.root << "<bibliography/>" and ins = xmldoc.at(ns("bibliography"))
|
67
|
+
ins.at(ns("./referenced[@hidden = 'true']")) or
|
68
|
+
ins.add_child("<references hidden='true' normative='false'/>").first
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_hidden_bibliography(xmldoc, refs)
|
72
|
+
ins = new_hidden_ref(xmldoc)
|
73
|
+
refs.each do |k, v|
|
74
|
+
_, url = @files.targetfile_id(v, {})
|
75
|
+
ins << <<~XML
|
76
|
+
<bibitem id="#{k}">
|
77
|
+
<docidentifier type="repository">current-metanorma-collection/#{v}</docidentifier>
|
78
|
+
<uri type='citation'>#{url}</uri>
|
79
|
+
</bibitem>
|
80
|
+
XML
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
68
84
|
def eref2link(docxml)
|
69
85
|
isodoc = IsoDoc::PresentationXMLConvert.new({})
|
70
86
|
isodoc.bibitem_lookup(docxml)
|
71
87
|
isodoc.eref2link(docxml)
|
72
88
|
end
|
73
89
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
def supply_repo_ids(docxml)
|
82
|
-
docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
|
83
|
-
b.at(ns("./docidentifier[@type = 'repository']")) and next
|
90
|
+
def supply_repo_ids(doc)
|
91
|
+
doc.xpath(
|
92
|
+
ns("//bibitem[not(ancestor::bibitem)]" \
|
93
|
+
"[not(./docidentifier[@type = 'repository'])]"),
|
94
|
+
).each do |b|
|
84
95
|
b.xpath(ns("./docidentifier")).each do |docid|
|
85
|
-
id = @isodoc
|
86
|
-
.docid_prefix(docid["type"], docid.children.to_xml)
|
96
|
+
id = @isodoc.docid_prefix(docid["type"], docid.children.to_xml)
|
87
97
|
@files.get(id) or next
|
98
|
+
@files.get(id, :indirect_key) and next # will resolve as indirect key
|
88
99
|
docid.next = "<docidentifier type='repository'>" \
|
89
100
|
"current-metanorma-collection/#{id}</docidentifier>"
|
90
101
|
end
|
@@ -103,12 +114,11 @@ module Metanorma
|
|
103
114
|
|
104
115
|
def svgmap_resolve1(eref, isodoc, _docxml, ids)
|
105
116
|
href = isodoc.eref_target(eref) or return
|
106
|
-
|
107
|
-
(href =~ /^#/ && !ids[href.sub(/^#/, "")])
|
108
|
-
|
117
|
+
href == "##{eref['bibitemid']}" ||
|
118
|
+
(href =~ /^#/ && !ids[href.sub(/^#/, "")]) and return
|
109
119
|
eref["target"] = href.strip
|
110
120
|
eref.name = "link"
|
111
|
-
eref
|
121
|
+
eref.elements&.remove
|
112
122
|
end
|
113
123
|
|
114
124
|
# repo(current-metanorma-collection/ISO 17301-1:2016)
|
@@ -117,60 +127,83 @@ module Metanorma
|
|
117
127
|
# Preferably with anchor, and is a job to realise dynamic lookup
|
118
128
|
# of localities.
|
119
129
|
def update_direct_refs_to_docs(docxml, identifier)
|
120
|
-
|
121
|
-
erefs = Util::gather_citeases(docxml)
|
122
|
-
erefs1 = Util::gather_bibitemids(docxml)
|
130
|
+
erefs, erefs1 = update_direct_refs_to_docs_prep(docxml)
|
123
131
|
docxml.xpath(ns("//bibitem")).each do |b|
|
124
132
|
docid = b.at(ns("./docidentifier[@type = 'repository']")) or next
|
125
|
-
|
126
|
-
erefs1[b["id"]]&.each { |x| strip_eref(x) }
|
127
|
-
next
|
128
|
-
end
|
133
|
+
strip_unresolved_repo_erefs(identifier, docid, erefs1, b) or next
|
129
134
|
update_bibitem(b, identifier)
|
130
135
|
docid = docid_to_citeas(b) or next
|
131
136
|
erefs[docid] and update_anchors(b, docid, erefs[docid])
|
132
137
|
end
|
133
138
|
end
|
134
139
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
def docid_to_citeas(bib)
|
141
|
-
docid = bib.at(ns("./docidentifier[@primary = 'true']")) ||
|
142
|
-
bib.at(ns("./docidentifier")) or return
|
143
|
-
docid_prefix(docid)
|
140
|
+
def update_direct_refs_to_docs_prep(docxml)
|
141
|
+
@ncnames = {}
|
142
|
+
[Util::gather_citeases(docxml), Util::gather_bibitemids(docxml)]
|
144
143
|
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
145
|
+
# strip erefs if they are repository erefs, but do not point to a document
|
146
|
+
# within the current collection. This can happen if a collection consists
|
147
|
+
# of many documents, but not all are included in the current collection.
|
148
|
+
# Do not do this if this is a sectionsplit collection or a nested manifest.
|
149
|
+
# Return false if bibitem is not to be further processed
|
150
|
+
def strip_unresolved_repo_erefs(_document_id, bib_docid, erefs, bibitem)
|
151
|
+
%r{^current-metanorma-collection/(?!Missing:)}.match?(bib_docid.text) and
|
152
|
+
return true
|
153
|
+
@nested and return false
|
154
|
+
erefs[bibitem["id"]]&.each { |x| x.parent and strip_eref(x) }
|
155
|
+
false
|
152
156
|
end
|
153
157
|
|
154
158
|
# Resolve erefs to a container of ids in another doc,
|
155
159
|
# to an anchor eref (direct link)
|
156
|
-
def update_indirect_refs_to_docs(docxml, internal_refs)
|
157
|
-
bibitems =
|
158
|
-
erefs = Util::gather_bibitemids(docxml)
|
160
|
+
def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs)
|
161
|
+
bibitems, erefs = update_indirect_refs_to_docs_prep(docxml)
|
159
162
|
internal_refs.each do |schema, ids|
|
160
163
|
ids.each do |id, file|
|
161
|
-
|
164
|
+
k = indirect_ref_key(schema, id, docxml)
|
165
|
+
update_indirect_refs_to_docs1(docxml, k,
|
162
166
|
file, bibitems, erefs)
|
163
167
|
end
|
164
168
|
end
|
165
169
|
end
|
166
170
|
|
171
|
+
def update_indirect_refs_to_docs_prep(docxml)
|
172
|
+
bibitems = Util::gather_bibitems(docxml)
|
173
|
+
erefs = Util::gather_bibitemids(docxml)
|
174
|
+
@updated_anchors = {}
|
175
|
+
[bibitems, erefs]
|
176
|
+
end
|
177
|
+
|
178
|
+
def indirect_ref_key(schema, id, docxml)
|
179
|
+
/^#{schema}_/.match?(id) and return id
|
180
|
+
ret = "#{schema}_#{id}"
|
181
|
+
(k = docxml.root["type"]) && k != schema and
|
182
|
+
ret = "#{ret}_#{docxml.root['document_suffix']}"
|
183
|
+
ret
|
184
|
+
end
|
185
|
+
|
167
186
|
def update_indirect_refs_to_docs1(_docxml, key, file, bibitems, erefs)
|
168
187
|
erefs[key]&.each do |e|
|
169
188
|
e["citeas"] = file
|
170
|
-
|
171
|
-
a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
|
189
|
+
update_indirect_refs_to_docs_anchor(e, file)
|
172
190
|
end
|
173
|
-
|
191
|
+
update_indirect_refs_to_docs_docid(bibitems[key], file)
|
192
|
+
end
|
193
|
+
|
194
|
+
def update_indirect_refs_to_docs_anchor(eref, file)
|
195
|
+
a = eref.at(ns(".//locality[@type = 'anchor']/referenceFrom")) or return
|
196
|
+
suffix = file
|
197
|
+
@files.get(file) && p = @files.get(file, :parentid) and
|
198
|
+
suffix = "#{p}_#{suffix}"
|
199
|
+
existing = a.text
|
200
|
+
anchor = Metanorma::Utils::to_ncname("#{existing}_#{suffix}")
|
201
|
+
@updated_anchors[existing] or a.children = anchor
|
202
|
+
@updated_anchors[anchor] = true
|
203
|
+
end
|
204
|
+
|
205
|
+
def update_indirect_refs_to_docs_docid(bibitem, file)
|
206
|
+
docid = bibitem&.at(ns("./docidentifier[@type = 'repository']")) or
|
174
207
|
return
|
175
208
|
docid.children = "current-metanorma-collection/#{file}"
|
176
209
|
docid.previous =
|
@@ -183,8 +216,11 @@ module Metanorma
|
|
183
216
|
erefs.each do |e|
|
184
217
|
if @files.get(docid) then update_anchor_loc(bib, e, docid)
|
185
218
|
else
|
186
|
-
|
187
|
-
|
219
|
+
msg = "<strong>** Unresolved reference to document #{docid} " \
|
220
|
+
"from eref</strong>"
|
221
|
+
e << msg
|
222
|
+
strip_eref(e)
|
223
|
+
@log&.add("Cross-References", e, msg)
|
188
224
|
end
|
189
225
|
end
|
190
226
|
end
|
@@ -195,10 +231,9 @@ module Metanorma
|
|
195
231
|
@ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
|
196
232
|
ref = loc.at("./xmlns:referenceFrom") or return
|
197
233
|
anchor = "#{ref.text}_#{@ncnames[docid]}"
|
198
|
-
|
234
|
+
@files.get(docid, :anchors).inject([]) do |m, (_, x)|
|
199
235
|
m += x.values
|
200
|
-
end.include?(anchor)
|
201
|
-
|
236
|
+
end.include?(anchor) or return
|
202
237
|
ref.content = anchor
|
203
238
|
end
|
204
239
|
|
@@ -213,55 +248,5 @@ module Metanorma
|
|
213
248
|
ins << "<locality type='anchor'><referenceFrom>#{anchor.sub(/^_/, '')}" \
|
214
249
|
"</referenceFrom></locality>"
|
215
250
|
end
|
216
|
-
|
217
|
-
# gather internal bibitem references
|
218
|
-
def gather_internal_refs
|
219
|
-
@files.keys.each_with_object({}) do |i, refs|
|
220
|
-
@files.get(i, :attachment) and next
|
221
|
-
file, = @files.targetfile_id(i, read: true)
|
222
|
-
gather_internal_refs1(file, refs)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def gather_internal_refs1(file, refs)
|
227
|
-
Nokogiri::XML(file, &:huge)
|
228
|
-
.xpath(ns("//bibitem[@type = 'internal']/" \
|
229
|
-
"docidentifier[@type = 'repository']")).each do |d|
|
230
|
-
a = d.text.split(%r{/}, 2)
|
231
|
-
a.size > 1 or next
|
232
|
-
refs[a[0]] ||= {}
|
233
|
-
refs[a[0]][a[1]] = true
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
# resolve file location for the target of each internal reference
|
238
|
-
def locate_internal_refs
|
239
|
-
refs = gather_internal_refs
|
240
|
-
@files.keys.reject { |k| @files.get(k, :attachment) }.each do |ident|
|
241
|
-
locate_internal_refs1(refs, ident, @isodoc.docid_prefix("", ident.dup))
|
242
|
-
end
|
243
|
-
refs.each do |schema, ids|
|
244
|
-
ids.each do |id, key|
|
245
|
-
key == true and refs[schema][id] = "Missing:#{schema}:#{id}"
|
246
|
-
end
|
247
|
-
end
|
248
|
-
refs
|
249
|
-
end
|
250
|
-
|
251
|
-
def locate_internal_refs1(refs, identifier, ident)
|
252
|
-
t = locate_internal_refs1_prep(ident)
|
253
|
-
refs.each do |schema, ids|
|
254
|
-
ids.keys.select { |id| t[id] }.each do |id|
|
255
|
-
t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and
|
256
|
-
refs[schema][id] = identifier
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
def locate_internal_refs1_prep(ident)
|
262
|
-
file, _filename = @files.targetfile_id(ident, read: true)
|
263
|
-
xml = Nokogiri::XML(file, &:huge)
|
264
|
-
xml.xpath("//*[@id]").each_with_object({}) { |i, x| x[i["id"]] = i }
|
265
|
-
end
|
266
251
|
end
|
267
252
|
end
|
@@ -75,5 +75,82 @@ module Metanorma
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
# gather internal bibitem references
|
80
|
+
def gather_internal_refs
|
81
|
+
@files.keys.each_with_object({}) do |i, refs|
|
82
|
+
@files.get(i, :attachment) and next
|
83
|
+
file, = @files.targetfile_id(i, read: true)
|
84
|
+
gather_internal_refs1(file, i, refs)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def gather_internal_refs1(file, ident, refs)
|
89
|
+
f = Nokogiri::XML(file, &:huge)
|
90
|
+
!@files.get(ident, :sectionsplit) and
|
91
|
+
gather_internal_refs_indirect(f, refs)
|
92
|
+
key = @files.get(ident, :indirect_key) and
|
93
|
+
gather_internal_refs_sectionsplit(f, ident, key, refs)
|
94
|
+
end
|
95
|
+
|
96
|
+
def gather_internal_refs_indirect(doc, refs)
|
97
|
+
doc.xpath(ns("//bibitem[@type = 'internal']/" \
|
98
|
+
"docidentifier[@type = 'repository']")).each do |d|
|
99
|
+
a = d.text.split(%r{/}, 2)
|
100
|
+
a.size > 1 or next
|
101
|
+
refs[a[0]] ||= {}
|
102
|
+
refs[a[0]][a[1]] = false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def gather_internal_refs_sectionsplit(_doc, ident, key, refs)
|
107
|
+
refs[key] ||= {}
|
108
|
+
@files.get(ident, :ids).each_key do |k|
|
109
|
+
refs[key][k] = false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def populate_internal_refs(refs)
|
114
|
+
@files.keys.reject do |k|
|
115
|
+
@files.get(k, :attachment) || @files.get(k, :sectionsplit)
|
116
|
+
end.each do |ident|
|
117
|
+
locate_internal_refs1(refs, ident, @isodoc.docid_prefix("", ident.dup))
|
118
|
+
end
|
119
|
+
refs
|
120
|
+
end
|
121
|
+
|
122
|
+
# resolve file location for the target of each internal reference
|
123
|
+
def locate_internal_refs
|
124
|
+
refs = populate_internal_refs(gather_internal_refs)
|
125
|
+
refs.each do |schema, ids|
|
126
|
+
ids.each do |id, key|
|
127
|
+
key and next
|
128
|
+
refs[schema][id] = "Missing:#{schema}:#{id}"
|
129
|
+
@log&.add("Cross-References", nil, refs[schema][id])
|
130
|
+
end
|
131
|
+
end
|
132
|
+
refs
|
133
|
+
end
|
134
|
+
|
135
|
+
def locate_internal_refs1(refs, identifier, ident)
|
136
|
+
t = locate_internal_refs1_prep(ident)
|
137
|
+
refs.each do |schema, ids|
|
138
|
+
ids.keys.select { |id| t[id] }.each do |id|
|
139
|
+
t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and
|
140
|
+
refs[schema][id] = identifier
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def locate_internal_refs1_prep(ident)
|
146
|
+
file, = @files.targetfile_id(ident, read: true)
|
147
|
+
xml = Nokogiri::XML(file, &:huge)
|
148
|
+
r = xml.root["document_suffix"]
|
149
|
+
xml.xpath("//*[@id]").each_with_object({}) do |i, x|
|
150
|
+
/^semantic_/.match?(i.name) and next
|
151
|
+
x[i["id"]] = i
|
152
|
+
r and x[i["id"].sub(/_#{r}$/, "")] = i
|
153
|
+
end
|
154
|
+
end
|
78
155
|
end
|
79
156
|
end
|
@@ -66,10 +66,9 @@ module Metanorma
|
|
66
66
|
# @return [Hash<String, Metanorma::Document>]
|
67
67
|
def documents(dir = "")
|
68
68
|
docs = @docref.each_with_object({}) do |dr, m|
|
69
|
-
|
70
|
-
|
69
|
+
dr["fileref"] or next m
|
71
70
|
m[dr["identifier"]] = Document.parse_file(
|
72
|
-
|
71
|
+
rel_path_resolve(dir, dr["fileref"]),
|
73
72
|
dr["attachment"], dr["identifier"], dr["index"]
|
74
73
|
)
|
75
74
|
m
|
@@ -77,6 +76,11 @@ module Metanorma
|
|
77
76
|
@manifest.reduce(docs) { |mem, mnf| mem.merge mnf.documents(dir) }
|
78
77
|
end
|
79
78
|
|
79
|
+
def rel_path_resolve(dir, path)
|
80
|
+
p = Pathname.new(path)
|
81
|
+
p.absolute? ? path : File.join(dir, path)
|
82
|
+
end
|
83
|
+
|
80
84
|
# @param builder [Nokogiri::XML::Builder]
|
81
85
|
def to_xml(builder)
|
82
86
|
builder.manifest do |b|
|
@@ -10,8 +10,62 @@ module Metanorma
|
|
10
10
|
path.basename.to_s.gsub(clean_regex, fallback_sym))
|
11
11
|
end
|
12
12
|
|
13
|
+
def dup_bibitem(docid, bib)
|
14
|
+
newbib = @files.get(docid, :bibdata).dup
|
15
|
+
newbib.name = "bibitem"
|
16
|
+
newbib["hidden"] = "true"
|
17
|
+
newbib&.at("./*[local-name() = 'ext']")&.remove
|
18
|
+
newbib["id"] = bib["id"]
|
19
|
+
newbib
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_bibitem_docid(bib, identifier)
|
23
|
+
# IDs for repo references are untyped by default
|
24
|
+
docid = bib.at(ns("./docidentifier[not(@type)]")) ||
|
25
|
+
bib.at(ns("./docidentifier"))
|
26
|
+
docid &&= docid_prefix(docid)
|
27
|
+
if @files.get(docid) then docid
|
28
|
+
else
|
29
|
+
fail_update_bibitem(docid, identifier)
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def hide_refs(docxml)
|
35
|
+
docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or " \
|
36
|
+
"@hidden = 'false'])]")).each do |f|
|
37
|
+
f["hidden"] = "true"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def strip_eref(eref)
|
42
|
+
eref.xpath(ns("./locality | ./localityStack")).each(&:remove)
|
43
|
+
eref.replace(eref.children)
|
44
|
+
end
|
45
|
+
|
46
|
+
def docid_to_citeas(bib)
|
47
|
+
docid = bib.at(ns("./docidentifier[@primary = 'true']")) ||
|
48
|
+
bib.at(ns("./docidentifier")) or return
|
49
|
+
docid_prefix(docid)
|
50
|
+
end
|
51
|
+
|
52
|
+
def collect_erefs(docxml)
|
53
|
+
docxml.xpath(ns("//eref"))
|
54
|
+
.each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
|
55
|
+
m[:citeas][i["citeas"]] = true
|
56
|
+
m[:bibitemid][i["bibitemid"]] = true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
13
60
|
private
|
14
61
|
|
62
|
+
def docid_prefix(docid)
|
63
|
+
type = docid["type"]
|
64
|
+
type == "metanorma-collection" and type = nil
|
65
|
+
@c.decode(@isodoc
|
66
|
+
.docid_prefix(type, docid.children.to_xml)).gsub(/\s/, " ")
|
67
|
+
end
|
68
|
+
|
15
69
|
def create_non_existing_directory(output_directory)
|
16
70
|
!File.exist?(output_directory) and
|
17
71
|
FileUtils.mkdir_p(output_directory)
|
@@ -56,8 +110,8 @@ module Metanorma
|
|
56
110
|
class PdfOptionsNode
|
57
111
|
def initialize(doctype, options)
|
58
112
|
docproc = Metanorma::Registry.instance.find_processor(doctype)
|
59
|
-
if FontistUtils.
|
60
|
-
@fonts_manifest = FontistUtils.location_manifest(docproc)
|
113
|
+
if FontistUtils.has_custom_fonts?(docproc, options, {})
|
114
|
+
@fonts_manifest = FontistUtils.location_manifest(docproc, options)
|
61
115
|
end
|
62
116
|
end
|
63
117
|
|
@@ -92,8 +146,11 @@ module Metanorma
|
|
92
146
|
"prefatory-content": isodoc_builder(@xml.at(ns("//prefatory-content"))),
|
93
147
|
"final-content": isodoc_builder(@xml.at(ns("//final-content"))),
|
94
148
|
doctitle: m.at(ns("../bibdata/title"))&.text,
|
95
|
-
docnumber: m.at(ns("../bibdata/docidentifier"))&.text
|
96
|
-
|
149
|
+
docnumber: m.at(ns("../bibdata/docidentifier"))&.text }.each do |k, v|
|
150
|
+
v and @isodoc.meta.set(
|
151
|
+
k, v
|
152
|
+
)
|
153
|
+
end
|
97
154
|
end
|
98
155
|
|
99
156
|
def isodoc_builder(node)
|
@@ -11,7 +11,7 @@ module Metanorma
|
|
11
11
|
class CollectionRenderer
|
12
12
|
FORMATS = %i[html xml doc pdf].freeze
|
13
13
|
|
14
|
-
attr_accessor :isodoc
|
14
|
+
attr_accessor :isodoc, :nested
|
15
15
|
attr_reader :xml, :compile, :compile_options, :documents
|
16
16
|
|
17
17
|
# This is only going to render the HTML collection
|
@@ -49,6 +49,9 @@ module Metanorma
|
|
49
49
|
@compile = Compile.new
|
50
50
|
@c = HTMLEntities.new
|
51
51
|
@files_to_delete = []
|
52
|
+
@nested = options[:nested] # if false, this is the root instance of Renderer
|
53
|
+
# if true, then this is not the last time Renderer will be run
|
54
|
+
# (e.g. this is sectionsplit)
|
52
55
|
|
53
56
|
# list of files in the collection
|
54
57
|
@files = Metanorma::FileLookup.new(folder, self)
|
@@ -61,19 +61,6 @@ module Metanorma
|
|
61
61
|
def font_install(opt)
|
62
62
|
FontistUtils.install_fonts(@processor, opt) unless @fontist_installed
|
63
63
|
@fontist_installed = true
|
64
|
-
!opt[:fonts] ||
|
65
|
-
opt[:fontlicenseagreement] == "continue-without-fonts" and return
|
66
|
-
@font_overrides ||= []
|
67
|
-
font_install_override(opt)
|
68
|
-
end
|
69
|
-
|
70
|
-
def font_install_override(opt)
|
71
|
-
confirm = opt[:fontlicenseagreement] == "no-install-fonts" ? "no" : "yes"
|
72
|
-
CSV.parse_line(opt[:fonts], col_sep: ";").map(&:strip).each do |f|
|
73
|
-
@font_overrides.include?(f) and next
|
74
|
-
Fontist::Font.install(f, confirmation: confirm)
|
75
|
-
@font_overrides << f
|
76
|
-
end
|
77
64
|
end
|
78
65
|
|
79
66
|
private
|
@@ -85,9 +72,10 @@ module Metanorma
|
|
85
72
|
%i(bare sectionsplit no_install_fonts baseassetpath aligncrosselements
|
86
73
|
tocfigures toctables tocrecommendations strict)
|
87
74
|
.each { |x| ret[x] ||= options[x] }
|
88
|
-
|
75
|
+
custom_fonts = FontistUtils.has_custom_fonts?(@processor, options, ret)
|
76
|
+
ext == :pdf && custom_fonts &&
|
89
77
|
ret[:mn2pdf] =
|
90
|
-
{ font_manifest: FontistUtils.location_manifest(@processor) }
|
78
|
+
{ font_manifest: FontistUtils.location_manifest(@processor, ret) }
|
91
79
|
ret
|
92
80
|
end
|
93
81
|
end
|
@@ -39,17 +39,16 @@ module Metanorma
|
|
39
39
|
@files[i] = entry
|
40
40
|
end
|
41
41
|
|
42
|
-
def bibdata_process(entry,
|
42
|
+
def bibdata_process(entry, ident)
|
43
43
|
if entry[:attachment]
|
44
|
-
entry[:bibdata] = Metanorma::Document
|
45
|
-
.attachment_bibitem(identifier).root
|
44
|
+
entry[:bibdata] = Metanorma::Document.attachment_bibitem(ident).root
|
46
45
|
else
|
47
46
|
file, _filename = targetfile(entry, read: true)
|
48
47
|
xml = Nokogiri::XML(file, &:huge)
|
49
|
-
add_document_suffix(
|
50
|
-
entry
|
51
|
-
|
52
|
-
|
48
|
+
add_document_suffix(ident, xml)
|
49
|
+
entry.merge!(anchors: read_anchors(xml), ids: read_ids(xml),
|
50
|
+
bibdata: xml.at(ns("//bibdata")),
|
51
|
+
document_suffix: xml.root["document_suffix"])
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
@@ -84,19 +83,15 @@ module Metanorma
|
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
87
|
-
def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
|
88
|
-
doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
|
89
|
-
elem.attributes[attribute_name].value =
|
90
|
-
"#{elem.attributes[attribute_name].value}_#{suffix}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
86
|
def add_document_suffix(identifier, doc)
|
95
87
|
document_suffix = Metanorma::Utils::to_ncname(identifier)
|
96
88
|
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
97
|
-
add_suffix_to_attributes(doc, document_suffix, tag_name,
|
89
|
+
Util::add_suffix_to_attributes(doc, document_suffix, tag_name,
|
90
|
+
attribute_name, @isodoc)
|
98
91
|
end
|
99
92
|
url_in_css_styles(doc, document_suffix)
|
93
|
+
doc.root["document_suffix"] ||= ""
|
94
|
+
doc.root["document_suffix"] += document_suffix
|
100
95
|
end
|
101
96
|
|
102
97
|
# update relative URLs, url(#...), in CSS in @style attrs (including SVG)
|
@@ -4,16 +4,30 @@ module Metanorma
|
|
4
4
|
def add_section_split
|
5
5
|
ret = @files.keys.each_with_object({}) do |k, m|
|
6
6
|
if @files[k][:sectionsplit] == "true" && !@files[k]["attachment"]
|
7
|
-
|
8
|
-
|
9
|
-
m["#{k}:index.html"] = add_section_split_cover(manifest, k)
|
10
|
-
@files_to_delete << m["#{k}:index.html"][:ref]
|
7
|
+
process_section_split_instance(k, m)
|
8
|
+
cleanup_section_split_instance(k, m)
|
11
9
|
end
|
12
10
|
m[k] = @files[k]
|
13
11
|
end
|
14
12
|
@files = ret
|
15
13
|
end
|
16
14
|
|
15
|
+
def process_section_split_instance(key, manifest)
|
16
|
+
s, sectionsplit_manifest = sectionsplit(@files[key][:ref],
|
17
|
+
@files[key][:out_path], key)
|
18
|
+
s.each_with_index do |f1, i|
|
19
|
+
add_section_split_instance(f1, manifest, key, i)
|
20
|
+
end
|
21
|
+
manifest["#{key}:index.html"] =
|
22
|
+
add_section_split_cover(sectionsplit_manifest, key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def cleanup_section_split_instance(key, manifest)
|
26
|
+
@files_to_delete << manifest["#{key}:index.html"][:ref]
|
27
|
+
#@files[key].delete(:ids).delete(:anchors)
|
28
|
+
@files[key][:indirect_key] = @sectionsplit.key
|
29
|
+
end
|
30
|
+
|
17
31
|
def add_section_split_cover(manifest, ident)
|
18
32
|
cover = @sectionsplit
|
19
33
|
.section_split_cover(manifest, @parent.dir_name_cleanse(ident),
|
@@ -57,7 +71,7 @@ module Metanorma
|
|
57
71
|
def sectionsplit(file, outfile, ident)
|
58
72
|
@sectionsplit = Sectionsplit
|
59
73
|
.new(input: file, base: outfile, dir: File.dirname(file),
|
60
|
-
output: outfile,
|
74
|
+
output: outfile, compile_opts: @parent.compile_options,
|
61
75
|
fileslookup: self, ident: ident, isodoc: @isodoc)
|
62
76
|
coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
|
63
77
|
xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
|
@@ -16,7 +16,7 @@ module Metanorma
|
|
16
16
|
Util.log("[fontist] Skip font installation because" \
|
17
17
|
" --no-install-fonts argument passed", :debug)
|
18
18
|
return false
|
19
|
-
elsif !
|
19
|
+
elsif !has_custom_fonts?(processor, options, options)
|
20
20
|
Util.log("[fontist] Skip font installation because "\
|
21
21
|
"fonts_manifest is missing", :debug)
|
22
22
|
return false
|
@@ -89,7 +89,8 @@ module Metanorma
|
|
89
89
|
return unless validate_install_fonts(processor, options)
|
90
90
|
|
91
91
|
@@updated_formulas_repo = false
|
92
|
-
manifest = processor.fonts_manifest
|
92
|
+
manifest = processor.fonts_manifest.dup
|
93
|
+
append_source_fonts(manifest, options)
|
93
94
|
agree_to_terms, can_without_fonts, no_progress = validate_options(options)
|
94
95
|
|
95
96
|
install_fonts_safe(
|
@@ -100,14 +101,22 @@ module Metanorma
|
|
100
101
|
)
|
101
102
|
end
|
102
103
|
|
103
|
-
def self.
|
104
|
+
def self.has_custom_fonts?(processor, options, source_attributes)
|
104
105
|
!options[:no_install_fonts] \
|
105
106
|
&& processor.respond_to?(:fonts_manifest) \
|
106
|
-
&& !processor.fonts_manifest.nil?
|
107
|
+
&& !processor.fonts_manifest.nil? \
|
108
|
+
|| source_attributes[:fonts]
|
107
109
|
end
|
108
110
|
|
109
|
-
def self.location_manifest(processor)
|
110
|
-
Fontist::Manifest::Locations.from_hash(
|
111
|
+
def self.location_manifest(processor, source_attributes)
|
112
|
+
Fontist::Manifest::Locations.from_hash(
|
113
|
+
append_source_fonts(processor.fonts_manifest.dup, source_attributes),
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.append_source_fonts(manifest, source_attributes)
|
118
|
+
source_attributes[:fonts]&.split(";")&.each { |f| manifest[f] = nil }
|
119
|
+
manifest
|
111
120
|
end
|
112
121
|
end
|
113
122
|
end
|
@@ -4,7 +4,7 @@ require_relative "sectionsplit_links"
|
|
4
4
|
|
5
5
|
module Metanorma
|
6
6
|
class Sectionsplit
|
7
|
-
attr_accessor :filecache
|
7
|
+
attr_accessor :filecache, :key
|
8
8
|
|
9
9
|
def initialize(opts)
|
10
10
|
@input_filename = opts[:input]
|
@@ -24,7 +24,7 @@ module Metanorma
|
|
24
24
|
|
25
25
|
def build_collection
|
26
26
|
collection_setup(@base, @dir)
|
27
|
-
files = sectionsplit #(@input_filename, @base, @dir, @compile_opts)
|
27
|
+
files = sectionsplit # (@input_filename, @base, @dir, @compile_opts)
|
28
28
|
input_xml = Nokogiri::XML(File.read(@input_filename,
|
29
29
|
encoding: "UTF-8"), &:huge)
|
30
30
|
collection_manifest(@base, files, input_xml, @xml, @dir).render(
|
@@ -50,7 +50,7 @@ module Metanorma
|
|
50
50
|
|
51
51
|
def coll_cover
|
52
52
|
<<~COVER
|
53
|
-
<html><head
|
53
|
+
<html><head><meta charset="UTF-8"/></head><body>
|
54
54
|
<h1>{{ doctitle }}</h1>
|
55
55
|
<h2>{{ docnumber }}</h2>
|
56
56
|
<nav>{{ navigation }}</nav>
|
@@ -71,7 +71,8 @@ module Metanorma
|
|
71
71
|
@key = xref_preprocess(xml, @fileslookup, @ident)
|
72
72
|
SPLITSECTIONS.each_with_object([]) do |n, ret|
|
73
73
|
conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
|
74
|
-
ret << sectionfile(xml, emptydoc(xml), "#{@base}.#{ret.size}", s,
|
74
|
+
ret << sectionfile(xml, emptydoc(xml), "#{@base}.#{ret.size}", s,
|
75
|
+
n[1])
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
@@ -107,17 +108,30 @@ module Metanorma
|
|
107
108
|
def sectionsplit_preprocess_semxml(file, filename)
|
108
109
|
xml = Nokogiri::XML(file, &:huge)
|
109
110
|
type = xml.root.name.sub("-standard", "").to_sym
|
110
|
-
|
111
|
-
xml1 =
|
112
|
-
#f.write(@isodoc.to_xml(svg_preprocess(xml)))
|
113
|
-
f.write(@isodoc.to_xml((xml)))
|
114
|
-
f
|
115
|
-
end
|
111
|
+
sectionsplit_update_xrefs(xml)
|
112
|
+
xml1 = sectionsplit_write_semxml(filename, xml)
|
116
113
|
@filecache ||= []
|
117
114
|
@filecache << xml1
|
118
115
|
[xml1.path, type]
|
119
116
|
end
|
120
117
|
|
118
|
+
def sectionsplit_update_xrefs(xml)
|
119
|
+
if c = @fileslookup&.parent
|
120
|
+
n = c.nested
|
121
|
+
c.nested = true # so unresolved erefs are not deleted
|
122
|
+
c.update_xrefs(xml, @ident, {})
|
123
|
+
c.nested = n
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def sectionsplit_write_semxml(filename, xml)
|
128
|
+
Tempfile.open([filename, ".xml"], encoding: "utf-8") do |f|
|
129
|
+
# f.write(@isodoc.to_xml(svg_preprocess(xml)))
|
130
|
+
f.write(@isodoc.to_xml(xml))
|
131
|
+
f
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
121
135
|
def emptydoc(xml)
|
122
136
|
out = xml.dup
|
123
137
|
out.xpath(
|
@@ -3,27 +3,29 @@ module Metanorma
|
|
3
3
|
def xref_preprocess(xml, _fileslookup, _identifier)
|
4
4
|
key = (0...8).map { rand(65..90).chr }.join # random string
|
5
5
|
xml.root["type"] = key # to force recognition of internal refs
|
6
|
+
# bookmarks etc as new id elements introduced in Presentation XML:
|
7
|
+
# add doc suffix
|
8
|
+
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
9
|
+
Util::add_suffix_to_attributes(xml, xml.root["document_suffix"],
|
10
|
+
tag_name, attribute_name, @isodoc)
|
11
|
+
end
|
6
12
|
key
|
7
13
|
end
|
8
14
|
|
9
15
|
def xref_process(section, xml, key)
|
10
16
|
svg_preprocess(section, Metanorma::Utils::to_ncname(@ident))
|
11
17
|
refs = eref_to_internal_eref(section, xml, key)
|
12
|
-
refs += xref_to_internal_eref(section, key)
|
18
|
+
refs += xref_to_internal_eref(section, xml, key)
|
13
19
|
ins = new_hidden_ref(section)
|
14
20
|
copied_refs = copy_repo_items_biblio(ins, section, xml)
|
15
|
-
insert_indirect_biblio(ins, refs - copied_refs, key)
|
21
|
+
insert_indirect_biblio(ins, refs - copied_refs, key, xml)
|
16
22
|
end
|
17
23
|
|
18
|
-
def svg_preprocess(xml,
|
24
|
+
def svg_preprocess(xml, doc_suffix)
|
25
|
+
suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
|
19
26
|
xml.xpath("//m:svg", "m" => "http://www.w3.org/2000/svg").each do |s|
|
20
27
|
m = svgmap_wrap(s)
|
21
|
-
s
|
22
|
-
/^#/.match? a["href"] or next
|
23
|
-
a["href"] = a["href"].sub(/^#/, "")
|
24
|
-
m << "<target href='#{a['href']}'>" \
|
25
|
-
"<xref target='#{a['href']}_#{document_suffix}'/></target>"
|
26
|
-
end
|
28
|
+
svg_xrefs(s, m, suffix)
|
27
29
|
end
|
28
30
|
xml
|
29
31
|
end
|
@@ -35,33 +37,75 @@ module Metanorma
|
|
35
37
|
svg.at("./ancestor::xmlns:svgmap")
|
36
38
|
end
|
37
39
|
|
40
|
+
def svg_xrefs(svg, svgmap, suffix)
|
41
|
+
svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
|
42
|
+
/^#/.match? a["href"] or next
|
43
|
+
a["href"] = a["href"].sub(/^#/, "")
|
44
|
+
svgmap << "<target href='#{a['href']}'>" \
|
45
|
+
"<xref target='#{a['href']}#{suffix}'/></target>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
38
49
|
def make_anchor(anchor)
|
39
50
|
"<localityStack><locality type='anchor'><referenceFrom>" \
|
40
51
|
"#{anchor}</referenceFrom></locality></localityStack>"
|
41
52
|
end
|
42
53
|
|
43
|
-
def xref_to_internal_eref(xml, key)
|
44
|
-
|
45
|
-
|
46
|
-
x
|
54
|
+
def xref_to_internal_eref(section, xml, key)
|
55
|
+
bibitems, indirect = xref_to_internal_eref_prep(section, xml)
|
56
|
+
section.xpath(ns("//xref")).each_with_object({}) do |x, m|
|
57
|
+
xref_prefix_key(x, key, indirect)
|
58
|
+
x["bibitemid"] = x["target"]
|
47
59
|
m[x["bibitemid"]] = true
|
48
|
-
x.
|
49
|
-
x["type"] = key
|
50
|
-
x.name = "eref"
|
60
|
+
xref_to_internal_eref_anchor(x, key, bibitems, xml.root["document_suffix"])
|
51
61
|
end.keys
|
52
62
|
end
|
53
63
|
|
64
|
+
def xref_to_internal_eref_prep(section, xml)
|
65
|
+
bibitems = Util::gather_bibitems(section)
|
66
|
+
indirect_bibitems = Util::gather_bibitems(xml)
|
67
|
+
.select { |_, v| indirect_bib?(v) }
|
68
|
+
[bibitems, indirect_bibitems]
|
69
|
+
end
|
70
|
+
|
71
|
+
def xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix)
|
72
|
+
t = xref["target"]
|
73
|
+
if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
|
74
|
+
m = %r{^([^/]+)}.match(d.text) and
|
75
|
+
t.sub!(%r(#{m[0]}_), "")
|
76
|
+
end
|
77
|
+
t.sub!(%r{^#{key}_}, "")
|
78
|
+
xref << make_anchor(t.sub(%r(_#{document_suffix}$), ""))
|
79
|
+
xref.delete("target")
|
80
|
+
xref.name = "eref"
|
81
|
+
end
|
82
|
+
|
83
|
+
def xref_prefix_key(xref, key, indirect)
|
84
|
+
if b = indirect[xref["target"]]
|
85
|
+
t = b.at(ns("./docidentifier[@type = 'repository']"))
|
86
|
+
xref["type"] = t.text.sub(%r{/.*$}, "")
|
87
|
+
else
|
88
|
+
xref["target"] = "#{key}_#{xref['target']}"
|
89
|
+
xref["type"] = key
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
54
93
|
def eref_to_internal_eref(section, xml, key)
|
55
|
-
bibitems =
|
56
|
-
bibitemids = Util::gather_bibitemids(section)
|
94
|
+
bibitems, bibitemids = eref_to_internal_eref_prep(section, xml)
|
57
95
|
eref_to_internal_eref_select(section, xml, bibitems)
|
58
96
|
.each_with_object([]) do |x, m|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
97
|
+
url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))
|
98
|
+
bibitemids[x]&.each do |e|
|
99
|
+
id = eref_to_internal_eref1(e, key, url) and m << id
|
100
|
+
end
|
63
101
|
end
|
64
|
-
|
102
|
+
end
|
103
|
+
|
104
|
+
def eref_to_internal_eref_prep(section, xml)
|
105
|
+
bibitems = Util::gather_bibitems(xml)
|
106
|
+
.delete_if { |_, v| internal_bib?(v) }
|
107
|
+
bibitemids = Util::gather_bibitemids(section)
|
108
|
+
[bibitems, bibitemids]
|
65
109
|
end
|
66
110
|
|
67
111
|
def eref_to_internal_eref1(elem, key, url)
|
@@ -80,11 +124,22 @@ module Metanorma
|
|
80
124
|
def eref_to_internal_eref_select(section, _xml, bibitems)
|
81
125
|
refs = Util::gather_bibitemids(section).keys
|
82
126
|
refs.uniq.reject do |x|
|
83
|
-
b = bibitems[x] and (b
|
84
|
-
b.at(ns("./docidentifier/@type = 'repository']")))
|
127
|
+
b = bibitems[x] and ( indirect_bib?(b) || internal_bib?(b) )
|
85
128
|
end
|
86
129
|
end
|
87
130
|
|
131
|
+
def internal_bib?(bibitem)
|
132
|
+
bibitem["type"] == "internal" ||
|
133
|
+
bibitem.at(ns("./docidentifier[@type = 'repository']"))
|
134
|
+
end
|
135
|
+
|
136
|
+
def indirect_bib?(bibitem)
|
137
|
+
a = bibitem.at(ns("./docidentifier[@type = 'repository']")) or
|
138
|
+
return false
|
139
|
+
%r{^current-metanorma-collection/}.match?(a.text) and return false
|
140
|
+
a.text.include?("/")
|
141
|
+
end
|
142
|
+
|
88
143
|
# from standoc
|
89
144
|
def new_hidden_ref(xmldoc)
|
90
145
|
ins = xmldoc.at("bibliography") or
|
@@ -96,21 +151,39 @@ module Metanorma
|
|
96
151
|
bibitems = Util::gather_bibitems(section)
|
97
152
|
xml.xpath(ns("//references/bibitem[docidentifier/@type = 'repository']"))
|
98
153
|
.each_with_object([]) do |b, m|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
154
|
+
bibitems[b["id"]] or next
|
155
|
+
# section.at("//*[@bibitemid = '#{b['id']}']") or next
|
156
|
+
ins << b.dup
|
157
|
+
m << b["id"]
|
158
|
+
end
|
104
159
|
end
|
105
160
|
|
106
|
-
def insert_indirect_biblio(ins, refs,
|
107
|
-
refs.
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
161
|
+
def insert_indirect_biblio(ins, refs, key, xml)
|
162
|
+
refs.empty? and return
|
163
|
+
internal_bibitems, external_bibitems = insert_indirect_biblio_prep(xml)
|
164
|
+
refs.compact.reject do |x|
|
165
|
+
#external_bibitems[x.sub(/^#{key}_/, "")]
|
166
|
+
end.each do |x|
|
167
|
+
ins << if b = internal_bibitems[x.sub(/^#{key}_/, "")]
|
168
|
+
b.dup.tap { |m| m["id"] = x }
|
169
|
+
else new_indirect_bibitem(x, key)
|
170
|
+
end
|
113
171
|
end
|
114
172
|
end
|
173
|
+
|
174
|
+
def insert_indirect_biblio_prep(xml)
|
175
|
+
bibitems = Util::gather_bibitems(xml)
|
176
|
+
internal_bibitems = bibitems.select { |_, v| internal_bib?(v) }
|
177
|
+
external_bibitems = bibitems.reject { |_, v| internal_bib?(v) }
|
178
|
+
[internal_bibitems, external_bibitems]
|
179
|
+
end
|
180
|
+
|
181
|
+
def new_indirect_bibitem(ident, prefix)
|
182
|
+
<<~BIBENTRY
|
183
|
+
<bibitem id="#{ident}" type="internal">
|
184
|
+
<docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
|
185
|
+
</bibitem>
|
186
|
+
BIBENTRY
|
187
|
+
end
|
115
188
|
end
|
116
189
|
end
|
data/lib/metanorma/util.rb
CHANGED
@@ -60,6 +60,15 @@ module Metanorma
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def self.add_suffix_to_attributes(doc, suffix, tag_name, attr_name, isodoc)
|
64
|
+
(suffix.nil? || suffix.empty?) and return
|
65
|
+
doc.xpath(isodoc.ns("//#{tag_name}[@#{attr_name}]")).each do |elem|
|
66
|
+
a = elem.attributes[attr_name].value
|
67
|
+
/_#{suffix}$/.match?(a) or
|
68
|
+
elem.attributes[attr_name].value = "#{a}_#{suffix}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
63
72
|
class DisambigFiles
|
64
73
|
def initialize
|
65
74
|
@seen_filenames = []
|
data/lib/metanorma/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metanorma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|