metanorma 1.6.4 → 1.6.6
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 +129 -135
- data/lib/metanorma/collection_fileprocess.rb +77 -0
- data/lib/metanorma/collection_manifest.rb +8 -4
- data/lib/metanorma/collection_render_utils.rb +70 -13
- data/lib/metanorma/collection_renderer.rb +19 -8
- data/lib/metanorma/files_lookup.rb +21 -18
- data/lib/metanorma/files_lookup_sectionsplit.rb +21 -7
- data/lib/metanorma/processor.rb +7 -1
- data/lib/metanorma/sectionsplit.rb +24 -10
- data/lib/metanorma/sectionsplit_links.rb +110 -37
- data/lib/metanorma/util.rb +14 -1
- 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: c329757741717214253fd1ca5cf31cfaa1859c2c35647b5586970cb36595f1a3
|
4
|
+
data.tar.gz: c02920016d7294a37d9459e26d9d4e5c4291bc75a94181c1d139ad7f3a2e5215
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8fb74a61e67a308fb0523e4512bc4d2e0067d5dadb8cc736114e47781e9b638066a0e438cadeca16a1d210f785eeb544abd526a91483dfd81f6580b9fa051ff
|
7
|
+
data.tar.gz: de5e33cc1cfd207c6ad912759a5fc9e8cda3f576eaabd3e2c897662d299d298d37d9db052589990f5aa9f18a9ccd675d870212f0a07b987128d42eec198e5007
|
@@ -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
|
@@ -102,13 +113,12 @@ module Metanorma
|
|
102
113
|
end
|
103
114
|
|
104
115
|
def svgmap_resolve1(eref, isodoc, _docxml, ids)
|
105
|
-
href = isodoc.eref_target(eref)
|
106
|
-
|
107
|
-
(href =~ /^#/ && !ids[href.sub(/^#/, "")])
|
108
|
-
|
116
|
+
href = isodoc.eref_target(eref) or return
|
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,51 +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)
|
130
|
+
erefs, erefs1 = update_direct_refs_to_docs_prep(docxml)
|
122
131
|
docxml.xpath(ns("//bibitem")).each do |b|
|
123
|
-
docid = b.at(ns("./docidentifier[@type = 'repository']"))
|
124
|
-
(docid
|
132
|
+
docid = b.at(ns("./docidentifier[@type = 'repository']")) or next
|
133
|
+
strip_unresolved_repo_erefs(identifier, docid, erefs1, b) or next
|
125
134
|
update_bibitem(b, identifier)
|
126
135
|
docid = docid_to_citeas(b) or next
|
127
136
|
erefs[docid] and update_anchors(b, docid, erefs[docid])
|
128
137
|
end
|
129
138
|
end
|
130
139
|
|
131
|
-
def
|
132
|
-
|
133
|
-
|
134
|
-
docid_prefix(docid)
|
140
|
+
def update_direct_refs_to_docs_prep(docxml)
|
141
|
+
@ncnames = {}
|
142
|
+
[Util::gather_citeases(docxml), Util::gather_bibitemids(docxml)]
|
135
143
|
end
|
136
144
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
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
|
143
156
|
end
|
144
157
|
|
145
158
|
# Resolve erefs to a container of ids in another doc,
|
146
159
|
# to an anchor eref (direct link)
|
147
|
-
def update_indirect_refs_to_docs(docxml, internal_refs)
|
148
|
-
bibitems =
|
149
|
-
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)
|
150
162
|
internal_refs.each do |schema, ids|
|
151
163
|
ids.each do |id, file|
|
152
|
-
|
164
|
+
k = indirect_ref_key(schema, id, docxml)
|
165
|
+
update_indirect_refs_to_docs1(docxml, k,
|
153
166
|
file, bibitems, erefs)
|
154
167
|
end
|
155
168
|
end
|
156
169
|
end
|
157
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
|
+
|
158
186
|
def update_indirect_refs_to_docs1(_docxml, key, file, bibitems, erefs)
|
159
187
|
erefs[key]&.each do |e|
|
160
188
|
e["citeas"] = file
|
161
|
-
|
162
|
-
a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
|
189
|
+
update_indirect_refs_to_docs_anchor(e, file)
|
163
190
|
end
|
164
|
-
|
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
|
165
207
|
return
|
166
208
|
docid.children = "current-metanorma-collection/#{file}"
|
167
209
|
docid.previous =
|
@@ -174,8 +216,11 @@ module Metanorma
|
|
174
216
|
erefs.each do |e|
|
175
217
|
if @files.get(docid) then update_anchor_loc(bib, e, docid)
|
176
218
|
else
|
177
|
-
|
178
|
-
|
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)
|
179
224
|
end
|
180
225
|
end
|
181
226
|
end
|
@@ -186,10 +231,9 @@ module Metanorma
|
|
186
231
|
@ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
|
187
232
|
ref = loc.at("./xmlns:referenceFrom") or return
|
188
233
|
anchor = "#{ref.text}_#{@ncnames[docid]}"
|
189
|
-
|
234
|
+
@files.get(docid, :anchors).inject([]) do |m, (_, x)|
|
190
235
|
m += x.values
|
191
|
-
end.include?(anchor)
|
192
|
-
|
236
|
+
end.include?(anchor) or return
|
193
237
|
ref.content = anchor
|
194
238
|
end
|
195
239
|
|
@@ -204,55 +248,5 @@ module Metanorma
|
|
204
248
|
ins << "<locality type='anchor'><referenceFrom>#{anchor.sub(/^_/, '')}" \
|
205
249
|
"</referenceFrom></locality>"
|
206
250
|
end
|
207
|
-
|
208
|
-
# gather internal bibitem references
|
209
|
-
def gather_internal_refs
|
210
|
-
@files.keys.each_with_object({}) do |i, refs|
|
211
|
-
@files.get(i, :attachment) and next
|
212
|
-
file, = @files.targetfile_id(i, read: true)
|
213
|
-
gather_internal_refs1(file, refs)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def gather_internal_refs1(file, refs)
|
218
|
-
Nokogiri::XML(file, &:huge)
|
219
|
-
.xpath(ns("//bibitem[@type = 'internal']/" \
|
220
|
-
"docidentifier[@type = 'repository']")).each do |d|
|
221
|
-
a = d.text.split(%r{/}, 2)
|
222
|
-
a.size > 1 or next
|
223
|
-
refs[a[0]] ||= {}
|
224
|
-
refs[a[0]][a[1]] = true
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
# resolve file location for the target of each internal reference
|
229
|
-
def locate_internal_refs
|
230
|
-
refs = gather_internal_refs
|
231
|
-
@files.keys.reject { |k| @files.get(k, :attachment) }.each do |ident|
|
232
|
-
locate_internal_refs1(refs, ident, @isodoc.docid_prefix("", ident.dup))
|
233
|
-
end
|
234
|
-
refs.each do |schema, ids|
|
235
|
-
ids.each do |id, key|
|
236
|
-
key == true and refs[schema][id] = "Missing:#{schema}:#{id}"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
refs
|
240
|
-
end
|
241
|
-
|
242
|
-
def locate_internal_refs1(refs, identifier, ident)
|
243
|
-
t = locate_internal_refs1_prep(ident)
|
244
|
-
refs.each do |schema, ids|
|
245
|
-
ids.keys.select { |id| t[id] }.each do |id|
|
246
|
-
t[id].at("./ancestor-or-self::*[@type = '#{schema}']") and
|
247
|
-
refs[schema][id] = identifier
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def locate_internal_refs1_prep(ident)
|
253
|
-
file, _filename = @files.targetfile_id(ident, read: true)
|
254
|
-
xml = Nokogiri::XML(file, &:huge)
|
255
|
-
xml.xpath("//*[@id]").each_with_object({}) { |i, x| x[i["id"]] = i }
|
256
|
-
end
|
257
251
|
end
|
258
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|
|
@@ -118,7 +122,7 @@ module Metanorma
|
|
118
122
|
end
|
119
123
|
|
120
124
|
def docref_to_xml_attrs(elem, docref)
|
121
|
-
elem[:fileref] = @disambig.
|
125
|
+
elem[:fileref] = @disambig.strip_root(docref["fileref"])
|
122
126
|
%i(attachment sectionsplit).each do |i|
|
123
127
|
elem[i] = docref[i.to_s] if docref[i.to_s]
|
124
128
|
end
|
@@ -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)
|
@@ -81,25 +135,28 @@ module Metanorma
|
|
81
135
|
isodoc
|
82
136
|
end
|
83
137
|
|
138
|
+
# create the @meta class of isodoc, for populating Liquid,
|
139
|
+
# with "navigation" set to the index bar.
|
140
|
+
# extracted from the manifest
|
84
141
|
def isodoc_populate
|
85
|
-
# create the @meta class of isodoc, for populating Liquid,
|
86
|
-
# with "navigation" set to the index bar.
|
87
|
-
# extracted from the manifest
|
88
|
-
@isodoc.meta.set(:navigation, indexfile(@xml.at(ns("//manifest"))))
|
89
|
-
@isodoc.meta.set(:docrefs, liquid_docrefs)
|
90
|
-
@isodoc.meta.set(:"prefatory-content",
|
91
|
-
isodoc_builder(@isodoc,
|
92
|
-
@xml.at(ns("//prefatory-content"))))
|
93
|
-
@isodoc.meta.set(:"final-content",
|
94
|
-
isodoc_builder(isodoc,
|
95
|
-
@xml.at(ns("//final-content"))))
|
96
142
|
@isodoc.info(@xml, nil)
|
143
|
+
m = @xml.at(ns("//manifest"))
|
144
|
+
{ navigation: indexfile(m), nav_object: index_object(m),
|
145
|
+
docrefs: liquid_docrefs,
|
146
|
+
"prefatory-content": isodoc_builder(@xml.at(ns("//prefatory-content"))),
|
147
|
+
"final-content": isodoc_builder(@xml.at(ns("//final-content"))),
|
148
|
+
doctitle: m.at(ns("../bibdata/title"))&.text,
|
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
|
-
def isodoc_builder(
|
156
|
+
def isodoc_builder(node)
|
100
157
|
Nokogiri::HTML::Builder.new(encoding: "UTF-8") do |b|
|
101
158
|
b.div do |div|
|
102
|
-
node&.children&.each { |n| isodoc.parse(n, div) }
|
159
|
+
node&.children&.each { |n| @isodoc.parse(n, div) }
|
103
160
|
end
|
104
161
|
end.doc.root.to_html
|
105
162
|
end
|
@@ -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)
|
@@ -132,9 +135,7 @@ module Metanorma
|
|
132
135
|
# @param elm [Nokogiri::XML::Element]
|
133
136
|
# @return [String]
|
134
137
|
def indexfile_title(elm)
|
135
|
-
|
136
|
-
lbl = elm.at(ns("./title"))&.text
|
137
|
-
"#{lvl}#{lvl && lbl ? ': ' : ''}#{lbl}"
|
138
|
+
elm.at(ns("./title"))&.text
|
138
139
|
end
|
139
140
|
|
140
141
|
# uses the identifier to label documents; other attributes (title) can be
|
@@ -172,10 +173,6 @@ module Metanorma
|
|
172
173
|
end
|
173
174
|
|
174
175
|
# single level navigation list, with hierarchical nesting
|
175
|
-
# if multiple lists are needed as separate HTML fragments, multiple
|
176
|
-
# instances of this function will be needed,
|
177
|
-
# and associated to different variables in the call to @isodoc.metadata_init
|
178
|
-
# (including possibly an array of HTML fragments)
|
179
176
|
#
|
180
177
|
# @param elm [Nokogiri::XML::Element]
|
181
178
|
# @return [String] XML
|
@@ -191,6 +188,20 @@ module Metanorma
|
|
191
188
|
end.doc.root.to_html
|
192
189
|
end
|
193
190
|
|
191
|
+
# object to construct navigation out of in Liquid
|
192
|
+
def index_object(elm)
|
193
|
+
c = elm.xpath(ns("./manifest")).each_with_object([]) do |d, b|
|
194
|
+
b << index_object(d)
|
195
|
+
end
|
196
|
+
c.empty? and c = nil
|
197
|
+
r = Nokogiri::HTML::Builder.new do |b|
|
198
|
+
indexfile_docref(elm, b)
|
199
|
+
end
|
200
|
+
r &&= r.doc.root&.to_html&.gsub("\n", " ")
|
201
|
+
{ title: indexfile_title(elm),
|
202
|
+
docrefs: r, children: c }.compact
|
203
|
+
end
|
204
|
+
|
194
205
|
def liquid_docrefs
|
195
206
|
@xml.xpath(ns("//docref[@index = 'true']")).each_with_object([]) do |d, m|
|
196
207
|
ident = d.at(ns("./identifier")).children.to_xml
|
@@ -26,6 +26,7 @@ module Metanorma
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def read_files
|
29
|
+
@disambig = Util::DisambigFiles.new
|
29
30
|
@xml.xpath(ns("//docref")).each { |d| read_file(d) }
|
30
31
|
end
|
31
32
|
|
@@ -38,17 +39,16 @@ module Metanorma
|
|
38
39
|
@files[i] = entry
|
39
40
|
end
|
40
41
|
|
41
|
-
def bibdata_process(entry,
|
42
|
+
def bibdata_process(entry, ident)
|
42
43
|
if entry[:attachment]
|
43
|
-
entry[:bibdata] = Metanorma::Document
|
44
|
-
.attachment_bibitem(identifier).root
|
44
|
+
entry[:bibdata] = Metanorma::Document.attachment_bibitem(ident).root
|
45
45
|
else
|
46
46
|
file, _filename = targetfile(entry, read: true)
|
47
47
|
xml = Nokogiri::XML(file, &:huge)
|
48
|
-
add_document_suffix(
|
49
|
-
entry
|
50
|
-
|
51
|
-
|
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"])
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -65,30 +65,33 @@ module Metanorma
|
|
65
65
|
# identifier is the id with only spaces, no nbsp
|
66
66
|
def file_entry(ref, identifier)
|
67
67
|
out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
|
68
|
+
out1 = @disambig.source2dest_filename(out)
|
68
69
|
ret = if ref["fileref"]
|
69
70
|
{ type: "fileref", ref: @documents[identifier].file,
|
70
|
-
rel_path: ref["fileref"],
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
71
|
+
rel_path: ref["fileref"],
|
72
|
+
out_path: out1 } # @disambig.source2dest_filename(out) }
|
73
|
+
else { type: "id", ref: ref["id"] }
|
74
|
+
end
|
75
|
+
file_entry_copy(ref, ret)
|
76
76
|
ret.compact
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
79
|
+
def file_entry_copy(ref, ret)
|
80
|
+
%w(attachment sectionsplit index presentation-xml
|
81
|
+
bare-after-first).each do |s|
|
82
|
+
ret[s.gsub("-", "").to_sym] = ref[s] if ref[s]
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
def add_document_suffix(identifier, doc)
|
87
87
|
document_suffix = Metanorma::Utils::to_ncname(identifier)
|
88
88
|
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
89
|
-
add_suffix_to_attributes(doc, document_suffix, tag_name,
|
89
|
+
Util::add_suffix_to_attributes(doc, document_suffix, tag_name,
|
90
|
+
attribute_name, @isodoc)
|
90
91
|
end
|
91
92
|
url_in_css_styles(doc, document_suffix)
|
93
|
+
doc.root["document_suffix"] ||= ""
|
94
|
+
doc.root["document_suffix"] += document_suffix
|
92
95
|
end
|
93
96
|
|
94
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),
|
@@ -54,10 +68,10 @@ module Metanorma
|
|
54
68
|
[presfile, newkey, xml]
|
55
69
|
end
|
56
70
|
|
57
|
-
def sectionsplit(file, ident)
|
71
|
+
def sectionsplit(file, outfile, ident)
|
58
72
|
@sectionsplit = Sectionsplit
|
59
|
-
.new(input: file, base:
|
60
|
-
output:
|
73
|
+
.new(input: file, base: outfile, dir: File.dirname(file),
|
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)
|
data/lib/metanorma/processor.rb
CHANGED
@@ -18,7 +18,8 @@ module Metanorma
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def input_to_isodoc(file, filename, options = {})
|
21
|
-
Metanorma::Input::Asciidoc.new.process(file, filename,
|
21
|
+
Metanorma::Input::Asciidoc.new.process(file, filename,
|
22
|
+
@asciidoctor_backend, options)
|
22
23
|
end
|
23
24
|
|
24
25
|
# def input_to_isodoc(file, filename)
|
@@ -33,12 +34,17 @@ module Metanorma
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
def options_preprocess(options)
|
38
|
+
options[:output_formats] = output_formats
|
39
|
+
end
|
40
|
+
|
36
41
|
def output(isodoc_node, _inname, outname, _format, _options = {})
|
37
42
|
File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
|
38
43
|
end
|
39
44
|
|
40
45
|
def extract_options(file)
|
41
46
|
Metanorma::Input::Asciidoc.new.extract_options(file)
|
47
|
+
.merge(output_formats: output_formats)
|
42
48
|
end
|
43
49
|
|
44
50
|
def extract_metanorma_options(file)
|
@@ -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,13 +60,26 @@ 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 = []
|
66
75
|
end
|
67
76
|
|
77
|
+
def strip_root(name)
|
78
|
+
name.sub(%r{^(\./)?(\.\./)+}, "")
|
79
|
+
end
|
80
|
+
|
68
81
|
def source2dest_filename(name, disambig = true)
|
69
|
-
n = name
|
82
|
+
n = strip_root(name)
|
70
83
|
dir = File.dirname(n)
|
71
84
|
base = File.basename(n)
|
72
85
|
if disambig && @seen_filenames.include?(base)
|
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.6
|
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-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|