metanorma 1.6.2 → 1.6.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/lib/metanorma/collection.rb +15 -27
- data/lib/metanorma/collection_fileparse.rb +78 -125
- data/lib/metanorma/collection_fileprocess.rb +14 -190
- data/lib/metanorma/collection_manifest.rb +1 -3
- data/lib/metanorma/collection_render_utils.rb +111 -0
- data/lib/metanorma/collection_renderer.rb +17 -107
- data/lib/metanorma/compile.rb +15 -0
- data/lib/metanorma/compile_options.rb +16 -12
- data/lib/metanorma/document.rb +1 -1
- data/lib/metanorma/files_lookup.rb +20 -70
- data/lib/metanorma/files_lookup_sectionsplit.rb +69 -0
- data/lib/metanorma/input/asciidoc.rb +3 -2
- data/lib/metanorma/sectionsplit.rb +104 -158
- data/lib/metanorma/sectionsplit_links.rb +116 -0
- data/lib/metanorma/util.rb +31 -0
- data/lib/metanorma/version.rb +1 -1
- metadata +5 -2
@@ -7,172 +7,10 @@ require_relative "collection_fileparse"
|
|
7
7
|
module Metanorma
|
8
8
|
# XML collection renderer
|
9
9
|
class CollectionRenderer
|
10
|
-
=begin
|
11
|
-
# hash for each document in collection of document identifier to:
|
12
|
-
# document reference (fileref or id), type of document reference,
|
13
|
-
# and bibdata entry for that file
|
14
|
-
# @param path [String] path to collection
|
15
|
-
# @return [Hash{String=>Hash}]
|
16
|
-
def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
17
|
-
files = {}
|
18
|
-
@xml.xpath(ns("//docref")).each do |d|
|
19
|
-
orig_id = d.at(ns("./identifier"))
|
20
|
-
identifier = @c.decode(@isodoc
|
21
|
-
.docid_prefix(orig_id["type"], orig_id.children.to_xml))
|
22
|
-
files[identifier] = file_entry(d, orig_id.children.to_xml, path)
|
23
|
-
if files[identifier][:attachment]
|
24
|
-
files[identifier][:bibdata] = Metanorma::Document
|
25
|
-
.attachment_bibitem(identifier).root
|
26
|
-
else
|
27
|
-
file, _filename = targetfile(files[identifier], read: true)
|
28
|
-
xml = Nokogiri::XML(file)
|
29
|
-
add_document_suffix(identifier, xml)
|
30
|
-
files[identifier][:anchors] = read_anchors(xml)
|
31
|
-
files[identifier][:bibdata] = xml.at(ns("//bibdata"))
|
32
|
-
end
|
33
|
-
files[identifier][:bibitem] = files[identifier][:bibdata].dup
|
34
|
-
files[identifier][:bibitem].name = "bibitem"
|
35
|
-
files[identifier][:bibitem]["hidden"] = "true"
|
36
|
-
files[identifier][:bibitem]&.at("./*[local-name() = 'ext']")&.remove
|
37
|
-
end
|
38
|
-
add_section_split(files)
|
39
|
-
end
|
40
|
-
|
41
|
-
def add_section_split(files)
|
42
|
-
files.keys.each_with_object({}) do |k, m|
|
43
|
-
if files[k][:sectionsplit] == "true" && !files[k]["attachment"]
|
44
|
-
s, manifest = sectionsplit(files[k][:ref])
|
45
|
-
s.each_with_index do |f1, i|
|
46
|
-
add_section_split_instance(f1, m, k, i, files)
|
47
|
-
end
|
48
|
-
m["#{k}:index.html"] = add_section_split_cover(files, manifest, k)
|
49
|
-
end
|
50
|
-
m[k] = files[k]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_section_split_cover(files, manifest, ident)
|
55
|
-
cover = section_split_cover(manifest, dir_name_cleanse(ident))
|
56
|
-
files[ident][:out_path] = cover
|
57
|
-
{ attachment: true, index: false, out_path: cover,
|
58
|
-
ref: File.join(File.dirname(manifest.file), cover) }
|
59
|
-
end
|
60
|
-
|
61
|
-
def section_split_cover(col, ident)
|
62
|
-
dir = File.dirname(col.file)
|
63
|
-
@compile.collection_setup(nil, dir)
|
64
|
-
CollectionRenderer.new(col, dir,
|
65
|
-
output_folder: "#{ident}_collection",
|
66
|
-
format: %i(html),
|
67
|
-
coverpage: File.join(dir, "cover.html")).coverpage
|
68
|
-
FileUtils.mv "#{ident}_collection/index.html",
|
69
|
-
File.join(dir, "#{ident}_index.html")
|
70
|
-
FileUtils.rm_rf "#{ident}_collection"
|
71
|
-
"#{ident}_index.html"
|
72
|
-
end
|
73
|
-
|
74
|
-
def add_section_split_instance(file, manifest, key, idx, files)
|
75
|
-
presfile = File.join(File.dirname(files[key][:ref]),
|
76
|
-
File.basename(file[:url]))
|
77
|
-
manifest["#{key} #{file[:title]}"] =
|
78
|
-
{ parentid: key, presentationxml: true, type: "fileref",
|
79
|
-
rel_path: file[:url], out_path: File.basename(file[:url]),
|
80
|
-
anchors: read_anchors(Nokogiri::XML(File.read(presfile))),
|
81
|
-
bibdata: files[key][:bibdata], ref: presfile }
|
82
|
-
manifest["#{key} #{file[:title]}"][:bare] = true unless idx.zero?
|
83
|
-
end
|
84
|
-
|
85
|
-
def sectionsplit(file)
|
86
|
-
@compile.compile(
|
87
|
-
file, { format: :asciidoc, extension_keys: [:presentation] }
|
88
|
-
.merge(@compile_options)
|
89
|
-
)
|
90
|
-
r = file.sub(/\.xml$/, ".presentation.xml")
|
91
|
-
xml = Nokogiri::XML(File.read(r))
|
92
|
-
s = @compile.sectionsplit(xml, File.basename(r), File.dirname(r))
|
93
|
-
.sort_by { |f| f[:order] }
|
94
|
-
[s, @compile.collection_manifest(File.basename(r), s, xml, nil,
|
95
|
-
File.dirname(r))]
|
96
|
-
end
|
97
|
-
|
98
|
-
# rel_path is the source file address, determined relative to the YAML.
|
99
|
-
# out_path is the destination file address, with any references outside
|
100
|
-
# the working directory (../../...) truncated
|
101
|
-
# identifier is the id with only spaces, no nbsp
|
102
|
-
def file_entry(ref, identifier, _path)
|
103
|
-
out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
|
104
|
-
ret = if ref["fileref"]
|
105
|
-
{ type: "fileref", ref: @documents[identifier].file,
|
106
|
-
rel_path: ref["fileref"], out_path: out }
|
107
|
-
else { type: "id", ref: ref["id"] }
|
108
|
-
end
|
109
|
-
%i(attachment sectionsplit index).each do |s|
|
110
|
-
ret[s] = ref[s.to_s] if ref[s.to_s]
|
111
|
-
end
|
112
|
-
ret[:presentationxml] = ref["presentation-xml"]
|
113
|
-
ret[:bareafterfirst] = ref["bare-after-first"]
|
114
|
-
ret.compact
|
115
|
-
end
|
116
|
-
|
117
|
-
def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
|
118
|
-
doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
|
119
|
-
elem.attributes[attribute_name].value =
|
120
|
-
"#{elem.attributes[attribute_name].value}_#{suffix}"
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def add_document_suffix(identifier, doc)
|
125
|
-
document_suffix = Metanorma::Utils::to_ncname(identifier)
|
126
|
-
Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
|
127
|
-
add_suffix_to_attributes(doc, document_suffix, tag_name, attribute_name)
|
128
|
-
end
|
129
|
-
url_in_css_styles(doc, document_suffix)
|
130
|
-
end
|
131
|
-
|
132
|
-
# update relative URLs, url(#...), in CSS in @style attrs (including SVG)
|
133
|
-
def url_in_css_styles(doc, document_suffix)
|
134
|
-
doc.xpath("//*[@style]").each do |s|
|
135
|
-
s["style"] = s["style"]
|
136
|
-
.gsub(%r{url\(#([^)]+)\)}, "url(#\\1_#{document_suffix})")
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# return file contents + output filename for each file in the collection,
|
141
|
-
# given a docref entry
|
142
|
-
# @param data [Hash] docref entry
|
143
|
-
# @param read [Boolean] read the file in and return it
|
144
|
-
# @param doc [Boolean] I am a Metanorma document,
|
145
|
-
# so my URL should end with html or pdf or whatever
|
146
|
-
# @param relative [Boolean] Return output path,
|
147
|
-
# formed relative to YAML file, not input path, relative to calling function
|
148
|
-
# @return [Array<String, nil>]
|
149
|
-
def targetfile(data, options)
|
150
|
-
options = { read: false, doc: true, relative: false }.merge(options)
|
151
|
-
path = options[:relative] ? data[:rel_path] : data[:ref]
|
152
|
-
if data[:type] == "fileref"
|
153
|
-
ref_file path, data[:out_path], options[:read], options[:doc]
|
154
|
-
else
|
155
|
-
xml_file data[:id], options[:read]
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# @param ref [String]
|
160
|
-
# @param read [Boolean]
|
161
|
-
# @param doc [Boolean]
|
162
|
-
# @return [Array<String, nil>]
|
163
|
-
def ref_file(ref, out, read, doc)
|
164
|
-
file = File.read(ref, encoding: "utf-8") if read
|
165
|
-
filename = out.dup
|
166
|
-
filename.sub!(/\.xml$/, ".html") if doc
|
167
|
-
[file, filename]
|
168
|
-
end
|
169
|
-
=end
|
170
|
-
|
171
10
|
# compile and output individual file in collection
|
172
11
|
# warn "metanorma compile -x html #{f.path}"
|
173
12
|
def file_compile(file, filename, identifier)
|
174
|
-
|
175
|
-
return if @files.get(identifier,:sectionsplit) == "true"
|
13
|
+
return if @files.get(identifier, :sectionsplit) == "true"
|
176
14
|
|
177
15
|
opts = {
|
178
16
|
format: :asciidoc,
|
@@ -181,49 +19,38 @@ module Metanorma
|
|
181
19
|
}.merge(compile_options_update(identifier))
|
182
20
|
|
183
21
|
@compile.compile file, opts
|
184
|
-
|
185
|
-
@files.set(identifier,:outputs, {})
|
22
|
+
@files.set(identifier, :outputs, {})
|
186
23
|
file_compile_formats(filename, identifier)
|
187
24
|
end
|
188
25
|
|
189
26
|
def compile_options_update(identifier)
|
190
27
|
ret = @compile_options.dup
|
191
28
|
Array(@directives).include?("presentation-xml") ||
|
192
|
-
|
193
|
-
@files.get(identifier,:presentationxml) and
|
29
|
+
@files.get(identifier, :presentationxml) and
|
194
30
|
ret.merge!(passthrough_presentation_xml: true)
|
195
|
-
|
196
|
-
@files.get(identifier,:sectionsplit) == "true" and
|
31
|
+
@files.get(identifier, :sectionsplit) == "true" and
|
197
32
|
ret.merge!(sectionsplit: "true")
|
198
|
-
|
199
|
-
@files.get(identifier,:bare) == true and
|
33
|
+
@files.get(identifier, :bare) == true and
|
200
34
|
ret.merge!(bare: true)
|
201
35
|
ret
|
202
36
|
end
|
203
37
|
|
204
38
|
def file_compile_formats(filename, identifier)
|
205
|
-
#file_id = @files[identifier]
|
206
39
|
f = @files.get(identifier, :outputs)
|
207
40
|
@format << :presentation if @format.include?(:pdf)
|
208
41
|
@format.each do |e|
|
209
42
|
ext = @compile.processor.output_formats[e]
|
210
43
|
fn = File.basename(filename).sub(/(?<=\.)[^.]+$/, ext.to_s)
|
211
|
-
|
212
|
-
unless /html$/.match?(ext) && @files.get(identifier, :sectionsplit)
|
213
|
-
#file_id[:outputs][e] = File.join(@outdir, fn)
|
44
|
+
(/html$/.match?(ext) && @files.get(identifier, :sectionsplit)) or
|
214
45
|
f[e] = File.join(@outdir, fn)
|
215
|
-
end
|
216
46
|
end
|
217
|
-
@files.set(identifier
|
47
|
+
@files.set(identifier, :outputs, f)
|
218
48
|
end
|
219
49
|
|
220
|
-
#def copy_file_to_dest(fileref)
|
221
50
|
def copy_file_to_dest(identifier)
|
222
|
-
dest = File.join(@outdir, @files.get(identifier
|
51
|
+
dest = File.join(@outdir, @files.get(identifier, :out_path))
|
223
52
|
FileUtils.mkdir_p(File.dirname(dest))
|
224
|
-
|
225
|
-
#require "debug"; binding.b
|
226
|
-
FileUtils.cp @files.get(identifier,:ref), dest
|
53
|
+
FileUtils.cp @files.get(identifier, :ref), dest
|
227
54
|
end
|
228
55
|
|
229
56
|
# process each file in the collection
|
@@ -231,22 +58,19 @@ module Metanorma
|
|
231
58
|
def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
232
59
|
warn "\n\n\n\n\nInternal Refs: #{DateTime.now.strftime('%H:%M:%S')}"
|
233
60
|
internal_refs = locate_internal_refs
|
234
|
-
|
235
|
-
@files.keys.each_with_index do |identifier, i|
|
61
|
+
@files.keys.each_with_index do |ident, i|
|
236
62
|
i.positive? && Array(@directives).include?("bare-after-first") and
|
237
63
|
@compile_options.merge!(bare: true)
|
238
|
-
|
239
|
-
if @files.get(identifier,:attachment) then copy_file_to_dest(identifier)
|
64
|
+
if @files.get(ident, :attachment) then copy_file_to_dest(ident)
|
240
65
|
else
|
241
|
-
|
242
|
-
file, filename = @files.targetfile_id(identifier, read: true)
|
66
|
+
file, filename = @files.targetfile_id(ident, read: true)
|
243
67
|
warn "\n\n\n\n\nProcess #{filename}: #{DateTime.now.strftime('%H:%M:%S')}"
|
244
|
-
collection_xml = update_xrefs(file,
|
68
|
+
collection_xml = update_xrefs(file, ident, internal_refs)
|
245
69
|
collection_filename = File.basename(filename, File.extname(filename))
|
246
70
|
collection_xml_path = File.join(Dir.tmpdir,
|
247
71
|
"#{collection_filename}.xml")
|
248
72
|
File.write collection_xml_path, collection_xml, encoding: "UTF-8"
|
249
|
-
file_compile(collection_xml_path, filename,
|
73
|
+
file_compile(collection_xml_path, filename, ident)
|
250
74
|
FileUtils.rm(collection_xml_path)
|
251
75
|
end
|
252
76
|
end
|
@@ -108,9 +108,7 @@ module Metanorma
|
|
108
108
|
@disambig = Util::DisambigFiles.new
|
109
109
|
@docref.each do |dr|
|
110
110
|
drf = builder.docref do |b|
|
111
|
-
b.identifier
|
112
|
-
i << dr["identifier"]
|
113
|
-
end
|
111
|
+
b.identifier { |i| i << dr["identifier"] }
|
114
112
|
!dr["attachment"] && !dr["sectionsplit"] &&
|
115
113
|
d = @collection.bibdatas[dr["identifier"]] and
|
116
114
|
b.parent.add_child(d.bibitem.to_xml(bibdata: true))
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Metanorma
|
2
|
+
class CollectionRenderer
|
3
|
+
def dir_name_cleanse(name)
|
4
|
+
path = Pathname.new(name)
|
5
|
+
clean_regex = /[<>:"|?*]/
|
6
|
+
fallback_sym = "_"
|
7
|
+
return name.gsub(clean_regex, fallback_sym) unless path.absolute?
|
8
|
+
|
9
|
+
File.join(path.dirname,
|
10
|
+
path.basename.to_s.gsub(clean_regex, fallback_sym))
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def create_non_existing_directory(output_directory)
|
16
|
+
!File.exist?(output_directory) and
|
17
|
+
FileUtils.mkdir_p(output_directory)
|
18
|
+
end
|
19
|
+
|
20
|
+
def format_sort(formats)
|
21
|
+
ret = []
|
22
|
+
formats.include?(:xml) and ret << :xml
|
23
|
+
formats.include?(:presentation) and ret << :presentation
|
24
|
+
a = %i(presentation xml)
|
25
|
+
ret + formats.reject { |i| a.include? i }
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param options [Hash]
|
29
|
+
# @raise [ArgumentError]
|
30
|
+
def check_options(options)
|
31
|
+
(options[:format].is_a?(Array) && (FORMATS & options[:format]).any?) or
|
32
|
+
raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
|
33
|
+
end
|
34
|
+
|
35
|
+
def pdfconv
|
36
|
+
doctype = @doctype.to_sym
|
37
|
+
x = Asciidoctor.load nil, backend: doctype
|
38
|
+
x.converter.pdf_converter(PdfOptionsNode.new(doctype,
|
39
|
+
@compile_options))
|
40
|
+
end
|
41
|
+
|
42
|
+
def fail_update_bibitem(docid, identifier)
|
43
|
+
error = "[metanorma] Cannot find crossreference to document #{docid} " \
|
44
|
+
"in document #{identifier}."
|
45
|
+
@log&.add("Cross-References", nil, error)
|
46
|
+
Util.log(error, :warning)
|
47
|
+
end
|
48
|
+
|
49
|
+
def datauri_encode(docxml)
|
50
|
+
docxml.xpath(ns("//image")).each do |i|
|
51
|
+
i["src"] = Metanorma::Utils::datauri(i["src"])
|
52
|
+
end
|
53
|
+
docxml
|
54
|
+
end
|
55
|
+
|
56
|
+
class PdfOptionsNode
|
57
|
+
def initialize(doctype, options)
|
58
|
+
docproc = Metanorma::Registry.instance.find_processor(doctype)
|
59
|
+
if FontistUtils.has_fonts_manifest?(docproc, options)
|
60
|
+
@fonts_manifest = FontistUtils.location_manifest(docproc)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def attr(key)
|
65
|
+
if key == "fonts-manifest" && @fonts_manifest
|
66
|
+
@fonts_manifest
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Dummy
|
72
|
+
def attr(_key); end
|
73
|
+
end
|
74
|
+
|
75
|
+
def isodoc_create
|
76
|
+
x = Asciidoctor.load nil, backend: @doctype.to_sym
|
77
|
+
isodoc = x.converter.html_converter(Dummy.new) # to obtain Isodoc class
|
78
|
+
isodoc.i18n_init(@lang, @script, @locale) # read in internationalisation
|
79
|
+
isodoc.metadata_init(@lang, @script, @locale, isodoc.i18n)
|
80
|
+
isodoc.info(@xml, nil)
|
81
|
+
isodoc
|
82
|
+
end
|
83
|
+
|
84
|
+
def isodoc_populate
|
85
|
+
# create the @meta class of isodoc, for populating Liquid,
|
86
|
+
# with "navigation" set to the index bar.
|
87
|
+
# extracted from the manifest
|
88
|
+
@isodoc.meta.set(:navigation, indexfile(@xml.at(ns("//manifest"))))
|
89
|
+
@isodoc.meta.set(:docrefs, liquid_docrefs)
|
90
|
+
@isodoc.meta.set(:"prefatory-content",
|
91
|
+
isodoc_builder(@isodoc,
|
92
|
+
@xml.at(ns("//prefatory-content"))))
|
93
|
+
@isodoc.meta.set(:"final-content",
|
94
|
+
isodoc_builder(isodoc,
|
95
|
+
@xml.at(ns("//final-content"))))
|
96
|
+
@isodoc.info(@xml, nil)
|
97
|
+
end
|
98
|
+
|
99
|
+
def isodoc_builder(isodoc, node)
|
100
|
+
Nokogiri::HTML::Builder.new(encoding: "UTF-8") do |b|
|
101
|
+
b.div do |div|
|
102
|
+
node&.children&.each { |n| isodoc.parse(n, div) }
|
103
|
+
end
|
104
|
+
end.doc.root.to_html
|
105
|
+
end
|
106
|
+
|
107
|
+
def ns(xpath)
|
108
|
+
@isodoc.ns(xpath)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "isodoc"
|
4
2
|
require "htmlentities"
|
5
3
|
require_relative "collection_fileprocess"
|
6
4
|
require_relative "fontist_utils"
|
7
5
|
require_relative "util"
|
8
6
|
require_relative "files_lookup"
|
7
|
+
require_relative "collection_render_utils"
|
9
8
|
|
10
9
|
module Metanorma
|
11
10
|
# XML collection renderer
|
@@ -30,9 +29,9 @@ module Metanorma
|
|
30
29
|
def initialize(collection, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
31
30
|
check_options options
|
32
31
|
@xml = Nokogiri::XML collection.to_xml # @xml is the collection manifest
|
33
|
-
@lang = @xml.at(
|
34
|
-
@script = @xml.at(
|
35
|
-
@locale = @xml.at(
|
32
|
+
@lang = @xml.at("//xmlns:bibdata/xmlns:language")&.text || "en"
|
33
|
+
@script = @xml.at("//xmlns:bibdata/xmlns:script")&.text || "Latn"
|
34
|
+
@locale = @xml.at("//xmlns:bibdata/xmlns:locale")&.text
|
36
35
|
@doctype = doctype
|
37
36
|
require "metanorma-#{@doctype}"
|
38
37
|
|
@@ -49,22 +48,19 @@ module Metanorma
|
|
49
48
|
@disambig = Util::DisambigFiles.new
|
50
49
|
@compile = Compile.new
|
51
50
|
@c = HTMLEntities.new
|
51
|
+
@files_to_delete = []
|
52
52
|
|
53
53
|
# list of files in the collection
|
54
|
-
#@files = read_files folder
|
55
54
|
@files = Metanorma::FileLookup.new(folder, self)
|
55
|
+
@files.add_section_split
|
56
56
|
isodoc_populate
|
57
57
|
create_non_existing_directory(@outdir)
|
58
58
|
end
|
59
59
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
return name.gsub(clean_regex, fallback_sym) unless path.absolute?
|
65
|
-
|
66
|
-
File.join(path.dirname,
|
67
|
-
path.basename.to_s.gsub(clean_regex, fallback_sym))
|
60
|
+
def flush_files
|
61
|
+
warn @files.files_to_delete
|
62
|
+
@files.files_to_delete.each { |f| FileUtils.rm_f(f) }
|
63
|
+
@files_to_delete.each { |f| FileUtils.rm_f(f) }
|
68
64
|
end
|
69
65
|
|
70
66
|
# @param col [Metanorma::Collection] XML collection
|
@@ -83,14 +79,14 @@ module Metanorma
|
|
83
79
|
warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}"
|
84
80
|
cr.coverpage if options[:format]&.include?(:html)
|
85
81
|
warn "\n\n\n\n\nDone: #{DateTime.now.strftime('%H:%M:%S')}"
|
82
|
+
cr.flush_files
|
86
83
|
cr
|
87
84
|
end
|
88
85
|
|
89
86
|
def concatenate(col, options)
|
90
87
|
options[:format] << :presentation if options[:format].include?(:pdf)
|
91
88
|
options[:format].uniq.each do |e|
|
92
|
-
|
93
|
-
|
89
|
+
%i(presentation xml).include?(e) or next
|
94
90
|
ext = e == :presentation ? "presentation.xml" : e.to_s
|
95
91
|
File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") do |f|
|
96
92
|
f.write(concatenate1(col.clone, e).to_xml)
|
@@ -103,79 +99,20 @@ module Metanorma
|
|
103
99
|
def concatenate1(out, ext)
|
104
100
|
out.directives << "documents-inline"
|
105
101
|
out.bibdatas.each_key do |ident|
|
106
|
-
#id = @c.decode(@isodoc.docid_prefix(nil, ident.dup))
|
107
|
-
#@files[id][:attachment] || @files[id][:outputs].nil? and next
|
108
102
|
id = @isodoc.docid_prefix(nil, ident.dup)
|
109
|
-
@files.get(id
|
103
|
+
@files.get(id, :attachment) || @files.get(id, :outputs).nil? and next
|
110
104
|
|
111
105
|
out.documents[id] =
|
112
|
-
|
113
|
-
Metanorma::Document.raw_file(@files.get(id,:outputs)[ext])
|
106
|
+
Metanorma::Document.raw_file(@files.get(id, :outputs)[ext])
|
114
107
|
end
|
115
108
|
out
|
116
109
|
end
|
117
110
|
|
118
|
-
def pdfconv
|
119
|
-
doctype = @doctype.to_sym
|
120
|
-
x = Asciidoctor.load nil, backend: doctype
|
121
|
-
x.converter.pdf_converter(PdfOptionsNode.new(doctype, @compile_options))
|
122
|
-
end
|
123
|
-
|
124
|
-
class PdfOptionsNode
|
125
|
-
def initialize(doctype, options)
|
126
|
-
docproc = Metanorma::Registry.instance.find_processor(doctype)
|
127
|
-
if FontistUtils.has_fonts_manifest?(docproc, options)
|
128
|
-
@fonts_manifest = FontistUtils.location_manifest(docproc)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def attr(key)
|
133
|
-
if key == "fonts-manifest" && @fonts_manifest
|
134
|
-
@fonts_manifest
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class Dummy
|
140
|
-
def attr(_key); end
|
141
|
-
end
|
142
|
-
|
143
|
-
def isodoc_create
|
144
|
-
x = Asciidoctor.load nil, backend: @doctype.to_sym
|
145
|
-
isodoc = x.converter.html_converter(Dummy.new) # to obtain Isodoc class
|
146
|
-
isodoc.i18n_init(@lang, @script, @locale) # read in internationalisation
|
147
|
-
isodoc.metadata_init(@lang, @script, @locale, isodoc.i18n)
|
148
|
-
isodoc.info(@xml, nil)
|
149
|
-
isodoc
|
150
|
-
end
|
151
|
-
|
152
|
-
def isodoc_populate
|
153
|
-
# create the @meta class of isodoc, for populating Liquid,
|
154
|
-
# with "navigation" set to the index bar.
|
155
|
-
# extracted from the manifest
|
156
|
-
@isodoc.meta.set(:navigation, indexfile(@xml.at(ns("//manifest"))))
|
157
|
-
@isodoc.meta.set(:docrefs, liquid_docrefs)
|
158
|
-
@isodoc.meta.set(:"prefatory-content",
|
159
|
-
isodoc_builder(@isodoc,
|
160
|
-
@xml.at(ns("//prefatory-content"))))
|
161
|
-
@isodoc.meta.set(:"final-content",
|
162
|
-
isodoc_builder(isodoc, @xml.at(ns("//final-content"))))
|
163
|
-
@isodoc.info(@xml, nil)
|
164
|
-
end
|
165
|
-
|
166
|
-
def isodoc_builder(isodoc, node)
|
167
|
-
Nokogiri::HTML::Builder.new(encoding: "UTF-8") do |b|
|
168
|
-
b.div do |div|
|
169
|
-
node&.children&.each { |n| isodoc.parse(n, div) }
|
170
|
-
end
|
171
|
-
end.doc.root.to_html
|
172
|
-
end
|
173
|
-
|
174
111
|
# infer the flavour from the first document identifier; relaton does that
|
175
112
|
def doctype
|
176
|
-
if (docid = @xml.at(
|
113
|
+
if (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier/@type")&.text)
|
177
114
|
dt = docid.downcase
|
178
|
-
elsif (docid = @xml.at(
|
115
|
+
elsif (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier")&.text)
|
179
116
|
dt = docid.sub(/\s.*$/, "").lowercase
|
180
117
|
else return "standoc"
|
181
118
|
end
|
@@ -183,10 +120,6 @@ module Metanorma
|
|
183
120
|
@registry.alias(dt.to_sym)&.to_s || dt
|
184
121
|
end
|
185
122
|
|
186
|
-
def ns(xpath)
|
187
|
-
IsoDoc::Convert.new({}).ns(xpath)
|
188
|
-
end
|
189
|
-
|
190
123
|
# populate liquid template of ARGV[1] with metadata extracted from
|
191
124
|
# collection manifest
|
192
125
|
def coverpage
|
@@ -233,8 +166,7 @@ module Metanorma
|
|
233
166
|
|
234
167
|
def index_link(docref, ident)
|
235
168
|
if docref["fileref"]
|
236
|
-
|
237
|
-
@files.get(ident,:out_path).sub(/\.xml$/, ".html")
|
169
|
+
@files.get(ident, :out_path).sub(/\.xml$/, ".html")
|
238
170
|
else "#{docref['id']}.html"
|
239
171
|
end
|
240
172
|
end
|
@@ -270,27 +202,5 @@ module Metanorma
|
|
270
202
|
"level" => d.at(ns("./level"))&.text }
|
271
203
|
end
|
272
204
|
end
|
273
|
-
|
274
|
-
private
|
275
|
-
|
276
|
-
def create_non_existing_directory(output_directory)
|
277
|
-
!File.exist?(output_directory) and
|
278
|
-
FileUtils.mkdir_p(output_directory)
|
279
|
-
end
|
280
|
-
|
281
|
-
def format_sort(formats)
|
282
|
-
ret = []
|
283
|
-
formats.include?(:xml) and ret << :xml
|
284
|
-
formats.include?(:presentation) and ret << :presentation
|
285
|
-
a = %i(presentation xml)
|
286
|
-
ret + formats.reject { |i| a.include? i }
|
287
|
-
end
|
288
|
-
|
289
|
-
# @param options [Hash]
|
290
|
-
# @raise [ArgumentError]
|
291
|
-
def check_options(options)
|
292
|
-
(options[:format].is_a?(Array) && (FORMATS & options[:format]).any?) or
|
293
|
-
raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
|
294
|
-
end
|
295
205
|
end
|
296
206
|
end
|
data/lib/metanorma/compile.rb
CHANGED
@@ -176,6 +176,21 @@ module Metanorma
|
|
176
176
|
ext != :presentation
|
177
177
|
end
|
178
178
|
|
179
|
+
# assume we pass in Presentation XML, but we want to recover Semantic XML
|
180
|
+
def sectionsplit_convert(input_filename, file, output_filename = nil,
|
181
|
+
opts = {})
|
182
|
+
@isodoc ||= IsoDoc::PresentationXMLConvert.new({})
|
183
|
+
input_filename += ".xml" unless input_filename.match?(/\.xml$/)
|
184
|
+
File.exist?(input_filename) or
|
185
|
+
File.open(input_filename, "w:UTF-8") { |f| f.write(file) }
|
186
|
+
presxml = File.read(input_filename, encoding: "utf-8")
|
187
|
+
_xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
|
188
|
+
Sectionsplit.new(input: input_filename, isodoc: @isodoc, xml: presxml,
|
189
|
+
base: File.basename(output_filename || filename),
|
190
|
+
output: output_filename || filename,
|
191
|
+
dir: dir, compile_opts: opts).build_collection
|
192
|
+
end
|
193
|
+
|
179
194
|
private
|
180
195
|
|
181
196
|
def isodoc_error_process(err, strict, must_abort)
|
@@ -7,7 +7,7 @@ module Metanorma
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def xml_options_extract(file)
|
10
|
-
xml = Nokogiri::XML(file
|
10
|
+
xml = Nokogiri::XML(file, &:huge)
|
11
11
|
if xml.root
|
12
12
|
@registry.root_tags.each do |k, v|
|
13
13
|
return { type: k } if v == xml.root.name
|
@@ -36,29 +36,33 @@ module Metanorma
|
|
36
36
|
def get_extensions(options)
|
37
37
|
options[:extension_keys] ||=
|
38
38
|
@processor.output_formats.reduce([]) { |memo, (k, _)| memo << k }
|
39
|
-
extensions = options
|
39
|
+
extensions = extract_extensions(options)
|
40
|
+
if !extensions.include?(:presentation) && extensions.any? do |e|
|
41
|
+
@processor.use_presentation_xml(e)
|
42
|
+
end
|
43
|
+
extensions << :presentation
|
44
|
+
end
|
45
|
+
extensions
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_extensions(options)
|
49
|
+
options[:extension_keys].reduce([]) do |memo, e|
|
40
50
|
if @processor.output_formats[e] then memo << e
|
41
51
|
else
|
42
|
-
message = "[metanorma] Error: #{e} format is not supported
|
52
|
+
message = "[metanorma] Error: #{e} format is not supported " \
|
53
|
+
"for this standard."
|
43
54
|
@errors << message
|
44
55
|
Util.log(message, :error)
|
45
56
|
memo
|
46
57
|
end
|
47
58
|
end
|
48
|
-
if !extensions.include?(:presentation) && extensions.any? do |e|
|
49
|
-
@processor.use_presentation_xml(e)
|
50
|
-
end
|
51
|
-
extensions << :presentation
|
52
|
-
end
|
53
|
-
extensions
|
54
59
|
end
|
55
60
|
|
56
61
|
def font_install(opt)
|
57
62
|
FontistUtils.install_fonts(@processor, opt) unless @fontist_installed
|
58
63
|
@fontist_installed = true
|
59
|
-
|
60
|
-
opt[:fontlicenseagreement] == "continue-without-fonts"
|
61
|
-
|
64
|
+
!opt[:fonts] ||
|
65
|
+
opt[:fontlicenseagreement] == "continue-without-fonts" and return
|
62
66
|
@font_overrides ||= []
|
63
67
|
font_install_override(opt)
|
64
68
|
end
|
data/lib/metanorma/document.rb
CHANGED
@@ -87,7 +87,7 @@ module Metanorma
|
|
87
87
|
else
|
88
88
|
case format(file)
|
89
89
|
when :xml
|
90
|
-
from_xml Nokogiri::XML(File.read(file, encoding: "UTF-8"))
|
90
|
+
from_xml (Nokogiri::XML(File.read(file, encoding: "UTF-8")) { |x| x.huge })
|
91
91
|
when :yaml
|
92
92
|
yaml = File.read(file, encoding: "UTF-8")
|
93
93
|
Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
|