metanorma 1.7.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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