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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4bbd3fdfd37664da0a7f9e91cbecfcb0f7cdd49c004cf75eaa122c366ea6fba
4
- data.tar.gz: 6b61241e1010ed465995c23447b4828503495d8f4fb2366e64babe0ae6d0726e
3
+ metadata.gz: da01eef341e191e1e5feb7181afa5341ec66ff9b81792aace74bdcfc58a9690e
4
+ data.tar.gz: 36ab1f699a49b800cbeef67950e595f8306980b0406d8d0227d8570bf4581abc
5
5
  SHA512:
6
- metadata.gz: dc05aa1c9d8aec0e6d45b537e10a130f88e715116f0dd92820e73588ff5a6542a7f2f92099e504654d2ed21e4e95c4bd84c0b260e24f923720b38ae298455f33
7
- data.tar.gz: 870e182c05914d484180fd19360bfe1010cb9b57ed926926d76ba6cde3d9f2adbf2cb98e5d7e44702f2024cd51b52347524b9fb0ac28c0463d01b3d1dfc9d7b6
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
- def get_bibitem_docid(bib, identifier)
18
- # IDs for repo references are untyped by default
19
- docid = bib.at(ns("./docidentifier[not(@type)]")) ||
20
- bib.at(ns("./docidentifier"))
21
- docid &&= docid_prefix(docid)
22
- if @files.get(docid) then docid
23
- else
24
- fail_update_bibitem(docid, identifier)
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, identifier, internal_refs)
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
- ids = @files.get(identifier, :ids)
60
- @files.add_document_suffix(identifier, docxml)
61
- update_direct_refs_to_docs(docxml, identifier)
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(identifier, :sectionsplit_output) and eref2link(docxml)
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 hide_refs(docxml)
75
- docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or " \
76
- "@hidden = 'false'])]")).each do |f|
77
- f["hidden"] = "true"
78
- end
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
- return if href == "##{eref['bibitemid']}" ||
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&.elements&.remove
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
- @ncnames = {}
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
- unless %r{^current-metanorma-collection/}.match(docid.text)
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 strip_eref(eref)
136
- eref.xpath(ns("./locality | ./localityStack")).each(&:remove)
137
- eref.replace(eref.children)
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
- def collect_erefs(docxml)
147
- docxml.xpath(ns("//eref"))
148
- .each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
149
- m[:citeas][i["citeas"]] = true
150
- m[:bibitemid][i["bibitemid"]] = true
151
- end
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 = Util::gather_bibitems(docxml)
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
- update_indirect_refs_to_docs1(docxml, "#{schema}_#{id}",
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
- a = e.at(ns(".//locality[@type = 'anchor']/referenceFrom")) and
171
- a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
189
+ update_indirect_refs_to_docs_anchor(e, file)
172
190
  end
173
- docid = bibitems[key]&.at(ns("./docidentifier[@type = 'repository']")) or
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
- e << "<strong>** Unresolved reference to document #{docid} " \
187
- "from eref</strong>"
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
- return unless @files.get(docid, :anchors).inject([]) do |m, (_, x)|
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
- next m unless dr["fileref"]
70
-
69
+ dr["fileref"] or next m
71
70
  m[dr["identifier"]] = Document.parse_file(
72
- File.join(dir, dr["fileref"]),
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.has_fonts_manifest?(docproc, options)
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
- }.each { |k, v| v and @isodoc.meta.set(k, v) }
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
- ext == :pdf && FontistUtils.has_fonts_manifest?(@processor, options) and
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, identifier)
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(identifier, xml)
50
- entry[:anchors] = read_anchors(xml)
51
- entry[:ids] = read_ids(xml)
52
- entry[:bibdata] = xml.at(ns("//bibdata"))
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, attribute_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
- s, manifest = sectionsplit(@files[k][:ref], @files[k][:out_path], k)
8
- s.each_with_index { |f1, i| add_section_split_instance(f1, m, k, i) }
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, compile_options: @parent.compile_options,
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 !has_fonts_manifest?(processor)
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.has_fonts_manifest?(processor, options = {})
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(processor.fonts_manifest)
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/><body>
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, n[1])
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
- @fileslookup&.parent&.update_xrefs(xml, @ident, {})
111
- xml1 = Tempfile.open([filename, ".xml"], encoding: "utf-8") do |f|
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, document_suffix)
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.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
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
- xml.xpath(ns("//xref")).each_with_object({}) do |x, m|
45
- x["bibitemid"] = "#{key}_#{x['target']}"
46
- x << make_anchor(x["target"])
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.delete("target")
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 = Util::gather_bibitems(xml)
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
- url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))
60
- bibitemids[x]&.each do |e|
61
- id = eref_to_internal_eref1(e, key, url)
62
- id and m << id
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
- end
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["type"] == "internal" ||
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
- bibitems[b["id"]] or next
100
- # section.at("//*[@bibitemid = '#{b['id']}']") or next
101
- ins << b.dup
102
- m << b["id"]
103
- end
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, prefix)
107
- refs.each do |x|
108
- ins << <<~BIBENTRY
109
- <bibitem id="#{x}" type="internal">
110
- <docidentifier type="repository">#{x.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
111
- </bibitem>
112
- BIBENTRY
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
@@ -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 = []
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.6.5".freeze
2
+ VERSION = "1.6.7".freeze
3
3
  end
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.5
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-10-23 00:00:00.000000000 Z
11
+ date: 2023-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor