lib/isodoc/presentation_function/block.rb
require_relative "image"
require_relative "sourcecode"
require "rouge"
module IsoDoc
class PresentationXMLConvert < ::IsoDoc::Convert
def lower2cap(text)
/^[[:upper:]][[:upper:]]/.match?(text) and return text
text.capitalize
end
def block_delim
" — "
end
def prefix_name(node, delim, number, elem)
number.nil? || number.empty? and return
unless name = node.at(ns("./#{elem}"))
(node.children.empty? and node.add_child("<#{elem}></#{elem}>")) or
node.children.first.previous = "<#{elem}></#{elem}>"
name = node.children.first
end
if name.children.empty? then name.add_child(cleanup_entities(number.strip))
else (name.children.first.previous = "#{number.strip}#{delim}")
end
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)
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 = "<p keep-with-next='true'>#{where}</p>"
end
def example(docxml)
docxml.xpath(ns("//example")).each { |f| example1(f) }
end
def example1(elem)
n = @xrefs.get[elem["id"]]
lbl = if n.nil? || n[:label].nil? || n[:label].empty?
@i18n.example
else l10n("#{@i18n.example} #{n[:label]}")
end
prefix_name(elem, block_delim, lbl, "name")
end
def note(docxml)
docxml.xpath(ns("//note")).each { |f| note1(f) }
end
def note1(elem)
%w(bibdata bibitem).include?(elem.parent.name) ||
elem["notag"] == "true" and return
n = @xrefs.get[elem["id"]]
lbl = @i18n.note
(n.nil? || n[:label].nil? || n[:label].empty?) or
lbl = l10n("#{lbl} #{n[:label]}")
prefix_name(elem, "", lbl, "name")
end
def admonition(docxml)
docxml.xpath(ns("//admonition")).each { |f| admonition1(f) }
end
def admonition1(elem)
if elem["type"] == "box"
admonition_numbered1(elem)
else
elem["notag"] == "true" || elem.at(ns("./name")) and return
prefix_name(elem, "", @i18n.admonition[elem["type"]]&.upcase, "name")
end
end
def admonition_numbered1(elem)
elem["unnumbered"] && !elem.at(ns("./name")) and return
n = @xrefs.anchor(elem["id"], :label, false)
prefix_name(elem, block_delim, l10n("#{@i18n.box} #{n}"), "name")
end
def table(docxml)
table_long_strings_cleanup(docxml)
docxml.xpath(ns("//table")).each { |f| table1(f) }
end
def table1(elem)
labelled_ancestor(elem) and return
elem["unnumbered"] && !elem.at(ns("./name")) and return
n = @xrefs.anchor(elem["id"], :label, false)
prefix_name(elem, block_delim, l10n("#{lower2cap @i18n.table} #{n}"),
"name")
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
# 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("./autonumber")).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 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.xpath(ns("./li")).each do |li|
li["id"] ||= "_#{UUIDTools::UUID.random_create}"
end
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
end
end