pandoc Documentation

Universal markup converter

45,832 stars Haskell Haskell 1 file ยท ~26,240 tokens #commonmark#converter#document#haskell#markdown#markup#pandoc#presentation
RAW Doc

File: README.md

Pandoc

githubrelease
hackagerelease

stackage LTSpackage
CItests

pandoc-discuss on googlegroups

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

It can convert to

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 function
tostring.

A minimal example would be

lua
function Reader(input)
  return pandoc.Pandoc({ pandoc.CodeBlock(tostring(input)) })
end

This 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

lua
function Reader(input)
  return pandoc.Pandoc(input:map(
    function (s) return pandoc.CodeBlock(s.text) end))
end

In 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. A
ByteStringReader 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.

lua
-- read input as epub
function ByteStringReader (input)
  return pandoc.read(input, 'epub')
end

Format 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 or
enable, while those that are supported but disabled have value
false 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:

lua
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.:

lua
function Reader (input, opts)
  print(
    'The citations extension is',
    opts.extensions:includes 'citations' and 'enabled' or 'disabled'
  )
  -- ...
end

Extensions that are neither enabled nor disabled in the
Extensions 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.

lua
-- 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))
end

Example of use:

text
% 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.

text
/* Detailed source-code truncated for AI context efficiency. */

Example of use:

text
% 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 using
luarocks install luajson---but be sure you are installing it for
Lua 5.4, which is the version packaged with pandoc.

lua
-- 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)

end

Similar 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.

lua
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))
end

Example: 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.

text
/* Detailed source-code truncated for AI context efficiency. */

Example of use:

text
pandoc -f readable.lua -t markdown https://pandoc.org

and compare the output to

text
pandoc -f html -t markdown https://pandoc.org

File: 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 either
Writer 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.

lua
function Writer (doc, opts)
  -- ...
end

Writers 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 as
smart, citations, or hard_line_breaks. The global
Extensions 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:

lua
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.:

lua
function Writer (doc, opts)
  print(
    'The citations extension is',
    opts.extensions:includes 'citations' and 'enabled' or 'disabled'
  )
  -- ...
end

Default 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.

lua
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:

lua
Writer = pandoc.scaffolding.Writer

The 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.

lua
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}
end

The 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 to
pandoc.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,

lua
function Para(s)
  return "" .. s .. ""
end

Template 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:

lua
function Doc (body, meta, vars)
  vars.date = vars.date or meta.date or os.date '%B %e, %Y'
  return body, vars
end

Changes 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.

lua
function Writer (doc, opts)
  PANDOC_DOCUMENT = doc
  PANDOC_WRITER_OPTIONS = opts
  loadfile(PANDOC_SCRIPT_FILE)()
  return pandoc.write_classic(doc, opts)
end

File: 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 do
pandoc -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

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:

text
% 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:

text
pandoc mybook.txt -o mybook.epub

You 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]

text
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:

text
cd progit/en

As 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:

text
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:

text
perl -i -0pe \
's/^Insert\s*(.*)\.png\s*\n([^\n]*)$/!\[\2](..\/figures\/\1-tn.png)/mg' \
*/*.markdown

This 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 with
git 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:

text
---
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:

text
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.markdown

That'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:

  1. Use the --webtex option,
    which will use a web service to convert the TeX to an image.
  2. Use the --gladtex option
    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

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

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 programs pandoc and make.
    Please note that it is no longer maintained and refers to Quarto and pandoc-ext

Containers

Lua filters

(For a fuller list, see the lua-filters
repository
.)

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:

text
for f in *.txt; do pandoc "$f" -s -o "${f%.txt}.rtf"; done

In Windows Powershell:

text
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:

text
pandoc -s -f markdown -t icml -o my.icml my.md

I 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:

text
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:

text
msiexec /i pandoc-VERSION.msi ALLUSERS=1

This will put pandoc in C:\Program Files\Pandoc.
You can install Pandoc to a different directory by setting APPLICATIONFOLDER parameter,
for example:

text
msiexec /i pandoc-1.11.1.msi ALLUSERS=1 APPLICATIONFOLDER="C:\Pandoc"

How do I change the margins in PDF output?

The option

text
-V geometry:margin=1in

will set the margins to one inch on each side. If you don't want uniform
margins, you can do something like

text
-V geometry:"top=2cm, bottom=1.5cm, left=1cm, right=1cm"

Or

text
-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:

text
% 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 or
makeatother 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,

text
pandoc -o my.pdf --pdf-engine=/Library/TeX/texbin/pdflatex

When 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 of
require.js.
To ensure that this script is available in your HTML output, you
can use:

text
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:

text
pandoc --pdf-engine=context -V pdfa

Alternatively, --pdf-engine=pdflatex can be used with
the following in header-includes in metadata (or included from
a file using --include-in-header):

text
\usepackage[a-2u,mathxmp]{pdfx}
\usepackage[pdfa]{hyperref}

Or --pdf-engine=lualatex can be used with the following:

text
\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.)

lua
-- 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
end

How 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.

text
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 module
Text.Pandoc.Definition in the pandoc-types package .

A "filter" is a program that modifies the AST, between the
reader and the writer.

text
INPUT --reader--> AST --filter--> AST --writer--> OUTPUT

Pandoc 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:

    text
    source 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:

text
pandoc -s input.txt -t json | \
 pandoc-citeproc | \
 pandoc -s -f json -o output.html

But it is more convenient to use the --filter option,
which handles the plumbing automatically:

text
pandoc -s input.txt --filter pandoc-citeproc -o output.html

For 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:

text
perl -pe 's/^##+ (.*)$/\*\1\*/' source.txt

This 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:

text
## My heading ##

And what if your document contains a line starting with ## in an HTML
comment or delimited code block?

text
~~~~
### A third level heading in standard markdown
~~~~

We don't want to touch these lines. Moreover, what about Setext
style second-level heading?

text
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:

text
% 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:

{.haskell}
#!/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 = x

The 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:

text
chmod +x behead.hs

and then

text
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:

text
ghc -package-env=default --make behead.hs
pandoc -f SOURCEFORMAT -t TARGETFORMAT --filter ./behead

Note 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:

{.haskell}
#!/usr/bin/env runhaskell
-- wordpressify.hs
import Text.Pandoc.JSON

main = toJSONFilter wordpressify
  where wordpressify (Math x y) = Math x ("LaTeX " ++ y)
        wordpressify x = x

Mission 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:

{.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?

{.haskell}
#!/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 doInclude

Try this on the following:

text
Here's the pandoc README:

~~~~ {include="README"}
this will be replaced by contents of README
~~~~

What if we want to remove every link from a document, retaining
the link's text?

{.haskell}
#!/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 single
Inline 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 type
Pandoc -> 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 like

text
r[ใฏใ‚“](้ฃฏ)

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:

text
[ใฏใ‚“](-้ฃฏ)
{.haskell}
{-# 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 handleRuby

Note 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:

text
# first, make sure pandoc-types is installed:
cabal install --lib pandoc-types --package-env .
ghc --make handleRuby

Then run it:

text
% 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

  1. Put all the regular text in a markdown document in ALL CAPS
    (without touching text in URLs or link titles).

  2. Remove all horizontal rules from a document.

  3. Renumber all enumerated lists with roman numerals.

  4. Replace each delimited code block with class dot with an
    image generated by running dot -Tpng (from graphviz) on the
    contents of the code block.

  5. Find all code blocks with class python and 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

text
pandoc --filter demo --to=html

will 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.

text
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 to
    Applications, then Utilities. Then double click on
    Terminal. (Or, click the spotlight icon in the upper right
    hand corner of your screen and type Terminal -- you should
    see Terminal under Applications.)

  • On Windows, you can use either the classic command prompt or the
    more modern PowerShell terminal. If you use Windows in desktop
    mode, run the cmd or powershell command from the Start menu.
    If you use the Windows 8 start screen instead, simply type
    cmd or powershell, and then run either the "Command
    Prompt" or "Windows Powershell" application. If you are using
    cmd, type chcp 65001 before 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
      for Terminal. Or, use the keyboard shortcut Ctrl-Alt-T.
    • In Gnome, go to Applications, then Accessories, and
      select Terminal, or use Ctrl-Alt-T.
    • In XFCE, go to Applications, then System, then Terminal,
      or use Super-T.
    • In KDE, go to KMenu, then System, then Terminal Program (Konsole).

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

text
pandoc --version

and 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

text
pwd

on Linux or OSX, or

text
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

text
cd Documents

and hit enter. Now type

text
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

text
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:

text
mkdir pandoc-test

Now change to the pandoc-test directory:

text
cd pandoc-test

If the prompt doesn't tell you what directory you're in, you can
confirm that you're there by doing

text
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:

text
cd ..

Now, type

text
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 (or echo %cd% on Windows)
    to see what the current working directory is.
  • cd foo to change to the foo subdirectory of your working
    directory.
  • cd .. to move up to the parent of the working directory.
  • mkdir foo to create a subdirectory called foo in 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

text
pandoc

and hit enter. You should see the cursor just sitting there, waiting
for you to type something. Type this:

text
Hello *pandoc*!

- one
- two

When 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!

text
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:

text
pandoc -f html -t markdown

Now type:

text
Hello *pandoc*!

and hit Ctrl-D (or Ctrl-Z followed by Enter on Windows).
You should see:

text
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 use
TextEdit (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:

text
---
title: Test
...

# Test!

This is a test of *pandoc*.

- list one
- list two

Now save your file as test1.md in the directory
Documents/pandoc-test.

Note: If you use plain text a lot, you'll want a better editor than
Notepad 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 the
Documents/pandoc-test directory. Verify that with pwd.

Now type

text
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:

text
pandoc test1.md -f markdown -t html -s -o test1.html

The 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

text
open test1.html

On Windows, type

text
.\test1.html

You should see a browser window with your document.

To create a LaTeX document, you just need to change the command
slightly:

text
pandoc test1.md -f markdown -t latex -s -o test1.tex

Try 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:

text
pandoc test1.md -s -o test1.tex

Pandoc 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

text
pandoc test1.md -s -o test1.pdf

Step 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

text
pandoc --mathml

then enter this text, followed by Ctrl-D (Ctrl-Z followed by
Enter on Windows):

text
$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

text
pandoc --help

to get a list of all the supported options.

On OS X or Linux systems, you can also do

text
man pandoc

to 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.

text
`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.

text
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.

text
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.

text
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.

text
`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.

text
`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.

text
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.