metanorma 2.0.0 → 2.5.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/.envrc +1 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +23 -2
- data/Gemfile +17 -0
- data/Gemfile.devel +10 -0
- data/README.adoc +1 -1
- data/lib/metanorma/collection/artifact_store.rb +142 -0
- data/lib/metanorma/collection/collection.rb +160 -122
- data/lib/metanorma/collection/config/bibdata.rb +3 -3
- data/lib/metanorma/collection/config/compile_options.rb +4 -5
- data/lib/metanorma/collection/config/config.rb +81 -83
- data/lib/metanorma/collection/config/converters.rb +92 -8
- data/lib/metanorma/collection/config/directive.rb +9 -3
- data/lib/metanorma/collection/config/doc_container.rb +28 -0
- data/lib/metanorma/collection/config/manifest.rb +59 -29
- data/lib/metanorma/collection/config/namespaces.rb +12 -0
- data/lib/metanorma/collection/document/document.rb +56 -15
- data/lib/metanorma/collection/filelookup/filelookup.rb +185 -77
- data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +99 -27
- data/lib/metanorma/collection/filelookup/utils.rb +52 -0
- data/lib/metanorma/collection/helpers.rb +82 -0
- data/lib/metanorma/collection/log.rb +24 -0
- data/lib/metanorma/collection/manifest/manifest.rb +45 -14
- data/lib/metanorma/collection/multilingual/multilingual.rb +660 -0
- data/lib/metanorma/collection/renderer/filelocation.rb +166 -0
- data/lib/metanorma/collection/renderer/fileparse.rb +135 -115
- data/lib/metanorma/collection/renderer/fileprocess.rb +185 -37
- data/lib/metanorma/collection/renderer/navigation.rb +21 -7
- data/lib/metanorma/collection/renderer/render_word.rb +15 -10
- data/lib/metanorma/collection/renderer/renderer.rb +236 -32
- data/lib/metanorma/collection/renderer/svg.rb +107 -0
- data/lib/metanorma/collection/renderer/utils.rb +110 -39
- data/lib/metanorma/collection/sectionsplit/collection.rb +110 -0
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +198 -115
- data/lib/metanorma/collection/util/disambig_files.rb +4 -5
- data/lib/metanorma/collection/util/util.rb +155 -18
- data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +47 -33
- data/lib/metanorma/compile/assets/icc-boilerplate.adoc +41 -0
- data/lib/metanorma/compile/compile.rb +181 -156
- data/lib/metanorma/compile/compile_options.rb +186 -79
- data/lib/metanorma/compile/extract.rb +75 -58
- data/lib/metanorma/compile/flavor.rb +28 -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/render.rb +226 -0
- data/lib/metanorma/compile/validator.rb +26 -0
- data/lib/metanorma/compile/writeable.rb +12 -0
- data/lib/metanorma/util/fontist_helper.rb +35 -19
- data/lib/metanorma/version.rb +1 -1
- data/lib/metanorma.rb +1 -7
- data/metanorma.gemspec +15 -21
- data/plans/collection-rendering-architecture-review.md +516 -0
- metadata +65 -113
- data/.hound.yml +0 -5
- data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +0 -22
- data/lib/metanorma/asciidoctor_extensions.rb +0 -1
- data/lib/metanorma/compile/compile_validate.rb +0 -68
- data/lib/metanorma/config/config.rb +0 -23
- data/lib/metanorma/input/asciidoc.rb +0 -107
- data/lib/metanorma/input/base.rb +0 -9
- data/lib/metanorma/input.rb +0 -7
- data/lib/metanorma/processor/processor.rb +0 -54
- data/lib/metanorma/processor.rb +0 -6
- data/lib/metanorma/registry/registry.rb +0 -63
- data/lib/metanorma/shale_monkeypatch.rb +0 -15
- data/lib/metanorma/util/util.rb +0 -45
|
@@ -5,14 +5,15 @@ module Metanorma
|
|
|
5
5
|
# xml.root["type"] = key # to force recognition of internal refs
|
|
6
6
|
# bookmarks etc as new id elements introduced in Presentation XML:
|
|
7
7
|
# add doc suffix
|
|
8
|
+
# Run on Semantic XML
|
|
8
9
|
def xref_preprocess(xml, isodoc)
|
|
9
10
|
@isodoc = isodoc
|
|
10
11
|
key = (0...8).map { rand(65..90).chr }.join # random string
|
|
11
12
|
xml.root["type"] = key
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
::Metanorma::Collection::Util::
|
|
15
|
-
xml, xml.root["document_suffix"], tag_name,
|
|
13
|
+
Util::anchor_id_attributes.each do |(tag_name, attr_name)|
|
|
14
|
+
#tag_name == "xref" and tag_name = "fmt-xref"
|
|
15
|
+
::Metanorma::Collection::Util::add_suffix_to_attrs(
|
|
16
|
+
xml, xml.root["document_suffix"], tag_name, attr_name, isodoc
|
|
16
17
|
)
|
|
17
18
|
end
|
|
18
19
|
key
|
|
@@ -22,38 +23,39 @@ module Metanorma
|
|
|
22
23
|
@isodoc.ns(xpath)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def xref_process(section, xml, key, ident, isodoc)
|
|
26
|
+
def xref_process(section, xml, key, ident, isodoc, presxml)
|
|
26
27
|
@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)
|
|
28
|
+
svg_preprocess(section, Metanorma::Utils::to_ncname(ident), presxml)
|
|
29
|
+
refs = eref_to_internal_eref(section, xml, key, presxml)
|
|
30
|
+
refs += xref_to_internal_eref(section, xml, key, presxml)
|
|
30
31
|
ins = new_hidden_ref(section)
|
|
31
32
|
copied_refs = copy_repo_items_biblio(ins, section, xml)
|
|
32
33
|
insert_indirect_biblio(ins, refs - copied_refs, key, xml)
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
def svg_preprocess(xml, doc_suffix)
|
|
36
|
+
def svg_preprocess(xml, doc_suffix, presxml)
|
|
36
37
|
suffix = doc_suffix.nil? || doc_suffix.blank? ? "" : "_#{doc_suffix}"
|
|
37
38
|
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)
|
|
39
|
+
m = svgmap_wrap(s) or next
|
|
40
|
+
svg_xrefs(s, m, suffix, presxml)
|
|
40
41
|
end
|
|
41
42
|
xml
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def svgmap_wrap(svg)
|
|
45
46
|
ret = svg.at("./ancestor::xmlns:svgmap") and return ret
|
|
46
|
-
ret = svg.at("./ancestor::xmlns:figure")
|
|
47
|
+
ret = svg.at("./ancestor::xmlns:figure") or return
|
|
47
48
|
ret.wrap("<svgmap/>")
|
|
48
49
|
svg.at("./ancestor::xmlns:svgmap")
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
def svg_xrefs(svg, svgmap, suffix)
|
|
52
|
+
def svg_xrefs(svg, svgmap, suffix, presxml)
|
|
53
|
+
tag = presxml ? "fmt-xref" : "xref"
|
|
52
54
|
svg.xpath(".//m:a", "m" => "http://www.w3.org/2000/svg").each do |a|
|
|
53
55
|
/^#/.match? a["href"] or next
|
|
54
56
|
a["href"] = a["href"].sub(/^#/, "")
|
|
55
57
|
svgmap << "<target href='#{a['href']}'>" \
|
|
56
|
-
"
|
|
58
|
+
"<#{tag} target='#{a['href']}#{suffix}'/></target>"
|
|
57
59
|
end
|
|
58
60
|
end
|
|
59
61
|
|
|
@@ -65,15 +67,16 @@ module Metanorma
|
|
|
65
67
|
"#{anchor}</referenceFrom></locality></localityStack>"
|
|
66
68
|
end
|
|
67
69
|
|
|
68
|
-
def xref_to_internal_eref(section, xml, key)
|
|
70
|
+
def xref_to_internal_eref(section, xml, key, presxml)
|
|
69
71
|
key or return [] # no sectionsplit, no playing with xrefs
|
|
70
72
|
bibitems, indirect = xref_to_internal_eref_prep(section, xml)
|
|
71
|
-
|
|
73
|
+
tag = presxml ? "fmt-xref" : "xref"
|
|
74
|
+
section.xpath(ns("//#{tag}")).each_with_object({}) do |x, m|
|
|
72
75
|
xref_prefix_key(x, key, indirect)
|
|
73
76
|
x["bibitemid"] = x["target"]
|
|
74
77
|
m[x["bibitemid"]] = true
|
|
75
|
-
xref_to_internal_eref_anchor(x,
|
|
76
|
-
xml.root["document_suffix"])
|
|
78
|
+
xref_to_internal_eref_anchor(x, bibitems,
|
|
79
|
+
xml.root["document_suffix"], presxml)
|
|
77
80
|
end.keys
|
|
78
81
|
end
|
|
79
82
|
|
|
@@ -84,8 +87,9 @@ module Metanorma
|
|
|
84
87
|
[bibitems, indirect_bibitems]
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
def xref_to_internal_eref_anchor(xref,
|
|
90
|
+
def xref_to_internal_eref_anchor(xref, bibitems, document_suffix, presxml)
|
|
88
91
|
t = xref["target"]
|
|
92
|
+
key = xref["type"]
|
|
89
93
|
if d = bibitems[t]&.at(ns("./docidentifier[@type = 'repository']"))
|
|
90
94
|
m = %r{^([^/]+)}.match(d.text) and
|
|
91
95
|
t.sub!(%r(#{m[0]}_), "")
|
|
@@ -93,7 +97,7 @@ module Metanorma
|
|
|
93
97
|
key and t.sub!(%r{^#{key}_}, "")
|
|
94
98
|
make_anchor(xref, t.sub(%r(_#{document_suffix}$), ""))
|
|
95
99
|
xref.delete("target")
|
|
96
|
-
xref.name = "eref"
|
|
100
|
+
xref.name = presxml ? "fmt-eref" : "eref"
|
|
97
101
|
end
|
|
98
102
|
|
|
99
103
|
def xref_prefix_key(xref, key, indirect)
|
|
@@ -106,30 +110,40 @@ module Metanorma
|
|
|
106
110
|
end
|
|
107
111
|
end
|
|
108
112
|
|
|
109
|
-
def
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
def select_citation_uri(bib, lang)
|
|
114
|
+
bib or return
|
|
115
|
+
url = bib.at(ns("./uri[@type = 'citation']" \
|
|
116
|
+
"[@language = '#{lang}']")) ||
|
|
117
|
+
bib.at(ns("./uri[@type = 'citation']"))
|
|
118
|
+
url&.text
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def eref_to_internal_eref(section, xml, key, presxml)
|
|
122
|
+
bibitems, indirect, bibids, lang =
|
|
123
|
+
eref_to_internal_eref_prep(section, xml, presxml)
|
|
124
|
+
eref_to_internal_eref_select(section, xml, bibitems, presxml)
|
|
112
125
|
.each_with_object([]) do |x, m|
|
|
113
|
-
url = bibitems[x]
|
|
126
|
+
url = select_citation_uri(bibitems[x], lang)
|
|
114
127
|
bibids[x]&.each do |e|
|
|
115
128
|
e.at(ns("./localityStack | ./locality")) and next
|
|
116
|
-
id = eref_to_internal_eref1(e, key, url, indirect) and m << id
|
|
129
|
+
id = eref_to_internal_eref1(e, key, url, indirect, presxml) and m << id
|
|
117
130
|
end
|
|
118
131
|
end
|
|
119
132
|
end
|
|
120
133
|
|
|
121
|
-
def eref_to_internal_eref_prep(section, xml)
|
|
134
|
+
def eref_to_internal_eref_prep(section, xml, presxml)
|
|
122
135
|
bibitems = ::Metanorma::Collection::Util::gather_bibitems(xml)
|
|
123
136
|
.delete_if { |_, v| internal_bib?(v) }
|
|
124
137
|
indirect = ::Metanorma::Collection::Util::gather_bibitems(xml)
|
|
125
138
|
.select { |_, v| indirect_bib?(v) }
|
|
126
|
-
bibitemids = ::Metanorma::Collection::Util::gather_bibitemids(section)
|
|
127
|
-
|
|
139
|
+
bibitemids = ::Metanorma::Collection::Util::gather_bibitemids(section, presxml)
|
|
140
|
+
lang = xml.at(ns("//bibdata/language"))&.text || "en"
|
|
141
|
+
[bibitems, indirect, bibitemids, lang]
|
|
128
142
|
end
|
|
129
143
|
|
|
130
|
-
def eref_to_internal_eref1(elem, key, url, indirect)
|
|
144
|
+
def eref_to_internal_eref1(elem, key, url, indirect, presxml)
|
|
131
145
|
if url
|
|
132
|
-
elem.name = "link"
|
|
146
|
+
elem.name = presxml ? "fmt-link" : "link"
|
|
133
147
|
elem["target"] = url
|
|
134
148
|
nil
|
|
135
149
|
elsif !indirect[elem["bibitemid"]]
|
|
@@ -152,8 +166,8 @@ module Metanorma
|
|
|
152
166
|
elem["bibitemid"]
|
|
153
167
|
end
|
|
154
168
|
|
|
155
|
-
def eref_to_internal_eref_select(section, _xml, bibitems)
|
|
156
|
-
refs = ::Metanorma::Collection::Util::gather_bibitemids(section).keys
|
|
169
|
+
def eref_to_internal_eref_select(section, _xml, bibitems, presxml)
|
|
170
|
+
refs = ::Metanorma::Collection::Util::gather_bibitemids(section, presxml).keys
|
|
157
171
|
refs.uniq.reject do |x|
|
|
158
172
|
b = bibitems[x] and (indirect_bib?(b) || internal_bib?(b))
|
|
159
173
|
end
|
|
@@ -211,7 +225,7 @@ module Metanorma
|
|
|
211
225
|
|
|
212
226
|
def new_indirect_bibitem(ident, prefix)
|
|
213
227
|
<<~BIBENTRY
|
|
214
|
-
<bibitem id="#{ident}" type="internal">
|
|
228
|
+
<bibitem id="#{ident}" anchor="#{ident}" type="internal">
|
|
215
229
|
<docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
|
|
216
230
|
</bibitem>
|
|
217
231
|
BIBENTRY
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
== copyright-statement
|
|
2
|
+
=== Copyright notice
|
|
3
|
+
|
|
4
|
+
Copyright © 1994-{{docyear}} International Color Consortium®
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
the Specification and associated documentation files (the “Specification”) to
|
|
8
|
+
deal in the Specification without restriction, including without limitation the
|
|
9
|
+
rights to use, copy, modify, merge, publish, distribute, and/or sublicense
|
|
10
|
+
copies of the Specification, and to permit persons to whom the Specification is
|
|
11
|
+
furnished to do so, subject to the following conditions.
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Specification.
|
|
15
|
+
|
|
16
|
+
The Specification is provided "as is", without warranty of any kind, express,
|
|
17
|
+
implied, or otherwise, including but not limited to the warranties of
|
|
18
|
+
merchantability, fitness for a particular purpose and noninfringement. In no
|
|
19
|
+
event shall the International Color Consortium be liable for any claim, damages
|
|
20
|
+
or other liability, whether in an action of contract, tort or otherwise, arising
|
|
21
|
+
from, out of, or in connection with the Specification or the use or other
|
|
22
|
+
dealings in the Specification.
|
|
23
|
+
|
|
24
|
+
Except as contained in this notice, the name of the International Color
|
|
25
|
+
Consortium shall not be used in advertising or otherwise to promote the use or
|
|
26
|
+
other dealings in this Specification without prior written authorization from
|
|
27
|
+
the International Color Consortium.
|
|
28
|
+
|
|
29
|
+
== license-statement
|
|
30
|
+
=== Licenses and trademarks
|
|
31
|
+
|
|
32
|
+
International Color Consortium and the ICC logo are registered trademarks of the
|
|
33
|
+
International Color Consortium. Rather than put a trademark symbol in every
|
|
34
|
+
occurrence of other trademarked names, we state that we are using the names only
|
|
35
|
+
in an editorial fashion, and to the benefit of the trademark owner, with no
|
|
36
|
+
intention of infringement of the trademark.
|
|
37
|
+
|
|
38
|
+
== feedback-statement
|
|
39
|
+
=== For additional information on the ICC
|
|
40
|
+
|
|
41
|
+
Visit the ICC Web site: http://www.color.org
|
|
@@ -1,21 +1,38 @@
|
|
|
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
|
-
require "fontist/manifest
|
|
7
|
-
|
|
8
|
+
require "fontist/manifest"
|
|
9
|
+
require "metanorma-taste"
|
|
10
|
+
require_relative "writeable"
|
|
11
|
+
require_relative "validator"
|
|
8
12
|
require_relative "compile_options"
|
|
9
13
|
require_relative "../util/fontist_helper"
|
|
10
|
-
|
|
14
|
+
require "metanorma-core"
|
|
11
15
|
require_relative "extract"
|
|
12
16
|
require_relative "../collection/sectionsplit/sectionsplit"
|
|
13
17
|
require_relative "../util/worker_pool"
|
|
18
|
+
require_relative "output_filename"
|
|
19
|
+
require_relative "output_filename_config"
|
|
20
|
+
require_relative "flavor"
|
|
21
|
+
require_relative "relaton_drop"
|
|
22
|
+
require_relative "render"
|
|
14
23
|
|
|
15
24
|
module Metanorma
|
|
16
25
|
class Compile
|
|
26
|
+
include Validator
|
|
27
|
+
include CompileOptions
|
|
28
|
+
include Flavor
|
|
29
|
+
include Writeable
|
|
30
|
+
|
|
31
|
+
DEFAULT_NUM_WORKERS = 3
|
|
32
|
+
|
|
17
33
|
# @return [Array<String>]
|
|
18
|
-
attr_reader :errors
|
|
34
|
+
attr_reader :errors
|
|
35
|
+
attr_reader :processor
|
|
19
36
|
|
|
20
37
|
def initialize
|
|
21
38
|
@registry = Metanorma::Registry.instance
|
|
@@ -25,21 +42,43 @@ module Metanorma
|
|
|
25
42
|
@log = Metanorma::Utils::Log.new
|
|
26
43
|
end
|
|
27
44
|
|
|
45
|
+
# Main compile method that orchestrates the document conversion process
|
|
46
|
+
# @param filename [String] path to the input file
|
|
47
|
+
# @param options [Hash] compilation options
|
|
28
48
|
def compile(filename, options = {})
|
|
29
|
-
|
|
49
|
+
process_options!(filename, options)
|
|
30
50
|
@processor = @registry.find_processor(options[:type].to_sym)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
51
|
+
|
|
52
|
+
# Step 1: Generate Semantic XML
|
|
53
|
+
semantic_result = generate_semantic_xml(filename, options) or return nil
|
|
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
|
+
@extensions = extensions # Capture extensions for later access
|
|
64
|
+
extensions or return nil
|
|
65
|
+
|
|
66
|
+
# Step 4: Extract information from Semantic XML if requested
|
|
67
|
+
extract_information(semantic_xml, bibdata, options)
|
|
68
|
+
|
|
69
|
+
# Step 5: Generate output formats from Semantic XML
|
|
70
|
+
generate_outputs(
|
|
71
|
+
source_file, semantic_xml, bibdata, extensions, output_paths,
|
|
72
|
+
options
|
|
73
|
+
)
|
|
74
|
+
ensure
|
|
36
75
|
clean_exit(options)
|
|
37
76
|
end
|
|
38
77
|
|
|
39
|
-
def
|
|
78
|
+
def process_options!(filename, options)
|
|
40
79
|
require_libraries(options)
|
|
41
|
-
options =
|
|
42
|
-
validate_options(options)
|
|
80
|
+
options = extract_options(filename, options)
|
|
81
|
+
validate_options!(options)
|
|
43
82
|
@log.save_to(filename, options[:output_dir])
|
|
44
83
|
options[:log] = @log
|
|
45
84
|
end
|
|
@@ -49,7 +88,11 @@ module Metanorma
|
|
|
49
88
|
@log.write
|
|
50
89
|
end
|
|
51
90
|
|
|
52
|
-
|
|
91
|
+
# Step 1: Generate Semantic XML from input file
|
|
92
|
+
# @param filename [String] input file path
|
|
93
|
+
# @param options [Hash] compilation options
|
|
94
|
+
# @return [Array, nil] tuple of [source_file, semantic_xml] or nil on failure
|
|
95
|
+
def generate_semantic_xml(filename, options)
|
|
53
96
|
case extname = File.extname(filename)
|
|
54
97
|
when ".adoc" then process_input_adoc(filename, options)
|
|
55
98
|
when ".xml" then process_input_xml(filename, options)
|
|
@@ -60,175 +103,157 @@ module Metanorma
|
|
|
60
103
|
end
|
|
61
104
|
end
|
|
62
105
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
106
|
+
# Step 2: Prepare output paths for generated files
|
|
107
|
+
# Use default filename template if empty string is provided.
|
|
108
|
+
#
|
|
109
|
+
# @param filename [String] input file path
|
|
110
|
+
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
|
111
|
+
# @param options [Hash] compilation options
|
|
112
|
+
# @return [Hash] paths for different output formats
|
|
113
|
+
def prepare_output_paths(filename, bibdata, options)
|
|
114
|
+
basename = if options[:filename_template].nil?
|
|
115
|
+
filename.sub(/\.[^.]+$/, "")
|
|
116
|
+
else
|
|
117
|
+
drop = RelatonDrop.new(bibdata)
|
|
118
|
+
config = OutputFilenameConfig.new(options[:filename_template])
|
|
119
|
+
config.generate_filename(drop)
|
|
120
|
+
end
|
|
121
|
+
@output_filename = OutputFilename.new(
|
|
122
|
+
basename, options[:output_dir], @processor
|
|
123
|
+
)
|
|
124
|
+
{
|
|
125
|
+
xml: @output_filename.semantic_xml,
|
|
126
|
+
orig_filename: filename,
|
|
127
|
+
presentationxml: @output_filename.presentation_xml,
|
|
128
|
+
}
|
|
73
129
|
end
|
|
74
130
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
131
|
+
# Step 4: Extract information from Semantic XML
|
|
132
|
+
# @param semantic_xml [String] semantic XML content
|
|
133
|
+
# @param options [Hash] compilation options
|
|
134
|
+
def extract_information(semantic_xml, bibdata, options)
|
|
135
|
+
# Extract Relaton bibliographic data
|
|
136
|
+
export_relaton_from_bibdata(bibdata, options) if options[:relaton]
|
|
137
|
+
# Extract other components (sourcecode, images, requirements)
|
|
138
|
+
if options[:extract]
|
|
139
|
+
Extract.extract(
|
|
140
|
+
semantic_xml, options[:extract], options[:extract_type]
|
|
141
|
+
)
|
|
142
|
+
end
|
|
80
143
|
end
|
|
81
144
|
|
|
82
|
-
|
|
83
|
-
|
|
145
|
+
# Step 5: Generate output formats from Semantic XML
|
|
146
|
+
# @param source_file [String] source file content
|
|
147
|
+
# @param semantic_xml [String] semantic XML content
|
|
148
|
+
# @param bibdata [Nokogiri::XML::Element] the bibliographic data element
|
|
149
|
+
# @param extensions [Array<Symbol>] output formats to generate
|
|
150
|
+
# @param output_paths [Hash] paths for output files
|
|
151
|
+
# @param options [Hash] compilation options
|
|
152
|
+
def generate_outputs(
|
|
153
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
|
154
|
+
)
|
|
155
|
+
if extensions == %i(presentation)
|
|
156
|
+
# Just generate presentation XML
|
|
157
|
+
generate_presentation_xml(
|
|
158
|
+
source_file, semantic_xml, bibdata, output_paths, options
|
|
159
|
+
)
|
|
160
|
+
else
|
|
161
|
+
# Generate multiple output formats with parallel processing
|
|
162
|
+
generate_outputs_parallel(
|
|
163
|
+
source_file, semantic_xml, bibdata, extensions, output_paths, options
|
|
164
|
+
)
|
|
165
|
+
end
|
|
84
166
|
end
|
|
85
167
|
|
|
86
|
-
def
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
#
|
|
92
|
-
# outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
|
|
93
|
-
File.open(options[:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml }
|
|
168
|
+
def process_input_adoc_hdr(file, options)
|
|
169
|
+
hdr, rest = Metanorma::Input::Asciidoc.new.header(file)
|
|
170
|
+
attrs = hdr.split("\n")
|
|
171
|
+
options[:asciimath] and attrs << ":mn-keep-asciimath:"
|
|
172
|
+
process_input_adoc_overrides(attrs, options)
|
|
173
|
+
"#{attrs.join("\n")}\n\n#{rest}"
|
|
94
174
|
end
|
|
95
175
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
|
|
176
|
+
def process_input_adoc_overrides(attrs, options)
|
|
177
|
+
Metanorma::TasteRegister.instance.available_tastes
|
|
178
|
+
.include?(options[:supplied_type]) or return
|
|
179
|
+
c = Metanorma::TasteRegister.get(options[:supplied_type])
|
|
180
|
+
c.process_input_adoc_overrides(attrs, options)
|
|
99
181
|
end
|
|
100
182
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
end
|
|
183
|
+
def process_input_adoc_includes(file, filename)
|
|
184
|
+
dir = File.dirname(filename)
|
|
185
|
+
dir != "." and
|
|
186
|
+
file = file.gsub(/^include::/, "include::#{dir}/")
|
|
187
|
+
.gsub(/^embed::/, "embed::#{dir}/")
|
|
188
|
+
file
|
|
108
189
|
end
|
|
109
190
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@
|
|
117
|
-
.new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
|
|
118
|
-
gather_and_install_fonts(file, options.dup, extensions)
|
|
119
|
-
process_exts_run(fnames, file, isodoc, extensions, options)
|
|
120
|
-
@queue.shutdown
|
|
191
|
+
def process_input_adoc(filename, options)
|
|
192
|
+
Util.log("[metanorma] Processing: AsciiDoc input.", :info)
|
|
193
|
+
file = read_file(filename)
|
|
194
|
+
file = process_input_adoc_hdr(file, options)
|
|
195
|
+
file = process_input_adoc_includes(file, filename)
|
|
196
|
+
update_options_after_preprocessing(file, options)
|
|
197
|
+
[file, @processor.input_to_isodoc(file, filename, options)]
|
|
121
198
|
end
|
|
122
199
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
200
|
+
# need to update options, for any content added;
|
|
201
|
+
# e.g. new attributes from Metanorma taste
|
|
202
|
+
def update_options_after_preprocessing(file, options)
|
|
203
|
+
new_options = { extension_keys: options[:extension_keys] }
|
|
204
|
+
Tempfile.open(["tmp", ".adoc"], encoding: "UTF-8") do |f|
|
|
205
|
+
f.write(file)
|
|
206
|
+
f.close
|
|
207
|
+
new_options = extract_options(f, new_options)
|
|
126
208
|
end
|
|
209
|
+
new_options.compact!
|
|
210
|
+
new_options.delete(:filename)
|
|
211
|
+
options.merge!(new_options)
|
|
127
212
|
end
|
|
128
213
|
|
|
129
|
-
def
|
|
130
|
-
Util.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
214
|
+
def process_input_xml(filename, _options)
|
|
215
|
+
Util.log("[metanorma] Processing: Metanorma XML input.", :info)
|
|
216
|
+
# TODO NN: this is a hack -- we should provide/bridge the
|
|
217
|
+
# document attributes in Metanorma XML
|
|
218
|
+
["", read_file(filename)]
|
|
134
219
|
end
|
|
135
220
|
|
|
136
|
-
def
|
|
137
|
-
|
|
138
|
-
fnames[:out] = fnames[:f].sub(/\.[^.]+$/, ".#{fnames[:ext]}")
|
|
139
|
-
isodoc_options = get_isodoc_options(file, options, ext)
|
|
140
|
-
thread = true
|
|
141
|
-
unless process_ext_simple(ext, isodoc, fnames, options,
|
|
142
|
-
isodoc_options)
|
|
143
|
-
thread = process_exts1(ext, fnames, isodoc, options, isodoc_options)
|
|
144
|
-
end
|
|
145
|
-
thread
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def process_ext_simple(ext, isodoc, fnames, options, isodoc_options)
|
|
149
|
-
if ext == :rxl
|
|
150
|
-
relaton_export(isodoc, options.merge(relaton: fnames[:out]))
|
|
151
|
-
elsif options[:passthrough_presentation_xml] && ext == :presentation
|
|
152
|
-
f = File.exist?(fnames[:f]) ? fnames[:f] : fnames[:orig_filename]
|
|
153
|
-
FileUtils.cp f, fnames[:presentationxml]
|
|
154
|
-
elsif ext == :html && options[:sectionsplit]
|
|
155
|
-
sectionsplit_convert(fnames[:xml], isodoc, fnames[:out],
|
|
156
|
-
isodoc_options)
|
|
157
|
-
else return false
|
|
158
|
-
end
|
|
159
|
-
true
|
|
221
|
+
def read_file(filename)
|
|
222
|
+
File.read(filename, encoding: "utf-8").gsub("\r\n", "\n")
|
|
160
223
|
end
|
|
161
224
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
225
|
+
# Returns a mapping of format types to file suffixes based on the
|
|
226
|
+
# extensions that were determined during compilation.
|
|
227
|
+
# This method is only available after compile() has been called and
|
|
228
|
+
# reached Step 3 where extensions are finalized.
|
|
229
|
+
#
|
|
230
|
+
# @return [Hash] mapping of format symbols to file extensions
|
|
231
|
+
# e.g., { html: "html", doc: "doc", pdf: "pdf" }
|
|
232
|
+
# @return [Hash] empty hash if extensions haven't been captured yet
|
|
233
|
+
def output_format_mapping
|
|
234
|
+
@extensions && @processor or return {}
|
|
235
|
+
@extensions.each_with_object({}) do |ext, mapping|
|
|
236
|
+
if @processor.output_formats[ext]
|
|
237
|
+
mapping[ext] = @processor.output_formats[ext]
|
|
167
238
|
end
|
|
168
|
-
else
|
|
169
|
-
process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
|
|
170
239
|
end
|
|
171
240
|
end
|
|
172
241
|
|
|
173
|
-
def
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
@processor.output(isodoc, fnames[:xml], fnames[:out], ext,
|
|
184
|
-
isodoc_options)
|
|
185
|
-
true # return as Thread
|
|
186
|
-
rescue StandardError => e
|
|
187
|
-
strict = ext == :presentation || isodoc_options[:strict] == "true"
|
|
188
|
-
isodoc_error_process(e, strict, true)
|
|
189
|
-
ext != :presentation
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# assume we pass in Presentation XML, but we want to recover Semantic XML
|
|
193
|
-
def sectionsplit_convert(input_filename, file, output_filename = nil,
|
|
194
|
-
opts = {})
|
|
195
|
-
@isodoc ||= IsoDoc::PresentationXMLConvert.new({})
|
|
196
|
-
input_filename += ".xml" unless input_filename.match?(/\.xml$/)
|
|
197
|
-
File.exist?(input_filename) or
|
|
198
|
-
File.open(input_filename, "w:UTF-8") { |f| f.write(file) }
|
|
199
|
-
presxml = File.read(input_filename, encoding: "utf-8")
|
|
200
|
-
_xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
|
|
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
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
private
|
|
214
|
-
|
|
215
|
-
def isodoc_error_process(err, strict, must_abort)
|
|
216
|
-
if strict || err.message.include?("Fatal:")
|
|
217
|
-
@errors << err.message
|
|
218
|
-
else
|
|
219
|
-
puts err.message
|
|
220
|
-
end
|
|
221
|
-
puts err.backtrace.join("\n")
|
|
222
|
-
must_abort and 1
|
|
242
|
+
def process_compile_dummy(flavor)
|
|
243
|
+
file = Tempfile.new(%w(tmp .adoc))
|
|
244
|
+
file.write <<~OUTPUT
|
|
245
|
+
Document Title
|
|
246
|
+
:flavor: #{flavor}
|
|
247
|
+
:mn-output-extensions: xml, presentation
|
|
248
|
+
|
|
249
|
+
OUTPUT
|
|
250
|
+
file.close
|
|
251
|
+
compile(file.path, agree_to_terms: true)
|
|
223
252
|
end
|
|
224
253
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if options[:output_dir]
|
|
229
|
-
File.join options[:output_dir], File.basename(options[:filename])
|
|
230
|
-
else options[:filename]
|
|
231
|
-
end
|
|
254
|
+
def extract_log_messages(flavor)
|
|
255
|
+
process_compile_dummy(flavor)
|
|
256
|
+
@log.display_messages
|
|
232
257
|
end
|
|
233
258
|
end
|
|
234
259
|
end
|