Remember our recent post showing that one can wrangle Markdown files
programmatically without regex? That
tech note showed how to convert Markdown bodies to XML in order to
extract information from them. Now, this post goes one step further and
presents tinkr, a package for
converting .md and .Rmd files to XML, editing them, and… writing them
back as Markdown!
General tinkr workflow
The goal of tinkr is to convert Markdown files to XML and back to
allow their editing with xml2 (XPath!) instead of numerous complicated
regular expressions. The XML represents the full Markdown syntax tree
(or AST). If new
to XPath refer to this great
intro. The package
offers two functions, to_xml and to_md.
The current workflow for editing .md and .Rmd with tinkr is
use to_xml to obtain XML from Markdown (based on
commonmark::markdown_xml and blogdown:::split_yaml_body).
edit the XML using xml2.
use to_md to save back the resulting Markdown (this uses a XSLT
stylesheet, and the xslt
package).
Maybe there could be shortcuts functions for some operations in 2, maybe
not.
The md to XML to md loop on which tinkr is based is slightly lossy
because of Markdown syntax redundancy. For instance
lists can be created with either “+”, “-” or “*“. When using
tinkr, the md after editing will only use”-” for lists.
Links built like [word][smallref] and bottom [smallref]: URL
become [word](URL).
Characters are escaped (e.g. “[” when not for a link).
Block quotes lines all get “__” whereas in the input only the
first could have a “__” at the beginning of the first line.
Tables are no longer pretty, i.e. each header is followed by three
dashes no matter the length of the longest string in the column. See
this
cheatsheet.
Such losses make your Markdown file different, and the git diff a bit
harder to parse, but should not change the documents your .md or .Rmd
is rendered to. If it does, report a bug in the issue
tracker! And in any case,
as mentioned in the docs of the namer
package, such programmatic Markdown
editing is best paired with version
control.
A solution to not loose your Markdown style, e.g. your preferring “*“
over “-” for lists is to tweak our XSL
stylesheet and provide its filepath as
stylesheet_path argument to to_md.
If you want to read more technical details, head over to that
section. But we’ll show examples first!
A few tinkr examples
Since tinkr is still a toddler package, it’s available from GitHub
only.
remotes::install_github(&quot;ropenscilabs/tinkr&quot;)
Use tinkr to change header level
We read “example1.md”, change all headers 3 to headers 1, and save it
back to md.
# From Markdown to XML
path