require_relative "image" require_relative "sourcecode" require_relative "autonum" require "rouge" module IsoDoc class PresentationXMLConvert < ::IsoDoc::Convert def lower2cap(text) text.nil? and return text x = Nokogiri::XML("#{text}") firsttext = x.at(".//text()[string-length(normalize-space(.))>0]") or return text /^[[:upper:]][[:upper:]]/.match?(firsttext.text) and return text firsttext.replace(firsttext.text.capitalize) to_xml(x.root.children) end def block_delim " — " end def formula(docxml) docxml.xpath(ns("//formula")).each { |f| formula1(f) } end def formula1(elem) formula_where(elem.at(ns("./dl"))) lbl = @xrefs.anchor(elem["id"], :label, false) lbl.nil? || lbl.empty? or prefix_name(elem, {}, lbl, "name") end def formula_where(dlist) dlist or return dlist["class"] = "formula_dl" where = dlist.xpath(ns("./dt")).size > 1 ? @i18n.where : @i18n.where_one dlist.previous = "

#{where}

" end def example(docxml) docxml.xpath(ns("//example")).each { |f| example1(f) } end def example1(elem) n = @xrefs.get[elem["id"]] lbl = labelled_autonum(@i18n.example, elem["id"], n&.dig(:label)) prefix_name(elem, { caption: block_delim }, lbl, "name") end def note(docxml) docxml.xpath(ns("//note")).each { |f| note1(f) } end def note_delim(_elem) "" end def note1(elem) %w(bibdata bibitem).include?(elem.parent.name) || elem["notag"] == "true" or lbl = note_label(elem) prefix_name(elem, { label: note_delim(elem) }, lbl, "name") end def note_label(elem) n = @xrefs.get[elem["id"]] labelled_autonum(@i18n.note, elem["id"], n&.dig(:label)) end def admonition(docxml) docxml.xpath(ns("//admonition")).each { |f| admonition1(f) } end def admonition1(elem) if elem["type"] == "box" admonition_numbered1(elem) elsif elem["notag"] == "true" || elem.at(ns("./name")) prefix_name(elem, { label: admonition_delim(elem) }, nil, "name") else label = admonition_label(elem, nil) prefix_name(elem, { label: admonition_delim(elem) }, label, "name") end end def admonition_numbered1(elem) # elem["unnumbered"] && !elem.at(ns("./name")) and return label = admonition_label(elem, @xrefs.anchor(elem["id"], :label, false)) prefix_name(elem, { caption: block_delim }, label, "name") end def admonition_label(elem, num) lbl = if elem["type"] == "box" then @i18n.box else @i18n.admonition[elem["type"]]&.upcase end #lbl &&= "#{lbl}" #num and lbl = l10n("#{lbl} #{autonum(elem['id'], num)}") labelled_autonum(lbl, elem["id"], num) end def admonition_delim(_elem) "" end def table(docxml) table_long_strings_cleanup(docxml) docxml.xpath(ns("//table")).each { |f| table1(f) } end def table1(elem) table_fn(elem) labelled_ancestor(elem) and return elem["unnumbered"] && !elem.at(ns("./name")) and return n = @xrefs.anchor(elem["id"], :label, false) #lbl = "#{lower2cap @i18n.table} "\ #"#{autonum(elem['id'], n)}" lbl = labelled_autonum(lower2cap(@i18n.table), elem["id"], n) prefix_name(elem, { caption: table_delim }, l10n(lbl), "name") end def table_delim block_delim end def table_long_strings_cleanup(docxml) @break_up_urls_in_tables or return docxml.xpath(ns("//td | //th")).each do |d| d.traverse do |n| n.text? or next ret = Metanorma::Utils::break_up_long_str(n.text) n.content = ret end end end def table_fn(elem) (elem.xpath(ns(".//fn")) - elem.xpath(ns("./name//fn"))) .each_with_index do |f, i| table_fn1(elem, f, i) end end def table_fn1(table, fnote, idx); end # we use this to eliminate the semantic amend blocks from rendering def amend(docxml) docxml.xpath(ns("//amend")).each { |f| amend1(f) } end def amend1(elem) elem.xpath(ns("./locality | ./localityStack | ./autonumber | " \ "./classification | ./contributor")).each(&:remove) elem.xpath(ns("./newcontent")).each { |a| a.name = "quote" } elem.xpath(ns("./description")).each { |a| a.replace(a.children) } elem.replace(elem.children) end def dl(docxml) docxml.xpath(ns("//dl")).each { |f| dl1(f) } end def dl1(elem) elem.at(ns("./name")) and prefix_name(elem, {}, "", "name") # copy name to fmt-name end def ul(docxml) docxml.xpath(ns("//ul")).each { |f| ul1(f) } end def ul1(elem) elem.at(ns("./name")) and prefix_name(elem, {}, "", "name") # copy name to fmt-name end def ol(docxml) docxml.xpath(ns("//ol")).each { |f| ol1(f) } @xrefs.list_anchor_names(docxml.xpath(ns(@xrefs.sections_xpath))) docxml.xpath(ns("//ol/li")).each { |f| ol_label(f) } end # We don't really want users to specify type of ordered list; # we will use by default a fixed hierarchy as practiced by ISO (though not # fully spelled out): a) 1) i) A) I) def ol_depth(node) depth = node.ancestors("ul, ol").size + 1 type = :alphabet type = :arabic if [2, 7].include? depth type = :roman if [3, 8].include? depth type = :alphabet_upper if [4, 9].include? depth type = :roman_upper if [5, 10].include? depth type end def ol1(elem) elem["type"] ||= ol_depth(elem).to_s elem.at(ns("./name")) and prefix_name(elem, {}, "", "name") # copy name to fmt-name end def ol_label(elem) elem["label"] = @xrefs.anchor(elem["id"], :label, false) end def source(docxml) docxml.xpath(ns("//source/modification")).each do |f| source_modification(f) end docxml.xpath(ns("//table/source")).each { |f| tablesource(f) } docxml.xpath(ns("//figure/source")).each { |f| figuresource(f) } end def tablesource(elem) source1(elem) end def figuresource(elem) source1(elem) end def source1(elem) while elem&.next_element&.name == "source" elem << "; #{to_xml(elem.next_element.remove.children)}" end elem.children = l10n("[#{@i18n.source}: #{to_xml(elem.children).strip}]") end def source_modification(mod) termsource_modification(mod.parent) end def quote(docxml) docxml.xpath(ns("//quote")).each { |f| quote1(f) } end def quote1(elem) author = elem.at(ns("./author")) source = elem.at(ns("./source")) author.nil? && source.nil? and return p = "— " p += author.remove.to_xml if author p += ", " if author && source if source source.name = "eref" p += source.remove.to_xml end elem << "

#{l10n p}

" end end end