module IsoDoc
class PresentationXMLConvert < ::IsoDoc::Convert
def prefix_name(node, delims, label, elem)
label, delims = prefix_name_defaults(node, delims, label)
name, ins, ids, number = prefix_name_prep(node, elem)
ins.next = fmt_xref_label(label, number, ids)
# autonum can be empty, e.g single note in clause: "NOTE []"
number and node["autonum"] = number.gsub(/<[^>]+>/, "")
!node.at(ns("./fmt-#{elem}")) &&
(c = fmt_caption(label, elem, name, ids, delims)) and ins.next = c
prefix_name_postprocess(node, elem)
end
def prefix_name_defaults(node, delims, label)
label&.empty? and label = nil
delims.nil? and delims = {}
[label, delims]
end
def prefix_name_prep(node, elem)
lbls = prefix_name_labels(node)
name = node.at(ns("./#{elem}")) and name["id"] = lbls[:name]
ins = name || node.add_first_child("").elements.first
node["unnumbered"] or
number = @xrefs.anchor(node["id"], :value, false)&.strip
[name, ins, lbls, number]
end
def prefix_name_labels(node)
{ elem: node["id"],
name: "_#{UUIDTools::UUID.random_create}" }
end
def prefix_name_postprocess(node, elem)
node.at(ns("./sentinel"))&.remove
strip_duplicate_ids(node, node.at(ns("./#{elem}")),
node.at(ns("./fmt-#{elem}")))
end
def transfer_id(old, new)
old["id"] or return
new["id"] = old["id"]
old["original-id"] = old["id"]
old.delete("id")
end
def gather_all_ids(elem)
elem.xpath(".//*[@id]").each_with_object([]) do |i, m|
m << i["id"]
end
end
# remove ids duplicated between title and fmt-title
# index terms are assumed transferred to fmt-title from title
def strip_duplicate_ids(_node, sem_title, pres_title)
sem_title && pres_title or return
ids = gather_all_ids(pres_title)
sem_title.xpath(".//*[@id]").each do |x|
ids.include?(x["id"]) or next
x["original-id"] = x["id"]
x.delete("id")
end
sem_title.xpath(ns(".//index")).each(&:remove)
end
def semx(node, label, element = "autonum")
id = node["id"] || node[:id]
/#{l})
end
def autonum(id, num)
/#{num}"
end
def labelled_autonum(label, id, num)
elem = "#{label}"
num.blank? and return elem
l10n("#{elem} #{autonum(id, num)}")
end
def fmt_xref_label(label, _number, ids)
label or return ""
x = @xrefs.anchor(ids[:elem], :xref, false) or return ""
ret = "#{x}"
container = @xrefs.anchor(ids[:elem], :container, false)
y = prefix_container_fmt_xref_label(container, x)
y != x and
ret += "#{y}"
ret
end
def prefix_container_fmt_xref_label(container, xref)
container or return xref
container_container = @xrefs.anchor(container, :container, false)
container_label =
prefix_container_fmt_xref_label(container_container,
@xrefs.anchor(container, :xref, false))
l10n(connectives_spans(@i18n.nested_xref
.sub("%1", "#{container_label}")
.sub("%2", xref)))
end
# detect whether string which may contain XML markup is empty
def empty_xml?(str)
str.blank? and return true
x = Nokogiri::XML::DocumentFragment.parse(str)
x.to_str.strip.empty?
end
# Remove ".blank?" tests if want empty delim placeholders for manipulation
def fmt_caption(label, elem, name, ids, delims)
label = fmt_caption_label_wrap(label)
c = fmt_caption2(label, elem, name, ids, delims)
empty_xml?(c) and return
!delims[:label].blank? and
f = "#{delims[:label]}"
"#{c}#{f}"
end
def fmt_caption_label_wrap(label)
empty_xml?(label) || %r{#{to_xml(name.children)}"
elsif label then label
end
end
end
end