metanorma 2.0.6 → 2.0.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: f27c1f604a729b827832e208b2ca5db54b8db3f5b3f69fe905e0f0ae87a08f53
4
- data.tar.gz: 781c8396a4c325a34c456ba935e40aba94d4062b283b475cf1bc381aa4ead712
3
+ metadata.gz: 6cf068df8203ed463672bcbef38ca1f5f1483ac2e08c9c37ee2236777dc86fad
4
+ data.tar.gz: 67c17ad923912cdf66f69b539691525a60751725e8f3d918fca5030d858661c7
5
5
  SHA512:
6
- metadata.gz: 8305b0f43fec6a78fc64b2d79fde688d829bacb3e4ce772d14a6c68ceaa71141a6948c4d7c1d6a358f21c4e86e601f44c4e6411a0e5c7c2522a0a8fed71856f1
7
- data.tar.gz: 6d9418c471d3966f00796dd0840cf33400188e93e61585b0b777cc31db70d020b92cd7f89f00754734a5331db29600ec4955b2b52bc86d62da3c11c98f71b45d
6
+ metadata.gz: b33588bb9dbd2f0e63c7438bf3739e3c46698be76566d4430658f12284c8221bd0c2532ae86318dcae0a4b1df90e7e270b12405e120bdd076ee18e4f85933820
7
+ data.tar.gz: 186204d57aa31ab72ea3454ea5e20b9d7b3506bcbe501c6e0c44312e22d26e83cfd1fd7b355ac3358b15cba24d234c55cbd2af369343974a34ac7cfef262c3a6
@@ -28,16 +28,20 @@ module Metanorma
28
28
  def initialize(**args)
29
29
  @file = args[:file]
30
30
  @dirname = File.expand_path(File.dirname(@file)) # feeds @manifest
31
- @documents = args[:documents] || {} # feeds initialize_directives
31
+ @documents = args[:documents] || {} # feeds initialize_directives, initialize_docs
32
32
  @bibdatas = args[:documents] || {}
33
33
  initialize_vars
34
34
  initialize_config(args[:config])
35
35
  initialize_directives
36
+ initialize_docs
37
+ validate_flavor(flavor)
38
+ end
39
+
40
+ def initialize_docs
36
41
  @documents.merge! @manifest.documents
37
42
  @bibdatas.merge! @manifest.documents
38
43
  @documents.transform_keys { |k| Util::key(k) }
39
44
  @bibdatas.transform_keys { |k| Util::key(k) }
40
- validate_flavor(flavor)
41
45
  end
42
46
 
43
47
  def initialize_vars
@@ -54,6 +58,8 @@ module Metanorma
54
58
  @final = config.final_content
55
59
  @manifest = ::Metanorma::Collection::Manifest
56
60
  .new(config.manifest, self, @dirname) # feeds initialize_directives
61
+ @format = config.format.map(&:to_sym)
62
+ @format&.empty? and @format = nil
57
63
  end
58
64
 
59
65
  def initialize_directives
@@ -88,7 +94,9 @@ module Metanorma
88
94
  end
89
95
 
90
96
  def render(opts)
91
- opts[:format].nil? || opts[:format].empty? and opts[:format] = [:html]
97
+ if opts[:format].nil? || opts[:format].empty?
98
+ opts[:format] = @format || [:html]
99
+ end
92
100
  opts[:log] = @log
93
101
  opts[:flavor] = @flavor
94
102
  ::Metanorma::Collection::Renderer.render self, opts
@@ -44,7 +44,7 @@ module Metanorma
44
44
 
45
45
  xml do
46
46
  root "entry"
47
- map_attribute "id", to: :id
47
+ map_attribute "target", to: :id
48
48
  map_attribute "attachment", to: :attachment
49
49
  map_attribute "sectionsplit", to: :sectionsplit
50
50
  map_attribute "index", to: :index
@@ -55,7 +55,7 @@ module Metanorma
55
55
  map_element "title", to: :title
56
56
  map_element "bibdata", using: { from: :bibdata_from_xml,
57
57
  to: :bibdata_to_xml }
58
- map_element "entry", to: :entry # using: { from: :entry_from_xml, to: :entry_to_xml }
58
+ map_element "entry", to: :entry
59
59
  end
60
60
 
61
61
  def entry_from_xml(model, node)
@@ -62,12 +62,24 @@ module Metanorma
62
62
  file, _filename = targetfile(entry, read: true)
63
63
  xml = Nokogiri::XML(file, &:huge)
64
64
  add_document_suffix(ident, xml)
65
- entry.merge!(anchors: read_anchors(xml), ids: read_ids(xml),
66
- bibdata: xml.at(ns("//bibdata")),
67
- document_suffix: xml.root["document_suffix"])
65
+ entry.merge!(bibdata_extract(xml))
68
66
  end
69
67
  end
70
68
 
69
+ def anchors_lookup(anchors)
70
+ anchors.values.each_with_object({}) do |v, m|
71
+ v.each_value { |v1| m[v1] = true }
72
+ end
73
+ end
74
+
75
+ def bibdata_extract(xml)
76
+ anchors = read_anchors(xml)
77
+ { anchors: anchors, anchors_lookup: anchors_lookup(anchors),
78
+ ids: read_ids(xml),
79
+ bibdata: xml.at(ns("//bibdata")),
80
+ document_suffix: xml.root["document_suffix"] }
81
+ end
82
+
71
83
  def bibitem_process(entry)
72
84
  entry[:bibitem] = entry[:bibdata].dup
73
85
  entry[:bibitem].name = "bibitem"
@@ -76,7 +88,7 @@ module Metanorma
76
88
  end
77
89
 
78
90
  # ref is the absolute source file address
79
- # rel_path is the relative source file address, relative to the YAML locaton
91
+ # rel_path is the relative source file address, relative to the YAML location
80
92
  # out_path is the destination file address, with any references outside
81
93
  # the working directory (../../...) truncated, and based on relative path
82
94
  # identifier is the id with only spaces, no nbsp
@@ -1,4 +1,5 @@
1
1
  require_relative "../sectionsplit/sectionsplit"
2
+ # require "concurrent-ruby"
2
3
 
3
4
  module Metanorma
4
5
  class Collection
@@ -16,13 +17,25 @@ module Metanorma
16
17
 
17
18
  def process_section_split_instance(key, manifest)
18
19
  s, sectionsplit_manifest = sectionsplit(key)
20
+ # section_split_instance_threads(s, manifest, key)
19
21
  s.each_with_index do |f1, i|
20
22
  add_section_split_instance(f1, manifest, key, i)
21
23
  end
22
24
  a = add_section_split_attachments(sectionsplit_manifest, key) and
23
25
  manifest["#{key}:attachments"] = a
24
- manifest["#{key}:index.html"] =
25
- add_section_split_cover(sectionsplit_manifest, key)
26
+ add_section_split_cover(manifest, sectionsplit_manifest, key)
27
+ end
28
+
29
+ def section_split_instance_threads(s, manifest, key)
30
+ @mutex = Mutex.new
31
+ pool = Concurrent::FixedThreadPool.new(4)
32
+ s.each_with_index do |f1, i|
33
+ pool.post do
34
+ add_section_split_instance(f1, manifest, key, i)
35
+ end
36
+ end
37
+ pool.shutdown
38
+ pool.wait_for_termination
26
39
  end
27
40
 
28
41
  def cleanup_section_split_instance(key, manifest)
@@ -31,24 +44,34 @@ module Metanorma
31
44
  @files[key][:indirect_key] = @sectionsplit.key
32
45
  end
33
46
 
34
- def add_section_split_cover(manifest, ident)
47
+ def add_section_split_cover(manifest, sectionsplit_manifest, ident)
35
48
  cover = @sectionsplit
36
- .section_split_cover(manifest, @parent.dir_name_cleanse(ident),
49
+ .section_split_cover(sectionsplit_manifest,
50
+ @parent.dir_name_cleanse(ident),
37
51
  one_doc_collection?)
38
52
  @files[ident][:out_path] = cover
39
- { attachment: true, index: false, out_path: cover,
40
- ref: File.join(File.dirname(manifest.file), cover) }
53
+ src = File.join(File.dirname(sectionsplit_manifest.file), cover)
54
+ m = { attachment: true, index: false, out_path: cover, ref: src }
55
+ manifest["#{ident}:index.html"] = m
56
+ one_doc_collection? and
57
+ add_cover_one_doc_coll(manifest, sectionsplit_manifest, ident, m)
58
+ end
59
+
60
+ def add_cover_one_doc_coll(manifest, sectionsplit_manifest, key, entry)
61
+ idx = File.join(File.dirname(sectionsplit_manifest.file), "index.html")
62
+ FileUtils.cp entry[:ref], idx
63
+ manifest["#{key}:index1.html"] =
64
+ entry.merge(out_path: "index.html", ref: idx)
41
65
  end
42
66
 
43
67
  def one_doc_collection?
44
- return false
45
68
  docs = 0
46
69
  @files.each_value do |v|
47
70
  v[:attachment] and next
48
71
  v[:presentationxml] and next
49
72
  docs += 1
50
73
  end
51
- docs > 1
74
+ docs <= 1
52
75
  end
53
76
 
54
77
  def add_section_split_attachments(manifest, ident)
@@ -62,15 +85,16 @@ module Metanorma
62
85
 
63
86
  def add_section_split_instance(file, manifest, key, idx)
64
87
  presfile, newkey, xml = add_section_split_instance_prep(file, key)
65
- manifest[newkey] =
66
- { parentid: key, presentationxml: true, type: "fileref",
67
- rel_path: file[:url], out_path: File.basename(file[:url]),
68
- anchors: read_anchors(xml), ids: read_ids(xml),
69
- sectionsplit_output: true,
70
- bibdata: @files[key][:bibdata], ref: presfile }
88
+ anchors = read_anchors(xml)
89
+ m = { parentid: key, presentationxml: true, type: "fileref",
90
+ rel_path: file[:url], out_path: File.basename(file[:url]),
91
+ anchors: anchors, anchors_lookup: anchors_lookup(anchors),
92
+ ids: read_ids(xml),
93
+ sectionsplit_output: true, indirect_key: @sectionsplit.key,
94
+ bibdata: @files[key][:bibdata], ref: presfile }
95
+ m[:bare] = true unless idx.zero?
96
+ manifest[newkey] = m
71
97
  @files_to_delete << file[:url]
72
- manifest[newkey][:indirect_key] = @sectionsplit.key
73
- manifest[newkey][:bare] = true unless idx.zero?
74
98
  end
75
99
 
76
100
  def add_section_split_instance_prep(file, key)
@@ -19,6 +19,7 @@ module Metanorma
19
19
  @nested || sso or
20
20
  Metanorma::Collection::XrefProcess::xref_process(xml, xml, nil, docid,
21
21
  @isodoc)
22
+ @ncnames = {}
22
23
  @nested or update_indirect_refs_to_docs(xml, docid, internal_refs)
23
24
  @files.add_document_suffix(docid, xml)
24
25
  @nested or update_sectionsplit_refs_to_docs(xml, internal_refs)
@@ -49,9 +50,11 @@ module Metanorma
49
50
  end
50
51
  end
51
52
 
53
+ ANCHOR_XPATH = "xmlns:locality[@type = 'anchor']/xmlns:referenceFrom"
54
+ .freeze
55
+
52
56
  def update_sectionsplit_eref_to_doc(eref, internal_refs, doclist, opts)
53
- a = eref.at(ns("./localityStack/locality[@type = 'anchor']/" \
54
- "referenceFrom")) or return
57
+ a = eref.at("./xmlns:localityStack/#{ANCHOR_XPATH}") or return
55
58
  doc = internal_refs[opts[:key]]["#{a.text}_#{opts[:target_suffix]}"]
56
59
  bibitemid = Metanorma::Utils::to_ncname("#{doc}_#{opts[:source_suffix]}")
57
60
  eref["bibitemid"] = bibitemid
@@ -59,12 +62,6 @@ module Metanorma
59
62
  doclist
60
63
  end
61
64
 
62
- def eref2link(docxml)
63
- isodoc = IsoDoc::PresentationXMLConvert.new({})
64
- isodoc.bibitem_lookup(docxml)
65
- isodoc.eref2link(docxml)
66
- end
67
-
68
65
  BIBITEM_NOT_REPO_XPATH = "//bibitem[not(ancestor::bibitem)]" \
69
66
  "[not(./docidentifier[@type = 'repository'])]".freeze
70
67
 
@@ -79,64 +76,37 @@ module Metanorma
79
76
  end
80
77
  end
81
78
 
82
- def svg_datauri(docxml, docid)
83
- rel = @files.get(docid, :rel_path)
84
- parent = @files.get(docid, :parentid) and
85
- rel = @files.get(parent, :rel_path)
86
- # if sectionsplit, use orig file dir
87
- dir = File.join(@dirname, File.dirname(rel))
88
- datauri_encode(docxml, dir)
89
- end
90
-
91
- def svgmap_resolve(docxml, docid)
92
- ids = @files.get(docid, :ids)
93
- docxml = svg_unnest(svg_datauri(docxml, docid))
94
- isodoc = IsoDoc::PresentationXMLConvert.new({})
95
- isodoc.bibitem_lookup(docxml)
96
- docxml.xpath(ns("//svgmap//eref")).each do |e|
97
- svgmap_resolve_eref(e, isodoc, docxml, ids)
98
- end
99
- Vectory::SvgMapping.new(docxml, "").call
100
- docxml.xpath(ns("//svgmap")).each { |s| isodoc.svgmap_extract(s) }
101
- end
102
-
103
- def svg_unnest(docxml)
104
- docxml.xpath(ns("//svgmap//image[.//*[name() = 'image']]")).each do |i|
105
- s = i.elements.detect { |e| e.name == "svg" } and
106
- i.replace(s)
107
- end
108
- docxml
109
- end
110
-
111
- def svgmap_resolve_eref(eref, isodoc, _docxml, ids)
112
- href = isodoc.eref_target(eref) or return
113
- href = href[:link]
114
- href == "##{eref['bibitemid']}" ||
115
- (href =~ /^#/ && !ids[href.sub(/^#/, "")]) and return
116
- eref["target"] = href.strip
117
- eref.name = "link"
118
- eref.elements&.remove
119
- end
120
-
121
79
  # repo(current-metanorma-collection/ISO 17301-1:2016)
122
80
  # replaced by bibdata of "ISO 17301-1:2016" in situ as bibitem.
123
81
  # Any erefs to that bibitem id are replaced with relative URL
124
82
  # Preferably with anchor, and is a job to realise dynamic lookup
125
83
  # of localities.
126
84
  def update_direct_refs_to_docs(docxml, identifier)
127
- erefs, erefs1 = update_direct_refs_to_docs_prep(docxml)
85
+ erefs, erefs_no_anchor, anchors, erefs1 =
86
+ update_direct_refs_to_docs_prep(docxml)
128
87
  docxml.xpath(ns("//bibitem")).each do |b|
129
88
  docid = b.at(ns("./docidentifier[@type = 'repository']")) or next
130
89
  strip_unresolved_repo_erefs(identifier, docid, erefs1, b) or next
131
90
  update_bibitem(b, identifier)
132
91
  docid = docid_to_citeas(b) or next
133
- erefs[docid] and update_anchors(b, docid, erefs[docid])
92
+ erefs[docid] and
93
+ update_anchors(b, docid, erefs[docid], erefs_no_anchor[docid],
94
+ anchors[docid])
134
95
  end
135
96
  end
136
97
 
98
+ # Hash(docid) of arrays
137
99
  def update_direct_refs_to_docs_prep(docxml)
138
- @ncnames = {}
139
- [Util::gather_citeases(docxml), Util::gather_bibitemids(docxml)]
100
+ erefs = Util::gather_citeases(docxml)
101
+ no_anchor = erefs.keys.each_with_object({}) { |k, m| m[k] = [] }
102
+ anchors = erefs.keys.each_with_object({}) { |k, m| m[k] = [] }
103
+ erefs.each do |k, v|
104
+ v.each do |e|
105
+ if loc = e.at(".//#{ANCHOR_XPATH}") then anchors[k] << loc
106
+ else no_anchor[k] << e end
107
+ end
108
+ end
109
+ [erefs, no_anchor, anchors, Util::gather_bibitemids(docxml)]
140
110
  end
141
111
 
142
112
  # strip erefs if they are repository erefs, but do not point to a document
@@ -155,56 +125,78 @@ module Metanorma
155
125
  # Resolve erefs to a container of ids in another doc,
156
126
  # to an anchor eref (direct link)
157
127
  def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs)
158
- bibitems, erefs = update_indirect_refs_to_docs_prep(docxml)
128
+ bib, erefs, doc_suffix, doc_type, f = update_indirect_refs_prep(docxml)
159
129
  internal_refs.each do |schema, ids|
160
- s = "#{schema}_"
130
+ add_suffix = doc_suffix && doc_type && doc_type != schema
161
131
  ids.each do |id, file|
162
- k = indirect_ref_key(s, schema, id, docxml)
163
- update_indirect_refs_to_docs1(docxml, k, file, bibitems, erefs)
132
+ f[file] ||= { url: @files.url?(file),
133
+ parentid: @files.get(file) && @files.get(file,
134
+ :parentid) }
135
+ k = indirect_ref_key(schema, id, doc_suffix, add_suffix)
136
+ update_indirect_refs_to_docs1(f[file], k, file, bib, erefs)
164
137
  end
165
138
  end
166
139
  end
167
140
 
168
- def update_indirect_refs_to_docs_prep(docxml)
141
+ def update_indirect_refs_prep(docxml)
169
142
  @updated_anchors = {}
170
- [Util::gather_bibitems(docxml), Util::gather_bibitemids(docxml)]
143
+ @indirect_keys = {}
144
+ [Util::gather_bibitems(docxml), Util::gather_bibitemids(docxml),
145
+ docxml.root["document_suffix"], docxml.root["type"], {}]
146
+ end
147
+
148
+ def indirect_ref_key(schema, id, doc_suffix, doc_type)
149
+ /^#{schema}_/.match?(id) and return id
150
+ key = [schema, id, doc_suffix, doc_type].join("::")
151
+ x = @indirect_keys[key] and return x
152
+ ret = "#{schema}_#{id}"
153
+ doc_suffix && doc_type && doc_type != schema and
154
+ ret = "#{ret}_#{doc_suffix}"
155
+ @indirect_keys[key] = ret
156
+ ret
171
157
  end
172
158
 
173
- def indirect_ref_key(schema_, schema, id, docxml)
174
- /^#{schema_}/.match?(id) and return id
175
- ret = schema_ + id
176
- suffix = docxml.root["document_suffix"] or return ret
177
- (k = docxml.root["type"]) && k != schema or return ret
178
- "#{ret}_#{suffix}"
159
+ def indirect_ref_key(schema, id, doc_suffix, add_suffix)
160
+ /^#{schema}_/.match?(id) and return id
161
+ #key = "#{schema}_#{id}"
162
+ x = @indirect_keys.dig(schema, id) and return x
163
+ @indirect_keys[schema] ||= {}
164
+ @indirect_keys[schema][id] = if add_suffix
165
+ "#{schema}_#{id}_#{doc_suffix}"
166
+ else
167
+ "#{schema}_#{id}"
168
+ end
179
169
  end
180
170
 
181
- #OLD
182
- def indirect_ref_key1(schema, id, docxml)
171
+ def indirect_ref_keyx(schema, id, doc_suffix, doc_type)
183
172
  /^#{schema}_/.match?(id) and return id
184
173
  ret = "#{schema}_#{id}"
185
- suffix = docxml.root["document_suffix"]
186
- (k = docxml.root["type"]) && k != schema && suffix and
187
- ret = "#{ret}_#{suffix}"
174
+ doc_suffix && doc_type && doc_type != schema and
175
+ ret = "#{ret}_#{doc_suffix}"
188
176
  ret
189
177
  end
190
178
 
191
- def update_indirect_refs_to_docs1(_docxml, key, file, bibitems, erefs)
179
+ def update_indirect_refs_to_docs1(filec, key, file, bibitems, erefs)
192
180
  erefs[key]&.each do |e|
193
181
  e["citeas"] = file
194
- update_indirect_refs_to_docs_anchor(e, file)
182
+ update_indirect_refs_to_docs_anchor(e, file, filec[:url],
183
+ filec[:parentid])
195
184
  end
196
185
  update_indirect_refs_to_docs_docid(bibitems[key], file)
197
186
  end
198
187
 
199
- def update_indirect_refs_to_docs_anchor(eref, file)
200
- a = eref.at(ns(".//locality[@type = 'anchor']/referenceFrom")) or return
201
- suffix = file
202
- @files.get(file) && p = @files.get(file, :parentid) and
203
- suffix = "#{p}_#{suffix}"
188
+ def update_indirect_refs_to_docs_anchor(eref, file, url, parentid)
189
+ a = eref.at(".//#{ANCHOR_XPATH}") or return
190
+ parentid and file = "#{parentid}_#{file}"
204
191
  existing = a.text
205
- anchor = existing
206
- @files.url?(file) or
207
- anchor = Metanorma::Utils::to_ncname("#{anchor}_#{suffix}")
192
+ anchor = if url then existing
193
+ else
194
+ #suffix_anchor_indirect(existing, suffix)
195
+ #k = "#{existing}_#{file}"
196
+ #@ncnames[k] ||= Metanorma::Utils::to_ncname(k)
197
+ @indirect_keys[existing] ||= {}
198
+ @indirect_keys[existing][file] ||= Metanorma::Utils::to_ncname("#{existing}_#{file}")
199
+ end
208
200
  @updated_anchors[existing] or a.children = anchor
209
201
  @updated_anchors[anchor] = true
210
202
  end
@@ -216,55 +208,36 @@ module Metanorma
216
208
  "<docidentifier type='metanorma-collection'>#{file}</docidentifier>"
217
209
  end
218
210
 
219
- # update crossrefences to other documents, to include
220
- # disambiguating document suffix on id
221
- def update_anchors(bib, docid, erefs)
222
- erefs.each do |e|
223
- if @files.get(docid) then update_anchor_loc(bib, e, docid)
224
- else
225
- msg = "<strong>** Unresolved reference to document #{docid} " \
226
- "from eref</strong>"
227
- e << msg
228
- strip_eref(e)
229
- @log&.add("Cross-References", e, msg)
230
- end
211
+ # bottleneck
212
+ def update_anchors(bib, docid, erefs, erefs_no_anchor, erefs_anchors)
213
+ @files.get(docid) or error_anchor(erefs, docid)
214
+ has_anchors, url, ncn_docid = update_anchors_prep(docid)
215
+ erefs_no_anchor.each do |e|
216
+ update_anchor_create_loc(bib, e, docid)
217
+ end
218
+ !url && has_anchors or return
219
+ erefs_anchors.each do |e|
220
+ update_anchors1(docid, ncn_docid, e)
231
221
  end
232
222
  end
233
223
 
234
- def update_anchor_loc(bib, eref, docid)
235
- loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
236
- return update_anchor_create_loc(bib, eref, docid)
237
- a = @files.get(docid, :anchors) or return
238
- ref = loc.elements&.first or return
239
- anchor = suffix_anchor(ref.text, docid)
240
- a.values.detect { |x| x.value?(anchor) } or return
241
- ref.content = anchor
242
- end
243
-
244
- #OLD
245
- def update_anchor_loc1(bib, eref, docid)
246
- loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
247
- return update_anchor_create_loc(bib, eref, docid)
248
- ref = loc.at("./xmlns:referenceFrom") or return
249
- anchor = suffix_anchor(ref, docid)
250
- a = @files.get(docid, :anchors) or return
251
- a.inject([]) { |m, (_, x)| m + x.values }
252
- .include?(anchor) or return
253
- ref.content = anchor
224
+ def update_anchors1(docid, ncn_docid, anchor)
225
+ @concat_anchors[anchor.text] ||= "#{ncn_docid}_#{anchor.text}"
226
+ if @files.get(docid).dig(:anchors_lookup, @concat_anchors[anchor.text])
227
+ anchor.content = @concat_anchors[anchor.text]
228
+ end
254
229
  end
255
230
 
256
- def suffix_anchor(ref, docid)
257
- @ncnames[docid] ||= "#{Metanorma::Utils::to_ncname(docid)}_"
258
- @files.url?(docid) or return ref
259
- @ncnames[docid] + ref
231
+ def update_anchors_prep(docid)
232
+ @concat_anchors = {}
233
+ [@files.get(docid)&.key?(:anchors_lookup), @files.url?(docid),
234
+ Metanorma::Utils::to_ncname(docid)]
260
235
  end
261
236
 
262
- #OLD
263
- def suffix_anchor1(ref, docid)
264
- @ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
265
- anchor = ref.text
266
- @files.url?(docid) or anchor = "#{@ncnames[docid]}_#{anchor}"
267
- anchor
237
+ # encode both prefix and suffix to NCName
238
+ def suffix_anchor_indirect(prefix, suffix)
239
+ k = "#{prefix}_#{suffix}"
240
+ @ncnames[k] ||= Metanorma::Utils::to_ncname(k)
268
241
  end
269
242
 
270
243
  # if there is a crossref to another document, with no anchor, retrieve the
@@ -276,7 +249,7 @@ module Metanorma
276
249
  ref = ins.at(ns("./locality/referenceFrom"))&.text
277
250
  a = @files.get(docid, :anchors).dig(type, ref) or return
278
251
  ins << "<locality type='anchor'><referenceFrom>#{a.sub(/^_/, '')}" \
279
- "</referenceFrom></locality>"
252
+ "</referenceFrom></locality>"
280
253
  end
281
254
  end
282
255
  end
@@ -8,6 +8,7 @@ require_relative "../multilingual/multilingual"
8
8
  require_relative "utils"
9
9
  require_relative "render_word"
10
10
  require_relative "navigation"
11
+ require_relative "svg"
11
12
 
12
13
  module Metanorma
13
14
  class Collection
@@ -74,6 +75,7 @@ module Metanorma
74
75
 
75
76
  def flush_files
76
77
  warn "\n\n\n\n\nDone: #{DateTime.now.strftime('%H:%M:%S')}"
78
+ warn "\nFiles to delete:\n"
77
79
  warn @files.files_to_delete
78
80
  @files.files_to_delete.each { |f| FileUtils.rm_f(f) }
79
81
  @files_to_delete.each { |f| FileUtils.rm_f(f) }
@@ -0,0 +1,44 @@
1
+ module Metanorma
2
+ class Collection
3
+ class Renderer
4
+ def svg_datauri(docxml, docid)
5
+ rel = @files.get(docid, :rel_path)
6
+ parent = @files.get(docid, :parentid) and
7
+ rel = @files.get(parent, :rel_path)
8
+ # if sectionsplit, use orig file dir
9
+ dir = File.join(@dirname, File.dirname(rel))
10
+ datauri_encode(docxml, dir)
11
+ end
12
+
13
+ def svgmap_resolve(docxml, docid)
14
+ ids = @files.get(docid, :ids)
15
+ docxml = svg_unnest(svg_datauri(docxml, docid))
16
+ isodoc = IsoDoc::PresentationXMLConvert.new({})
17
+ isodoc.bibitem_lookup(docxml)
18
+ docxml.xpath(ns("//svgmap//eref")).each do |e|
19
+ svgmap_resolve_eref(e, isodoc, docxml, ids)
20
+ end
21
+ Vectory::SvgMapping.new(docxml, "").call
22
+ docxml.xpath(ns("//svgmap")).each { |s| isodoc.svgmap_extract(s) }
23
+ end
24
+
25
+ def svg_unnest(docxml)
26
+ docxml.xpath(ns("//svgmap//image[.//*[name() = 'image']]")).each do |i|
27
+ s = i.elements.detect { |e| e.name == "svg" } and
28
+ i.replace(s)
29
+ end
30
+ docxml
31
+ end
32
+
33
+ def svgmap_resolve_eref(eref, isodoc, _docxml, ids)
34
+ href = isodoc.eref_target(eref) or return
35
+ href = href[:link]
36
+ href == "##{eref['bibitemid']}" ||
37
+ (href =~ /^#/ && !ids[href.sub(/^#/, "")]) and return
38
+ eref["target"] = href.strip
39
+ eref.name = "link"
40
+ eref.elements&.remove
41
+ end
42
+ end
43
+ end
44
+ end
@@ -203,6 +203,22 @@ module Metanorma
203
203
  end.doc.root.to_html
204
204
  end
205
205
 
206
+ def eref2link(docxml)
207
+ isodoc = IsoDoc::PresentationXMLConvert.new({})
208
+ isodoc.bibitem_lookup(docxml)
209
+ isodoc.eref2link(docxml)
210
+ end
211
+
212
+ def error_anchor(erefs, docid)
213
+ erefs.each do |e|
214
+ msg = "<strong>** Unresolved reference to document #{docid} " \
215
+ "from eref</strong>"
216
+ e << msg
217
+ strip_eref(e)
218
+ @log&.add("Cross-References", e, msg)
219
+ end
220
+ end
221
+
206
222
  def ns(xpath)
207
223
  @isodoc.ns(xpath)
208
224
  end
@@ -76,22 +76,22 @@ module Metanorma
76
76
  File.basename(ret)
77
77
  end
78
78
 
79
- def section_split_cover(col, ident, _one_doc_coll)
79
+ def section_split_cover(col, ident, one_doc_coll)
80
80
  dir = File.dirname(col.file)
81
81
  collection_setup(nil, dir)
82
82
  r = ::Metanorma::Collection::Renderer
83
83
  .new(col, dir, output_folder: "#{ident}_collection",
84
- format: %i(html), coverpage: File.join(dir, "cover.html"))
84
+ format: %i(html),
85
+ coverpage: File.join(dir, "cover.html"))
85
86
  r.coverpage
86
- section_split_cover1(ident, r, dir, _one_doc_coll)
87
+ section_split_cover1(ident, r, dir, one_doc_coll)
87
88
  end
88
89
 
89
90
  def section_split_cover1(ident, renderer, dir, _one_doc_coll)
90
- # filename = one_doc_coll ? "#{ident}_index.html" : "index.html"
91
91
  filename = File.basename("#{ident}_index.html")
92
92
  # ident can be a directory with YAML indirection
93
- FileUtils.mv File.join(renderer.outdir, "index.html"),
94
- File.join(dir, filename)
93
+ dest = File.join(dir, filename)
94
+ FileUtils.mv File.join(renderer.outdir, "index.html"), dest
95
95
  FileUtils.rm_rf renderer.outdir
96
96
  filename
97
97
  end
@@ -2,6 +2,7 @@ require "yaml"
2
2
  require_relative "../../util/util"
3
3
  require_relative "../xrefprocess/xrefprocess"
4
4
  require_relative "collection"
5
+ require "concurrent-ruby"
5
6
 
6
7
  module Metanorma
7
8
  class Collection
@@ -35,12 +36,32 @@ module Metanorma
35
36
  def sectionsplit
36
37
  xml = sectionsplit_prep(File.read(@input_filename), @base, @dir)
37
38
  @key = Metanorma::Collection::XrefProcess::xref_preprocess(xml, @isodoc)
38
- SPLITSECTIONS.each_with_object([]) do |n, ret|
39
+ empty = empty_doc(xml)
40
+ empty1 = empty_attachments(empty)
41
+ @mutex = Mutex.new
42
+ @pool = Concurrent::FixedThreadPool.new(4)
43
+ sectionsplit1(xml, empty, empty1, 0)
44
+ end
45
+
46
+ def sectionsplit1(xml, empty, empty1, idx)
47
+ ret = SPLITSECTIONS.each_with_object([]) do |n, m|
39
48
  conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
40
- ret << sectionfile(xml, emptydoc(xml, ret.size),
41
- "#{@base}.#{ret.size}", s, n[1])
49
+ sectionsplit2(xml, idx.zero? ? empty : empty1, s, n[1],
50
+ { acc: m, idx: idx })
51
+ idx += 1
42
52
  end
43
53
  end
54
+ @pool.shutdown
55
+ @pool.wait_for_termination
56
+ ret
57
+ end
58
+
59
+ def sectionsplit2(xml, empty, chunks, parentnode, opt)
60
+ @pool.post do
61
+ a = sectionfile(xml, empty, "#{@base}.#{opt[:idx]}", chunks,
62
+ parentnode)
63
+ @mutex.synchronize { opt[:acc] << a }
64
+ end
44
65
  end
45
66
 
46
67
  def block?(node)
@@ -108,7 +129,25 @@ module Metanorma
108
129
  "//indexsect | //colophon"),
109
130
  ).each(&:remove)
110
131
  ordinal.zero? or out.xpath(ns("//metanorma-ext//attachment | " \
111
- "//semantic__metanorma-ext//semantic__attachment"))
132
+ "//semantic__metanorma-ext//semantic__attachment"))
133
+ .each(&:remove) # keep only one copy of attachments
134
+ out
135
+ end
136
+
137
+ def empty_doc(xml)
138
+ out = xml.dup
139
+ out.xpath(
140
+ ns("//preface | //sections | //annex | //bibliography/clause | " \
141
+ "//bibliography/references[not(@hidden = 'true')] | " \
142
+ "//indexsect | //colophon"),
143
+ ).each(&:remove)
144
+ out
145
+ end
146
+
147
+ def empty_attachments(xml)
148
+ out = xml.dup
149
+ out.xpath(ns("//metanorma-ext//attachment | " \
150
+ "//semantic__metanorma-ext//semantic__attachment"))
112
151
  .each(&:remove) # keep only one copy of attachments
113
152
  out
114
153
  end
@@ -126,7 +165,9 @@ module Metanorma
126
165
  @ident, @isodoc)
127
166
  truncate_semxml(out, chunks)
128
167
  outname = "#{file}.xml"
129
- File.open(File.join(@splitdir, outname), "w:UTF-8") { |f| f.write(out) }
168
+ File.open(File.join(@splitdir, outname), "w:UTF-8") do |f|
169
+ f.write(out)
170
+ end
130
171
  outname
131
172
  end
132
173
 
@@ -114,6 +114,14 @@ module Metanorma
114
114
  fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
115
115
  orig_filename: File.expand_path(filename),
116
116
  presentationxml: f.sub(/\.[^.]+$/, ".presentation.xml") }
117
+ if extensions == %i(presentation)
118
+ process_ext(:presentation, file, isodoc, fnames, options)
119
+ else
120
+ process_exts_queue(fnames, extensions, file, isodoc, options)
121
+ end
122
+ end
123
+
124
+ def process_exts_queue(fnames, extensions, file, isodoc, options)
117
125
  @queue = ::Metanorma::Util::WorkersPool
118
126
  .new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
119
127
  gather_and_install_fonts(file, options.dup, extensions)
@@ -1,8 +1,7 @@
1
1
  module Metanorma
2
2
  class Compile
3
3
  def relaton_export(isodoc, options)
4
- return unless options[:relaton]
5
-
4
+ options[:relaton] or return
6
5
  xml = Nokogiri::XML(isodoc, &:huge)
7
6
  bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
8
7
  # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
@@ -18,8 +17,7 @@ module Metanorma
18
17
  end
19
18
 
20
19
  def extract(isodoc, dirname, extract_types)
21
- return unless dirname
22
-
20
+ dirname or return
23
21
  extract_types.nil? || extract_types.empty? and
24
22
  extract_types = %i[sourcecode image requirement]
25
23
  FileUtils.rm_rf dirname
@@ -14,15 +14,16 @@ module Metanorma
14
14
  end
15
15
 
16
16
  def extract_metanorma_options(file)
17
- headerextract = file.sub(/\n\n.*$/m, "\n")
18
- /\n:mn-document-class:\s+(?<type>\S[^\n]*)\n/ =~ headerextract
19
- /\n:mn-output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ headerextract
20
- /\n:mn-relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ headerextract
21
- /\n(?<asciimath>:mn-keep-asciimath:[^\n]*)\n/ =~ headerextract
22
- /\n(?<novalid>:novalid:[^\n]*)\n/ =~ headerextract
23
- asciimath = if defined?(asciimath)
24
- !asciimath.nil? && asciimath != ":mn-keep-asciimath: false"
25
- end
17
+ hdr = file.sub(/\n\n.*$/m, "\n")
18
+ /\n:(?:mn-)?(?:document-class|flavor):\s+(?<type>\S[^\n]*)\n/ =~ hdr
19
+ /\n:(?:mn-)?output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ hdr
20
+ /\n:(?:mn-)?relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ hdr
21
+ /\n(?<asciimath>:(?:mn-)?keep-asciimath:[^\n]*)\n/ =~ hdr
22
+ /\n(?<novalid>:novalid:[^\n]*)\n/ =~ hdr
23
+ if defined?(asciimath)
24
+ asciimath =
25
+ !asciimath.nil? && !/keep-asciimath: false/.match?(asciimath)
26
+ end
26
27
  asciimath = nil if asciimath == false
27
28
  {
28
29
  type: defined?(type) ? type&.strip : nil,
@@ -62,7 +63,7 @@ module Metanorma
62
63
  toc-tables toc-recommendations).freeze
63
64
 
64
65
  def attr_name_normalise(name)
65
- name.gsub("-", "").sub(/override$/, "_override").sub(/pdf$/, "_pdf")
66
+ name.delete("-").sub(/override$/, "_override").sub(/pdf$/, "_pdf")
66
67
  .to_sym
67
68
  end
68
69
 
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "2.0.6".freeze
2
+ VERSION = "2.0.7".freeze
3
3
  end
data/metanorma.gemspec CHANGED
@@ -24,10 +24,11 @@ Gem::Specification.new do |spec|
24
24
  spec.required_ruby_version = ">= 3.1.0"
25
25
 
26
26
  spec.add_runtime_dependency "asciidoctor"
27
+ spec.add_runtime_dependency "concurrent-ruby"
27
28
  spec.add_runtime_dependency "fontist", ">= 1.14.3"
28
29
  spec.add_runtime_dependency "htmlentities"
29
30
  spec.add_runtime_dependency "isodoc", ">= 2.6.3"
30
- spec.add_runtime_dependency "mn2pdf", "~> 1"
31
+ spec.add_runtime_dependency "mn2pdf", "~> 2"
31
32
  spec.add_runtime_dependency "nokogiri"
32
33
  spec.add_runtime_dependency "shale"
33
34
 
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: 2.0.6
4
+ version: 2.0.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: 2024-10-14 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: fontist
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +86,14 @@ dependencies:
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '1'
89
+ version: '2'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '1'
96
+ version: '2'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: nokogiri
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -316,6 +330,7 @@ files:
316
330
  - lib/metanorma/collection/renderer/navigation.rb
317
331
  - lib/metanorma/collection/renderer/render_word.rb
318
332
  - lib/metanorma/collection/renderer/renderer.rb
333
+ - lib/metanorma/collection/renderer/svg.rb
319
334
  - lib/metanorma/collection/renderer/utils.rb
320
335
  - lib/metanorma/collection/sectionsplit/collection.rb
321
336
  - lib/metanorma/collection/sectionsplit/sectionsplit.rb