require "date" require "nokogiri" require "htmlentities" require "json" require "pathname" require "open-uri" require "pp" require "isodoc" module Asciidoctor module ISO module Base def content(node) node.content end def skip(node, name = nil) name = name || node.node_name w = "converter missing for #{name} node in ISO backend" warning(node, w, nil) nil end def html_doc_path(file) File.join(File.dirname(__FILE__), File.join("html", file)) end def doc_converter IsoDoc::Convert.new( htmlstylesheet: html_doc_path("htmlstyle.css"), wordstylesheet: nil, standardstylesheet: html_doc_path("isodoc.css"), header: html_doc_path("header.html"), htmlcoverpage: html_doc_path("html_iso_titlepage.html"), wordcoverpage: html_doc_path("word_iso_titlepage.html"), htmlintropage: html_doc_path("html_iso_intro.html"), wordintropage: html_doc_path("word_iso_intro.html"), ) end def init @fn_number = 0 @draft = false @refids = Set.new @anchors = {} end def document(node) init ret1 = makexml(node) validate(ret1) ret = ret1.to_xml(indent: 2) filename = node.attr("docfile").gsub(/\.adoc/, ".xml"). gsub(%r{^.*/}, '') File.open("#{filename}", "w") { |f| f.write(ret) } doc_converter.convert filename ret end def makexml(node) result = ["\n"] @draft = node.attributes.has_key?("draft") result << noko { |ixml| front node, ixml } result << noko { |ixml| middle node, ixml } result << "" result = textcleanup(result.flatten * "\n") ret1 = cleanup(Nokogiri::XML(result)) ret1.root.add_namespace(nil, "http://riboseinc.com/isoxml") ret1 end def is_draft @draft end def front(node, xml) title node, xml metadata node, xml end def middle(node, xml) xml.sections do |s| s << node.content if node.blocks? end end def add_term_source(xml_t, seen_xref, m) attr = { bibitemid: seen_xref.children[0]["target"], format: seen_xref.children[0]["format"] } xml_t.origin seen_xref.children[0].content, **attr_code(attr) xml_t.isosection m[:section].gsub(/ /, "") if m[:section] if m[:text] xml_t.modification do |mod| mod.p { |p| p << m[:text] } end end end TERM_REFERENCE_RE_STR = <<~REGEXP ^(?]+>) (,\s(?
[^, ]+))? (,\s(?.*))? $ REGEXP TERM_REFERENCE_RE = Regexp.new(TERM_REFERENCE_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"), Regexp::IGNORECASE) def extract_termsource_refs(text) matched = TERM_REFERENCE_RE.match text if matched.nil? warning(node, "term reference not in expected format", text) end matched end def termsource(node) matched = extract_termsource_refs(node.content) or return noko do |xml| attrs = { status: matched[:text] ? "identical" : "modified" } xml.termsource **attrs do |xml_t| seen_xref = Nokogiri::XML.fragment(matched[:xref]) add_term_source(xml_t, seen_xref, matched) style(node, matched[:text]) end end.join("\n") end def paragraph(node) return termsource(node) if node.role == "source" attrs = { align: node.attr("align"), id: Utils::anchor_or_uuid(node) } noko do |xml| xml.p **attr_code(attrs) do |xml_t| xml_t << node.content style(node, Utils::flatten_rawtext(node).join(" ")) end end.join("\n") end def inline_footnote(node) noko do |xml| @fn_number += 1 xml.fn **{reference: @fn_number} do |fn| # TODO multi-paragraph footnotes fn.p { |p| p << node.text } footnote_style(node, node.text) end end.join("\n") end def open(node) # open block is a container of multiple blocks, # treated as a single block. # We append each contained block to its parent result = [] if node.blocks? node.blocks.each do |b| result << send(b.context, b) end else result = paragraph(node) end result end def inline_break(node) noko do |xml| xml << node.text xml.br end.join("\n") end def page_break(node) noko do |xml| xml << node.text xml.pagebreak end.join("\n") end def thematic_break(node) noko do |xml| xml << node.text xml.hr end.join("\n") end def inline_quoted(node) noko do |xml| case node.type when :emphasis then xml.em node.text when :strong then xml.strong node.text when :monospaced then xml.tt node.text when :double then xml << "\"#{node.text}\"" when :single then xml << "'#{node.text}'" when :superscript then xml.sup node.text when :subscript then xml.sub node.text when :asciimath then xml.stem node.text, **{ type: "AsciiMath" } else case node.role when "alt" then xml.admitted { |a| a << node.text } when "deprecated" then xml.deprecates { |a| a << node.text } when "domain" then xml.domain { |a| a << node.text } when "strike" then xml.strike node.text when "smallcap" then xml.smallcap node.text else xml << node.text end end end.join end end end end