metanorma 1.4.0 → 1.4.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/Gemfile +1 -0
- data/README.adoc +7 -0
- data/lib/metanorma/collection.rb +3 -6
- data/lib/metanorma/collection_fileparse.rb +28 -14
- data/lib/metanorma/collection_fileprocess.rb +25 -32
- data/lib/metanorma/collection_renderer.rb +1 -2
- data/lib/metanorma/compile.rb +73 -97
- data/lib/metanorma/extract.rb +72 -0
- data/lib/metanorma/input/asciidoc.rb +13 -7
- data/lib/metanorma/registry.rb +9 -11
- data/lib/metanorma/version.rb +1 -1
- data/lib/metanorma/worker_pool.rb +29 -0
- data/metanorma.gemspec +4 -3
- metadata +31 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8457479b196c4d3db250ce33f650cd822f1ac8f1a510d1b6ac9653038446e1e
|
|
4
|
+
data.tar.gz: f1219e134ab2113cd3e25c5bca39fe3194a3a038f9b6500f0d5e35d66f168d0d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e62d329f40ca168b5f2250ae86e676b89650c754233a4d249eea45bdf7652863ce5824a128bbff0c6225435a97be4bb8b420ce9cfca44587be9d1d852c33599
|
|
7
|
+
data.tar.gz: 1b18636330ca30bba9f2a0080e1728c6d05763349ffafebab78e1b61043f3b45c5160156dfdbf541d886fc14e195ee54808cbfbc4dd8d296e7bb56ee5edca735
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
|
@@ -247,6 +247,13 @@ The options hash has the same structure it does when invoked in metanorma-cli:
|
|
|
247
247
|
`:relaton`: exports the bibdata Relaton XML description of the document (which is part of its Metanorma XML)
|
|
248
248
|
to the nominated directory
|
|
249
249
|
|
|
250
|
+
== Threaded execution
|
|
251
|
+
|
|
252
|
+
Metanorma has threaded execution, to generate output documents from the same Presentation XML input more quickly.
|
|
253
|
+
Similar to https://github.com/relaton/relaton[relaton], the `METANORMA_PARALLEL` environment variable
|
|
254
|
+
can be used to override the default number of parallel fetches used.
|
|
255
|
+
|
|
256
|
+
|
|
250
257
|
== Origin of name
|
|
251
258
|
|
|
252
259
|
*Meta-* is a prefix of Greek origin ("μετα") for "`with`" "`after`".
|
data/lib/metanorma/collection.rb
CHANGED
|
@@ -91,12 +91,9 @@ module Metanorma
|
|
|
91
91
|
private
|
|
92
92
|
|
|
93
93
|
def parse_xml(file)
|
|
94
|
-
xml = Nokogiri::XML File.read(file, encoding: "UTF-8")
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (b = xml.at("/xmlns:metanorma-collection/xmlns:bibdata"))
|
|
98
|
-
bd = Relaton::Cli.parse_xml b
|
|
99
|
-
end
|
|
94
|
+
xml = Nokogiri::XML File.read(file, encoding: "UTF-8") { |c| c.huge }
|
|
95
|
+
(b = xml.at("/xmlns:metanorma-collection/xmlns:bibdata")) and
|
|
96
|
+
bd = Relaton::Cli.parse_xml(b)
|
|
100
97
|
mnf_xml = xml.at("/xmlns:metanorma-collection/xmlns:manifest")
|
|
101
98
|
mnf = CollectionManifest.from_xml mnf_xml
|
|
102
99
|
pref = pref_final_content xml.at("//xmlns:prefatory-content")
|
|
@@ -83,11 +83,15 @@ module Metanorma
|
|
|
83
83
|
add_document_suffix(identifier, docxml)
|
|
84
84
|
update_direct_refs_to_docs(docxml, identifier)
|
|
85
85
|
svgmap_resolve(datauri_encode(docxml))
|
|
86
|
+
hide_refs(docxml)
|
|
87
|
+
docxml.to_xml
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def hide_refs(docxml)
|
|
86
91
|
docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or "\
|
|
87
92
|
"@hidden = 'false'])]")).each do |f|
|
|
88
93
|
f["hidden"] = "true"
|
|
89
94
|
end
|
|
90
|
-
docxml.to_xml
|
|
91
95
|
end
|
|
92
96
|
|
|
93
97
|
def supply_repo_ids(docxml)
|
|
@@ -97,7 +101,8 @@ module Metanorma
|
|
|
97
101
|
b.xpath(ns("./docidentifier")).each do |d|
|
|
98
102
|
next unless @files[d.text]
|
|
99
103
|
|
|
100
|
-
d.next = "<docidentifier type='repository'>
|
|
104
|
+
d.next = "<docidentifier type='repository'>"\
|
|
105
|
+
"current-metanorma-collection/#{d.text}"
|
|
101
106
|
end
|
|
102
107
|
end
|
|
103
108
|
end
|
|
@@ -111,29 +116,30 @@ module Metanorma
|
|
|
111
116
|
|
|
112
117
|
def svgmap_resolve(docxml)
|
|
113
118
|
isodoc = IsoDoc::Convert.new({})
|
|
119
|
+
isodoc.bibitem_lookup(docxml)
|
|
114
120
|
docxml.xpath(ns("//svgmap//eref")).each do |e|
|
|
115
|
-
|
|
116
|
-
next if href == "##{e['bibitemid']}" ||
|
|
117
|
-
href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
|
|
118
|
-
|
|
119
|
-
e["target"] = href.strip
|
|
120
|
-
e.name = "link"
|
|
121
|
-
e&.elements&.remove
|
|
121
|
+
svgmap_resolve1(e, isodoc)
|
|
122
122
|
end
|
|
123
123
|
Metanorma::Utils::svgmap_rewrite(docxml, "")
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
def svgmap_resolve1(eref, isodoc)
|
|
127
|
+
href = isodoc.eref_target(eref)
|
|
128
|
+
return if href == "##{eref['bibitemid']}" ||
|
|
129
|
+
(href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']"))
|
|
130
|
+
|
|
131
|
+
eref["target"] = href.strip
|
|
132
|
+
eref.name = "link"
|
|
133
|
+
eref&.elements&.remove
|
|
134
|
+
end
|
|
135
|
+
|
|
126
136
|
# repo(current-metanorma-collection/ISO 17301-1:2016)
|
|
127
137
|
# replaced by bibdata of "ISO 17301-1:2016" in situ as bibitem.
|
|
128
138
|
# Any erefs to that bibitem id are replaced with relative URL
|
|
129
139
|
# Preferably with anchor, and is a job to realise dynamic lookup
|
|
130
140
|
# of localities.
|
|
131
141
|
def update_direct_refs_to_docs(docxml, identifier)
|
|
132
|
-
erefs = docxml
|
|
133
|
-
.each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
|
|
134
|
-
m[:citeas][i["citeas"]] = true
|
|
135
|
-
m[:bibitemid][i["bibitemid"]] = true
|
|
136
|
-
end
|
|
142
|
+
erefs = collect_erefs(docxml)
|
|
137
143
|
docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
|
|
138
144
|
docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
|
|
139
145
|
next unless docid && %r{^current-metanorma-collection/}.match(docid)
|
|
@@ -144,6 +150,14 @@ module Metanorma
|
|
|
144
150
|
end
|
|
145
151
|
end
|
|
146
152
|
|
|
153
|
+
def collect_erefs(docxml)
|
|
154
|
+
docxml.xpath(ns("//eref"))
|
|
155
|
+
.each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
|
|
156
|
+
m[:citeas][i["citeas"]] = true
|
|
157
|
+
m[:bibitemid][i["bibitemid"]] = true
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
147
161
|
# Resolve erefs to a container of ids in another doc,
|
|
148
162
|
# to an anchor eref (direct link)
|
|
149
163
|
def update_indirect_refs_to_docs(docxml, internal_refs)
|
|
@@ -99,17 +99,15 @@ module Metanorma
|
|
|
99
99
|
out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
|
|
100
100
|
ret = if ref["fileref"]
|
|
101
101
|
{ type: "fileref", ref: @documents[identifier].file,
|
|
102
|
-
rel_path: ref["fileref"],
|
|
103
|
-
|
|
104
|
-
else
|
|
105
|
-
{ type: "id", ref: ref["id"] }
|
|
102
|
+
rel_path: ref["fileref"], out_path: out }
|
|
103
|
+
else { type: "id", ref: ref["id"] }
|
|
106
104
|
end
|
|
107
105
|
%i(attachment sectionsplit index).each do |s|
|
|
108
106
|
ret[s] = ref[s.to_s] if ref[s.to_s]
|
|
109
107
|
end
|
|
110
|
-
ret[:presentationxml] = ref["presentation-xml"]
|
|
111
|
-
ret[:bareafterfirst] = ref["bare-after-first"]
|
|
112
|
-
ret
|
|
108
|
+
ret[:presentationxml] = ref["presentation-xml"]
|
|
109
|
+
ret[:bareafterfirst] = ref["bare-after-first"]
|
|
110
|
+
ret.compact
|
|
113
111
|
end
|
|
114
112
|
|
|
115
113
|
def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
|
|
@@ -164,10 +162,15 @@ module Metanorma
|
|
|
164
162
|
def file_compile(file, filename, identifier)
|
|
165
163
|
return if @files[identifier][:sectionsplit] == "true"
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
opts = {
|
|
166
|
+
format: :asciidoc,
|
|
167
|
+
extension_keys: @format,
|
|
168
|
+
output_dir: @outdir,
|
|
169
|
+
}.merge(compile_options(identifier))
|
|
170
|
+
|
|
171
|
+
@compile.compile file, opts
|
|
169
172
|
@files[identifier][:outputs] = {}
|
|
170
|
-
file_compile_formats(
|
|
173
|
+
file_compile_formats(filename, identifier)
|
|
171
174
|
end
|
|
172
175
|
|
|
173
176
|
def compile_options(identifier)
|
|
@@ -182,29 +185,18 @@ module Metanorma
|
|
|
182
185
|
ret
|
|
183
186
|
end
|
|
184
187
|
|
|
185
|
-
def file_compile_formats(
|
|
188
|
+
def file_compile_formats(filename, identifier)
|
|
189
|
+
file_id = @files[identifier]
|
|
190
|
+
@format << :presentation if @format.include?(:pdf)
|
|
186
191
|
@format.each do |e|
|
|
187
192
|
ext = @compile.processor.output_formats[e]
|
|
188
193
|
fn = File.basename(filename).sub(/(?<=\.)[^.]+$/, ext.to_s)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
else
|
|
192
|
-
FileUtils.cp file.path.sub(/\.xml$/, ".#{ext}"),
|
|
193
|
-
File.join(@outdir, fn)
|
|
194
|
-
@files[identifier][:outputs][e] = File.join(@outdir, fn)
|
|
194
|
+
unless /html$/.match?(ext) && file_id[:sectionsplit]
|
|
195
|
+
file_id[:outputs][e] = File.join(@outdir, fn)
|
|
195
196
|
end
|
|
196
197
|
end
|
|
197
198
|
end
|
|
198
199
|
|
|
199
|
-
def file_sectionsplit_copy(file, base, identifier, ext, format)
|
|
200
|
-
dir = file.path.sub(/\.xml$/, ".#{ext}_collection")
|
|
201
|
-
files = Dir.glob("#{dir}/*.#{ext}")
|
|
202
|
-
FileUtils.cp files, @outdir
|
|
203
|
-
cover = File.join(@outdir, base.sub(/\.html$/, ".index.html"))
|
|
204
|
-
FileUtils.cp File.join(dir, "index.html"), cover
|
|
205
|
-
@files[identifier][:outputs][format] = cover
|
|
206
|
-
end
|
|
207
|
-
|
|
208
200
|
def copy_file_to_dest(fileref)
|
|
209
201
|
dest = File.join(@outdir, fileref[:out_path])
|
|
210
202
|
FileUtils.mkdir_p(File.dirname(dest))
|
|
@@ -223,12 +215,13 @@ module Metanorma
|
|
|
223
215
|
else
|
|
224
216
|
file, filename = targetfile(x, read: true)
|
|
225
217
|
warn "\n\n\n\n\nProcess #{filename}: #{DateTime.now.strftime('%H:%M:%S')}"
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
218
|
+
collection_xml = update_xrefs(file, identifier, internal_refs)
|
|
219
|
+
collection_filename = File.basename(filename, File.extname(filename))
|
|
220
|
+
collection_xml_path = File.join(Dir.tmpdir,
|
|
221
|
+
"#{collection_filename}.xml")
|
|
222
|
+
File.write collection_xml_path, collection_xml, encoding: "UTF-8"
|
|
223
|
+
file_compile(collection_xml_path, filename, identifier)
|
|
224
|
+
FileUtils.rm(collection_xml_path)
|
|
232
225
|
end
|
|
233
226
|
end
|
|
234
227
|
end
|
|
@@ -16,7 +16,7 @@ module Metanorma
|
|
|
16
16
|
# @param options [Hash]
|
|
17
17
|
# @option options [String] :coverpage cover page HTML (Liquid template)
|
|
18
18
|
# @option options [Array<Symbol>] :format list of formats (xml,html,doc,pdf)
|
|
19
|
-
# @option options [String] :
|
|
19
|
+
# @option options [String] :output_folder output directory
|
|
20
20
|
#
|
|
21
21
|
# We presuppose that the bibdata of the document is equivalent to that of
|
|
22
22
|
# the collection, and that the flavour gem can sensibly process it. We may
|
|
@@ -62,7 +62,6 @@ module Metanorma
|
|
|
62
62
|
# @option options [Strong] :ourput_folder output directory
|
|
63
63
|
def self.render(col, options = {})
|
|
64
64
|
folder = File.dirname col.file
|
|
65
|
-
# require "byebug"; byebug
|
|
66
65
|
warn "\n\n\n\n\nRender Init: #{DateTime.now.strftime('%H:%M:%S')}"
|
|
67
66
|
cr = new(col, folder, options)
|
|
68
67
|
warn "\n\n\n\n\nRender Files: #{DateTime.now.strftime('%H:%M:%S')}"
|
data/lib/metanorma/compile.rb
CHANGED
|
@@ -8,6 +8,8 @@ require_relative "compile_validate"
|
|
|
8
8
|
require_relative "fontist_utils"
|
|
9
9
|
require_relative "util"
|
|
10
10
|
require_relative "sectionsplit"
|
|
11
|
+
require_relative "extract"
|
|
12
|
+
require_relative "worker_pool"
|
|
11
13
|
|
|
12
14
|
module Metanorma
|
|
13
15
|
class Compile
|
|
@@ -32,7 +34,7 @@ module Metanorma
|
|
|
32
34
|
extract(isodoc, options[:extract], options[:extract_type])
|
|
33
35
|
FontistUtils.install_fonts(@processor, options) unless @fontist_installed
|
|
34
36
|
@fontist_installed = true
|
|
35
|
-
|
|
37
|
+
process_exts(filename, extensions, file, isodoc, options)
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def require_libraries(options)
|
|
@@ -128,112 +130,85 @@ module Metanorma
|
|
|
128
130
|
File.open(options[:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml }
|
|
129
131
|
end
|
|
130
132
|
|
|
131
|
-
def
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
|
|
135
|
-
HTMLEntities.new.decode(xml.children.to_xml)
|
|
133
|
+
def export_output(fname, content, **options)
|
|
134
|
+
mode = options[:binary] ? "wb" : "w:UTF-8"
|
|
135
|
+
File.open(fname, mode) { |f| f.write content }
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
def wrap_html(options, file_extension, outfilename)
|
|
139
|
+
if options[:wrapper] && /html$/.match(file_extension)
|
|
140
|
+
outfilename = outfilename.sub(/\.html$/, "")
|
|
141
|
+
FileUtils.mkdir_p outfilename
|
|
142
|
+
FileUtils.mv "#{outfilename}.html", outfilename
|
|
143
|
+
FileUtils.mv "#{outfilename}_images", outfilename, force: true
|
|
143
144
|
end
|
|
144
|
-
FileUtils.rm_rf dirname
|
|
145
|
-
FileUtils.mkdir_p dirname
|
|
146
|
-
xml = Nokogiri::XML(isodoc) { |config| config.huge }
|
|
147
|
-
sourcecode_export(xml, dirname) if extract_types.include? :sourcecode
|
|
148
|
-
image_export(xml, dirname) if extract_types.include? :image
|
|
149
|
-
requirement_export(xml, dirname) if extract_types.include? :requirement
|
|
150
145
|
end
|
|
151
146
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
xml.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
147
|
+
# isodoc is Raw Metanorma XML
|
|
148
|
+
def process_exts(filename, extensions, file, isodoc, options)
|
|
149
|
+
f = File.expand_path(change_output_dir(options))
|
|
150
|
+
fnames = { xml: f.sub(/\.[^.]+$/, ".xml"), f: f,
|
|
151
|
+
orig_filename: File.expand_path(filename),
|
|
152
|
+
presentationxml: f.sub(/\.[^.]+$/, ".presentation.xml") }
|
|
153
|
+
@queue = ::Metanorma::WorkersPool
|
|
154
|
+
.new(ENV["METANORMA_PARALLEL"]&.to_i || 3)
|
|
155
|
+
Util.sort_extensions_execution(extensions).each do |ext|
|
|
156
|
+
process_ext(ext, file, isodoc, fnames, options)
|
|
160
157
|
end
|
|
158
|
+
@queue.shutdown
|
|
161
159
|
end
|
|
162
160
|
|
|
163
|
-
def
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
File.open("#{dirname}/image/#{filename}", "wb") do |f|
|
|
172
|
-
f.write(Base64.strict_decode64(imgdata))
|
|
173
|
-
end
|
|
161
|
+
def process_ext(ext, file, isodoc, fnames, options)
|
|
162
|
+
fnames[:ext] = @processor.output_formats[ext]
|
|
163
|
+
fnames[:out] = fnames[:f].sub(/\.[^.]+$/, ".#{fnames[:ext]}")
|
|
164
|
+
isodoc_options = get_isodoc_options(file, options, ext)
|
|
165
|
+
thread = nil
|
|
166
|
+
unless process_ext_simple(ext, isodoc, fnames, options,
|
|
167
|
+
isodoc_options)
|
|
168
|
+
thread = process_exts1(ext, fnames, isodoc, options, isodoc_options)
|
|
174
169
|
end
|
|
170
|
+
thread
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def process_ext_simple(ext, isodoc, fnames, options, isodoc_options)
|
|
174
|
+
if ext == :rxl
|
|
175
|
+
relaton_export(isodoc, options.merge(relaton: fnames[:out]))
|
|
176
|
+
elsif options[:passthrough_presentation_xml] && ext == :presentation
|
|
177
|
+
f = File.exists?(fnames[:f]) ? fnames[:f] : fnames[:orig_filename]
|
|
178
|
+
FileUtils.cp f, fnames[:presentationxml]
|
|
179
|
+
elsif ext == :html && options[:sectionsplit]
|
|
180
|
+
sectionsplit_convert(fnames[:xml], isodoc, fnames[:out],
|
|
181
|
+
isodoc_options)
|
|
182
|
+
else return false
|
|
183
|
+
end
|
|
184
|
+
true
|
|
175
185
|
end
|
|
176
186
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
xml.at(REQUIREMENT_XPATH) or return
|
|
183
|
-
FileUtils.mkdir_p "#{dirname}/requirement"
|
|
184
|
-
xml.xpath(REQUIREMENT_XPATH).each_with_index do |s, i|
|
|
185
|
-
filename = s["filename"] || sprintf("%s-%04d.xml", s.name, i)
|
|
186
|
-
File.open("#{dirname}/requirement/#{filename}", "w:UTF-8") do |f|
|
|
187
|
-
f.write s
|
|
187
|
+
def process_exts1(ext, fnames, isodoc, options, isodoc_options)
|
|
188
|
+
if @processor.use_presentation_xml(ext)
|
|
189
|
+
@queue.schedule(ext, fnames.dup, options.dup,
|
|
190
|
+
isodoc_options.dup) do |a, b, c, d|
|
|
191
|
+
process_output_threaded(a, b, c, d)
|
|
188
192
|
end
|
|
193
|
+
else
|
|
194
|
+
process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
|
|
189
195
|
end
|
|
190
196
|
end
|
|
191
197
|
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
end
|
|
198
|
+
def process_output_threaded(ext, fnames1, options1, isodoc_options1)
|
|
199
|
+
@processor.output(nil, fnames1[:presentationxml], fnames1[:out], ext,
|
|
200
|
+
isodoc_options1)
|
|
201
|
+
wrap_html(options1, fnames1[:ext], fnames1[:out])
|
|
202
|
+
rescue StandardError => e
|
|
203
|
+
isodoc_error_process(e)
|
|
199
204
|
end
|
|
200
205
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
file_extension = @processor.output_formats[ext]
|
|
208
|
-
outfilename = f.sub(/\.[^.]+$/, ".#{file_extension}")
|
|
209
|
-
isodoc_options = get_isodoc_options(file, options, ext)
|
|
210
|
-
if ext == :rxl
|
|
211
|
-
relaton_export(isodoc, options.merge(relaton: outfilename))
|
|
212
|
-
elsif options[:passthrough_presentation_xml] && ext == :presentation
|
|
213
|
-
FileUtils.cp f, presentationxml_name
|
|
214
|
-
elsif ext == :html && options[:sectionsplit]
|
|
215
|
-
sectionsplit_convert(xml_name, isodoc, outfilename, isodoc_options)
|
|
216
|
-
else
|
|
217
|
-
if ext == :pdf && FontistUtils.has_fonts_manifest?(@processor,
|
|
218
|
-
options)
|
|
219
|
-
isodoc_options[:mn2pdf] = {
|
|
220
|
-
font_manifest: FontistUtils.location_manifest(@processor),
|
|
221
|
-
}
|
|
222
|
-
end
|
|
223
|
-
begin
|
|
224
|
-
if @processor.use_presentation_xml(ext)
|
|
225
|
-
@processor.output(nil, presentationxml_name, outfilename, ext,
|
|
226
|
-
isodoc_options)
|
|
227
|
-
else
|
|
228
|
-
@processor.output(isodoc, xml_name, outfilename, ext,
|
|
229
|
-
isodoc_options)
|
|
230
|
-
end
|
|
231
|
-
rescue StandardError => e
|
|
232
|
-
isodoc_error_process(e)
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
wrap_html(options, file_extension, outfilename)
|
|
236
|
-
end
|
|
206
|
+
def process_output_unthreaded(ext, fnames, isodoc, isodoc_options)
|
|
207
|
+
@processor.output(isodoc, fnames[:xml], fnames[:out], ext,
|
|
208
|
+
isodoc_options)
|
|
209
|
+
nil # return as Thread
|
|
210
|
+
rescue StandardError => e
|
|
211
|
+
isodoc_error_process(e)
|
|
237
212
|
end
|
|
238
213
|
|
|
239
214
|
private
|
|
@@ -248,14 +223,15 @@ module Metanorma
|
|
|
248
223
|
end
|
|
249
224
|
|
|
250
225
|
def get_isodoc_options(file, options, ext)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
226
|
+
ret = @processor.extract_options(file)
|
|
227
|
+
ret[:datauriimage] = true if options[:datauriimage]
|
|
228
|
+
ret[:sourcefilename] = options[:filename]
|
|
254
229
|
%i(bare sectionsplit no_install_fonts baseassetpath aligncrosselements)
|
|
255
|
-
.each
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
230
|
+
.each { |x| ret[x] ||= options[x] }
|
|
231
|
+
ext == :pdf && FontistUtils.has_fonts_manifest?(@processor, options) and
|
|
232
|
+
ret[:mn2pdf] =
|
|
233
|
+
{ font_manifest: FontistUtils.location_manifest(@processor) }
|
|
234
|
+
ret
|
|
259
235
|
end
|
|
260
236
|
|
|
261
237
|
# @param options [Hash]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Metanorma
|
|
2
|
+
class Compile
|
|
3
|
+
def relaton_export(isodoc, options)
|
|
4
|
+
return unless options[:relaton]
|
|
5
|
+
|
|
6
|
+
xml = Nokogiri::XML(isodoc) { |config| config.huge }
|
|
7
|
+
bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
|
|
8
|
+
# docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
|
|
9
|
+
# outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
|
|
10
|
+
File.open(options[:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def clean_sourcecode(xml)
|
|
14
|
+
xml.xpath(".//callout | .//annotation | .//xmlns:callout | "\
|
|
15
|
+
".//xmlns:annotation").each(&:remove)
|
|
16
|
+
xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
|
|
17
|
+
HTMLEntities.new.decode(xml.children.to_xml)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def extract(isodoc, dirname, extract_types)
|
|
21
|
+
return unless dirname
|
|
22
|
+
|
|
23
|
+
extract_types.nil? || extract_types.empty? and
|
|
24
|
+
extract_types = %i[sourcecode image requirement]
|
|
25
|
+
FileUtils.rm_rf dirname
|
|
26
|
+
FileUtils.mkdir_p dirname
|
|
27
|
+
xml = Nokogiri::XML(isodoc) { |config| config.huge }
|
|
28
|
+
sourcecode_export(xml, dirname) if extract_types.include? :sourcecode
|
|
29
|
+
image_export(xml, dirname) if extract_types.include? :image
|
|
30
|
+
extract_types.include?(:requirement) and
|
|
31
|
+
requirement_export(xml, dirname)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def sourcecode_export(xml, dirname)
|
|
35
|
+
xml.at("//sourcecode | //xmlns:sourcecode") or return
|
|
36
|
+
FileUtils.mkdir_p "#{dirname}/sourcecode"
|
|
37
|
+
xml.xpath("//sourcecode | //xmlns:sourcecode").each_with_index do |s, i|
|
|
38
|
+
filename = s["filename"] || sprintf("sourcecode-%04d.txt", i)
|
|
39
|
+
export_output("#{dirname}/sourcecode/#{filename}",
|
|
40
|
+
clean_sourcecode(s.dup))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def image_export(xml, dirname)
|
|
45
|
+
xml.at("//image | //xmlns:image") or return
|
|
46
|
+
FileUtils.mkdir_p "#{dirname}/image"
|
|
47
|
+
xml.xpath("//image | //xmlns:image").each_with_index do |s, i|
|
|
48
|
+
next unless /^data:image/.match? s["src"]
|
|
49
|
+
|
|
50
|
+
%r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ s["src"]
|
|
51
|
+
fn = s["filename"] || sprintf("image-%<num>04d.%<name>s",
|
|
52
|
+
num: i, name: imgtype)
|
|
53
|
+
export_output("#{dirname}/image/#{fn}", Base64.strict_decode64(imgdata),
|
|
54
|
+
binary: true)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
REQUIREMENT_XPATH =
|
|
59
|
+
"//requirement | //xmlns:requirement | //recommendation | "\
|
|
60
|
+
"//xmlns:recommendation | //permission | //xmlns:permission".freeze
|
|
61
|
+
|
|
62
|
+
def requirement_export(xml, dirname)
|
|
63
|
+
xml.at(REQUIREMENT_XPATH) or return
|
|
64
|
+
FileUtils.mkdir_p "#{dirname}/requirement"
|
|
65
|
+
xml.xpath(REQUIREMENT_XPATH).each_with_index do |s, i|
|
|
66
|
+
fn = s["filename"] ||
|
|
67
|
+
sprintf("%<name>s-%<num>04d.xml", name: s.name, num: i)
|
|
68
|
+
export_output("#{dirname}/requirement/#{fn}", s)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -56,13 +56,19 @@ module Metanorma
|
|
|
56
56
|
attr&.sub(/^#{name}:\s*$/, "#{name}: true")&.sub(/^#{name}:\s+/, "")
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
ADOC_OPTIONS =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
ADOC_OPTIONS =
|
|
60
|
+
%w(htmlstylesheet htmlcoverpage htmlintropage scripts
|
|
61
|
+
scripts-override scripts-pdf wordstylesheet i18nyaml
|
|
62
|
+
standardstylesheet header wordcoverpage wordintropage
|
|
63
|
+
ulstyle olstyle htmlstylesheet-override bare
|
|
64
|
+
htmltoclevels doctoclevels sectionsplit base-asset-path
|
|
65
|
+
body-font header-font monospace-font title-font
|
|
66
|
+
align-cross-elements wordstylesheet-override
|
|
67
|
+
pdf-encrypt pdf-encryption-length pdf-user-password
|
|
68
|
+
pdf-owner-password pdf-allow-copy-content pdf-allow-edit-content
|
|
69
|
+
pdf-allow-assemble-document pdf-allow-edit-annotations
|
|
70
|
+
pdf-allow-print pdf-allow-print-hq pdf-allow-fill-in-forms
|
|
71
|
+
pdf-allow-access-content pdf-encrypt-metadata).freeze
|
|
66
72
|
|
|
67
73
|
def extract_options(file)
|
|
68
74
|
header = file.sub(/\n\n.*$/m, "\n")
|
data/lib/metanorma/registry.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Registry of all Metanorma types and entry points
|
|
2
2
|
#
|
|
3
3
|
|
|
4
|
-
require
|
|
4
|
+
require "singleton"
|
|
5
5
|
|
|
6
6
|
class Error < StandardError
|
|
7
7
|
end
|
|
@@ -14,15 +14,16 @@ module Metanorma
|
|
|
14
14
|
|
|
15
15
|
def initialize
|
|
16
16
|
@processors = {}
|
|
17
|
-
@aliases = {csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa}
|
|
17
|
+
@aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def alias(x)
|
|
21
21
|
@aliases[x]
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def register
|
|
24
|
+
def register(processor)
|
|
25
25
|
raise Error unless processor < ::Metanorma::Processor
|
|
26
|
+
|
|
26
27
|
p = processor.new
|
|
27
28
|
# p.short[-1] is the canonical name
|
|
28
29
|
short = Array(p.short)
|
|
@@ -31,7 +32,8 @@ module Metanorma
|
|
|
31
32
|
@aliases[s] = short[-1]
|
|
32
33
|
end
|
|
33
34
|
Array(p.short)
|
|
34
|
-
Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered",
|
|
35
|
+
Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered",
|
|
36
|
+
:info)
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def find_processor(short)
|
|
@@ -42,21 +44,17 @@ module Metanorma
|
|
|
42
44
|
@processors.keys
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
def processors
|
|
46
|
-
@processors
|
|
47
|
-
end
|
|
48
|
-
|
|
49
47
|
def output_formats
|
|
50
|
-
@processors.inject({}) do |acc, (k,v)|
|
|
48
|
+
@processors.inject({}) do |acc, (k, v)|
|
|
51
49
|
acc[k] = v.output_formats
|
|
52
50
|
acc
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
54
|
def root_tags
|
|
57
|
-
@processors.inject({}) do |acc, (k,v)|
|
|
55
|
+
@processors.inject({}) do |acc, (k, v)|
|
|
58
56
|
if v.asciidoctor_backend
|
|
59
|
-
x = Asciidoctor.load nil, {backend: v.asciidoctor_backend}
|
|
57
|
+
x = Asciidoctor.load nil, { backend: v.asciidoctor_backend }
|
|
60
58
|
acc[k] = x.converter.xml_root_tag
|
|
61
59
|
end
|
|
62
60
|
acc
|
data/lib/metanorma/version.rb
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Metanorma
|
|
2
|
+
class WorkersPool
|
|
3
|
+
def initialize(workers)
|
|
4
|
+
@workers = workers
|
|
5
|
+
@queue = SizedQueue.new(@workers)
|
|
6
|
+
@threads = Array.new(@workers) do
|
|
7
|
+
Thread.new do
|
|
8
|
+
catch(:exit) do
|
|
9
|
+
loop do
|
|
10
|
+
job, args = @queue.pop
|
|
11
|
+
job.call *args
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def schedule(*args, &block)
|
|
19
|
+
@queue << [block, args]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def shutdown
|
|
23
|
+
@workers.times do
|
|
24
|
+
schedule { throw :exit }
|
|
25
|
+
end
|
|
26
|
+
@threads.map(&:join)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/metanorma.gemspec
CHANGED
|
@@ -34,13 +34,14 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
# spec.add_dependency "relaton-cli"
|
|
35
35
|
# spec.add_dependency "metanorma-standoc"
|
|
36
36
|
|
|
37
|
-
spec.add_development_dependency "
|
|
37
|
+
spec.add_development_dependency "debug"
|
|
38
38
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
|
39
|
-
spec.add_development_dependency "metanorma-iso", "~> 1.
|
|
39
|
+
spec.add_development_dependency "metanorma-iso", "~> 1.10"
|
|
40
|
+
spec.add_development_dependency "mnconvert"
|
|
40
41
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
41
42
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
42
43
|
spec.add_development_dependency "rspec-command", "~> 1.0"
|
|
43
44
|
spec.add_development_dependency "rubocop", "~> 1.5.2"
|
|
44
45
|
spec.add_development_dependency "sassc", "~> 2.4.0"
|
|
45
|
-
spec.add_development_dependency "
|
|
46
|
+
spec.add_development_dependency "reline", "~> 0.2.8.pre.11"
|
|
46
47
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metanorma
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-12-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: asciidoctor
|
|
@@ -109,19 +109,19 @@ dependencies:
|
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: '0'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
112
|
+
name: debug
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
|
-
- - "
|
|
115
|
+
- - ">="
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
117
|
+
version: '0'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
|
-
- - "
|
|
122
|
+
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
124
|
+
version: '0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: equivalent-xml
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -142,14 +142,28 @@ dependencies:
|
|
|
142
142
|
requirements:
|
|
143
143
|
- - "~>"
|
|
144
144
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: 1.
|
|
145
|
+
version: '1.10'
|
|
146
146
|
type: :development
|
|
147
147
|
prerelease: false
|
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 1.
|
|
152
|
+
version: '1.10'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: mnconvert
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
153
167
|
- !ruby/object:Gem::Dependency
|
|
154
168
|
name: rake
|
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -221,19 +235,19 @@ dependencies:
|
|
|
221
235
|
- !ruby/object:Gem::Version
|
|
222
236
|
version: 2.4.0
|
|
223
237
|
- !ruby/object:Gem::Dependency
|
|
224
|
-
name:
|
|
238
|
+
name: reline
|
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
|
226
240
|
requirements:
|
|
227
|
-
- - "
|
|
241
|
+
- - "~>"
|
|
228
242
|
- !ruby/object:Gem::Version
|
|
229
|
-
version:
|
|
243
|
+
version: 0.2.8.pre.11
|
|
230
244
|
type: :development
|
|
231
245
|
prerelease: false
|
|
232
246
|
version_requirements: !ruby/object:Gem::Requirement
|
|
233
247
|
requirements:
|
|
234
|
-
- - "
|
|
248
|
+
- - "~>"
|
|
235
249
|
- !ruby/object:Gem::Version
|
|
236
|
-
version:
|
|
250
|
+
version: 0.2.8.pre.11
|
|
237
251
|
description: Library to process any Metanorma standard.
|
|
238
252
|
email:
|
|
239
253
|
- open.source@ribose.com
|
|
@@ -274,6 +288,7 @@ files:
|
|
|
274
288
|
- lib/metanorma/compile_validate.rb
|
|
275
289
|
- lib/metanorma/config.rb
|
|
276
290
|
- lib/metanorma/document.rb
|
|
291
|
+
- lib/metanorma/extract.rb
|
|
277
292
|
- lib/metanorma/fontist_utils.rb
|
|
278
293
|
- lib/metanorma/input.rb
|
|
279
294
|
- lib/metanorma/input/asciidoc.rb
|
|
@@ -283,6 +298,7 @@ files:
|
|
|
283
298
|
- lib/metanorma/sectionsplit.rb
|
|
284
299
|
- lib/metanorma/util.rb
|
|
285
300
|
- lib/metanorma/version.rb
|
|
301
|
+
- lib/metanorma/worker_pool.rb
|
|
286
302
|
- metanorma.gemspec
|
|
287
303
|
homepage: https://github.com/metanorma/metanorma
|
|
288
304
|
licenses:
|
|
@@ -303,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
303
319
|
- !ruby/object:Gem::Version
|
|
304
320
|
version: '0'
|
|
305
321
|
requirements: []
|
|
306
|
-
rubygems_version: 3.2.
|
|
322
|
+
rubygems_version: 3.2.32
|
|
307
323
|
signing_key:
|
|
308
324
|
specification_version: 4
|
|
309
325
|
summary: Metanorma is the standard of standards; the metanorma gem allows you to create
|