Class: Metanorma::Collection::Sectionsplit
- Inherits:
-
Object
- Object
- Metanorma::Collection::Sectionsplit
- Defined in:
- lib/metanorma/collection/sectionsplit/collection.rb,
lib/metanorma/collection/sectionsplit/sectionsplit.rb
Constant Summary collapse
- SPLITSECTIONS =
[["//preface/*", "preface"], ["//sections/*", "sections"], ["//annex", nil], ["//bibliography/*[not(@hidden = 'true')]", "bibliography"], ["//indexsect", nil], ["//colophon", nil]].freeze
- FN_CAPTIONS =
".//fmt-fn-label/span[@class = 'fmt-caption-label']".freeze
Instance Attribute Summary collapse
-
#filecache ⇒ Object
Returns the value of attribute filecache.
-
#key ⇒ Object
Returns the value of attribute key.
Instance Method Summary collapse
- #att_dir(file) ⇒ Object
-
#block?(node) ⇒ Boolean
TODO move to metanorma-utils.
- #build_collection ⇒ Object
- #coll_cover ⇒ Object
- #collection_manifest(filename, files, origxml, _presxml, dir) ⇒ Object
- #collection_setup(filename, dir) ⇒ Object
- #collectionyaml(files, xml) ⇒ Object
- #conflate_floatingtitles(nodes) ⇒ Object
- #create_sectionfile(xml, out, file, chunks, parentnode) ⇒ Object
- #empty_attachments(xml) ⇒ Object
- #empty_doc(xml) ⇒ Object
-
#initialize(opts) ⇒ Sectionsplit
constructor
A new instance of Sectionsplit.
- #ns(xpath) ⇒ Object
- #section_split_attachments(out: nil) ⇒ Object
- #section_split_cover(col, ident, one_doc_coll) ⇒ Object
- #section_split_cover1(ident, renderer, dir, _one_doc_coll) ⇒ Object
- #sectionfile(fulldoc, xml, file, chunks, parentnode) ⇒ Object
- #sectionfile_fn_filter(xml) ⇒ Object
- #sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen) ⇒ Object
- #sectionfile_fn_filter_fnbody_renumber(fnbody, _idx, ids) ⇒ Object
-
#sectionfile_fn_filter_prep(xml) ⇒ Object
map fmt-fn-body/@id = fn/@target to fn.
- #sectionfile_fn_filter_renumber(fnbody, idx, ids, seen) ⇒ Object
- #sectionfile_insert(ins, chunks, parentnode) ⇒ Object
- #sectionfile_review_filter(xml) ⇒ Object
-
#sectionfile_review_filter_prep(xml) ⇒ Object
map fmt-review-body/@id = fmt-review-start/end/@target to fmt-review-stary/end.
- #sectionfile_review_filter_renumber(fnbody, _idx, ids) ⇒ Object
-
#sectionsplit ⇒ Object
Input XML is Semantic XML.
-
#sectionsplit1(xml, empty, empty1, idx) ⇒ Object
xml is Presentation XML.
- #sectionsplit2(xml, empty, chunks, parentnode, opt) ⇒ Object
- #sectionsplit_prep(file, filename, dir) ⇒ Object
- #sectionsplit_preprocess_semxml(file, filename) ⇒ Object
- #sectionsplit_update_xrefs(xml) ⇒ Object
- #sectionsplit_write_semxml(filename, xml) ⇒ Object
- #titlerender(section) ⇒ Object
Constructor Details
#initialize(opts) ⇒ Sectionsplit
Returns a new instance of Sectionsplit.
12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 12 def initialize(opts) @input_filename = opts[:input] @base = opts[:base] @output_filename = opts[:output] @xml = opts[:xml] @dir = opts[:dir] @compile_opts = opts[:compile_opts] || {} @fileslookup = opts[:fileslookup] @ident = opts[:ident] @isodoc = opts[:isodoc] @isodoc_presxml = opts[:isodoc_presxml] @document_suffix = opts[:document_suffix] end |
Instance Attribute Details
#filecache ⇒ Object
Returns the value of attribute filecache.
10 11 12 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 10 def filecache @filecache end |
#key ⇒ Object
Returns the value of attribute key.
10 11 12 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 10 def key @key end |
Instance Method Details
#att_dir(file) ⇒ Object
66 67 68 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 66 def att_dir(file) "_#{File.basename(file, '.*')}_attachments" end |
#block?(node) ⇒ Boolean
TODO move to metanorma-utils
72 73 74 75 76 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 72 def block?(node) %w(p table formula admonition ol ul dl figure quote sourcecode example pre note pagebreak hr bookmark requirement recommendation permission svgmap inputform toc passthrough review imagemap).include?(node.name) end |
#build_collection ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 4 def build_collection collection_setup(@base, @dir) files = sectionsplit input_xml = Nokogiri::XML(File.read(@input_filename, encoding: "UTF-8"), &:huge) collection_manifest(@base, files, input_xml, @xml, @dir).render( { format: i(html), output_folder: "#{@output_filename}_collection", coverpage: File.join(@dir, "cover.html") }.merge(@compile_opts), ) (out: "#{@output_filename}_collection") end |
#coll_cover ⇒ Object
24 25 26 27 28 29 30 31 32 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 24 def coll_cover " <html><head><meta charset=\"UTF-8\"/></head><body>\n <h1>{{ doctitle }}</h1>\n <h2>{{ docnumber }}</h2>\n <nav>{{ navigation }}</nav>\n </body></html>\n COVER\nend\n" |
#collection_manifest(filename, files, origxml, _presxml, dir) ⇒ Object
34 35 36 37 38 39 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 34 def collection_manifest(filename, files, origxml, _presxml, dir) File.open(File.join(dir, "#{filename}.html.yaml"), "w:UTF-8") do |f| f.write(collectionyaml(files, origxml)) end Metanorma::Collection.parse File.join(dir, "#{filename}.html.yaml") end |
#collection_setup(filename, dir) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 16 def collection_setup(filename, dir) FileUtils.mkdir_p "#{filename}_collection" if filename FileUtils.mkdir_p dir File.open(File.join(dir, "cover.html"), "w:UTF-8") do |f| f.write(coll_cover) end end |
#collectionyaml(files, xml) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 41 def collectionyaml(files, xml) #warn xml.to_xml ret = { directives: ["presentation-xml", "bare-after-first"], bibdata: { title: { type: "title-main", language: @lang, content: xml.at(ns("//bibdata/title")).text }, type: "collection", docid: { type: xml.at(ns("//bibdata/docidentifier/@type")).text, id: xml.at(ns("//bibdata/docidentifier")).text, }, }, manifest: { level: "collection", title: "Collection", docref: files.sort_by { |f| f[:order] }.each.map do |f| { fileref: f[:url], identifier: f[:title] } end }, } ::Metanorma::Util::recursive_string_keys(ret).to_yaml end |
#conflate_floatingtitles(nodes) ⇒ Object
78 79 80 81 82 83 84 85 86 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 78 def conflate_floatingtitles(nodes) holdover = false nodes.each_with_object([]) do |x, m| if holdover then m.last << x else m << [x] end holdover = block?(x) end end |
#create_sectionfile(xml, out, file, chunks, parentnode) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 151 def create_sectionfile(xml, out, file, chunks, parentnode) ins = out.at(ns("//metanorma-extension")) || out.at(ns("//bibdata")) sectionfile_insert(ins, chunks, parentnode) sectionfile_fn_filter(sectionfile_review_filter(out)) Metanorma::Collection::XrefProcess::xref_process(out, xml, @key, @ident, @isodoc, true) outname = "#{file}.xml" File.open(File.join(@splitdir, outname), "w:UTF-8") do |f| f.write(out) end outname end |
#empty_attachments(xml) ⇒ Object
141 142 143 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 141 def (xml) xml.dup end |
#empty_doc(xml) ⇒ Object
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 130 def empty_doc(xml) out = xml.dup out.xpath( ns("//preface | //sections | //annex | " \ "//references/bibitem[not(@hidden = 'true')] | " \ "//indexsect | //colophon"), ).each(&:remove) ::Metanorma::Collection::Util::hide_refs(out) out end |
#ns(xpath) ⇒ Object
26 27 28 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 26 def ns(xpath) @isodoc.ns(xpath) end |
#section_split_attachments(out: nil) ⇒ Object
70 71 72 73 74 75 76 77 78 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 70 def (out: nil) = att_dir(@tmp_filename) File.directory?() or return dir = out || File.dirname(@input_filename) ret = File.join(dir, att_dir(@output_filename)) FileUtils.rm_rf ret FileUtils.mv , ret File.basename(ret) end |
#section_split_cover(col, ident, one_doc_coll) ⇒ Object
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 80 def section_split_cover(col, ident, one_doc_coll) dir = File.dirname(col.file) collection_setup(nil, dir) r = ::Metanorma::Collection::Renderer .new(col, dir, output_folder: "#{ident}_collection", format: i(html), coverpage: File.join(dir, "cover.html")) r.coverpage section_split_cover1(ident, r, dir, one_doc_coll) end |
#section_split_cover1(ident, renderer, dir, _one_doc_coll) ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/metanorma/collection/sectionsplit/collection.rb', line 91 def section_split_cover1(ident, renderer, dir, _one_doc_coll) filename = File.basename("#{ident}_index.html") # ident can be a directory with YAML indirection dest = File.join(dir, filename) FileUtils.mv File.join(renderer.outdir, "index.html"), dest FileUtils.rm_rf renderer.outdir filename end |
#sectionfile(fulldoc, xml, file, chunks, parentnode) ⇒ Object
145 146 147 148 149 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 145 def sectionfile(fulldoc, xml, file, chunks, parentnode) fname = create_sectionfile(fulldoc, xml.dup, file, chunks, parentnode) { order: chunks.last["displayorder"].to_i, url: fname, title: titlerender(chunks.last) } end |
#sectionfile_fn_filter(xml) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 172 def sectionfile_fn_filter(xml) ids = sectionfile_fn_filter_prep(xml) xml.root.xpath(ns("./fmt-footnote-container/fmt-fn-body")).each do |f| ids.has_key?(f["id"]) or f.remove end seen = {} xml.root.xpath(ns("/fmt-footnote-container/fmt-fn-body")) .each_with_index do |fnbody, i| sectionfile_fn_filter_renumber(fnbody, i, ids, seen) end xml end |
#sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen) ⇒ Object
200 201 202 203 204 205 206 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 200 def sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen) ids[fnbody["id"]].each do |f| @isodoc_presxml.renumber_document_footnote(f, idx, seen) fnlabel = f.at(ns(FN_CAPTIONS)) and fnlabel.children = @isodoc_presxml.fn_ref_label(f) end end |
#sectionfile_fn_filter_fnbody_renumber(fnbody, _idx, ids) ⇒ Object
208 209 210 211 212 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 208 def sectionfile_fn_filter_fnbody_renumber(fnbody, _idx, ids) fnlabel = fnbody.at(ns(FN_CAPTIONS)) or return fnbody["reference"] = ids[fnbody["id"]].first["reference"] fnlabel.children = @isodoc_presxml.fn_body_label(fnbody) end |
#sectionfile_fn_filter_prep(xml) ⇒ Object
map fmt-fn-body/@id = fn/@target to fn
186 187 188 189 190 191 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 186 def sectionfile_fn_filter_prep(xml) xml.xpath(ns("//fn")).each_with_object({}) do |f, m| m[f["target"]] ||= [] m[f["target"]] << f end end |
#sectionfile_fn_filter_renumber(fnbody, idx, ids, seen) ⇒ Object
195 196 197 198 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 195 def sectionfile_fn_filter_renumber(fnbody, idx, ids, seen) sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen) sectionfile_fn_filter_fnbody_renumber(fnbody, idx, ids) end |
#sectionfile_insert(ins, chunks, parentnode) ⇒ Object
164 165 166 167 168 169 170 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 164 def sectionfile_insert(ins, chunks, parentnode) if parentnode ins.next = "<#{parentnode}/>" chunks.each { |c| ins.next.add_child(c.dup) } else chunks.each { |c| ins.next = c.dup } end end |
#sectionfile_review_filter(xml) ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 224 def sectionfile_review_filter(xml) ids = sectionfile_review_filter_prep(xml) xml.root.xpath(ns("./review-container/fmt-review-body")).each do |f| ids.has_key?(f["id"]) or f.remove end xml.root.xpath(ns("./review-container/fmt-review-body")) .each_with_index do |fnbody, i| sectionfile_review_filter_renumber(fnbody, i, ids) end xml end |
#sectionfile_review_filter_prep(xml) ⇒ Object
map fmt-review-body/@id = fmt-review-start/end/@target to fmt-review-stary/end
216 217 218 219 220 221 222 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 216 def sectionfile_review_filter_prep(xml) xml.xpath(ns("//fmt-review-start | //fmt-review-end")) .each_with_object({}) do |f, m| m[f["target"]] ||= [] m[f["target"]] << f end end |
#sectionfile_review_filter_renumber(fnbody, _idx, ids) ⇒ Object
236 237 238 239 240 241 242 243 244 245 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 236 def sectionfile_review_filter_renumber(fnbody, _idx, ids) ids[fnbody["id"]].each do |f| case f.name when "fmt-review-start" f.children = @isodoc_presxml.comment_bookmark_start_label(f) when "fmt-review-end" f.children = @isodoc_presxml.comment_bookmark_end_label(f) end end end |
#sectionsplit ⇒ Object
Input XML is Semantic XML
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 37 def sectionsplit xml = sectionsplit_prep(File.read(@input_filename), @base, @dir) @key = Metanorma::Collection::XrefProcess::xref_preprocess(xml, @isodoc) empty = empty_doc(xml) empty1 = (empty) @mutex = Mutex.new # @pool = Concurrent::FixedThreadPool.new(4) @pool = Concurrent::FixedThreadPool.new(1) sectionsplit1(xml, empty, empty1, 0) end |
#sectionsplit1(xml, empty, empty1, idx) ⇒ Object
xml is Presentation XML
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 49 def sectionsplit1(xml, empty, empty1, idx) ret = SPLITSECTIONS.each_with_object([]) do |n, m| conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s| sectionsplit2(xml, idx.zero? ? empty : empty1, s, n[1], { acc: m, idx: idx }) idx += 1 end end @pool.shutdown @pool.wait_for_termination ret end |
#sectionsplit2(xml, empty, chunks, parentnode, opt) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 62 def sectionsplit2(xml, empty, chunks, parentnode, opt) @pool.post do warn "#{@base}.#{opt[:idx]}" a = sectionfile(xml, empty, "#{@base}.#{opt[:idx]}", chunks, parentnode) @mutex.synchronize { opt[:acc] << a } end end |
#sectionsplit_prep(file, filename, dir) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 88 def sectionsplit_prep(file, filename, dir) @splitdir = dir xml, type = sectionsplit_preprocess_semxml(file, filename) flags = { format: :asciidoc, extension_keys: [:presentation], type: type }.merge(@compile_opts) Compile.new.compile(xml, flags) f = File.open(xml.sub(/\.xml$/, ".presentation.xml"), encoding: "utf-8") r = Nokogiri::XML(f, &:huge) f.close r.xpath("//xmlns:svgmap1").each { |x| x.name = "svgmap" } r end |
#sectionsplit_preprocess_semxml(file, filename) ⇒ Object
101 102 103 104 105 106 107 108 109 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 101 def sectionsplit_preprocess_semxml(file, filename) xml = Nokogiri::XML(file, &:huge) type = xml.root["flavor"] type ||= xml.root.name.sub("-standard", "").to_sym sectionsplit_update_xrefs(xml) xml1 = sectionsplit_write_semxml(filename, xml) @tmp_filename = xml1 [xml1, type] end |
#sectionsplit_update_xrefs(xml) ⇒ Object
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 111 def sectionsplit_update_xrefs(xml) if c = @fileslookup&.parent n = c.nested c.nested = true # so unresolved erefs are not deleted c.update_xrefs(xml, @ident, {}) c.nested = n xml.xpath("//xmlns:svgmap").each { |x| x.name = "svgmap1" } # do not process svgmap until after files are split end end |
#sectionsplit_write_semxml(filename, xml) ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 122 def sectionsplit_write_semxml(filename, xml) outname = Pathname.new("tmp_#{filename}").sub_ext(".xml").to_s File.open(outname, "w:UTF-8") do |f| f.write(@isodoc.to_xml(xml)) end outname end |
#titlerender(section) ⇒ Object
247 248 249 250 251 252 253 |
# File 'lib/metanorma/collection/sectionsplit/sectionsplit.rb', line 247 def titlerender(section) title = section.at(ns("./fmt-title")) or return "[Untitled]" t = title.dup t.xpath(ns(".//tab | .//br")).each { |x| x.replace(" ") } t.xpath(ns(".//bookmark")).each(&:remove) t.xpath(".//text()").map(&:text).join end |