metanorma 2.1.4 → 2.1.5
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/.rubocop.yml +4 -1
- data/lib/metanorma/collection/manifest/manifest.rb +1 -1
- data/lib/metanorma/collection/renderer/navigation.rb +1 -1
- data/lib/metanorma/compile/compile.rb +248 -92
- data/lib/metanorma/compile/compile_options.rb +87 -82
- data/lib/metanorma/compile/extract.rb +76 -56
- data/lib/metanorma/compile/flavor.rb +57 -0
- data/lib/metanorma/compile/output_filename.rb +75 -0
- data/lib/metanorma/compile/output_filename_config.rb +27 -0
- data/lib/metanorma/compile/relaton_drop.rb +56 -0
- data/lib/metanorma/compile/validator.rb +28 -0
- data/lib/metanorma/compile/writeable.rb +12 -0
- data/lib/metanorma/version.rb +1 -1
- data/metanorma.gemspec +1 -1
- metadata +8 -3
- data/lib/metanorma/compile/compile_validate.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6fcf07578e0bbbcd55d7ea1cbdafbe588333b5060ad10b1bb4e0851b33e4036
|
4
|
+
data.tar.gz: 7a91ca6650c240fe06eb68fc5986617662cdd6958160ecea1dafeeb09dd644e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34989eb8241876f89038ecc1dd1353c09f9c54961b74b50048eddd330eb0a24eca628ad0e8a893108042ad4b89b57b8de8e9ff32166b7eb2e3098f0ef4340bb2
|
7
|
+
data.tar.gz: 2f9d6d4f182481d8b02b46082bafd6d75fb8d6b1a72c42987a161c60fb3a00fb4d8c5cc53674a9d001996f64bc8cea9b9e854b9d544af5126db1070c30413ac5
|
data/.rubocop.yml
CHANGED
@@ -136,7 +136,7 @@ module Metanorma
|
|
136
136
|
#require "debug"; binding.b
|
137
137
|
entry.file && !(Pathname.new entry.file).absolute? and
|
138
138
|
entry.file = File.join(prefix, entry.file)
|
139
|
-
entry
|
139
|
+
entry&.entry&.each do |f|
|
140
140
|
update_filepaths(f, prefix)
|
141
141
|
end
|
142
142
|
end
|
@@ -1,21 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "fileutils"
|
2
4
|
require "nokogiri"
|
3
5
|
require "htmlentities"
|
4
6
|
require "yaml"
|
5
7
|
require "fontist"
|
6
8
|
require "fontist/manifest/install"
|
7
|
-
require_relative "
|
9
|
+
require_relative "writeable"
|
10
|
+
require_relative "validator"
|
8
11
|
require_relative "compile_options"
|
9
12
|
require_relative "../util/fontist_helper"
|
10
13
|
require_relative "../util/util"
|
11
14
|
require_relative "extract"
|
12
15
|
require_relative "../collection/sectionsplit/sectionsplit"
|
13
16
|
require_relative "../util/worker_pool"
|
17
|
+
require_relative "output_filename"
|
18
|
+
require_relative "output_filename_config"
|
19
|
+
require_relative "flavor"
|
20
|
+
require_relative "relaton_drop"
|
14
21
|
|
15
22
|
module Metanorma
|
16
23
|
class Compile
|
24
|
+
include Validator
|
25
|
+
include CompileOptions
|
26
|
+
include Flavor
|
27
|
+
include Writeable
|
28
|
+
|
29
|
+
DEFAULT_NUM_WORKERS = 3
|
30
|
+
|
17
31
|
# @return [Array<String>]
|
18
|
-
attr_reader :errors
|
32
|
+
attr_reader :errors
|
33
|
+
attr_reader :processor
|
19
34
|
|
20
35
|
def initialize
|
21
36
|
@registry = Metanorma::Registry.instance
|
@@ -25,22 +40,48 @@ module Metanorma
|
|
25
40
|
@log = Metanorma::Utils::Log.new
|
26
41
|
end
|
27
42
|
|
43
|
+
# Main compile method that orchestrates the document conversion process
|
44
|
+
# @param filename [String] path to the input file
|
45
|
+
# @param options [Hash] compilation options
|
28
46
|
def compile(filename, options = {})
|
29
|
-
|
47
|
+
process_options!(filename, options)
|
30
48
|
@processor = @registry.find_processor(options[:type].to_sym)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
49
|
+
|
50
|
+
# Step 1: Generate Semantic XML
|
51
|
+
semantic_result = generate_semantic_xml(filename, options)
|
52
|
+
return nil unless semantic_result
|
53
|
+
|
54
|
+
source_file, semantic_xml = semantic_result
|
55
|
+
|
56
|
+
# Step 2: Prepare output paths
|
57
|
+
xml = Nokogiri::XML(semantic_xml, &:huge)
|
58
|
+
bibdata = extract_relaton_metadata(xml)
|
59
|
+
output_paths = prepare_output_paths(filename, bibdata, options)
|
60
|
+
|
61
|
+
# Step 3: Determine which output formats to generate
|
62
|
+
extensions = get_extensions(options)
|
63
|
+
return nil unless extensions
|
64
|
+
|
65
|
+
# Step 4: Extract information from Semantic XML if requested
|
66
|
+
extract_information(semantic_xml, bibdata, options)
|
67
|
+
|
68
|
+
# Step 5: Generate output formats from Semantic XML
|
69
|
+
generate_outputs(
|
70
|
+
source_file,
|
71
|
+
semantic_xml,
|
72
|
+
bibdata,
|
73
|
+
extensions,
|
74
|
+
output_paths,
|
75
|
+
options,
|
76
|
+
)
|
36
77
|
ensure
|
37
78
|
clean_exit(options)
|
38
79
|
end
|
39
80
|
|
40
|
-
def
|
81
|
+
def process_options!(filename, options)
|
41
82
|
require_libraries(options)
|
42
|
-
options =
|
43
|
-
validate_options(options)
|
83
|
+
options = extract_options(filename, options)
|
84
|
+
validate_options!(options)
|
44
85
|
@log.save_to(filename, options[:output_dir])
|
45
86
|
options[:log] = @log
|
46
87
|
end
|
@@ -50,7 +91,11 @@ module Metanorma
|
|
50
91
|
@log.write
|
51
92
|
end
|
52
93
|
|
53
|
-
|
94
|
+
# Step 1: Generate Semantic XML from input file
|
95
|
+
# @param filename [String] input file path
|
96
|
+
# @param options [Hash] compilation options
|
97
|
+
# @return [Array, nil] tuple of [source_file, semantic_xml] or nil on failure
|
98
|
+
def generate_semantic_xml(filename, options)
|
54
99
|
case extname = File.extname(filename)
|
55
100
|
when ".adoc" then process_input_adoc(filename, options)
|
56
101
|
when ".xml" then process_input_xml(filename, options)
|
@@ -61,6 +106,113 @@ module Metanorma
|
|
61
106
|
end
|
62
107
|
end
|
63
108
|
|
109
|
+
# Step 2: Prepare output paths for generated files
|
110
|
+
# Use default filename template if empty string is provided.
|
111
|
+
#
|
112
|
+
# @param filename [String] input file path
|
113
|
+
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
114
|
+
# @param options [Hash] compilation options
|
115
|
+
# @return [Hash] paths for different output formats
|
116
|
+
def prepare_output_paths(filename, bibdata, options)
|
117
|
+
basename = if !options[:filename_template].nil?
|
118
|
+
drop = RelatonDrop.new(bibdata)
|
119
|
+
config = OutputFilenameConfig.new(options[:filename_template])
|
120
|
+
config.generate_filename(drop)
|
121
|
+
else
|
122
|
+
filename.sub(/\.[^.]+$/, "")
|
123
|
+
end
|
124
|
+
|
125
|
+
@output_filename = OutputFilename.new(
|
126
|
+
basename,
|
127
|
+
options[:output_dir],
|
128
|
+
@processor,
|
129
|
+
)
|
130
|
+
|
131
|
+
{
|
132
|
+
xml: @output_filename.semantic_xml,
|
133
|
+
orig_filename: filename,
|
134
|
+
presentationxml: @output_filename.presentation_xml,
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
# Step 4: Extract information from Semantic XML
|
139
|
+
# @param semantic_xml [String] semantic XML content
|
140
|
+
# @param options [Hash] compilation options
|
141
|
+
def extract_information(semantic_xml, bibdata, options)
|
142
|
+
# Extract Relaton bibliographic data
|
143
|
+
export_relaton_from_bibdata(bibdata, options) if options[:relaton]
|
144
|
+
|
145
|
+
# Extract other components (sourcecode, images, requirements)
|
146
|
+
if options[:extract]
|
147
|
+
Extract.extract(
|
148
|
+
semantic_xml,
|
149
|
+
options[:extract],
|
150
|
+
options[:extract_type],
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Step 5: Generate output formats from Semantic XML
|
156
|
+
# @param source_file [String] source file content
|
157
|
+
# @param semantic_xml [String] semantic XML content
|
158
|
+
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
159
|
+
# @param extensions [Array<Symbol>] output formats to generate
|
160
|
+
# @param output_paths [Hash] paths for output files
|
161
|
+
# @param options [Hash] compilation options
|
162
|
+
def generate_outputs(
|
163
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
164
|
+
)
|
165
|
+
if extensions == %i(presentation)
|
166
|
+
# Just generate presentation XML
|
167
|
+
generate_presentation_xml(
|
168
|
+
source_file, semantic_xml, bibdata, output_paths, options
|
169
|
+
)
|
170
|
+
else
|
171
|
+
# Generate multiple output formats with parallel processing
|
172
|
+
generate_outputs_parallel(
|
173
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
174
|
+
)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Generate presentation XML from semantic XML
|
179
|
+
def generate_presentation_xml(
|
180
|
+
source_file, semantic_xml, bibdata, output_paths, options
|
181
|
+
)
|
182
|
+
process_ext(
|
183
|
+
:presentation, source_file, semantic_xml, bibdata, output_paths, options
|
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
|
204
|
+
end
|
205
|
+
|
206
|
+
def process_extensions_in_order(
|
207
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
208
|
+
)
|
209
|
+
Util.sort_extensions_execution(extensions).each do |ext|
|
210
|
+
process_ext(
|
211
|
+
ext, source_file, semantic_xml, bibdata, output_paths, options
|
212
|
+
) or break
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
64
216
|
def process_input_adoc(filename, options)
|
65
217
|
Util.log("[metanorma] Processing: AsciiDoc input.", :info)
|
66
218
|
file = read_file(filename)
|
@@ -84,19 +236,21 @@ module Metanorma
|
|
84
236
|
File.read(filename, encoding: "utf-8").gsub("\r\n", "\n")
|
85
237
|
end
|
86
238
|
|
87
|
-
|
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)
|
88
243
|
return unless options[:relaton]
|
89
244
|
|
90
|
-
xml = Nokogiri::XML(isodoc, &:huge)
|
91
|
-
bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
|
92
245
|
# docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
|
93
246
|
# outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
|
94
|
-
|
247
|
+
export_output(options[:relaton], bibdata.to_xml)
|
95
248
|
end
|
96
249
|
|
97
|
-
|
98
|
-
|
99
|
-
|
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")
|
100
254
|
end
|
101
255
|
|
102
256
|
def wrap_html(options, file_extension, outfilename)
|
@@ -109,90 +263,101 @@ module Metanorma
|
|
109
263
|
end
|
110
264
|
|
111
265
|
# isodoc is Raw Metanorma XML
|
112
|
-
def process_exts(filename, extensions, file, isodoc, options)
|
113
|
-
f = File.expand_path(change_output_dir(options))
|
114
|
-
fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
|
115
|
-
orig_filename: File.expand_path(filename),
|
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
266
|
|
124
|
-
def
|
125
|
-
@queue = ::Metanorma::Util::WorkersPool
|
126
|
-
.new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
|
127
|
-
gather_and_install_fonts(file, options.dup, extensions)
|
128
|
-
process_exts_run(fnames, file, isodoc, extensions, options)
|
129
|
-
@queue.shutdown
|
130
|
-
end
|
131
|
-
|
132
|
-
def process_exts_run(fnames, file, isodoc, extensions, options)
|
267
|
+
def gather_and_install_fonts(source_file, options, extensions)
|
133
268
|
Util.sort_extensions_execution(extensions).each do |ext|
|
134
|
-
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def gather_and_install_fonts(file, options, extensions)
|
139
|
-
Util.sort_extensions_execution(extensions).each do |ext|
|
140
|
-
isodoc_options = get_isodoc_options(file, options, ext)
|
269
|
+
isodoc_options = get_isodoc_options(source_file, options, ext)
|
141
270
|
font_install(isodoc_options.merge(options))
|
142
271
|
end
|
143
272
|
end
|
144
273
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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
|
+
)
|
153
296
|
end
|
154
|
-
thread
|
155
297
|
end
|
156
298
|
|
157
|
-
|
299
|
+
# Process special extensions with custom handling
|
300
|
+
def process_ext_special(
|
301
|
+
ext, semantic_xml, bibdata, output_paths, options, isodoc_options
|
302
|
+
)
|
158
303
|
if ext == :rxl
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
+
|
164
324
|
elsif ext == :html && options[:sectionsplit]
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
168
333
|
end
|
169
|
-
true
|
170
334
|
end
|
171
335
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
178
|
-
else
|
179
|
-
process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
|
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)
|
180
341
|
end
|
181
342
|
end
|
182
343
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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])
|
187
350
|
rescue StandardError => e
|
188
|
-
strict = ext == :presentation ||
|
351
|
+
strict = ext == :presentation || isodoc_options[:strict] == true
|
189
352
|
isodoc_error_process(e, strict, false)
|
190
353
|
end
|
191
354
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
196
361
|
rescue StandardError => e
|
197
362
|
strict = ext == :presentation || isodoc_options[:strict] == "true"
|
198
363
|
isodoc_error_process(e, strict, true)
|
@@ -205,7 +370,7 @@ module Metanorma
|
|
205
370
|
@isodoc ||= IsoDoc::PresentationXMLConvert.new({})
|
206
371
|
input_filename += ".xml" unless input_filename.match?(/\.xml$/)
|
207
372
|
File.exist?(input_filename) or
|
208
|
-
|
373
|
+
export_output(input_filename, file)
|
209
374
|
presxml = File.read(input_filename, encoding: "utf-8")
|
210
375
|
_xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
|
211
376
|
|
@@ -231,14 +396,5 @@ module Metanorma
|
|
231
396
|
puts err.backtrace.join("\n")
|
232
397
|
must_abort and 1
|
233
398
|
end
|
234
|
-
|
235
|
-
# @param options [Hash]
|
236
|
-
# @return [String]
|
237
|
-
def change_output_dir(options)
|
238
|
-
if options[:output_dir]
|
239
|
-
File.join options[:output_dir], File.basename(options[:filename])
|
240
|
-
else options[:filename]
|
241
|
-
end
|
242
|
-
end
|
243
399
|
end
|
244
400
|
end
|
@@ -2,104 +2,109 @@ require "csv"
|
|
2
2
|
|
3
3
|
module Metanorma
|
4
4
|
class Compile
|
5
|
-
|
6
|
-
options
|
7
|
-
|
5
|
+
module CompileOptions
|
6
|
+
def require_libraries(options)
|
7
|
+
options&.dig(:require)&.each { |r| require r }
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def extract_xml_options(file)
|
11
|
+
xml = Nokogiri::XML(file, &:huge)
|
12
|
+
if xml.root
|
13
|
+
@registry.root_tags.each do |k, v|
|
14
|
+
return { type: k } if v == xml.root.name
|
15
|
+
end
|
14
16
|
end
|
17
|
+
{}
|
15
18
|
end
|
16
|
-
{}
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
20
|
+
def extract_options(filename, options)
|
21
|
+
content = read_file(filename)
|
22
|
+
o = Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
|
23
|
+
.merge(extract_xml_options(content))
|
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
|
32
|
+
options[:extension_keys] ||= o[:extensions]&.split(/, */)&.map(&:to_sym)
|
33
|
+
options[:extension_keys] = nil if options[:extension_keys] == [:all]
|
34
|
+
options[:format] ||= :asciidoc
|
35
|
+
options[:filename] = filename
|
36
|
+
options[:fontlicenseagreement] ||= "no-install-fonts"
|
37
|
+
options[:novalid] = o[:novalid] if o[:novalid]
|
38
|
+
options
|
39
|
+
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
def get_extensions(options)
|
42
|
+
ext = extract_extensions(options)
|
43
|
+
!ext.include?(:presentation) && ext.any? do |e|
|
44
|
+
@processor.use_presentation_xml(e)
|
45
|
+
end and ext << :presentation
|
46
|
+
!ext.include?(:rxl) && options[:site_generate] and
|
47
|
+
ext << :rxl
|
48
|
+
ext
|
49
|
+
end
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def extract_extensions(options)
|
52
|
+
options[:extension_keys] ||=
|
53
|
+
@processor.output_formats.reduce([]) { |memo, (k, _)| memo << k }
|
54
|
+
options[:extension_keys].reduce([]) do |memo, e|
|
55
|
+
if @processor.output_formats[e] then memo << e
|
56
|
+
else
|
57
|
+
unsupported_format_error(e)
|
58
|
+
memo
|
59
|
+
end
|
55
60
|
end
|
56
61
|
end
|
57
|
-
end
|
58
62
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
def font_install(opt)
|
64
|
+
@fontist_installed or
|
65
|
+
Util::FontistHelper.install_fonts(@processor, opt)
|
66
|
+
@fontist_installed = true
|
67
|
+
end
|
64
68
|
|
65
|
-
|
69
|
+
private
|
66
70
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
def unsupported_format_error(ext)
|
72
|
+
message = "[metanorma] Error: #{ext} format is not supported " \
|
73
|
+
"for this standard."
|
74
|
+
@errors << message
|
75
|
+
Util.log(message, :error)
|
76
|
+
end
|
73
77
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
78
|
+
def get_isodoc_options(file, options, ext)
|
79
|
+
ret = @processor.extract_options(file)
|
80
|
+
dir = options[:filename].sub(%r(/[^/]+$), "/")
|
81
|
+
ret[:i18nyaml] &&= File.join(dir, ret[:i18nyaml])
|
82
|
+
copy_isodoc_options_attrs(options, ret)
|
83
|
+
font_manifest_mn2pdf(options, ret, ext)
|
84
|
+
ret[:output_formats]&.select! do |k, _|
|
85
|
+
options[:extension_keys].include?(k)
|
86
|
+
end
|
87
|
+
ret[:log] = @log
|
88
|
+
ret
|
82
89
|
end
|
83
|
-
ret[:log] = @log
|
84
|
-
ret
|
85
|
-
end
|
86
90
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
def copy_isodoc_options_attrs(options, ret)
|
92
|
+
ret[:datauriimage] = true if options[:datauriimage]
|
93
|
+
ret[:sourcefilename] = options[:filename]
|
94
|
+
%i(bare sectionsplit install_fonts baseassetpath aligncrosselements
|
95
|
+
tocfigures toctables tocrecommendations strict)
|
96
|
+
.each { |x| ret[x] ||= options[x] }
|
97
|
+
end
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
|
99
|
+
def font_manifest_mn2pdf(options, ret, ext)
|
100
|
+
custom_fonts = Util::FontistHelper
|
101
|
+
.has_custom_fonts?(@processor, options, ret)
|
98
102
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
+
ext == :pdf && custom_fonts and
|
104
|
+
ret[:mn2pdf] = {
|
105
|
+
font_manifest: Util::FontistHelper.location_manifest(@processor, ret),
|
106
|
+
}
|
107
|
+
end
|
103
108
|
end
|
104
109
|
end
|
105
110
|
end
|
@@ -1,68 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "writeable"
|
4
|
+
|
1
5
|
module Metanorma
|
2
6
|
class Compile
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
module Extract
|
8
|
+
# @param isodoc [String] the XML document
|
9
|
+
# @param dirname [String, nil] the directory to extract to
|
10
|
+
# @param extract_types [Array<Symbol>, nil] the types to extract
|
11
|
+
# @return [void]
|
12
|
+
def self.extract(isodoc, dirname, extract_types)
|
13
|
+
dirname or return
|
14
|
+
extract_types.nil? || extract_types.empty? and
|
15
|
+
extract_types = %i[sourcecode image requirement]
|
16
|
+
FileUtils.rm_rf dirname
|
17
|
+
FileUtils.mkdir_p dirname
|
18
|
+
xml = Nokogiri::XML(isodoc, &:huge)
|
19
|
+
extract_types.each do |type|
|
20
|
+
case type
|
21
|
+
when :sourcecode
|
22
|
+
export_sourcecode(xml, dirname)
|
23
|
+
when :image
|
24
|
+
export_image(xml, dirname)
|
25
|
+
when :requirement
|
26
|
+
export_requirement(xml, dirname)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
9
30
|
|
10
|
-
|
11
|
-
|
12
|
-
".//xmlns:annotation").each(&:remove)
|
13
|
-
xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
|
14
|
-
a = xml.at("./body | ./xmlns:body") and xml = a
|
15
|
-
HTMLEntities.new.decode(xml.children.to_xml)
|
16
|
-
end
|
31
|
+
class << self
|
32
|
+
include Writeable
|
17
33
|
|
18
|
-
|
19
|
-
dirname or return
|
20
|
-
extract_types.nil? || extract_types.empty? and
|
21
|
-
extract_types = %i[sourcecode image requirement]
|
22
|
-
FileUtils.rm_rf dirname
|
23
|
-
FileUtils.mkdir_p dirname
|
24
|
-
xml = Nokogiri::XML(isodoc, &:huge)
|
25
|
-
sourcecode_export(xml, dirname) if extract_types.include? :sourcecode
|
26
|
-
image_export(xml, dirname) if extract_types.include? :image
|
27
|
-
extract_types.include?(:requirement) and
|
28
|
-
requirement_export(xml, dirname)
|
29
|
-
end
|
34
|
+
private
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
# @param xml [Nokogiri::XML::Document] the XML document
|
37
|
+
# @return [String] the cleaned sourcecode
|
38
|
+
def clean_sourcecode(xml)
|
39
|
+
xml.xpath(".//callout | .//annotation | .//xmlns:callout | "\
|
40
|
+
".//xmlns:annotation").each(&:remove)
|
41
|
+
xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
|
42
|
+
a = xml.at("./body | ./xmlns:body") and xml = a
|
43
|
+
HTMLEntities.new.decode(xml.children.to_xml)
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
def export_sourcecode(xml, dirname)
|
47
|
+
xml.at("//sourcecode | //xmlns:sourcecode") or return
|
48
|
+
FileUtils.mkdir_p "#{dirname}/sourcecode"
|
49
|
+
xml.xpath("//sourcecode | //xmlns:sourcecode").each_with_index do |s, i|
|
50
|
+
filename = s["filename"] || sprintf("sourcecode-%04d.txt", i)
|
51
|
+
export_output("#{dirname}/sourcecode/#{filename}",
|
52
|
+
clean_sourcecode(s.dup))
|
53
|
+
end
|
54
|
+
end
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
56
|
+
def export_image(xml, dirname)
|
57
|
+
xml.at("//image | //xmlns:image") or return
|
58
|
+
FileUtils.mkdir_p "#{dirname}/image"
|
59
|
+
xml.xpath("//image | //xmlns:image").each_with_index do |s, i|
|
60
|
+
next unless /^data:image/.match? s["src"]
|
61
|
+
|
62
|
+
%r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ s["src"]
|
63
|
+
fn = s["filename"] || sprintf("image-%<num>04d.%<name>s",
|
64
|
+
num: i, name: imgtype)
|
65
|
+
export_output(
|
66
|
+
"#{dirname}/image/#{fn}",
|
67
|
+
Base64.strict_decode64(imgdata),
|
68
|
+
binary: true,
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
54
72
|
|
55
|
-
|
56
|
-
|
57
|
-
|
73
|
+
REQUIREMENT_XPATH =
|
74
|
+
"//requirement | //xmlns:requirement | //recommendation | "\
|
75
|
+
"//xmlns:recommendation | //permission | //xmlns:permission"
|
58
76
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
77
|
+
def export_requirement(xml, dirname)
|
78
|
+
xml.at(REQUIREMENT_XPATH) or return
|
79
|
+
FileUtils.mkdir_p "#{dirname}/requirement"
|
80
|
+
xml.xpath(REQUIREMENT_XPATH).each_with_index do |s, i|
|
81
|
+
fn = s["filename"] ||
|
82
|
+
sprintf("%<name>s-%<num>04d.xml", name: s.name, num: i)
|
83
|
+
export_output("#{dirname}/requirement/#{fn}", s)
|
84
|
+
end
|
85
|
+
end
|
66
86
|
end
|
67
87
|
end
|
68
88
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
class Compile
|
5
|
+
module Flavor
|
6
|
+
# Load the flavor gem for the given standard type
|
7
|
+
# @param stdtype [Symbol] the standard type
|
8
|
+
# @return [void]
|
9
|
+
def load_flavor(stdtype)
|
10
|
+
stdtype = stdtype.to_sym
|
11
|
+
flavor = stdtype2flavor(stdtype)
|
12
|
+
@registry.supported_backends.include? stdtype or
|
13
|
+
Util.log("[metanorma] Info: Loading `#{flavor}` gem "\
|
14
|
+
"for standard type `#{stdtype}`.", :info)
|
15
|
+
require_flavor(flavor)
|
16
|
+
@registry.supported_backends.include? stdtype or
|
17
|
+
Util.log("[metanorma] Error: The `#{flavor}` gem does not "\
|
18
|
+
"support the standard type #{stdtype}. Exiting.", :fatal)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Convert the standard type to the flavor gem name
|
22
|
+
# @param stdtype [Symbol] the standard type
|
23
|
+
# @return [String] the flavor gem name
|
24
|
+
def stdtype2flavor(stdtype)
|
25
|
+
flavor = STDTYPE2FLAVOR[stdtype] || stdtype
|
26
|
+
"metanorma-#{flavor}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
STDTYPE2FLAVOR = {}.freeze
|
32
|
+
|
33
|
+
def require_flavor(flavor)
|
34
|
+
require flavor
|
35
|
+
Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
|
36
|
+
rescue LoadError => e
|
37
|
+
error_log = "#{Date.today}-error.log"
|
38
|
+
File.write(error_log, e)
|
39
|
+
|
40
|
+
msg = <<~MSG
|
41
|
+
Error: #{e.message}
|
42
|
+
Metanorma has encountered an exception.
|
43
|
+
|
44
|
+
If this problem persists, please report this issue at the following link:
|
45
|
+
|
46
|
+
* https://github.com/metanorma/metanorma/issues/new
|
47
|
+
|
48
|
+
Please attach the #{error_log} file.
|
49
|
+
Your valuable feedback is very much appreciated!
|
50
|
+
|
51
|
+
- The Metanorma team
|
52
|
+
MSG
|
53
|
+
Util.log(msg, :fatal)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
class Compile
|
5
|
+
class OutputFilename
|
6
|
+
# Returns an instance of OutputFilename from the source filename
|
7
|
+
# @param source_filename [String] the source filename
|
8
|
+
# @param output_dir [String, nil] the output directory
|
9
|
+
# @param processor [Metanorma::Processor, nil] the processor
|
10
|
+
# @return [OutputFilename] the instance of OutputFilename
|
11
|
+
def self.from_filename(source_filename, output_dir = nil, processor = nil)
|
12
|
+
new(strip_ext(source_filename), output_dir, processor)
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
private
|
17
|
+
|
18
|
+
def strip_ext(filename)
|
19
|
+
filename.sub(/\.[^.]*$/, "")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param noext_filename [String] the path (absolute/relative) of the source file, without extension (e.g., "/a/b/c/test")
|
24
|
+
# @param output_dir [String, nil] the output directory
|
25
|
+
# @param processor [Metanorma::Processor, nil] the processor
|
26
|
+
# @return [OutputFilename] the instance of OutputFilename
|
27
|
+
def initialize(noext_filename, output_dir = nil, processor = nil)
|
28
|
+
@noext_filename = noext_filename
|
29
|
+
@output_dir = output_dir
|
30
|
+
@processor = processor
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the full file path name with the semantic XML extension
|
34
|
+
# @return [String] the full file path name with the semantic XML extension
|
35
|
+
def semantic_xml
|
36
|
+
with_extension("xml")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the full file path name with the presentation XML extension
|
40
|
+
# @return [String] the full file path name with the presentation XML extension
|
41
|
+
def presentation_xml
|
42
|
+
with_extension("presentation.xml")
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the full file path name with the given format extension
|
46
|
+
# @param format [Symbol] the format
|
47
|
+
# @return [String, nil] the full file path name with the format extension
|
48
|
+
def for_format(format)
|
49
|
+
ext = @processor&.output_formats&.[](format)
|
50
|
+
ext ? with_extension(ext) : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the full file path name with the given extension
|
54
|
+
# @param ext [String] the extension
|
55
|
+
# @return [String] the full file path name with the extension
|
56
|
+
def with_extension(ext)
|
57
|
+
file = change_output_dir
|
58
|
+
"#{file}.#{ext}"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def change_output_dir
|
64
|
+
File.expand_path(if !@output_dir.nil?
|
65
|
+
File.join(
|
66
|
+
@output_dir,
|
67
|
+
File.basename(@noext_filename),
|
68
|
+
)
|
69
|
+
else
|
70
|
+
@noext_filename
|
71
|
+
end)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
class Compile
|
5
|
+
class OutputFilenameConfig
|
6
|
+
DEFAULT_TEMPLATE =
|
7
|
+
"{{ document.docidentifier | downcase" \
|
8
|
+
" | replace: '/' , '-'" \
|
9
|
+
" | replace: ' ' , '-' }}"
|
10
|
+
|
11
|
+
attr_reader :template
|
12
|
+
|
13
|
+
def initialize(template)
|
14
|
+
@template = if template.nil? || template.empty?
|
15
|
+
DEFAULT_TEMPLATE
|
16
|
+
else
|
17
|
+
template
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_filename(relaton_data)
|
22
|
+
template = Liquid::Template.parse(@template)
|
23
|
+
template.render("document" => relaton_data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "liquid"
|
4
|
+
|
5
|
+
module Metanorma
|
6
|
+
class Compile
|
7
|
+
class RelatonDrop < Liquid::Drop
|
8
|
+
def initialize(relaton_data)
|
9
|
+
@relaton = relaton_data
|
10
|
+
end
|
11
|
+
|
12
|
+
def docidentifier
|
13
|
+
at("./docidentifier")
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
at("./title")
|
18
|
+
end
|
19
|
+
|
20
|
+
def date
|
21
|
+
at("./date/on")
|
22
|
+
end
|
23
|
+
|
24
|
+
def publisher
|
25
|
+
at("./contributor[role/@type = 'publisher']/organization/name")
|
26
|
+
end
|
27
|
+
|
28
|
+
def language
|
29
|
+
at("./language")
|
30
|
+
end
|
31
|
+
|
32
|
+
def script
|
33
|
+
at("./script")
|
34
|
+
end
|
35
|
+
|
36
|
+
def version
|
37
|
+
at("./version")
|
38
|
+
end
|
39
|
+
|
40
|
+
def slugify
|
41
|
+
docidentifier&.downcase
|
42
|
+
&.gsub(/[^a-z0-9]+/, "-")
|
43
|
+
&.gsub(/-+/, "-")
|
44
|
+
&.gsub(/^-|-$/, "")
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def at(xpath)
|
50
|
+
@relaton.at(xpath)&.text
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
class Compile
|
5
|
+
module Validator
|
6
|
+
def validate_options!(options)
|
7
|
+
validate_type!(options)
|
8
|
+
validate_format!(options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate_type!(options)
|
12
|
+
unless options[:type]
|
13
|
+
Util.log("[metanorma] Error: Please specify a standard type: "\
|
14
|
+
"#{@registry.supported_backends}.", :fatal)
|
15
|
+
end
|
16
|
+
stdtype = options[:type].to_sym
|
17
|
+
load_flavor(stdtype)
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_format!(options)
|
21
|
+
unless options[:format] == :asciidoc
|
22
|
+
Util.log("[metanorma] Error: Only source file format currently "\
|
23
|
+
"supported is 'asciidoc'.", :fatal)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/metanorma/version.rb
CHANGED
data/metanorma.gemspec
CHANGED
@@ -45,7 +45,7 @@ Gem::Specification.new do |spec|
|
|
45
45
|
spec.add_development_dependency "rspec", "~> 3.0"
|
46
46
|
spec.add_development_dependency "rspec-command", "~> 1.0"
|
47
47
|
spec.add_development_dependency "rubocop", "~> 1"
|
48
|
-
spec.add_development_dependency "rubocop-performance"
|
48
|
+
spec.add_development_dependency "rubocop-performance"
|
49
49
|
spec.add_development_dependency "sassc-embedded", "~> 1"
|
50
50
|
spec.add_development_dependency "simplecov", "~> 0.15"
|
51
51
|
spec.add_development_dependency "xml-c14n"
|
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.5
|
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-03-
|
11
|
+
date: 2025-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -340,8 +340,13 @@ files:
|
|
340
340
|
- lib/metanorma/collection/xrefprocess/xrefprocess.rb
|
341
341
|
- lib/metanorma/compile/compile.rb
|
342
342
|
- lib/metanorma/compile/compile_options.rb
|
343
|
-
- lib/metanorma/compile/compile_validate.rb
|
344
343
|
- lib/metanorma/compile/extract.rb
|
344
|
+
- lib/metanorma/compile/flavor.rb
|
345
|
+
- lib/metanorma/compile/output_filename.rb
|
346
|
+
- lib/metanorma/compile/output_filename_config.rb
|
347
|
+
- lib/metanorma/compile/relaton_drop.rb
|
348
|
+
- lib/metanorma/compile/validator.rb
|
349
|
+
- lib/metanorma/compile/writeable.rb
|
345
350
|
- lib/metanorma/config/config.rb
|
346
351
|
- lib/metanorma/input.rb
|
347
352
|
- lib/metanorma/input/asciidoc.rb
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class Compile
|
3
|
-
def validate_options(options)
|
4
|
-
validate_type(options)
|
5
|
-
validate_format(options)
|
6
|
-
end
|
7
|
-
|
8
|
-
def validate_type(options)
|
9
|
-
unless options[:type]
|
10
|
-
Util.log("[metanorma] Error: Please specify a standard type: "\
|
11
|
-
"#{@registry.supported_backends}.", :fatal)
|
12
|
-
end
|
13
|
-
stdtype = options[:type].to_sym
|
14
|
-
load_flavor(stdtype)
|
15
|
-
end
|
16
|
-
|
17
|
-
def validate_format(options)
|
18
|
-
unless options[:format] == :asciidoc
|
19
|
-
Util.log("[metanorma] Error: Only source file format currently "\
|
20
|
-
"supported is 'asciidoc'.", :fatal)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def load_flavor(stdtype)
|
25
|
-
stdtype = stdtype.to_sym
|
26
|
-
flavor = stdtype2flavor(stdtype)
|
27
|
-
@registry.supported_backends.include? stdtype or
|
28
|
-
Util.log("[metanorma] Info: Loading `#{flavor}` gem "\
|
29
|
-
"for standard type `#{stdtype}`.", :info)
|
30
|
-
require_flavor(flavor)
|
31
|
-
@registry.supported_backends.include? stdtype or
|
32
|
-
Util.log("[metanorma] Error: The `#{flavor}` gem does not "\
|
33
|
-
"support the standard type #{stdtype}. Exiting.", :fatal)
|
34
|
-
end
|
35
|
-
|
36
|
-
def stdtype2flavor(stdtype)
|
37
|
-
flavor = STDTYPE2FLAVOR[stdtype] || stdtype
|
38
|
-
"metanorma-#{flavor}"
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
STDTYPE2FLAVOR = {}.freeze
|
44
|
-
|
45
|
-
def require_flavor(flavor)
|
46
|
-
require flavor
|
47
|
-
Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
|
48
|
-
rescue LoadError => e
|
49
|
-
error_log = "#{Date.today}-error.log"
|
50
|
-
File.write(error_log, e)
|
51
|
-
|
52
|
-
msg = <<~MSG
|
53
|
-
Error: #{e.message}
|
54
|
-
Metanorma has encountered an exception.
|
55
|
-
|
56
|
-
If this problem persists, please report this issue at the following link:
|
57
|
-
|
58
|
-
* https://github.com/metanorma/metanorma/issues/new
|
59
|
-
|
60
|
-
Please attach the #{error_log} file.
|
61
|
-
Your valuable feedback is very much appreciated!
|
62
|
-
|
63
|
-
- The Metanorma team
|
64
|
-
MSG
|
65
|
-
Util.log(msg, :fatal)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|