metanorma 2.0.5 → 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.
@@ -1,6 +1,8 @@
1
1
  require "yaml"
2
2
  require_relative "../../util/util"
3
3
  require_relative "../xrefprocess/xrefprocess"
4
+ require_relative "collection"
5
+ require "concurrent-ruby"
4
6
 
5
7
  module Metanorma
6
8
  class Collection
@@ -17,49 +19,13 @@ module Metanorma
17
19
  @fileslookup = opts[:fileslookup]
18
20
  @ident = opts[:ident]
19
21
  @isodoc = opts[:isodoc]
22
+ @document_suffix = opts[:document_suffix]
20
23
  end
21
24
 
22
25
  def ns(xpath)
23
26
  @isodoc.ns(xpath)
24
27
  end
25
28
 
26
- def build_collection
27
- collection_setup(@base, @dir)
28
- files = sectionsplit # (@input_filename, @base, @dir, @compile_opts)
29
- input_xml = Nokogiri::XML(File.read(@input_filename,
30
- encoding: "UTF-8"), &:huge)
31
- collection_manifest(@base, files, input_xml, @xml, @dir).render(
32
- { format: %i(html), output_folder: "#{@output_filename}_collection",
33
- coverpage: File.join(@dir, "cover.html") }.merge(@compile_opts),
34
- )
35
- section_split_attachments(out: "#{@output_filename}_collection")
36
- end
37
-
38
- def collection_manifest(filename, files, origxml, _presxml, dir)
39
- File.open(File.join(dir, "#{filename}.html.yaml"), "w:UTF-8") do |f|
40
- f.write(collectionyaml(files, origxml))
41
- end
42
- Metanorma::Collection.parse File.join(dir, "#{filename}.html.yaml")
43
- end
44
-
45
- def collection_setup(filename, dir)
46
- FileUtils.mkdir_p "#{filename}_collection" if filename
47
- FileUtils.mkdir_p dir
48
- File.open(File.join(dir, "cover.html"), "w:UTF-8") do |f|
49
- f.write(coll_cover)
50
- end
51
- end
52
-
53
- def coll_cover
54
- <<~COVER
55
- <html><head><meta charset="UTF-8"/></head><body>
56
- <h1>{{ doctitle }}</h1>
57
- <h2>{{ docnumber }}</h2>
58
- <nav>{{ navigation }}</nav>
59
- </body></html>
60
- COVER
61
- end
62
-
63
29
  SPLITSECTIONS =
64
30
  [["//preface/*", "preface"], ["//sections/*", "sections"],
65
31
  ["//annex", nil],
@@ -70,17 +36,37 @@ module Metanorma
70
36
  def sectionsplit
71
37
  xml = sectionsplit_prep(File.read(@input_filename), @base, @dir)
72
38
  @key = Metanorma::Collection::XrefProcess::xref_preprocess(xml, @isodoc)
73
- 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|
74
48
  conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
75
- ret << sectionfile(xml, emptydoc(xml, ret.size),
76
- "#{@base}.#{ret.size}", s, n[1])
49
+ sectionsplit2(xml, idx.zero? ? empty : empty1, s, n[1],
50
+ { acc: m, idx: idx })
51
+ idx += 1
77
52
  end
78
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
79
65
  end
80
66
 
81
67
  def block?(node)
82
68
  %w(p table formula admonition ol ul dl figure quote sourcecode example
83
- pre note pagebrreak hr bookmark requirement recommendation permission
69
+ pre note pagebreak hr bookmark requirement recommendation permission
84
70
  svgmap inputform toc passthrough review imagemap).include?(node.name)
85
71
  end
86
72
 
@@ -142,7 +128,26 @@ module Metanorma
142
128
  "//bibliography/references[not(@hidden = 'true')] | " \
143
129
  "//indexsect | //colophon"),
144
130
  ).each(&:remove)
145
- ordinal.zero? or out.xpath(ns("//metanorma-ext//attachment"))
131
+ ordinal.zero? or out.xpath(ns("//metanorma-ext//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"))
146
151
  .each(&:remove) # keep only one copy of attachments
147
152
  out
148
153
  end
@@ -158,11 +163,36 @@ module Metanorma
158
163
  sectionfile_insert(ins, chunks, parentnode)
159
164
  Metanorma::Collection::XrefProcess::xref_process(out, xml, @key,
160
165
  @ident, @isodoc)
166
+ truncate_semxml(out, chunks)
161
167
  outname = "#{file}.xml"
162
- 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
163
171
  outname
164
172
  end
165
173
 
174
+ def semantic_xml_ids_gather(out)
175
+ out.at(ns("//semantic__bibdata")) or return
176
+ SPLITSECTIONS.each_with_object({}) do |s, m|
177
+ out.xpath(ns(s[0].sub("//", "//semantic__"))).each do |x|
178
+ x["id"] or next
179
+ m[x["id"].sub(/^semantic__/, "")] = x
180
+ end
181
+ end
182
+ end
183
+
184
+ def semxml_presxml_nodes_match(nodes, chunks)
185
+ chunks.each do |x|
186
+ nodes[x["id"]] and nodes.delete(x["id"])
187
+ end
188
+ end
189
+
190
+ def truncate_semxml(out, chunks)
191
+ nodes = semantic_xml_ids_gather(out) or return
192
+ semxml_presxml_nodes_match(nodes, chunks)
193
+ nodes.each_value(&:remove)
194
+ end
195
+
166
196
  def sectionfile_insert(ins, chunks, parentnode)
167
197
  if parentnode
168
198
  ins.next = "<#{parentnode}/>"
@@ -180,64 +210,6 @@ module Metanorma
180
210
  .each { |x| x.replace(x.children) }
181
211
  t.children.to_xml
182
212
  end
183
-
184
- def collectionyaml(files, xml)
185
- ret = {
186
- directives: ["presentation-xml", "bare-after-first"],
187
- bibdata: {
188
- title: {
189
- type: "title-main", language: @lang,
190
- content: xml.at(ns("//bibdata/title")).text
191
- },
192
- type: "collection",
193
- docid: {
194
- type: xml.at(ns("//bibdata/docidentifier/@type")).text,
195
- id: xml.at(ns("//bibdata/docidentifier")).text,
196
- },
197
- },
198
- manifest: {
199
- level: "collection", title: "Collection",
200
- docref: files.sort_by { |f| f[:order] }.each.map do |f|
201
- { fileref: f[:url], identifier: f[:title] }
202
- end
203
- },
204
- }
205
- ::Metanorma::Util::recursive_string_keys(ret).to_yaml
206
- end
207
-
208
- def section_split_cover(col, ident, _one_doc_coll)
209
- dir = File.dirname(col.file)
210
- collection_setup(nil, dir)
211
- r = ::Metanorma::Collection::Renderer
212
- .new(col, dir, output_folder: "#{ident}_collection",
213
- format: %i(html), coverpage: File.join(dir, "cover.html"))
214
- r.coverpage
215
- section_split_cover1(ident, r, dir, _one_doc_coll)
216
- end
217
-
218
- def att_dir(file)
219
- "_#{File.basename(file, '.*')}_attachments"
220
- end
221
-
222
- def section_split_attachments(out: nil)
223
- attachments = att_dir(@tmp_filename)
224
- File.directory?(attachments) or return
225
- dir = out || File.dirname(@input_filename)
226
- ret = File.join(dir, att_dir(@output_filename))
227
- FileUtils.rm_rf ret
228
- FileUtils.mv attachments, ret
229
- File.basename(ret)
230
- end
231
-
232
- def section_split_cover1(ident, renderer, dir, _one_doc_coll)
233
- # filename = one_doc_coll ? "#{ident}_index.html" : "index.html"
234
- filename = File.basename("#{ident}_index.html")
235
- # ident can be a directory with YAML indirection
236
- FileUtils.mv File.join(renderer.outdir, "index.html"),
237
- File.join(dir, filename)
238
- FileUtils.rm_rf renderer.outdir
239
- filename
240
- end
241
213
  end
242
214
  end
243
215
  end
@@ -30,8 +30,7 @@ module Metanorma
30
30
  end
31
31
  end
32
32
 
33
- def add_suffix_to_attributes(doc, suffix, tag_name, attr_name,
34
- isodoc)
33
+ def add_suffix_to_attrs(doc, suffix, tag_name, attr_name, isodoc)
35
34
  (suffix.nil? || suffix.empty?) and return
36
35
  doc.xpath(isodoc.ns("//#{tag_name}[@#{attr_name}]")).each do |elem|
37
36
  a = elem.attributes[attr_name].value
@@ -62,8 +61,8 @@ isodoc)
62
61
  def attr(_key); end
63
62
  end
64
63
 
65
- def load_isodoc(doctype)
66
- x = Asciidoctor.load nil, backend: doctype.to_sym
64
+ def load_isodoc(flavor)
65
+ x = Asciidoctor.load nil, backend: flavor.to_sym
67
66
  x.converter.html_converter(Dummy.new) # to obtain Isodoc class
68
67
  end
69
68
  end
@@ -10,9 +10,9 @@ module Metanorma
10
10
  key = (0...8).map { rand(65..90).chr }.join # random string
11
11
  xml.root["type"] = key
12
12
  Metanorma::Utils::anchor_attributes
13
- .each do |(tag_name, attribute_name)|
14
- ::Metanorma::Collection::Util::add_suffix_to_attributes(
15
- xml, xml.root["document_suffix"], tag_name, attribute_name, isodoc
13
+ .each do |(tag_name, attr_name)|
14
+ ::Metanorma::Collection::Util::add_suffix_to_attrs(
15
+ xml, xml.root["document_suffix"], tag_name, attr_name, isodoc
16
16
  )
17
17
  end
18
18
  key
@@ -33,6 +33,7 @@ module Metanorma
33
33
  relaton_export(isodoc, options)
34
34
  extract(isodoc, options[:extract], options[:extract_type])
35
35
  process_exts(filename, extensions, file, isodoc, options)
36
+ ensure
36
37
  clean_exit(options)
37
38
  end
38
39
 
@@ -113,6 +114,14 @@ module Metanorma
113
114
  fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
114
115
  orig_filename: File.expand_path(filename),
115
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)
116
125
  @queue = ::Metanorma::Util::WorkersPool
117
126
  .new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
118
127
  gather_and_install_fonts(file, options.dup, extensions)
@@ -33,15 +33,15 @@ module Metanorma
33
33
  "support the standard type #{stdtype}. Exiting.", :fatal)
34
34
  end
35
35
 
36
- private
37
-
38
- STDTYPE2FLAVOR = {}.freeze
39
-
40
36
  def stdtype2flavor(stdtype)
41
37
  flavor = STDTYPE2FLAVOR[stdtype] || stdtype
42
38
  "metanorma-#{flavor}"
43
39
  end
44
40
 
41
+ private
42
+
43
+ STDTYPE2FLAVOR = {}.freeze
44
+
45
45
  def require_flavor(flavor)
46
46
  require flavor
47
47
  Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
@@ -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
@@ -10,39 +10,20 @@ module Metanorma
10
10
  novalid: options[:novalid],
11
11
  attributes: ["nodoc", "stem", "docfile=#{filename}",
12
12
  "output_dir=#{options[:output_dir]}"] }
13
- unless asciidoctor_validate(file, filename, out_opts)
14
- warn "Cannot continue compiling Asciidoctor document"
15
- abort
16
- end
17
13
  ::Asciidoctor.convert(file, out_opts)
18
14
  end
19
15
 
20
- def asciidoctor_validate(file, filename, options)
21
- err = nil
22
- begin
23
- previous_stderr = $stderr
24
- $stderr = StringIO.new
25
- ::Asciidoctor.load(file, options)
26
- %r{(\n|^)asciidoctor: ERROR: ['"]?#{Regexp.escape(filename ||
27
- '<empty>')}['"]?: line \d+: include file not found: }
28
- .match($stderr.string) and err = $stderr.string
29
- ensure
30
- $stderr = previous_stderr
31
- end
32
- warn err unless err.nil?
33
- err.nil?
34
- end
35
-
36
16
  def extract_metanorma_options(file)
37
- headerextract = file.sub(/\n\n.*$/m, "\n")
38
- /\n:mn-document-class:\s+(?<type>\S[^\n]*)\n/ =~ headerextract
39
- /\n:mn-output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ headerextract
40
- /\n:mn-relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ headerextract
41
- /\n(?<asciimath>:mn-keep-asciimath:[^\n]*)\n/ =~ headerextract
42
- /\n(?<novalid>:novalid:[^\n]*)\n/ =~ headerextract
43
- asciimath = if defined?(asciimath)
44
- !asciimath.nil? && asciimath != ":mn-keep-asciimath: false"
45
- 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
46
27
  asciimath = nil if asciimath == false
47
28
  {
48
29
  type: defined?(type) ? type&.strip : nil,
@@ -82,7 +63,7 @@ module Metanorma
82
63
  toc-tables toc-recommendations).freeze
83
64
 
84
65
  def attr_name_normalise(name)
85
- name.gsub("-", "").sub(/override$/, "_override").sub(/pdf$/, "_pdf")
66
+ name.delete("-").sub(/override$/, "_override").sub(/pdf$/, "_pdf")
86
67
  .to_sym
87
68
  end
88
69
 
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "2.0.5".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.5
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-09-30 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,7 +330,9 @@ 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
335
+ - lib/metanorma/collection/sectionsplit/collection.rb
320
336
  - lib/metanorma/collection/sectionsplit/sectionsplit.rb
321
337
  - lib/metanorma/collection/util/disambig_files.rb
322
338
  - lib/metanorma/collection/util/util.rb