metanorma 1.7.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -1
  3. data/lib/metanorma/array_monkeypatch.rb +9 -0
  4. data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
  5. data/lib/metanorma/collection/collection.rb +225 -0
  6. data/lib/metanorma/collection/config/bibdata.rb +12 -0
  7. data/lib/metanorma/collection/config/compile_options.rb +13 -0
  8. data/lib/metanorma/collection/config/config.rb +163 -0
  9. data/lib/metanorma/collection/config/converters.rb +30 -0
  10. data/lib/metanorma/collection/config/directive.rb +10 -0
  11. data/lib/metanorma/collection/config/manifest.rb +88 -0
  12. data/lib/metanorma/collection/document/document.rb +133 -0
  13. data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
  14. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
  15. data/lib/metanorma/collection/manifest/manifest.rb +237 -0
  16. data/lib/metanorma/collection/renderer/fileparse.rb +247 -0
  17. data/lib/metanorma/collection/renderer/fileprocess.rb +173 -0
  18. data/lib/metanorma/collection/renderer/navigation.rb +133 -0
  19. data/lib/metanorma/collection/renderer/render_word.rb +133 -0
  20. data/lib/metanorma/collection/renderer/renderer.rb +157 -0
  21. data/lib/metanorma/collection/renderer/utils.rb +183 -0
  22. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -0
  23. data/lib/metanorma/collection/util/disambig_files.rb +37 -0
  24. data/lib/metanorma/collection/util/util.rb +72 -0
  25. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
  26. data/lib/metanorma/{compile.rb → compile/compile.rb} +17 -11
  27. data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
  28. data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
  29. data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
  30. data/lib/metanorma/{config.rb → config/config.rb} +1 -1
  31. data/lib/metanorma/input/asciidoc.rb +3 -3
  32. data/lib/metanorma/input/base.rb +1 -5
  33. data/lib/metanorma/processor/processor.rb +54 -0
  34. data/lib/metanorma/processor.rb +1 -49
  35. data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
  36. data/lib/metanorma/shale_monkeypatch.rb +15 -0
  37. data/lib/metanorma/util/fontist_helper.rb +130 -0
  38. data/lib/metanorma/util/util.rb +45 -0
  39. data/lib/metanorma/util/worker_pool.rb +39 -0
  40. data/lib/metanorma/version.rb +1 -1
  41. data/lib/metanorma.rb +13 -8
  42. data/metanorma.gemspec +2 -1
  43. metadata +50 -24
  44. data/lib/metanorma/collection.rb +0 -244
  45. data/lib/metanorma/collection_fileparse.rb +0 -257
  46. data/lib/metanorma/collection_fileprocess.rb +0 -168
  47. data/lib/metanorma/collection_manifest.rb +0 -168
  48. data/lib/metanorma/collection_render_utils.rb +0 -169
  49. data/lib/metanorma/collection_render_word.rb +0 -131
  50. data/lib/metanorma/collection_renderer.rb +0 -237
  51. data/lib/metanorma/collection_xref_process.rb +0 -217
  52. data/lib/metanorma/document.rb +0 -133
  53. data/lib/metanorma/files_lookup.rb +0 -224
  54. data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
  55. data/lib/metanorma/fontist_utils.rb +0 -122
  56. data/lib/metanorma/sectionsplit.rb +0 -216
  57. data/lib/metanorma/util.rb +0 -127
  58. data/lib/metanorma/worker_pool.rb +0 -29
@@ -0,0 +1,222 @@
1
+ module Metanorma
2
+ class Collection
3
+ module XrefProcess
4
+ class << self
5
+ # xml.root["type"] = key # to force recognition of internal refs
6
+ # bookmarks etc as new id elements introduced in Presentation XML:
7
+ # add doc suffix
8
+ def xref_preprocess(xml, isodoc)
9
+ @isodoc = isodoc
10
+ key = (0...8).map { rand(65..90).chr }.join # random string
11
+ xml.root["type"] = key
12
+ Metanorma::Utils::anchor_attributes
13
+ .each do |(tag_name, attribute_name)|
14
+ ::Metanorma::Collection::Util::add_suffix_to_attributes(
15
+ xml, xml.root["document_suffix"], tag_name, attribute_name, isodoc
16
+ )
17
+ end
18
+ key
19
+ end
20
+
21
+ def ns(xpath)
22
+ @isodoc.ns(xpath)
23
+ end
24
+
25
+ def xref_process(section, xml, key, ident, isodoc)
26
+ @isodoc ||= isodoc
27
+ svg_preprocess(section, Metanorma::Utils::to_ncname(ident))
28
+ refs = eref_to_internal_eref(section, xml, key)
29
+ refs += xref_to_internal_eref(section, xml, key)
30
+ ins = new_hidden_ref(section)
31
+ copied_refs = copy_repo_items_biblio(ins, section, xml)
32
+ insert_indirect_biblio(ins, refs - copied_refs, key, xml)
33
+ end
34
+
35
+ def svg_preprocess(xml, doc_suffix)
36
+ suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
37
+ xml.xpath("//m:svg", "m" => "http://www.w3.org/2000/svg").each do |s|
38
+ m = svgmap_wrap(s)
39
+ svg_xrefs(s, m, suffix)
40
+ end
41
+ xml
42
+ end
43
+
44
+ def svgmap_wrap(svg)
45
+ ret = svg.at("./ancestor::xmlns:svgmap") and return ret
46
+ ret = svg.at("./ancestor::xmlns:figure")
47
+ ret.wrap("<svgmap/>")
48
+ svg.at("./ancestor::xmlns:svgmap")
49
+ end
50
+
51
+ def svg_xrefs(svg, svgmap, suffix)
52
+ svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
53
+ /^#/.match? a["href"] or next
54
+ a["href"] = a["href"].sub(/^#/, "")
55
+ svgmap << "<target href='#{a['href']}'>" \
56
+ "<xref target='#{a['href']}#{suffix}'/></target>"
57
+ end
58
+ end
59
+
60
+ def make_anchor(elem, anchor)
61
+ elem.at(ns("./localityStack | ./locality")) and return
62
+ elem.text.strip.empty? && elem.elements.empty? and elem << anchor
63
+ elem <<
64
+ "<localityStack><locality type='anchor'><referenceFrom>" \
65
+ "#{anchor}</referenceFrom></locality></localityStack>"
66
+ end
67
+
68
+ def xref_to_internal_eref(section, xml, key)
69
+ key or return [] # no sectionsplit, no playing with xrefs
70
+ bibitems, indirect = xref_to_internal_eref_prep(section, xml)
71
+ section.xpath(ns("//xref")).each_with_object({}) do |x, m|
72
+ xref_prefix_key(x, key, indirect)
73
+ x["bibitemid"] = x["target"]
74
+ m[x["bibitemid"]] = true
75
+ xref_to_internal_eref_anchor(x, key, bibitems,
76
+ xml.root["document_suffix"])
77
+ end.keys
78
+ end
79
+
80
+ def xref_to_internal_eref_prep(section, xml)
81
+ bibitems = ::Metanorma::Collection::Util::gather_bibitems(section)
82
+ indirect_bibitems = ::Metanorma::Collection::Util::gather_bibitems(xml)
83
+ .select { |_, v| indirect_bib?(v) }
84
+ [bibitems, indirect_bibitems]
85
+ end
86
+
87
+ def xref_to_internal_eref_anchor(xref, key, bibitems, document_suffix)
88
+ t = xref["target"]
89
+ if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
90
+ m = %r{^([^/]+)}.match(d.text) and
91
+ t.sub!(%r(#{m[0]}_), "")
92
+ end
93
+ key and t.sub!(%r{^#{key}_}, "")
94
+ make_anchor(xref, t.sub(%r(_#{document_suffix}$), ""))
95
+ xref.delete("target")
96
+ xref.name = "eref"
97
+ end
98
+
99
+ def xref_prefix_key(xref, key, indirect)
100
+ if b = indirect[xref["target"]]
101
+ t = b.at(ns("./docidentifier[@type = 'repository']"))
102
+ xref["type"] = t.text.sub(%r{/.*$}, "")
103
+ elsif key
104
+ xref["target"] = "#{key}_#{xref['target']}"
105
+ xref["type"] = key
106
+ end
107
+ end
108
+
109
+ def eref_to_internal_eref(section, xml, key)
110
+ bibitems, indirect, bibids = eref_to_internal_eref_prep(section, xml)
111
+ eref_to_internal_eref_select(section, xml, bibitems)
112
+ .each_with_object([]) do |x, m|
113
+ url = bibitems[x]&.at(ns("./uri[@type = 'citation']"))&.text
114
+ bibids[x]&.each do |e|
115
+ e.at(ns("./localityStack | ./locality")) and next
116
+ id = eref_to_internal_eref1(e, key, url, indirect) and m << id
117
+ end
118
+ end
119
+ end
120
+
121
+ def eref_to_internal_eref_prep(section, xml)
122
+ bibitems = ::Metanorma::Collection::Util::gather_bibitems(xml)
123
+ .delete_if { |_, v| internal_bib?(v) }
124
+ indirect = ::Metanorma::Collection::Util::gather_bibitems(xml)
125
+ .select { |_, v| indirect_bib?(v) }
126
+ bibitemids = ::Metanorma::Collection::Util::gather_bibitemids(section)
127
+ [bibitems, indirect, bibitemids]
128
+ end
129
+
130
+ def eref_to_internal_eref1(elem, key, url, indirect)
131
+ if url
132
+ elem.name = "link"
133
+ elem["target"] = url
134
+ nil
135
+ elsif !indirect[elem["bibitemid"]]
136
+ nil
137
+ else
138
+ eref_to_internal_eref1_internal(elem, key, indirect)
139
+ end
140
+ end
141
+
142
+ def eref_to_internal_eref1_internal(elem, key, indirect)
143
+ t = elem["bibitemid"]
144
+ if key
145
+ t = "#{key}_#{t}"
146
+ elem["type"] = key
147
+ elsif d = indirect[t]&.at(ns("./docidentifier[@type = 'repository']"))
148
+ m = %r{^([^/]+)}.match(d.text) and
149
+ t.sub!(%r(#{m[0]}_), "")
150
+ end
151
+ make_anchor(elem, t)
152
+ elem["bibitemid"]
153
+ end
154
+
155
+ def eref_to_internal_eref_select(section, _xml, bibitems)
156
+ refs = ::Metanorma::Collection::Util::gather_bibitemids(section).keys
157
+ refs.uniq.reject do |x|
158
+ b = bibitems[x] and (indirect_bib?(b) || internal_bib?(b))
159
+ end
160
+ end
161
+
162
+ def internal_bib?(bibitem)
163
+ bibitem["type"] == "internal" ||
164
+ bibitem.at(ns("./docidentifier[@type = 'repository']"))
165
+ end
166
+
167
+ def indirect_bib?(bibitem)
168
+ a = bibitem.at(ns("./docidentifier[@type = 'repository']")) or
169
+ return false
170
+ %r{^current-metanorma-collection/}.match?(a.text) and return false
171
+ a.text.include?("/")
172
+ end
173
+
174
+ # from standoc
175
+ def new_hidden_ref(xmldoc)
176
+ ins = xmldoc.at("bibliography") or
177
+ xmldoc.root << "<bibliography/>" and ins = xmldoc.at("bibliography")
178
+ ins.add_child("<references hidden='true' normative='false'/>").first
179
+ end
180
+
181
+ def copy_repo_items_biblio(ins, section, xml)
182
+ bibitems = ::Metanorma::Collection::Util::gather_bibitems(section)
183
+ xml.xpath(ns("//references/bibitem[docidentifier/@type = 'repository']"))
184
+ .each_with_object([]) do |b, m|
185
+ bibitems[b["id"]] or next
186
+ # section.at("//*[@bibitemid = '#{b['id']}']") or next
187
+ ins << b.dup
188
+ m << b["id"]
189
+ end
190
+ end
191
+
192
+ def insert_indirect_biblio(ins, refs, key, xml)
193
+ refs.empty? and return
194
+ internal_bibitems, = insert_indirect_biblio_prep(xml)
195
+ refs.compact.reject do |x|
196
+ # external_bibitems[x.sub(/^#{key}_/, "")]
197
+ end.each do |x|
198
+ ins << if b = internal_bibitems[x.sub(/^#{key}_/, "")]
199
+ b.dup.tap { |m| m["id"] = x }
200
+ else new_indirect_bibitem(x, key)
201
+ end
202
+ end
203
+ end
204
+
205
+ def insert_indirect_biblio_prep(xml)
206
+ bibitems = ::Metanorma::Collection::Util::gather_bibitems(xml)
207
+ internal_bibitems = bibitems.select { |_, v| internal_bib?(v) }
208
+ external_bibitems = bibitems.reject { |_, v| internal_bib?(v) }
209
+ [internal_bibitems, external_bibitems]
210
+ end
211
+
212
+ def new_indirect_bibitem(ident, prefix)
213
+ <<~BIBENTRY
214
+ <bibitem id="#{ident}" type="internal">
215
+ <docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
216
+ </bibitem>
217
+ BIBENTRY
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -6,11 +6,11 @@ require "fontist"
6
6
  require "fontist/manifest/install"
7
7
  require_relative "compile_validate"
8
8
  require_relative "compile_options"
9
- require_relative "fontist_utils"
10
- require_relative "util"
11
- require_relative "sectionsplit"
9
+ require_relative "../util/fontist_helper"
10
+ require_relative "../util/util"
12
11
  require_relative "extract"
13
- require_relative "worker_pool"
12
+ require_relative "../collection/sectionsplit/sectionsplit"
13
+ require_relative "../util/worker_pool"
14
14
 
15
15
  module Metanorma
16
16
  class Compile
@@ -86,7 +86,7 @@ module Metanorma
86
86
  def relaton_export(isodoc, options)
87
87
  return unless options[:relaton]
88
88
 
89
- xml = Nokogiri::XML(isodoc) { |config| config.huge }
89
+ xml = Nokogiri::XML(isodoc, &:huge)
90
90
  bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
91
91
  # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
92
92
  # outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
@@ -113,7 +113,7 @@ module Metanorma
113
113
  fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
114
114
  orig_filename: File.expand_path(filename),
115
115
  presentationxml: f.sub(/\.[^.]+$/, ".presentation.xml") }
116
- @queue = ::Metanorma::WorkersPool
116
+ @queue = ::Metanorma::Util::WorkersPool
117
117
  .new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
118
118
  gather_and_install_fonts(file, options.dup, extensions)
119
119
  process_exts_run(fnames, file, isodoc, extensions, options)
@@ -189,7 +189,7 @@ module Metanorma
189
189
  ext != :presentation
190
190
  end
191
191
 
192
- # assume we pass in Presentation XML, but we want to recover Semantic XML
192
+ # assume we pass in Presentation XML, but we want to recover Semantic XML
193
193
  def sectionsplit_convert(input_filename, file, output_filename = nil,
194
194
  opts = {})
195
195
  @isodoc ||= IsoDoc::PresentationXMLConvert.new({})
@@ -198,10 +198,16 @@ module Metanorma
198
198
  File.open(input_filename, "w:UTF-8") { |f| f.write(file) }
199
199
  presxml = File.read(input_filename, encoding: "utf-8")
200
200
  _xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
201
- Sectionsplit.new(input: input_filename, isodoc: @isodoc, xml: presxml,
202
- base: File.basename(output_filename || filename),
203
- output: output_filename || filename,
204
- dir: dir, compile_opts: opts).build_collection
201
+
202
+ ::Metanorma::Collection::Sectionsplit.new(
203
+ input: input_filename,
204
+ isodoc: @isodoc,
205
+ xml: presxml,
206
+ base: File.basename(output_filename || filename),
207
+ output: output_filename || filename,
208
+ dir: dir,
209
+ compile_opts: opts,
210
+ ).build_collection
205
211
  end
206
212
 
207
213
  private
@@ -57,7 +57,8 @@ module Metanorma
57
57
  end
58
58
 
59
59
  def font_install(opt)
60
- FontistUtils.install_fonts(@processor, opt) unless @fontist_installed
60
+ @fontist_installed or
61
+ Util::FontistHelper.install_fonts(@processor, opt)
61
62
  @fontist_installed = true
62
63
  end
63
64
 
@@ -83,16 +84,19 @@ module Metanorma
83
84
  def copy_isodoc_options_attrs(options, ret)
84
85
  ret[:datauriimage] = true if options[:datauriimage]
85
86
  ret[:sourcefilename] = options[:filename]
86
- %i(bare sectionsplit no_install_fonts baseassetpath aligncrosselements
87
+ %i(bare sectionsplit install_fonts baseassetpath aligncrosselements
87
88
  tocfigures toctables tocrecommendations strict)
88
89
  .each { |x| ret[x] ||= options[x] }
89
90
  end
90
91
 
91
92
  def font_manifest_mn2pdf(options, ret, ext)
92
- custom_fonts = FontistUtils.has_custom_fonts?(@processor, options, ret)
93
+ custom_fonts = Util::FontistHelper
94
+ .has_custom_fonts?(@processor, options, ret)
95
+
93
96
  ext == :pdf && custom_fonts and
94
- ret[:mn2pdf] = { font_manifest: FontistUtils
95
- .location_manifest(@processor, ret) }
97
+ ret[:mn2pdf] = {
98
+ font_manifest: Util::FontistHelper.location_manifest(@processor, ret),
99
+ }
96
100
  end
97
101
  end
98
102
  end
@@ -35,7 +35,7 @@ module Metanorma
35
35
 
36
36
  private
37
37
 
38
- STDTYPE2FLAVOR = { }.freeze
38
+ STDTYPE2FLAVOR = {}.freeze
39
39
 
40
40
  def stdtype2flavor(stdtype)
41
41
  flavor = STDTYPE2FLAVOR[stdtype] || stdtype
@@ -3,7 +3,7 @@ module Metanorma
3
3
  def relaton_export(isodoc, options)
4
4
  return unless options[:relaton]
5
5
 
6
- xml = Nokogiri::XML(isodoc) { |config| config.huge }
6
+ xml = Nokogiri::XML(isodoc, &:huge)
7
7
  bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
8
8
  # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
9
9
  # outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
@@ -24,7 +24,7 @@ module Metanorma
24
24
  extract_types = %i[sourcecode image requirement]
25
25
  FileUtils.rm_rf dirname
26
26
  FileUtils.mkdir_p dirname
27
- xml = Nokogiri::XML(isodoc) { |config| config.huge }
27
+ xml = Nokogiri::XML(isodoc, &:huge)
28
28
  sourcecode_export(xml, dirname) if extract_types.include? :sourcecode
29
29
  image_export(xml, dirname) if extract_types.include? :image
30
30
  extract_types.include?(:requirement) and
@@ -15,7 +15,7 @@ module Metanorma
15
15
  attr_accessor :logs
16
16
 
17
17
  def initialize
18
- @logs ||= %i[warning error fatal]
18
+ @logs = %i[warning error fatal]
19
19
  end
20
20
  end
21
21
 
@@ -35,9 +35,9 @@ module Metanorma
35
35
 
36
36
  def extract_metanorma_options(file)
37
37
  headerextract = file.sub(/\n\n.*$/m, "\n")
38
- /\n:mn-document-class:\s+(?<type>[^\n]+)\n/ =~ headerextract
39
- /\n:mn-output-extensions:\s+(?<extensions>[^\n]+)\n/ =~ headerextract
40
- /\n:mn-relaton-output-file:\s+(?<relaton>[^\n]+)\n/ =~ headerextract
38
+ /\n:mn-document-class:\s+(?<type>\S[^\n]*)\n/ =~ headerextract
39
+ /\n:mn-output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ headerextract
40
+ /\n:mn-relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ headerextract
41
41
  /\n(?<asciimath>:mn-keep-asciimath:[^\n]*)\n/ =~ headerextract
42
42
  /\n(?<novalid>:novalid:[^\n]*)\n/ =~ headerextract
43
43
  asciimath = if defined?(asciimath)
@@ -1,13 +1,9 @@
1
-
2
1
  module Metanorma
3
2
  module Input
4
-
5
3
  class Base
6
-
7
- def process(file, filename, type)
4
+ def process(_file, _filename, _type)
8
5
  raise "This is an abstract class"
9
6
  end
10
-
11
7
  end
12
8
  end
13
9
  end
@@ -0,0 +1,54 @@
1
+ # Registry of all Metanorma types and entry points
2
+ #
3
+
4
+ module Metanorma
5
+ class Processor
6
+ attr_reader :short, :input_format, :asciidoctor_backend
7
+
8
+ def initialize
9
+ raise "This is an abstract class!"
10
+ end
11
+
12
+ def output_formats
13
+ {
14
+ xml: "xml",
15
+ presentation: "presentation.xml",
16
+ rxl: "rxl",
17
+ }
18
+ end
19
+
20
+ def input_to_isodoc(file, filename, options = {})
21
+ Metanorma::Input::Asciidoc.new.process(file, filename,
22
+ @asciidoctor_backend, options)
23
+ end
24
+
25
+ # def input_to_isodoc(file, filename)
26
+ # raise "This is an abstract class!"
27
+ # end
28
+
29
+ def use_presentation_xml(ext)
30
+ case ext
31
+ when :html, :doc, :pdf then true
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ def options_preprocess(options)
38
+ options[:output_formats] ||= output_formats
39
+ end
40
+
41
+ def output(isodoc_node, _inname, outname, _format, _options = {})
42
+ File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
43
+ end
44
+
45
+ def extract_options(file)
46
+ Metanorma::Input::Asciidoc.new.extract_options(file)
47
+ .merge(output_formats: output_formats)
48
+ end
49
+
50
+ def extract_metanorma_options(file)
51
+ Metanorma::Input::Asciidoc.new.extract_metanorma_options(file)
52
+ end
53
+ end
54
+ end
@@ -1,54 +1,6 @@
1
- # Registry of all Metanorma types and entry points
2
- #
1
+ require_relative "./processor/processor"
3
2
 
4
3
  module Metanorma
5
4
  class Processor
6
- attr_reader :short, :input_format, :asciidoctor_backend
7
-
8
- def initialize
9
- raise "This is an abstract class!"
10
- end
11
-
12
- def output_formats
13
- {
14
- xml: "xml",
15
- presentation: "presentation.xml",
16
- rxl: "rxl",
17
- }
18
- end
19
-
20
- def input_to_isodoc(file, filename, options = {})
21
- Metanorma::Input::Asciidoc.new.process(file, filename,
22
- @asciidoctor_backend, options)
23
- end
24
-
25
- # def input_to_isodoc(file, filename)
26
- # raise "This is an abstract class!"
27
- # end
28
-
29
- def use_presentation_xml(ext)
30
- case ext
31
- when :html, :doc, :pdf then true
32
- else
33
- false
34
- end
35
- end
36
-
37
- def options_preprocess(options)
38
- options[:output_formats] ||= output_formats
39
- end
40
-
41
- def output(isodoc_node, _inname, outname, _format, _options = {})
42
- File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
43
- end
44
-
45
- def extract_options(file)
46
- Metanorma::Input::Asciidoc.new.extract_options(file)
47
- .merge(output_formats: output_formats)
48
- end
49
-
50
- def extract_metanorma_options(file)
51
- Metanorma::Input::Asciidoc.new.extract_metanorma_options(file)
52
- end
53
5
  end
54
6
  end
@@ -1,5 +1,4 @@
1
1
  # Registry of all Metanorma types and entry points
2
- #
3
2
 
4
3
  require "singleton"
5
4
 
@@ -0,0 +1,15 @@
1
+ module Shale
2
+ module Adapter
3
+ module Nokogiri
4
+ class Node
5
+ def content
6
+ @node
7
+ end
8
+
9
+ def to_xml
10
+ @node.to_xml
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,130 @@
1
+ require "fontist"
2
+ module Metanorma
3
+ module Util
4
+ class FontistHelper
5
+ class << self
6
+ private
7
+
8
+ def validate_options(options)
9
+ agree_to_terms = options[:agree_to_terms] || false
10
+ continue_without_fonts = options[:continue_without_fonts] || false
11
+ no_progress = !options[:progress]
12
+
13
+ [agree_to_terms, continue_without_fonts, no_progress]
14
+ end
15
+
16
+ def validate_install_fonts(processor, options)
17
+ unless install_fonts?(options)
18
+ Util.log("[fontist] Skip font installation because" \
19
+ " --no-install-fonts argument passed", :debug)
20
+ return false
21
+ end
22
+ unless has_custom_fonts?(processor, options, options)
23
+ Util.log("[fontist] Skip font installation because "\
24
+ "fonts_manifest is missing", :debug)
25
+ return false
26
+ end
27
+ true
28
+ end
29
+
30
+ def install_fonts_safe(manifest, agree, continue, no_progress)
31
+ fontist_install(manifest, agree, no_progress)
32
+ rescue Fontist::Errors::LicensingError
33
+ license_error_log(continue)
34
+ rescue Fontist::Errors::FontError => e
35
+ log_level = continue ? :warning : :fatal
36
+ Util.log("[fontist] '#{e.font}' font is not supported. " \
37
+ "Please report this issue at github.com/metanorma/metanorma" \
38
+ "/issues to report this issue.", log_level)
39
+ rescue Fontist::Errors::FormulaIndexNotFoundError
40
+ fontist_update_repo(manifest, agree, continue, no_progress)
41
+ end
42
+
43
+ def fontist_install(manifest, agree, no_progress)
44
+ if agree
45
+ no_license_log
46
+ else
47
+ Fontist.log_level = :info
48
+ end
49
+
50
+ Fontist::Manifest::Install.from_hash(
51
+ manifest,
52
+ confirmation: agree ? "yes" : "no",
53
+ no_progress: no_progress,
54
+ )
55
+ end
56
+
57
+ def license_error_log(continue)
58
+ if continue
59
+ Util.log(
60
+ "[fontist] Processing will continue without fonts installed",
61
+ :debug,
62
+ )
63
+ else
64
+ Util.log("[fontist] Aborting without proper fonts installed," \
65
+ " make sure that you have set option --agree-to-terms",
66
+ :fatal)
67
+ end
68
+ end
69
+
70
+ def no_license_log
71
+ Util.log(
72
+ "[fontist] Font licenses are not shown with --agree-to-terms option.",
73
+ :info,
74
+ )
75
+ end
76
+
77
+ def fontist_update_repo(manifest, agree, continue, no_progress)
78
+ if @@updated_formulas_repo
79
+ Util.log(
80
+ "[fontist] Bug: formula index not found after 'fontist update'",
81
+ :fatal,
82
+ )
83
+ end
84
+ Util.log("[fontist] Missing formula index. Fetching it...", :debug)
85
+ Fontist::Formula.update_formulas_repo
86
+ @@updated_formulas_repo = true
87
+ install_fonts_safe(manifest, agree, continue, no_progress)
88
+ end
89
+ end
90
+
91
+ def self.install_fonts(processor, options)
92
+ return unless validate_install_fonts(processor, options)
93
+
94
+ @@updated_formulas_repo = false
95
+ manifest = processor.fonts_manifest.dup
96
+ append_source_fonts(manifest, options)
97
+ agree_to_terms, can_without_fonts, no_progress = validate_options(options)
98
+
99
+ install_fonts_safe(
100
+ manifest,
101
+ agree_to_terms,
102
+ can_without_fonts,
103
+ no_progress,
104
+ )
105
+ end
106
+
107
+ def self.has_custom_fonts?(processor, options, source_attributes)
108
+ install_fonts?(options) \
109
+ && processor.respond_to?(:fonts_manifest) \
110
+ && !processor.fonts_manifest.nil? \
111
+ || source_attributes[:fonts]
112
+ end
113
+
114
+ def self.location_manifest(processor, source_attributes)
115
+ Fontist::Manifest::Locations.from_hash(
116
+ append_source_fonts(processor.fonts_manifest.dup, source_attributes),
117
+ )
118
+ end
119
+
120
+ def self.append_source_fonts(manifest, source_attributes)
121
+ source_attributes[:fonts]&.split(";")&.each { |f| manifest[f] = nil }
122
+ manifest
123
+ end
124
+
125
+ def self.install_fonts?(options)
126
+ options[:install_fonts].nil? || options[:install_fonts]
127
+ end
128
+ end
129
+ end
130
+ end