Skip to content
Carsten Bormann edited this page Mar 6, 2016 · 38 revisions

Elements of kramdown-rfc syntax

This page is a memo about the various elements of the kramdown-rfc syntax. It is not ordered by significance of the element, but by its technical aspects.

Additions to the kramdown syntax

Some additional syntax was added to the standard markdown syntax as already exhibited by kramdown. Reference: lib/kramdown-rfc2629.rb, i.e., class Kramdown::Parser::RFC2629Kramdown

File inclusion

Files can be included with the syntax {::include fn} (this needs to be flush left in column 1). A typical example from a recent RFC, where the contents of a figure was machine-generated:

~~~~~~~~~~
{::include ../ghc/packets-new/p4.out}
~~~~~~~~~~
{: #example2 title="A longer RPL example"}

(Note that this can be suppressed for use in servers by setting the environment variable KRAMDOWN_SAFE; it may not be as useful for online tools as it is for Makefile-driven draft generation.)

{{}} syntax

In markdown, an internal reference with an empty link text should have the form [](#RFC7252). Interestingly, this syntax (empty link text) has specifically not been supported by kramdown, but that is being changed with the upcoming next release.

So the following syntax for an internal reference with empty link text was invented (note that the # is implied unless ref is a full URI [1.0.29]):

  • {{ref}} for an internal reference, regardless of biblio, section, figure, table.
  • {{?ref}} for a biblio reference that automatically generates the entry as informative
  • {{!ref}} for a biblio reference that automatically generates the entry as normative

Where ref is not a valid XML ID, it is prefixed by an underscore.

To support referenced drafts evolving into RFCs without having to touch the entire document, they can be given a kramdown-internal symbolic name in the YAML, which is then referenced as {{-name}}. (1.0.29 adds support for adding alias names to other biblio references.)

((())) syntax

Markdown does not have syntax for index entries. kramdown-rfc emulates some asciidoc/pandoc syntax here.

  • Leading ! ➔ primary flag is set
  • item/optional subitem comma-separated, either one needs to be in quotes if it contains a comma

Mapping kramdown's markdown elements to RFCXML

It is not always straightforward how to elicit RFCXML behavior where markdown has been shaped by its HTML background.

Footnotes ➔ crefs

Footnotes turn into crefs (editing comments). Note that [IALs][inline-attribute-lists] are needed to add a source attribute, making this a bit unwieldy unless complemented with an ALD:

Another questionable paragraph.[^1]{: source="observer"}

[^1]: so why not delete it

<!-- taking the noise out into an ALD: -->

{:cabo: source="cabo"}

(This section to be removed by the RFC editor.)[^2]{:cabo}

[^2]: are we sure about this?

Math handling (mostly unimplemented)

Abbreviations ➔ automatic irefs

A kramdown mapping from an abbreviation to a full phrase is instead used to automatically create index entries.

*[IANA]:
*[MUST]: BCP19
*[MAY]: BCP19
*[MUST NOT]: BCP19
*[SHALL]: BCP19
*[CBOR]: (((Object Representation, Concise Binary))) (((CBOR)))

The word in square brackets (which must match exactly, case-sensitively) is entered into the index automatically for each place where it occurs. If no title is given, just the word is entered (first example). If one is given, that becomes the main item (the auto-indexed word becomes the subitem, second example and following). If full control is desired (e.g., for multiple entries per occurrence), just write down the full index entries instead (last example).

Special IAL attributes

(IAL = Inline Attribute Lists, a kramdown extension borrowed from Maruku. Note that the kramdown support for ALD = Attribute Definition Lists comes free of charge with markdown and has been used to factor out some ugly, repetitive IALs.)

Generally, IAL attributes are copied to the XML elements created. There is some special handling for

  • id, which is usually translated to anchor, so the #id syntax can be used in IALs
  • href, which is usually translated to target; in a link, it is translated to xref for internal links and eref for external ones; &foo; is converted to an entity reference

There are also some element-specific hacks, such as:

  • translating artwork-align etc. on a figure to an align attribute etc. for the artwork in the figure.

  • translating class for code blocks into type (after removing the language- inserted by kramdown)

  • an attribute cols is translated into ttcol attributes for a table (so the writer does not have to memorize the arcane markdown table attribute syntax, which is also supported)

  • element content is turned into title attributes where needed (with some markup loss)

  • codespans are converted to style="verb", em/strong to emph/strong

  • vspace hacks [TODO]

The YAML header

Mostly documented by examples in README.md.

The structure of the YAML header is mostly derived from the structure of the front matter in RFCXML. The YAML header is a map (hash) with keys as defined below.

Some of these keys create attributes in the <rfc> element, with the following abbreviations also available:

Name <rfc> Attribute
ipr ipr
docname docName
cat category
number number
obsoletes obsoletes
updates updates
seriesno seriesNo

The following hash keys create front matter elements or their attributes:

Name XML Type
title <title> String
abbrev <title abbrev="..."> String
author <author...> Author
date <date> Date
area <area> String
wg <workgroup> String
kw <keyword> String

An Author is structured like an author in the references list. A date can be null (for "n.d."), a YAML date, an integer for a year, or a string that will be parsed into YYYY-MM (defaulting to now if that parse fails); an array of strings is joined and turned into the actual value of the year attribute.

There are some additions for evoking other XML features:

  • entity: a hash named "entity" is turned into additional entity declarations that then can be referenced as {{&entityname}} in the text.

    entity:
      SELF: "[RFC-XXXX]"
  • pi: a hash named "pi" allows adding processing instructions of the form <?rfc name="value" ?> to the front matter. A value that is not given (i.e., nil) is interpreted as "yes", as is true. false turns into "no".

    pi:
      toc: yes
      sortrefs: yes
      symrefs: yes
      compact: yes
      comments: yes

    As an abbreviation, if all values are "yes", the hash can be replaced by an array of names, as in:

    pi: [toc, sortrefs, symrefs, compact, comments]

References

The YAML keys normative and informative are maps (hashes) that create reference entries. In each, a map key that is an RFC name, an I-D name, or one of the additional reference styles for external standards documents from W3C etc. (to be defined what is in bibxml2 etc.) does not need a map value, as in:

normative:
  RFC2119:
  RFC7252:
  I-D.ietf-core-block:
  W3C.REC-xml.xml:

For references not in the xml2rfc.ietf.org libraries, more information has to be given (example with slightly over the top usage of seriesinfo):

informative:
  TypedArray:
    -: ta
    target: https://www.khronos.org/registry/typedarray/specs/1.0/
    title: Typed Array Specification
    author:
      -
        ins: V. Vukicevic
        name: Vladimir Vukicevic
        org: Mozilla Corporation
      -
        ins: K. Russell
        name: Kenneth Russell
        org: Google, Inc.
    seriesinfo:
      ISBN: 9780470747995
      DOI: 10.1109/MIC.2012.29
    date: 2011-02-08
    format:
      TXT: http://foo.bar/baz.txt
      PDF: http://foo.bar/baz.pdf
    ann: >
      This is a long annotation.

Here, TypedArray is the reference label as will be visible in the document, - is an alias name (see above), target, title, seriesinfo, format, annotation, date and author are the parts of the reference as defined in RFCXML. More information about authors below.

Seriesinfo

In RFCXML references, seriesinfo is sometimes used as a catchall for things that don't fit elsewhere. A slightly over the top example:

    seriesinfo:
      "ISO/IEC": JTC1/SC2/WG2 N4246R2
      ISSN: "0001-0782"
      "ACM Press": "Communications of the ACM vol 13 no 7 pp 422-426"
       "in: ECMA-262 6th Edition,": "The ECMAScript 2015 Language Specification"
      "Ph.D.": "Dissertation, University of California, Irvine"
      ISBN: 9780470747995
      DOI: 10.1109/MIC.2012.29
      'CoRE ticket': '#204'
      IEEE: "Transactions on Information Theory, Vol. 23, No. 3, pp. 337-343"
      'HTTPBIS ticket': '#131, closed 2009-12-02'

Author {#author}

An author key can be a single hash or an array of hashes, each an author entry. An author entry has a combined initials/surname (ins) entry, a full name, and other keys as defined in RFCXML:

| Name | Element/Attribute | |-----------+---------------------| | role | role | | org | organization | | abbrev | organization/abbrev | | street | postal/street | | city | postal/city | | region | postal/region | | code | postal/code | | country | postal/country | | phone | phone | | facsimile | facsimile | | email | email | | uri | uri |

Sections

After the YAML header, markdown sections are delimited by lines surrounded by empty lines, of the form:

--- sectionname

The sections are as follows:

Section Purpose
abstract Abstract
middle Main body, chapters of the document
back Back matter, appendices
fluff Unused, treated as comments

In addition, sections normative and informative can be used to add XML material to the front of the respective reference sections (the text generated from the YAML header is appended to that text). The usefulness of this function is limited as kramdown translates GIs and attribute names into lower case, and RFCXML inexplicably contains some mixed-case GIs; these therefore cannot be used from the markdown.

Avoiding Pitfalls

While markdown text entry usually provides a smooth experience, there are a few pitfalls that need to be watched:

  • Use of <something> without intending to create an XML element --- always escape left angle brackets that could be mistaken for XML with \< constructs. (The symptom may be that the XML-like text is simply swallowed, a hard to understand error message from xml2rfc, or weird formatting.)

  • Use of beyond-ASCII characters together with coding: us-ascii --- don't use coding: us-ascii unless you really need it. xml2rfc can usually convert beyond-ASCII characters into ASCII for the text version, and the HTML version may even benefit from the correct beyond-ASCII characters. (For final submission, of course the RFC-editor "non-ASCII" guidelines need to be fulfilled.)

  • Use of HT characters (horizontal tabs). In the best case, they will unpredictably mess up the alignment of artwork; in the worst case they will send xml2rfc into a loop. Avoid horizontal tabs and other control characters in the markdown input.

Some of these pitfalls could be addressed by adding some detection in the kramdown-rfc converter, but not all of them.

Clone this wiki locally