metanorma 2.1.4 → 2.5.4
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/.rubocop.yml +23 -2
- data/Gemfile +14 -0
- data/README.adoc +1 -1
- data/lib/metanorma/collection/artifact_store.rb +142 -0
- data/lib/metanorma/collection/collection.rb +140 -131
- data/lib/metanorma/collection/config/bibdata.rb +1 -1
- data/lib/metanorma/collection/config/config.rb +50 -20
- data/lib/metanorma/collection/config/converters.rb +89 -31
- data/lib/metanorma/collection/config/doc_container.rb +28 -0
- data/lib/metanorma/collection/config/manifest.rb +30 -6
- data/lib/metanorma/collection/config/namespaces.rb +12 -0
- data/lib/metanorma/collection/document/document.rb +54 -15
- data/lib/metanorma/collection/filelookup/filelookup.rb +170 -74
- data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +62 -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 +27 -14
- data/lib/metanorma/collection/multilingual/multilingual.rb +1 -1
- data/lib/metanorma/collection/renderer/filelocation.rb +166 -0
- data/lib/metanorma/collection/renderer/fileparse.rb +60 -55
- data/lib/metanorma/collection/renderer/fileprocess.rb +184 -40
- data/lib/metanorma/collection/renderer/navigation.rb +20 -6
- data/lib/metanorma/collection/renderer/render_word.rb +8 -4
- data/lib/metanorma/collection/renderer/renderer.rb +202 -19
- data/lib/metanorma/collection/renderer/svg.rb +60 -5
- data/lib/metanorma/collection/renderer/utils.rb +76 -42
- data/lib/metanorma/collection/sectionsplit/collection.rb +14 -4
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +141 -61
- data/lib/metanorma/collection/util/disambig_files.rb +4 -5
- data/lib/metanorma/collection/util/util.rb +147 -23
- data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +7 -7
- data/lib/metanorma/compile/assets/icc-boilerplate.adoc +41 -0
- data/lib/metanorma/compile/compile.rb +180 -165
- data/lib/metanorma/compile/compile_options.rb +155 -83
- data/lib/metanorma/compile/extract.rb +76 -56
- data/lib/metanorma/compile/flavor.rb +19 -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 +196 -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 +11 -20
- data/plans/collection-rendering-architecture-review.md +516 -0
- metadata +42 -122
- 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 -88
- 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/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,16 +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
|
-
|
|
19
|
-
}.merge(compile_options_update(identifier))
|
|
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
|
|
20
22
|
@compile.compile file, opts
|
|
21
23
|
@files.set(identifier, :outputs, {})
|
|
22
|
-
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
|
+
}
|
|
23
88
|
end
|
|
24
89
|
|
|
25
90
|
def compile_options_update(identifier)
|
|
@@ -34,28 +99,14 @@ module Metanorma
|
|
|
34
99
|
ret
|
|
35
100
|
end
|
|
36
101
|
|
|
37
|
-
def
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
f[e] = File.join(@outdir, fn)
|
|
46
|
-
end
|
|
47
|
-
@files.set(identifier, :outputs, f)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def copy_file_to_dest(identifier)
|
|
51
|
-
out = Pathname.new(@files.get(identifier, :out_path)).cleanpath
|
|
52
|
-
out.absolute? and
|
|
53
|
-
out = out.relative_path_from(File.expand_path(FileUtils.pwd))
|
|
54
|
-
dest = File.join(@outdir, @disambig.source2dest_filename(out.to_s))
|
|
55
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
56
|
-
source = @files.get(identifier, :ref)
|
|
57
|
-
source != dest and FileUtils.cp_r source, dest, remove_destination: true
|
|
58
|
-
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
|
|
59
110
|
|
|
60
111
|
# process each file in the collection
|
|
61
112
|
# files are held in memory, and altered as postprocessing
|
|
@@ -70,18 +121,50 @@ module Metanorma
|
|
|
70
121
|
if @files.get(ident, :attachment) then copy_file_to_dest(ident)
|
|
71
122
|
else
|
|
72
123
|
file, fname = @files.targetfile_id(ident, read: true)
|
|
124
|
+
@preserve_unresolved && member_stored?(ident, file) and next
|
|
73
125
|
warn "\n\n\n\n\nProcess #{fname}: #{DateTime.now.strftime('%H:%M:%S')}"
|
|
74
126
|
collection_xml = update_xrefs(file, ident, internal_refs)
|
|
75
|
-
|
|
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)$/, "")
|
|
76
134
|
collection_xml_path = File.join(Dir.tmpdir,
|
|
77
135
|
"#{collection_filename}.xml")
|
|
78
136
|
File.write collection_xml_path, collection_xml, encoding: "UTF-8"
|
|
79
137
|
file_compile(collection_xml_path, fname, ident)
|
|
80
|
-
FileUtils.
|
|
138
|
+
FileUtils.rm_f(collection_xml_path)
|
|
81
139
|
end
|
|
82
140
|
end
|
|
83
141
|
end
|
|
84
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
|
+
|
|
85
168
|
# gather internal bibitem references
|
|
86
169
|
def gather_internal_refs
|
|
87
170
|
@files.keys.each_with_object({}) do |i, refs|
|
|
@@ -135,7 +218,7 @@ module Metanorma
|
|
|
135
218
|
ids.each do |id, key|
|
|
136
219
|
key and next
|
|
137
220
|
refs[schema][id] = "Missing:#{schema}:#{id}"
|
|
138
|
-
@log&.add("
|
|
221
|
+
@log&.add("METANORMA_1", nil, params: [refs[schema][id]])
|
|
139
222
|
end
|
|
140
223
|
end
|
|
141
224
|
refs
|
|
@@ -155,23 +238,84 @@ module Metanorma
|
|
|
155
238
|
def locate_internal_refs1_prep(file)
|
|
156
239
|
xml = Nokogiri::XML(file, &:huge)
|
|
157
240
|
r = xml.root["document_suffix"]
|
|
158
|
-
xml.xpath("//*[@id]").each_with_object({}) do |i, x|
|
|
159
|
-
/^semantic_/.match?(i.name) and next
|
|
241
|
+
ret = xml.xpath("//*[@id]").each_with_object({}) do |i, x|
|
|
160
242
|
x[i["id"]] = i
|
|
161
243
|
r and x[i["id"].sub(/_#{r}$/, "")] = i
|
|
162
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
|
|
163
250
|
end
|
|
164
251
|
|
|
165
252
|
def update_bibitem(bib, identifier)
|
|
166
|
-
|
|
167
|
-
newbib
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
|
171
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>"
|
|
172
265
|
dest.previous = "<uri type='citation'>#{url}</uri>"
|
|
173
266
|
bib.replace(newbib)
|
|
174
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
|
|
175
319
|
end
|
|
176
320
|
end
|
|
177
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)
|
|
@@ -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
|
-
flavor = @flavor.to_sym
|
|
6
|
+
flavor = Util::taste2flavor(@flavor).to_sym
|
|
7
|
+
opts = Util::taste2isodoc_attrs(@flavor, :doc)
|
|
7
8
|
x = Asciidoctor.load nil, backend: flavor
|
|
8
|
-
x.converter.doc_converter(DocOptionsNode.new(@directives, @dirname
|
|
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)
|
|
@@ -112,7 +114,7 @@ module Metanorma
|
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
class DocOptionsNode
|
|
115
|
-
def initialize(directives, dir)
|
|
117
|
+
def initialize(directives, dir, options)
|
|
116
118
|
@dir = dir
|
|
117
119
|
@wordcoverpage =
|
|
118
120
|
Util::hash_key_detect(directives, "document-word-coverpage",
|
|
@@ -120,12 +122,14 @@ module Metanorma
|
|
|
120
122
|
@wordintropage =
|
|
121
123
|
Util::hash_key_detect(directives, "document-word-intropage",
|
|
122
124
|
@wordintropage)
|
|
125
|
+
@options = options
|
|
123
126
|
end
|
|
124
127
|
|
|
125
128
|
def attr(key)
|
|
126
129
|
case key
|
|
127
130
|
when "wordcoverpage" then Util::rel_path_resolve(@dir, @wordcoverpage)
|
|
128
131
|
when "wordintropage" then Util::rel_path_resolve(@dir, @wordintropage)
|
|
132
|
+
else @options[key.to_sym]
|
|
129
133
|
end
|
|
130
134
|
end
|
|
131
135
|
end
|