metanorma 1.6.4 → 1.6.6

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