metanorma 1.7.6 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|