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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abbc191b2e898bbeeea46f7867bb9d25d44cfd7f9a0dd2c690fcbdb8383136fd
4
- data.tar.gz: a9e184662fcf25a575c278d604440b8215fd7b54b76f980a4cf4bfd5f8a1f543
3
+ metadata.gz: c329757741717214253fd1ca5cf31cfaa1859c2c35647b5586970cb36595f1a3
4
+ data.tar.gz: c02920016d7294a37d9459e26d9d4e5c4291bc75a94181c1d139ad7f3a2e5215
5
5
  SHA512:
6
- metadata.gz: bfc28efd7f7f48f0bfd7dfa630bf88f1186006022dc6d5f82f188a3749304bc73837c9e96dd9246655de67f2b1ee29d9525f49c2ba568e2116d4329bf3689bda
7
- data.tar.gz: 40bc185f4dbe9b4570349e22a15334a2e3fb089dfe3002ab43cb4a8ffa4afe4f2a3ae8357f80e61d585a57ab3b64e24dd5fb2700241dd6f1b958693214afdbc6
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
- 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
@@ -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
- return if href == "##{eref['bibitemid']}" ||
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&.elements&.remove
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
- @ncnames = {}
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 && %r{^current-metanorma-collection/}.match(docid.text)) or next
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 docid_to_citeas(bib)
132
- docid = bib.at(ns("./docidentifier[@primary = 'true']")) ||
133
- bib.at(ns("./docidentifier")) or return
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
- def collect_erefs(docxml)
138
- docxml.xpath(ns("//eref"))
139
- .each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
140
- m[:citeas][i["citeas"]] = true
141
- m[:bibitemid][i["bibitemid"]] = true
142
- 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
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 = Util::gather_bibitems(docxml)
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
- update_indirect_refs_to_docs1(docxml, "#{schema}_#{id}",
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
- a = e.at(ns(".//locality[@type = 'anchor']/referenceFrom")) and
162
- a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
189
+ update_indirect_refs_to_docs_anchor(e, file)
163
190
  end
164
- 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
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
- e << "<strong>** Unresolved reference to document #{docid} " \
178
- "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)
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
- return unless @files.get(docid, :anchors).inject([]) do |m, (_, x)|
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
- 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|
@@ -118,7 +122,7 @@ module Metanorma
118
122
  end
119
123
 
120
124
  def docref_to_xml_attrs(elem, docref)
121
- elem[:fileref] = @disambig.source2dest_filename(docref["fileref"])
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(isodoc, node)
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
- lvl = elm.at(ns("./level"))&.text&.capitalize
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, identifier)
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(identifier, xml)
49
- entry[:anchors] = read_anchors(xml)
50
- entry[:ids] = read_ids(xml)
51
- 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"])
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"], out_path: out }
71
- else { type: "id", ref: ref["id"] } end
72
- %w(attachment sectionsplit index presentation-xml
73
- bare-after-first).each do |s|
74
- ret[s.gsub("-", "").to_sym] = ref[s] if ref[s]
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 add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
80
- doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
81
- elem.attributes[attribute_name].value =
82
- "#{elem.attributes[attribute_name].value}_#{suffix}"
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, attribute_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
- s, manifest = sectionsplit(@files[k][:ref], 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),
@@ -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: File.basename(file), dir: File.dirname(file),
60
- output: file, compile_options: @parent.compile_options,
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)
@@ -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, @asciidoctor_backend, options)
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/><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,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.sub(%r{^(\./)?(\.\./)+}, "")
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)
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.6.4".freeze
2
+ VERSION = "1.6.6".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.4
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-10-09 00:00:00.000000000 Z
11
+ date: 2023-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor