metanorma 1.2.8 → 1.3.0

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.
@@ -45,6 +45,7 @@ module Metanorma
45
45
  mnf.xpath("xmlns:docref").map do |dr|
46
46
  h = { "identifier" => dr.at("identifier").text }
47
47
  h["fileref"] = dr[:fileref] if dr[:fileref]
48
+ h["attachment"] = dr[:attachment] if dr[:attachment]
48
49
  h
49
50
  end
50
51
  end
@@ -62,7 +63,7 @@ module Metanorma
62
63
  docs = @docref.each_with_object({}) do |dr, m|
63
64
  next m unless dr["fileref"]
64
65
 
65
- m[dr["identifier"]] = Document.parse_file File.join(dir, dr["fileref"])
66
+ m[dr["identifier"]] = Document.parse_file(File.join(dir, dr["fileref"]), dr["attachment"])
66
67
  m
67
68
  end
68
69
  @manifest.reduce(docs) do |mem, mnf|
@@ -101,6 +102,7 @@ module Metanorma
101
102
  @docref.each do |dr|
102
103
  drf = builder.docref { |b| b.identifier dr["identifier"] }
103
104
  drf[:fileref] = dr["fileref"]
105
+ drf[:attachment] = dr["attachment"] if dr["attachment"]
104
106
  if collection.directives.include?("documents-inline")
105
107
  id = collection.documents.find_index { |k, _| k == dr["identifier"] }
106
108
  drf[:id] = format("doc%<index>09d", index: id)
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "isodoc"
4
- require_relative "./collection_fileprocess"
4
+ require_relative "collection_fileprocess"
5
+ require_relative "fontist_utils"
5
6
 
6
7
  module Metanorma
7
8
  # XML collection renderer
@@ -64,6 +65,7 @@ module Metanorma
64
65
  out = col.clone
65
66
  out.directives << "documents-inline"
66
67
  out.documents.keys.each do |id|
68
+ next if @files[id][:attachment]
67
69
  filename = @files[id][:outputs][e]
68
70
  out.documents[id] = Metanorma::Document.raw_file(filename)
69
71
  end
@@ -74,13 +76,27 @@ module Metanorma
74
76
  end
75
77
 
76
78
  def pdfconv
77
- x = Asciidoctor.load nil, backend: @doctype.to_sym
78
- x.converter.pdf_converter(Dummy.new)
79
+ doctype = @doctype.to_sym
80
+ x = Asciidoctor.load nil, backend: doctype
81
+ x.converter.pdf_converter(PdfOptionsNode.new(doctype, @compile_options))
82
+ end
83
+
84
+ class PdfOptionsNode
85
+ def initialize(doctype, options)
86
+ doc_proc = Metanorma::Registry.instance.find_processor(doctype)
87
+ @font_locations = FontistUtils.fontist_font_locations(doc_proc, options)
88
+ end
89
+
90
+ def attr(key)
91
+ if key == "mn2pdf-font-manifest-file" && @font_locations
92
+ @font_locations.path
93
+ end
94
+ end
79
95
  end
80
96
 
81
97
  # Dummy class
82
98
  class Dummy
83
- def attr(_xyz); end
99
+ def attr(_key); end
84
100
  end
85
101
 
86
102
  # The isodoc class for the metanorma flavour we are using
@@ -2,9 +2,10 @@ require "fileutils"
2
2
  require "nokogiri"
3
3
  require "htmlentities"
4
4
  require "yaml"
5
-
6
5
  require "fontist"
7
6
  require "fontist/manifest/install"
7
+ require_relative "compile_validate"
8
+ require_relative "fontist_utils"
8
9
 
9
10
  module Metanorma
10
11
  class Compile
@@ -25,23 +26,19 @@ module Metanorma
25
26
  (file, isodoc = process_input(filename, options)) or return nil
26
27
  relaton_export(isodoc, options)
27
28
  extract(isodoc, options[:extract], options[:extract_type])
28
- install_fonts(options)
29
+ FontistUtils.install_fonts(@processor, options)
29
30
  process_extensions(extensions, file, isodoc, options)
30
31
  end
31
32
 
32
33
  def require_libraries(options)
33
- if options[:require]
34
- options[:require].each do |r|
35
- require r
36
- end
37
- end
34
+ options&.dig(:require)&.each { |r| require r }
38
35
  end
39
36
 
40
37
  def xml_options_extract(file)
41
38
  xml = Nokogiri::XML(file)
42
39
  if xml.root
43
40
  @registry.root_tags.each do |k, v|
44
- return { type: k } if v == xml.root.name
41
+ return { type: k } if v == xml.root.name
45
42
  end
46
43
  end
47
44
  {}
@@ -63,48 +60,6 @@ module Metanorma
63
60
  options
64
61
  end
65
62
 
66
- def validate_type(options)
67
- unless options[:type]
68
- Util.log("[metanorma] Error: Please specify a standard type: #{@registry.supported_backends}.", :error)
69
- return nil
70
- end
71
-
72
- stdtype = options[:type].to_sym
73
- metanorma_flavor = "metanorma-#{stdtype}"
74
-
75
- unless @registry.supported_backends.include? stdtype
76
- Util.log("[metanorma] Info: Loading `#{metanorma_flavor}` gem for standard type `#{stdtype}`.", :info)
77
- end
78
-
79
- begin
80
- require "metanorma-#{stdtype}"
81
- Util.log("[metanorma] Info: gem `#{metanorma_flavor}` loaded.", :info)
82
-
83
- rescue Gem::ConflictError
84
- Util.log("[metanorma] Error: Couldn't resolve dependencies for `metanorma-#{stdtype}`, Please add it to your Gemfile and run bundle install first", :error)
85
- return false
86
-
87
- rescue LoadError
88
- Util.log("[metanorma] Error: loading gem `#{metanorma_flavor}` failed. Exiting.", :error)
89
- return false
90
- end
91
-
92
- unless @registry.supported_backends.include? stdtype
93
- Util.log("[metanorma] Error: The `#{metanorma_flavor}` gem still doesn't support `#{stdtype}`. Exiting.", :error)
94
- return false
95
- end
96
-
97
- true
98
- end
99
-
100
- def validate_format(options)
101
- unless options[:format] == :asciidoc
102
- Util.log("[metanorma] Error: Only source file format currently supported is 'asciidoc'.", :error)
103
- return false
104
- end
105
- true
106
- end
107
-
108
63
  def get_extensions(options)
109
64
  options[:extension_keys] ||= @processor.output_formats.reduce([]) do |memo, (k, _)|
110
65
  memo << k
@@ -121,7 +76,7 @@ module Metanorma
121
76
  end
122
77
  if !extensions.include?(:presentation) and extensions.any? { |e| @processor.use_presentation_xml(e) }
123
78
  extensions << :presentation
124
- end
79
+ end
125
80
  extensions
126
81
  end
127
82
 
@@ -187,7 +142,7 @@ module Metanorma
187
142
  xml.xpath("//sourcecode | //xmlns:sourcecode").each_with_index do |s, i|
188
143
  filename = s["filename"] || sprintf("sourcecode-%04d.txt", i)
189
144
  File.open("#{dirname}/sourcecode/#{filename}", "w:UTF-8") do |f|
190
- f.write clean_sourcecode(s.dup)
145
+ f.write clean_sourcecode(s.dup)
191
146
  end
192
147
  end
193
148
  end
@@ -197,6 +152,7 @@ module Metanorma
197
152
  FileUtils.mkdir_p "#{dirname}/image"
198
153
  xml.xpath("//image | //xmlns:image").each_with_index do |s, i|
199
154
  next unless /^data:image/.match s["src"]
155
+
200
156
  %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ s["src"]
201
157
  filename = s["filename"] || sprintf("image-%04d.%s", i, imgtype)
202
158
  File.open("#{dirname}/image/#{filename}", "wb") do |f|
@@ -222,22 +178,22 @@ module Metanorma
222
178
 
223
179
  # dependency ordering
224
180
  def sort_extensions_execution(ext)
225
- case ext
226
- when :xml then 0
227
- when :rxl then 1
228
- when :presentation then 2
229
- else
230
- 99
231
- end
181
+ case ext
182
+ when :xml then 0
183
+ when :rxl then 1
184
+ when :presentation then 2
185
+ else
186
+ 99
187
+ end
232
188
  end
233
189
 
234
190
  def wrap_html(options, file_extension, outfilename)
235
- if options[:wrapper] and /html$/.match file_extension
236
- outfilename = outfilename.sub(/\.html$/, "")
237
- FileUtils.mkdir_p outfilename
238
- FileUtils.mv "#{outfilename}.html", outfilename
239
- FileUtils.mv "#{outfilename}_images", outfilename, force: true
240
- end
191
+ if options[:wrapper] && /html$/.match(file_extension)
192
+ outfilename = outfilename.sub(/\.html$/, "")
193
+ FileUtils.mkdir_p outfilename
194
+ FileUtils.mv "#{outfilename}.html", outfilename
195
+ FileUtils.mv "#{outfilename}_images", outfilename, force: true
196
+ end
241
197
  end
242
198
 
243
199
  # isodoc is Raw Metanorma XML
@@ -250,11 +206,13 @@ module Metanorma
250
206
  end.each do |ext|
251
207
  isodoc_options = @processor.extract_options(file)
252
208
  isodoc_options[:datauriimage] = true if options[:datauriimage]
209
+ isodoc_options[:sourcefilename] = options[:filename]
253
210
  file_extension = @processor.output_formats[ext]
254
211
  outfilename = f.sub(/\.[^.]+$/, ".#{file_extension}")
255
212
  if ext == :pdf
256
- font_locations = fontist_font_locations(options)
257
- isodoc_options[:mn2pdf] = { font_manifest_file: font_locations.path } if font_locations
213
+ font_locations = FontistUtils.fontist_font_locations(@processor, options)
214
+ font_locations and
215
+ isodoc_options[:mn2pdf] = { font_manifest_file: font_locations.path }
258
216
  end
259
217
  if ext == :rxl
260
218
  options[:relaton] = outfilename
@@ -276,93 +234,8 @@ module Metanorma
276
234
  end
277
235
  end
278
236
 
279
- def install_fonts(options)
280
- if options[:no_install_fonts]
281
- Util.log("[fontist] Skip font installation because" \
282
- " --no-install-fonts argument passed", :debug)
283
- return
284
- end
285
-
286
- if missing_fontist_manifest?
287
- Util.log("[fontist] Skip font installation because font_manifest is missing", :debug)
288
- return
289
- end
290
-
291
- @updated_formulas_repo = false
292
-
293
- manifest = @processor.fonts_manifest
294
- agree_to_terms = options[:agree_to_terms] || false
295
- continue_without_fonts = options[:continue_without_fonts] || false
296
- no_progress = options[:no_progress] || false
297
-
298
- install_fonts_safe(manifest, agree_to_terms, continue_without_fonts, no_progress)
299
- end
300
-
301
237
  private
302
238
 
303
- def install_fonts_safe(manifest, agree, continue, no_progress)
304
- fontist_install(manifest, agree, no_progress)
305
- rescue Fontist::Errors::LicensingError
306
- if continue
307
- Util.log(
308
- "[fontist] Processing will continue without fonts installed",
309
- :debug
310
- )
311
- else
312
- Util.log("[fontist] Aborting without proper fonts installed," \
313
- " make sure that you have set option --agree-to-terms", :fatal)
314
- end
315
- rescue Fontist::Errors::FontError => e
316
- log_level = continue ? :warning : :fatal
317
- Util.log("[fontist] '#{e.font}' font is not supported. " \
318
- "Please report this issue at github.com/metanorma/metanorma-"\
319
- "#{@processor.short}/issues to report this issue.", log_level)
320
- rescue Fontist::Errors::FormulaIndexNotFoundError
321
- if @updated_formulas_repo
322
- Util.log(
323
- "[fontist] Bug: formula index not found after 'fontist update'",
324
- :fatal
325
- )
326
- end
327
- Util.log("[fontist] Missing formula index. Fetching it...", :debug)
328
- Fontist::Formula.update_formulas_repo
329
- @updated_formulas_repo = true
330
- install_fonts_safe(manifest, agree, continue, no_progress)
331
- end
332
-
333
- def fontist_install(manifest, agree, no_progress)
334
- Fontist::Manifest::Install.from_hash(
335
- manifest,
336
- confirmation: agree ? "yes" : "no",
337
- no_progress: no_progress
338
- )
339
- end
340
-
341
- def fontist_font_locations(options)
342
- return nil if missing_fontist_manifest? || options[:no_install_fonts]
343
-
344
- dump_fontist_manifest_locations(@processor.fonts_manifest)
345
- rescue Fontist::Errors::FormulaIndexNotFoundError
346
- raise unless options[:continue_without_fonts]
347
-
348
- nil
349
- end
350
-
351
- def dump_fontist_manifest_locations(manifest)
352
- location_manifest = Fontist::Manifest::Locations.from_hash(
353
- manifest
354
- )
355
- location_manifest_file = Tempfile.new(["fontist_locations", ".yml"])
356
- location_manifest_file.write location_manifest.to_yaml
357
- location_manifest_file.flush
358
-
359
- location_manifest_file
360
- end
361
-
362
- def missing_fontist_manifest?
363
- !@processor.respond_to?(:fonts_manifest) || @processor.fonts_manifest.nil?
364
- end
365
-
366
239
  # @param options [Hash]
367
240
  # @return [String]
368
241
  def change_output_dir(options)
@@ -0,0 +1,45 @@
1
+ module Metanorma
2
+ class Compile
3
+ def validate_type(options)
4
+ unless options[:type]
5
+ Util.log("[metanorma] Error: Please specify a standard type: "\
6
+ "#{@registry.supported_backends}.", :error)
7
+ return nil
8
+ end
9
+ stdtype = options[:type].to_sym
10
+ metanorma_flavor = "metanorma-#{stdtype}"
11
+ unless @registry.supported_backends.include? stdtype
12
+ Util.log("[metanorma] Info: Loading `#{metanorma_flavor}` gem "\
13
+ "for standard type `#{stdtype}`.", :info)
14
+ end
15
+ begin
16
+ require "metanorma-#{stdtype}"
17
+ Util.log("[metanorma] Info: gem `#{metanorma_flavor}` loaded.", :info)
18
+ rescue Gem::ConflictError
19
+ Util.log("[metanorma] Error: Couldn't resolve dependencies for "\
20
+ "`metanorma-#{stdtype}`, Please add it to your Gemfile "\
21
+ "and run bundle install first", :error)
22
+ return false
23
+ rescue LoadError
24
+ Util.log("[metanorma] Error: loading gem `#{metanorma_flavor}` "\
25
+ "failed. Exiting.", :error)
26
+ return false
27
+ end
28
+ unless @registry.supported_backends.include? stdtype
29
+ Util.log("[metanorma] Error: The `#{metanorma_flavor}` gem "\
30
+ "still doesn't support `#{stdtype}`. Exiting.", :error)
31
+ return false
32
+ end
33
+ true
34
+ end
35
+
36
+ def validate_format(options)
37
+ unless options[:format] == :asciidoc
38
+ Util.log("[metanorma] Error: Only source file format currently "\
39
+ "supported is 'asciidoc'.", :error)
40
+ return false
41
+ end
42
+ true
43
+ end
44
+ end
45
+ end
@@ -1,20 +1,22 @@
1
1
  module Metanorma
2
2
  class Document
3
3
  # @return [Strin]
4
- attr_reader :file
4
+ attr_reader :file, :attachment
5
5
 
6
6
  # @param bibitem [RelatonBib::BibliographicItem]
7
7
  def initialize(bibitem, file, options = {})
8
8
  @bibitem = bibitem
9
9
  @file = file
10
+ @attachment = options[:attachment]
10
11
  @raw = options[:raw]
11
12
  end
12
13
 
13
14
  class << self
14
15
  # @param file [String] file path
16
+ # @param attachment [Bool] is an attachment
15
17
  # @return [Metanorma::Document]
16
- def parse_file(file)
17
- new bibitem(file), file
18
+ def parse_file(file, attachment)
19
+ new bibitem(file), file, { attachment: attachment }
18
20
  end
19
21
 
20
22
  # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
@@ -0,0 +1,108 @@
1
+ module Metanorma
2
+ class FontistUtils
3
+ class << self
4
+ private
5
+
6
+ def validate_options(options)
7
+ agree_to_terms = options[:agree_to_terms] || false
8
+ continue_without_fonts = options[:continue_without_fonts] || false
9
+ no_progress = options[:no_progress] || false
10
+
11
+ [agree_to_terms, continue_without_fonts, no_progress]
12
+ end
13
+
14
+ def validate_install_fonts(processor, options)
15
+ if options[:no_install_fonts]
16
+ Util.log("[fontist] Skip font installation because" \
17
+ " --no-install-fonts argument passed", :debug)
18
+ return false
19
+ elsif missing_fontist_manifest?(processor)
20
+ Util.log("[fontist] Skip font installation because "\
21
+ "font_manifest is missing", :debug)
22
+ return false
23
+ end
24
+ true
25
+ end
26
+
27
+ def install_fonts_safe(manifest, agree, continue, no_progress)
28
+ fontist_install(manifest, agree, no_progress)
29
+ rescue Fontist::Errors::LicensingError
30
+ if continue
31
+ Util.log(
32
+ "[fontist] Processing will continue without fonts installed",
33
+ :debug
34
+ )
35
+ else
36
+ Util.log("[fontist] Aborting without proper fonts installed," \
37
+ " make sure that you have set option --agree-to-terms",
38
+ :fatal)
39
+ end
40
+ rescue Fontist::Errors::FontError => e
41
+ log_level = continue ? :warning : :fatal
42
+ Util.log("[fontist] '#{e.font}' font is not supported. " \
43
+ "Please report this issue at github.com/metanorma/metanorma" \
44
+ "/issues to report this issue.", log_level)
45
+ rescue Fontist::Errors::FormulaIndexNotFoundError
46
+ if @@updated_formulas_repo
47
+ Util.log(
48
+ "[fontist] Bug: formula index not found after 'fontist update'",
49
+ :fatal
50
+ )
51
+ end
52
+ Util.log("[fontist] Missing formula index. Fetching it...", :debug)
53
+ Fontist::Formula.update_formulas_repo
54
+ @@updated_formulas_repo = true
55
+ install_fonts_safe(manifest, agree, continue, no_progress)
56
+ end
57
+
58
+ def fontist_install(manifest, agree, no_progress)
59
+ Fontist::Manifest::Install.from_hash(
60
+ manifest,
61
+ confirmation: agree ? "yes" : "no",
62
+ no_progress: no_progress
63
+ )
64
+ end
65
+
66
+ def dump_fontist_manifest_locations(manifest)
67
+ location_manifest = Fontist::Manifest::Locations.from_hash(
68
+ manifest
69
+ )
70
+ location_manifest_file = Tempfile.new(["fontist_locations", ".yml"])
71
+ location_manifest_file.write location_manifest.to_yaml
72
+ location_manifest_file.flush
73
+ location_manifest_file
74
+ end
75
+
76
+ def missing_fontist_manifest?(processor)
77
+ !processor.respond_to?(:fonts_manifest) || processor.fonts_manifest.nil?
78
+ end
79
+ end
80
+
81
+ def self.install_fonts(processor, options)
82
+ return unless validate_install_fonts(processor, options)
83
+
84
+ @@updated_formulas_repo = false
85
+ manifest = processor.fonts_manifest
86
+ agree_to_terms, can_without_fonts, no_progress = validate_options(options)
87
+
88
+ install_fonts_safe(
89
+ manifest,
90
+ agree_to_terms,
91
+ can_without_fonts,
92
+ no_progress
93
+ )
94
+ end
95
+
96
+ def self.fontist_font_locations(processor, options)
97
+ if missing_fontist_manifest?(processor) || options[:no_install_fonts]
98
+ return nil
99
+ end
100
+
101
+ dump_fontist_manifest_locations(processor.fonts_manifest)
102
+ rescue Fontist::Errors::FormulaIndexNotFoundError
103
+ raise unless options[:continue_without_fonts]
104
+
105
+ nil
106
+ end
107
+ end
108
+ end