Class: Metanorma::CollectionRenderer
- Inherits:
-
Object
- Object
- Metanorma::CollectionRenderer
- Defined in:
- lib/metanorma/collection_renderer.rb,
lib/metanorma/collection_fileparse.rb,
lib/metanorma/collection_fileprocess.rb
Overview
XML collection renderer
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
- #collect_erefs(docxml) ⇒ Object
- #compile_options(identifier) ⇒ Object
- #concatenate(col, options) ⇒ Object
- #concatenate1(out, ext) ⇒ Object
- #copy_file_to_dest(fileref) ⇒ Object
-
#coverpage ⇒ Object
populate liquid template of ARGV with metadata extracted from collection manifest.
- #datauri_encode(docxml) ⇒ Object
- #dir_name_cleanse(name) ⇒ 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(filename, identifier) ⇒ Object
-
#file_entry(ref, identifier, _path) ⇒ Object
rel_path is the source file address, determined relative to the YAML.
-
#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.
- #hide_refs(docxml) ⇒ Object
- #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
- #supply_repo_ids(docxml) ⇒ Object
- #svgmap_resolve(docxml) ⇒ Object
- #svgmap_resolve1(eref, isodoc) ⇒ 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, = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength @xml = Nokogiri::XML collection.to_xml # @xml is the collection manifest @lang = @xml&.at(ns("//bibdata/language"))&.text || "en" @script = @xml&.at(ns("//bibdata/script"))&.text || "Latn" @doctype = doctype require "metanorma-#{@doctype}" # output processor for flavour @isodoc = isodoc @outdir = dir_name_cleanse([:output_folder]) @coverpage = [:coverpage] @format = Util.sort_extensions_execution([:format]) @compile_options = [:compile] || {} @compile_options[:no_install_fonts] = true if [:no_install_fonts] @log = [:log] @documents = collection.documents @directives = collection.directives @disambig = Util::DisambigFiles.new @compile = Compile.new # list of files in the collection @files = read_files folder isodoc_populate(@isodoc) FileUtils.rm_rf @outdir FileUtils.mkdir_p @outdir end |
Class Method Details
.render(col, options = {}) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/metanorma/collection_renderer.rb', line 69 def self.render(col, = {}) folder = File.dirname col.file warn "\n\n\n\n\nRender Init: #{DateTime.now.strftime('%H:%M:%S')}" cr = new(col, folder, ) 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, ) warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}" cr.coverpage if [: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
120 121 122 123 124 125 126 127 128 |
# File 'lib/metanorma/collection_fileprocess.rb', line 120 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, dir_name_cleanse(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) presfile = File.join(File.dirname(files[key][:ref]), 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
113 114 115 116 117 118 |
# File 'lib/metanorma/collection_fileprocess.rb', line 113 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 |
#collect_erefs(docxml) ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/metanorma/collection_fileparse.rb', line 153 def collect_erefs(docxml) docxml.xpath(ns("//eref")) .each_with_object({ citeas: {}, bibitemid: {} }) do |i, m| m[:citeas][i["citeas"]] = true m[:bibitemid][i["bibitemid"]] = true end end |
#compile_options(identifier) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/metanorma/collection_fileprocess.rb', line 176 def (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
82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/metanorma/collection_renderer.rb', line 82 def concatenate(col, ) [:format] << :presentation if [:format].include?(:pdf) [:format].uniq.each do |e| next unless %i(presentation xml).include?(e) ext = e == :presentation ? "presentation.xml" : e.to_s File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") do |f| f.write(concatenate1(col.clone, e).to_xml) end end [:format].include?(:pdf) and pdfconv.convert(File.join(@outdir, "collection.presentation.xml")) end |
#concatenate1(out, ext) ⇒ Object
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/metanorma/collection_renderer.rb', line 96 def concatenate1(out, ext) out.directives << "documents-inline" out.documents.each_key do |id| next if @files[id][:attachment] || @files[id][:outputs].nil? out.documents[id] = Metanorma::Document.raw_file(@files[id][:outputs][ext]) end out end |
#copy_file_to_dest(fileref) ⇒ Object
200 201 202 203 204 |
# File 'lib/metanorma/collection_fileprocess.rb', line 200 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
174 175 176 177 178 179 180 |
# File 'lib/metanorma/collection_renderer.rb', line 174 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
110 111 112 113 114 115 |
# File 'lib/metanorma/collection_fileparse.rb', line 110 def datauri_encode(docxml) docxml.xpath(ns("//image")).each do |i| i["src"] = Metanorma::Utils::datauri(i["src"]) end docxml end |
#dir_name_cleanse(name) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/metanorma/collection_renderer.rb', line 54 def dir_name_cleanse(name) path = Pathname.new(name) clean_regex = /[<>:"|?*]/ fallback_sym = "_" return name.gsub(clean_regex, fallback_sym) unless path.absolute? File.join(path.dirname, path.basename.to_s.gsub(clean_regex, fallback_sym)) end |
#docrefs(elm, builder) ⇒ Object
203 204 205 206 207 208 209 210 211 212 |
# File 'lib/metanorma/collection_renderer.rb', line 203 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
157 158 159 160 161 162 163 164 165 166 |
# File 'lib/metanorma/collection_renderer.rb', line 157 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”
162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/metanorma/collection_fileprocess.rb', line 162 def file_compile(file, filename, identifier) return if @files[identifier][:sectionsplit] == "true" opts = { format: :asciidoc, extension_keys: @format, output_dir: @outdir, }.merge((identifier)) @compile.compile file, opts @files[identifier][:outputs] = {} file_compile_formats(filename, identifier) end |
#file_compile_formats(filename, identifier) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/metanorma/collection_fileprocess.rb', line 188 def file_compile_formats(filename, identifier) file_id = @files[identifier] @format << :presentation if @format.include?(:pdf) @format.each do |e| ext = @compile.processor.output_formats[e] fn = File.basename(filename).sub(/(?<=\.)[^.]+$/, ext.to_s) unless /html$/.match?(ext) && file_id[:sectionsplit] file_id[: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 |
# 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"] ret[:bareafterfirst] = ref["bare-after-first"] ret.compact end |
#files ⇒ Object
process each file in the collection files are held in memory, and altered as postprocessing
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/metanorma/collection_fileprocess.rb', line 208 def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength 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')}" collection_xml = update_xrefs(file, identifier, internal_refs) collection_filename = File.basename(filename, File.extname(filename)) collection_xml_path = File.join(Dir.tmpdir, "#{collection_filename}.xml") File.write collection_xml_path, collection_xml, encoding: "UTF-8" file_compile(collection_xml_path, filename, identifier) FileUtils.rm(collection_xml_path) end end end |
#gather_internal_refs ⇒ Object
gather internal bibitem references
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/metanorma/collection_fileparse.rb', line 222 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 |
#hide_refs(docxml) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/metanorma/collection_fileparse.rb', line 90 def hide_refs(docxml) docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or "\ "@hidden = 'false'])]")).each do |f| f["hidden"] = "true" end end |
#index_link(docref, ident) ⇒ Object
214 215 216 217 218 219 |
# File 'lib/metanorma/collection_renderer.rb', line 214 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)
229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/metanorma/collection_renderer.rb', line 229 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]
195 196 197 198 199 |
# File 'lib/metanorma/collection_renderer.rb', line 195 def indexfile_docref(elm, builder) return "" unless elm.at(ns("./docref[@index = 'true']")) builder.ul { |b| docrefs(elm, b) } end |
#indexfile_title(elm) ⇒ String
184 185 186 187 188 |
# File 'lib/metanorma/collection_renderer.rb', line 184 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
134 135 136 137 138 139 140 141 |
# File 'lib/metanorma/collection_renderer.rb', line 134 def isodoc x = Asciidoctor.load nil, backend: @doctype.to_sym isodoc = x.converter.html_converter(Dummy.new) isodoc.i18n_init(@lang, @script) # read in internationalisation isodoc.(@lang, @script, isodoc.i18n) isodoc.info(@xml, nil) isodoc end |
#isodoc_populate(isodoc) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/metanorma/collection_renderer.rb', line 143 def isodoc_populate(isodoc) # create the @meta class of isodoc, with "navigation" set to the index bar # extracted from the manifest nav = indexfile(@xml.at(ns("//manifest"))) i18n = isodoc.i18n i18n.set("navigation", nav) isodoc.(@lang, @script, i18n) # populate the @meta class of isodoc with the various metadata fields # native to the flavour; used to populate Liquid isodoc.info(@xml, nil) isodoc end |
#locate_internal_refs ⇒ Object
resolve file location for the target of each internal reference
239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/metanorma/collection_fileparse.rb', line 239 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
252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/metanorma/collection_fileparse.rb', line 252 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
168 169 170 |
# File 'lib/metanorma/collection_renderer.rb', line 168 def ns(xpath) IsoDoc::Convert.new({}).ns(xpath) end |
#pdfconv ⇒ Object
107 108 109 110 111 |
# File 'lib/metanorma/collection_renderer.rb', line 107 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) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength 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 .(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>
153 154 155 156 157 158 |
# File 'lib/metanorma/collection_fileprocess.rb', line 153 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 |
#supply_repo_ids(docxml) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/metanorma/collection_fileparse.rb', line 97 def supply_repo_ids(docxml) docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b| next if b&.at(ns("./docidentifier[@type = 'repository']")) b.xpath(ns("./docidentifier")).each do |d| next unless @files[d.text] d.next = "<docidentifier type='repository'>"\ "current-metanorma-collection/#{d.text}" end end end |
#svgmap_resolve(docxml) ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/metanorma/collection_fileparse.rb', line 117 def svgmap_resolve(docxml) isodoc = IsoDoc::Convert.new({}) isodoc.bibitem_lookup(docxml) docxml.xpath(ns("//svgmap//eref")).each do |e| svgmap_resolve1(e, isodoc) end Metanorma::Utils::svgmap_rewrite(docxml, "") end |
#svgmap_resolve1(eref, isodoc) ⇒ Object
126 127 128 129 130 131 132 133 134 |
# File 'lib/metanorma/collection_fileparse.rb', line 126 def svgmap_resolve1(eref, isodoc) href = isodoc.eref_target(eref) return if href == "##{eref['bibitemid']}" || (href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")) eref["target"] = href.strip eref.name = "link" eref&.elements&.remove 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
139 140 141 142 143 144 145 146 147 |
# File 'lib/metanorma/collection_fileprocess.rb', line 139 def targetfile(data, ) = { read: false, doc: true, relative: false }.merge() path = [:relative] ? data[:rel_path] : data[:ref] if data[:type] == "fileref" ref_file path, data[:out_path], [:read], [:doc] else xml_file data[:id], [: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
211 212 213 214 215 216 217 218 219 |
# File 'lib/metanorma/collection_fileparse.rb', line 211 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
196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/metanorma/collection_fileparse.rb', line 196 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
186 187 188 189 190 191 192 193 194 |
# File 'lib/metanorma/collection_fileparse.rb', line 186 def update_anchors(bib, docxml, docid) # rubocop:disable Metrics/AbcSize 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) # rubocop:disable Metrics/AbcSize 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.
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/metanorma/collection_fileparse.rb', line 141 def update_direct_refs_to_docs(docxml, identifier) erefs = collect_erefs(docxml) 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)
163 164 165 166 167 168 169 |
# File 'lib/metanorma/collection_fileparse.rb', line 163 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
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/metanorma/collection_fileparse.rb', line 171 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 |
# File 'lib/metanorma/collection_fileparse.rb', line 79 def update_xrefs(file, identifier, internal_refs) docxml = Nokogiri::XML(file) { |config| config.huge } supply_repo_ids(docxml) 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)) hide_refs(docxml) 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 |