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