Class: Metanorma::Collection
- Inherits:
-
Object
- Object
- Metanorma::Collection
- Defined in:
- lib/metanorma/collection/collection.rb,
lib/metanorma/collection/log.rb,
lib/metanorma/collection/helpers.rb,
lib/metanorma/collection/util/util.rb,
lib/metanorma/collection/renderer/svg.rb,
lib/metanorma/collection/config/config.rb,
lib/metanorma/collection/config/bibdata.rb,
lib/metanorma/collection/renderer/utils.rb,
lib/metanorma/collection/config/manifest.rb,
lib/metanorma/collection/filelookup/base.rb,
lib/metanorma/collection/config/directive.rb,
lib/metanorma/collection/filelookup/utils.rb,
lib/metanorma/collection/config/converters.rb,
lib/metanorma/collection/config/namespaces.rb,
lib/metanorma/collection/document/document.rb,
lib/metanorma/collection/manifest/manifest.rb,
lib/metanorma/collection/renderer/renderer.rb,
lib/metanorma/collection/renderer/fileparse.rb,
lib/metanorma/collection/renderer/navigation.rb,
lib/metanorma/collection/util/disambig_files.rb,
lib/metanorma/collection/config/doc_container.rb,
lib/metanorma/collection/renderer/fileprocess.rb,
lib/metanorma/collection/renderer/render_word.rb,
lib/metanorma/collection/filelookup/filelookup.rb,
lib/metanorma/collection/renderer/filelocation.rb,
lib/metanorma/collection/config/compile_options.rb,
lib/metanorma/collection/sectionsplit/collection.rb,
lib/metanorma/collection/xrefprocess/xrefprocess.rb,
lib/metanorma/collection/multilingual/multilingual.rb,
lib/metanorma/collection/sectionsplit/sectionsplit.rb,
lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb
Overview
Metanorma collection of documents
Defined Under Namespace
Modules: Config, Util, XrefProcess Classes: Document, FileLookup, Manifest, Multilingual, Renderer, Sectionsplit
Constant Summary collapse
- METANORMA_LOG_MESSAGES =
{ # rubocop:disable Naming/VariableNumber "METANORMA_1": { category: "Cross-References", error: "Missing cross-reference: %s", severity: 2 }, "METANORMA_2": { category: "Cross-References", error: "[metanorma] Cannot find crossreference to document %s in document %s.", severity: 2 }, "METANORMA_3": { category: "Cross-References", error: "<strong>** Unresolved reference to document %s from eref</strong>", severity: 2 }, }.freeze
Instance Attribute Summary collapse
-
#bibdata ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#bibdatas ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#compile ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#config ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#coverpage ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#coverpage_pdf_portfolio ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#directives ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#dirname ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#disambig ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#documents ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#file ⇒ Object
readonly
Returns the value of attribute file.
-
#final ⇒ Object
readonly
Returns the value of attribute final.
-
#manifest ⇒ Array<String>
Documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
-
#prefatory ⇒ Object
readonly
Returns the value of attribute prefatory.
Class Method Summary collapse
- .check_file_existence(filepath) ⇒ Object
- .parse(file) ⇒ Object
- .pre_parse_model(collection_model) ⇒ Object
- .resolve_fileref(ref_folder, fileref) ⇒ String
- .resolve_identifier(identifier) ⇒ String
-
.set_fileref_resolver(&block) ⇒ Object
NOTE: MUST ALWAYS RETURN PATH relative to working directory (initial YAML file location).
- .set_identifier_resolver(&block) ⇒ Object
- .set_pre_parse_model(&block) ⇒ Object
- .unset_fileref_resolver ⇒ Object
Instance Method Summary collapse
- #clean_exit ⇒ Object
- #content_to_xml(elm, builder) ⇒ Object
-
#doc_containers ⇒ Object
Populate the Config#documents collection with DocContainer wrappers.
-
#doccontainer1_inner(doc) ⇒ Object
Inner XML of a single <doc-container> as a string.
-
#dummy_header_docidentifier ⇒ Object
Pick a real docidentifier value for the prefatory dummy header so the flavor’s metadata_id has something pubid-parseable to put into the bibdata, instead of falling back to its (Liquid-templated) docid_template (issue #558).
-
#fetch_flavor ⇒ Object
TODO: retrieve flavor based on @bibdata publisher when lookup implemented Will still infer based on docid, but will validate it before proceeding.
- #first_doc_docid ⇒ Object
- #flavor ⇒ Object
-
#initialize(**args) ⇒ Collection
constructor
A new instance of Collection.
- #initialize_config(config) ⇒ Object
- #initialize_directives ⇒ Object
- #initialize_docs ⇒ Object
- #initialize_vars ⇒ Object
- #output_folder(opts) ⇒ Object
- #prefatory_extract_xml(presxml) ⇒ Object
-
#prefatory_parse(cnt) ⇒ String
XML.
-
#prefatory_parse_fix_bibdata(bibdata) ⇒ Object
Stop standoc ownerless copyright from breaking Relaton parse of bibdata.
- #prefatory_parse_semantic(cnt) ⇒ Object
- #render(opts) ⇒ Object
-
#to_xml ⇒ String
XML.
- #validate_flavor(flavor) ⇒ Object
Constructor Details
#initialize(**args) ⇒ Collection
Returns a new instance of Collection.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/metanorma/collection/collection.rb', line 27 def initialize(**args) @file = args[:file] @dirname = File.(File.dirname(@file)) # feeds @manifest @documents = args[:documents] || {} # feeds initialize_directives, initialize_docs @bibdatas = args[:documents] || {} initialize_vars initialize_config(args[:config]) initialize_directives initialize_docs validate_flavor(flavor) end |
Instance Attribute Details
#bibdata ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def bibdata @bibdata end |
#bibdatas ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def bibdatas @bibdatas end |
#compile ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def compile @compile end |
#config ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def config @config end |
#coverpage ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def coverpage @coverpage end |
#coverpage_pdf_portfolio ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def coverpage_pdf_portfolio @coverpage_pdf_portfolio end |
#directives ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def directives @directives end |
#dirname ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def dirname @dirname end |
#disambig ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def disambig @disambig end |
#documents ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def documents @documents end |
#file ⇒ Object (readonly)
Returns the value of attribute file.
16 17 18 |
# File 'lib/metanorma/collection/collection.rb', line 16 def file @file end |
#final ⇒ Object (readonly)
Returns the value of attribute final.
16 17 18 |
# File 'lib/metanorma/collection/collection.rb', line 16 def final @final end |
#manifest ⇒ Array<String>
Returns documents-inline to inject the XML into the collection manifest; documents-external to keeps them outside.
20 21 22 |
# File 'lib/metanorma/collection/collection.rb', line 20 def manifest @manifest end |
#prefatory ⇒ Object (readonly)
Returns the value of attribute prefatory.
16 17 18 |
# File 'lib/metanorma/collection/collection.rb', line 16 def prefatory @prefatory end |
Class Method Details
.check_file_existence(filepath) ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/metanorma/collection/helpers.rb', line 59 def check_file_existence(filepath) unless File.exist?(filepath) = "#{filepath} not found!" ::Metanorma::Util.log("[metanorma] Error: #{}", :error) raise FileNotFoundException.new .to_s end end |
.parse(file) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/metanorma/collection/helpers.rb', line 67 def parse(file) # need @dirname initialised before collection object initialisation @dirname = File.(File.dirname(file)) config = case file when /\.xml$/ ::Metanorma::Collection::Config::Config.from_xml(File.read(file)) when /.ya?ml$/ y = YAML.safe_load(File.read(file)) pre_parse_model(y) ::Metanorma::Collection::Config::Config.from_yaml(y.to_yaml) end new(file: file, config: config) end |
.pre_parse_model(collection_model) ⇒ Object
31 32 33 34 |
# File 'lib/metanorma/collection/helpers.rb', line 31 def pre_parse_model(collection_model) @pre_parse_model_proc or return @pre_parse_model_proc.call(collection_model) end |
.resolve_fileref(ref_folder, fileref) ⇒ String
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/metanorma/collection/helpers.rb', line 45 def resolve_fileref(ref_folder, fileref) warn ref_folder warn fileref unless @fileref_resolver (Pathname.new fileref).absolute? or fileref = File.join(ref_folder, fileref) return fileref end @fileref_resolver.call(ref_folder, fileref) end |
.resolve_identifier(identifier) ⇒ String
38 39 40 41 |
# File 'lib/metanorma/collection/helpers.rb', line 38 def resolve_identifier(identifier) @identifier_resolver or return identifier @identifier_resolver.call(identifier) end |
.set_fileref_resolver(&block) ⇒ Object
allow user-specific function to resolve fileref
NOTE: MUST ALWAYS RETURN PATH relative to working directory (initial YAML file location). @fileref_resolver.call(ref_folder, fileref) fileref is not what is in the YAML, but the resolved path relative to the working directory
22 23 24 |
# File 'lib/metanorma/collection/helpers.rb', line 22 def set_fileref_resolver(&block) @fileref_resolver = block end |
.set_identifier_resolver(&block) ⇒ Object
allow user-specific function to resolve identifier
12 13 14 |
# File 'lib/metanorma/collection/helpers.rb', line 12 def set_identifier_resolver(&block) @identifier_resolver = block end |
.set_pre_parse_model(&block) ⇒ Object
allow user-specific function to run in pre-parse model stage
6 7 8 |
# File 'lib/metanorma/collection/helpers.rb', line 6 def set_pre_parse_model(&block) @pre_parse_model_proc = block end |
.unset_fileref_resolver ⇒ Object
26 27 28 |
# File 'lib/metanorma/collection/helpers.rb', line 26 def unset_fileref_resolver @fileref_resolver = nil end |
Instance Method Details
#clean_exit ⇒ Object
83 84 85 86 |
# File 'lib/metanorma/collection/collection.rb', line 83 def clean_exit @log.write(File.join(@dirname, "#{File.basename(@file, '.*')}.err.html")) end |
#content_to_xml(elm, builder) ⇒ Object
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/metanorma/collection/collection.rb', line 148 def content_to_xml(elm, builder) (cnt = send(elm)) or return @compile.load_flavor(Util::taste2flavor(flavor)) out = prefatory_parse( Util::asciidoc_dummy_header( docidentifier: dummy_header_docidentifier, ) + cnt.strip, ) builder.send("#{elm}-content") { |b| b << out } end |
#doc_containers ⇒ Object
Populate the Config#documents collection with DocContainer wrappers. Only emit them when the ‘documents-inline` directive is set; otherwise the manifest’s <entry fileref=…> already references them externally.
101 102 103 104 105 106 107 108 109 |
# File 'lib/metanorma/collection/collection.rb', line 101 def doc_containers @directives.detect { |d| d.key == "documents-inline" } or return [] @documents.each_with_index.map do |(_, d), idx| ::Metanorma::Collection::Config::DocContainer.new( id: format("doc%<index>09d", index: idx), content: doccontainer1_inner(d), ) end end |
#doccontainer1_inner(doc) ⇒ Object
Inner XML of a single <doc-container> as a string. The body is either the document’s <metanorma> presentation root (with its own xmlns) or an attachment payload.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/metanorma/collection/collection.rb', line 114 def doccontainer1_inner(doc) b = Nokogiri::XML::Builder.new do |xml| xml.send(:wrapper) do |w| if doc. doc.bibitem and w << doc.bibitem.root.to_xml w. Vectory::Utils::datauri(doc.file) else doc.to_xml w w.parent.children.first["flavor"] = Util::taste2flavor(flavor) end end end b.parent.elements.first.children.map(&:to_xml).join end |
#dummy_header_docidentifier ⇒ Object
Pick a real docidentifier value for the prefatory dummy header so the flavor’s metadata_id has something pubid-parseable to put into the bibdata, instead of falling back to its (Liquid-templated) docid_template (issue #558). Prefer the first manifest document’s docidentifier (concrete, e.g. “IHO S-97”); fall back to the collection’s own (which may carry suffixes like “(all parts)” that pubid won’t parse). Both candidates are wrapped because the bibitem field may be a parsed Relaton BibliographicItem in some phases and a Nokogiri::XML::Document in others.
168 169 170 |
# File 'lib/metanorma/collection/collection.rb', line 168 def dummy_header_docidentifier first_doc_docid || @bibdata&.docidentifier&.first&.content end |
#fetch_flavor ⇒ Object
TODO: retrieve flavor based on @bibdata publisher when lookup implemented Will still infer based on docid, but will validate it before proceeding
233 234 235 236 237 238 239 240 241 242 |
# File 'lib/metanorma/collection/collection.rb', line 233 def fetch_flavor docid = @bibdata&.docidentifier&.first or return f = docid.type&.downcase || docid.content&.sub(/\s.*$/, "")&.downcase or return f = Util::taste2flavor(f) require ::Metanorma::Compile.new.stdtype2flavor_gem(f) f rescue LoadError, NameError nil end |
#first_doc_docid ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/metanorma/collection/collection.rb', line 172 def first_doc_docid bib = documents.values.first&.bibitem or return nil if bib.respond_to?(:docidentifier) bib.docidentifier&.first&.content elsif bib.respond_to?(:at) # Nokogiri (rendering-phase shape) # Use local-name() so the match works regardless of whether the # rendering-phase document carries a default namespace, without # tripping Nokogiri's "undefined namespace prefix" error when # it doesn't. bib.at("//*[local-name()='docidentifier']")&.text end end |
#flavor ⇒ Object
227 228 229 |
# File 'lib/metanorma/collection/collection.rb', line 227 def flavor @flavor ||= fetch_flavor || "standoc" end |
#initialize_config(config) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/metanorma/collection/collection.rb', line 54 def initialize_config(config) @config = config @directives = config.directive || [] # feeds initialize_directives @bibdata = config.bibdata @prefatory = config.prefatory_content @final = config.final_content @manifest = ::Metanorma::Collection::Manifest .new(config.manifest, self, @dirname) # feeds initialize_directives @format = config.format.map(&:to_sym) @format&.empty? and @format = nil end |
#initialize_directives ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/metanorma/collection/collection.rb', line 66 def initialize_directives d = @directives.each_with_object({}) { |x, m| m[x.key] = x.value } @coverpage = d["coverpage"] @coverpage_pdf_portfolio = d["coverpage-pdf-portfolio"] @coverpage_style = d["coverpage-style"] @flavor = d["flavor"] if (@documents.any? || @manifest) && !d.key?("documents-inline") && !d.key?("documents-external") @directives << ::Metanorma::Collection::Config::Directive .new(key: "documents-inline") end end |
#initialize_docs ⇒ Object
39 40 41 42 43 44 |
# File 'lib/metanorma/collection/collection.rb', line 39 def initialize_docs @documents.merge! @manifest.documents @bibdatas.merge! @manifest.documents @documents.transform_keys { |k| Util::key(k) } @bibdatas.transform_keys { |k| Util::key(k) } end |
#initialize_vars ⇒ Object
46 47 48 49 50 51 52 |
# File 'lib/metanorma/collection/collection.rb', line 46 def initialize_vars @compile = Metanorma::Compile.new # feeds @manifest @log = Metanorma::Utils::Log.new @log.suppress_log = { severity: 4, category: [], error_ids: [], locations: [] } @disambig = Util::DisambigFiles.new end |
#output_folder(opts) ⇒ Object
139 140 141 142 143 144 |
# File 'lib/metanorma/collection/collection.rb', line 139 def output_folder(opts) opts[:output_folder] ||= config.output_folder opts[:output_folder] && !Pathname.new(opts[:output_folder]).absolute? and opts[:output_folder] = File.join(@dirname, opts[:output_folder]) warn opts[:output_folder] end |
#prefatory_extract_xml(presxml) ⇒ Object
197 198 199 200 201 202 203 |
# File 'lib/metanorma/collection/collection.rb', line 197 def prefatory_extract_xml(presxml) body = presxml.at("//xmlns:sections") body.at("//xmlns:p[@class = 'zzSTDTitle1']")&.remove body.text.to_s.strip.empty? and body = presxml.at("//xmlns:preface") body.at("//xmlns:clause[@type = 'toc']")&.remove body.children.to_xml end |
#prefatory_parse(cnt) ⇒ String
Returns XML.
187 188 189 190 191 192 193 194 195 |
# File 'lib/metanorma/collection/collection.rb', line 187 def prefatory_parse(cnt) x = prefatory_parse_semantic(cnt) _, filepath = Util::nokogiri_to_temp(x, "foo", ".presentation.xml") c1 = Util::isodoc_create(Util::taste2flavor(@flavor), @manifest.lang, @manifest.script, x, presxml: true).convert(filepath, nil, true) presxml = Nokogiri::XML(c1) prefatory_extract_xml(presxml) end |
#prefatory_parse_fix_bibdata(bibdata) ⇒ Object
Stop standoc ownerless copyright from breaking Relaton parse of bibdata
218 219 220 221 222 223 224 225 |
# File 'lib/metanorma/collection/collection.rb', line 218 def prefatory_parse_fix_bibdata(bibdata) if cop = bibdata.at("//xmlns:copyright") cop.at("./xmlns:owner") or cop.children.first.previous = "<owner><organization><name>SDO</name></organization></owner>" end bibdata end |
#prefatory_parse_semantic(cnt) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/metanorma/collection/collection.rb', line 205 def prefatory_parse_semantic(cnt) c = Asciidoctor.convert(cnt, backend: Util::taste2flavor(flavor).to_sym, header_footer: true) x = Nokogiri::XML(c) x.xpath("//xmlns:clause").each { |n| n["unnumbered"] = true } b = x.at("//xmlns:bibdata") prefatory_parse_fix_bibdata(b) b.children = ::Metanorma::Standoc::Cleanup::MergeBibitems .new(b.to_xml, @bibdata.to_xml(bibdata: true)).merge.to_noko.children x end |
#render(opts) ⇒ Object
129 130 131 132 133 134 135 136 137 |
# File 'lib/metanorma/collection/collection.rb', line 129 def render(opts) opts[:format].nil? || opts[:format].empty? and opts[:format] = @format || [:html] opts[:log] = @log opts[:flavor] = @flavor output_folder(opts) ::Metanorma::Collection::Renderer.render self, opts clean_exit end |
#to_xml ⇒ String
Returns XML.
89 90 91 92 93 94 95 96 |
# File 'lib/metanorma/collection/collection.rb', line 89 def to_xml c = ::Metanorma::Collection::Config::Config .new(directive: @directives, bibdata: @bibdata, manifest: @manifest.config, documents: doc_containers, prefatory_content: @prefatory, final_content: @final) c.collection = self c.to_xml end |
#validate_flavor(flavor) ⇒ Object
79 80 81 |
# File 'lib/metanorma/collection/collection.rb', line 79 def validate_flavor(flavor) ::Metanorma::Compile.new.load_flavor(flavor) end |