mmark

package module
v1.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2017 License: BSD-2-Clause Imports: 16 Imported by: 70

README

Mmark

Mmark is a powerful markdown processor Go geared towards writing IETF documents. It is, however, also suited for writing books and other technical documentation.

Further documentation can be found at my site. A complete syntax document can be found here.

With Mmark your can write RFCs using markdown. Mmark (written in Go) provides an advanced markdown dialect that processes a (single) file to produce internet-drafts in XML format. Internet-drafts written in mmark can produce xml2rfc v2, xml2rfc v3 and HTML5 output.

It also allows for writing large documents such as technical books, like my Learning Go book. Sample text output of this book (when rendered as an I-D) can be found here. It is not perfect due to limitations in xml2rfc version 2. Fully rendered HTML version can be found here.

Mmark is a fork of blackfriday which is a Markdown processor implemented in Go. It supports a number of extensions, inspired by Leanpub, kramdown and Asciidoc, that allows for large documents to be written.

Example documents written in Mmark can be found in the rfc/ directory.

Mmark adds the following syntax elements to black friday:

  • TOML titleblock.
  • Including other files.
  • More enumerated lists and task-lists.
  • Table and codeblock captions.
  • Quote attribution (quote "captions").
  • Table footers, header and block tables.
  • Subfigures.
  • Inline Attribute Lists.
  • Indices.
  • Citations.
  • Abstract/Preface/Notes sections.
  • Parts.
  • Asides.
  • Main-, middle- and backmatter divisions.
  • Math support.
  • Example lists.
  • HTML Comment parsing.
  • BCP14 (RFC2119) keyword detection.
  • Include raw XML references.
  • Abbreviations.
  • Super- and subscript.
  • Callouts in code blocks.

Usage

In the mmark subdirectory you can build the mmark tool:

% cd mmark
% go build
% ./mmark -version
1.3.4

To output v2 xml just give it a markdown file and:

% ./mmark/mmark -xml2 -page mmark2rfc.md

Making a draft in text form:

% ./mmark/mmark -xml2 -page mmark2rfc.md > x.xml \
&& xml2rfc --text x.xml \
&& rm x.xml && mv x.txt mmark2rfc.txt

Outputting v3 xml is done with the -xml switch. There is not yet a processor for this XML, but you should be able to validate the resulting XML against the schema from the xml2rfc v3 draft. I'm trying to stay current with the latest draft for the V3 spec: https://tools.ietf.org/html/draft-iab-xml2rfc-03

Running from a Docker Container

To use mmark and xml2rfc without installing and configuring the separate software packages and dependencies, you can also use mmark via a Docker container. You can use https://github.com/paulej/rfctools to build a Docker image or you can use the one already created and available in Docker Hub (https://hub.docker.com/r/paulej/rfctools/).

To use Docker, you invoke commands like this:

% docker run --rm paulej/rfctools mmark -version
1.3.4

To output a v2 XML file as demonstrated in the previous section, use this command:

% docker run --rm -v $(pwd):/rfc paulej/rfctools mmark -xml2 -page mmark2rfc.md

Making a draft in text form:

% docker run --rm -v $(pwd):/rfc paulej/rfctools mmark -xml2 -page mmark2rfc.md >x.xml \
&& docker run --rm -v $(pwd):/rfc -v $HOME/.cache/xml2rfc:/var/cache/xml2rfc \
--user=$(id -u):$(id -g) paulej/rfctools xml2rfc --text x.xml \
&& rm x.xml && mv x.xml mmark2rfc.txt

The docker container expects source files to be stored in /rfc, so the above command maps the current directory to /rfc. Likewise, xml2rfc will attempt to write cache files to /var/cache/xml2rfc, so the above command maps the user's cache directory in the container.

Note also that the xml2rfc program will write an output file that will be owned by "root". To prevent that (and the cache files) from being owned by root, we instruct docker to run using the user's default user ID and group ID via the --user switch.

There is a script available called "md2rfc" simplifies the above to this:

% docker run --rm -v $(pwd):/rfc -v $HOME/.cache/xml2rfc:/var/cache/xml2rfc \
--user=$(id -u):$(id -g) paulej/rfctools mmark2rfc.md

Still appreciating that is a lot to type, there is an example directory in the https://github.com/paulej/rfctools repository that contains a Makefile. Place your .md file in a directory along with that Makefile and just type "make" to produce the .txt file.

Syntax

See the syntax document on all syntax elements that are supported by Mmark.

Documentation

Overview

Package markdown is a package for parsing and processing markdown text. It translates plain text with simple formatting rules into HTML or XML.

Index

Constants

View Source
const (
	HTML_SKIP_HTML                 = 1 << iota // skip preformatted HTML blocks
	HTML_SKIP_STYLE                            // skip embedded <style> elements
	HTML_SKIP_IMAGES                           // skip embedded images
	HTML_SKIP_LINKS                            // skip all links
	HTML_SAFELINK                              // only link to trusted protocols
	HTML_NOFOLLOW_LINKS                        // only link with rel="nofollow"
	HTML_HREF_TARGET_BLANK                     // add a blank target
	HTML_OMIT_CONTENTS                         // skip the main contents (for a standalone table of contents)
	HTML_COMPLETE_PAGE                         // generate a complete HTML page
	HTML_USE_SMARTYPANTS                       // enable smart punctuation substitutions
	HTML_SMARTYPANTS_FRACTIONS                 // enable smart fractions (with HTML_USE_SMARTYPANTS)
	HTML_SMARTYPANTS_DASHES                    // enable smart dashes (with HTML_USE_SMARTYPANTS)
	HTML_SMARTYPANTS_LATEX_DASHES              // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS and HTML_SMARTYPANTS_DASHES)
	HTML_SMARTYPANTS_ANGLED_QUOTES             // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering
	HTML_FOOTNOTE_RETURN_LINKS                 // generate a link at the end of a footnote to return to the source
)

Html renderer configuration options.

View Source
const (
	EXTENSION_ABBREVIATIONS              // Render abbreviations `*[HTML]: Hyper Text Markup Language`
	EXTENSION_AUTO_HEADER_IDS            // Create the header ID from the text
	EXTENSION_AUTOLINK                   // Detect embedded URLs that are not explicitly marked
	EXTENSION_CITATION                   // Support citations via the link syntax
	EXTENSION_EXAMPLE_LISTS              // Render '(@tag)  ' example lists
	EXTENSION_FENCED_CODE                // Render fenced code blocks
	EXTENSION_FOOTNOTES                  // Pandoc-style footnotes
	EXTENSION_HARD_LINE_BREAK            // Translate newlines into line breaks
	EXTENSION_HEADER_IDS                 // Specify header IDs with {#id}
	EXTENSION_INCLUDE                    // Include file with {{ syntax
	EXTENSION_INLINE_ATTR                // Detect CommonMark's IAL syntax
	EXTENSION_LAX_HTML_BLOCKS            // Loosen up HTML block parsing rules
	EXTENSION_MATH                       // Detect $$...$$ and parse as math
	EXTENSION_MATTER                     // Use {frontmatter} {mainmatter} {backmatter} (TODO(miek): not actually used)
	EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK // No need to insert an empty line to start a (code, quote, order list, unorder list)block
	EXTENSION_PARTS                      // Detect part headers (-#)
	EXTENSION_QUOTES                     // Allow A> as asides
	EXTENSION_SHORT_REF                  // (#id) will be a cross reference
	EXTENSION_SPACE_HEADERS              // Be strict about prefix header rules
	EXTENSION_TABLES                     // Render tables
	EXTENSION_TITLEBLOCK_TOML            // Titleblock in TOML
	EXTENSION_UNIQUE_HEADER_IDS          // When detecting identical anchors add a sequence number -1, -2 etc
	EXTENSION_BACKSLASH_LINE_BREAK       // Translate trailing backslashes into line breaks
	EXTENSION_RFC7328                    // Parse RFC 7328 markdown. Depends on FOOTNOTES extension.
	EXTENSION_DEFINITION_LISTS           // render definition lists

)

These are the supported markdown parsing extensions. OR these values together to select multiple extensions.

View Source
const (
	DefaultIpr  = "trust200902"
	DefaultArea = "Internet"
)
View Source
const Version = "1.3.6"
View Source
const (
	XML2_STANDALONE = 1 << iota // create standalone document
)

XML renderer configuration options.

View Source
const (
	XML_STANDALONE = 1 << iota // create standalone document
)

XML renderer configuration options.

Variables

View Source
var (
	// These have been known to change, these are the current ones (2015-08-27).
	CitationsBase = "https://xml2rfc.tools.ietf.org/public/rfc/"

	// CitationsRFC is the URL where the citations for RFCs are.
	CitationsRFC = CitationsBase + "bibxml/"

	// CitationsANSI is the URL where the citations for ANSI documents are.
	CitationsANSI = CitationsBase + "bibxml2/"

	// CitationsID is the URL where the citations for I-Ds are.
	CitationsID = CitationsBase + "bibxml3/"

	// CitationsW3C is the URL where the citations for W3C documents are.
	CitationsW3C = CitationsBase + "bibxml4/"
)
View Source
var PIs = []string{"toc", "symrefs", "sortrefs", "compact", "subcompact", "private", "topblock", "header", "footer", "comments"}

PIs the processing instructions.

View Source
var SourceCodeTypes = map[string]bool{
	"abnf":       true,
	"asn.1":      true,
	"bash":       true,
	"c++":        true,
	"c":          true,
	"cbor":       true,
	"dtd":        true,
	"java":       true,
	"javascript": true,
	"json":       true,
	"mib":        true,
	"perl":       true,
	"pseudocode": true,
	"python":     true,
	"rnc":        true,
	"xml":        true,

	"go": true,
}

SourceCodeTypes are the different languages that are supported as a type attribute in sourcecode, see Section 2.48.4 of XML2RFC v3 (-21).

Functions

func Parse

func Parse(input []byte, renderer Renderer, extensions int) *bytes.Buffer

Parse is the main rendering function. It parses and renders a block of markdown-encoded text. The supplied Renderer is used to format the output, and extensions dictates which non-standard extensions are enabled.

To use the supplied Html or XML renderers, see HtmlRenderer, XmlRenderer and Xml2Renderer, respectively.

Types

type HtmlRendererParameters

type HtmlRendererParameters struct {
	// Prepend this text to each relative URL.
	AbsolutePrefix string
	// Add this text to each footnote anchor, to ensure uniqueness.
	FootnoteAnchorPrefix string
	// Show this text inside the <a> tag for a footnote return link, if the
	// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string
	// <sup>[return]</sup> is used.
	FootnoteReturnLinkContents string
}

type Markdown

type Markdown struct {
	// contains filtered or unexported fields
}

Markdown is an io.Writer. Writing a buffer with markdown text will be converted to the output format the renderer outputs. Note that the conversion only takes place when String() or Bytes() is called.

func NewMarkdown

func NewMarkdown(renderer Renderer, extensions int) *Markdown

func (*Markdown) Bytes

func (m *Markdown) Bytes() []byte

func (*Markdown) String

func (m *Markdown) String() string

func (*Markdown) Write

func (m *Markdown) Write(p []byte) (n int, err error)

type Renderer

type Renderer interface {
	// block-level callbacks
	BlockCode(out *bytes.Buffer, text []byte, lang string, caption []byte, subfigure bool, callouts bool)
	BlockQuote(out *bytes.Buffer, text []byte, attribution []byte)
	BlockHtml(out *bytes.Buffer, text []byte)
	CommentHtml(out *bytes.Buffer, text []byte)
	// SpecialHeader is used for Abstract and Preface. The what string contains abstract or preface.
	SpecialHeader(out *bytes.Buffer, what []byte, text func() bool, id string)
	// Note is use for typesetting notes.
	Note(out *bytes.Buffer, text func() bool, id string)
	Part(out *bytes.Buffer, text func() bool, id string)
	Header(out *bytes.Buffer, text func() bool, level int, id string)
	HRule(out *bytes.Buffer)
	List(out *bytes.Buffer, text func() bool, flags, start int, group []byte)
	ListItem(out *bytes.Buffer, text []byte, flags int)
	Paragraph(out *bytes.Buffer, text func() bool, flags int)

	Table(out *bytes.Buffer, header []byte, body []byte, footer []byte, columnData []int, caption []byte)
	TableRow(out *bytes.Buffer, text []byte)
	TableHeaderCell(out *bytes.Buffer, text []byte, flags, colspan int)
	TableCell(out *bytes.Buffer, text []byte, flags, colspan int)

	Footnotes(out *bytes.Buffer, text func() bool)
	FootnoteItem(out *bytes.Buffer, name, text []byte, flags int)
	TitleBlockTOML(out *bytes.Buffer, data *title)
	Aside(out *bytes.Buffer, text []byte)
	Figure(out *bytes.Buffer, text []byte, caption []byte)

	// Span-level callbacks
	AutoLink(out *bytes.Buffer, link []byte, kind int)
	CodeSpan(out *bytes.Buffer, text []byte)
	// CalloutText is called when a callout is seen in the text. Id is the text
	// seen between < and > and ids references the callout counter(s) in the code.
	CalloutText(out *bytes.Buffer, id string, ids []string)
	// Called when a callout is seen in a code block. Index is the callout counter, id
	// is the number seen between < and >.
	CalloutCode(out *bytes.Buffer, index, id string)
	DoubleEmphasis(out *bytes.Buffer, text []byte)
	Emphasis(out *bytes.Buffer, text []byte)
	Subscript(out *bytes.Buffer, text []byte)
	Superscript(out *bytes.Buffer, text []byte)
	Image(out *bytes.Buffer, link []byte, title []byte, alt []byte, subfigure bool)
	LineBreak(out *bytes.Buffer)
	Link(out *bytes.Buffer, link []byte, title []byte, content []byte)
	RawHtmlTag(out *bytes.Buffer, tag []byte)
	TripleEmphasis(out *bytes.Buffer, text []byte)
	StrikeThrough(out *bytes.Buffer, text []byte)
	FootnoteRef(out *bytes.Buffer, ref []byte, id int)
	Index(out *bytes.Buffer, primary, secondary []byte, prim bool)
	Citation(out *bytes.Buffer, link, title []byte)
	Abbreviation(out *bytes.Buffer, abbr, title []byte)
	Example(out *bytes.Buffer, index int)
	Math(out *bytes.Buffer, text []byte, display bool)

	// Low-level callbacks
	Entity(out *bytes.Buffer, entity []byte)
	NormalText(out *bytes.Buffer, text []byte)

	// Header and footer
	DocumentHeader(out *bytes.Buffer, start bool)
	DocumentFooter(out *bytes.Buffer, start bool)

	// Frontmatter, mainmatter or backmatter
	DocumentMatter(out *bytes.Buffer, matter int)
	References(out *bytes.Buffer, citations map[string]*citation)

	// Helper functions
	Flags() int

	// Attr returns the inline attribute.
	Attr() *inlineAttr
	// SetAttr set the inline attribute.
	SetAttr(*inlineAttr)
	// AttrString return the string representation of this inline attribute.
	AttrString(*inlineAttr) string
}

Renderer is the rendering interface. This is mostly of interest if you are implementing a new rendering format.

When a byte slice is provided, it contains the (rendered) contents of the element.

When a callback is provided instead, it will write the contents of the respective element directly to the output buffer and return true on success. If the callback returns false, the rendering function should reset the output buffer as though it had never been called.

Currently Html, XML2RFC v3 and XML2RFC v2 implementations are provided.

func HtmlRenderer

func HtmlRenderer(flags int, css, head string) Renderer

HtmlRenderer creates and configures an Html object, which satisfies the Renderer interface.

flags is a set of HTML_* options ORed together. css is a URL for the document's stylesheet.

func HtmlRendererWithParameters

func HtmlRendererWithParameters(flags int, css, head string, renderParameters HtmlRendererParameters) Renderer

func Xml2Renderer

func Xml2Renderer(flags int) Renderer

Xml2Renderer creates and configures a Xml2 object, which satisfies the Renderer interface.

flags is a set of XML2_* options ORed together

func XmlRenderer

func XmlRenderer(flags int) Renderer

XmlRenderer creates and configures a Xml object, which satisfies the Renderer interface.

flags is a set of XML_* options ORed together

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL