metanorma 1.7.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -1
  3. data/lib/metanorma/array_monkeypatch.rb +9 -0
  4. data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
  5. data/lib/metanorma/collection/collection.rb +225 -0
  6. data/lib/metanorma/collection/config/bibdata.rb +12 -0
  7. data/lib/metanorma/collection/config/compile_options.rb +13 -0
  8. data/lib/metanorma/collection/config/config.rb +163 -0
  9. data/lib/metanorma/collection/config/converters.rb +30 -0
  10. data/lib/metanorma/collection/config/directive.rb +10 -0
  11. data/lib/metanorma/collection/config/manifest.rb +88 -0
  12. data/lib/metanorma/collection/document/document.rb +133 -0
  13. data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
  14. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
  15. data/lib/metanorma/collection/manifest/manifest.rb +237 -0
  16. data/lib/metanorma/collection/renderer/fileparse.rb +247 -0
  17. data/lib/metanorma/collection/renderer/fileprocess.rb +173 -0
  18. data/lib/metanorma/collection/renderer/navigation.rb +133 -0
  19. data/lib/metanorma/collection/renderer/render_word.rb +133 -0
  20. data/lib/metanorma/collection/renderer/renderer.rb +157 -0
  21. data/lib/metanorma/collection/renderer/utils.rb +183 -0
  22. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -0
  23. data/lib/metanorma/collection/util/disambig_files.rb +37 -0
  24. data/lib/metanorma/collection/util/util.rb +72 -0
  25. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
  26. data/lib/metanorma/{compile.rb → compile/compile.rb} +17 -11
  27. data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
  28. data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
  29. data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
  30. data/lib/metanorma/{config.rb → config/config.rb} +1 -1
  31. data/lib/metanorma/input/asciidoc.rb +3 -3
  32. data/lib/metanorma/input/base.rb +1 -5
  33. data/lib/metanorma/processor/processor.rb +54 -0
  34. data/lib/metanorma/processor.rb +1 -49
  35. data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
  36. data/lib/metanorma/shale_monkeypatch.rb +15 -0
  37. data/lib/metanorma/util/fontist_helper.rb +130 -0
  38. data/lib/metanorma/util/util.rb +45 -0
  39. data/lib/metanorma/util/worker_pool.rb +39 -0
  40. data/lib/metanorma/version.rb +1 -1
  41. data/lib/metanorma.rb +13 -8
  42. data/metanorma.gemspec +2 -1
  43. metadata +51 -26
  44. data/Gemfile.devel +0 -2
  45. data/lib/metanorma/collection.rb +0 -243
  46. data/lib/metanorma/collection_fileparse.rb +0 -254
  47. data/lib/metanorma/collection_fileprocess.rb +0 -157
  48. data/lib/metanorma/collection_manifest.rb +0 -139
  49. data/lib/metanorma/collection_render_utils.rb +0 -169
  50. data/lib/metanorma/collection_render_word.rb +0 -131
  51. data/lib/metanorma/collection_renderer.rb +0 -230
  52. data/lib/metanorma/document.rb +0 -133
  53. data/lib/metanorma/files_lookup.rb +0 -208
  54. data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
  55. data/lib/metanorma/fontist_utils.rb +0 -122
  56. data/lib/metanorma/sectionsplit.rb +0 -216
  57. data/lib/metanorma/sectionsplit_links.rb +0 -189
  58. data/lib/metanorma/util.rb +0 -127
  59. data/lib/metanorma/worker_pool.rb +0 -29
@@ -1,169 +0,0 @@
1
- module Metanorma
2
- class CollectionRenderer
3
- def dir_name_cleanse(name)
4
- path = Pathname.new(name)
5
- clean_regex = /[<>:"|?*]/
6
- fallback_sym = "_"
7
- return name.gsub(clean_regex, fallback_sym) unless path.absolute?
8
-
9
- File.join(path.dirname,
10
- path.basename.to_s.gsub(clean_regex, fallback_sym))
11
- end
12
-
13
- def dup_bibitem(docid, bib)
14
- newbib = @files.get(docid, :bibdata).dup
15
- newbib.name = "bibitem"
16
- newbib["hidden"] = "true"
17
- newbib&.at("./*[local-name() = 'ext']")&.remove
18
- newbib["id"] = bib["id"]
19
- newbib
20
- end
21
-
22
- def get_bibitem_docid(bib, identifier)
23
- docid =
24
- bib.at(ns("./docidentifier[@type = 'metanorma-collection']")) ||
25
- bib.at(ns("./docidentifier[not(@type)]")) ||
26
- bib.at(ns("./docidentifier"))
27
- docid &&= docid_prefix(docid)
28
- if @files.get(docid) then docid
29
- else
30
- fail_update_bibitem(docid, identifier)
31
- nil
32
- end
33
- end
34
-
35
- def hide_refs(docxml)
36
- docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or " \
37
- "@hidden = 'false'])]")).each do |f|
38
- f["hidden"] = "true"
39
- end
40
- end
41
-
42
- def strip_eref(eref)
43
- eref.xpath(ns("./locality | ./localityStack")).each(&:remove)
44
- eref.replace(eref.children)
45
- end
46
-
47
- def docid_to_citeas(bib)
48
- docid = bib.at(ns("./docidentifier[@primary = 'true']")) ||
49
- bib.at(ns("./docidentifier")) or return
50
- docid_prefix(docid)
51
- end
52
-
53
- def collect_erefs(docxml)
54
- docxml.xpath(ns("//eref"))
55
- .each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
56
- m[:citeas][i["citeas"]] = true
57
- m[:bibitemid][i["bibitemid"]] = true
58
- end
59
- end
60
-
61
- private
62
-
63
- def docid_prefix(docid)
64
- type = docid["type"]
65
- type == "metanorma-collection" and type = nil
66
- @c.decode(@isodoc
67
- .docid_prefix(type, docid.children.to_xml)).gsub(/\s/, " ")
68
- end
69
-
70
- def create_non_existing_directory(output_directory)
71
- !File.exist?(output_directory) and
72
- FileUtils.mkdir_p(output_directory)
73
- end
74
-
75
- def format_sort(formats)
76
- ret = []
77
- formats.include?(:xml) and ret << :xml
78
- formats.include?(:presentation) and ret << :presentation
79
- a = %i(presentation xml)
80
- ret + formats.reject { |i| a.include? i }
81
- end
82
-
83
- # @param options [Hash]
84
- # @raise [ArgumentError]
85
- def check_options(options)
86
- (options[:format].is_a?(Array) && (FORMATS & options[:format]).any?) or
87
- raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
88
- end
89
-
90
- def pdfconv
91
- doctype = @doctype.to_sym
92
- x = Asciidoctor.load nil, backend: doctype
93
- x.converter.pdf_converter(PdfOptionsNode.new(doctype,
94
- @compile_options))
95
- end
96
-
97
- def fail_update_bibitem(docid, identifier)
98
- error = "[metanorma] Cannot find crossreference to document #{docid} " \
99
- "in document #{identifier}."
100
- @log&.add("Cross-References", nil, error)
101
- Util.log(error, :warning)
102
- end
103
-
104
- def datauri_encode(docxml)
105
- docxml.xpath(ns("//image")).each do |i|
106
- i["src"] = Vectory::Utils::datauri(i["src"])
107
- end
108
- docxml
109
- end
110
-
111
- class PdfOptionsNode
112
- def initialize(doctype, options)
113
- docproc = Metanorma::Registry.instance.find_processor(doctype)
114
- if FontistUtils.has_custom_fonts?(docproc, options, {})
115
- @fonts_manifest = FontistUtils.location_manifest(docproc, options)
116
- end
117
- end
118
-
119
- def attr(key)
120
- if key == "fonts-manifest" && @fonts_manifest
121
- @fonts_manifest
122
- end
123
- end
124
- end
125
-
126
- class Dummy
127
- def attr(_key); end
128
- end
129
-
130
- def isodoc_create
131
- x = Asciidoctor.load nil, backend: @doctype.to_sym
132
- isodoc = x.converter.html_converter(Dummy.new) # to obtain Isodoc class
133
- isodoc.i18n_init(@lang, @script, @locale) # read in internationalisation
134
- isodoc.metadata_init(@lang, @script, @locale, isodoc.i18n)
135
- isodoc.info(@xml, nil)
136
- isodoc
137
- end
138
-
139
- # create the @meta class of isodoc, for populating Liquid,
140
- # with "navigation" set to the index bar.
141
- # extracted from the manifest
142
- def isodoc_populate
143
- @isodoc.info(@xml, nil)
144
- m = @xml.at(ns("//manifest"))
145
- { navigation: indexfile(m), nav_object: index_object(m),
146
- docrefs: liquid_docrefs,
147
- "prefatory-content": isodoc_builder(@xml.at(ns("//prefatory-content"))),
148
- "final-content": isodoc_builder(@xml.at(ns("//final-content"))),
149
- doctitle: m.at(ns("../bibdata/title"))&.text,
150
- docnumber: m.at(ns("../bibdata/docidentifier"))&.text }.each do |k, v|
151
- v and @isodoc.meta.set(
152
- k, v
153
- )
154
- end
155
- end
156
-
157
- def isodoc_builder(node)
158
- Nokogiri::HTML::Builder.new(encoding: "UTF-8") do |b|
159
- b.div do |div|
160
- node&.children&.each { |n| @isodoc.parse(n, div) }
161
- end
162
- end.doc.root.to_html
163
- end
164
-
165
- def ns(xpath)
166
- @isodoc.ns(xpath)
167
- end
168
- end
169
- end
@@ -1,131 +0,0 @@
1
- module Metanorma
2
- class CollectionRenderer
3
- def docconv
4
- @tempfile_cache ||= []
5
- doctype = @doctype.to_sym
6
- x = Asciidoctor.load nil, backend: doctype
7
- x.converter.doc_converter(DocOptionsNode.new(@directives, @dirname))
8
- end
9
-
10
- def concat_extract_files(filename)
11
- xml = Nokogiri::XML(File.read(filename, encoding: "UTF-8"), &:huge)
12
- docs = xml.xpath(ns("//doc-container")).each_with_object([]) do |x, m|
13
- n = Nokogiri::XML::Document.new
14
- n.add_child(x.elements.first.remove)
15
- m << n
16
- end
17
- [wrapping_doc(docs.first.dup, xml), docs]
18
- end
19
-
20
- def wrapping_doc(doc, xml)
21
- doc.at(ns("//bibdata")).replace(xml.at(ns("//bibdata")).to_xml)
22
- sections = wrapping_doc_body(doc)
23
- wrapping_doc_intro_outro(xml, sections)
24
- set_displayorder_wrapping_doc(doc)
25
- end
26
-
27
- def wrapping_doc_intro_outro(xml, sections)
28
- p = xml.at(ns("//prefatory-content")) and
29
- sections.previous = "<preface>#{p.children.to_xml}</preface>"
30
- p = xml.at(ns("//final-content")) and
31
- sections.next = "<annex>#{p.children.to_xml}</annex>"
32
- end
33
-
34
- def wrapping_doc_body(doc)
35
- doc.xpath(ns("//annex | //preface | //bibliography")).each(&:remove)
36
- s = doc.at(ns("//sections"))
37
- repl = <<~BODY
38
- <sections><clause id='_collection_placeholder'><p>PLACEHOLDER</p></clause></sections>
39
- BODY
40
- s.replace(repl)
41
- doc.at(ns("//sections"))
42
- end
43
-
44
- def set_displayorder_wrapping_doc(doc)
45
- doc.xpath(ns("//preface/* | //sections/* | //annex"))
46
- .each_with_index do |x, i|
47
- x["displayorder"] = i + 1
48
- end
49
- doc
50
- end
51
-
52
- SECTION_BREAK = '<p class="MsoNormal"><br clear="all" class="section"/></p>'
53
- .freeze
54
- DIV1 = '<div class="WordSection1">&#xa0;</div>'.freeze
55
- DIV2 = '<div class="WordSection2">&#xa0;</div>'.freeze
56
-
57
- def docconv_convert1(docs)
58
- docs.each_with_index.with_object([]) do |(d, i), m|
59
- conv = docconv
60
- conv.convert_init(d.to_xml(encoding: "UTF-8"), "xxxx", false)
61
- html = conv.postprocess_cleanup(conv.convert1(d, "xxx", "."))
62
- @tempfile_cache += conv.tempfile_cache # hold on to the temp img files
63
- b = Nokogiri::XML(html).at("//body")
64
- i == docs.size - 1 or
65
- b << '<p class="MsoNormal"><br clear="all" class="section"/></p>'
66
- m << b.children
67
- end
68
- end
69
-
70
- def collection_coverpages(conv, docs)
71
- conv.wordintropage and [DIV2, SECTION_BREAK].reverse.each do |s|
72
- docs.unshift(Nokogiri::XML(s).root)
73
- end
74
- conv.wordcoverpage and [DIV1, SECTION_BREAK].reverse.each do |s|
75
- docs.unshift(Nokogiri::XML(s).root)
76
- end
77
- docs
78
- end
79
-
80
- def docconv_convert(filename)
81
- pref_file, docs = concat_extract_files(filename)
82
- body = docconv_convert1(docs)
83
- collection_conv = overall_docconv_converter(body)
84
- collection_coverpages(collection_conv, body)
85
- collection_conv.convert(filename, pref_file.to_xml, false)
86
- end
87
-
88
- def overall_docconv_cover(collection_conv)
89
- p = Util::hash_key_detect(@directives, "collection-word-coverpage", nil)
90
- collection_conv.wordcoverpage =
91
- Util::rel_path_resolve(@dirname, p)
92
- p = Util::hash_key_detect(@directives, "collection-word-intropage", nil)
93
- collection_conv.wordintropage =
94
- Util::rel_path_resolve(@dirname, p)
95
- end
96
-
97
- def overall_docconv_converter(body)
98
- collection_conv = docconv
99
- collection_conv.options[:collection_doc] = body.map(&:to_xml).join
100
- overall_docconv_cover(collection_conv)
101
-
102
- def collection_conv.postprocess_cleanup(result)
103
- ret = to_xhtml(super)
104
- b = ret.at("//div[@id = '_collection_placeholder']")
105
- b.replace(@options[:collection_doc])
106
- from_xhtml(ret)
107
- end
108
-
109
- collection_conv
110
- end
111
-
112
- class DocOptionsNode
113
- def initialize(directives, dir)
114
- @dir = dir
115
- @wordcoverpage =
116
- Util::hash_key_detect(directives, "document-word-coverpage",
117
- @wordcoverpage)
118
- @wordintropage =
119
- Util::hash_key_detect(directives, "document-word-intropage",
120
- @wordintropage)
121
- end
122
-
123
- def attr(key)
124
- case key
125
- when "wordcoverpage" then Util::rel_path_resolve(@dir, @wordcoverpage)
126
- when "wordintropage" then Util::rel_path_resolve(@dir, @wordintropage)
127
- end
128
- end
129
- end
130
- end
131
- end
@@ -1,230 +0,0 @@
1
- require "isodoc"
2
- require "htmlentities"
3
- require_relative "collection_fileprocess"
4
- require_relative "fontist_utils"
5
- require_relative "util"
6
- require_relative "files_lookup"
7
- require_relative "collection_render_utils"
8
- require_relative "collection_render_word"
9
-
10
- module Metanorma
11
- # XML collection renderer
12
- class CollectionRenderer
13
- FORMATS = %i[html xml doc pdf].freeze
14
-
15
- attr_accessor :isodoc, :nested
16
- attr_reader :xml, :compile, :compile_options, :documents
17
-
18
- # This is only going to render the HTML collection
19
- # @param xml [Metanorma::Collection] input XML collection
20
- # @param folder [String] input folder
21
- # @param options [Hash]
22
- # @option options [String] :coverpage cover page HTML (Liquid template)
23
- # @option options [Array<Symbol>] :format list of formats (xml,html,doc,pdf)
24
- # @option options [String] :output_folder output directory
25
- #
26
- # We presuppose that the bibdata of the document is equivalent to that of
27
- # the collection, and that the flavour gem can sensibly process it. We may
28
- # need to enhance metadata in the flavour gems isodoc/metadata.rb with
29
- # collection metadata
30
- def initialize(collection, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
31
- check_options options
32
- @xml = Nokogiri::XML collection.to_xml # @xml is the collection manifest
33
- @lang = @xml.at("//xmlns:bibdata/xmlns:language")&.text || "en"
34
- @script = @xml.at("//xmlns:bibdata/xmlns:script")&.text || "Latn"
35
- @locale = @xml.at("//xmlns:bibdata/xmlns:locale")&.text
36
- @doctype = doctype
37
- @compile = Compile.new
38
- @compile.load_flavor(@doctype)
39
-
40
- @isodoc = isodoc_create # output processor for flavour
41
- @outdir = dir_name_cleanse(options[:output_folder])
42
- @coverpage = options[:coverpage] || collection.coverpage
43
- @format = Util.sort_extensions_execution(options[:format])
44
- @compile_options = options[:compile] || {}
45
- @compile_options[:no_install_fonts] = true if options[:no_install_fonts]
46
- @log = options[:log]
47
- @documents = collection.documents
48
- @bibdata = collection.documents
49
- @directives = collection.directives
50
- @dirname = collection.dirname
51
- @disambig = Util::DisambigFiles.new
52
- @c = HTMLEntities.new
53
- @files_to_delete = []
54
- @nested = options[:nested] # if false, this is the root instance of Renderer
55
- # if true, then this is not the last time Renderer will be run
56
- # (e.g. this is sectionsplit)
57
-
58
- # list of files in the collection
59
- @files = Metanorma::FileLookup.new(folder, self)
60
- @files.add_section_split
61
- isodoc_populate
62
- create_non_existing_directory(@outdir)
63
- end
64
-
65
- def flush_files
66
- warn "\n\n\n\n\nDone: #{DateTime.now.strftime('%H:%M:%S')}"
67
- warn @files.files_to_delete
68
- @files.files_to_delete.each { |f| FileUtils.rm_f(f) }
69
- @files_to_delete.each { |f| FileUtils.rm_f(f) }
70
- end
71
-
72
- # @param col [Metanorma::Collection] XML collection
73
- # @param options [Hash]
74
- # @option options [String] :coverpage cover page HTML (Liquid template)
75
- # @option options [Array<Symbol>] :format list of formats
76
- # @option options [Strong] :ourput_folder output directory
77
- def self.render(col, options = {})
78
- warn "\n\n\n\n\nRender Init: #{DateTime.now.strftime('%H:%M:%S')}"
79
- cr = new(col, File.dirname(col.file), options)
80
- cr.files
81
- cr.concatenate(col, options)
82
- options[:format]&.include?(:html) and cr.coverpage
83
- cr.flush_files
84
- cr
85
- end
86
-
87
- def concatenate(col, options)
88
- warn "\n\n\n\n\nConcatenate: #{DateTime.now.strftime('%H:%M:%S')}"
89
- (options[:format] & %i(pdf doc)).empty? or
90
- options[:format] << :presentation
91
- concatenate_prep(col, options)
92
- concatenate_outputs(options)
93
- end
94
-
95
- def concatenate_prep(col, options)
96
- %i(xml presentation).each do |e|
97
- options[:format].include?(e) or next
98
- ext = e == :presentation ? "presentation.xml" : e.to_s
99
- File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") do |f|
100
- f.write(concatenate1(col.clone, e).to_xml)
101
- end
102
- end
103
- end
104
-
105
- def concatenate_outputs(options)
106
- pres = File.join(@outdir, "collection.presentation.xml")
107
- options[:format].include?(:pdf) and pdfconv.convert(pres)
108
- options[:format].include?(:doc) and docconv_convert(pres)
109
- end
110
-
111
- def concatenate1(out, ext)
112
- out.directives << "documents-inline"
113
- out.bibdatas.each_key do |ident|
114
- id = @isodoc.docid_prefix(nil, ident.dup)
115
- @files.get(id, :attachment) || @files.get(id, :outputs).nil? and next
116
- out.documents[Util::key id] =
117
- Metanorma::Document.raw_file(@files.get(id, :outputs)[ext])
118
- end
119
- out
120
- end
121
-
122
- # infer the flavour from the first document identifier; relaton does that
123
- def doctype
124
- if (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier/@type")&.text)
125
- dt = docid.downcase
126
- elsif (docid = @xml.at("//xmlns:bibdata/xmlns:docidentifier")&.text)
127
- dt = docid.sub(/\s.*$/, "").lowercase
128
- else return "standoc"
129
- end
130
- @registry = Metanorma::Registry.instance
131
- @registry.alias(dt.to_sym)&.to_s || dt
132
- end
133
-
134
- # populate liquid template of ARGV[1] with metadata extracted from
135
- # collection manifest
136
- def coverpage
137
- @coverpage or return
138
- warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}"
139
- File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
140
- f.write @isodoc.populate_template(File.read(@coverpage))
141
- end
142
- end
143
-
144
- # @param elm [Nokogiri::XML::Element]
145
- # @return [String]
146
- def indexfile_title(elm)
147
- elm.at(ns("./title"))&.text
148
- end
149
-
150
- # uses the identifier to label documents; other attributes (title) can be
151
- # looked up in @files[id][:bibdata]
152
- #
153
- # @param elm [Nokogiri::XML::Element]
154
- # @param builder [Nokogiri::XML::Builder]
155
- def indexfile_docref(elm, builder)
156
- return "" unless elm.at(ns("./docref[@index = 'true']"))
157
-
158
- builder.ul { |b| docrefs(elm, b) }
159
- end
160
-
161
- # @param elm [Nokogiri::XML::Element]
162
- # @param builder [Nokogiri::XML::Builder]
163
- def docrefs(elm, builder)
164
- elm.xpath(ns("./docref[@index = 'true']")).each do |d|
165
- ident = docref_ident(d)
166
- builder.li do |li|
167
- li.a href: index_link(d, ident) do |a|
168
- a << ident.split(/([<>&])/).map do |x|
169
- /[<>&]/.match?(x) ? x : @c.encode(x, :hexadecimal)
170
- end.join
171
- end
172
- end
173
- end
174
- end
175
-
176
- def docref_ident(docref)
177
- ident = docref.at(ns("./identifier")).children.to_xml
178
- @c.decode(@isodoc.docid_prefix(nil, ident))
179
- end
180
-
181
- def index_link(docref, ident)
182
- if docref["fileref"]
183
- @files.get(ident, :out_path).sub(/\.xml$/, ".html")
184
- else "#{docref['id']}.html"
185
- end
186
- end
187
-
188
- # single level navigation list, with hierarchical nesting
189
- #
190
- # @param elm [Nokogiri::XML::Element]
191
- # @return [String] XML
192
- def indexfile(elm)
193
- Nokogiri::HTML::Builder.new do |b|
194
- b.ul do
195
- b.li indexfile_title(elm)
196
- indexfile_docref(elm, b)
197
- elm.xpath(ns("./manifest")).each do |d|
198
- b << indexfile(d)
199
- end
200
- end
201
- end.doc.root.to_html
202
- end
203
-
204
- # object to construct navigation out of in Liquid
205
- def index_object(elm)
206
- c = elm.xpath(ns("./manifest")).each_with_object([]) do |d, b|
207
- b << index_object(d)
208
- end
209
- c.empty? and c = nil
210
- r = Nokogiri::HTML::Builder.new do |b|
211
- indexfile_docref(elm, b)
212
- end
213
- r &&= r.doc.root&.to_html&.gsub("\n", " ")
214
- { title: indexfile_title(elm),
215
- docrefs: r, children: c }.compact
216
- end
217
-
218
- def liquid_docrefs
219
- @xml.xpath(ns("//docref[@index = 'true']")).each_with_object([]) do |d, m|
220
- ident = d.at(ns("./identifier")).children.to_xml
221
- ident = @c.decode(@isodoc.docid_prefix(nil, ident))
222
- title = d.at(ns("./bibdata/title[@type = 'main']")) ||
223
- d.at(ns("./bibdata/title")) || d.at(ns("./title"))
224
- m << { "identifier" => ident, "file" => index_link(d, ident),
225
- "title" => title&.children&.to_xml,
226
- "level" => d.at(ns("./level"))&.text }
227
- end
228
- end
229
- end
230
- end
@@ -1,133 +0,0 @@
1
- module Metanorma
2
- class Document
3
- # @return [Strin]
4
- attr_reader :file, :attachment, :bibitem, :index
5
-
6
- # @param bibitem [RelatonBib::BibliographicItem]
7
- def initialize(bibitem, file, options = {})
8
- @bibitem = bibitem
9
- @file = file
10
- @attachment = options[:attachment]
11
- @index = options[:index]
12
- @index = true if @index.nil?
13
- @raw = options[:raw]
14
- end
15
-
16
- class << self
17
- # @param file [String] file path
18
- # @param attachment [Bool] is an attachment
19
- # @param identifier [String] is the identifier assigned the file
20
- # in the collection file
21
- # @param index [Bool] is indication on whether to index this file in coverpage
22
- # @return [Metanorma::Document]
23
- def parse_file(file, attachment, identifier = nil, index = true)
24
- new(bibitem(file, attachment, identifier), file,
25
- { attachment: attachment, index: index })
26
- end
27
-
28
- # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
29
- # @return [Metanorma::Document]
30
- def parse_xml(xml)
31
- new from_xml(xml)
32
- end
33
-
34
- # raw XML file, can be used to put in entire file instead of just bibitem
35
- def raw_file(filename)
36
- doc = Nokogiri::XML(File.read(filename, encoding: "UTF-8")) do |config|
37
- config.huge
38
- end
39
- new(doc, filename, raw: true)
40
- end
41
-
42
- def attachment_bibitem(identifier)
43
- Nokogiri::XML <<~DOCUMENT
44
- <bibdata><docidentifier>#{identifier}</docidentifier></bibdata>
45
- DOCUMENT
46
- end
47
-
48
- private
49
-
50
- def mn2relaton_parser(tag)
51
- case tag.sub(/-standard/, "")
52
- when "bipm" then RelatonBipm::XMLParser
53
- when "bsi" then RelatonBsi::XMLParser
54
- when "ietf" then RelatonIetf::XMLParser
55
- when "iho" then RelatonIho::XMLParser
56
- when "itu" then RelatonItu::XMLParser
57
- when "iec" then RelatonIec::XMLParser
58
- when "iso" then RelatonIsoBib::XMLParser
59
- when "nist" then RelatonNist::XMLParser
60
- when "ogc" then RelatonOgc::XMLParser
61
- else RelatonBib::XMLParser
62
- end
63
- end
64
-
65
- # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
66
- # @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
67
- def from_xml(xml)
68
- b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
69
- r = mn2relaton_parser(xml.root.name)
70
- r.from_xml(b.to_xml)
71
- end
72
-
73
- # @param file [String]
74
- # @return [Symbol] file type
75
- def format(file)
76
- case file
77
- when /\.xml$/ then :xml
78
- when /.ya?ml$/ then :yaml
79
- end
80
- end
81
-
82
- # @param file [String]
83
- # @return [RelatonBib::BibliographicItem,
84
- # RelatonIso::IsoBibliographicItem]
85
- def bibitem(file, attachment, identifier)
86
- if attachment then attachment_bibitem(identifier)
87
- else
88
- case format(file)
89
- when :xml
90
- from_xml (Nokogiri::XML(File.read(file, encoding: "UTF-8")) { |x| x.huge })
91
- when :yaml
92
- yaml = File.read(file, encoding: "UTF-8")
93
- Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
94
- end
95
- end
96
- end
97
- end
98
-
99
- # @param builder [Nokogiri::XML::Builder, nil]
100
- # @return [Nokogiri::XML::Builder, String]
101
- def to_xml(builder = nil)
102
- if builder
103
- render_xml builder
104
- else
105
- Nokogiri::XML::Builder.new do |b|
106
- root = render_xml b
107
- root["xmlns"] = "http://metanorma.org"
108
- end.to_xml
109
- end
110
- end
111
-
112
- # @return [String]
113
- def type
114
- first = @bibitem.docidentifier.first
115
- @type ||= (first&.type&.downcase ||
116
- first&.id&.match(/^[^\s]+/)&.to_s)&.downcase ||
117
- "standoc"
118
- end
119
-
120
- private
121
-
122
- def render_xml(builder)
123
- if @raw
124
- #builder << @bibitem.root.to_xml
125
- builder.parent.add_child(@bibitem.root)
126
- else
127
- builder.send("#{type}-standard") do |b|
128
- b << @bibitem.to_xml(bibdata: true)
129
- end
130
- end
131
- end
132
- end
133
- end