metanorma 2.1.7 → 2.1.8
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 +4 -4
- data/lib/metanorma/collection/collection.rb +1 -1
- data/lib/metanorma/compile/assets/icc-boilerplate.adoc +41 -0
- data/lib/metanorma/compile/compile.rb +29 -204
- data/lib/metanorma/compile/compile_options.rb +27 -12
- data/lib/metanorma/compile/flavor.rb +3 -6
- data/lib/metanorma/compile/render.rb +178 -0
- data/lib/metanorma/compile/validator.rb +2 -4
- data/lib/metanorma/input/asciidoc.rb +12 -6
- data/lib/metanorma/registry/registry.rb +6 -8
- data/lib/metanorma/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2491a406715a008c828e167a72d00c415af554237517bcbfdeb76818545d548
|
4
|
+
data.tar.gz: 5e7a842f9fa86b6cbd8ec4ff5730489ba3ff89330d4d74aa6a7de1f4ece68f0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42c9068a65961a2c785b0ee3d5cfcdc9710bcfffeb8309b4bb91b7b213cd9fa97ffff220586f1d9b52d2b230c9cb4743180d3e25209a9e4dfb22cb14d6f89468
|
7
|
+
data.tar.gz: de9167c3dddad4904aba5101a9cea1864654eea8549a6d45eff4fe6bc8d266ea927356b769ef6090126f0177d4c725d0f9059be2c9de0ec7816f3e68c5976081
|
@@ -172,7 +172,7 @@ module Metanorma
|
|
172
172
|
def fetch_flavor
|
173
173
|
docid = @bibdata.docidentifier.first or return
|
174
174
|
f = docid.type.downcase || docid.id.sub(/\s.*$/, "").downcase or return
|
175
|
-
require ::Metanorma::Compile.new.
|
175
|
+
require ::Metanorma::Compile.new.stdtype2flavor_gem(f)
|
176
176
|
f
|
177
177
|
rescue LoadError
|
178
178
|
nil
|
@@ -0,0 +1,41 @@
|
|
1
|
+
== copyright-statement
|
2
|
+
=== Copyright notice
|
3
|
+
|
4
|
+
Copyright © 1994-{{docyear}} International Color Consortium®
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
7
|
+
the Specification and associated documentation files (the “Specification”) to
|
8
|
+
deal in the Specification without restriction, including without limitation the
|
9
|
+
rights to use, copy, modify, merge, publish, distribute, and/or sublicense
|
10
|
+
copies of the Specification, and to permit persons to whom the Specification is
|
11
|
+
furnished to do so, subject to the following conditions.
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
14
|
+
copies or substantial portions of the Specification.
|
15
|
+
|
16
|
+
The Specification is provided "as is", without warranty of any kind, express,
|
17
|
+
implied, or otherwise, including but not limited to the warranties of
|
18
|
+
merchantability, fitness for a particular purpose and noninfringement. In no
|
19
|
+
event shall the International Color Consortium be liable for any claim, damages
|
20
|
+
or other liability, whether in an action of contract, tort or otherwise, arising
|
21
|
+
from, out of, or in connection with the Specification or the use or other
|
22
|
+
dealings in the Specification.
|
23
|
+
|
24
|
+
Except as contained in this notice, the name of the International Color
|
25
|
+
Consortium shall not be used in advertising or otherwise to promote the use or
|
26
|
+
other dealings in this Specification without prior written authorization from
|
27
|
+
the International Color Consortium.
|
28
|
+
|
29
|
+
== license-statement
|
30
|
+
=== Licenses and trademarks
|
31
|
+
|
32
|
+
International Color Consortium and the ICC logo are registered trademarks of the
|
33
|
+
International Color Consortium. Rather than put a trademark symbol in every
|
34
|
+
occurrence of other trademarked names, we state that we are using the names only
|
35
|
+
in an editorial fashion, and to the benefit of the trademark owner, with no
|
36
|
+
intention of infringement of the trademark.
|
37
|
+
|
38
|
+
== feedback-statement
|
39
|
+
=== For additional information on the ICC
|
40
|
+
|
41
|
+
Visit the ICC Web site: http://www.color.org
|
@@ -18,6 +18,7 @@ require_relative "output_filename"
|
|
18
18
|
require_relative "output_filename_config"
|
19
19
|
require_relative "flavor"
|
20
20
|
require_relative "relaton_drop"
|
21
|
+
require_relative "render"
|
21
22
|
|
22
23
|
module Metanorma
|
23
24
|
class Compile
|
@@ -114,20 +115,18 @@ module Metanorma
|
|
114
115
|
# @param options [Hash] compilation options
|
115
116
|
# @return [Hash] paths for different output formats
|
116
117
|
def prepare_output_paths(filename, bibdata, options)
|
117
|
-
basename = if
|
118
|
+
basename = if options[:filename_template].nil?
|
119
|
+
filename.sub(/\.[^.]+$/, "")
|
120
|
+
else
|
118
121
|
drop = RelatonDrop.new(bibdata)
|
119
122
|
config = OutputFilenameConfig.new(options[:filename_template])
|
120
123
|
config.generate_filename(drop)
|
121
|
-
else
|
122
|
-
filename.sub(/\.[^.]+$/, "")
|
123
124
|
end
|
124
|
-
|
125
125
|
@output_filename = OutputFilename.new(
|
126
126
|
basename,
|
127
127
|
options[:output_dir],
|
128
128
|
@processor,
|
129
129
|
)
|
130
|
-
|
131
130
|
{
|
132
131
|
xml: @output_filename.semantic_xml,
|
133
132
|
orig_filename: filename,
|
@@ -175,53 +174,40 @@ module Metanorma
|
|
175
174
|
end
|
176
175
|
end
|
177
176
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
)
|
185
|
-
end
|
186
|
-
|
187
|
-
# Generate multiple output formats with parallel processing
|
188
|
-
def generate_outputs_parallel(
|
189
|
-
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
190
|
-
)
|
191
|
-
@queue = ::Metanorma::Util::WorkersPool.new(
|
192
|
-
ENV["METANORMA_PARALLEL"]&.to_i || DEFAULT_NUM_WORKERS,
|
193
|
-
)
|
194
|
-
|
195
|
-
# Install required fonts for all extensions
|
196
|
-
gather_and_install_fonts(source_file, options.dup, extensions)
|
197
|
-
|
198
|
-
# Process each extension in order
|
199
|
-
process_extensions_in_order(
|
200
|
-
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
201
|
-
)
|
202
|
-
|
203
|
-
@queue.shutdown
|
177
|
+
def process_input_adoc_hdr(file, options)
|
178
|
+
hdr, rest = Metanorma::Input::Asciidoc.new.header(file)
|
179
|
+
attrs = hdr.split("\n")
|
180
|
+
options[:asciimath] and attrs << ":mn-keep-asciimath:"
|
181
|
+
process_input_adoc_overrides(attrs, options)
|
182
|
+
"#{attrs.join("\n")}\n\n#{rest}"
|
204
183
|
end
|
205
184
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
185
|
+
# TODO: to config
|
186
|
+
def process_input_adoc_overrides(attrs, options)
|
187
|
+
case options[:supplied_type]
|
188
|
+
when :icc
|
189
|
+
f = File.join(File.dirname(__FILE__), "assets", "icc-boilerplate.adoc")
|
190
|
+
[":boilerplate-authority: #{f}",
|
191
|
+
":publisher: International Color Consortium",
|
192
|
+
":publisher_abbr: ICC"].each { |a| attrs << a }
|
193
|
+
options[":boilerplate-authority:"] = f
|
213
194
|
end
|
195
|
+
attrs
|
214
196
|
end
|
215
197
|
|
216
|
-
def
|
217
|
-
Util.log("[metanorma] Processing: AsciiDoc input.", :info)
|
218
|
-
file = read_file(filename)
|
219
|
-
options[:asciimath] and
|
220
|
-
file.sub!(/^(=[^\n]+\n)/, "\\1:mn-keep-asciimath:\n")
|
198
|
+
def process_input_adoc_includes(file, filename)
|
221
199
|
dir = File.dirname(filename)
|
222
200
|
dir != "." and
|
223
201
|
file = file.gsub(/^include::/, "include::#{dir}/")
|
224
202
|
.gsub(/^embed::/, "embed::#{dir}/")
|
203
|
+
file
|
204
|
+
end
|
205
|
+
|
206
|
+
def process_input_adoc(filename, options)
|
207
|
+
Util.log("[metanorma] Processing: AsciiDoc input.", :info)
|
208
|
+
file = read_file(filename)
|
209
|
+
file = process_input_adoc_hdr(file, options)
|
210
|
+
file = process_input_adoc_includes(file, filename)
|
225
211
|
[file, @processor.input_to_isodoc(file, filename, options)]
|
226
212
|
end
|
227
213
|
|
@@ -235,166 +221,5 @@ module Metanorma
|
|
235
221
|
def read_file(filename)
|
236
222
|
File.read(filename, encoding: "utf-8").gsub("\r\n", "\n")
|
237
223
|
end
|
238
|
-
|
239
|
-
# Export given bibliographic data to Relaton XML on disk
|
240
|
-
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
241
|
-
# @param options [Hash] compilation options
|
242
|
-
def export_relaton_from_bibdata(bibdata, options)
|
243
|
-
return unless options[:relaton]
|
244
|
-
|
245
|
-
# docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
|
246
|
-
# outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
|
247
|
-
export_output(options[:relaton], bibdata.to_xml)
|
248
|
-
end
|
249
|
-
|
250
|
-
# @param xml [Nokogiri::XML::Document] the XML document
|
251
|
-
# @return [Nokogiri::XML::Element] the bibliographic data element
|
252
|
-
def extract_relaton_metadata(xml)
|
253
|
-
xml.at("//bibdata") || xml.at("//xmlns:bibdata")
|
254
|
-
end
|
255
|
-
|
256
|
-
def wrap_html(options, file_extension, outfilename)
|
257
|
-
if options[:wrapper] && /html$/.match(file_extension)
|
258
|
-
outfilename = outfilename.sub(/\.html$/, "")
|
259
|
-
FileUtils.mkdir_p outfilename
|
260
|
-
FileUtils.mv "#{outfilename}.html", outfilename
|
261
|
-
FileUtils.mv "#{outfilename}_images", outfilename, force: true
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
# isodoc is Raw Metanorma XML
|
266
|
-
|
267
|
-
def gather_and_install_fonts(source_file, options, extensions)
|
268
|
-
Util.sort_extensions_execution(extensions).each do |ext|
|
269
|
-
isodoc_options = get_isodoc_options(source_file, options, ext)
|
270
|
-
font_install(isodoc_options.merge(options))
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
# Process a single extension (output format)
|
275
|
-
def process_ext(ext, source_file, semantic_xml, bibdata, output_paths,
|
276
|
-
options)
|
277
|
-
output_paths[:ext] = @processor.output_formats[ext]
|
278
|
-
output_paths[:out] = @output_filename.for_format(ext) ||
|
279
|
-
output_paths[:xml].sub(/\.[^.]+$/, ".#{output_paths[:ext]}")
|
280
|
-
isodoc_options = get_isodoc_options(source_file, options, ext)
|
281
|
-
|
282
|
-
# Handle special cases first
|
283
|
-
return true if process_ext_special(
|
284
|
-
ext, semantic_xml, bibdata, output_paths, options, isodoc_options
|
285
|
-
)
|
286
|
-
|
287
|
-
# Otherwise, determine if it uses presentation XML
|
288
|
-
if @processor.use_presentation_xml(ext)
|
289
|
-
# Format requires presentation XML first, then convert to final format
|
290
|
-
process_via_presentation_xml(ext, output_paths, options, isodoc_options)
|
291
|
-
else
|
292
|
-
# Format can be generated directly from semantic XML
|
293
|
-
process_from_semantic_xml(
|
294
|
-
ext, output_paths, semantic_xml, isodoc_options
|
295
|
-
)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
# Process special extensions with custom handling
|
300
|
-
def process_ext_special(
|
301
|
-
ext, semantic_xml, bibdata, output_paths, options, isodoc_options
|
302
|
-
)
|
303
|
-
if ext == :rxl
|
304
|
-
|
305
|
-
# Special case: Relaton export
|
306
|
-
export_relaton_from_bibdata(
|
307
|
-
bibdata,
|
308
|
-
options.merge(relaton: output_paths[:out]),
|
309
|
-
)
|
310
|
-
true
|
311
|
-
|
312
|
-
elsif ext == :presentation && options[:passthrough_presentation_xml]
|
313
|
-
|
314
|
-
# Special case: Pass through presentation XML
|
315
|
-
f = if File.exist?(output_paths[:orig_filename])
|
316
|
-
output_paths[:orig_filename]
|
317
|
-
else
|
318
|
-
output_paths[:xml]
|
319
|
-
end
|
320
|
-
|
321
|
-
FileUtils.cp f, output_paths[:presentationxml]
|
322
|
-
true
|
323
|
-
|
324
|
-
elsif ext == :html && options[:sectionsplit]
|
325
|
-
|
326
|
-
# Special case: Split HTML into sections
|
327
|
-
sectionsplit_convert(
|
328
|
-
output_paths[:xml], semantic_xml, output_paths[:out], isodoc_options
|
329
|
-
)
|
330
|
-
true
|
331
|
-
else
|
332
|
-
false
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
# Process format that requires presentation XML
|
337
|
-
def process_via_presentation_xml(ext, output_paths, options, isodoc_options)
|
338
|
-
@queue.schedule(ext, output_paths.dup, options.dup,
|
339
|
-
isodoc_options.dup) do |a, b, c, d|
|
340
|
-
process_output_from_presentation_xml(a, b, c, d)
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
# Generate output format from presentation XML
|
345
|
-
def process_output_from_presentation_xml(ext, output_paths, options,
|
346
|
-
isodoc_options)
|
347
|
-
@processor.output(nil, output_paths[:presentationxml],
|
348
|
-
output_paths[:out], ext, isodoc_options)
|
349
|
-
wrap_html(options, output_paths[:ext], output_paths[:out])
|
350
|
-
rescue StandardError => e
|
351
|
-
strict = ext == :presentation || isodoc_options[:strict] == true
|
352
|
-
isodoc_error_process(e, strict, false)
|
353
|
-
end
|
354
|
-
|
355
|
-
# Process format directly from semantic XML
|
356
|
-
def process_from_semantic_xml(ext, output_paths, semantic_xml,
|
357
|
-
isodoc_options)
|
358
|
-
@processor.output(semantic_xml, output_paths[:xml], output_paths[:out],
|
359
|
-
ext, isodoc_options)
|
360
|
-
true # Return as Thread equivalent
|
361
|
-
rescue StandardError => e
|
362
|
-
strict = ext == :presentation || isodoc_options[:strict] == "true"
|
363
|
-
isodoc_error_process(e, strict, true)
|
364
|
-
ext != :presentation
|
365
|
-
end
|
366
|
-
|
367
|
-
# assume we pass in Presentation XML, but we want to recover Semantic XML
|
368
|
-
def sectionsplit_convert(input_filename, file, output_filename = nil,
|
369
|
-
opts = {})
|
370
|
-
@isodoc ||= IsoDoc::PresentationXMLConvert.new({})
|
371
|
-
input_filename += ".xml" unless input_filename.match?(/\.xml$/)
|
372
|
-
File.exist?(input_filename) or
|
373
|
-
export_output(input_filename, file)
|
374
|
-
presxml = File.read(input_filename, encoding: "utf-8")
|
375
|
-
_xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
|
376
|
-
|
377
|
-
::Metanorma::Collection::Sectionsplit.new(
|
378
|
-
input: input_filename,
|
379
|
-
isodoc: @isodoc,
|
380
|
-
xml: presxml,
|
381
|
-
base: File.basename(output_filename || filename),
|
382
|
-
output: output_filename || filename,
|
383
|
-
dir: dir,
|
384
|
-
compile_opts: opts,
|
385
|
-
).build_collection
|
386
|
-
end
|
387
|
-
|
388
|
-
private
|
389
|
-
|
390
|
-
def isodoc_error_process(err, strict, must_abort)
|
391
|
-
if strict || err.message.include?("Fatal:")
|
392
|
-
@errors << err.message
|
393
|
-
else
|
394
|
-
puts err.message
|
395
|
-
end
|
396
|
-
puts err.backtrace.join("\n")
|
397
|
-
must_abort and 1
|
398
|
-
end
|
399
224
|
end
|
400
225
|
end
|
@@ -18,17 +18,9 @@ module Metanorma
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def extract_options(filename, options)
|
21
|
-
|
22
|
-
o
|
23
|
-
|
24
|
-
options[:type] ||= o[:type]&.to_sym
|
25
|
-
t = @registry.alias(options[:type]) and options[:type] = t
|
26
|
-
dir = filename.sub(%r(/[^/]+$), "/")
|
27
|
-
options[:relaton] ||= File.join(dir, o[:relaton]) if o[:relaton]
|
28
|
-
if o[:sourcecode]
|
29
|
-
options[:sourcecode] ||= File.join(dir,
|
30
|
-
o[:sourcecode])
|
31
|
-
end
|
21
|
+
o = options_in_file(filename)
|
22
|
+
extract_flavor_options(options, o)
|
23
|
+
extract_dir_options(options, o, filename)
|
32
24
|
options[:extension_keys] ||= o[:extensions]&.split(/, */)&.map(&:to_sym)
|
33
25
|
options[:extension_keys] = nil if options[:extension_keys] == [:all]
|
34
26
|
options[:format] ||= :asciidoc
|
@@ -38,6 +30,29 @@ module Metanorma
|
|
38
30
|
options
|
39
31
|
end
|
40
32
|
|
33
|
+
def options_in_file(filename)
|
34
|
+
content = read_file(filename)
|
35
|
+
Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
|
36
|
+
.merge(extract_xml_options(content))
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract_flavor_options(options, options_in_file)
|
40
|
+
options[:type] ||= options_in_file[:type]
|
41
|
+
options[:type] = options[:type]&.to_sym
|
42
|
+
options[:supplied_type] = options[:type]
|
43
|
+
t = @registry.alias(options[:type]) and options[:type] = t
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_dir_options(options, options_in_file, filename)
|
47
|
+
dir = filename.sub(%r(/[^/]+$), "/")
|
48
|
+
options_in_file[:relaton] and
|
49
|
+
options[:relaton] ||= File.join(dir,
|
50
|
+
options_in_file[:relaton])
|
51
|
+
options_in_file[:sourcecode] and
|
52
|
+
options[:sourcecode] ||= File.join(dir,
|
53
|
+
options_in_file[:sourcecode])
|
54
|
+
end
|
55
|
+
|
41
56
|
def get_extensions(options)
|
42
57
|
ext = extract_extensions(options)
|
43
58
|
!ext.include?(:presentation) && ext.any? do |e|
|
@@ -70,7 +85,7 @@ module Metanorma
|
|
70
85
|
|
71
86
|
def unsupported_format_error(ext)
|
72
87
|
message = "[metanorma] Error: #{ext} format is not supported " \
|
73
|
-
|
88
|
+
"for this standard."
|
74
89
|
@errors << message
|
75
90
|
Util.log(message, :error)
|
76
91
|
end
|
@@ -8,7 +8,7 @@ module Metanorma
|
|
8
8
|
# @return [void]
|
9
9
|
def load_flavor(stdtype)
|
10
10
|
stdtype = stdtype.to_sym
|
11
|
-
flavor =
|
11
|
+
flavor = stdtype2flavor_gem(stdtype)
|
12
12
|
@registry.supported_backends.include? stdtype or
|
13
13
|
Util.log("[metanorma] Info: Loading `#{flavor}` gem "\
|
14
14
|
"for standard type `#{stdtype}`.", :info)
|
@@ -21,15 +21,12 @@ module Metanorma
|
|
21
21
|
# Convert the standard type to the flavor gem name
|
22
22
|
# @param stdtype [Symbol] the standard type
|
23
23
|
# @return [String] the flavor gem name
|
24
|
-
def
|
25
|
-
|
26
|
-
"metanorma-#{flavor}"
|
24
|
+
def stdtype2flavor_gem(stdtype)
|
25
|
+
"metanorma-#{stdtype}"
|
27
26
|
end
|
28
27
|
|
29
28
|
private
|
30
29
|
|
31
|
-
STDTYPE2FLAVOR = {}.freeze
|
32
|
-
|
33
30
|
def require_flavor(flavor)
|
34
31
|
require flavor
|
35
32
|
Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module Metanorma
|
2
|
+
class Compile
|
3
|
+
# Generate presentation XML from semantic XML
|
4
|
+
def generate_presentation_xml(source_file, xml, bibdata, output_paths, opt)
|
5
|
+
process_ext(:presentation, source_file, xml, bibdata, output_paths, opt)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate multiple output formats with parallel processing
|
9
|
+
def generate_outputs_parallel(
|
10
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
11
|
+
)
|
12
|
+
@queue = ::Metanorma::Util::WorkersPool.new(
|
13
|
+
ENV["METANORMA_PARALLEL"]&.to_i || DEFAULT_NUM_WORKERS,
|
14
|
+
)
|
15
|
+
# Install required fonts for all extensions
|
16
|
+
gather_and_install_fonts(source_file, options.dup, extensions)
|
17
|
+
# Process each extension in order
|
18
|
+
process_extensions_in_order(
|
19
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
20
|
+
)
|
21
|
+
@queue.shutdown
|
22
|
+
end
|
23
|
+
|
24
|
+
def process_extensions_in_order(
|
25
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
26
|
+
)
|
27
|
+
Util.sort_extensions_execution(extensions).each do |ext|
|
28
|
+
process_ext(
|
29
|
+
ext, source_file, semantic_xml, bibdata, output_paths, options
|
30
|
+
) or break
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Export given bibliographic data to Relaton XML on disk
|
35
|
+
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
36
|
+
# @param options [Hash] compilation options
|
37
|
+
def export_relaton_from_bibdata(bibdata, options)
|
38
|
+
options[:relaton] or return
|
39
|
+
export_output(options[:relaton], bibdata.to_xml)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param xml [Nokogiri::XML::Document] the XML document
|
43
|
+
# @return [Nokogiri::XML::Element] the bibliographic data element
|
44
|
+
def extract_relaton_metadata(xml)
|
45
|
+
xml.at("//bibdata") || xml.at("//xmlns:bibdata")
|
46
|
+
end
|
47
|
+
|
48
|
+
def wrap_html(options, file_extension, outfilename)
|
49
|
+
if options[:wrapper] && /html$/.match(file_extension)
|
50
|
+
outfilename = outfilename.sub(/\.html$/, "")
|
51
|
+
FileUtils.mkdir_p outfilename
|
52
|
+
FileUtils.mv "#{outfilename}.html", outfilename
|
53
|
+
FileUtils.mv "#{outfilename}_images", outfilename, force: true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# isodoc is Raw Metanorma XML
|
58
|
+
def gather_and_install_fonts(source_file, options, extensions)
|
59
|
+
Util.sort_extensions_execution(extensions).each do |ext|
|
60
|
+
isodoc_options = get_isodoc_options(source_file, options, ext)
|
61
|
+
font_install(isodoc_options.merge(options))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Process a single extension (output format)
|
66
|
+
def process_ext(ext, source_file, semantic_xml, bibdata, output_paths,
|
67
|
+
options)
|
68
|
+
output_paths[:ext] = @processor.output_formats[ext]
|
69
|
+
output_paths[:out] = @output_filename.for_format(ext) ||
|
70
|
+
output_paths[:xml].sub(/\.[^.]+$/, ".#{output_paths[:ext]}")
|
71
|
+
isodoc_options = get_isodoc_options(source_file, options, ext)
|
72
|
+
|
73
|
+
# Handle special cases first
|
74
|
+
return true if process_ext_special(
|
75
|
+
ext, semantic_xml, bibdata, output_paths, options, isodoc_options
|
76
|
+
)
|
77
|
+
|
78
|
+
# Otherwise, determine if it uses presentation XML
|
79
|
+
if @processor.use_presentation_xml(ext)
|
80
|
+
# Format requires presentation XML first, then convert to final format
|
81
|
+
process_via_presentation_xml(ext, output_paths, options, isodoc_options)
|
82
|
+
else
|
83
|
+
# Format can be generated directly from semantic XML
|
84
|
+
process_from_semantic_xml(
|
85
|
+
ext, output_paths, semantic_xml, isodoc_options
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Process special extensions with custom handling
|
91
|
+
def process_ext_special(
|
92
|
+
ext, sem_xml, bibdata, output_paths, options, isodoc_options
|
93
|
+
)
|
94
|
+
if ext == :rxl
|
95
|
+
# Special case: Relaton export
|
96
|
+
export_relaton_from_bibdata(
|
97
|
+
bibdata,
|
98
|
+
options.merge(relaton: output_paths[:out]),
|
99
|
+
)
|
100
|
+
true
|
101
|
+
elsif ext == :presentation && options[:passthrough_presentation_xml]
|
102
|
+
# Special case: Pass through presentation XML
|
103
|
+
f = if File.exist?(output_paths[:orig_filename])
|
104
|
+
output_paths[:orig_filename]
|
105
|
+
else
|
106
|
+
output_paths[:xml]
|
107
|
+
end
|
108
|
+
FileUtils.cp f, output_paths[:presentationxml]
|
109
|
+
true
|
110
|
+
elsif ext == :html && options[:sectionsplit]
|
111
|
+
# Special case: Split HTML into sections
|
112
|
+
sectionsplit_convert(
|
113
|
+
output_paths[:xml], sem_xml, output_paths[:out], isodoc_options
|
114
|
+
)
|
115
|
+
true
|
116
|
+
else
|
117
|
+
false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Process format that requires presentation XML
|
122
|
+
def process_via_presentation_xml(ext, output_paths, options, isodoc_options)
|
123
|
+
@queue.schedule(ext, output_paths.dup, options.dup,
|
124
|
+
isodoc_options.dup) do |a, b, c, d|
|
125
|
+
process_output_from_presentation_xml(a, b, c, d)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Generate output format from presentation XML
|
130
|
+
def process_output_from_presentation_xml(ext, output_paths, options,
|
131
|
+
isodoc_options)
|
132
|
+
@processor.output(nil, output_paths[:presentationxml],
|
133
|
+
output_paths[:out], ext, isodoc_options)
|
134
|
+
wrap_html(options, output_paths[:ext], output_paths[:out])
|
135
|
+
rescue StandardError => e
|
136
|
+
strict = ext == :presentation || isodoc_options[:strict] == true
|
137
|
+
isodoc_error_process(e, strict, false)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Process format directly from semantic XML
|
141
|
+
def process_from_semantic_xml(ext, output_paths, sem_xml, isodoc_options)
|
142
|
+
@processor.output(sem_xml, output_paths[:xml], output_paths[:out],
|
143
|
+
ext, isodoc_options)
|
144
|
+
true # Return as Thread equivalent
|
145
|
+
rescue StandardError => e
|
146
|
+
strict = ext == :presentation || isodoc_options[:strict] == "true"
|
147
|
+
isodoc_error_process(e, strict, true)
|
148
|
+
ext != :presentation
|
149
|
+
end
|
150
|
+
|
151
|
+
# assume we pass in Presentation XML, but we want to recover Semantic XML
|
152
|
+
def sectionsplit_convert(input_filename, file, output_filename = nil,
|
153
|
+
opts = {})
|
154
|
+
@isodoc ||= IsoDoc::PresentationXMLConvert.new({})
|
155
|
+
input_filename += ".xml" unless input_filename.match?(/\.xml$/)
|
156
|
+
File.exist?(input_filename) or export_output(input_filename, file)
|
157
|
+
presxml = File.read(input_filename, encoding: "utf-8")
|
158
|
+
_xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
|
159
|
+
::Metanorma::Collection::Sectionsplit.new(
|
160
|
+
input: input_filename, isodoc: @isodoc, xml: presxml,
|
161
|
+
base: File.basename(output_filename || filename),
|
162
|
+
output: output_filename || filename, dir: dir, compile_opts: opts
|
163
|
+
).build_collection
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def isodoc_error_process(err, strict, must_abort)
|
169
|
+
if strict || err.message.include?("Fatal:")
|
170
|
+
@errors << err.message
|
171
|
+
else
|
172
|
+
puts err.message
|
173
|
+
end
|
174
|
+
puts err.backtrace.join("\n")
|
175
|
+
must_abort and 1
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -9,19 +9,17 @@ module Metanorma
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def validate_type!(options)
|
12
|
-
|
12
|
+
options[:type] or
|
13
13
|
Util.log("[metanorma] Error: Please specify a standard type: "\
|
14
14
|
"#{@registry.supported_backends}.", :fatal)
|
15
|
-
end
|
16
15
|
stdtype = options[:type].to_sym
|
17
16
|
load_flavor(stdtype)
|
18
17
|
end
|
19
18
|
|
20
19
|
def validate_format!(options)
|
21
|
-
|
20
|
+
options[:format] == :asciidoc or
|
22
21
|
Util.log("[metanorma] Error: Only source file format currently "\
|
23
22
|
"supported is 'asciidoc'.", :fatal)
|
24
|
-
end
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -13,8 +13,14 @@ module Metanorma
|
|
13
13
|
::Asciidoctor.convert(file, out_opts)
|
14
14
|
end
|
15
15
|
|
16
|
+
def header(file)
|
17
|
+
ret = file.split("\n\n", 2) or return [nil, nil]
|
18
|
+
ret[0] and ret[0] += "\n"
|
19
|
+
[ret[0], ret[1]]
|
20
|
+
end
|
21
|
+
|
16
22
|
def extract_metanorma_options(file)
|
17
|
-
hdr = file
|
23
|
+
hdr, = header(file)
|
18
24
|
/\n:(?:mn-)?(?:document-class|flavor):\s+(?<type>\S[^\n]*)\n/ =~ hdr
|
19
25
|
/\n:(?:mn-)?output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ hdr
|
20
26
|
/\n:(?:mn-)?relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ hdr
|
@@ -22,7 +28,7 @@ module Metanorma
|
|
22
28
|
/\n(?<novalid>:novalid:[^\n]*)\n/ =~ hdr
|
23
29
|
if defined?(asciimath)
|
24
30
|
asciimath =
|
25
|
-
!asciimath.nil? && !/keep-asciimath
|
31
|
+
!asciimath.nil? && !/keep-asciimath:\s*false/.match?(asciimath)
|
26
32
|
end
|
27
33
|
asciimath = nil if asciimath == false
|
28
34
|
{
|
@@ -68,17 +74,17 @@ module Metanorma
|
|
68
74
|
end
|
69
75
|
|
70
76
|
def extract_options(file)
|
71
|
-
|
77
|
+
hdr, = header(file)
|
72
78
|
ret = ADOC_OPTIONS.each_with_object({}) do |w, acc|
|
73
|
-
m = /\n:#{w}:\s+([^\n]+)\n/.match(
|
79
|
+
m = /\n:#{w}:\s+([^\n]+)\n/.match(hdr) or next
|
74
80
|
acc[attr_name_normalise(w)] = m[1]&.strip
|
75
81
|
end
|
76
82
|
ret2 = EMPTY_ADOC_OPTIONS_DEFAULT_TRUE.each_with_object({}) do |w, acc|
|
77
|
-
m = /\n:#{w}:([^\n]*)\n/.match(
|
83
|
+
m = /\n:#{w}:([^\n]*)\n/.match(hdr) || [nil, "true"]
|
78
84
|
acc[attr_name_normalise(w)] = (m[1].strip != "false")
|
79
85
|
end
|
80
86
|
ret3 = EMPTY_ADOC_OPTIONS_DEFAULT_FALSE.each_with_object({}) do |w, acc|
|
81
|
-
m = /\n:#{w}:([^\n]*)\n/.match(
|
87
|
+
m = /\n:#{w}:([^\n]*)\n/.match(hdr) || [nil, "false"]
|
82
88
|
acc[attr_name_normalise(w)] = !["false"].include?(m[1].strip)
|
83
89
|
end
|
84
90
|
ret.merge(ret2).merge(ret3).compact
|
@@ -11,9 +11,11 @@ module Metanorma
|
|
11
11
|
|
12
12
|
attr_reader :processors
|
13
13
|
|
14
|
+
# TODO: make aliases configurable
|
14
15
|
def initialize
|
15
16
|
@processors = {}
|
16
|
-
@aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa
|
17
|
+
@aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa,
|
18
|
+
icc: :iso }
|
17
19
|
end
|
18
20
|
|
19
21
|
def alias(flavour)
|
@@ -21,18 +23,14 @@ module Metanorma
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def register(processor)
|
24
|
-
|
25
|
-
|
26
|
+
processor < ::Metanorma::Processor or raise Error
|
26
27
|
p = processor.new
|
27
28
|
# p.short[-1] is the canonical name
|
28
29
|
short = Array(p.short)
|
29
30
|
@processors[short[-1]] = p
|
30
|
-
short.each
|
31
|
-
@aliases[s] = short[-1]
|
32
|
-
end
|
31
|
+
short.each { |s| @aliases[s] = short[-1] }
|
33
32
|
Array(p.short)
|
34
|
-
Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered",
|
35
|
-
:info)
|
33
|
+
Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered", :info)
|
36
34
|
end
|
37
35
|
|
38
36
|
def find_processor(short)
|
data/lib/metanorma/version.rb
CHANGED
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.1.
|
4
|
+
version: 2.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -338,6 +338,7 @@ files:
|
|
338
338
|
- lib/metanorma/collection/util/disambig_files.rb
|
339
339
|
- lib/metanorma/collection/util/util.rb
|
340
340
|
- lib/metanorma/collection/xrefprocess/xrefprocess.rb
|
341
|
+
- lib/metanorma/compile/assets/icc-boilerplate.adoc
|
341
342
|
- lib/metanorma/compile/compile.rb
|
342
343
|
- lib/metanorma/compile/compile_options.rb
|
343
344
|
- lib/metanorma/compile/extract.rb
|
@@ -345,6 +346,7 @@ files:
|
|
345
346
|
- lib/metanorma/compile/output_filename.rb
|
346
347
|
- lib/metanorma/compile/output_filename_config.rb
|
347
348
|
- lib/metanorma/compile/relaton_drop.rb
|
349
|
+
- lib/metanorma/compile/render.rb
|
348
350
|
- lib/metanorma/compile/validator.rb
|
349
351
|
- lib/metanorma/compile/writeable.rb
|
350
352
|
- lib/metanorma/config/config.rb
|