metanorma 1.4.3 → 1.4.4

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: d977a50a2b1b4c0a016439be744d32ef51fad6a4f0e5869f0ea31654065bb584
4
- data.tar.gz: 3da646653cdea95e20f7e0c5ee07a9ccf301b4f73506d1f65059e03b71c064de
3
+ metadata.gz: c8457479b196c4d3db250ce33f650cd822f1ac8f1a510d1b6ac9653038446e1e
4
+ data.tar.gz: f1219e134ab2113cd3e25c5bca39fe3194a3a038f9b6500f0d5e35d66f168d0d
5
5
  SHA512:
6
- metadata.gz: be99d0c2c11598c9e5dcd05df5da7a1bcdf49a161a56928ef8c1873bae349b401823d5f112b2aa4e0350bc20511125921c626fbd4c7ef862f6291476a409281c
7
- data.tar.gz: aaba4884d254314d5f3436d6f709503a34810398f093e1010cb4186c2bb1fcd7ebc1b41725dc0542db3ce4a7896f151b826a146332d3a4a2fffb0be47f9a3482
6
+ metadata.gz: 8e62d329f40ca168b5f2250ae86e676b89650c754233a4d249eea45bdf7652863ce5824a128bbff0c6225435a97be4bb8b420ce9cfca44587be9d1d852c33599
7
+ data.tar.gz: 1b18636330ca30bba9f2a0080e1728c6d05763349ffafebab78e1b61043f3b45c5160156dfdbf541d886fc14e195ee54808cbfbc4dd8d296e7bb56ee5edca735
data/README.adoc CHANGED
@@ -247,6 +247,13 @@ The options hash has the same structure it does when invoked in metanorma-cli:
247
247
  `:relaton`: exports the bibdata Relaton XML description of the document (which is part of its Metanorma XML)
248
248
  to the nominated directory
249
249
 
250
+ == Threaded execution
251
+
252
+ Metanorma has threaded execution, to generate output documents from the same Presentation XML input more quickly.
253
+ Similar to https://github.com/relaton/relaton[relaton], the `METANORMA_PARALLEL` environment variable
254
+ can be used to override the default number of parallel fetches used.
255
+
256
+
250
257
  == Origin of name
251
258
 
252
259
  *Meta-* is a prefix of Greek origin ("μετα") for "`with`" "`after`".
@@ -16,7 +16,7 @@ module Metanorma
16
16
  # @param options [Hash]
17
17
  # @option options [String] :coverpage cover page HTML (Liquid template)
18
18
  # @option options [Array<Symbol>] :format list of formats (xml,html,doc,pdf)
19
- # @option options [String] :ourput_folder output directory
19
+ # @option options [String] :output_folder output directory
20
20
  #
21
21
  # We presuppose that the bibdata of the document is equivalent to that of
22
22
  # the collection, and that the flavour gem can sensibly process it. We may
@@ -9,6 +9,7 @@ require_relative "fontist_utils"
9
9
  require_relative "util"
10
10
  require_relative "sectionsplit"
11
11
  require_relative "extract"
12
+ require_relative "worker_pool"
12
13
 
13
14
  module Metanorma
14
15
  class Compile
@@ -33,7 +34,7 @@ module Metanorma
33
34
  extract(isodoc, options[:extract], options[:extract_type])
34
35
  FontistUtils.install_fonts(@processor, options) unless @fontist_installed
35
36
  @fontist_installed = true
36
- process_extensions(filename, extensions, file, isodoc, options)
37
+ process_exts(filename, extensions, file, isodoc, options)
37
38
  end
38
39
 
39
40
  def require_libraries(options)
@@ -119,6 +120,16 @@ module Metanorma
119
120
  File.read(filename, encoding: "utf-8").gsub("\r\n", "\n")
120
121
  end
121
122
 
123
+ def relaton_export(isodoc, options)
124
+ return unless options[:relaton]
125
+
126
+ xml = Nokogiri::XML(isodoc) { |config| config.huge }
127
+ bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
128
+ # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
129
+ # outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
130
+ File.open(options[:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml }
131
+ end
132
+
122
133
  def export_output(fname, content, **options)
123
134
  mode = options[:binary] ? "wb" : "w:UTF-8"
124
135
  File.open(fname, mode) { |f| f.write content }
@@ -134,41 +145,68 @@ module Metanorma
134
145
  end
135
146
 
136
147
  # isodoc is Raw Metanorma XML
137
- def process_extensions(filename, extensions, file, isodoc, options)
138
- f = change_output_dir options
139
- name = { xml: f.sub(/\.[^.]+$/, ".xml"),
140
- presentationxml: f.sub(/\.[^.]+$/, ".presentation.xml") }
148
+ def process_exts(filename, extensions, file, isodoc, options)
149
+ f = File.expand_path(change_output_dir(options))
150
+ fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
151
+ orig_filename: File.expand_path(filename),
152
+ presentationxml: f.sub(/\.[^.]+$/, ".presentation.xml") }
153
+ @queue = ::Metanorma::WorkersPool
154
+ .new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
141
155
  Util.sort_extensions_execution(extensions).each do |ext|
142
- file_extension = @processor.output_formats[ext]
143
- name[:out] = f.sub(/\.[^.]+$/, ".#{file_extension}")
144
- isodoc_options = get_isodoc_options(file, options, ext)
145
- if ext == :rxl
146
- relaton_export(isodoc, options.merge(relaton: name[:out]))
147
- elsif options[:passthrough_presentation_xml] && ext == :presentation
148
- FileUtils.cp filename, name[:presentationxml]
149
- elsif ext == :html && options[:sectionsplit]
150
- sectionsplit_convert(name[:xml], isodoc, name[:out], isodoc_options)
151
- else
152
- if ext == :pdf && FontistUtils.has_fonts_manifest?(@processor,
153
- options)
154
- isodoc_options[:mn2pdf] = {
155
- font_manifest: FontistUtils.location_manifest(@processor),
156
- }
157
- end
158
- process_extensions1(ext, name, isodoc, isodoc_options)
159
- end
160
- wrap_html(options, file_extension, name[:out])
156
+ process_ext(ext, file, isodoc, fnames, options)
157
+ end
158
+ @queue.shutdown
159
+ end
160
+
161
+ def process_ext(ext, file, isodoc, fnames, options)
162
+ fnames[:ext] = @processor.output_formats[ext]
163
+ fnames[:out] = fnames[:f].sub(/\.[^.]+$/, ".#{fnames[:ext]}")
164
+ isodoc_options = get_isodoc_options(file, options, ext)
165
+ thread = nil
166
+ unless process_ext_simple(ext, isodoc, fnames, options,
167
+ isodoc_options)
168
+ thread = process_exts1(ext, fnames, isodoc, options, isodoc_options)
169
+ end
170
+ thread
171
+ end
172
+
173
+ def process_ext_simple(ext, isodoc, fnames, options, isodoc_options)
174
+ if ext == :rxl
175
+ relaton_export(isodoc, options.merge(relaton: fnames[:out]))
176
+ elsif options[:passthrough_presentation_xml] && ext == :presentation
177
+ f = File.exists?(fnames[:f]) ? fnames[:f] : fnames[:orig_filename]
178
+ FileUtils.cp f, fnames[:presentationxml]
179
+ elsif ext == :html && options[:sectionsplit]
180
+ sectionsplit_convert(fnames[:xml], isodoc, fnames[:out],
181
+ isodoc_options)
182
+ else return false
161
183
  end
184
+ true
162
185
  end
163
186
 
164
- def process_extensions1(ext, fnames, isodoc, isodoc_options)
187
+ def process_exts1(ext, fnames, isodoc, options, isodoc_options)
165
188
  if @processor.use_presentation_xml(ext)
166
- @processor.output(nil, fnames[:presentationxml], fnames[:out], ext,
167
- isodoc_options)
189
+ @queue.schedule(ext, fnames.dup, options.dup,
190
+ isodoc_options.dup) do |a, b, c, d|
191
+ process_output_threaded(a, b, c, d)
192
+ end
168
193
  else
169
- @processor.output(isodoc, fnames[:xml], fnames[:out], ext,
170
- isodoc_options)
194
+ process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
171
195
  end
196
+ end
197
+
198
+ def process_output_threaded(ext, fnames1, options1, isodoc_options1)
199
+ @processor.output(nil, fnames1[:presentationxml], fnames1[:out], ext,
200
+ isodoc_options1)
201
+ wrap_html(options1, fnames1[:ext], fnames1[:out])
202
+ rescue StandardError => e
203
+ isodoc_error_process(e)
204
+ end
205
+
206
+ def process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
207
+ @processor.output(isodoc, fnames[:xml], fnames[:out], ext,
208
+ isodoc_options)
209
+ nil # return as Thread
172
210
  rescue StandardError => e
173
211
  isodoc_error_process(e)
174
212
  end
@@ -184,15 +222,16 @@ module Metanorma
184
222
  end
185
223
  end
186
224
 
187
- def get_isodoc_options(file, options, _ext)
188
- isodoc_options = @processor.extract_options(file)
189
- isodoc_options[:datauriimage] = true if options[:datauriimage]
190
- isodoc_options[:sourcefilename] = options[:filename]
225
+ def get_isodoc_options(file, options, ext)
226
+ ret = @processor.extract_options(file)
227
+ ret[:datauriimage] = true if options[:datauriimage]
228
+ ret[:sourcefilename] = options[:filename]
191
229
  %i(bare sectionsplit no_install_fonts baseassetpath aligncrosselements)
192
- .each do |x|
193
- isodoc_options[x] ||= options[x]
194
- end
195
- isodoc_options
230
+ .each { |x| ret[x] ||= options[x] }
231
+ ext == :pdf && FontistUtils.has_fonts_manifest?(@processor, options) and
232
+ ret[:mn2pdf] =
233
+ { font_manifest: FontistUtils.location_manifest(@processor) }
234
+ ret
196
235
  end
197
236
 
198
237
  # @param options [Hash]
@@ -1,7 +1,7 @@
1
1
  # Registry of all Metanorma types and entry points
2
2
  #
3
3
 
4
- require 'singleton'
4
+ require "singleton"
5
5
 
6
6
  class Error < StandardError
7
7
  end
@@ -14,15 +14,16 @@ module Metanorma
14
14
 
15
15
  def initialize
16
16
  @processors = {}
17
- @aliases = {csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa}
17
+ @aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa }
18
18
  end
19
19
 
20
20
  def alias(x)
21
21
  @aliases[x]
22
22
  end
23
23
 
24
- def register processor
24
+ def register(processor)
25
25
  raise Error unless processor < ::Metanorma::Processor
26
+
26
27
  p = processor.new
27
28
  # p.short[-1] is the canonical name
28
29
  short = Array(p.short)
@@ -31,7 +32,8 @@ module Metanorma
31
32
  @aliases[s] = short[-1]
32
33
  end
33
34
  Array(p.short)
34
- Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered", :info)
35
+ Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered",
36
+ :info)
35
37
  end
36
38
 
37
39
  def find_processor(short)
@@ -42,21 +44,17 @@ module Metanorma
42
44
  @processors.keys
43
45
  end
44
46
 
45
- def processors
46
- @processors
47
- end
48
-
49
47
  def output_formats
50
- @processors.inject({}) do |acc, (k,v)|
48
+ @processors.inject({}) do |acc, (k, v)|
51
49
  acc[k] = v.output_formats
52
50
  acc
53
51
  end
54
52
  end
55
53
 
56
54
  def root_tags
57
- @processors.inject({}) do |acc, (k,v)|
55
+ @processors.inject({}) do |acc, (k, v)|
58
56
  if v.asciidoctor_backend
59
- x = Asciidoctor.load nil, {backend: v.asciidoctor_backend}
57
+ x = Asciidoctor.load nil, { backend: v.asciidoctor_backend }
60
58
  acc[k] = x.converter.xml_root_tag
61
59
  end
62
60
  acc
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.4.3".freeze
2
+ VERSION = "1.4.4".freeze
3
3
  end
@@ -0,0 +1,29 @@
1
+ module Metanorma
2
+ class WorkersPool
3
+ def initialize(workers)
4
+ @workers = workers
5
+ @queue = SizedQueue.new(@workers)
6
+ @threads = Array.new(@workers) do
7
+ Thread.new do
8
+ catch(:exit) do
9
+ loop do
10
+ job, args = @queue.pop
11
+ job.call *args
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def schedule(*args, &block)
19
+ @queue << [block, args]
20
+ end
21
+
22
+ def shutdown
23
+ @workers.times do
24
+ schedule { throw :exit }
25
+ end
26
+ @threads.map(&:join)
27
+ end
28
+ end
29
+ 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.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-13 00:00:00.000000000 Z
11
+ date: 2021-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -298,6 +298,7 @@ files:
298
298
  - lib/metanorma/sectionsplit.rb
299
299
  - lib/metanorma/util.rb
300
300
  - lib/metanorma/version.rb
301
+ - lib/metanorma/worker_pool.rb
301
302
  - metanorma.gemspec
302
303
  homepage: https://github.com/metanorma/metanorma
303
304
  licenses: