Class: Metanorma::CollectionRenderer
- Inherits:
-
Object
- Object
- Metanorma::CollectionRenderer
show all
- Defined in:
- lib/metanorma/collection_renderer.rb,
lib/metanorma/collection_fileparse.rb,
lib/metanorma/collection_fileprocess.rb
Overview
Defined Under Namespace
Classes: Dummy, PdfOptionsNode
Constant Summary
collapse
- FORMATS =
%i[html xml doc pdf].freeze
Class Method Summary
collapse
Instance Method Summary
collapse
-
#add_document_suffix(identifier, doc) ⇒ Object
-
#add_section_split(files) ⇒ Object
-
#add_section_split_cover(files, manifest, ident) ⇒ Object
-
#add_section_split_instance(file, manifest, key, idx, files) ⇒ Object
-
#add_suffix_to_attributes(doc, suffix, tag_name, attribute_name) ⇒ Object
-
#compile_options(identifier) ⇒ Object
-
#concatenate(col, options) ⇒ Object
-
#copy_file_to_dest(fileref) ⇒ Object
-
#coverpage ⇒ Object
populate liquid template of ARGV with metadata extracted from collection manifest.
-
#datauri_encode(docxml) ⇒ Object
-
#docrefs(elm, builder) ⇒ Object
-
#doctype ⇒ Object
infer the flavour from the first document identifier; relaton does that.
-
#dup_bibitem(docid, bib) ⇒ Object
-
#fail_update_bibitem(docid, identifier) ⇒ Object
-
#file_compile(file, filename, identifier) ⇒ Object
compile and output individual file in collection warn “metanorma compile -x html #ff.path”.
-
#file_compile_formats(file, filename, identifier) ⇒ Object
-
#file_entry(ref, identifier, _path) ⇒ Object
rel_path is the source file address, determined relative to the YAML.
-
#file_sectionsplit_copy(file, base, identifier, ext, format) ⇒ Object
-
#files ⇒ Object
process each file in the collection files are held in memory, and altered as postprocessing.
-
#gather_internal_refs ⇒ Object
gather internal bibitem references.
-
#index_link(docref, ident) ⇒ Object
-
#indexfile(elm) ⇒ String
single level navigation list, with hierarchical nesting if multiple lists are needed as separate HTML fragments, multiple instances of this function will be needed, and associated to different variables in the call to @isodoc.metadata_init (including possibly an array of HTML fragments).
-
#indexfile_docref(elm, builder) ⇒ Object
uses the identifier to label documents; other attributes (title) can be looked up in @files[:bibdata].
-
#indexfile_title(elm) ⇒ String
-
#initialize(collection, folder, options = {}) ⇒ CollectionRenderer
constructor
This is only going to render the HTML collection We presuppose that the bibdata of the document is equivalent to that of the collection, and that the flavour gem can sensibly process it.
-
#isodoc ⇒ Object
The isodoc class for the metanorma flavour we are using.
-
#isodoc_populate(isodoc) ⇒ Object
-
#locate_internal_refs ⇒ Object
resolve file location for the target of each internal reference.
-
#locate_internal_refs1(refs, identifier, filedesc) ⇒ Object
-
#ns(xpath) ⇒ Object
-
#pdfconv ⇒ Object
-
#read_anchors(xml) ⇒ Object
map locality type and label (e.g. “clause” “1”) to id = anchor for a document Note: will only key clauses, which have unambiguous reference label in locality.
-
#read_anchors1(key, val, ret) ⇒ Object
-
#read_files(path) ⇒ Hash{String=>Hash}
hash for each document in collection of document identifier to: document reference (fileref or id), type of document reference, and bibdata entry for that file.
-
#ref_file(ref, out, read, doc) ⇒ Array<String, nil>
-
#section_split_cover(col, ident) ⇒ Object
-
#sectionsplit(file) ⇒ Object
-
#svgmap_resolve(docxml) ⇒ Object
-
#targetfile(data, options) ⇒ Array<String, nil>
return file contents + output filename for each file in the collection, given a docref entry so my URL should end with html or pdf or whatever formed relative to YAML file, not input path, relative to calling function.
-
#update_anchor_create_loc(_bib, eref, docid) ⇒ Object
if there is a crossref to another document, with no anchor, retrieve the anchor given the locality, and insert it into the crossref.
-
#update_anchor_loc(bib, eref, docid) ⇒ Object
-
#update_anchors(bib, docxml, docid) ⇒ Object
update crossrefences to other documents, to include disambiguating document suffix on id.
-
#update_bibitem(bib, identifier) ⇒ Object
-
#update_direct_refs_to_docs(docxml, identifier) ⇒ Object
repo(current-metanorma-collection/ISO 17301-1:2016) replaced by bibdata of “ISO 17301-1:2016” in situ as bibitem.
-
#update_indirect_refs_to_docs(docxml, internal_refs) ⇒ Object
Resolve erefs to a container of ids in another doc, to an anchor eref (direct link).
-
#update_indirect_refs_to_docs1(docxml, schema, id, file) ⇒ Object
-
#update_xrefs(file, identifier, internal_refs) ⇒ String
Resolves direct links to other files in collection (repo(current-metanorma-collection/x), and indirect links to other files in collection (bibitem[@type = ‘internal’] pointing to a file anchor in another file in the collection).
-
#xml_file(id, read) ⇒ Array<String, nil>
Constructor Details
#initialize(collection, folder, options = {}) ⇒ CollectionRenderer
This is only going to render the HTML collection We presuppose that the bibdata of the document is equivalent to that of the collection, and that the flavour gem can sensibly process it. We may need to enhance metadata in the flavour gems isodoc/metadata.rb with collection metadata
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/metanorma/collection_renderer.rb', line 25
def initialize(collection, folder, options = {}) check_options options
@xml = Nokogiri::XML collection.to_xml @lang = @xml&.at(ns("//bibdata/language"))&.text || "en"
@script = @xml&.at(ns("//bibdata/script"))&.text || "Latn"
@doctype = doctype
require "metanorma-#{@doctype}"
@isodoc = isodoc
@outdir = options[:output_folder]
@coverpage = options[:coverpage]
@format = Util.sort_extensions_execution(options[:format])
@compile_options = options[:compile] || {}
@compile_options[:no_install_fonts] = true if options[:no_install_fonts]
@log = options[:log]
@documents = collection.documents
@directives = collection.directives
@disambig = Util::DisambigFiles.new
@compile = Compile.new
@files = read_files folder
isodoc_populate(@isodoc)
FileUtils.rm_rf @outdir
FileUtils.mkdir_p @outdir
end
|
Class Method Details
.render(col, options = {}) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/metanorma/collection_renderer.rb', line 59
def self.render(col, options = {})
folder = File.dirname col.file
warn "\n\n\n\n\nRender Init: #{DateTime.now.strftime('%H:%M:%S')}"
cr = new(col, folder, options)
warn "\n\n\n\n\nRender Files: #{DateTime.now.strftime('%H:%M:%S')}"
cr.files
warn "\n\n\n\n\nConcatenate: #{DateTime.now.strftime('%H:%M:%S')}"
cr.concatenate(col, options)
warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}"
cr.coverpage if options[:format]&.include?(:html)
warn "\n\n\n\n\nDone: #{DateTime.now.strftime('%H:%M:%S')}"
end
|
Instance Method Details
#add_document_suffix(identifier, doc) ⇒ Object
122
123
124
125
126
127
128
129
130
|
# File 'lib/metanorma/collection_fileprocess.rb', line 122
def add_document_suffix(identifier, doc)
document_suffix = Metanorma::Utils::to_ncname(identifier)
[%w[* id], %w[* bibitemid], %w[review from],
%w[review to], %w[index to], %w[xref target],
%w[callout target]]
.each do |(tag_name, attribute_name)|
add_suffix_to_attributes(doc, document_suffix, tag_name, attribute_name)
end
end
|
#add_section_split(files) ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/metanorma/collection_fileprocess.rb', line 38
def add_section_split(files)
files.keys.each_with_object({}) do |k, m|
if files[k][:sectionsplit] == "true" && !files[k]["attachment"]
s, manifest = sectionsplit(files[k][:ref])
s.each_with_index do |f1, i|
add_section_split_instance(f1, m, k, i, files)
end
m["#{k}:index.html"] = add_section_split_cover(files, manifest, k)
end
m[k] = files[k]
end
end
|
#add_section_split_cover(files, manifest, ident) ⇒ Object
51
52
53
54
55
56
|
# File 'lib/metanorma/collection_fileprocess.rb', line 51
def add_section_split_cover(files, manifest, ident)
cover = section_split_cover(manifest, ident)
files[ident][:out_path] = cover
{ attachment: true, index: false, out_path: cover,
ref: File.join(File.dirname(manifest.file), cover) }
end
|
#add_section_split_instance(file, manifest, key, idx, files) ⇒ Object
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/metanorma/collection_fileprocess.rb', line 71
def add_section_split_instance(file, manifest, key, idx, files)
dir = File.dirname(files[key][:ref])
presfile = File.join(dir, File.basename(file[:url]))
manifest["#{key} #{file[:title]}"] =
{ parentid: key, presentationxml: true, type: "fileref",
rel_path: file[:url], out_path: File.basename(file[:url]),
anchors: read_anchors(Nokogiri::XML(File.read(presfile))),
bibdata: files[key][:bibdata], ref: presfile }
manifest["#{key} #{file[:title]}"][:bare] = true unless idx.zero?
end
|
#add_suffix_to_attributes(doc, suffix, tag_name, attribute_name) ⇒ Object
115
116
117
118
119
120
|
# File 'lib/metanorma/collection_fileprocess.rb', line 115
def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
elem.attributes[attribute_name].value =
"#{elem.attributes[attribute_name].value}_#{suffix}"
end
end
|
#compile_options(identifier) ⇒ Object
173
174
175
176
177
178
179
180
181
182
183
|
# File 'lib/metanorma/collection_fileprocess.rb', line 173
def compile_options(identifier)
ret = @compile_options.dup
Array(@directives).include?("presentation-xml") ||
@files[identifier][:presentationxml] and
ret.merge!(passthrough_presentation_xml: true)
@files[identifier][:sectionsplit] == "true" and
ret.merge!(sectionsplit: "true")
@files[identifier][:bare] == true and
ret.merge!(bare: true)
ret
end
|
#concatenate(col, options) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/metanorma/collection_renderer.rb', line 73
def concatenate(col, options)
options[:format] << :presentation if options[:format].include?(:pdf)
options[:format].uniq.each do |e|
next unless %i(presentation xml).include?(e)
ext = e == :presentation ? "presentation.xml" : e.to_s
out = col.clone
out.directives << "documents-inline"
out.documents.each_key do |id|
next if @files[id][:attachment] || @files[id][:outputs].nil?
filename = @files[id][:outputs][e]
out.documents[id] = Metanorma::Document.raw_file(filename)
end
File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") do |f|
f.write(out.to_xml)
end
end
options[:format].include?(:pdf) and
pdfconv.convert(File.join(@outdir, "collection.presentation.xml"))
end
|
#copy_file_to_dest(fileref) ⇒ Object
208
209
210
211
212
|
# File 'lib/metanorma/collection_fileprocess.rb', line 208
def copy_file_to_dest(fileref)
dest = File.join(@outdir, fileref[:out_path])
FileUtils.mkdir_p(File.dirname(dest))
FileUtils.cp fileref[:ref], dest
end
|
#coverpage ⇒ Object
populate liquid template of ARGV with metadata extracted from collection manifest
160
161
162
163
164
165
166
|
# File 'lib/metanorma/collection_renderer.rb', line 160
def coverpage
return unless @coverpage
File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
f.write @isodoc.populate_template(File.read(@coverpage))
end
end
|
#datauri_encode(docxml) ⇒ Object
92
93
94
95
96
97
|
# File 'lib/metanorma/collection_fileparse.rb', line 92
def datauri_encode(docxml)
docxml.xpath(ns("//image")).each do |i|
i["src"] = Metanorma::Utils::datauri(i["src"])
end
docxml
end
|
#docrefs(elm, builder) ⇒ Object
189
190
191
192
193
194
195
196
197
198
|
# File 'lib/metanorma/collection_renderer.rb', line 189
def docrefs(elm, builder)
elm.xpath(ns("./docref[@index = 'true']")).each do |d|
ident = d.at(ns("./identifier")).children.to_xml
builder.li do |li|
li.a **{ href: index_link(d, ident) } do |a|
a << ident
end
end
end
end
|
#doctype ⇒ Object
infer the flavour from the first document identifier; relaton does that
143
144
145
146
147
148
149
150
151
152
|
# File 'lib/metanorma/collection_renderer.rb', line 143
def doctype
if (docid = @xml&.at(ns("//bibdata/docidentifier/@type"))&.text)
dt = docid.downcase
elsif (docid = @xml&.at(ns("//bibdata/docidentifier"))&.text)
dt = docid.sub(/\s.*$/, "").lowercase
else return "standoc"
end
@registry = Metanorma::Registry.instance
@registry.alias(dt.to_sym)&.to_s || dt
end
|
#dup_bibitem(docid, bib) ⇒ Object
61
62
63
64
65
66
67
68
|
# File 'lib/metanorma/collection_fileparse.rb', line 61
def dup_bibitem(docid, bib)
newbib = @files[docid][:bibdata].dup
newbib.name = "bibitem"
newbib["hidden"] = "true"
newbib&.at("./*[local-name() = 'ext']")&.remove
newbib["id"] = bib["id"]
newbib
end
|
#fail_update_bibitem(docid, identifier) ⇒ Object
54
55
56
57
58
59
|
# File 'lib/metanorma/collection_fileparse.rb', line 54
def fail_update_bibitem(docid, identifier)
error = "[metanorma] Cannot find crossreference to document #{docid} "\
"in document #{identifier}."
@log.add("Cross-References", nil, error)
Util.log(error, :warning)
end
|
#file_compile(file, filename, identifier) ⇒ Object
compile and output individual file in collection warn “metanorma compile -x html #Metanorma::CollectionRenderer.ff.path”
164
165
166
167
168
169
170
171
|
# File 'lib/metanorma/collection_fileprocess.rb', line 164
def file_compile(file, filename, identifier)
return if @files[identifier][:sectionsplit] == "true"
@compile.compile file.path, { format: :asciidoc, extension_keys: @format }
.merge(compile_options(identifier))
@files[identifier][:outputs] = {}
file_compile_formats(file, filename, identifier)
end
|
185
186
187
188
189
190
191
192
193
194
195
196
197
|
# File 'lib/metanorma/collection_fileprocess.rb', line 185
def file_compile_formats(file, filename, identifier)
@format.each do |e|
ext = @compile.processor.output_formats[e]
fn = File.basename(filename).sub(/(?<=\.)[^.]+$/, ext.to_s)
if /html$/.match?(ext) && @files[identifier][:sectionsplit]
else
FileUtils.cp file.path.sub(/\.xml$/, ".#{ext}"),
File.join(@outdir, fn)
@files[identifier][:outputs][e] = File.join(@outdir, fn)
end
end
end
|
#file_entry(ref, identifier, _path) ⇒ Object
rel_path is the source file address, determined relative to the YAML. out_path is the destination file address, with any references outside the working directory (../../…) truncated
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
# File 'lib/metanorma/collection_fileprocess.rb', line 98
def file_entry(ref, identifier, _path)
out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
ret = if ref["fileref"]
{ type: "fileref", ref: @documents[identifier].file,
rel_path: ref["fileref"],
out_path: out }
else
{ type: "id", ref: ref["id"] }
end
%i(attachment sectionsplit index).each do |s|
ret[s] = ref[s.to_s] if ref[s.to_s]
end
ret[:presentationxml] = ref["presentation-xml"] if ref["presentation-xml"]
ret[:bareafterfirst] = ref["bare-after-first"] if ref["bare-after-first"]
ret
end
|
#file_sectionsplit_copy(file, base, identifier, ext, format) ⇒ Object
199
200
201
202
203
204
205
206
|
# File 'lib/metanorma/collection_fileprocess.rb', line 199
def file_sectionsplit_copy(file, base, identifier, ext, format)
dir = file.path.sub(/\.xml$/, ".#{ext}_collection")
files = Dir.glob("#{dir}/*.#{ext}")
FileUtils.cp files, @outdir
cover = File.join(@outdir, base.sub(/\.html$/, ".index.html"))
FileUtils.cp File.join(dir, "index.html"), cover
@files[identifier][:outputs][format] = cover
end
|
#files ⇒ Object
process each file in the collection files are held in memory, and altered as postprocessing
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
# File 'lib/metanorma/collection_fileprocess.rb', line 216
def files warn "\n\n\n\n\nInternal Refs: #{DateTime.now.strftime('%H:%M:%S')}"
internal_refs = locate_internal_refs
@files.each_with_index do |(identifier, x), i|
i.positive? && Array(@directives).include?("bare-after-first") and
@compile_options.merge!(bare: true)
if x[:attachment] then copy_file_to_dest(x)
else
file, filename = targetfile(x, read: true)
warn "\n\n\n\n\nProcess #{filename}: #{DateTime.now.strftime('%H:%M:%S')}"
file = update_xrefs(file, identifier, internal_refs)
Tempfile.open(["collection", ".xml"], encoding: "utf-8") do |f|
f.write(file)
f.close
file_compile(f, filename, identifier)
end
end
end
end
|
#gather_internal_refs ⇒ Object
gather internal bibitem references
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# File 'lib/metanorma/collection_fileparse.rb', line 195
def gather_internal_refs
@files.each_with_object({}) do |(_, x), refs|
next if x[:attachment]
file, = targetfile(x, read: true)
Nokogiri::XML(file)
.xpath(ns("//bibitem[@type = 'internal']/"\
"docidentifier[@type = 'repository']")).each do |d|
a = d.text.split(%r{/}, 2)
a.size > 1 or next
refs[a[0]] ||= {}
refs[a[0]][a[1]] = true
end
end
end
|
#index_link(docref, ident) ⇒ Object
200
201
202
203
204
205
|
# File 'lib/metanorma/collection_renderer.rb', line 200
def index_link(docref, ident)
if docref["fileref"]
@files[ident][:out_path].sub(/\.xml$/, ".html")
else "#{docref['id']}.html"
end
end
|
#indexfile(elm) ⇒ String
single level navigation list, with hierarchical nesting if multiple lists are needed as separate HTML fragments, multiple instances of this function will be needed, and associated to different variables in the call to @isodoc.metadata_init (including possibly an array of HTML fragments)
215
216
217
218
219
220
221
222
223
224
225
|
# File 'lib/metanorma/collection_renderer.rb', line 215
def indexfile(elm)
Nokogiri::HTML::Builder.new do |b|
b.ul do
b.li indexfile_title(elm)
indexfile_docref(elm, b)
elm.xpath(ns("./manifest")).each do |d|
b << indexfile(d)
end
end
end.doc.root.to_html
end
|
#indexfile_docref(elm, builder) ⇒ Object
uses the identifier to label documents; other attributes (title) can be looked up in @files[:bibdata]
181
182
183
184
185
|
# File 'lib/metanorma/collection_renderer.rb', line 181
def indexfile_docref(elm, builder)
return "" unless elm.at(ns("./docref[@index = 'true']"))
builder.ul { |b| docrefs(elm, b) }
end
|
#indexfile_title(elm) ⇒ String
170
171
172
173
174
|
# File 'lib/metanorma/collection_renderer.rb', line 170
def indexfile_title(elm)
lvl = elm&.at(ns("./level"))&.text&.capitalize
lbl = elm&.at(ns("./title"))&.text
"#{lvl}#{lvl && lbl ? ': ' : ''}#{lbl}"
end
|
#isodoc ⇒ Object
The isodoc class for the metanorma flavour we are using
120
121
122
123
124
125
126
127
|
# File 'lib/metanorma/collection_renderer.rb', line 120
def isodoc
x = Asciidoctor.load nil, backend: @doctype.to_sym
isodoc = x.converter.html_converter(Dummy.new)
isodoc.i18n_init(@lang, @script) isodoc.metadata_init(@lang, @script, isodoc.i18n)
isodoc.info(@xml, nil)
isodoc
end
|
#isodoc_populate(isodoc) ⇒ Object
129
130
131
132
133
134
135
136
137
138
139
140
|
# File 'lib/metanorma/collection_renderer.rb', line 129
def isodoc_populate(isodoc)
nav = indexfile(@xml.at(ns("//manifest")))
i18n = isodoc.i18n
i18n.set("navigation", nav)
isodoc.metadata_init(@lang, @script, i18n)
isodoc.info(@xml, nil)
isodoc
end
|
#locate_internal_refs ⇒ Object
resolve file location for the target of each internal reference
212
213
214
215
216
217
218
219
220
221
222
223
|
# File 'lib/metanorma/collection_fileparse.rb', line 212
def locate_internal_refs
refs = gather_internal_refs
@files.keys.reject { |k| @files[k][:attachment] }.each do |identifier|
locate_internal_refs1(refs, identifier, @files[identifier])
end
refs.each do |schema, ids|
ids.each do |id, key|
key == true and refs[schema][id] = "Missing:#{schema}:#{id}"
end
end
refs
end
|
#locate_internal_refs1(refs, identifier, filedesc) ⇒ Object
225
226
227
228
229
230
231
232
233
234
235
236
|
# File 'lib/metanorma/collection_fileparse.rb', line 225
def locate_internal_refs1(refs, identifier, filedesc)
file, _filename = targetfile(filedesc, read: true)
xml = Nokogiri::XML(file) { |config| config.huge }
t = xml.xpath("//*/@id").each_with_object({}) { |i, x| x[i.text] = true }
refs.each do |schema, ids|
ids.keys.select { |id| t[id] }.each do |id|
n = xml.at("//*[@id = '#{id}']") and
n.at("./ancestor-or-self::*[@type = '#{schema}']") and
refs[schema][id] = identifier
end
end
end
|
#ns(xpath) ⇒ Object
154
155
156
|
# File 'lib/metanorma/collection_renderer.rb', line 154
def ns(xpath)
IsoDoc::Convert.new({}).ns(xpath)
end
|
#pdfconv ⇒ Object
95
96
97
98
99
|
# File 'lib/metanorma/collection_renderer.rb', line 95
def pdfconv
doctype = @doctype.to_sym
x = Asciidoctor.load nil, backend: doctype
x.converter.pdf_converter(PdfOptionsNode.new(doctype, @compile_options))
end
|
#read_anchors(xml) ⇒ Object
map locality type and label (e.g. “clause” “1”) to id = anchor for a document Note: will only key clauses, which have unambiguous reference label in locality. Notes, examples etc with containers are just plunked against UUIDs, so that their IDs can at least be registered to be tracked as existing.
10
11
12
13
14
15
16
|
# File 'lib/metanorma/collection_fileparse.rb', line 10
def read_anchors(xml)
xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
xrefs.parse xml
xrefs.get.each_with_object({}) do |(k, v), ret|
read_anchors1(k, v, ret)
end
end
|
#read_anchors1(key, val, ret) ⇒ Object
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/metanorma/collection_fileparse.rb', line 18
def read_anchors1(key, val, ret)
val[:type] ||= "clause"
ret[val[:type]] ||= {}
index = if val[:container] || val[:label].nil? || val[:label].empty?
UUIDTools::UUID.random_create.to_s
else val[:label]
end
ret[val[:type]][index] = key
ret[val[:type]][val[:value]] = key if val[:value]
end
|
#read_files(path) ⇒ Hash{String=>Hash}
hash for each document in collection of document identifier to: document reference (fileref or id), type of document reference, and bibdata entry for that file
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# File 'lib/metanorma/collection_fileprocess.rb', line 15
def read_files(path) files = {}
@xml.xpath(ns("//docref")).each do |d|
identifier = d.at(ns("./identifier")).children.to_xml
files[identifier] = file_entry(d, identifier, path)
if files[identifier][:attachment]
files[identifier][:bibdata] = Metanorma::Document
.attachment_bibitem(identifier).root
else
file, _filename = targetfile(files[identifier], read: true)
xml = Nokogiri::XML(file)
add_document_suffix(identifier, xml)
files[identifier][:anchors] = read_anchors(xml)
files[identifier][:bibdata] = xml.at(ns("//bibdata"))
end
files[identifier][:bibitem] = files[identifier][:bibdata].dup
files[identifier][:bibitem].name = "bibitem"
files[identifier][:bibitem]["hidden"] = "true"
files[identifier][:bibitem]&.at("./*[local-name() = 'ext']")&.remove
end
add_section_split(files)
end
|
#ref_file(ref, out, read, doc) ⇒ Array<String, nil>
155
156
157
158
159
160
|
# File 'lib/metanorma/collection_fileprocess.rb', line 155
def ref_file(ref, out, read, doc)
file = File.read(ref, encoding: "utf-8") if read
filename = out.dup
filename.sub!(/\.xml$/, ".html") if doc
[file, filename]
end
|
#section_split_cover(col, ident) ⇒ Object
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/metanorma/collection_fileprocess.rb', line 58
def section_split_cover(col, ident)
dir = File.dirname(col.file)
@compile.collection_setup(nil, dir)
CollectionRenderer.new(col, dir,
output_folder: "#{ident}_collection",
format: %i(html),
coverpage: File.join(dir, "cover.html")).coverpage
FileUtils.mv "#{ident}_collection/index.html",
File.join(dir, "#{ident}_index.html")
FileUtils.rm_rf "#{ident}_collection"
"#{ident}_index.html"
end
|
#sectionsplit(file) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/metanorma/collection_fileprocess.rb', line 82
def sectionsplit(file)
@compile.compile(
file, { format: :asciidoc, extension_keys: [:presentation] }
.merge(@compile_options)
)
r = file.sub(/\.xml$/, ".presentation.xml")
xml = Nokogiri::XML(File.read(r))
s = @compile.sectionsplit(xml, File.basename(r), File.dirname(r))
.sort_by { |f| f[:order] }
[s, @compile.collection_manifest(File.basename(r), s, xml, nil,
File.dirname(r))]
end
|
#svgmap_resolve(docxml) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/metanorma/collection_fileparse.rb', line 99
def svgmap_resolve(docxml)
isodoc = IsoDoc::Convert.new({})
docxml.xpath(ns("//svgmap//eref")).each do |e|
href = isodoc.eref_target(e)
next if href == "##{e['bibitemid']}" ||
href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
e["target"] = href.strip
e.name = "link"
e&.elements&.remove
end
Metanorma::Utils::svgmap_rewrite(docxml, "")
end
|
#targetfile(data, options) ⇒ Array<String, nil>
return file contents + output filename for each file in the collection, given a docref entry so my URL should end with html or pdf or whatever formed relative to YAML file, not input path, relative to calling function
141
142
143
144
145
146
147
148
149
|
# File 'lib/metanorma/collection_fileprocess.rb', line 141
def targetfile(data, options)
options = { read: false, doc: true, relative: false }.merge(options)
path = options[:relative] ? data[:rel_path] : data[:ref]
if data[:type] == "fileref"
ref_file path, data[:out_path], options[:read], options[:doc]
else
xml_file data[:id], options[:read]
end
end
|
#update_anchor_create_loc(_bib, eref, docid) ⇒ Object
if there is a crossref to another document, with no anchor, retrieve the anchor given the locality, and insert it into the crossref
184
185
186
187
188
189
190
191
192
|
# File 'lib/metanorma/collection_fileparse.rb', line 184
def update_anchor_create_loc(_bib, eref, docid)
ins = eref.at(ns("./localityStack")) or return
type = ins&.at(ns("./locality/@type"))&.text
type = "clause" if type == "annex"
ref = ins&.at(ns("./locality/referenceFrom"))&.text
anchor = @files[docid][:anchors].dig(type, ref) or return
ins << "<locality type='anchor'><referenceFrom>#{anchor.sub(/^_/, '')}"\
"</referenceFrom></locality>"
end
|
#update_anchor_loc(bib, eref, docid) ⇒ Object
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/metanorma/collection_fileparse.rb', line 169
def update_anchor_loc(bib, eref, docid)
loc = eref.at(ns(".//locality[@type = 'anchor']")) or
return update_anchor_create_loc(bib, eref, docid)
document_suffix = Metanorma::Utils::to_ncname(docid)
ref = loc.at(ns("./referenceFrom")) || return
anchor = "#{ref.text}_#{document_suffix}"
return unless @files[docid][:anchors].inject([]) do |m, (_, x)|
m += x.values
end.include?(anchor)
ref.content = anchor
end
|
#update_anchors(bib, docxml, docid) ⇒ Object
update crossrefences to other documents, to include disambiguating document suffix on id
159
160
161
162
163
164
165
166
167
|
# File 'lib/metanorma/collection_fileparse.rb', line 159
def update_anchors(bib, docxml, docid) docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
if @files[docid] then update_anchor_loc(bib, e, docid)
else
e << "<strong>** Unresolved reference to document #{docid} "\
"from eref</strong>"
end
end
end
|
#update_bibitem(bib, identifier) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/metanorma/collection_fileparse.rb', line 40
def update_bibitem(bib, identifier) docid = bib&.at(ns("./docidentifier"))&.children&.to_xml
return fail_update_bibitem(docid, identifier) unless @files[docid]
newbib = dup_bibitem(docid, bib)
bib.replace(newbib)
_file, url = targetfile(@files[docid], relative: true, read: false,
doc: !@files[docid][:attachment])
uri_node = Nokogiri::XML::Node.new "uri", newbib
uri_node[:type] = "citation"
uri_node.content = url
newbib.at(ns("./docidentifier")).previous = uri_node
end
|
#update_direct_refs_to_docs(docxml, identifier) ⇒ Object
repo(current-metanorma-collection/ISO 17301-1:2016) replaced by bibdata of “ISO 17301-1:2016” in situ as bibitem. Any erefs to that bibitem id are replaced with relative URL Preferably with anchor, and is a job to realise dynamic lookup of localities.
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/metanorma/collection_fileparse.rb', line 118
def update_direct_refs_to_docs(docxml, identifier)
erefs = docxml.xpath(ns("//eref"))
.each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
m[:citeas][i["citeas"]] = true
m[:bibitemid][i["bibitemid"]] = true
end
docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
next unless docid && %r{^current-metanorma-collection/}.match(docid)
update_bibitem(b, identifier)
docid = b&.at(ns("./docidentifier"))&.children&.to_xml or next
erefs[:citeas][docid] and update_anchors(b, docxml, docid)
end
end
|
#update_indirect_refs_to_docs(docxml, internal_refs) ⇒ Object
Resolve erefs to a container of ids in another doc, to an anchor eref (direct link)
136
137
138
139
140
141
142
|
# File 'lib/metanorma/collection_fileparse.rb', line 136
def update_indirect_refs_to_docs(docxml, internal_refs)
internal_refs.each do |schema, ids|
ids.each do |id, file|
update_indirect_refs_to_docs1(docxml, schema, id, file)
end
end
end
|
#update_indirect_refs_to_docs1(docxml, schema, id, file) ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/metanorma/collection_fileparse.rb', line 144
def update_indirect_refs_to_docs1(docxml, schema, id, file)
docxml.xpath(ns("//eref[@bibitemid = '#{schema}_#{id}']")).each do |e|
e["citeas"] = file
if a = e.at(ns(".//locality[@type = 'anchor']/referenceFrom"))
a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
end
end
docid = docxml.at(ns("//bibitem[@id = '#{schema}_#{id}']/"\
"docidentifier[@type = 'repository']")) or return
docid.children = "current-metanorma-collection/#{file}"
docid.previous = "<docidentifier type='X'>#{file}</docidentifier>"
end
|
#update_xrefs(file, identifier, internal_refs) ⇒ String
Resolves direct links to other files in collection (repo(current-metanorma-collection/x), and indirect links to other files in collection (bibitem[@type = ‘internal’] pointing to a file anchor in another file in the collection)
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/metanorma/collection_fileparse.rb', line 79
def update_xrefs(file, identifier, internal_refs)
docxml = Nokogiri::XML(file) { |config| config.huge }
update_indirect_refs_to_docs(docxml, internal_refs)
add_document_suffix(identifier, docxml)
update_direct_refs_to_docs(docxml, identifier)
svgmap_resolve(datauri_encode(docxml))
docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or "\
"@hidden = 'false'])]")).each do |f|
f["hidden"] = "true"
end
docxml.to_xml
end
|
#xml_file(id, read) ⇒ Array<String, nil>
32
33
34
35
36
|
# File 'lib/metanorma/collection_fileparse.rb', line 32
def xml_file(id, read)
file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
filename = "#{id}.html"
[file, filename]
end
|