class Metanorma::Collection
Metanorma
collection of documents
Attributes
@return [Array<String>] documents-inline to inject the XML into
the collection manifest; documents-external to keeps them outside
@return [Hash<String, Metanorma::Document>]
@return [String]
@return [String, nil]
@return [String, nil]
Public Class Methods
@param file [String] path to source file @param directives [Array<String>] documents-inline to inject the XML into
the collection manifest; documents-external to keeps them outside
@param bibdata [RelatonBib::BibliographicItem] @param manifest [Metanorma::CollectionManifest] @param documents [Hash<String, Metanorma::Document>] @param prefatory [String] @param final [String] rubocop:disable Metrics/AbcSize,Metrics/MethodLength
# File lib/metanorma/collection.rb, line 33 def initialize(**args) @file = args[:file] @directives = args[:directives] || [] @bibdata = args[:bibdata] @manifest = args[:manifest] @manifest.collection = self @documents = args[:documents] || {} if @documents.any? && !@directives.include?("documents-inline") @directives << "documents-inline" end @documents.merge! @manifest.documents(File.dirname(@file)) @prefatory = args[:prefatory] @final = args[:final] @log = Metanorma::Utils::Log.new @disambig = Util::DisambigFiles.new end
@param file [String] @return [RelatonBib::BibliographicItem,
RelatonIso::IsoBibliographicItem]
# File lib/metanorma/collection.rb, line 84 def parse(file) case file when /\.xml$/ then parse_xml(file) when /.ya?ml$/ then parse_yaml(file) end end
Private Class Methods
@param xml [Nokogiri::XML::Document] @parma mnf [Metanorma::CollectionManifest] @return [Hash{String=>Metanorma::Document}]
# File lib/metanorma/collection.rb, line 124 def docs_from_xml(xml, mnf) xml.xpath("//xmlns:doc-container//xmlns:bibdata") .each_with_object({}) do |b, m| bd = Relaton::Cli.parse_xml b docref = mnf.docref_by_id bd.docidentifier.first.id m[docref["identifier"]] = Document.new bd, docref["fileref"] m end end
# File lib/metanorma/collection.rb, line 93 def parse_xml(file) xml = Nokogiri::XML File.read(file, encoding: "UTF-8") do |config| config.huge end if (b = xml.at("/xmlns:metanorma-collection/xmlns:bibdata")) bd = Relaton::Cli.parse_xml b end mnf_xml = xml.at("/xmlns:metanorma-collection/xmlns:manifest") mnf = CollectionManifest.from_xml mnf_xml pref = pref_final_content xml.at("//xmlns:prefatory-content") fnl = pref_final_content xml.at("//xmlns:final-content") new(file: file, bibdata: bd, manifest: mnf, documents: docs_from_xml(xml, mnf), prefatory: pref, final: fnl) end
# File lib/metanorma/collection.rb, line 108 def parse_yaml(file) yaml = YAML.load_file file if yaml["bibdata"] bd = Relaton::Cli::YAMLConvertor.convert_single_file yaml["bibdata"] end mnf = CollectionManifest.from_yaml yaml["manifest"] dirs = yaml["directives"] pref = yaml["prefatory-content"] fnl = yaml["final-content"] new(file: file, directives: dirs, bibdata: bd, manifest: mnf, prefatory: pref, final: fnl) end
@param xml [Nokogiri::XML::Element, nil] @return [String, nil]
# File lib/metanorma/collection.rb, line 136 def pref_final_content(xml) return unless xml <<~CONT == #{xml.at('title')&.text} #{xml.at('p')&.text} CONT end
Public Instance Methods
rubocop:enable Metrics/AbcSize,Metrics/MethodLength
# File lib/metanorma/collection.rb, line 51 def clean_exit @log.write(File.join(File.dirname(@file), "#{File.basename(@file, '.*')}.err")) end
# File lib/metanorma/collection.rb, line 67 def collection_body(coll) coll << @bibdata.to_xml(bibdata: true, date_format: :full) @manifest.to_xml coll content_to_xml "prefatory", coll doccontainer coll content_to_xml "final", coll end
# File lib/metanorma/collection.rb, line 75 def render(opts) CollectionRenderer.render self, opts.merge(log: @log) clean_exit end
@return [String] XML
# File lib/metanorma/collection.rb, line 57 def to_xml b = Nokogiri::XML::Builder.new do |xml| xml.send("metanorma-collection", "xmlns" => "http://metanorma.org") do |mc| collection_body(mc) end end b.to_xml end
Private Instance Methods
@param elm [String] 'prefatory' or 'final' @param builder [Nokogiri::XML::Builder]
# File lib/metanorma/collection.rb, line 163 def content_to_xml(elm, builder) return unless (cnt = send(elm)) require "metanorma-#{doctype}" out = sections(dummy_header + cnt.strip) builder.send("#{elm}-content") { |b| b << out } end
@param builder [Nokogiri::XML::Builder]
# File lib/metanorma/collection.rb, line 179 def doccontainer(builder) return unless Array(@directives).include? "documents-inline" documents.each_with_index do |(_, d), i| doccontainer1(builder, d, i) end end
# File lib/metanorma/collection.rb, line 187 def doccontainer1(builder, doc, idx) id = format("doc%<index>09d", index: idx) builder.send("doc-container", id: id) do |b| if doc.attachment doc.bibitem and b << doc.bibitem.root.to_xml b.attachment Metanorma::Utils::datauri(doc.file) else doc.to_xml b end end end
@return [String]
# File lib/metanorma/collection.rb, line 199 def doctype @doctype ||= fetch_doctype || "standoc" end
@return [String]
# File lib/metanorma/collection.rb, line 153 def dummy_header <<~DUMMY = X A DUMMY end
@return [String]
# File lib/metanorma/collection.rb, line 204 def fetch_doctype docid = @bibdata.docidentifier.first return unless docid docid.type&.downcase || docid.id&.sub(/\s.*$/, "")&.downcase end
@param cnt [String] prefatory/final content @return [String] XML
# File lib/metanorma/collection.rb, line 173 def sections(cnt) c = Asciidoctor.convert(cnt, backend: doctype.to_sym, header_footer: true) Nokogiri::XML(c).at("//xmlns:sections").children.to_xml end