metanorma 1.2.8 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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