Quick Scriptable Markdown with Pandoc

Patrick Wheeler

June 8 2014

Swiss Arm Knife Converstion Tool

Focus

markdown to html

## hi

This is text and [this is a link.](http://www.example.com)
<h2 id="hi">hi</h2>
<p>This is text and <a href="http://www.example.com">this is a link.</a></p>

When rendered:

hi

This is text and this is a link.

More

## This is a list

* item one
* item two
<h2 id="this-is-a-list">This is a list</h2>
<ul>
<li>item one</li>
<li>item two</li>
</ul>

rendered:

This is a list

Easy of use

Who has the time? markdown -> html

## This is a list

* item one
* item two
<h2 id="this-is-a-list">This is a list</h2>
<ul>
<li>item one</li>
<li>item two</li>
</ul>

Who has the time? markdown -> asciidoc

## This is a list

* item one
* item two
[[this-is-a-list]]
This is a list
~~~~~~~~~~~~~~

* item one
* item two

Who has the time? markdown -> docbook

## This is a list

* item one
* item two
<sect1 id="this-is-a-list">
  <title>This is a list</title>
  <itemizedlist spacing="compact">
    <listitem>
      <para>
        item one
      </para>
    </listitem>
    <listitem>
      <para>
        item two
      </para>
    </listitem>
  </itemizedlist>
</sect1>

Who has the time? markdown -> latex

## This is a list

* item one [link](http://www.example.com]
* item two
\subsection{This is a list}\label{this-is-a-list}

\begin{itemize}
\itemsep1pt\parskip0pt\parsep0pt
\item
  item one {[}link{]}(http://www.example.com{]}
\item
  item two
\end{itemize}

Who has the time? markdown -> json

## This is a list

* item one
* item two
[{"unMeta":{}},[{"t":"Header","c":[2,["this-is-a-list",[],[]],[{"t":"Str","c":"This"},{"t":"Space","c":[]},{"t":"Str","c":"is"},{"t":"Space","c":[]},{"t":"Str","c":"a"},{"t":"Space","c":[]},{"t":"Str","c":"list"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Str","c":"item"},{"t":"Space","c":[]},{"t":"Str","c":"one"}]}],[{"t":"Plain","c":[{"t":"Str","c":"item"},{"t":"Space","c":[]},{"t":"Str","c":"two"}]}]]}]]

This can represent all of pandoc's internal AST.

Who has the time? markdown -> etc

Output formats: asciidoc, beamer, context, docbook, docx,
                dzslides, epub, epub3, fb2, html, html5, icml,
                json, latex, man, markdown, markdown_github,
                markdown_mmd, markdown_phpextra,
                markdown_strict, mediawiki, native, odt,
                opendocument, opml, org, pdf*, plain, revealjs,
                rst, rtf, s5, slideous, slidy, texinfo, textile
                [*for pdf output, use latex or beamer and -o FILENAME.pdf]

Scriptablity

Since it is easy to out the internal AST it is simple to filter and edit the AST and send it along to other formats.

In fact that is what I have been doing for all of my little converstion examples. I would have been too lazy to copy and paste all of the converstions you have seen so far.

So instead I made a small haskell script to access and filter pandoc AST with command line commands.

Scriptablity CLI

 ```{ cmdBlock="pandoc -t html5" inClasses="markdown" outClasses="html5"}
 ## This is a h2 header
 ```

becomes:

## This is a h2 header
<h2 id="this-is-a-h2-header">This is a h2 header</h2>

Scriptablity CLI - ls

 ```{ showCmdBlock="ls -l" outClasses="bashOut"}
 ## This is a h2 header
 ```

becomes:

$ ls -l
total 3144
-rw-r--r-- 1 pjw users  206358 Jun  8 13:07 a.svg
drwxr-xr-x 7 pjw users    4096 Jun  6 10:11 blogging
-rw-r--r-- 1 pjw users   11654 Jun  7 03:09 chicago-author-date.csl
-rw-r--r-- 1 pjw users   11654 Jun  6 23:43 chicago-author-date.csl.orig
-rw-r--r-- 1 pjw users   20916 Jun  8 13:07 circle.svg
-rw-r--r-- 1 pjw users    3080 Jun  8 15:36 diaExample.svg
-rw-r--r-- 1 pjw users   61550 Jun  8 15:36 dotExample.png
-rwxr-xr-x 1 pjw users 2374623 Jun  6 09:36 e
-rw-r--r-- 1 pjw users   14801 Jun  6 09:01 e.png
-rw-r--r-- 1 pjw users  206374 Jun  6 21:05 e.svg
-rw-r--r-- 1 pjw users    4284 Jan  9  2013 ghcFromSource.md
-rw-r--r-- 1 pjw users    6741 Jun  8 00:50 hello.png
-rw-r--r-- 1 pjw users    7758 Jan 16  2013 lazy.md
drwxr-xr-x 2 pjw users    4096 Jun  6 10:08 log
-rw-r--r-- 1 pjw users     488 Mar 14  2013 nixCommandLineHelpers.txt
-rw-r--r-- 1 pjw users    2873 Apr 12  2013 nixHackage.md
-rw-r--r-- 1 pjw users   15734 Jun  8 13:07 nix.html
-rw-r--r-- 1 pjw users    8864 Jun  8 13:07 nix.md
drwxr-xr-x 2 pjw users    4096 Jun  6 10:03 noteLog
-rwxr-xr-x 1 pjw users    1241 Jun  8 15:02 pandocCmdFilter.hs
-rwxr-xr-x 1 pjw users     415 Jun  8 10:35 pandocDebugFilter.hs
-rwxr-xr-x 1 pjw users    1179 Jun  8 02:00 pandocDotFilter.hs
-rwxr-xr-x 1 pjw users     481 Jun  8 14:45 pandocJsonFormatterFilter.hs
-rw-r--r-- 1 pjw users     362 Jun  7 03:12 pandocmarkdown.bib
-rwxr-xr-x 1 pjw users     721 Jun  8 06:01 pandocShowFilter.hs
-rw-r--r-- 1 pjw users     246 Dec 18  2012 paper2.md
-rw-r--r-- 1 pjw users    1691 Jun  8 13:07 sc2.svg
-rw-r--r-- 1 pjw users    3824 Jun  8 13:07 sc3.svg
-rw-r--r-- 1 pjw users    4123 Jun  8 13:07 sc4.svg
-rw-r--r-- 1 pjw users    1383 Jun  8 13:07 sc5.svg
-rw-r--r-- 1 pjw users   27509 Jun  8 13:07 sc6.svg
-rw-r--r-- 1 pjw users    4104 Jun  8 13:07 sc7.svg
-rw-r--r-- 1 pjw users    8120 Jun  8 13:07 sc8.svg
-rw-r--r-- 1 pjw users    3105 Jun  8 15:24 sc.svg
-rw-r--r-- 1 pjw users      61 Jun  8 13:06 test.css
-rw-r--r-- 1 pjw users   24725 Jun  8 15:36 testDebugFilter.html
-rw-r--r-- 1 pjw users    6034 Jun  8 15:37 testDebugFilter.md
-rw-r--r-- 1 pjw users    1714 Jun  8 01:01 testDotfilter.html
-rw-r--r-- 1 pjw users     626 Jun  8 01:01 testDotFilter.html
-rw-r--r-- 1 pjw users     136 Jun  8 01:01 testDotFilter.md
-rw-r--r-- 1 pjw users    6741 Jun  8 01:01 testDot.png
-rw-r--r-- 1 pjw users    1547 Jun 21  2013 testLeftD.hs
-rw-r--r-- 1 pjw users    4745 Jun  7 00:33 test.md
-rw-r--r-- 1 pjw users     681 Jun  8 15:36 tmp.dot
-rw-r--r-- 1 pjw users    4740 Jun  6 09:01 tmp.hi
-rw-r--r-- 1 pjw users     380 Jun  8 15:36 tmp.hs
-rw-r--r-- 1 pjw users    8280 Jun  6 09:36 tmp.o
drwxr-xr-x 2 pjw users    4096 Jun  6 10:03 todo
-rw-r--r-- 1 pjw users    2531 Jun 21  2013 turnRelectBugs.hs
drwxr-xr-x 4 pjw users    4096 Mar 30  2013 typeAnnotations

Filters

Command Line Filter

To inport a file with highlighting:

 ```{ cmdBlock="cat pandocCmdFilter.hs" outClasses="haskell"}
 ```
#!/usr/bin/env runhaskell
-- behead2.hs
import Text.Pandoc.JSON

import System.Process

import Data.Monoid
import Data.List (find)

main :: IO ()
main = toJSONFilter handleCmds

handleCmds :: Block -> IO Block
handleCmds (CodeBlock (ident, [] , (("showCmdBlock",cmd0):attrs)) code) = do
    cmdBlock <- handleCmds $ CodeBlock (ident, [], (("cmdBlock",cmd0):attrs)) code
    return $ Div ("", ["groupCodeBlock"], [])
                 [ CodeBlock (ident, ["bash"], []) $ "$ " <> cmd0
                 , cmdBlock
                 ]
handleCmds (CodeBlock (ident, [] , (("cmdBlock",cmd0):attrs)) code) = do
    let (cmd:args) = words cmd0
    let outClasses =
              words
            . maybe [] snd
            . find ((== "outClasses") . fst)
            $ attrs
    let inClasses =
              words
            . maybe [] snd
            . find ((== "inClasses") . fst)
            $ attrs
    let inputBlock =
            if null code
            then Null
            else CodeBlock (ident, inClasses, []) code
    result <- readProcess cmd args code
    return $ Div ("", ["groupCodeBlock"], [])
                 [ inputBlock
                 , CodeBlock (ident, outClasses, []) result
                 ]
handleCmds x = return x

GraphViz - Inline dot files

test

Inline Diagrams Code

{-# LANGUAGE NoMonomorphismRestriction #-}
import Diagrams.Prelude
import Diagrams.TwoD
import Diagrams.Backend.SVG
import Data.List

example = hrule (2 * sum sizes) === circles # centerX
  where circles = hcat . map alignT . zipWith scale sizes
                $ repeat (circle 1)
        sizes   = [2,5,4,7,1,3]

main = renderSVG "diaExample.svg" (Width 500)  (example # lw 0.2)

test

Easy of use + Scriptablity