File: README.md
Pandoc
The universal markup converter
Pandoc is a Haskell library for converting from
one markup format to another, and a command-line tool that uses this
library.
It can convert from
asciidoc(AsciiDoc markup)bibtex(BibTeX bibliography)biblatex(BibLaTeX bibliography)bits(BITS XML, alias
forjats)commonmark(CommonMark Markdown)commonmark_x(CommonMark Markdown with
extensions)creole(Creole 1.0)csljson(CSL
JSON
bibliography)csv(CSV table)tsv
(TSV
table)djot(Djot markup)docbook(DocBook)docx(Word docx)dokuwiki(DokuWiki markup)endnotexml(EndNote XML
bibliography)epub(EPUB)fb2
(FictionBook2
e-book)gfm(GitHub-Flavored
Markdown),
or the deprecated and less accuratemarkdown_github; usemarkdown_github
only if you need extensions not supported ingfm.haddock(Haddock
markup)html(HTML)ipynb(Jupyter
notebook)jats(JATS XML)jira
(Jira/Confluence
wiki markup)json(JSON version of native AST)latex(LaTeX)markdown(Pandocโs
Markdown)markdown_mmd
(MultiMarkdown)markdown_phpextra(PHP Markdown
Extra)markdown_strict(original unextended
Markdown)mediawiki(MediaWiki
markup)man(roff man)mdoc(mdoc manual page
markup)muse(Muse)native(native Haskell)odt(OpenDocument text
document)opml(OPML)org(Emacs Org mode)pod(Perlโs Plain Old
Documentation)pptx
(PowerPoint)ris(RIS
bibliography)rtf(Rich Text
Format)rst
(reStructuredText)t2t(txt2tags)textile(Textile)tikiwiki(TikiWiki
markup)twiki(TWiki
markup)typst(typst)vimwiki(Vimwiki)xlsx(Excel
spreadsheet)xml(XML version of native AST)- the path of a custom Lua reader, see Custom readers and
writers
below
It can convert to
ansi(text with ANSI escape
codes, for terminal
viewing)asciidoc(modern AsciiDoc as interpreted by
Asciidoctor)asciidoc_legacy(AsciiDoc as interpreted byasciidoc-py).asciidoctor(deprecated synonym forasciidoc)bbcodeBBCodebbcode_fluxbbBBCode
(FluxBB)bbcode_phpbbBBCode
(phpBB)bbcode_steamBBCode
(Steam)bbcode_hubzillaBBCode
(Hubzilla)bbcode_xenforoBBCode
(xenForo)beamer(LaTeX beamer slide show)bibtex(BibTeX bibliography)biblatex(BibLaTeX bibliography)chunkedhtml(zip archive of multiple linked HTML files)commonmark(CommonMark Markdown)commonmark_x(CommonMark Markdown with
extensions)context(ConTeXt)csljson(CSL
JSON
bibliography)djot(Djot markup)docbookordocbook4(DocBook 4)docbook5(DocBook 5)docx(Word docx)dokuwiki(DokuWiki markup)epuborepub3(EPUB v3 book)epub2(EPUB v2)fb2
(FictionBook2
e-book)gfm(GitHub-Flavored
Markdown),
or the deprecated and less accuratemarkdown_github; usemarkdown_github
only if you need extensions not supported ingfm.haddock(Haddock
markup)htmlorhtml5(HTML,
i.e.ย HTML5/XHTML polyglot
markup)html4(XHTML 1.0 Transitional)icml(InDesign
ICML)ipynb(Jupyter
notebook)jats_archiving(JATS XML, Archiving and
Interchange Tag Set)jats_articleauthoring(JATS XML, Article
Authoring Tag Set)jats_publishing(JATS XML, Journal
Publishing Tag Set)jats(alias forjats_archiving)jira
(Jira/Confluence
wiki markup)json(JSON version of native AST)latex(LaTeX)man(roff man)markdown(Pandocโs
Markdown)markdown_mmd
(MultiMarkdown)markdown_phpextra(PHP Markdown
Extra)markdown_strict(original unextended
Markdown)markua(Markua)mediawiki(MediaWiki
markup)ms(roff ms)muse(Muse)native(native Haskell)odt(OpenDocument text
document)opml(OPML)opendocument(OpenDocument
XML)org(Emacs Org mode)pdf(PDF)plain(plain text)pptx
(PowerPoint
slide show)rst
(reStructuredText)rtf(Rich Text
Format)texinfo(GNU Texinfo)textile(Textile)t2t(txt2tags)slideous(Slideous HTML
and JavaScript slide show)slidy(Slidy HTML and
JavaScript slide show)dzslides(DZSlides HTML5 +
JavaScript slide show)revealjs(reveal.js HTML5 + JavaScript
slide show)s5(S5 HTML and JavaScript
slide show)tei(TEI Simple)typst(typst)vimdoc
(Vimdoc)xml(XML version of native AST)xwiki(XWiki
markup)zimwiki(ZimWiki
markup)- the path of a custom Lua writer, see Custom readers and
writers
below
Pandoc can also produce PDF output via LaTeX, Groff ms, or HTML.
Pandocโs enhanced version of Markdown includes syntax for tables,
definition lists, metadata blocks, footnotes, citations, math, and much
more. See the Userโs Manual below under Pandocโs
Markdown.
Pandoc has a modular design: it consists of a set of readers, which
parse text in a given format and produce a native representation of the
document (an abstract syntax tree or AST), and a set of writers, which
convert this native representation into a target format. Thus, adding an
input or output format requires only adding a reader or writer. Users
can also run custom pandoc filters to modify the intermediate AST (see
the documentation for filters and
Lua filters).
Because pandocโs intermediate representation of a document is less
expressive than many of the formats it converts between, one should not
expect perfect conversions between every format and every other. Pandoc
attempts to preserve the structural elements of a document, but not
formatting details such as margin size. And some document elements, such
as complex tables, may not fit into pandocโs simple document model.
While conversions from pandocโs Markdown to all formats aspire to be
perfect, conversions from formats more expressive than pandocโs Markdown
can be expected to be lossy.
Installing
Hereโs how to install pandoc.
Documentation
Pandocโs website contains a full Userโs
Guide. It is also available
here as pandoc-flavored Markdown. The website also
contains some examples of the use of
pandoc, a limited online
demo, and a WebAssembly-based online
demo.
Contributing
Pull requests, bug reports, and feature requests are welcome. Please
make sure to read the contributor guidelines before
opening a new issue.
License
ยฉ 2006-2024 John MacFarlane ([email protected]). Released under the
GPL,
version 2 or greater. This software carries no warranty of any kind.
(See COPYRIGHT for full copyright and warranty notices.)
File: doc/custom-readers.md
author:
- John MacFarlane
date: 'November 18, 2021'
title: Creating Custom Pandoc Readers in Lua
Introduction
If you need to parse a format not already handled by pandoc,
you can create a custom reader using the Lua language.
Pandoc has a built-in Lua interpreter, so you needn't
install any additional software to do this.
A custom reader is a Lua file that defines a function
called Reader, which takes two arguments:
- the raw input to be parsed, as a list of sources
- optionally, a table of reader options, e.g.
{ columns = 62, standalone = true }.
The Reader function should return a Pandoc AST.
This can be created using functions in the pandoc module,
which is automatically in scope. (Indeed, all of the utility
functions that are available for Lua filters are available
in custom readers, too.)
Each source item corresponds to a file or stream passed to pandoc
containing its text and name. E.g., if a single file input.txt
is passed to pandoc, then the list of sources will contain just a
single element s, where s.name == 'input.txt' and s.text
contains the file contents as a string.
The sources list, as well as each of its elements, can be
converted to a string via the Lua standard library functiontostring.
A minimal example would be
function Reader(input)
return pandoc.Pandoc({ pandoc.CodeBlock(tostring(input)) })
endThis just returns a document containing a big code block with all
of the input. Or, to create a separate code block for each input
file, one might write
function Reader(input)
return pandoc.Pandoc(input:map(
function (s) return pandoc.CodeBlock(s.text) end))
endIn a nontrivial reader, you'll want to parse the input.
You can do this using standard Lua library functions
(for example, the patterns library), or with the powerful
and fast lpeg parsing library, which is automatically in scope.
You can also use external Lua libraries (for example,
an XML parser).
A previous pandoc version passed a raw string instead of a list
of sources to the Reader function. Reader functions that rely on
this are obsolete, but still supported: Pandoc analyzes any
script error, detecting when code assumed the old behavior. The
code is rerun with raw string input in this case, thereby
ensuring backwards compatibility.
Bytestring readers
In order to read binary formats, including docx, odt, and epub,
pandoc supports the ByteStringReader function. AByteStringReader function is similar to the Reader function
that processes text input. Instead of a list of sources, the
ByteStringReader function is passed a bytestring, i.e., a string
that contains the binary input.
-- read input as epub
function ByteStringReader (input)
return pandoc.read(input, 'epub')
endFormat extensions
Custom readers can be built such that their behavior is
controllable through format extensions, such as smart,citations, or hard-line-breaks. Supported extensions are those
that are present as a key in the global Extensions table. Fields
of extensions that are enabled default have the value true orenable, while those that are supported but disabled have valuefalse or disable.
Example: A reader with the following global table supports the
extensions smart, citations, and foobar, with smart enabled and
the other two disabled by default:
Extensions = {
smart = 'enable',
citations = 'disable',
foobar = true
}The users control extensions as usual, e.g., pandoc -f my-reader.lua+citations. The extensions are accessible through
the reader options' extensions field, e.g.:
function Reader (input, opts)
print(
'The citations extension is',
opts.extensions:includes 'citations' and 'enabled' or 'disabled'
)
-- ...
endExtensions that are neither enabled nor disabled in theExtensions field are treated as unsupported by the
reader. Trying to modify such an extension via the command line
will lead to an error.
Example: plain text reader
This is a simple example using lpeg to parse the input
into space-separated strings and blankline-separated paragraphs.
-- A sample custom reader that just parses text into blankline-separated
-- paragraphs with space-separated words.
-- For better performance we put these functions in local variables:
local P, S, R, Cf, Cc, Ct, V, Cs, Cg, Cb, B, C, Cmt =
lpeg.P, lpeg.S, lpeg.R, lpeg.Cf, lpeg.Cc, lpeg.Ct, lpeg.V,
lpeg.Cs, lpeg.Cg, lpeg.Cb, lpeg.B, lpeg.C, lpeg.Cmt
local whitespacechar = S(" \t\r\n")
local wordchar = (1 - whitespacechar)
local spacechar = S(" \t")
local newline = P"\r"^-1 * P"\n"
local blanklines = newline * (spacechar^0 * newline)^1
local endline = newline - blanklines
-- Grammar
G = P{ "Pandoc",
Pandoc = Ct(V"Block"^0) / pandoc.Pandoc;
Block = blanklines^0 * V"Para" ;
Para = Ct(V"Inline"^1) / pandoc.Para;
Inline = V"Str" + V"Space" + V"SoftBreak" ;
Str = wordchar^1 / pandoc.Str;
Space = spacechar^1 / pandoc.Space;
SoftBreak = endline / pandoc.SoftBreak;
}
function Reader(input)
return lpeg.match(G, tostring(input))
endExample of use:
% pandoc -f plain.lua -t native
*Hello there*, this is plain text with no formatting
except paragraph breaks.
- Like this one.
^D
[ Para
[ Str "*Hello"
, Space
, Str "there*,"
, Space
, Str "this"
, Space
, Str "is"
, Space
, Str "plain"
, Space
, Str "text"
, Space
, Str "with"
, Space
, Str "no"
, Space
, Str "formatting"
, SoftBreak
, Str "except"
, Space
, Str "paragraph"
, Space
, Str "breaks."
]
, Para
[ Str "-"
, Space
, Str "Like"
, Space
, Str "this"
, Space
, Str "one."
]
]Example: a wiki Creole reader
This is a parser for Creole common wiki markup.
It uses an lpeg grammar. Fun fact: this custom reader is faster than
pandoc's built-in creole reader! This shows that high-performance
readers can be designed in this way.
/* Detailed source-code truncated for AI context efficiency. */Example of use:
% pandoc -f creole.lua -t markdown
== Wiki Creole
You can make things **bold** or //italic// or **//both//** or //**both**//.
Character formatting extends across line breaks: **bold,
this is still bold. This line deliberately does not end in star-star.
Not bold. Character formatting does not cross paragraph boundaries.
You can use [[internal links]] or [[http://www.wikicreole.org|external links]],
give the link a [[internal links|different]] name.
^D
## Wiki Creole
You can make things **bold** or *italic* or ***both*** or ***both***.
Character formatting extends across line breaks: \*\*bold, this is still
bold. This line deliberately does not end in star-star.
Not bold. Character formatting does not cross paragraph boundaries.
You can use [internal links](internal links) or [external
links](http://www.wikicreole.org), give the link a
[different](internal links) name.Example: parsing JSON from an API
This custom reader consumes the JSON output of
https://www.reddit.com/r/haskell.json and produces
a document containing the current top articles on the
Haskell subreddit.
It assumes that the pandoc.json library is available, which
ships with pandoc versions after (not including) 3.1. It's still
possible to use this with older pandoc version by using a
different JSON library. E.g., luajson can be installed usingluarocks install luajson---but be sure you are installing it for
Lua 5.4, which is the version packaged with pandoc.
-- consumes the output of https://www.reddit.com/r/haskell.json
local json = require 'pandoc.json'
local function read_inlines(raw)
local doc = pandoc.read(raw, "commonmark")
return pandoc.utils.blocks_to_inlines(doc.blocks)
end
local function read_blocks(raw)
local doc = pandoc.read(raw, "commonmark")
return doc.blocks
end
function Reader(input)
local parsed = json.decode(tostring(input))
local blocks = {}
for _,entry in ipairs(parsed.data.children) do
local d = entry.data
table.insert(blocks, pandoc.Header(2,
pandoc.Link(read_inlines(d.title), d.url)))
for _,block in ipairs(read_blocks(d.selftext)) do
table.insert(blocks, block)
end
end
return pandoc.Pandoc(blocks)
endSimilar code can be used to consume JSON output from other APIs.
Note that the content of the text fields is markdown, so we
convert it using pandoc.read().
Example: syntax-highlighted code files
This is a reader that puts the content of each input file into a
code block, sets the file's extension as the block's class to
enable code highlighting, and places the filename as a header
above each code block.
function to_code_block (source)
local _, lang = pandoc.path.split_extension(source.name)
return pandoc.Div{
pandoc.Header(1, source.name == '' and '<stdin>' or source.name),
pandoc.CodeBlock(source.text, {class=lang}),
}
end
function Reader (input, opts)
return pandoc.Pandoc(input:map(to_code_block))
endExample: extracting the content from web pages
This reader uses the command-line program readable
(install via npm install readability-cli)
to clean out parts of HTML input that have to do with
navigation, leaving only the content.
/* Detailed source-code truncated for AI context efficiency. */Example of use:
pandoc -f readable.lua -t markdown https://pandoc.organd compare the output to
pandoc -f html -t markdown https://pandoc.orgFile: doc/custom-writers.md
author:
- John MacFarlane
date: 'November 21, 2021'
title: Creating Custom Pandoc Writers in Lua
Introduction
If you need to render a format not already handled by pandoc,
or you want to change how pandoc renders a format,
you can create a custom writer using the Lua language.
Pandoc has a built-in Lua interpreter, so you needn't
install any additional software to do this.
A custom writer is a Lua file that defines how to render the
document. Writers must define just a single function, named eitherWriter or ByteStringWriter, which gets passed the document and
writer options, and then handles the conversion of the document,
rendering it into a string. This interface was introduced in
pandoc 2.17.2, with ByteString writers becoming available in
pandoc 3.0.
Pandoc also supports "classic" custom writers, where a Lua
function must be defined for each AST element type. Classic style
writers are deprecated and should be replaced with new-style
writers if possible.
Writers
Custom writers using the new style must contain a global function
named Writer or ByteStringWriter. Pandoc calls this function
with the document and writer options as arguments, and expects the
function to return a UTF-8 encoded string.
function Writer (doc, opts)
-- ...
endWriters that do not return text but binary data should define a
function with name ByteStringWriter instead. The function must
still return a string, but it does not have to be UTF-8 encoded
and can contain arbitrary binary data.
If both Writer and ByteStringWriter functions are defined,
then only the Writer function will be used.
Format extensions
Writers can be customized through format extensions, such assmart, citations, or hard_line_breaks. The globalExtensions table indicates supported extensions with a
key. Extensions enabled by default are assigned a true value,
while those that are supported but disabled are assigned a false
value.
Example: A writer with the following global table supports the
extensions smart, citations, and foobar, with smart enabled and
the others disabled by default:
Extensions = {
smart = true,
citations = false,
foobar = false
}The users control extensions as usual, e.g., pandoc -t my-writer.lua+citations. The extensions are accessible through
the writer options' extensions field, e.g.:
function Writer (doc, opts)
print(
'The citations extension is',
opts.extensions:includes 'citations' and 'enabled' or 'disabled'
)
-- ...
endDefault template
The default template of a custom writer is defined by the return
value of the global function Template. Pandoc uses the default
template for rendering when the user has not specified a template,
but invoked with the -s/--standalone flag.
The Template global can be left undefined, in which case pandoc
will throw an error when it would otherwise use the default
template.
Example: modified Markdown writer
Writers have access to all modules described in the Lua filters
documentation. This includes pandoc.write, which can be used
to render a document in a format already supported by pandoc. The
document can be modified before this conversion, as demonstrated
in the following short example. It renders a document as GitHub
Flavored Markdown, but always uses fenced code blocks, never
indented code.
function Writer (doc, opts)
local filter = {
CodeBlock = function (cb)
-- only modify if code block has no attributes
if cb.attr == pandoc.Attr() then
local delimited = '```\n' .. cb.text .. '\n```'
return pandoc.RawBlock('markdown', delimited)
end
end
}
return pandoc.write(doc:walk(filter), 'gfm', opts)
end
Template = pandoc.template.default 'gfm'Reducing boilerplate with `pandoc.scaffolding.Writer`
The pandoc.scaffolding.Writer structure is a custom writer scaffold
that serves to avoid common boilerplate code when defining a custom
writer. The object can be used as a function and allows to skip details
like metadata and template handling, requiring only the render functions
for each AST element type.
The value of pandoc.scaffolding.Writer is a function that should
usually be assigned to the global Writer:
Writer = pandoc.scaffolding.WriterThe render functions for Block and Inline values can then be added
to Writer.Block and Writer.Inline, respectively. The functions
are passed the element and the WriterOptions.
Writer.Inline.Str = function (str)
return str.text
end
Writer.Inline.SoftBreak = function (_, opts)
return opts.wrap_text == "wrap-preserve"
and cr
or space
end
Writer.Inline.LineBreak = cr
Writer.Block.Para = function (para)
return {Writer.Inlines(para.content), pandoc.layout.blankline}
endThe render functions must return a string, a pandoc.layout Doc
element, or a list of such elements. In the latter case, the
values are concatenated as if they were passed topandoc.layout.concat. If the value does not depend on the input,
a constant can be used as well.
The tables Writer.Block and Writer.Inline can be used as
functions; they apply the right render function for an element of
the respective type. E.g., Writer.Block(pandoc.Para 'x') will
delegate to the Writer.Para render function and will return the
result of that call.
Similarly, the functions Writer.Blocks and Writer.Inlines can
be used to render lists of elements, and Writer.Pandoc renders
the document's blocks. The function Writer.Blocks can take a
separator as an optional second argument, e.g.,Writer.Blocks(blks, pandoc.layout.cr); the default block
separator is pandoc.layout.blankline.
All predefined functions can be overwritten when needed.
The resulting Writer uses the render functions to handle metadata
values and converts them to template variables. The template is
applied automatically if one is given.
Classic style
A writer using the classic style defines rendering functions for
each element of the pandoc AST. Note that this style is
deprecated and may be removed in later versions.
For example,
function Para(s)
return "" .. s .. ""
endTemplate variables
New template variables can be added, or existing ones
modified, by returning a second value from function Doc.
For example, the following will add the current date in
variable date, unless date is already defined as either a
metadata value or a variable:
function Doc (body, meta, vars)
vars.date = vars.date or meta.date or os.date '%B %e, %Y'
return body, vars
endChanges in pandoc 3.0
Custom writers were reworked in pandoc 3.0. For technical reasons,
the global variables PANDOC_DOCUMENT and PANDOC_WRITER_OPTIONS
are set to the empty document and default values, respectively.
The old behavior can be restored by adding the following snippet,
which turns a classic into a new style writer.
function Writer (doc, opts)
PANDOC_DOCUMENT = doc
PANDOC_WRITER_OPTIONS = opts
loadfile(PANDOC_SCRIPT_FILE)()
return pandoc.write_classic(doc, opts)
endFile: doc/customizing-pandoc.md
author:
- Mauro Bieg
- John MacFarlane
title: Customizing Pandoc
This document provides a quick overview over the various ways to
customize pandoc's output, with links to fuller documentation
and some examples.
Templates
When the -s/--standalone option is used, pandoc will
generate a standalone document rather than a fragment.
For example, in HTML output this will include the<head> element; in LaTeX output, it will include the
preamble.
Pandoc comes with a default template for (almost) every output
format. A template is a plain text file containing variables
that are replaced by text generated by pandoc. For example,
the variable $body$ will be replaced by the document body,
and $title$ by the title from metadata.
To look at the default template for an output format, you can dopandoc -D FORMAT, where FORMAT is replaced by the name of
the format. For example pandoc -D latex. You can also use your
own template instead, either by using the --template option
or by putting the custom template in your user data directory
(on Linux and macOS, ~/.pandoc/templates/).
Note that in many cases you can avoid the need for a custom
template by including a file with the --include-in-header,--include-before-body, or --include-after-body option.
Or you can set the corresponding template variable directly.
Template variables
There are several ways to set template variables:
--variable |
--metadata |
YAML metadata and --metadata-file |
|
|---|---|---|---|
| values can beโฆ | strings and bools | strings and bools | also YAML objects and lists |
| strings areโฆ | inserted verbatim | escaped | interpreted as markdown |
| accessible by filters: | no | yes | yes |
For more information, see Templates in
the pandoc manual.
Example: adding structured author data to HTML
TODO
Example: generating documents from YAML metadata
TODO
Reference docx/pptx/odt
For docx, pptx or odt documents, things are a bit more
complicated. Instead of a single template file, you need to
provide a customized reference.docx/pptx/odt.
See the manual for the--reference-doc option.
Example: changing the font and line spacing in a Word docx
TODO
Filters
Templates are very powerful, but they are only a sort of scaffold to
place your document's body text in. You cannot directly change the
body text using the template.
If you need to affect the output of the actual body text, you
can use a pandoc filter. A filter is a small program that
transforms the document, between the parsing and the writing phase,
while it is still in pandoc's native format. For example,
a filter might find all the Header elements of a document
and capitalize their text.
Pandoc's native representation of a document is an
abstract syntax tree (AST), not unlike the HTML DOM. It is
documented
here. A Pandoc document is a chunk of
metadata (Meta) and a list of Blocks. The Blocks, in
turn, are composed of other Blocks and Inline elements.
(Block elements are things like paragraphs, lists, headers,
and code blocks. Inline elements are individual words,
links, emphasis, and so on.) Filters operate on these
elements. You can use pandoc -t native to learn about the
AST's structure.
There are two kinds of filters: JSON filters (which transform a
JSON serialization of the pandoc AST, and may be written in any
language that can parse and emit JSON), and Lua filters (which
use an interface built directly into pandoc, and must be written
in the Lua language). If you are writing your own filters, it
is best to use Lua filters, which are more portable (they
require only pandoc itself) and more efficient. See Lua
filters for documentation and examples. If
you would prefer to write your filter in another language, see
Filters for a gentle introduction to JSON
filters.
There's a repository of lua filters at
pandoc/lua-filters
on GitHub. A number of pandoc filters, written in
Haskell, are available on
Hackage
and can be installed using the stack or cabal tools.
The wiki also lists third party
filters.
Example: capitalizing headers
TODO
Example: code extractor
TODO
Generic Divs and Spans
TODO
Divs and Spans: generic blocks
that can be transformed with filters
Example: colored text
Example: custom styles in docx
Raw attributes
TODO
Generic raw attributes:
to include raw snippets
Custom writers
TODO
Custom writers
Custom syntax highlighting
TODO
Custom syntax highlighting,
provided by the skylighting
library
including highlighting styles
File: doc/epub.md
title: Creating an ebook with pandoc author: John MacFarlane
Starting with version 1.6, pandoc can produce output in the EPUB
electronic book format. EPUB books can be viewed on iPads, Nooks, and
other electronic book readers, including many smart phones. (They can
also be converted to Kindle books using the GUI only KindlePreviewer
on Windows and Mac OSX. KindleGen โ which offers a command line
interface and supports Linux, Mac OSX
and Windows โ has been deprecated, but binaries can still
be found on the internet.)
This means that it's now very easy to produce an electronic book!
Let's try it.
A toy example
Use your text editor to create a file mybook.txt, with the following
contents:
% My Book
% Sam Smith
This is my book!
# Chapter One
Chapter one is over.
# Chapter Two
Chapter two has just begun.To make this into an ebook takes only one command:
pandoc mybook.txt -o mybook.epubYou can upload mybook.epub to your ebook reader and try it out.
Note that if your markdown file contains links to local images, for
example
pandoc will automatically include the images in the generated
epub.
A real book
To see what this would look like for a real book, let's convert Scott
Chacon's book Pro Git, which he wrote using pandoc's markdown variant
and released under a Creative Commons license. (If you use the book,
please consider buying a copy to help support his excellent work.)
You can find the markdown source for the book on its
github site. Let's get a copy of the whole repository:[^1]
git clone https://github.com/progit/progit.git[^1]: If you don't have git, you can browse to the github site and
click "Download Source" to get the same files in a zip or tar archive.
This command will create a working directory called progit on
your machine. The actual markdown sources for the English version
of the book are in the en subdirectory, so start by changing
to that directory:
cd progit/enAs you can see, each chapter is a single text file in its own directory.
Chacon does some postprocessing on these files, for example, to insert images.
This is a placeholder for Figure 1-1, for example:
Insert 18333fig0101.png
Figure 1-1. Local version control diagram.The actual image file is called 18333fig0101-tn.png and lives in
the figures subdirectory of the repository, as you can verify.
For demonstration purposes, we want pure markdown files, so let's
change this placeholder into a markdown image link. Pandoc will
treat a paragraph containing a single image as a figure with
a caption, which is what we want:
We can make this change in all the files with a perl one-liner:
perl -i -0pe \
's/^Insert\s*(.*)\.png\s*\n([^\n]*)$/!\[\2](..\/figures\/\1-tn.png)/mg' \
*/*.markdownThis will modify the files in place. (We won't worry about backing
them up; if we mess up, we can get the original files back withgit reset --hard.)
OK! Now we're almost ready to make an ebook. We have the chapters,
each in its own file, but we still need a title. Create a file,title.txt, with a pandoc YAML metadata block:
---
title: Pro Git
author: Scott Chacon
rights: Creative Commons Non-Commercial Share Alike 3.0
language: en-US
...See the User's Guide for more information
about these fields.
Now run pandoc to make the ebook, using our title page and modified
chapter files as sources:
pandoc -o progit.epub title.txt \
01-introduction/01-chapter1.markdown \
02-git-basics/01-chapter2.markdown \
03-git-branching/01-chapter3.markdown \
04-git-server/01-chapter4.markdown \
05-distributed-git/01-chapter5.markdown \
06-git-tools/01-chapter6.markdown \
07-customizing-git/01-chapter7.markdown \
08-git-and-other-scms/01-chapter8.markdown \
09-git-internals/01-chapter9.markdownThat's it! The ebook, progit.epub, is ready to be uploaded to your reader.
Changing the format
You can use the --css option to specify a CSS file
for the book. The default CSS is minimal and can be found
on GitHub
or in the epub.css file in your data directory
(see --data-dir in the User's Guide).
You can even embed fonts in the EPUB if you want; see the User's Guide
under --epub-embed-font for instructions.
Math
Pandoc has an EPUB3 writer. It renders LaTeX math into MathML, which
EPUB3 readers are supposed to support (but unfortunately few do).
Of course, this isn't much help if you want EPUB2 output (pandoc -t epub2)
or target readers that don't support MathML. Then you have two options:
- Use the
--webtexoption,
which will use a web service to convert the TeX to an image. - Use the
--gladtexoption
to convert maths into SVG images on your local machine.
Both GladTeX and WebTeX add the LaTeX source of the formula as alternative text
of the image, increasing accessibility for blind users.
File: doc/extras.md
title: Pandoc Extras author: John MacFarlane
This is a curated list of some of the most useful third-party
software that extends pandoc's capabilities. For a more
complete list, see the Pandoc Extras wiki page.
GUI
- PanWriter is
a Markdown editor with live preview that can import and export
using pandoc. - Pandoc Mac OS X
Services
allows you to invoke pandoc from any text editor with the
opened file as input.
Editor support
- pandoc-mode for Emacs
- vim-pandoc for Vim
- Panache is a language server, formatter, and linter
for Pandoc markdown.
CLI wrappers
- panzer allows you to
specify command-line options and styles in the Markdown file's YAML
metadata. - pandocomatic
is similar to panzer but also provides support for
converting directory trees. - panrun is a more
minimalistic alternative to panzer and pandocomatic.
Editing/document changes
- pandiff creates prose
diffs for any document format supported by pandoc. - pancritic allows using
CriticMarkup with pandoc.
Charts and data
- R Markdown allows you to
process Markdown documents with integrated data and charts
(integrates pandoc). - pandoc-plot
allows you to integrate programmatically generated plots
generated by various tools.
Citations
- zotxt is Zotero extension
for working with pandoc
Numbering and cross-references
- pandoc-crossref
is a filter that adds support for figure, table, and
equation numbers and cross-references. - pandoc-xnos is
a suite of filters supporting numbering and
cross-referencing figures, equations, tables, and sections.
Academic publishing workflows
- Quarto is an open-source scientific and technical publishing system
to make reproducible, production quality
articles, presentations, websites, blogs, and books.
It supports equations, citations, crossrefs, figure panels, callouts, advanced layout, etc. - Manubot is a workflow and set of tools for the next
generation of scholarly publishing, including citation support and
support for multiple output formats.
It's especially suited for papers with a very large set of authors. - pandoc-ext includes goodies such as
putting the Abstract into a section,
multiple bibliographies,
support the Citation Typing Ontology (CiTO), etc. - Baseprinter is an open-source pandoc wrapper to
generate Baseprint document snapshots and HTML/PDF previews.
These snapshots can be self-published/archived as editions of a
Baseprint document succession. - Pandoc Scholar is a
set of utilities to make publishing of scientific articles as simple and
pleasant as possible. It simplifies setting authors' metadata in
YAML blocks, allows to add semantic annotation to citations, and
only requires the programspandocandmake.
Please note that it is no longer maintained and refers toQuartoandpandoc-ext
Containers
Lua filters
(For a fuller list, see the lua-filters
repository.)
- Spell
checking. - Word count.
- Embed textually-specified
diagrams in Mermaid, Dot/GraphViz,
PlantUML, Asymptote, CeTZ, and TikZ. - Create subfigures in pandoc's Markdown.
- Handle scholarly
metadata. - Panda provides
conditionals, code file inclusion, string expansion,
and diagrams from code blocks.
Logo
Here is a logo designed by pandoc contributor Albert Krewinkel:
https://github.com/tarleb/pandoc-logo.
File: doc/faqs.md
% FAQs
::: faqs
How can I convert a whole directory of files from Markdown to RTF?
On linux or OSX:
for f in *.txt; do pandoc "$f" -s -o "${f%.txt}.rtf"; doneIn Windows Powershell:
gci -r -i *.txt
|foreach{$rtf=$_.directoryname+"\"+$_.basename+".rtf";pandoc -f markdown -s $_.fullname -o $rtf}I used pandoc to convert a document to ICML (or OPML or RTF), and when I try to open it I'm told it's invalid. What have I done wrong?
Be sure to use the -s or --standalone flag, or you just get a
fragment, not a full document with the required header:
pandoc -s -f markdown -t icml -o my.icml my.mdI get a blank document when I try to convert a markdown document in Chinese to PDF.
By default, pandoc uses pdflatex to generate the PDF, and pdflatex
doesn't handle Chinese characters. But you can change the default to
use xelatex instead. You should also make sure you're using a font
with Chinese glyphs. For example:
pandoc -o c.pdf --pdf-engine=xelatex -V mainfont='Adobe Ming Std'The Windows installer does a single user install, rather than installing pandoc for all users. How can I install pandoc for all users?
Run the following command as admin:
msiexec /i pandoc-VERSION.msi ALLUSERS=1This will put pandoc in C:\Program Files\Pandoc.
You can install Pandoc to a different directory by setting APPLICATIONFOLDER parameter,
for example:
msiexec /i pandoc-1.11.1.msi ALLUSERS=1 APPLICATIONFOLDER="C:\Pandoc"How do I change the margins in PDF output?
The option
-V geometry:margin=1inwill set the margins to one inch on each side. If you don't want uniform
margins, you can do something like
-V geometry:"top=2cm, bottom=1.5cm, left=1cm, right=1cm"Or
-V geometry:"left=3cm, width=10cm"For more options, see the documentation for the LaTeX geometry
package.
How does pandoc compare to multimarkdown?
Here is a wiki
page
comparing the two.
When I specify an image width of 50% and convert to LaTeX, pandoc sets the height to textheight and the aspect ratio isn't preserved. How can I prevent this?
For example, if you convert an image with {width="50%"}, the LaTeX produced
will be \includegraphics[width=0.5\textwidth,height=\textheight].
This output presupposes the following code in pandoc's default latex
template:
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}If you don't have this in your custom template, you should
add it. If we didn't set the height explicitly in this way,
the image would not be resized correctly unless it was
being resized to smaller than its original size.
Pandoc sometimes uses too much memory. How can I limit the memory used by pandoc?
pandoc +RTS -M30m -RTS will limit heap memory to 30MB.
When converting a document requires more than this, an out of
memory error will be issued.
When using `--include-in-header` with PDF or LaTeX output, how do I reference tex declarations coming after `$header-includes$` in the default template?
For various reasons, the $header-includes$ are not at the very
end of the LaTeX preamble. This poses a problem when the code
you are inserting depends on declarations in the preamble coming
after the $header-includes$ location. For example, you might
want to reference the \author and \title metadata values
(set at the very bottom of the preamble) and present them in
margins. In that case you can wrap your code in etoolbox's\AtEndPreamble. The technique is demonstrated in this
gist.
When using \AtEndPreamble, keep any makeatletter ormakeatother outside of the \AtEndPreamble, as shown in the
example.
How can I convert PDFs to other formats using pandoc?
You can't. You can try opening the PDF in Word or Google Docs
and saving in a format from which pandoc can convert directly.
Do I really need to install a 1 GB TeX installation to produce a PDF using pandoc?
No. You can get by with a relatively small TeX installation,
for example, by starting with MacTeX's Basic TeX distribution
and using the tlmgr tool to install a few packages required by pandoc
(see the manual).
Or, you can produce PDFs via HTML and wkhtmltopdf,
or via groff ms and pdfroff. (These don't produce as nice
typography as TeX, particularly when it comes to math, but they
may be fine for many purposes.)
Converting to PDF on an M1 Mac, I get a "Cannot allocate memory" error.
We are not sure why this happens, but we have found that
fully specifying the pdflatex path avoids the error. For
example,
pandoc -o my.pdf --pdf-engine=/Library/TeX/texbin/pdflatexWhen I convert from ipynb, some visualizations aren't showing up.
First, unless your target is a binary format (docx, odt, epub),
you must use either --extract-media or (for HTML only)--embed-resources to make the images in the ipynb container
available to your output file.
Second, some Jupyter extensions, especially those that use JavaScript
for visualizations, assume the presence ofrequire.js.
To ensure that this script is available in your HTML output, you
can use:
pandoc -s -o output.html input.ipynb \
-V header-includes='<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>'How can I get BibTeX references to work when converting from LaTeX?
Use the --citeproc option.
If it still doesn't work, you may need to tell pandoc where
your bibliography file is using --bibliography.
Your references may not be formatted the same as they are
when you use latex and bibtex; you can change the format
of the citations by specifying an appropriate CSL bibliography
style using --csl
(see the manual).
How can I produce PDF/A with pandoc?
The simplest approach is via ConTeXt:
pandoc --pdf-engine=context -V pdfaAlternatively, --pdf-engine=pdflatex can be used with
the following in header-includes in metadata (or included from
a file using --include-in-header):
\usepackage[a-2u,mathxmp]{pdfx}
\usepackage[pdfa]{hyperref}Or --pdf-engine=lualatex can be used with the following:
\usepackage{hyperxmp}
\hypersetup{pdfapart=3,pdfaconformance=B}
\immediate\pdfobj stream attr{/N 3} file{sRGB.icc}
\pdfcatalog{/OutputIntents [<<
/Type /OutputIntent /S /GTS_PDFA1
/DestOutputProfile \the\pdflastobj\space 0 R
/OutputConditionIdentifier (sRGB) /Info (sRGB)
>>]}Pandoc adds column widths to pipe tables when any line is wider than the setting for `--columns`. How can I prevent this?
Save this filter as nowidths.lua and then pass --lua-filter nowidths.lua as an additional option to pandoc.
(See issue 8139.)
-- Unset the width attribute of HTML colspecs in tables
-- See https://github.com/jgm/pandoc/issues/8139
function Table (tbl)
if PANDOC_VERSION[1] >= 2 and PANDOC_VERSION[2] >= 10 then
tbl.colspecs = tbl.colspecs:map(function (colspec)
local align = colspec[1]
local width = nil -- default width
return {align, width}
end)
else
for i, w in ipairs(tbl.widths) do
tbl.widths[i] = 0
end
end
return tbl
endHow can I use pandoc to read Word files in the old .DOC format?
Install antiword and use it to convert the doc to DocBook,
which can be read by pandoc.
antiword -x db input.doc | pandoc -f docbook:::
File: doc/filters.md
% Pandoc filters
% John MacFarlane
Summary
Pandoc provides an interface for users to write programs (known
as filters) which act on pandocโs AST.
Pandoc consists of a set of readers and writers. When converting
a document from one format to another, text is parsed by a
reader into pandocโs intermediate representation of the
document---an "abstract syntax tree" or AST---which is then
converted by the writer into the target format.
The pandoc AST format is defined in the moduleText.Pandoc.Definition in the pandoc-types package
.
A "filter" is a program that modifies the AST, between the
reader and the writer.
INPUT --reader--> AST --filter--> AST --writer--> OUTPUTPandoc supports two kinds of filters:
Lua filters use the Lua language to
define transformations on the pandoc AST. They are
described in a separate document.JSON filters, described here, are pipes that read from
standard input and write to standard output, consuming and
producing a JSON representation of the pandoc AST:textsource format โ (pandoc) โ JSON-formatted AST โ (JSON filter) โ JSON-formatted AST โ (pandoc) โ target format
Lua filters have a couple of advantages. They use a Lua
interpreter that is embedded in pandoc, so you don't need
to have any external software installed. And they are
usually faster than JSON filters. But if you wish to
write your filter in a language other than Lua, you may
prefer to use a JSON filter. JSON filters may be written
in any programming language.
You can use a JSON filter directly in a pipeline:
pandoc -s input.txt -t json | \
pandoc-citeproc | \
pandoc -s -f json -o output.htmlBut it is more convenient to use the --filter option,
which handles the plumbing automatically:
pandoc -s input.txt --filter pandoc-citeproc -o output.htmlFor a gentle introduction into writing your own filters,
continue this guide. Thereโs also a list of third party filters
on the wiki.
A simple example
Suppose you wanted to replace all level 2+ headings in a markdown
document with regular paragraphs, with text in italics. How would you go
about doing this?
A first thought would be to use regular expressions. Something
like this:
perl -pe 's/^##+ (.*)$/\*\1\*/' source.txtThis should work most of the time. But don't forget
that ATX style headings can end with a sequence of #s
that is not part of the heading text:
## My heading ##And what if your document contains a line starting with ## in an HTML
comment or delimited code block?
~~~~
### A third level heading in standard markdown
~~~~We don't want to touch these lines. Moreover, what about Setext
style second-level heading?
A heading
---------We need to handle those too. Finally, can we be sure that adding
asterisks to each side of our string will put it in italics?
What if the string already contains asterisks around it? Then we'll
end up with bold text, which is not what we want. And what if it contains
a regular unescaped asterisk?
How would you modify your regular expression to handle these cases? It
would be hairy, to say the least.
A better approach is to let pandoc handle the parsing, and
then modify the AST before the document is written. For this,
we can use a filter.
To see what sort of AST is produced when pandoc parses our text,
we can use pandoc's native output format:
% cat test.txt
## my heading
text with *italics*
% pandoc -s -t native test.txt
Pandoc (Meta {unMeta = fromList []})
[Header 2 ("my-heading",[],[]) [Str "My",Space,Str "heading"]
, Para [Str "text",Space,Str "with",Space,Emph [Str "italics"]] ]A Pandoc document consists of a Meta block (containing
metadata like title, authors, and date) and a list of Block
elements. In this case, we have two Blocks, a Header and a Para.
Each has as its content a list of Inline elements. For more details on
the pandoc AST, see the haddock documentation for Text.Pandoc.Definition.
We can use Haskell to create a JSON filter that transforms this
AST, replacing each Header block with level >= 2 with a Para
with its contents wrapped inside an Emph inline:
#!/usr/bin/env runhaskell
-- behead.hs
import Text.Pandoc.JSON
main :: IO ()
main = toJSONFilter behead
behead :: Block -> Block
behead (Header n _ xs) | n >= 2 = Para [Emph xs]
behead x = xThe toJSONFilter function does two things. First, it lifts
the behead function (which maps Block -> Block) onto a
transformation of the entire Pandoc AST, walking the AST
and transforming each block. Second, it wraps this Pandoc -> Pandoc transformation with the necessary JSON serialization
and deserialization, producing an executable that consumes
JSON from stdin and produces JSON to stdout.
To use the filter, make it executable:
chmod +x behead.hsand then
pandoc -f SOURCEFORMAT -t TARGETFORMAT --filter ./behead.hs(It is also necessary that pandoc-types be installed in the
local package repository. To do this using cabal-install,cabal v2-update && cabal v2-install --lib pandoc-types --package-env ..)
Alternatively, we could compile the filter:
ghc -package-env=default --make behead.hs
pandoc -f SOURCEFORMAT -t TARGETFORMAT --filter ./beheadNote that if the filter is placed in the system PATH, then the initial./ is not needed. Note also that the command line can include
multiple instances of --filter: the filters will be applied in
sequence.
LaTeX for WordPress
Another easy example. WordPress blogs require a special format for
LaTeX math. Instead of $e=mc^2$, you need: $LaTeX e=mc^2$.
How can we convert a markdown document accordingly?
Again, it's difficult to do the job reliably with regexes.
A $ might be a regular currency indicator, or it might occur in
a comment or code block or inline code span. We just want to find
the $s that begin LaTeX math. If only we had a parser...
We do. Pandoc already extracts LaTeX math, so:
#!/usr/bin/env runhaskell
-- wordpressify.hs
import Text.Pandoc.JSON
main = toJSONFilter wordpressify
where wordpressify (Math x y) = Math x ("LaTeX " ++ y)
wordpressify x = xMission accomplished. (I've omitted type signatures here,
just to show it can be done.)
But I don't want to learn Haskell!
While it's easiest to write pandoc filters in Haskell, it is fairly
easy to write them in python using the pandocfilters package.
The package is in PyPI and can be installed using pip install pandocfilters or easy_install pandocfilters.
Here's our "beheading" filter in python:
#!/usr/bin/env python
"""
Pandoc filter to convert all level 2+ headings to paragraphs with
emphasized text.
"""
from pandocfilters import toJSONFilter, Emph, Para
def behead(key, value, format, meta):
if key == 'Header' and value[0] >= 2:
return Para([Emph(value[2])])
if __name__ == "__main__":
toJSONFilter(behead)toJSONFilter(behead) walks the AST and applies the behead action
to each element. If behead returns nothing, the node is unchanged;
if it returns an object, the node is replaced; if it returns a list,
the new list is spliced in.
Note that, although these parameters are not used in this example,format provides access to the target format, and meta provides access to
the document's metadata.
There are many examples of python filters in the pandocfilters
repository.
For a more Pythonic alternative to pandocfilters, see
the panflute library.
Don't like Python? There are also ports of pandocfilters in
Starting with pandoc 2.0, pandoc includes built-in support for
writing filters in lua. The lua interpreter is built in to
pandoc, so a lua filter does not require any additional software
to run. See the documentation on lua
filters.
Include files
So none of our transforms have involved IO. How about a script that
reads a markdown document, finds all the inline code blocks with
attribute include, and replaces their contents with the contents of
the file given?
#!/usr/bin/env runhaskell
-- includes.hs
import Text.Pandoc.JSON
import qualified Data.Text.IO as TIO
import qualified Data.Text as T
doInclude :: Block -> IO Block
doInclude cb@(CodeBlock (id, classes, namevals) contents) =
case lookup (T.pack "include") namevals of
Just f -> CodeBlock (id, classes, namevals) <$>
TIO.readFile (T.unpack f)
Nothing -> return cb
doInclude x = return x
main :: IO ()
main = toJSONFilter doIncludeTry this on the following:
Here's the pandoc README:
~~~~ {include="README"}
this will be replaced by contents of README
~~~~Removing links
What if we want to remove every link from a document, retaining
the link's text?
#!/usr/bin/env runhaskell
-- delink.hs
import Text.Pandoc.JSON
main = toJSONFilter delink
delink :: Inline -> [Inline]
delink (Link _ txt _) = txt
delink x = [x]Note that delink can't be a function of type Inline -> Inline,
because the thing we want to replace the link with is not a singleInline element, but a list of them. So we make delink a function
from an Inline element to a list of Inline elements.toJSONFilter can still lift this function to a transformation of typePandoc -> Pandoc.
A filter for ruby text
Finally, here's a nice real-world example, developed on the
pandoc-discuss list. Qubyte wrote:
I'm interested in using pandoc to turn my markdown notes on Japanese
into nicely set HTML and (Xe)LaTeX. With HTML5, ruby (typically used to
phonetically read chinese characters by placing text above or to the
side) is standard, and support from browsers is emerging (Webkit based
browsers appear to fully support it). For those browsers that don't
support it yet (notably Firefox) the feature falls back in a nice way
by placing the phonetic reading inside brackets to the side of each
Chinese character, which is suitable for other output formats too. As
for (Xe)LaTeX, ruby is not an issue.At the moment, I use inline HTML to achieve the result when the
conversion is to HTML, but it's ugly and uses a lot of keystrokes, for
example{.xml}<ruby>ใ<rt></rt>้ฃฏ<rp>๏ผ</rp><rt>ใฏใ</rt><rp>๏ผ</rp></ruby>sets ใ้ฃฏ "gohan" with "han" spelt phonetically above the second
character, or to the right of it in brackets if the browser does not
support ruby. I'd like to have something more liketextr[ใฏใ](้ฃฏ)or any keystroke saving convention would be welcome.
We came up with the following script, which uses the convention that a
markdown link with a URL beginning with a hyphen is interpreted as ruby:
[ใฏใ](-้ฃฏ){-# LANGUAGE OverloadedStrings #-}
-- handleruby.hs
import Text.Pandoc.JSON
import System.Environment (getArgs)
import qualified Data.Text as T
handleRuby :: Maybe Format -> Inline -> Inline
handleRuby (Just format) x@(Link attr [Str ruby] (src,_)) =
case T.uncons src of
Just ('-',kanji)
| format == Format "html" -> RawInline format $
"<ruby>" <> kanji <> "<rp>(</rp><rt>" <> ruby <>
"</rt><rp>)</rp></ruby>"
| format == Format "latex" -> RawInline format $
"\\ruby{" <> kanji <> "}{" <> ruby <> "}"
| otherwise -> Str ruby
_ -> x
handleRuby _ x = x
main :: IO ()
main = toJSONFilter handleRubyNote that, when a script is called using --filter, pandoc passes
it the target format as the first argument. When a function's
first argument is of type Maybe Format, toJSONFilter will
automatically assign it Just the target format or Nothing.
We compile our script:
# first, make sure pandoc-types is installed:
cabal install --lib pandoc-types --package-env .
ghc --make handleRubyThen run it:
% pandoc -F ./handleRuby -t html
[ใฏใ](-้ฃฏ)
^D
<ruby>้ฃฏ<rp>(</rp><rt>ใฏใ</rt><rp>)</rp></ruby>
% pandoc -F ./handleRuby -t latex
[ใฏใ](-้ฃฏ)
^D
\ruby{้ฃฏ}{ใฏใ}Note: to use this to generate PDFs via LaTeX, you'll need
to use --pdf-engine=xelatex, specify a mainfont that has
the Japanese characters (e.g. "Noto Sans CJK JP"), and add\usepackage{ruby} to your template or header-includes.
Exercises
Put all the regular text in a markdown document in ALL CAPS
(without touching text in URLs or link titles).Remove all horizontal rules from a document.
Renumber all enumerated lists with roman numerals.
Replace each delimited code block with class
dotwith an
image generated by runningdot -Tpng(from graphviz) on the
contents of the code block.Find all code blocks with class
pythonand run them
using the python interpreter, printing the results to the console.
Technical details of JSON filters
A JSON filter is any program which can consume and produce a
valid pandoc JSON document representation. This section describes
the technical details surrounding the invocation of filters.
Arguments
The program will always be called with the target format as the
only argument. A pandoc invocation like
pandoc --filter demo --to=htmlwill cause pandoc to call the program demo with argument html.
Environment variables
Pandoc sets additional environment variables before calling a
filter.
PANDOC_VERSION
: The version of the pandoc binary used to process the document.
Example: 2.11.1.
PANDOC_READER_OPTIONS
: JSON object representation of the options passed to the input
parser.
Object fields:
`abbreviations`
: set of known abbreviations (array of strings).
`columns`
: number of columns in terminal; an integer.
`default-image-extension`
: default extension for images; a string.
`extensions`
: integer representation of the syntax extensions bit
field.
`indented-code-classes`
: default classes for indented code blocks; array of
strings.
`standalone`
: whether the input was a standalone document with header;
either `true` or `false`.
`strip-comments`
: HTML comments are stripped instead of parsed as raw HTML;
either `true` or `false`.
`tab-stop`
: width (i.e.ย equivalent number of spaces) of tab stops;
integer.
`track-changes`
: track changes setting for docx; one of
`"accept-changes"`, `"reject-changes"`, and
`"all-changes"`.Supported interpreters
Files passed to the --filter/-F parameter are expected to be
executable. However, if the executable bit is not set, then
pandoc tries to guess a suitable interpreter from the file
extension.
file extension interpreter
.py python
.hs runhaskell
.pl perl
.rb ruby
.php php
.js node
.r Rscript
File: doc/getting-started.md
title: Getting started with pandoc author: John MacFarlane
This document is for people who are unfamiliar with command line
tools. Command-line experts can go straight to the User's
Guide or the pandoc man page.
Step 1: Install pandoc
First, install pandoc, following the instructions for
your platform.
Step 2: Open a terminal
Pandoc is a command-line tool. There is no graphic user interface.
So, to use it, you'll need to open a terminal window:
On OS X, the Terminal application can be found in
/Applications/Utilities. Open a Finder window and go toApplications, thenUtilities. Then double click onTerminal. (Or, click the spotlight icon in the upper right
hand corner of your screen and typeTerminal-- you should
seeTerminalunderApplications.)On Windows, you can use either the classic command prompt or the
more modern PowerShell terminal. If you use Windows in desktop
mode, run thecmdorpowershellcommand from the Start menu.
If you use the Windows 8 start screen instead, simply typecmdorpowershell, and then run either the "Command
Prompt" or "Windows Powershell" application. If you are usingcmd, typechcp 65001before using pandoc, to set the
encoding to UTF-8.On Linux, there are many possible configurations, depending on
what desktop environment you're using:- In Unity, use the search function on the
Dash, and search
forTerminal. Or, use the keyboard shortcutCtrl-Alt-T. - In Gnome, go to
Applications, thenAccessories, and
selectTerminal, or useCtrl-Alt-T. - In XFCE, go to
Applications, thenSystem, thenTerminal,
or useSuper-T. - In KDE, go to
KMenu, thenSystem, thenTerminal Program (Konsole).
- In Unity, use the search function on the
You should now see a rectangle with a "prompt" (possibly just a symbol
like %, but probably including more information, such as your
username and directory), and a blinking cursor.
Let's verify that pandoc is installed. Type
pandoc --versionand hit enter. You should see a message telling you which version
of pandoc is installed, and giving you some additional information.
Step 3: Changing directories
First, let's see where we are. Type
pwdon Linux or OSX, or
echo %cd%on Windows, and hit enter. Your terminal should print your current
working directory. (Guess what pwd stands for?) This should be your
home directory.
Let's navigate now to our Documents directory: type
cd Documentsand hit enter. Now type
pwd(or echo %cd% on Windows)
again. You should be in the Documents subdirectory of your home
directory. To go back to your home directory, you could type
cd ..The .. means "one level up."
Go back to your Documents directory if you're not there already.
Let's try creating a subdirectory called pandoc-test:
mkdir pandoc-testNow change to the pandoc-test directory:
cd pandoc-testIf the prompt doesn't tell you what directory you're in, you can
confirm that you're there by doing
pwd(or echo %cd%) again.
OK, that's all you need to know for now about using the terminal.
But here's a secret that will save you a lot of typing. You can
always type the up-arrow key to go back through your history
of commands. So if you want to use a command you typed earlier,
you don't need to type it again: just use up-arrow until it comes
up. Try this. (You can use down-arrow as well, to go the other
direction.) Once you have the command, you can also use the
left and right arrows and the backspace/delete key to edit it.
Most terminals also support tab completion of directories and
filenames. To try this, let's first go back up to our Documents
directory:
cd ..Now, type
cd pandoc-and hit the tab key instead of enter. Your terminal should fill
in the rest (test), and then you can hit enter.
To review:
pwd(orecho %cd%on Windows)
to see what the current working directory is.cd footo change to thefoosubdirectory of your working
directory.cd ..to move up to the parent of the working directory.mkdir footo create a subdirectory calledfooin the
working directory.- up-arrow to go back through your command history.
- tab to complete directories and file names.
Step 4: Using pandoc as a filter
Type
pandocand hit enter. You should see the cursor just sitting there, waiting
for you to type something. Type this:
Hello *pandoc*!
- one
- twoWhen you're finished (the cursor should be at the beginning of the line),
type Ctrl-D on OS X or Linux, or Ctrl-Z followed
by Enter on Windows. You should now see your text converted to HTML!
Hello *pandoc*!
<li>one</li>
<li>two</li>What just happened? When pandoc is invoked without specifying any
input files, it operates as a "filter," taking input from the
terminal and sending its output back to the terminal. You can use
this feature to play around with pandoc.
By default, input is interpreted as pandoc markdown, and output is
HTML. But we can change that. Let's try converting from HTML
to markdown:
pandoc -f html -t markdownNow type:
Hello *pandoc*!and hit Ctrl-D (or Ctrl-Z followed by Enter on Windows).
You should see:
Hello *pandoc*!Now try converting something from markdown to LaTeX. What command
do you think you should use?
Step 5: Text editor basics
You'll probably want to use pandoc to convert a file, not to read
text from the terminal. That's easy, but first we need to create
a text file in our pandoc-test subdirectory.
Important: To create a text file, you'll need to use a text
editor, not a word processor like Microsoft Word. On Windows, you
can use Notepad (in Accessories). On OS X, you can useTextEdit (in Applications). On Linux, different platforms come
with different text editors: Gnome has GEdit, and KDE has Kate.
Start up your text editor. Type the following:
---
title: Test
...
# Test!
This is a test of *pandoc*.
- list one
- list twoNow save your file as test1.md in the directoryDocuments/pandoc-test.
Note: If you use plain text a lot, you'll want a better editor thanNotepad or TextEdit. You might want to look at
Visual Studio Code or
Sublime Text or (if you're willing
to put in some time learning an unfamiliar interface)
Vim or Emacs.
Step 6: Converting a file
Go back to your terminal. We should still be in theDocuments/pandoc-test directory. Verify that with pwd.
Now type
ls(or dir if you're on Windows).
This will list the files in the current directory. You should see
the file you created, test1.md.
To convert it to HTML, use this command:
pandoc test1.md -f markdown -t html -s -o test1.htmlThe filename test1.md tells pandoc which file to convert.
The -s option says to create a "standalone" file, with a header
and footer, not just a fragment. And the -o test1.html says
to put the output in the file test1.html. Note that we could
have omitted -f markdown and -t html, since the default
is to convert from markdown to HTML, but it doesn't hurt to
include them.
Check that the file was created by typing ls again. You
should see test1.html. Now open this in a browser. On OS X,
you can type
open test1.htmlOn Windows, type
.\test1.htmlYou should see a browser window with your document.
To create a LaTeX document, you just need to change the command
slightly:
pandoc test1.md -f markdown -t latex -s -o test1.texTry opening test1.tex in your text editor.
Pandoc can often figure out the input and output formats from
the filename extensions. So, you could have just used:
pandoc test1.md -s -o test1.texPandoc knows you're trying to create a LaTeX document, because of the.tex extension.
Now try creating a Word document (with extension docx).
If you want to create a PDF, you'll need to have LaTeX installed.
(See MacTeX on OS X,
MiKTeX on Windows, or install the texlive
package on Linux.) Then do
pandoc test1.md -s -o test1.pdfStep 7: Command-line options
You now know the basics. Pandoc has a lot of options. At this point
you can start to learn more about them by reading the
User's Guide.
Here's an example. The --mathml option causes pandoc to
convert TeX math into MathML. Type
pandoc --mathmlthen enter this text, followed by Ctrl-D (Ctrl-Z followed byEnter on Windows):
$x = y^2$Now try the same thing without --mathml. See the difference
in output?
If you forget an option, or forget which formats are supported, you
can always do
pandoc --helpto get a list of all the supported options.
On OS X or Linux systems, you can also do
man pandocto get the pandoc manual page. All of this information is also
in the User's Guide.
If you get stuck, you can always ask questions on the
discussion forum.
But be sure to check the FAQs first,
and search through the forum to see if your question has
been answered before.
File: doc/jats.md
title: JATS author: Albert Krewinkel
This document describes pandoc's handling of JATS.
Metadata Values
abstract
: Article summary. Added via the document's front matter via the
<abstract> element.
author
: list of article contributors. Each author should have a surname
and a given name listed in the entry; if the author has no
surname value, then the item will be used as the contributors
string-name.
`orcid`
: the contributor's ORCID identifier.
`surname`
: surname of the contributor. Usually the family name in
western names.
See [`<surname>`][elem:surname].
`given-names`
: personal names of the contributor; this includes middle
names (if any) in western-style names.
See [`<given-names>`][elem:given-names].
`name`
: full name of the author; included only as a fallback if
`author.surname` is not available. Tagged with
[`<string-name>`][elem:string-name].
`email`
: the contributor's email address.
Used as the contents of the [``][elem:given-names]
element.
`affiliation`
: either full affiliation entries as described in field
`affiliation`, or a list of affiliation identifiers.
The identifiers link to the organizations with which an
author is affiliated. Each identifier in this list must
also occur as the `id` of an affiliation listed in the
top-level `affiliation` list.
If the top-level `affiliation` field is set, then this
entry assumed to be a list of identifiers, and a list of
full entries if that field is unset.
Full entries must be given if the articleauthoring tag
set it used, as affiliation links are not allowed in that
schema.
`roles`
: a list of dictionaries describing the author's role(s).
Each role is added as an [`<role>`] element to
the author's [`<contrib>`] element. The following examples
illustrate:
An ad-hoc role:
```yaml
roles:
- name: Dolphin Catcher
```
A role specified with CRediT.
```yaml
roles:
- credit: writing-review-editing
```
The `credit-name` is automatically looked up from
the CRediT taxonomy, but you can also specify it
yourself:
```yaml
roles:
- credit: writing-review-editing
credit-name: Writing โ review & editing
```
A role specified with CRediT, including an
optional degree of contribution. Note that
specifying the degree only is allowed when
using CRediT roles and not ad-hoc roles.
```yaml
roles:
- credit: writing-review-editing
degree: Lead
```
A role specified with CRediT with a label override,
useful for internationalization:
```yaml
roles:
- credit: writing-review-editing
name: Escrita โ revisรฃo e ediรงรฃo
```
The value for `credit` and `credit-name`
must be from one of the 14 terms from the
Contribution Role Taxonomy (CRediT):
| `credit` | `credit-name` |
|--------------------------|----------------------------|
| `conceptualization` | Conceptualization |
| `data-curation` | Data curation |
| `formal-analysis` | Formal analysis |
| `funding-acquisition` | Funding acquisition |
| `investigation` | Investigation |
| `methodology` | Methodology |
| `project-administration` | Project administration |
| `resources` | Resources |
| `software` | Software |
| `supervision` | Supervision |
| `validation` | Validation |
| `visualization` | Visualization |
| `writing-original-draft` | Writing โ original draft |
| `writing-review-editing` | Writing โ review & editing |
JATS suggests in [`<degree-contribution>`] to use one of
the following three values when specifying the degree of
contribution:
1. `Lead`
2. `Equal`
3. `Supporting`
`equal-contrib`
: boolean attribute used to mark authors who contributed
equally to the work. The
[`equal-contrib`][attr:equal-contrib] attribute, set to
`yes`, is added to the author's [`<contrib>`] element if
this is set to a truthy value.
`cor-id`
: identifier linking to the contributor's correspondence
information. The info itself must be stored as an item in
`article.author-notes.corresp`. If the `cor-id` value is
set, then an [`<xref>`][elem:xref] link of
[`ref-type`][attr:ref-type] `corresp` is added. The
[`rid`][attr:rid] attribute is set to `cor-`, where
`` is the stringified value of this attribute.
Furthermore, the [`corresp`][attr:corresp] attribute on
the author's [`<contrib>`] element is set to `yes` if
this attribute is set to a truthy.affiliation
: the list of organizations with which contributors are
affiliated. Each institution is added as an <aff> element to
the author's contrib-group.
The fields are given in the order in which they are included in
the output.
`id`
: internal identifier; used as the [`<aff>`] element's `id`
value, prefixed with `aff-`.
`group`
: name of the research group or other low-level organizational
structure; used as value of an [``] element with
[`content-type`][attr:content-type] set to `group`.
`department`
: name of the department or other mid-level organizational
structure; used as value of an [``] element with
[`content-type`][attr:content-type] set to `dept`.
`organization`
: name of the company, university, or other top-level
organizational structure; used as value of an
[``] element. The institution element is wrapped
in an [``] element; any identifiers, like
`ringgold` or `ror`, are added to the wrapper and must hence
belong to this organization (not the department or group).
`isni`
: International Standard Name Identifier of the organization.
Added via an [``] element with
[`institution-id-type`](attr:institution-id-type) set to
`ISNI`.
`ringgold`
: [Ringgold] identifier of the organization. Added via an
[``] element with
[`institution-id-type`](attr:institution-id-type) set to
`Ringgold`.
`ror`
: Research Organization Registry identifier of the
organization. Added via an [``] element with
[`institution-id-type`](attr:institution-id-type) set to
`ROR`.
`pid`
: Array of persistent identifiers which are added as
[``] elements. Each item must contain a map
with keys `type`, used as
[`institution-id-type`](attr:institution-id-type), and `id`,
used as element content.
`street-address`
: The organization's street address; each list item is wrapped
in an [`<addr-line>`] element, separated by a comma and
space (`, `).
`city`
: City in which the organization is located; used only if
`street-address` is not given, in which case the value is
wrapped in a [`<city>`] element.
`country`
: Country in which the organization is located; used as the
value of a [`<country>`] element.
`country-code`
: Two letter ISO-3166-1 country identifier; used as the
[`country`][attr:country] attribute in element [`<country>`]
(if the latter is present).copyright
: Copyright and licensing information. This information is
rendered via the `` element.
It is recommended to use the `license` field (described below)
for licensing information. If licensing information is
included below `copyright`, then the variables `type`, `link`,
and `text` should always be used together.
`statement`
: copyright notice or statement; used as content of the
[`<copyright-statement>`][elem:copyright-statement]. Use a
list for multiple statements.
`year`
: the year of copyright; used as content of the
[`<copyright-year>`][elem:copyright-year]. Use a list to
for multiple copyright years. The JATS documentation
states that this field need not to be used if the year is
included in the copyright statement.
`holder`
: the copyright holder; included via the
[`<copyright-holder>`][elem:copyright-holder] element. Use
a list for multiple copyright holders.
`text`
: inline text setting the license under which the text is
published; included via the
[`<license-p>`][elem:copyright-holder] element.
`type`
: type of the license; used as value of the
[`license-type`][attr:license-type] attribute.
`link`
: external link describing the license; used as value of a
`xlink:href` attribute in the `<license>` element.date
: publication date. This value should usually be a string
representation of a date. Pandoc will parse and deconstruct the
date into the components given below. It is also possible to
pass these components directly.
The publication date is recorded in the document via the
[``] element and its sub-elements. The
[`publication-format`][attr:publication-format] attribute is
always set to `electronic`.
`iso-8601`
: ISO-8601 representation of the publication date. Used as the
value of the [``] element's
[`iso-8601-date`][attr:iso-8601-date] attribute.
This value is set automatically if pandoc can parse the
`date` value as a date.
`day`, `month`, `year`
: Day, month, and year of the publication date. Only the
publication year is required. The values are used as the
contents of the elements with the respective names.
The values are set automatically if pandoc can parse the
`date` value as a date.
`type`
: The type of event marked by this date. The value is set as
the [`date-type`][attr:date-type] attribute on the
[``] element and defaults to "pub" if not
specified.article
: information concerning the article that identifies or describes
it. The key-value pairs within this map are typically used
within the <article-meta> element.
`publisher-id`
: external article identifier assigned by the publisher. Used
as the content of the [`<article-id>`][elem:article-id]
element with attribute [`pub-id-type`][attr:pub-id-type] set
to `publisher-id`.
`doi`
: Digital Object Identifier (DOI) assigned to the article.
Used as the content of the [`<article-id>`][elem:article-id]
element with attribute [`pub-id-type`][attr:pub-id-type] set
to `doi`.
`pmid`
: PubMed Identifier (PubMed ID) assigned to the article. Used
as the content of the [`<article-id>`][elem:article-id]
element with attribute [`pub-id-type`][attr:pub-id-type] set
to `pmid`.
`pmcid`
: PubMed Central Identifier assigned to the article. Used as
the content of the [`<article-id>`][elem:article-id] element
with attribute [`pub-id-type`][attr:pub-id-type] set to
`pmcid`.
`art-access-id`
: generic article accession identifier. Used as the content of
the [`<article-id>`][elem:article-id] element with attribute
[`pub-id-type`][attr:pub-id-type] set to `art-access-id`.
`heading`
: name of a subject or topic describing the article. Used as
the content of the [`<subject>`][elem:subject] element,
nested in a [`<subj-group>`][elem:subj-group] element which
has `heading` as its
[`subj-group-type`][attr:subj-group-type] attribute.
`categories`
: list a subject or topic describing the article. Items are
each used as the content a the [`<subject>`][elem:subject]
element, grouped in a single
[`<subj-group>`][elem:subj-group] element with its
[`subj-group-type`][attr:subj-group-type] attribute set to
`categories`.
`author-notes`
: Additional information about authors, like conflict of
interest statements and corresponding author contact info.
Wrapped in an [`<author-notes>`][elem:author-notes] element.
`conflict`
: Conflict of interest statement. Rendered as a footnote
([`<fn>`][elem:fn]) of [`fn-type`](attr:fn-type)
`conflict`.
`con`
: Contributed-by information. Rendered as a footnote
([`<fn>`][elem:fn]) of [`fn-type`](attr:fn-type) `con`.
`corresp`
: Correspondence information. This must be a list of
contributor correspondence items, where each item must
have the properties `id` and `email`. The info is then
rendered via a [`<corresp>`][elem:corresp] element.
`funding-statement`
: Prose describing the funding. Added to the article's
frontmatter via the
[`funding-statement`][elem:funding-statement] element.journal
: information on the journal in which the article is published.
This must be a map; the following key/value pairs are
recognized.
`publisher-id`
: journal identifier assigned by the publisher. Used as
content of element [`<journal-id>`][elem:journal-id] with
attribute [`journal-id-type`][attr:journal-id-type] set to
`publisher-id`.
`nlm-ta`
: journal identifier assigned by PubMed. Used as content of
element [`<journal-id>`][elem:journal-id] with attribute
[`journal-id-type`][attr:journal-id-type] set to `nlm-ta`.
`pmc`
: journal identifier assigned by PubMed Central. Used as
content of element [`<journal-id>`][elem:journal-id] with
attribute [`journal-id-type`][attr:journal-id-type] set to
`pmc`.
`title`
: full title of the journal in which the article is published.
Used as content of the
[`<journal-title>`][elem:journal-title] element.
`abbrev-title`
: short form of the journal title. Used as content of the
[`<abbrev-journal-title>`][elem:abbrev-journal-title]
element.
`pissn`
: ISSN identifier of the publication's print version. Used as
content of the [``][elem:issn] element with the
[`publication-format`][attr:publication-format] attribute
set to `print`.
`eissn`
: ISSN identifier of the publication's electronic version.
Used as content of the [``][elem:issn] element with
the [`publication-format`][attr:publication-format]
attribute set to `electronic`.
`publisher-name`
: name of the publishing entity (person, company, or other).
Used as the content of the
[``][elem:publisher-name] element.
`publisher-loc`
: place of publication. Used as the content of the
[``][elem:publisher-loc] element.license
: Article licensing information. Each item of this field is
rendered as a <license> element within the
`` element.
Item content should be either a single paragraph, or a map
with the fields listed below.
`text`
: inline text describing a license under which the text is
published; included via the
[`<license-p>`][elem:copyright-holder] element.
`type`
: type of the license; used as value of the
[`license-type`][attr:license-type] attribute.
`link`
: external link describing the license; used as value of a
`xlink:href` attribute in the `<license>` element.notes
: Additional notes concerning the whole article. Added to the
article's frontmatter via the <notes> element.
subtitle
: Subordinate part of the document title. Added to the
document's front matter as a
<subtitle> element.
tags
: list of keywords. Items are used as contents of the
<kwd> element; the elements are grouped in a
<kwd-group> with the
kwd-group-type value author.
title
: The article title. Added to the document's front matter via the
<article-title> element.
supplementary-material
: Supplementary metadata. Added to the document's front matter
via the <supplementary-material>
element. Only available with jats_articlepublishing.
floats-group
: List of floating objects, such as figures, tables, text boxes,
etc., that are not part of the main text. The value is
rendered by nesting it below a
<floats-group> element. Only available
with jats_publishing and jats_archiving.
Required Metadata
Pandoc will try to generate a valid JATS document even when
information is missing, filling in placeholders or using empty
values. This circumvents the intend to ensure a minimum set of
information being present in documents of a certain tag set. It is
hence recommended to always provide the information listed below.
Publishing Tag Set
Required metadata values:
- One or more of
journal.publisher-id,journal.nlm-ta,journal.pmc. - One or more of
journal.pissn,journal.eissn.