class Metanorma::Collection

Metanorma collection of documents

Attributes

directives[RW]

@return [Array<String>] documents-inline to inject the XML into

the collection manifest; documents-external to keeps them outside
disambig[RW]
documents[RW]

@return [Hash<String, Metanorma::Document>]

file[R]

@return [String]

final[R]

@return [String, nil]

prefatory[R]

@return [String, nil]

Public Class Methods

new(**args) click to toggle source

@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
parse(file) click to toggle source

@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

docs_from_xml(xml, mnf) click to toggle source

@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
parse_xml(file) click to toggle source
# 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
parse_yaml(file) click to toggle source
# 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
pref_final_content(xml) click to toggle source

@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

clean_exit() click to toggle source

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
collection_body(coll) click to toggle source
# 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
render(opts) click to toggle source
# File lib/metanorma/collection.rb, line 75
def render(opts)
  CollectionRenderer.render self, opts.merge(log: @log)
  clean_exit
end
to_xml() click to toggle source

@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

content_to_xml(elm, builder) click to toggle source

@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
doccontainer(builder) click to toggle source

@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
doccontainer1(builder, doc, idx) click to toggle source
# 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
doctype() click to toggle source

@return [String]

# File lib/metanorma/collection.rb, line 199
def doctype
  @doctype ||= fetch_doctype || "standoc"
end
dummy_header() click to toggle source

@return [String]

# File lib/metanorma/collection.rb, line 153
    def dummy_header
      <<~DUMMY
        = X
        A

      DUMMY
    end
fetch_doctype() click to toggle source

@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
sections(cnt) click to toggle source

@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