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
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require "isodoc"
|
|
4
4
|
require "metanorma-utils"
|
|
5
5
|
require_relative "fileparse"
|
|
6
|
+
require_relative "filelocation"
|
|
7
|
+
require_relative "../artifact_store"
|
|
8
|
+
require "json"
|
|
6
9
|
|
|
7
10
|
module Metanorma
|
|
8
11
|
class Collection
|
|
@@ -10,15 +13,78 @@ module Metanorma
|
|
|
10
13
|
# compile and output individual file in collection
|
|
11
14
|
# warn "metanorma compile -x html #{f.path}"
|
|
12
15
|
def file_compile(file, filename, identifier)
|
|
13
|
-
@files.get(identifier, :sectionsplit)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
sectionsplit_val = @files.get(identifier, :sectionsplit)
|
|
17
|
+
sectionsplit_val and return
|
|
18
|
+
opts = compile_options_base(identifier)
|
|
19
|
+
.merge(compile_options_update(identifier))
|
|
20
|
+
|
|
21
|
+
err_count = @compile.errors.size
|
|
19
22
|
@compile.compile file, opts
|
|
20
23
|
@files.set(identifier, :outputs, {})
|
|
21
|
-
file_compile_formats(filename, identifier)
|
|
24
|
+
file_compile_formats(filename, identifier, opts)
|
|
25
|
+
file_compile_verify(identifier, @compile.errors[err_count..] || [])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# A member whose rendering raised produces no output file, but the
|
|
29
|
+
# collection build used to continue, exit 0, and link the absent
|
|
30
|
+
# document from index.html -- silent data loss (#586). Two
|
|
31
|
+
# complementary checks close that hole. (1) Compile pools rescued
|
|
32
|
+
# error messages in @compile.errors for its caller to surface; the
|
|
33
|
+
# standalone CLI does, but the collection pipeline never read the
|
|
34
|
+
# pool. The pool is shared across members and never reset, so the
|
|
35
|
+
# slice appended during this member's compile is this member's
|
|
36
|
+
# errors -- sound while members compile sequentially (the current
|
|
37
|
+
# design; @compile's own format-level parallelism is joined before
|
|
38
|
+
# compile returns). (2) Independently of whether anything was
|
|
39
|
+
# pooled, verify the outputs registered for the member exist on
|
|
40
|
+
# disk. Failures are reported here and accumulated; the collection
|
|
41
|
+
# renders every remaining member before Collection#render aborts,
|
|
42
|
+
# so one run reports all failed members.
|
|
43
|
+
def file_compile_verify(identifier, errors)
|
|
44
|
+
# Section-split parts (marked with :parentid) register format
|
|
45
|
+
# slots they never produce -- their :xml slot in particular is
|
|
46
|
+
# never written, and under filename renaming it aliases to the
|
|
47
|
+
# parent's name -- so verifying them is a false positive. #586
|
|
48
|
+
# was scoped to the non-sectionsplit path; parts are excluded
|
|
49
|
+
# like their parents (which return early above).
|
|
50
|
+
@files.get(identifier, :parentid) and return
|
|
51
|
+
missing = (@files.get(identifier, :outputs) || {})
|
|
52
|
+
.reject { |_fmt, path| File.exist?(path) }
|
|
53
|
+
errors.empty? && missing.empty? and return
|
|
54
|
+
file_compile_failure_log(identifier, errors, missing)
|
|
55
|
+
msg = file_compile_failure_msg(identifier, errors, missing)
|
|
56
|
+
::Metanorma::Util.log("[metanorma] Error: #{msg}", :error)
|
|
57
|
+
fatal_errors << msg
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def file_compile_failure_log(identifier, errors, missing)
|
|
61
|
+
missing.each_value do |path|
|
|
62
|
+
@log&.add("METANORMA_4", nil, params: [identifier, path])
|
|
63
|
+
end
|
|
64
|
+
errors.each do |e|
|
|
65
|
+
@log&.add("METANORMA_5", nil, params: [identifier, e])
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def file_compile_failure_msg(identifier, errors, missing)
|
|
70
|
+
ret = []
|
|
71
|
+
missing.empty? or
|
|
72
|
+
ret << "expected output not generated: " \
|
|
73
|
+
"#{missing.values.join(', ')}"
|
|
74
|
+
ret += errors
|
|
75
|
+
"Failed to render collection member #{identifier}: #{ret.join('; ')}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def compile_options_base(identifier)
|
|
79
|
+
e = @files.get(identifier, :extract_opts)
|
|
80
|
+
{
|
|
81
|
+
format: :asciidoc,
|
|
82
|
+
extension_keys: @files.get(identifier, :format),
|
|
83
|
+
fonts: e&.dig(:fonts),
|
|
84
|
+
output_dir: @outdir,
|
|
85
|
+
pdffile: @files.get(identifier, :pdffile),
|
|
86
|
+
type: Util::taste2flavor(@flavor),
|
|
87
|
+
}
|
|
22
88
|
end
|
|
23
89
|
|
|
24
90
|
def compile_options_update(identifier)
|
|
@@ -33,26 +99,14 @@ module Metanorma
|
|
|
33
99
|
ret
|
|
34
100
|
end
|
|
35
101
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
end
|
|
45
|
-
@files.set(identifier, :outputs, f)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def copy_file_to_dest(identifier)
|
|
49
|
-
out = Pathname.new(@files.get(identifier, :out_path)).cleanpath
|
|
50
|
-
out.absolute? and
|
|
51
|
-
out = out.relative_path_from(File.expand_path(FileUtils.pwd))
|
|
52
|
-
dest = File.join(@outdir, @disambig.source2dest_filename(out.to_s))
|
|
53
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
54
|
-
FileUtils.cp @files.get(identifier, :ref), dest
|
|
55
|
-
end
|
|
102
|
+
# def allowed_extension_keys
|
|
103
|
+
# ret = @format.dup
|
|
104
|
+
# @directives.detect { |d| d.key == "individual-pdf" } or
|
|
105
|
+
# ret.delete(:pdf)
|
|
106
|
+
# @directives.detect { |d| d.key == "individual-doc" } or
|
|
107
|
+
# ret.delete(:doc)
|
|
108
|
+
# ret
|
|
109
|
+
# end
|
|
56
110
|
|
|
57
111
|
# process each file in the collection
|
|
58
112
|
# files are held in memory, and altered as postprocessing
|
|
@@ -67,22 +121,55 @@ module Metanorma
|
|
|
67
121
|
if @files.get(ident, :attachment) then copy_file_to_dest(ident)
|
|
68
122
|
else
|
|
69
123
|
file, fname = @files.targetfile_id(ident, read: true)
|
|
124
|
+
@preserve_unresolved && member_stored?(ident, file) and next
|
|
70
125
|
warn "\n\n\n\n\nProcess #{fname}: #{DateTime.now.strftime('%H:%M:%S')}"
|
|
71
126
|
collection_xml = update_xrefs(file, ident, internal_refs)
|
|
72
|
-
|
|
127
|
+
@preserve_unresolved and
|
|
128
|
+
store_member_artefacts(ident, file, collection_xml)
|
|
129
|
+
# Strip .xml or .html extension, but NOT section numbers like .0
|
|
130
|
+
fname_base = File.basename(fname)
|
|
131
|
+
collection_filename = fname_base
|
|
132
|
+
/\.(xml|html)$/.match?(fname_base) and
|
|
133
|
+
collection_filename = fname_base.sub(/\.(xml|html)$/, "")
|
|
73
134
|
collection_xml_path = File.join(Dir.tmpdir,
|
|
74
135
|
"#{collection_filename}.xml")
|
|
75
136
|
File.write collection_xml_path, collection_xml, encoding: "UTF-8"
|
|
76
137
|
file_compile(collection_xml_path, fname, ident)
|
|
77
|
-
FileUtils.
|
|
138
|
+
FileUtils.rm_f(collection_xml_path)
|
|
78
139
|
end
|
|
79
140
|
end
|
|
80
141
|
end
|
|
81
142
|
|
|
143
|
+
# Persist an isolated member's stub-bearing Semantic XML and its anchor
|
|
144
|
+
# contribution to the content-addressed store, so a later reinflation pass
|
|
145
|
+
# can relink the stubs and a re-run can resume without recompiling.
|
|
146
|
+
# Within-campaign content key for a member. (Cross-build soundness needs
|
|
147
|
+
# the full input closure -- source + includes + templates + schemas +
|
|
148
|
+
# versions; see the plan gotcha. Here the source bytes + tool version
|
|
149
|
+
# suffice because inputs are frozen across a single build campaign.)
|
|
150
|
+
def member_content_hash(source)
|
|
151
|
+
ArtifactStore.content_hash(source, ::Metanorma::VERSION)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Resume predicate: is this member already compiled and stored for its
|
|
155
|
+
# current input content? If so the isolated compile can skip it.
|
|
156
|
+
def member_stored?(ident, source)
|
|
157
|
+
@artifact_store.key?(ident, member_content_hash(source), :semantic)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def store_member_artefacts(ident, source, semantic_xml)
|
|
161
|
+
hash = member_content_hash(source)
|
|
162
|
+
@artifact_store.write(ident, hash, :semantic, semantic_xml)
|
|
163
|
+
@artifact_store.write(ident, hash, :anchors,
|
|
164
|
+
JSON.generate(@files.get(ident, :anchors) || {}))
|
|
165
|
+
@keep_cache or @artifact_store.prune_superseded(ident, hash)
|
|
166
|
+
end
|
|
167
|
+
|
|
82
168
|
# gather internal bibitem references
|
|
83
169
|
def gather_internal_refs
|
|
84
170
|
@files.keys.each_with_object({}) do |i, refs|
|
|
85
171
|
@files.get(i, :attachment) and next
|
|
172
|
+
@files.get(i, :sectionsplit) and next
|
|
86
173
|
file, = @files.targetfile_id(i, read: true)
|
|
87
174
|
gather_internal_refs1(file, i, refs)
|
|
88
175
|
end
|
|
@@ -131,7 +218,7 @@ module Metanorma
|
|
|
131
218
|
ids.each do |id, key|
|
|
132
219
|
key and next
|
|
133
220
|
refs[schema][id] = "Missing:#{schema}:#{id}"
|
|
134
|
-
@log&.add("
|
|
221
|
+
@log&.add("METANORMA_1", nil, params: [refs[schema][id]])
|
|
135
222
|
end
|
|
136
223
|
end
|
|
137
224
|
refs
|
|
@@ -151,23 +238,84 @@ module Metanorma
|
|
|
151
238
|
def locate_internal_refs1_prep(file)
|
|
152
239
|
xml = Nokogiri::XML(file, &:huge)
|
|
153
240
|
r = xml.root["document_suffix"]
|
|
154
|
-
xml.xpath("//*[@id]").each_with_object({}) do |i, x|
|
|
155
|
-
/^semantic_/.match?(i.name) and next
|
|
241
|
+
ret = xml.xpath("//*[@id]").each_with_object({}) do |i, x|
|
|
156
242
|
x[i["id"]] = i
|
|
157
243
|
r and x[i["id"].sub(/_#{r}$/, "")] = i
|
|
158
244
|
end
|
|
245
|
+
xml.xpath("//*[@anchor]").each do |i|
|
|
246
|
+
ret[i["anchor"]] = i
|
|
247
|
+
r and ret[i["anchor"].sub(/_#{r}$/, "")] = i
|
|
248
|
+
end
|
|
249
|
+
ret
|
|
159
250
|
end
|
|
160
251
|
|
|
161
252
|
def update_bibitem(bib, identifier)
|
|
162
|
-
|
|
163
|
-
newbib
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
253
|
+
newbib, url, attachment = update_bibitem_prep(bib, identifier)
|
|
254
|
+
newbib or return
|
|
255
|
+
dest = begin
|
|
256
|
+
newbib.at("./docidentifier") || newbib.at(ns("./docidentifier"))
|
|
257
|
+
rescue StandardError
|
|
258
|
+
nil
|
|
259
|
+
end
|
|
167
260
|
dest or dest = newbib.elements[-1]
|
|
261
|
+
# An attachment carries both a <uri type="attachment"> (which drives
|
|
262
|
+
# isodoc's fmt-link attachment="true") and the citation uri; the
|
|
263
|
+
# attachment uri goes first. metanorma/iso-10303#208.
|
|
264
|
+
attachment and dest.previous = "<uri type='attachment'>#{url}</uri>"
|
|
168
265
|
dest.previous = "<uri type='citation'>#{url}</uri>"
|
|
169
266
|
bib.replace(newbib)
|
|
170
267
|
end
|
|
268
|
+
|
|
269
|
+
def update_bibitem_prep(bib, identifier)
|
|
270
|
+
docid = get_bibitem_docid(bib, identifier) or return [nil, nil, nil]
|
|
271
|
+
newbib = dup_bibitem(docid, bib)
|
|
272
|
+
attachment = @files.get(docid, :attachment)
|
|
273
|
+
url = @files.url(docid, relative: true, doc: !attachment)
|
|
274
|
+
current_html = referencing_html_location(identifier, attachment)
|
|
275
|
+
url = make_relative_path(current_html, url) if current_html
|
|
276
|
+
[newbib, url, attachment]
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Location of the HTML that will carry the cross-reference to the target,
|
|
280
|
+
# used as the base for relativising the attachment/citation URL.
|
|
281
|
+
#
|
|
282
|
+
# Normally this is the referencing document's own output (:outputs[:html]
|
|
283
|
+
# after compilation, else :out_path converted to .html before it).
|
|
284
|
+
#
|
|
285
|
+
# But when the referencing document is sectionsplit, its content is not
|
|
286
|
+
# emitted at its own out_path: it is split into section files written at
|
|
287
|
+
# the sectionsplit output location (the collection root, unless a
|
|
288
|
+
# sectionsplit_filename directory is configured). Relativising an
|
|
289
|
+
# attachment URL against the unsplit out_path then overshoots -- the
|
|
290
|
+
# ../../ climbs above the split file and the attachment link breaks
|
|
291
|
+
# (https://github.com/metanorma/iso-10303/issues/208). So for attachment
|
|
292
|
+
# targets of a sectionsplit document, base the relative path on the
|
|
293
|
+
# sectionsplit output directory instead.
|
|
294
|
+
def referencing_html_location(identifier, attachment)
|
|
295
|
+
attachment && @files.get(identifier, :sectionsplit) and
|
|
296
|
+
return sectionsplit_ref_html(identifier)
|
|
297
|
+
document_ref_html(identifier)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# The split section files sit at the sectionsplit output directory: the
|
|
301
|
+
# collection root, or the directory of a configured sectionsplit_filename.
|
|
302
|
+
def sectionsplit_ref_html(identifier)
|
|
303
|
+
d = @files.preserve_directory_structure?(identifier)
|
|
304
|
+
d ? File.join(File.dirname(d), "x.html") : "x.html"
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Use :outputs[:html] if available (after compilation), otherwise convert
|
|
308
|
+
# :out_path to HTML (before compilation), following ref_file_xml2html.
|
|
309
|
+
def document_ref_html(identifier)
|
|
310
|
+
@files.get(identifier, :outputs)&.dig(:html) ||
|
|
311
|
+
out_path_to_html(@files.get(identifier, :out_path))
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def out_path_to_html(out_path)
|
|
315
|
+
out_path or return nil
|
|
316
|
+
out_path.end_with?(".xml") and return out_path.sub(/\.xml$/, ".html")
|
|
317
|
+
"#{out_path}.html"
|
|
318
|
+
end
|
|
171
319
|
end
|
|
172
320
|
end
|
|
173
321
|
end
|
|
@@ -4,10 +4,10 @@ module Metanorma
|
|
|
4
4
|
# @param elm [Nokogiri::XML::Element]
|
|
5
5
|
# @return [String]
|
|
6
6
|
def indexfile_title(entry)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
x.
|
|
7
|
+
titles = entry.bibdata && Array(entry.bibdata.title)
|
|
8
|
+
if titles && !titles.empty? &&
|
|
9
|
+
(x = titles.detect { |t| t.type == "main" } || titles.first)
|
|
10
|
+
x.content
|
|
11
11
|
else
|
|
12
12
|
entry.title
|
|
13
13
|
end
|
|
@@ -39,9 +39,23 @@ module Metanorma
|
|
|
39
39
|
@c.decode(@isodoc.docid_prefix(nil, ident))
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Check if file has a recognized MIME type (other than XML)
|
|
43
|
+
# If so, don't append .html (e.g., .svg, .png, .jpg, etc.)
|
|
42
44
|
def index_link(docref, ident)
|
|
43
45
|
if docref.file
|
|
44
|
-
@files.get(ident, :out_path)
|
|
46
|
+
out_path = @files.get(ident, :out_path)
|
|
47
|
+
# Ensure the path ends with .html for documents, but not for recognized file types
|
|
48
|
+
if Util::mime_file_recognised?(out_path) && !out_path.end_with?(".xml")
|
|
49
|
+
# File has a recognized extension (like .svg, .png), keep it as is
|
|
50
|
+
out_path
|
|
51
|
+
elsif out_path.end_with?(".xml")
|
|
52
|
+
out_path.sub(/\.xml$/, ".html")
|
|
53
|
+
elsif out_path.end_with?(".html")
|
|
54
|
+
out_path
|
|
55
|
+
else
|
|
56
|
+
"#{out_path}.html"
|
|
57
|
+
end
|
|
58
|
+
|
|
45
59
|
else "#{docref.id}.html"
|
|
46
60
|
end
|
|
47
61
|
end
|
|
@@ -55,7 +69,7 @@ module Metanorma
|
|
|
55
69
|
|
|
56
70
|
def index?(mnf)
|
|
57
71
|
mnf.index and return true
|
|
58
|
-
mnf.entry
|
|
72
|
+
mnf.entry&.detect { |e| index?(e) }
|
|
59
73
|
end
|
|
60
74
|
|
|
61
75
|
def indexfile1(mnf)
|
|
@@ -114,7 +128,7 @@ module Metanorma
|
|
|
114
128
|
files.each { |f| docrefs(f, u) }
|
|
115
129
|
end
|
|
116
130
|
end
|
|
117
|
-
r.doc.root&.to_html&.
|
|
131
|
+
r.doc.root&.to_html&.tr("\n", " ")
|
|
118
132
|
end
|
|
119
133
|
|
|
120
134
|
def liquid_docrefs(mnfs)
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
module Metanorma
|
|
2
2
|
class Collection
|
|
3
3
|
class Renderer
|
|
4
|
-
def docconv
|
|
4
|
+
def docconv(added_options = {})
|
|
5
5
|
@tempfile_cache ||= []
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
x.
|
|
6
|
+
flavor = Util::taste2flavor(@flavor).to_sym
|
|
7
|
+
opts = Util::taste2isodoc_attrs(@flavor, :doc)
|
|
8
|
+
x = Asciidoctor.load nil, backend: flavor
|
|
9
|
+
x.converter.doc_converter(DocOptionsNode.new(@directives, @dirname,
|
|
10
|
+
added_options.merge(opts)))
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def concat_extract_files(filename)
|
|
@@ -34,7 +36,8 @@ module Metanorma
|
|
|
34
36
|
|
|
35
37
|
def wrapping_doc_body(doc)
|
|
36
38
|
doc.xpath(ns("//annex | //preface | //bibliography")).each(&:remove)
|
|
37
|
-
s = doc.at(ns("//sections"))
|
|
39
|
+
s = doc.at(ns("//sections")) ||
|
|
40
|
+
doc.root.elements[-1].after("<sections/>").next
|
|
38
41
|
repl = <<~BODY
|
|
39
42
|
<sections><clause id='_collection_placeholder'><p>PLACEHOLDER</p></clause></sections>
|
|
40
43
|
BODY
|
|
@@ -50,8 +53,8 @@ module Metanorma
|
|
|
50
53
|
doc
|
|
51
54
|
end
|
|
52
55
|
|
|
53
|
-
SECTION_BREAK =
|
|
54
|
-
.freeze
|
|
56
|
+
SECTION_BREAK =
|
|
57
|
+
'<p class="MsoNormal"><br clear="all" class="section"/></p>'.freeze
|
|
55
58
|
DIV1 = '<div class="WordSection1"> </div>'.freeze
|
|
56
59
|
DIV2 = '<div class="WordSection2"> </div>'.freeze
|
|
57
60
|
|
|
@@ -69,10 +72,10 @@ module Metanorma
|
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
def collection_coverpages(conv, docs)
|
|
72
|
-
conv.wordintropage and [DIV2, SECTION_BREAK].
|
|
75
|
+
conv.wordintropage and [DIV2, SECTION_BREAK].reverse_each do |s|
|
|
73
76
|
docs.unshift(Nokogiri::XML(s).root)
|
|
74
77
|
end
|
|
75
|
-
conv.wordcoverpage and [DIV1, SECTION_BREAK].
|
|
78
|
+
conv.wordcoverpage and [DIV1, SECTION_BREAK].reverse_each do |s|
|
|
76
79
|
docs.unshift(Nokogiri::XML(s).root)
|
|
77
80
|
end
|
|
78
81
|
docs
|
|
@@ -111,7 +114,7 @@ module Metanorma
|
|
|
111
114
|
end
|
|
112
115
|
|
|
113
116
|
class DocOptionsNode
|
|
114
|
-
def initialize(directives, dir)
|
|
117
|
+
def initialize(directives, dir, options)
|
|
115
118
|
@dir = dir
|
|
116
119
|
@wordcoverpage =
|
|
117
120
|
Util::hash_key_detect(directives, "document-word-coverpage",
|
|
@@ -119,12 +122,14 @@ module Metanorma
|
|
|
119
122
|
@wordintropage =
|
|
120
123
|
Util::hash_key_detect(directives, "document-word-intropage",
|
|
121
124
|
@wordintropage)
|
|
125
|
+
@options = options
|
|
122
126
|
end
|
|
123
127
|
|
|
124
128
|
def attr(key)
|
|
125
129
|
case key
|
|
126
130
|
when "wordcoverpage" then Util::rel_path_resolve(@dir, @wordcoverpage)
|
|
127
131
|
when "wordintropage" then Util::rel_path_resolve(@dir, @wordintropage)
|
|
132
|
+
else @options[key.to_sym]
|
|
128
133
|
end
|
|
129
134
|
end
|
|
130
135
|
end
|