metanorma 1.7.6 → 2.0.0
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 +5 -1
- data/lib/metanorma/array_monkeypatch.rb +9 -0
- data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
- data/lib/metanorma/collection/collection.rb +225 -0
- data/lib/metanorma/collection/config/bibdata.rb +12 -0
- data/lib/metanorma/collection/config/compile_options.rb +13 -0
- data/lib/metanorma/collection/config/config.rb +163 -0
- data/lib/metanorma/collection/config/converters.rb +30 -0
- data/lib/metanorma/collection/config/directive.rb +10 -0
- data/lib/metanorma/collection/config/manifest.rb +88 -0
- data/lib/metanorma/collection/document/document.rb +133 -0
- data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
- data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
- data/lib/metanorma/collection/manifest/manifest.rb +237 -0
- data/lib/metanorma/collection/renderer/fileparse.rb +247 -0
- data/lib/metanorma/collection/renderer/fileprocess.rb +173 -0
- data/lib/metanorma/collection/renderer/navigation.rb +133 -0
- data/lib/metanorma/collection/renderer/render_word.rb +133 -0
- data/lib/metanorma/collection/renderer/renderer.rb +157 -0
- data/lib/metanorma/collection/renderer/utils.rb +183 -0
- data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -0
- data/lib/metanorma/collection/util/disambig_files.rb +37 -0
- data/lib/metanorma/collection/util/util.rb +72 -0
- data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
- data/lib/metanorma/{compile.rb → compile/compile.rb} +17 -11
- data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
- data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
- data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
- data/lib/metanorma/{config.rb → config/config.rb} +1 -1
- data/lib/metanorma/input/asciidoc.rb +3 -3
- data/lib/metanorma/input/base.rb +1 -5
- data/lib/metanorma/processor/processor.rb +54 -0
- data/lib/metanorma/processor.rb +1 -49
- data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
- data/lib/metanorma/shale_monkeypatch.rb +15 -0
- data/lib/metanorma/util/fontist_helper.rb +130 -0
- data/lib/metanorma/util/util.rb +45 -0
- data/lib/metanorma/util/worker_pool.rb +39 -0
- data/lib/metanorma/version.rb +1 -1
- data/lib/metanorma.rb +13 -8
- data/metanorma.gemspec +2 -1
- metadata +51 -26
- data/Gemfile.devel +0 -2
- data/lib/metanorma/collection.rb +0 -243
- data/lib/metanorma/collection_fileparse.rb +0 -254
- data/lib/metanorma/collection_fileprocess.rb +0 -157
- data/lib/metanorma/collection_manifest.rb +0 -139
- data/lib/metanorma/collection_render_utils.rb +0 -169
- data/lib/metanorma/collection_render_word.rb +0 -131
- data/lib/metanorma/collection_renderer.rb +0 -230
- data/lib/metanorma/document.rb +0 -133
- data/lib/metanorma/files_lookup.rb +0 -208
- data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
- data/lib/metanorma/fontist_utils.rb +0 -122
- data/lib/metanorma/sectionsplit.rb +0 -216
- data/lib/metanorma/sectionsplit_links.rb +0 -189
- data/lib/metanorma/util.rb +0 -127
- data/lib/metanorma/worker_pool.rb +0 -29
@@ -1,169 +0,0 @@
|
|
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
|
-
def dup_bibitem(docid, bib)
|
14
|
-
newbib = @files.get(docid, :bibdata).dup
|
15
|
-
newbib.name = "bibitem"
|
16
|
-
newbib["hidden"] = "true"
|
17
|
-
newbib&.at("./*[local-name() = 'ext']")&.remove
|
18
|
-
newbib["id"] = bib["id"]
|
19
|
-
newbib
|
20
|
-
end
|
21
|
-
|
22
|
-
def get_bibitem_docid(bib, identifier)
|
23
|
-
docid =
|
24
|
-
bib.at(ns("./docidentifier[@type = 'metanorma-collection']")) ||
|
25
|
-
bib.at(ns("./docidentifier[not(@type)]")) ||
|
26
|
-
bib.at(ns("./docidentifier"))
|
27
|
-
docid &&= docid_prefix(docid)
|
28
|
-
if @files.get(docid) then docid
|
29
|
-
else
|
30
|
-
fail_update_bibitem(docid, identifier)
|
31
|
-
nil
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def hide_refs(docxml)
|
36
|
-
docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or " \
|
37
|
-
"@hidden = 'false'])]")).each do |f|
|
38
|
-
f["hidden"] = "true"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def strip_eref(eref)
|
43
|
-
eref.xpath(ns("./locality | ./localityStack")).each(&:remove)
|
44
|
-
eref.replace(eref.children)
|
45
|
-
end
|
46
|
-
|
47
|
-
def docid_to_citeas(bib)
|
48
|
-
docid = bib.at(ns("./docidentifier[@primary = 'true']")) ||
|
49
|
-
bib.at(ns("./docidentifier")) or return
|
50
|
-
docid_prefix(docid)
|
51
|
-
end
|
52
|
-
|
53
|
-
def collect_erefs(docxml)
|
54
|
-
docxml.xpath(ns("//eref"))
|
55
|
-
.each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
|
56
|
-
m[:citeas][i["citeas"]] = true
|
57
|
-
m[:bibitemid][i["bibitemid"]] = true
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def docid_prefix(docid)
|
64
|
-
type = docid["type"]
|
65
|
-
type == "metanorma-collection" and type = nil
|
66
|
-
@c.decode(@isodoc
|
67
|
-
.docid_prefix(type, docid.children.to_xml)).gsub(/\s/, " ")
|
68
|
-
end
|
69
|
-
|
70
|
-
def create_non_existing_directory(output_directory)
|
71
|
-
!File.exist?(output_directory) and
|
72
|
-
FileUtils.mkdir_p(output_directory)
|
73
|
-
end
|
74
|
-
|
75
|
-
def format_sort(formats)
|
76
|
-
ret = []
|
77
|
-
formats.include?(:xml) and ret << :xml
|
78
|
-
formats.include?(:presentation) and ret << :presentation
|
79
|
-
a = %i(presentation xml)
|
80
|
-
ret + formats.reject { |i| a.include? i }
|
81
|
-
end
|
82
|
-
|
83
|
-
# @param options [Hash]
|
84
|
-
# @raise [ArgumentError]
|
85
|
-
def check_options(options)
|
86
|
-
(options[:format].is_a?(Array) && (FORMATS & options[:format]).any?) or
|
87
|
-
raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
|
88
|
-
end
|
89
|
-
|
90
|
-
def pdfconv
|
91
|
-
doctype = @doctype.to_sym
|
92
|
-
x = Asciidoctor.load nil, backend: doctype
|
93
|
-
x.converter.pdf_converter(PdfOptionsNode.new(doctype,
|
94
|
-
@compile_options))
|
95
|
-
end
|
96
|
-
|
97
|
-
def fail_update_bibitem(docid, identifier)
|
98
|
-
error = "[metanorma] Cannot find crossreference to document #{docid} " \
|
99
|
-
"in document #{identifier}."
|
100
|
-
@log&.add("Cross-References", nil, error)
|
101
|
-
Util.log(error, :warning)
|
102
|
-
end
|
103
|
-
|
104
|
-
def datauri_encode(docxml)
|
105
|
-
docxml.xpath(ns("//image")).each do |i|
|
106
|
-
i["src"] = Vectory::Utils::datauri(i["src"])
|
107
|
-
end
|
108
|
-
docxml
|
109
|
-
end
|
110
|
-
|
111
|
-
class PdfOptionsNode
|
112
|
-
def initialize(doctype, options)
|
113
|
-
docproc = Metanorma::Registry.instance.find_processor(doctype)
|
114
|
-
if FontistUtils.has_custom_fonts?(docproc, options, {})
|
115
|
-
@fonts_manifest = FontistUtils.location_manifest(docproc, options)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def attr(key)
|
120
|
-
if key == "fonts-manifest" && @fonts_manifest
|
121
|
-
@fonts_manifest
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class Dummy
|
127
|
-
def attr(_key); end
|
128
|
-
end
|
129
|
-
|
130
|
-
def isodoc_create
|
131
|
-
x = Asciidoctor.load nil, backend: @doctype.to_sym
|
132
|
-
isodoc = x.converter.html_converter(Dummy.new) # to obtain Isodoc class
|
133
|
-
isodoc.i18n_init(@lang, @script, @locale) # read in internationalisation
|
134
|
-
isodoc.metadata_init(@lang, @script, @locale, isodoc.i18n)
|
135
|
-
isodoc.info(@xml, nil)
|
136
|
-
isodoc
|
137
|
-
end
|
138
|
-
|
139
|
-
# create the @meta class of isodoc, for populating Liquid,
|
140
|
-
# with "navigation" set to the index bar.
|
141
|
-
# extracted from the manifest
|
142
|
-
def isodoc_populate
|
143
|
-
@isodoc.info(@xml, nil)
|
144
|
-
m = @xml.at(ns("//manifest"))
|
145
|
-
{ navigation: indexfile(m), nav_object: index_object(m),
|
146
|
-
docrefs: liquid_docrefs,
|
147
|
-
"prefatory-content": isodoc_builder(@xml.at(ns("//prefatory-content"))),
|
148
|
-
"final-content": isodoc_builder(@xml.at(ns("//final-content"))),
|
149
|
-
doctitle: m.at(ns("../bibdata/title"))&.text,
|
150
|
-
docnumber: m.at(ns("../bibdata/docidentifier"))&.text }.each do |k, v|
|
151
|
-
v and @isodoc.meta.set(
|
152
|
-
k, v
|
153
|
-
)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def isodoc_builder(node)
|
158
|
-
Nokogiri::HTML::Builder.new(encoding: "UTF-8") do |b|
|
159
|
-
b.div do |div|
|
160
|
-
node&.children&.each { |n| @isodoc.parse(n, div) }
|
161
|
-
end
|
162
|
-
end.doc.root.to_html
|
163
|
-
end
|
164
|
-
|
165
|
-
def ns(xpath)
|
166
|
-
@isodoc.ns(xpath)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class CollectionRenderer
|
3
|
-
def docconv
|
4
|
-
@tempfile_cache ||= []
|
5
|
-
doctype = @doctype.to_sym
|
6
|
-
x = Asciidoctor.load nil, backend: doctype
|
7
|
-
x.converter.doc_converter(DocOptionsNode.new(@directives, @dirname))
|
8
|
-
end
|
9
|
-
|
10
|
-
def concat_extract_files(filename)
|
11
|
-
xml = Nokogiri::XML(File.read(filename, encoding: "UTF-8"), &:huge)
|
12
|
-
docs = xml.xpath(ns("//doc-container")).each_with_object([]) do |x, m|
|
13
|
-
n = Nokogiri::XML::Document.new
|
14
|
-
n.add_child(x.elements.first.remove)
|
15
|
-
m << n
|
16
|
-
end
|
17
|
-
[wrapping_doc(docs.first.dup, xml), docs]
|
18
|
-
end
|
19
|
-
|
20
|
-
def wrapping_doc(doc, xml)
|
21
|
-
doc.at(ns("//bibdata")).replace(xml.at(ns("//bibdata")).to_xml)
|
22
|
-
sections = wrapping_doc_body(doc)
|
23
|
-
wrapping_doc_intro_outro(xml, sections)
|
24
|
-
set_displayorder_wrapping_doc(doc)
|
25
|
-
end
|
26
|
-
|
27
|
-
def wrapping_doc_intro_outro(xml, sections)
|
28
|
-
p = xml.at(ns("//prefatory-content")) and
|
29
|
-
sections.previous = "<preface>#{p.children.to_xml}</preface>"
|
30
|
-
p = xml.at(ns("//final-content")) and
|
31
|
-
sections.next = "<annex>#{p.children.to_xml}</annex>"
|
32
|
-
end
|
33
|
-
|
34
|
-
def wrapping_doc_body(doc)
|
35
|
-
doc.xpath(ns("//annex | //preface | //bibliography")).each(&:remove)
|
36
|
-
s = doc.at(ns("//sections"))
|
37
|
-
repl = <<~BODY
|
38
|
-
<sections><clause id='_collection_placeholder'><p>PLACEHOLDER</p></clause></sections>
|
39
|
-
BODY
|
40
|
-
s.replace(repl)
|
41
|
-
doc.at(ns("//sections"))
|
42
|
-
end
|
43
|
-
|
44
|
-
def set_displayorder_wrapping_doc(doc)
|
45
|
-
doc.xpath(ns("//preface/* | //sections/* | //annex"))
|
46
|
-
.each_with_index do |x, i|
|
47
|
-
x["displayorder"] = i + 1
|
48
|
-
end
|
49
|
-
doc
|
50
|
-
end
|
51
|
-
|
52
|
-
SECTION_BREAK = '<p class="MsoNormal"><br clear="all" class="section"/></p>'
|
53
|
-
.freeze
|
54
|
-
DIV1 = '<div class="WordSection1"> </div>'.freeze
|
55
|
-
DIV2 = '<div class="WordSection2"> </div>'.freeze
|
56
|
-
|
57
|
-
def docconv_convert1(docs)
|
58
|
-
docs.each_with_index.with_object([]) do |(d, i), m|
|
59
|
-
conv = docconv
|
60
|
-
conv.convert_init(d.to_xml(encoding: "UTF-8"), "xxxx", false)
|
61
|
-
html = conv.postprocess_cleanup(conv.convert1(d, "xxx", "."))
|
62
|
-
@tempfile_cache += conv.tempfile_cache # hold on to the temp img files
|
63
|
-
b = Nokogiri::XML(html).at("//body")
|
64
|
-
i == docs.size - 1 or
|
65
|
-
b << '<p class="MsoNormal"><br clear="all" class="section"/></p>'
|
66
|
-
m << b.children
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def collection_coverpages(conv, docs)
|
71
|
-
conv.wordintropage and [DIV2, SECTION_BREAK].reverse.each do |s|
|
72
|
-
docs.unshift(Nokogiri::XML(s).root)
|
73
|
-
end
|
74
|
-
conv.wordcoverpage and [DIV1, SECTION_BREAK].reverse.each do |s|
|
75
|
-
docs.unshift(Nokogiri::XML(s).root)
|
76
|
-
end
|
77
|
-
docs
|
78
|
-
end
|
79
|
-
|
80
|
-
def docconv_convert(filename)
|
81
|
-
pref_file, docs = concat_extract_files(filename)
|
82
|
-
body = docconv_convert1(docs)
|
83
|
-
collection_conv = overall_docconv_converter(body)
|
84
|
-
collection_coverpages(collection_conv, body)
|
85
|
-
collection_conv.convert(filename, pref_file.to_xml, false)
|
86
|
-
end
|
87
|
-
|
88
|
-
def overall_docconv_cover(collection_conv)
|
89
|
-
p = Util::hash_key_detect(@directives, "collection-word-coverpage", nil)
|
90
|
-
collection_conv.wordcoverpage =
|
91
|
-
Util::rel_path_resolve(@dirname, p)
|
92
|
-
p = Util::hash_key_detect(@directives, "collection-word-intropage", nil)
|
93
|
-
collection_conv.wordintropage =
|
94
|
-
Util::rel_path_resolve(@dirname, p)
|
95
|
-
end
|
96
|
-
|
97
|
-
def overall_docconv_converter(body)
|
98
|
-
collection_conv = docconv
|
99
|
-
collection_conv.options[:collection_doc] = body.map(&:to_xml).join
|
100
|
-
overall_docconv_cover(collection_conv)
|
101
|
-
|
102
|
-
def collection_conv.postprocess_cleanup(result)
|
103
|
-
ret = to_xhtml(super)
|
104
|
-
b = ret.at("//div[@id = '_collection_placeholder']")
|
105
|
-
b.replace(@options[:collection_doc])
|
106
|
-
from_xhtml(ret)
|
107
|
-
end
|
108
|
-
|
109
|
-
collection_conv
|
110
|
-
end
|
111
|
-
|
112
|
-
class DocOptionsNode
|
113
|
-
def initialize(directives, dir)
|
114
|
-
@dir = dir
|
115
|
-
@wordcoverpage =
|
116
|
-
Util::hash_key_detect(directives, "document-word-coverpage",
|
117
|
-
@wordcoverpage)
|
118
|
-
@wordintropage =
|
119
|
-
Util::hash_key_detect(directives, "document-word-intropage",
|
120
|
-
@wordintropage)
|
121
|
-
end
|
122
|
-
|
123
|
-
def attr(key)
|
124
|
-
case key
|
125
|
-
when "wordcoverpage" then Util::rel_path_resolve(@dir, @wordcoverpage)
|
126
|
-
when "wordintropage" then Util::rel_path_resolve(@dir, @wordintropage)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
@@ -1,230 +0,0 @@
|
|
1
|
-
require "isodoc"
|
2
|
-
require "htmlentities"
|
3
|
-
require_relative "collection_fileprocess"
|
4
|
-
require_relative "fontist_utils"
|
5
|
-
require_relative "util"
|
6
|
-
require_relative "files_lookup"
|
7
|
-
require_relative "collection_render_utils"
|
8
|
-
require_relative "collection_render_word"
|
9
|
-
|
10
|
-
module Metanorma
|
11
|
-
# XML collection renderer
|
12
|
-
class CollectionRenderer
|
13
|
-
FORMATS = %i[html xml doc pdf].freeze
|
14
|
-
|
15
|
-
attr_accessor :isodoc, :nested
|
16
|
-
attr_reader :xml, :compile, :compile_options, :documents
|
17
|
-
|
18
|
-
# This is only going to render the HTML collection
|
19
|
-
# @param xml [Metanorma::Collection] input XML collection
|
20
|
-
# @param folder [String] input folder
|
21
|
-
# @param options [Hash]
|
22
|
-
# @option options [String] :coverpage cover page HTML (Liquid template)
|
23
|
-
# @option options [Array<Symbol>] :format list of formats (xml,html,doc,pdf)
|
24
|
-
# @option options [String] :output_folder output directory
|
25
|
-
#
|
26
|
-
# We presuppose that the bibdata of the document is equivalent to that of
|
27
|
-
# the collection, and that the flavour gem can sensibly process it. We may
|
28
|
-
# need to enhance metadata in the flavour gems isodoc/metadata.rb with
|
29
|
-
# collection metadata
|
30
|
-
def initialize(collection, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
31
|
-
check_options options
|
32
|
-
@xml = Nokogiri::XML collection.to_xml # @xml is the collection manifest
|
33
|
-
@lang = @xml.at("//xmlns:bibdata/xmlns:language")&.text || "en"
|
34
|
-
@script = @xml.at("//xmlns:bibdata/xmlns:script")&.text || "Latn"
|
35
|
-
@locale = @xml.at("//xmlns:bibdata/xmlns:locale")&.text
|
36
|
-
@doctype = doctype
|
37
|
-
@compile = Compile.new
|
38
|
-
@compile.load_flavor(@doctype)
|
39
|
-
|
40
|
-
@isodoc = isodoc_create # output processor for flavour
|
41
|
-
@outdir = dir_name_cleanse(options[:output_folder])
|
42
|
-
@coverpage = options[:coverpage] || collection.coverpage
|
43
|
-
@format = Util.sort_extensions_execution(options[:format])
|
44
|
-
@compile_options = options[:compile] || {}
|
45
|
-
@compile_options[:no_install_fonts] = true if options[:no_install_fonts]
|
46
|
-
@log = options[:log]
|
47
|
-
@documents = collection.documents
|
48
|
-
@bibdata = collection.documents
|
49
|
-
@directives = collection.directives
|
50
|
-
@dirname = collection.dirname
|
51
|
-
@disambig = Util::DisambigFiles.new
|
52
|
-
@c = HTMLEntities.new
|
53
|
-
@files_to_delete = []
|
54
|
-
@nested = options[:nested] # if false, this is the root instance of Renderer
|
55
|
-
# if true, then this is not the last time Renderer will be run
|
56
|
-
# (e.g. this is sectionsplit)
|
57
|
-
|
58
|
-
# list of files in the collection
|
59
|
-
@files = Metanorma::FileLookup.new(folder, self)
|
60
|
-
@files.add_section_split
|
61
|
-
isodoc_populate
|
62
|
-
create_non_existing_directory(@outdir)
|
63
|
-
end
|
64
|
-
|
65
|
-
def flush_files
|
66
|
-
warn "\n\n\n\n\nDone: #{DateTime.now.strftime('%H:%M:%S')}"
|
67
|
-
warn @files.files_to_delete
|
68
|
-
@files.files_to_delete.each { |f| FileUtils.rm_f(f) }
|
69
|
-
@files_to_delete.each { |f| FileUtils.rm_f(f) }
|
70
|
-
end
|
71
|
-
|
72
|
-
# @param col [Metanorma::Collection] XML collection
|
73
|
-
# @param options [Hash]
|
74
|
-
# @option options [String] :coverpage cover page HTML (Liquid template)
|
75
|
-
# @option options [Array<Symbol>] :format list of formats
|
76
|
-
# @option options [Strong] :ourput_folder output directory
|
77
|
-
def self.render(col, options = {})
|
78
|
-
warn "\n\n\n\n\nRender Init: #{DateTime.now.strftime('%H:%M:%S')}"
|
79
|
-
cr = new(col, File.dirname(col.file), options)
|
80
|
-
cr.files
|
81
|
-
cr.concatenate(col, options)
|
82
|
-
options[:format]&.include?(:html) and cr.coverpage
|
83
|
-
cr.flush_files
|
84
|
-
cr
|
85
|
-
end
|
86
|
-
|
87
|
-
def concatenate(col, options)
|
88
|
-
warn "\n\n\n\n\nConcatenate: #{DateTime.now.strftime('%H:%M:%S')}"
|
89
|
-
(options[:format] & %i(pdf doc)).empty? or
|
90
|
-
options[:format] << :presentation
|
91
|
-
concatenate_prep(col, options)
|
92
|
-
concatenate_outputs(options)
|
93
|
-
end
|
94
|
-
|
95
|
-
def concatenate_prep(col, options)
|
96
|
-
%i(xml presentation).each do |e|
|
97
|
-
options[:format].include?(e) or next
|
98
|
-
ext = e == :presentation ? "presentation.xml" : e.to_s
|
99
|
-
File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") do |f|
|
100
|
-
f.write(concatenate1(col.clone, e).to_xml)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def concatenate_outputs(options)
|
106
|
-
pres = File.join(@outdir, "collection.presentation.xml")
|
107
|
-
options[:format].include?(:pdf) and pdfconv.convert(pres)
|
108
|
-
options[:format].include?(:doc) and docconv_convert(pres)
|
109
|
-
end
|
110
|
-
|
111
|
-
def concatenate1(out, ext)
|
112
|
-
out.directives << "documents-inline"
|
113
|
-
out.bibdatas.each_key do |ident|
|
114
|
-
id = @isodoc.docid_prefix(nil, ident.dup)
|
115
|
-
@files.get(id, :attachment) || @files.get(id, :outputs).nil? and next
|
116
|
-
out.documents[Util::key id] =
|
117
|
-
Metanorma::Document.raw_file(@files.get(id, :outputs)[ext])
|
118
|
-
end
|
119
|
-
out
|
120
|
-
end
|
121
|
-
|
122
|
-
# infer the flavour from the first document identifier; relaton does that
|
123
|
-
def doctype
|
124
|
-
if (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier/@type")&.text)
|
125
|
-
dt = docid.downcase
|
126
|
-
elsif (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier")&.text)
|
127
|
-
dt = docid.sub(/\s.*$/, "").lowercase
|
128
|
-
else return "standoc"
|
129
|
-
end
|
130
|
-
@registry = Metanorma::Registry.instance
|
131
|
-
@registry.alias(dt.to_sym)&.to_s || dt
|
132
|
-
end
|
133
|
-
|
134
|
-
# populate liquid template of ARGV[1] with metadata extracted from
|
135
|
-
# collection manifest
|
136
|
-
def coverpage
|
137
|
-
@coverpage or return
|
138
|
-
warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}"
|
139
|
-
File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
|
140
|
-
f.write @isodoc.populate_template(File.read(@coverpage))
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# @param elm [Nokogiri::XML::Element]
|
145
|
-
# @return [String]
|
146
|
-
def indexfile_title(elm)
|
147
|
-
elm.at(ns("./title"))&.text
|
148
|
-
end
|
149
|
-
|
150
|
-
# uses the identifier to label documents; other attributes (title) can be
|
151
|
-
# looked up in @files[id][:bibdata]
|
152
|
-
#
|
153
|
-
# @param elm [Nokogiri::XML::Element]
|
154
|
-
# @param builder [Nokogiri::XML::Builder]
|
155
|
-
def indexfile_docref(elm, builder)
|
156
|
-
return "" unless elm.at(ns("./docref[@index = 'true']"))
|
157
|
-
|
158
|
-
builder.ul { |b| docrefs(elm, b) }
|
159
|
-
end
|
160
|
-
|
161
|
-
# @param elm [Nokogiri::XML::Element]
|
162
|
-
# @param builder [Nokogiri::XML::Builder]
|
163
|
-
def docrefs(elm, builder)
|
164
|
-
elm.xpath(ns("./docref[@index = 'true']")).each do |d|
|
165
|
-
ident = docref_ident(d)
|
166
|
-
builder.li do |li|
|
167
|
-
li.a href: index_link(d, ident) do |a|
|
168
|
-
a << ident.split(/([<>&])/).map do |x|
|
169
|
-
/[<>&]/.match?(x) ? x : @c.encode(x, :hexadecimal)
|
170
|
-
end.join
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def docref_ident(docref)
|
177
|
-
ident = docref.at(ns("./identifier")).children.to_xml
|
178
|
-
@c.decode(@isodoc.docid_prefix(nil, ident))
|
179
|
-
end
|
180
|
-
|
181
|
-
def index_link(docref, ident)
|
182
|
-
if docref["fileref"]
|
183
|
-
@files.get(ident, :out_path).sub(/\.xml$/, ".html")
|
184
|
-
else "#{docref['id']}.html"
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
# single level navigation list, with hierarchical nesting
|
189
|
-
#
|
190
|
-
# @param elm [Nokogiri::XML::Element]
|
191
|
-
# @return [String] XML
|
192
|
-
def indexfile(elm)
|
193
|
-
Nokogiri::HTML::Builder.new do |b|
|
194
|
-
b.ul do
|
195
|
-
b.li indexfile_title(elm)
|
196
|
-
indexfile_docref(elm, b)
|
197
|
-
elm.xpath(ns("./manifest")).each do |d|
|
198
|
-
b << indexfile(d)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end.doc.root.to_html
|
202
|
-
end
|
203
|
-
|
204
|
-
# object to construct navigation out of in Liquid
|
205
|
-
def index_object(elm)
|
206
|
-
c = elm.xpath(ns("./manifest")).each_with_object([]) do |d, b|
|
207
|
-
b << index_object(d)
|
208
|
-
end
|
209
|
-
c.empty? and c = nil
|
210
|
-
r = Nokogiri::HTML::Builder.new do |b|
|
211
|
-
indexfile_docref(elm, b)
|
212
|
-
end
|
213
|
-
r &&= r.doc.root&.to_html&.gsub("\n", " ")
|
214
|
-
{ title: indexfile_title(elm),
|
215
|
-
docrefs: r, children: c }.compact
|
216
|
-
end
|
217
|
-
|
218
|
-
def liquid_docrefs
|
219
|
-
@xml.xpath(ns("//docref[@index = 'true']")).each_with_object([]) do |d, m|
|
220
|
-
ident = d.at(ns("./identifier")).children.to_xml
|
221
|
-
ident = @c.decode(@isodoc.docid_prefix(nil, ident))
|
222
|
-
title = d.at(ns("./bibdata/title[@type = 'main']")) ||
|
223
|
-
d.at(ns("./bibdata/title")) || d.at(ns("./title"))
|
224
|
-
m << { "identifier" => ident, "file" => index_link(d, ident),
|
225
|
-
"title" => title&.children&.to_xml,
|
226
|
-
"level" => d.at(ns("./level"))&.text }
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
data/lib/metanorma/document.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
class Document
|
3
|
-
# @return [Strin]
|
4
|
-
attr_reader :file, :attachment, :bibitem, :index
|
5
|
-
|
6
|
-
# @param bibitem [RelatonBib::BibliographicItem]
|
7
|
-
def initialize(bibitem, file, options = {})
|
8
|
-
@bibitem = bibitem
|
9
|
-
@file = file
|
10
|
-
@attachment = options[:attachment]
|
11
|
-
@index = options[:index]
|
12
|
-
@index = true if @index.nil?
|
13
|
-
@raw = options[:raw]
|
14
|
-
end
|
15
|
-
|
16
|
-
class << self
|
17
|
-
# @param file [String] file path
|
18
|
-
# @param attachment [Bool] is an attachment
|
19
|
-
# @param identifier [String] is the identifier assigned the file
|
20
|
-
# in the collection file
|
21
|
-
# @param index [Bool] is indication on whether to index this file in coverpage
|
22
|
-
# @return [Metanorma::Document]
|
23
|
-
def parse_file(file, attachment, identifier = nil, index = true)
|
24
|
-
new(bibitem(file, attachment, identifier), file,
|
25
|
-
{ attachment: attachment, index: index })
|
26
|
-
end
|
27
|
-
|
28
|
-
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
29
|
-
# @return [Metanorma::Document]
|
30
|
-
def parse_xml(xml)
|
31
|
-
new from_xml(xml)
|
32
|
-
end
|
33
|
-
|
34
|
-
# raw XML file, can be used to put in entire file instead of just bibitem
|
35
|
-
def raw_file(filename)
|
36
|
-
doc = Nokogiri::XML(File.read(filename, encoding: "UTF-8")) do |config|
|
37
|
-
config.huge
|
38
|
-
end
|
39
|
-
new(doc, filename, raw: true)
|
40
|
-
end
|
41
|
-
|
42
|
-
def attachment_bibitem(identifier)
|
43
|
-
Nokogiri::XML <<~DOCUMENT
|
44
|
-
<bibdata><docidentifier>#{identifier}</docidentifier></bibdata>
|
45
|
-
DOCUMENT
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def mn2relaton_parser(tag)
|
51
|
-
case tag.sub(/-standard/, "")
|
52
|
-
when "bipm" then RelatonBipm::XMLParser
|
53
|
-
when "bsi" then RelatonBsi::XMLParser
|
54
|
-
when "ietf" then RelatonIetf::XMLParser
|
55
|
-
when "iho" then RelatonIho::XMLParser
|
56
|
-
when "itu" then RelatonItu::XMLParser
|
57
|
-
when "iec" then RelatonIec::XMLParser
|
58
|
-
when "iso" then RelatonIsoBib::XMLParser
|
59
|
-
when "nist" then RelatonNist::XMLParser
|
60
|
-
when "ogc" then RelatonOgc::XMLParser
|
61
|
-
else RelatonBib::XMLParser
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
66
|
-
# @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
|
67
|
-
def from_xml(xml)
|
68
|
-
b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
|
69
|
-
r = mn2relaton_parser(xml.root.name)
|
70
|
-
r.from_xml(b.to_xml)
|
71
|
-
end
|
72
|
-
|
73
|
-
# @param file [String]
|
74
|
-
# @return [Symbol] file type
|
75
|
-
def format(file)
|
76
|
-
case file
|
77
|
-
when /\.xml$/ then :xml
|
78
|
-
when /.ya?ml$/ then :yaml
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# @param file [String]
|
83
|
-
# @return [RelatonBib::BibliographicItem,
|
84
|
-
# RelatonIso::IsoBibliographicItem]
|
85
|
-
def bibitem(file, attachment, identifier)
|
86
|
-
if attachment then attachment_bibitem(identifier)
|
87
|
-
else
|
88
|
-
case format(file)
|
89
|
-
when :xml
|
90
|
-
from_xml (Nokogiri::XML(File.read(file, encoding: "UTF-8")) { |x| x.huge })
|
91
|
-
when :yaml
|
92
|
-
yaml = File.read(file, encoding: "UTF-8")
|
93
|
-
Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# @param builder [Nokogiri::XML::Builder, nil]
|
100
|
-
# @return [Nokogiri::XML::Builder, String]
|
101
|
-
def to_xml(builder = nil)
|
102
|
-
if builder
|
103
|
-
render_xml builder
|
104
|
-
else
|
105
|
-
Nokogiri::XML::Builder.new do |b|
|
106
|
-
root = render_xml b
|
107
|
-
root["xmlns"] = "http://metanorma.org"
|
108
|
-
end.to_xml
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# @return [String]
|
113
|
-
def type
|
114
|
-
first = @bibitem.docidentifier.first
|
115
|
-
@type ||= (first&.type&.downcase ||
|
116
|
-
first&.id&.match(/^[^\s]+/)&.to_s)&.downcase ||
|
117
|
-
"standoc"
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def render_xml(builder)
|
123
|
-
if @raw
|
124
|
-
#builder << @bibitem.root.to_xml
|
125
|
-
builder.parent.add_child(@bibitem.root)
|
126
|
-
else
|
127
|
-
builder.send("#{type}-standard") do |b|
|
128
|
-
b << @bibitem.to_xml(bibdata: true)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|