metanorma 1.6.2 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/metanorma/collection.rb +15 -27
- data/lib/metanorma/collection_fileparse.rb +80 -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 +51 -44
- data/lib/metanorma/input/asciidoc.rb +3 -2
- data/lib/metanorma/sectionsplit.rb +101 -156
- data/lib/metanorma/sectionsplit_links.rb +116 -0
- data/lib/metanorma/util.rb +31 -0
- data/lib/metanorma/version.rb +1 -1
- metadata +4 -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)
|