require_relative "cleanup_inline" module IsoDoc module Ietf class RfcConvert < ::IsoDoc::Convert def cleanup(docxml) image_cleanup(docxml) figure_cleanup(docxml) table_cleanup(docxml) footnote_cleanup(docxml) sourcecode_cleanup(docxml) li_cleanup(docxml) deflist_cleanup(docxml) bookmark_cleanup(docxml) cref_cleanup(docxml) front_cleanup(docxml) u_cleanup(docxml) biblio_cleanup(docxml) # feeds aside aside_cleanup(docxml) docxml end def biblio_cleanup(xmldoc) biblio_abstract_cleanup(xmldoc) biblio_date_cleanup(xmldoc) biblio_refcontent_cleanup(xmldoc) annotation_cleanup(xmldoc) end def biblio_date_cleanup(xmldoc) xmldoc.xpath("//date[@cleanme]").each do |a| a.delete("cleanme") d = @c.decode(a.text).gsub(/–/, "-").sub(/-\d\d\d\d.*$/, "") if attrs = date_attr(d) attrs.each do |k, v| a[k] = v end a.children.remove else a.remove end end end def biblio_abstract_cleanup(xmldoc) xmldoc.xpath("//abstract[@cleanme]").each do |a| a.delete("cleanme") ret = reparse_abstract(a) a.children = if a.at("./p") then ret else "#{ret}" end end end def biblio_refcontent_cleanup(xmldoc) xmldoc.xpath("//refcontent").each do |a| val = a.text.strip if val.empty? then a.remove else a.children = val end end end def reparse_abstract(abstract) a1 = Nokogiri::XML(abstract.dup.to_xml .sub("", "")).root noko do |xml| a1.children.each { |n| parse(n, xml) } end.join end def li_cleanup(xmldoc) xmldoc.xpath("//li[t]").each do |li| next unless li.elements.size == 1 li.children = li.elements[0].children end end def front_cleanup(xmldoc) xmldoc.xpath("//title").each { |s| s.children = s.text } xmldoc.xpath("//reference/front[not(author)]").each do |f| insert = f.at("./seriesInfo[last()]") || f.at("./title") insert.next = "" end end def table_footnote_cleanup(docxml) docxml.xpath("//table[descendant::fn]").each do |t| t.xpath(".//fn").each do |a| t << "" end end end def figure_footnote_cleanup(docxml) docxml.xpath("//figure[descendant::fn]").each do |t| t.xpath(".//fn").each do |a| t << "" end end end def table_cleanup(docxml) table_footnote_cleanup(docxml) end def figure_cleanup(docxml) figure_postamble(docxml) figure_unnest(docxml) figure_footnote_cleanup(docxml) figure_data_uri(docxml) end def figure_data_uri(docxml) docxml.xpath("//artwork").each do |a| next unless %r{^data:image/svg\+xml;base64}.match?(a["src"]) f = Metanorma::Utils::save_dataimage(a["src"]) a.delete("src") a.children = File.read(f).sub(%r{<\?.+\?>}, "") end end def figure_unnest(docxml) docxml.xpath("//figure[descendant::figure]").each do |f| insert = f f.xpath(".//figure").each do |a| title = f.at("./name") and a.children.first.previous = title.remove insert.next = a.remove insert = insert.next_element end f.remove end end def figure_postamble(docxml) make_postamble(docxml) move_postamble(docxml) move_preamble(docxml) end def make_postamble(docxml) docxml.xpath("//figure").each do |f| a = f.at("./artwork | ./sourcecode") || next name = f.at("./name")&.remove b = a.xpath("./preceding-sibling::*")&.remove c = a.xpath("./following-sibling::*")&.remove a = a.remove name and f << name b.empty? or f << "#{to_xml(b)}" a and f << a c.empty? or f << "#{to_xml(c)}" end end def move_postamble(docxml) docxml.xpath("//postamble").each do |p| insert = p.parent p.remove.elements.each do |e| insert.next = e insert = insert.next_element end end end def move_preamble(docxml) docxml.xpath("//preamble").each do |p| insert = p.parent p.remove.elements.each do |e| insert.previous = e end end end # for markup in pseudocode def sourcecode_cleanup(docxml) docxml.xpath("//sourcecode").each do |s| s.children = to_xml(s.children).gsub(%r{
\n}, "\n") .gsub(%r{\s+(])}, "\\1").gsub(%r{\s+}, "") sourcecode_remove_markup(s) s.children = "" end end def sourcecode_remove_markup(node) node.traverse do |n| next if n.text? next if %w(name callout annotation note sourcecode).include? n.name case n.name when "br" then n.replace("\n") when "t" then n.replace("\n\n#{n.children}") else n.replace(n.children) end end end def annotation_cleanup(docxml) docxml.xpath("//reference").each do |r| while r.next_element&.name == "aside" annotation_cleanup1(r) end end docxml.xpath("//references/aside").each(&:remove) end def annotation_cleanup1(ref) aside = ref.next_element aside.name = "annotation" aside.traverse do |n| n.name == "t" and n.replace(n.children) end ref << aside end def deflist_cleanup(docxml) dt_cleanup(docxml) dd_cleanup(docxml) end def dt_cleanup(docxml) docxml.xpath("//dt").each do |d| d.first_element_child&.name == "bookmark" and d["anchor"] ||= d.first_element_child["anchor"] d.xpath(".//t").each do |t| d["anchor"] ||= t["anchor"] t.replace(t.children) end end end def dd_cleanup(docxml) docxml.xpath("//dd").each do |d| d&.first_element_child&.name == "bookmark" and d["anchor"] ||= d.first_element_child["anchor"] end end def aside_cleanup(docxml) docxml.xpath("//*[aside]").each do |p| %w(section).include?(p.name) and next insert = p p.xpath("./aside").each do |a| insert.next = a.remove insert = insert.next_element end end end end end end