class Asciidoctor::Ietf::Converter

Constants

BCP_KEYWORDS
XML_NAMESPACE
XML_ROOT_TAG

Public Class Methods

new(backend, opts) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 17
def initialize(backend, opts)
  super
  @libdir = File.dirname(__FILE__)
end

Public Instance Methods

abstract_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 11
def abstract_cleanup(xmldoc)
  xmldoc.xpath("//abstract[not(text())]").each do |x|
    x.remove
    warn "Empty abstract section removed"
  end
end
annex_parse(attrs, xml, node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 188
def annex_parse(attrs, xml, node)
  attrs[:numbered] = node.attr("numbered")
  attrs[:removeInRFC] = node.attr("removeInRFC")
  attrs[:toc] = node.attr("toc")
  super
end
bcp14_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 18
def bcp14_cleanup(xmldoc)
  return unless @bcp_bold

  xmldoc.xpath("//strong").each do |s|
    next unless BCP_KEYWORDS.include?(s.text)

    s.name = "bcp14"
  end
end
cache_workgroup(_node) click to toggle source
# File lib/asciidoctor/ietf/validate.rb, line 37
def cache_workgroup(_node)
  Metanorma::Ietf::Data::WORKGROUPS
end
clause_parse(attrs, xml, node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 181
def clause_parse(attrs, xml, node)
  attrs[:numbered] = node.attr("numbered")
  attrs[:removeInRFC] = node.attr("removeInRFC")
  attrs[:toc] = node.attr("toc")
  super
end
cleanup(xmldoc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/cleanup.rb, line 4
def cleanup(xmldoc)
  bcp14_cleanup(xmldoc)
  abstract_cleanup(xmldoc)
  super
  rfc_anchor_cleanup(xmldoc)
end
content_validate(doc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/validate.rb, line 6
def content_validate(doc)
  super
  image_validate(doc)
  workgroup_validate(doc)
end
dl_attrs(node) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 26
def dl_attrs(node)
  attr_code(id: ::Metanorma::Utils::anchor_or_uuid(node),
            newline: node.attr("newline"),
            indent: node.attr("indent"),
            spacing: node.attr("spacing"))
end
doctype(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 35
def doctype(node)
  ret = super
  ret = "internet-draft" if ret == "article"
  ret
end
eref_text(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 80
def eref_text(node)
  matched = /^(of|comma|parens|bare),(.*+)$/.match node.text
  if matched.nil?
    f = nil
    c = node&.text&.sub(/^fn: /, "")
  else
    f = matched[1]
    c = matched[2]
  end
  [f, c]
end
html_extract_attributes(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 219
def html_extract_attributes(node)
  super.merge(use_xinclude: node.attr("use-xinclude"))
end
image_attributes(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/blocks.rb, line 69
def image_attributes(node)
  super.merge(attr_code(align: node.attr("align")))
end
image_validate(doc) click to toggle source
# File lib/asciidoctor/ietf/validate.rb, line 12
def image_validate(doc)
  doc.xpath("//image").each do |i|
    next if i["mimetype"] == "image/svg+xml"

    @log.add("MIME", i, "image #{i['src'][0, 40]} is not SVG!")
  end
end
inline_anchor_xref(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 63
def inline_anchor_xref(node)
  f, c = xref_text(node)
  f1, c = eref_text(node) if f.nil?
  t, rel = xref_rel(node)
  attrs = { target: t, type: "inline", displayFormat: f1, format: f,
            relative: rel }
  noko do |xml|
    xml.xref **attr_code(attrs) do |x|
      x << c
    end
  end.join
end
inline_indexterm(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 199
def inline_indexterm(node)
  noko do |xml|
    node.type == :visible and xml << node.text.sub(/^primary:(?=\S)/, "")
    terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
    if /^primary:\S/.match?(terms[0])
      terms[0].sub!(/^primary:/, "")
      has_primary = true
    end
    inline_indexterm1(has_primary, terms, xml)
  end.join
end
inline_indexterm1(has_primary, terms, xml) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 211
def inline_indexterm1(has_primary, terms, xml)
  xml.index **attr_code(primary: has_primary) do |i|
    i.primary { |x| x << terms[0] }
    a = terms[1] and i.secondary { |x| x << a }
    a = terms[2] and i.tertiary { |x| x << a }
  end
end
inline_quoted(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 41
def inline_quoted(node)
  noko do |xml|
    case node.type
    when :emphasis then xml.em { |s| s << node.text }
    when :strong then xml.strong { |s| s << node.text }
    when :monospaced then xml.tt { |s| s << node.text }
    when :double then xml << "\"#{node.text}\""
    when :single then xml << "'#{node.text}'"
    when :superscript then xml.sup { |s| s << node.text }
    when :subscript then xml.sub { |s| s << node.text }
    when :asciimath then stem_parse(node.text, xml, :asciimath)
    when :latexmath then stem_parse(node.text, xml, :latexmath)
    else
      case node.role
      when "bcp14" then xml.bcp14 { |s| s << node.text.upcase }
      else
        xml << node.text
      end
    end
  end.join
end
introduction_parse(attrs, xml, node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 195
def introduction_parse(attrs, xml, node)
  clause_parse(attrs, xml, node)
end
isodoc(lang, script, i18nyaml = nil) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 227
def isodoc(lang, script, i18nyaml = nil)
  conv = rfc_converter(EmptyAttr.new)
  i18n = conv.i18n_init(lang, script, i18nyaml)
  conv.metadata_init(lang, script, i18n)
  conv
end
listing_attrs(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/blocks.rb, line 73
def listing_attrs(node)
  super.merge(attr_code(markers: node.attr("markers"), src: node.attr("src")))
end
literal(node) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 57
def literal(node)
  noko do |xml|
    xml.figure **literal_attrs(node) do |f|
      figure_title(node, f)
      f.pre node.lines.join("\n"),
        **attr_code(align: node.attr("align"),
                    id: ::Metanorma::Utils::anchor_or_uuid(nil),
                    alt: node.attr("alt"))
    end
  end
end
makexml(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 22
def makexml(node)
  @draft = node.attributes.has_key?("draft")
  @workgroups = cache_workgroup(node)
  @bcp_bold = !node.attr?("no-rfc-bold-bcp14")
  @xinclude = node.attr?("use-xinclude")
  super
end
metadata_author(node, xml) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 8
def metadata_author(node, xml)
  personal_author(node, xml)
end
metadata_committee(node, xml) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 65
def metadata_committee(node, xml)
  return unless node.attr("workgroup")
  xml.editorialgroup do |a|
    committee_component("workgroup", node, a)
  end
end
metadata_ext(node, xml) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/front.rb, line 72
def metadata_ext(node, xml)
  super
  x = node.attr("area") and x.split(/,\s*/).each do |a|
    xml.area a
  end
  xml.ipr (node.attr("ipr") || "trust200902")
  x = node.attr("consensus") and xml.consensus x
  x = node.attr("index-include") and xml.indexInclude x
  x = node.attr("ipr-extract") and xml.iprExtract x
  x = node.attr("sort-refs") and xml.sortRefs x
  x = node.attr("sym-refs") and xml.symRefs x
  x = node.attr("toc-include") and xml.tocInclude x
  x = node.attr("toc-depth") and xml.tocDepth x
  x = node.attr("show-on-front-page") and xml.showOnFrontPage x
  xml.pi { |pi| set_pi(node, pi) }
end
metadata_publisher(node, xml) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 12
def metadata_publisher(node, xml)
  publishers = node.attr("publisher") || "IETF"
  csv_split(publishers)&.each do |p|
    xml.contributor do |c|
      c.role **{ type: "publisher" }
      c.organization { |a| organization(a, p, true) }
    end
  end
end
metadata_series(node, xml) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 38
def metadata_series(node, xml)
  xml.series **{ type: "stream" } do |s|
    s.title (node.attr("submission-type") || "IETF")
  end
  a = node.attr("intended-series") and
    xml.series **{ type: "intended" } do |s|
    parts = a.split(/ /)
    s.title parts[0]
    s.number parts[1..-1].join(" ") if parts.size > 1
  end
end
norm_ref_preface(f) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 178
def norm_ref_preface(f)
end
note(n) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 47
def note(n)
  noko do |xml|
    xml.note **attr_code(id: ::Metanorma::Utils::anchor_or_uuid(n),
                         removeInRFC: n.attr("remove-in-rfc")) do |c|
      n.title.nil? or c.name { |name| name << n.title }
      wrap_in_para(n, c)
    end
  end.join("\n")
end
ol_attrs(node) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 18
def ol_attrs(node)
  attr_code(id: ::Metanorma::Utils::anchor_or_uuid(node),
            type: node.attr("format") || olist_style(node.style),
            group: node.attr("group"),
            spacing: node.attr("spacing"),
            start: node.attr("start"))
end
org_abbrev() click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 34
def org_abbrev
  { "Internet Engineering Task Force" => "IETF" }
end
outputs(node, ret) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 30
def outputs(node, ret)
  File.open("#{@filename}.xml", "w:UTF-8") { |f| f.write(ret) }
  rfc_converter(node).convert("#{@filename}.xml")
end
para_attrs(node) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 4
def para_attrs(node)
  attr_code( "keep-with-next": node.attr("keepWithNext") ||
            node.attr("keep-with-next"),
            "keep-with-previous": node.attr("keepWithPrevious") ||
            node.attr("keep-with-previous"),
            id: ::Metanorma::Utils::anchor_or_uuid(node))
end
pi_code(rfc_pis, pi) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 130
def pi_code(rfc_pis, pi)
  rfc_pis.each_pair do |k, v|
    next if v.nil?
    pi.send k.to_s, v
  end
end
quotesource_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 67
def quotesource_cleanup(xmldoc)
  xmldoc.xpath("//quote/source | //terms/source").each do |x|
    if x["target"]&.match?(URI::DEFAULT_PARSER.make_regexp)
      x["uri"] = x["target"]
      x.delete("target")
    else
      xref_to_eref(x)
    end
  end
end
relaton_relations() click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 4
def relaton_relations
  %w(included-in described-by derived-from instance obsoletes updates)
end
rfc_anchor_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 28
def rfc_anchor_cleanup(xmldoc)
  map = {}
  xmldoc.xpath("//bibitem[docidentifier/@type = 'rfc-anchor']").each do |b|
    next if b.at("./ancestor::bibdata")

    map[b["id"]] = b.at("./docidentifier[@type = 'rfc-anchor']").text
    b["id"] = b.at("./docidentifier[@type = 'rfc-anchor']").text
  end
  xmldoc.xpath("//eref | //origin").each do |x|
    map[x["bibitemid"]] and x["bibitemid"] = map[x["bibitemid"]]
  end
  xmldoc
end
rfc_converter(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 223
def rfc_converter(node)
  IsoDoc::Ietf::RfcConvert.new(html_extract_attributes(node))
end
section_names_refs_cleanup(xml) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 78
def section_names_refs_cleanup(xml); end
set_pi(node, pi) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 89
def set_pi(node, pi)
  rfc_pis = {
    artworkdelimiter: node.attr("artworkdelimiter"),
    artworklines: node.attr("artworklines"),
    authorship: node.attr("authorship"),
    autobreaks: node.attr("autobreaks"),
    background: node.attr("background"),
    colonspace: node.attr("colonspace"),
    comments: node.attr("comments"),
    docmapping: node.attr("docmapping"),
    editing: node.attr("editing"),
    emoticonic: node.attr("emoticonic"),
    footer: node.attr("footer"),
    header: node.attr("header"),
    inline: node.attr("inline"),
    iprnotified: node.attr("iprnotified"),
    linkmailto: node.attr("linkmailto"),
    linefile: node.attr("linefile"),
    notedraftinprogress: node.attr("notedraftinprogress"),
    private: node.attr("private"),
    refparent: node.attr("refparent"),
    rfcedstyle: node.attr("rfcedstyle"),
    slides: node.attr("slides"),
    "text-list-symbols": node.attr("text-list-symbols"),
    tocappendix: node.attr("tocappendix"),
    tocindent: node.attr("tocindent"),
    tocnarrow: node.attr("tocnarrow"),
    tocompact: node.attr("tocompact"),
    topblock: node.attr("topblock"),
    useobject: node.attr("useobject"),
    strict: node.attr("strict"),
    compact: node.attr("compact"),
    subcompact: node.attr("subcompact"),
    tocinclude: node.attr("toc-include") == "false" ? "no" : "yes",
    tocdepth: node.attr("toc-depth"),
    symrefs: node.attr("sym-refs"),
    sortrefs: node.attr("sort-refs"),
  }
  pi_code(rfc_pis, pi)
end
sidebar(node) click to toggle source
smartquotes_cleanup(xmldoc) click to toggle source
# File lib/asciidoctor/ietf/cleanup.rb, line 42
def smartquotes_cleanup(xmldoc)
  xmldoc.traverse do |n|
    next unless n.text?

    n.replace(HTMLEntities.new.encode(
                n.text.gsub(/\u2019|\u2018|\u201a|\u201b/, "'")
                .gsub(/\u201c|\u201d|\u201e|\u201f/, '"'), :basic
              ))
  end
  xmldoc
end
table_attrs(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/converter.rb, line 76
def table_attrs(node)
  super.merge(align: node.attr("align"))
end
title(node, xml) click to toggle source
# File lib/asciidoctor/ietf/front.rb, line 50
def title(node, xml)
  ["en"].each do |lang|
    at = { language: lang, format: "text/plain" }
    xml.title **attr_code(at.merge(type: "main")) do |t|
      t << (::Metanorma::Utils::asciidoc_sub(node.attr("title")) ||
        ::Metanorma::Utils::asciidoc_sub(node.attr("title-en")) ||
        node.title)
    end
    a = node.attr("abbrev") and
      xml.title a, **attr_code(at.merge(type: "abbrev"))
    a = node.attr("asciititle") and
      xml.title a, **attr_code(at.merge(type: "ascii"))
  end
end
todo_attrs(node) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/blocks.rb, line 33
def todo_attrs(node)
  super.merge(attr_code(display: node.attr("display")))
end
ul_attrs(node) click to toggle source
# File lib/asciidoctor/ietf/blocks.rb, line 12
def ul_attrs(node)
  attr_code(id: ::Metanorma::Utils::anchor_or_uuid(node),
            nobullet: node.attr("nobullet"),
            spacing: node.attr("spacing"))
end
validate(doc) click to toggle source
# File lib/asciidoctor/ietf/validate.rb, line 31
def validate(doc)
  content_validate(doc)
  schema_validate(formattedstr_strip(doc.dup),
                  File.join(File.dirname(__FILE__), "ietf.rng"))
end
workgroup_validate(doc) click to toggle source
# File lib/asciidoctor/ietf/validate.rb, line 20
def workgroup_validate(doc)
  return if @workgroups.empty?

  doc.xpath("//bibdata/ext/editorialgroup/workgroup").each do |wg|
    wg_norm = wg.text.sub(/ (Working|Research) Group$/, "")
    next if @workgroups.include?(wg_norm)

    @log.add("Document Attributes", nil, "IETF: unrecognised working group #{wg.text}")
  end
end
xref_cleanup(xmldoc) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/cleanup.rb, line 59
def xref_cleanup(xmldoc)
  super
  xmldoc.xpath("//xref").each do |x|
    x.delete("displayFormat")
    x.delete("relative")
  end
end
xref_rel(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 104
def xref_rel(node)
  matched = /^([^#]+)#(.+)$/.match node.target
  if matched.nil?
    t = node.target.sub(/^#/, "")
    rel = nil
  else
    t = matched[1].sub(/\.(xml|adoc)$/, "")
    rel = matched[2]
  end
  [t, rel]
end
xref_text(node) click to toggle source
# File lib/asciidoctor/ietf/converter.rb, line 92
def xref_text(node)
  matched = /^format=(counter|title|none|default)(:.*+)?$/.match node.text
  if matched.nil?
    f = nil
    c = node&.text&.sub(/^fn: /, "")
  else
    f = matched[1]
    c = matched[2]&.sub(/^:/, "")
  end
  [f, c]
end
xref_to_eref(xref) click to toggle source
Calls superclass method
# File lib/asciidoctor/ietf/cleanup.rb, line 54
def xref_to_eref(xref)
  super
  xref.delete("format")
end