diff --git a/AUTHORS.md b/AUTHORS.md
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -147,6 +147,7 @@
 - RyanGlScott
 - Sascha Wilde
 - Scott Morrison
+- Sebastian Talmon
 - Sergei Trofimovich
 - Sergey Astanin
 - Shahbaz Youssefi
diff --git a/COPYRIGHT b/COPYRIGHT
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,5 +1,5 @@
 Pandoc
-Copyright (C) 2006-2017 John MacFarlane <jgm at berkeley dot edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm at berkeley dot edu>
 
 With the exceptions noted below, this code is released under the [GPL],
 version 2 or later:
@@ -37,7 +37,7 @@
 Text.Pandoc.Builder, Text.Pandoc.Generics, Text.Pandoc.JSON,
 Text.Pandoc.Walk) are licensed under the BSD 3-clause license:
 
-Copyright (c) 2006-2017, John MacFarlane
+Copyright (c) 2006-2018, John MacFarlane
 
 All rights reserved.
 
@@ -72,29 +72,29 @@
 Pandoc's templates (in `data/templates`) are dual-licensed GPL (v2 or
 higher, same as pandoc) and the BSD 3-clause license.
 
-Copyright (c) 2014--2017, John MacFarlane
+Copyright (c) 2014--2018, John MacFarlane
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Writers/Muse.hs
-Copyright (C) 2017 Alexander Krotov
+Copyright (C) 2017-2018 Alexander Krotov
 
 Released under the GNU General Public License version 2 or later.
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Writers/Texinfo.hs
-Copyright (C) 2008-2017 John MacFarlane and Peter Wang
+Copyright (C) 2008-2018 John MacFarlane and Peter Wang
 
 Released under the GNU General Public License version 2 or later.
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Writers/OpenDocument.hs
-Copyright (C) 2008-2017 Andrea Rossato and John MacFarlane
+Copyright (C) 2008-2018 Andrea Rossato and John MacFarlane
 
 Released under the GNU General Public License version 2 or later.
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Writers/Org.hs
-Copyright (C) 2010-2017 Puneeth Chaganti, John MacFarlane, and
+Copyright (C) 2010-2018 Puneeth Chaganti, John MacFarlane, and
                         Albert Krewinkel
 
 Released under the GNU General Public License version 2 or later.
@@ -108,20 +108,21 @@
 ----------------------------------------------------------------------
 src/Text/Pandoc/Readers/Docx.hs
 src/Text/Pandoc/Readers/Docx/*
-Copyright (C) 2014-2017 Jesse Rosenthal
+Copyright (C) 2014-2018 Jesse Rosenthal
 
 Released under the GNU General Public License version 2 or later.
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Readers/Textile.hs
-Copyright (C) 2010-2017 Paul Rivier and John MacFarlane
+Copyright (C) 2010-2018 Paul Rivier and John MacFarlane
 
 Released under the GNU General Public License version 2 or later.
 
 ----------------------------------------------------------------------
 src/Text/Pandoc/Readers/Org.hs
-test/Tests/Readers/Org.hs
-Copyright (C) 2014-2017 Albert Krewinkel
+src/Text/Pandoc/Readers/Org/*
+test/Tests/Readers/Org/*
+Copyright (C) 2014-2018 Albert Krewinkel
 
 Released under the GNU General Public License version 2 or later.
 
@@ -141,7 +142,7 @@
 
 ------------------------------------------------------------------------
 data/pandoc.lua
-Copyright (C) 2017 Albert Krewinkel
+Copyright (C) 2017-2018 Albert Krewinkel
 
 Released under the GNU General Public License version 2 or later.
 
@@ -155,7 +156,7 @@
 ------------------------------------------------------------------------
 Pandoc embeds a lua interpreter (via hslua).
 
-Copyright © 1994–2015 Lua.org, PUC-Rio.
+Copyright © 1994–2017 Lua.org, PUC-Rio.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/MANUAL.txt b/MANUAL.txt
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1,6 +1,6 @@
 % Pandoc User's Guide
 % John MacFarlane
-% December 27, 2017
+% January 7, 2018
 
 Synopsis
 ========
@@ -11,13 +11,16 @@
 ===========
 
 Pandoc is a [Haskell] library for converting from one markup format to
-another, and a command-line tool that uses this library. It can read
-[Markdown], [CommonMark], [PHP Markdown Extra], [GitHub-Flavored
-Markdown], [MultiMarkdown], and (subsets of) [Textile],
+another, and a command-line tool that uses this library.
+
+Pandoc can read [Markdown], [CommonMark], [PHP Markdown Extra],
+[GitHub-Flavored Markdown], [MultiMarkdown], and (subsets of) [Textile],
 [reStructuredText], [HTML], [LaTeX], [MediaWiki markup], [TWiki
 markup], [TikiWiki markup], [Creole 1.0], [Haddock markup], [OPML],
 [Emacs Org mode], [DocBook], [JATS], [Muse], [txt2tags], [Vimwiki],
-[EPUB], [ODT], and [Word docx]; and it can write plain text, [Markdown],
+[EPUB], [ODT], and [Word docx].
+
+Pandoc can write plain text, [Markdown],
 [CommonMark], [PHP Markdown Extra], [GitHub-Flavored Markdown],
 [MultiMarkdown], [reStructuredText], [XHTML], [HTML5], [LaTeX]
 \(including [`beamer`] slide shows\), [ConTeXt], [RTF], [OPML],
@@ -30,21 +33,20 @@
 [PDF] output on systems where LaTeX, ConTeXt, `pdfroff`,
 `wkhtmltopdf`, `prince`, or `weasyprint` is installed.
 
-Pandoc's enhanced version of Markdown includes syntax for [footnotes],
-[tables], flexible [ordered lists], [definition lists], [fenced code
-blocks], [superscripts and subscripts], [strikeout], [metadata blocks],
-automatic tables of contents, embedded LaTeX [math], [citations], and
-[Markdown inside HTML block elements][Extension:
-`markdown_in_html_blocks`]. (These enhancements, described further under
-[Pandoc's Markdown], can be disabled using the `markdown_strict` input
-or output format.)
+Pandoc's enhanced version of Markdown includes syntax for [tables],
+[definition lists], [metadata blocks], [`Div` blocks][Extension:
+`fenced_divs`], [footnotes] and [citations], embedded
+[LaTeX][Extension: `raw_tex`] (including [math]), [Markdown inside HTML
+block elements][Extension: `markdown_in_html_blocks`], and much more.
+These enhancements, described further under [Pandoc's Markdown],
+can be disabled using the `markdown_strict` format.
 
-In contrast to most existing tools for converting Markdown to HTML, which
-use regex substitutions, 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, and a set of writers, which convert
+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
+(like 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.
+or output format requires only adding a reader or writer. Users can also
+run custom [pandoc filters] to modify the intermediate AST.
 
 Because pandoc's intermediate representation of a document is less
 expressive than many of the formats it converts between, one should
@@ -109,45 +111,32 @@
 Using `pandoc`
 --------------
 
-If no *input-file* is specified, input is read from *stdin*.
-Otherwise, the *input-files* are concatenated (with a blank
-line between each) and used as input.  Output goes to *stdout* by
-default (though output to the terminal is disabled for the
-`odt`, `docx`, `epub2`, and `epub3` output formats, unless it is
-forced using `-o -`).  For output to a file, use the `-o`
-option:
+If no *input-files* are specified, input is read from *stdin*.
+Output goes to *stdout* by default. For output to a file,
+use the `-o` option:
 
     pandoc -o output.html input.txt
 
-By default, pandoc produces a document fragment, not a standalone
-document with a proper header and footer.  To produce a standalone
-document, use the `-s` or `--standalone` flag:
+By default, pandoc produces a document fragment. To produce a standalone
+document (e.g. a valid HTML file including `<head>` and `<body>`),
+use the `-s` or `--standalone` flag:
 
     pandoc -s -o output.html input.txt
 
 For more information on how standalone documents are produced, see
-[Templates], below.
-
-Instead of a file, an absolute URI may be given.  In this case
-pandoc will fetch the content using HTTP:
-
-    pandoc -f html -t markdown http://www.fsf.org
-
-It is possible to supply a custom User-Agent string or other
-header when requesting a document from a URL:
-
-    pandoc -f html -t markdown --request-header User-Agent:"Mozilla/5.0" \
-      http://www.fsf.org
+[Templates] below.
 
 If multiple input files are given, `pandoc` will concatenate them all (with
-blank lines between them) before parsing. This feature is disabled for
- binary input formats such as `EPUB`, `odt`, and `docx`.
+blank lines between them) before parsing. (Use `--file-scope` to parse files
+individually.)
 
+Specifying formats
+------------------
+
 The format of the input and output can be specified explicitly using
 command-line options.  The input format can be specified using the
-`-r/--read` or `-f/--from` options, the output format using the
-`-w/--write` or `-t/--to` options.  Thus, to convert `hello.txt` from
-Markdown to LaTeX, you could type:
+`-f/--from` option, the output format using the `-t/--to` option.
+Thus, to convert `hello.txt` from Markdown to LaTeX, you could type:
 
     pandoc -f markdown -t latex hello.txt
 
@@ -155,14 +144,15 @@
 
     pandoc -f html -t markdown hello.html
 
-Supported output formats are listed below under the `-t/--to` option.
-Supported input formats are listed below under the `-f/--from` option. Note
-that the `rst`, `textile`, `latex`, and `html` readers are not complete;
-there are some constructs that they do not parse.
+Supported input and output formats are listed below under [Options]
+(see `-f` for input formats and `-t` for output formats).  You
+can also use `pandoc --list-input-formats` and
+`pandoc --list-output-formats` to print lists of supported
+formats.
 
 If the input or output format is not specified explicitly, `pandoc`
-will attempt to guess it from the extensions of
-the input and output filenames.  Thus, for example,
+will attempt to guess it from the extensions of the filenames.
+Thus, for example,
 
     pandoc -o hello.tex hello.txt
 
@@ -171,8 +161,11 @@
 extension is unknown, the output format will default to HTML.
 If no input file is specified (so that input comes from *stdin*), or
 if the input files' extensions are unknown, the input format will
-be assumed to be Markdown unless explicitly specified.
+be assumed to be Markdown.
 
+Character encoding
+------------------
+
 Pandoc uses the UTF-8 character encoding for both input and output.
 If your local character encoding is not UTF-8, you
 should pipe input and output through [`iconv`]:
@@ -189,30 +182,12 @@
 Creating a PDF
 --------------
 
-To produce a PDF, specify an output file with a `.pdf` extension.
-By default, pandoc will use LaTeX to create the PDF:
+To produce a PDF, specify an output file with a `.pdf` extension:
 
     pandoc test.txt -o test.pdf
 
-Production of a PDF requires that a LaTeX engine be installed (see
-`--pdf-engine`, below), and assumes that the following LaTeX packages
-are available: [`amsfonts`], [`amsmath`], [`lm`], [`unicode-math`],
-[`ifxetex`], [`ifluatex`], [`listings`] (if the
-`--listings` option is used), [`fancyvrb`], [`longtable`],
-[`booktabs`], [`graphicx`] and [`grffile`] (if the document
-contains images), [`hyperref`], [`xcolor`] (with `colorlinks`), [`ulem`], [`geometry`] (with the
-`geometry` variable set), [`setspace`] (with `linestretch`), and
-[`babel`] (with `lang`).  The use of `xelatex` or `lualatex` as
-the LaTeX engine requires [`fontspec`].  `xelatex` uses
-[`polyglossia`] (with `lang`), [`xecjk`], and [`bidi`] (with the
-`dir` variable set). If the `mathspec` variable is set,
-`xelatex` will use [`mathspec`] instead of [`unicode-math`].
-The [`upquote`] and [`microtype`] packages are used if
-available, and [`csquotes`] will be used for [typography]
-if added to the template or included in any header file. The
-[`natbib`], [`biblatex`], [`bibtex`], and [`biber`] packages can
-optionally be used for [citation rendering]. These are included
-with all recent versions of [TeX Live].
+By default, pandoc will use LaTeX to create the PDF, which requires
+that a LaTeX engine be installed (see `--pdf-engine` below).
 
 Alternatively, pandoc can use [ConTeXt], `pdfroff`, or any of the
 following HTML/CSS-to-PDF-engines, to create a PDF: [`wkhtmltopdf`],
@@ -228,6 +203,30 @@
 `margin-right`, `margin-top`, `margin-bottom`, and `papersize`
 will affect the output.
 
+To debug the PDF creation, it can be useful to look at the intermediate
+representation: instead of `-o test.pdf`, use for example `-s -o test.tex`
+to output the generated LaTeX. You can then test it with `pdflatex test.tex`.
+
+When using LaTeX, the following packages need to be available
+(they are included with all recent versions of [TeX Live]):
+[`amsfonts`], [`amsmath`], [`lm`], [`unicode-math`],
+[`ifxetex`], [`ifluatex`], [`listings`] (if the
+`--listings` option is used), [`fancyvrb`], [`longtable`],
+[`booktabs`], [`graphicx`] and [`grffile`] (if the document
+contains images), [`hyperref`], [`xcolor`] (with `colorlinks`),
+[`ulem`], [`geometry`] (with the `geometry` variable set),
+[`setspace`] (with `linestretch`), and
+[`babel`] (with `lang`).  The use of `xelatex` or `lualatex` as
+the LaTeX engine requires [`fontspec`].  `xelatex` uses
+[`polyglossia`] (with `lang`), [`xecjk`], and [`bidi`] (with the
+`dir` variable set). If the `mathspec` variable is set,
+`xelatex` will use [`mathspec`] instead of [`unicode-math`].
+The [`upquote`] and [`microtype`] packages are used if
+available, and [`csquotes`] will be used for [typography]
+if added to the template or included in any header file. The
+[`natbib`], [`biblatex`], [`bibtex`], and [`biber`] packages can
+optionally be used for [citation rendering].
+
 [`amsfonts`]: https://ctan.org/pkg/amsfonts
 [`amsmath`]: https://ctan.org/pkg/amsmath
 [`lm`]: https://ctan.org/pkg/lm
@@ -262,6 +261,20 @@
 [`weasyprint`]: http://weasyprint.org
 [`prince`]: https://www.princexml.com/
 
+Reading from the Web
+--------------------
+
+Instead of an input file, an absolute URI may be given.  In this case
+pandoc will fetch the content using HTTP:
+
+    pandoc -f html -t markdown http://www.fsf.org
+
+It is possible to supply a custom User-Agent string or other
+header when requesting a document from a URL:
+
+    pandoc -f html -t markdown --request-header User-Agent:"Mozilla/5.0" \
+      http://www.fsf.org
+
 Options
 =======
 
@@ -318,9 +331,8 @@
     below). (`markdown_github` provides deprecated and less accurate
     support for Github-Flavored Markdown; please use `gfm` instead,
     unless you use extensions that do not work with `gfm`.) Note that
-    `odt`, `epub`, and `epub3` output will not be directed to
-    *stdout*; an output filename must be specified using the
-    `-o/--output` option.  Extensions can be individually enabled or
+    `odt`, `docx`, and `epub` output will not be directed to *stdout*
+    unless forced with `-o -`. Extensions can be individually enabled or
     disabled by appending `+EXTENSION` or `-EXTENSION` to the format
     name.  See [Extensions] below, for a list of extensions and their
     names.  See `--list-output-formats` and `--list-extensions`, below.
@@ -389,7 +401,7 @@
 
 `--list-extensions`[`=`*FORMAT*]
 
-:   List supported Markdown extensions, one per line, preceded
+:   List supported extensions, one per line, preceded
     by a `+` or `-` indicating whether it is enabled by default
     in *FORMAT*. If *FORMAT* is not specified, defaults for
     pandoc's Markdown are given.
@@ -482,6 +494,9 @@
 
      3. `$PATH` (executable only)
 
+    Filters and lua-filters are applied in the order specified
+    on the command line.
+
 `--lua-filter=`*SCRIPT*
 
 :   Transform the document in a similar fashion as JSON filters (see
@@ -539,8 +554,11 @@
     `insertion`, `deletion`, `comment-start`, and `comment-end`
     classes, respectively. The author and time of change is
     included. `all` is useful for scripting: only accepting changes
-    from a certain reviewer, say, or before a certain date. This
-    option only affects the docx reader.
+    from a certain reviewer, say, or before a certain date. If a
+    paragraph is inserted or deleted, `track-changes=all` produces a
+    span with the class `paragraph-insertion`/`paragraph-deletion`
+    before the affected paragraph break. This option only affects the
+    docx reader.
 
 `--extract-media=`*DIR*
 
@@ -3302,45 +3320,6 @@
 but it makes it easier to write pandoc filters to manipulate groups
 of inlines.
 
-#### Extension: `fenced_divs` ####
-
-Allow special fenced syntax for native `Div` blocks.  A Div
-starts with a fence containing at least three consecutive
-colons plus some attributes. The attributes may optionally
-be followed by another string of consecutive colons.
-The attribute syntax is exactly as in fenced code blocks (see
-[Extension: `fenced_code_attributes`]).  As with fenced
-code blocks, one can use either attributes in curly braces
-or a single unbraced word, which will be treated as a class
-name.  The Div ends with another line containing a string of at
-least three consecutive colons.  The fenced Div should be
-separated by blank lines from preceding and following blocks.
-
-Example:
-
-    ::::: {#special .sidebar}
-    Here is a paragraph.
-
-    And another.
-    :::::
-
-Fenced divs can be nested.  Opening fences are distinguished
-because they *must* have attributes:
-
-    ::: Warning ::::::
-    This is a warning.
-
-    ::: Danger
-    This is a warning within a warning.
-    :::
-    ::::::::::::::::::
-
-Fences without attributes are always closing fences.  Unlike
-with fenced code blocks, the number of colons in the closing
-fence need not match the number in the opening fence.  However,
-it can be helpful for visual clarity to use fences of different
-lengths to distinguish nested divs from their parents.
-
 #### Extension: `raw_tex` ####
 
 In addition to raw HTML, pandoc allows raw LaTeX, TeX, and ConTeXt to be
@@ -3602,13 +3581,59 @@
   is to look at the image resolution and the dpi metadata embedded in
   the image file.
 
-Spans
------
+Divs and Spans
+--------------
 
+Using the `native_divs` and `native_spans` extensions
+(see [above][Extension: `native_divs`]), HTML syntax can
+be used as part of markdown to create native `Div` and `Span`
+elements in the pandoc AST (as opposed to raw HTML).
+However, there is also nicer syntax available:
+
+#### Extension: `fenced_divs` ####
+
+Allow special fenced syntax for native `Div` blocks.  A Div
+starts with a fence containing at least three consecutive
+colons plus some attributes. The attributes may optionally
+be followed by another string of consecutive colons.
+The attribute syntax is exactly as in fenced code blocks (see
+[Extension: `fenced_code_attributes`]).  As with fenced
+code blocks, one can use either attributes in curly braces
+or a single unbraced word, which will be treated as a class
+name.  The Div ends with another line containing a string of at
+least three consecutive colons.  The fenced Div should be
+separated by blank lines from preceding and following blocks.
+
+Example:
+
+    ::::: {#special .sidebar}
+    Here is a paragraph.
+
+    And another.
+    :::::
+
+Fenced divs can be nested.  Opening fences are distinguished
+because they *must* have attributes:
+
+    ::: Warning ::::::
+    This is a warning.
+
+    ::: Danger
+    This is a warning within a warning.
+    :::
+    ::::::::::::::::::
+
+Fences without attributes are always closing fences.  Unlike
+with fenced code blocks, the number of colons in the closing
+fence need not match the number in the opening fence.  However,
+it can be helpful for visual clarity to use fences of different
+lengths to distinguish nested divs from their parents.
+
+
 #### Extension: `bracketed_spans` ####
 
 A bracketed sequence of inlines, as one would use to begin
-a link, will be treated as a span with attributes if it is
+a link, will be treated as a `Span` with attributes if it is
 followed immediately by attributes:
 
     [This is *some text*]{.class key="val"}
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,155 +1,149 @@
-Pandoc
-======
+<!-- Do not edit this file.  It is generated automatically from
+README.template and MANUAL.txt via the command:
+pandoc --lua-filter tools/update-readme.lua README.template -o README.md
+-->
 
-[![github release](https://img.shields.io/github/release/jgm/pandoc.svg?label=current+release)](https://github.com/jgm/pandoc/releases)
-[![hackage release](https://img.shields.io/hackage/v/pandoc.svg?label=hackage)](http://hackage.haskell.org/package/pandoc)
+# Pandoc
+
+[![github
+release](https://img.shields.io/github/release/jgm/pandoc.svg?label=current+release)](https://github.com/jgm/pandoc/releases)
+[![hackage
+release](https://img.shields.io/hackage/v/pandoc.svg?label=hackage)](http://hackage.haskell.org/package/pandoc)
 [![homebrew](https://img.shields.io/homebrew/v/pandoc.svg)](http://brewformulas.org/Pandoc)
-[![stackage LTS package](http://stackage.org/package/pandoc/badge/lts)](http://stackage.org/lts/package/pandoc)
-[![travis build status](https://img.shields.io/travis/jgm/pandoc/master.svg?label=travis+build)](https://travis-ci.org/jgm/pandoc)
-[![appveyor build status](https://ci.appveyor.com/api/projects/status/nvqs4ct090igjiqc?svg=true)](https://ci.appveyor.com/project/jgm/pandoc)
+[![stackage LTS
+package](http://stackage.org/package/pandoc/badge/lts)](http://stackage.org/lts/package/pandoc)
+[![travis build
+status](https://img.shields.io/travis/jgm/pandoc/master.svg?label=travis+build)](https://travis-ci.org/jgm/pandoc)
+[![appveyor build
+status](https://ci.appveyor.com/api/projects/status/nvqs4ct090igjiqc?svg=true)](https://ci.appveyor.com/project/jgm/pandoc)
 [![license](https://img.shields.io/badge/license-GPLv2+-lightgray.svg)](https://www.gnu.org/licenses/gpl.html)
-[![pandoc-discuss on google groups](https://img.shields.io/badge/pandoc-discuss-red.svg?style=social)](https://groups.google.com/forum/#!forum/pandoc-discuss)
-
+[![pandoc-discuss on google
+groups](https://img.shields.io/badge/pandoc-discuss-red.svg?style=social)](https://groups.google.com/forum/#!forum/pandoc-discuss)
 
-The universal markup converter
-------------------------------
+## 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 read
-[Markdown], [CommonMark], [PHP Markdown Extra], [GitHub-Flavored
-Markdown], [MultiMarkdown], and (subsets of) [Textile],
-[reStructuredText], [HTML], [LaTeX], [MediaWiki markup], [TWiki markup],
-[TikiWiki markup], [Creole 1.0], [Haddock markup], [OPML], [Emacs Org mode],
-[DocBook], [JATS], [Muse], [txt2tags], [Vimwiki], [EPUB], [ODT], and
-[Word docx]; and it can write plain text, [Markdown], [CommonMark], [PHP
-Markdown Extra], [GitHub-Flavored Markdown], [MultiMarkdown],
-[reStructuredText], [XHTML], [HTML5], [LaTeX] \(including
-[`beamer`] slide shows\), [ConTeXt], [RTF], [OPML], [DocBook], [JATS],
-[OpenDocument], [ODT], [Word docx], [GNU Texinfo], [MediaWiki
-markup], [DokuWiki markup], [ZimWiki markup], [Haddock markup],
-[EPUB] \(v2 or v3\), [FictionBook2], [Textile], [groff man],
-[groff ms], [Emacs Org mode], [AsciiDoc], [InDesign ICML], [TEI
-Simple], [Muse], [PowerPoint] slide shows and [Slidy], [Slideous],
-[DZSlides], [reveal.js] or [S5] HTML slide shows. It can also produce
-[PDF] output on systems where LaTeX, ConTeXt, `pdfroff`, `wkhtmltopdf`,
-`prince`, or `weasyprint` is installed.
+<div id="description">
 
-Pandoc's enhanced version of Markdown includes syntax for [footnotes],
-[tables], flexible [ordered lists], [definition lists], [fenced code
-blocks], [superscripts and subscripts], [strikeout], [metadata blocks],
-automatic tables of contents, embedded LaTeX [math], [citations], and
-[Markdown inside HTML block elements](#extension-markdown_in_html_blocks).
-(These enhancements, described further under
-[Pandoc's Markdown], can be disabled using the `markdown_strict` input
-or output format.)
+Pandoc is a [Haskell](https://www.haskell.org) library for converting
+from one markup format to another, and a command-line tool that uses
+this library.
 
-In contrast to most existing tools for converting Markdown to HTML, which
-use regex substitutions, 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, 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.
+Pandoc can read
+[Markdown](http://daringfireball.net/projects/markdown/),
+[CommonMark](http://commonmark.org), [PHP Markdown
+Extra](https://michelf.ca/projects/php-markdown/extra/),
+[GitHub-Flavored
+Markdown](https://help.github.com/articles/github-flavored-markdown/),
+[MultiMarkdown](http://fletcherpenney.net/multimarkdown/), and (subsets
+of) [Textile](http://redcloth.org/textile),
+[reStructuredText](http://docutils.sourceforge.net/docs/ref/rst/introduction.html),
+[HTML](http://www.w3.org/html/), [LaTeX](http://latex-project.org),
+[MediaWiki markup](https://www.mediawiki.org/wiki/Help:Formatting),
+[TWiki markup](http://twiki.org/cgi-bin/view/TWiki/TextFormattingRules),
+[TikiWiki
+markup](https://doc.tiki.org/Wiki-Syntax-Text#The_Markup_Language_Wiki-Syntax),
+[Creole 1.0](http://www.wikicreole.org/wiki/Creole1.0), [Haddock
+markup](https://www.haskell.org/haddock/doc/html/ch03s08.html),
+[OPML](http://dev.opml.org/spec2.html), [Emacs Org
+mode](http://orgmode.org), [DocBook](http://docbook.org),
+[JATS](https://jats.nlm.nih.gov),
+[Muse](https://amusewiki.org/library/manual),
+[txt2tags](http://txt2tags.org), [Vimwiki](https://vimwiki.github.io),
+[EPUB](http://idpf.org/epub),
+[ODT](http://en.wikipedia.org/wiki/OpenDocument), and [Word
+docx](https://en.wikipedia.org/wiki/Office_Open_XML).
 
-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.
+Pandoc can write plain text,
+[Markdown](http://daringfireball.net/projects/markdown/),
+[CommonMark](http://commonmark.org), [PHP Markdown
+Extra](https://michelf.ca/projects/php-markdown/extra/),
+[GitHub-Flavored
+Markdown](https://help.github.com/articles/github-flavored-markdown/),
+[MultiMarkdown](http://fletcherpenney.net/multimarkdown/),
+[reStructuredText](http://docutils.sourceforge.net/docs/ref/rst/introduction.html),
+[XHTML](http://www.w3.org/TR/xhtml1/),
+[HTML5](http://www.w3.org/TR/html5/), [LaTeX](http://latex-project.org)
+(including [`beamer`](https://ctan.org/pkg/beamer) slide shows),
+[ConTeXt](http://www.contextgarden.net/),
+[RTF](http://en.wikipedia.org/wiki/Rich_Text_Format),
+[OPML](http://dev.opml.org/spec2.html), [DocBook](http://docbook.org),
+[JATS](https://jats.nlm.nih.gov),
+[OpenDocument](http://opendocument.xml.org),
+[ODT](http://en.wikipedia.org/wiki/OpenDocument), [Word
+docx](https://en.wikipedia.org/wiki/Office_Open_XML), [GNU
+Texinfo](http://www.gnu.org/software/texinfo/), [MediaWiki
+markup](https://www.mediawiki.org/wiki/Help:Formatting), [DokuWiki
+markup](https://www.dokuwiki.org/dokuwiki), [ZimWiki
+markup](http://zim-wiki.org/manual/Help/Wiki_Syntax.html), [Haddock
+markup](https://www.haskell.org/haddock/doc/html/ch03s08.html),
+[EPUB](http://idpf.org/epub) (v2 or v3),
+[FictionBook2](http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1),
+[Textile](http://redcloth.org/textile), [groff
+man](http://man7.org/linux/man-pages/man7/groff_man.7.html), [groff
+ms](http://man7.org/linux/man-pages/man7/groff_ms.7.html), [Emacs Org
+mode](http://orgmode.org),
+[AsciiDoc](http://www.methods.co.nz/asciidoc/), [InDesign
+ICML](https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf),
+[TEI Simple](https://github.com/TEIC/TEI-Simple),
+[Muse](https://amusewiki.org/library/manual),
+[PowerPoint](https://en.wikipedia.org/wiki/Microsoft_PowerPoint) slide
+shows and [Slidy](http://www.w3.org/Talks/Tools/Slidy/),
+[Slideous](http://goessner.net/articles/slideous/),
+[DZSlides](http://paulrouget.com/dzslides/),
+[reveal.js](http://lab.hakim.se/reveal-js/) or
+[S5](http://meyerweb.com/eric/tools/s5/) HTML slide shows. It can also
+produce [PDF](https://www.adobe.com/pdf/) output on systems where LaTeX,
+ConTeXt, `pdfroff`, `wkhtmltopdf`, `prince`, or `weasyprint` is
+installed.
 
-[Markdown]: http://daringfireball.net/projects/markdown/
-[CommonMark]: http://commonmark.org
-[PHP Markdown Extra]: https://michelf.ca/projects/php-markdown/extra/
-[GitHub-Flavored Markdown]: https://help.github.com/articles/github-flavored-markdown/
-[MultiMarkdown]: http://fletcherpenney.net/multimarkdown/
-[reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html
-[S5]: http://meyerweb.com/eric/tools/s5/
-[Slidy]: http://www.w3.org/Talks/Tools/Slidy/
-[Slideous]: http://goessner.net/articles/slideous/
-[HTML]: http://www.w3.org/html/
-[HTML5]: http://www.w3.org/TR/html5/
-[XHTML]: http://www.w3.org/TR/xhtml1/
-[LaTeX]: http://latex-project.org
-[`beamer`]: https://ctan.org/pkg/beamer
-[Beamer User's Guide]: http://ctan.math.utah.edu/ctan/tex-archive/macros/latex/contrib/beamer/doc/beameruserguide.pdf
-[ConTeXt]: http://www.contextgarden.net/
-[RTF]: http://en.wikipedia.org/wiki/Rich_Text_Format
-[Creole 1.0]: http://www.wikicreole.org/wiki/Creole1.0
-[DocBook]: http://docbook.org
-[JATS]: https://jats.nlm.nih.gov
-[txt2tags]: http://txt2tags.org
-[EPUB]: http://idpf.org/epub
-[OPML]: http://dev.opml.org/spec2.html
-[OpenDocument]: http://opendocument.xml.org
-[ODT]: http://en.wikipedia.org/wiki/OpenDocument
-[Textile]: http://redcloth.org/textile
-[MediaWiki markup]: https://www.mediawiki.org/wiki/Help:Formatting
-[DokuWiki markup]: https://www.dokuwiki.org/dokuwiki
-[ZimWiki markup]: http://zim-wiki.org/manual/Help/Wiki_Syntax.html
-[TWiki markup]: http://twiki.org/cgi-bin/view/TWiki/TextFormattingRules
-[Haddock markup]: https://www.haskell.org/haddock/doc/html/ch03s08.html
-[groff man]: http://man7.org/linux/man-pages/man7/groff_man.7.html
-[groff ms]: http://man7.org/linux/man-pages/man7/groff_ms.7.html
-[Haskell]: https://www.haskell.org
-[GNU Texinfo]: http://www.gnu.org/software/texinfo/
-[Emacs Org mode]: http://orgmode.org
-[AsciiDoc]: http://www.methods.co.nz/asciidoc/
-[DZSlides]: http://paulrouget.com/dzslides/
-[Word docx]: https://en.wikipedia.org/wiki/Office_Open_XML
-[PDF]: https://www.adobe.com/pdf/
-[reveal.js]: http://lab.hakim.se/reveal-js/
-[FictionBook2]: http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1
-[InDesign ICML]: https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf
-[TEI Simple]: https://github.com/TEIC/TEI-Simple
-[Muse]: https://amusewiki.org/library/manual
-[PowerPoint]: https://en.wikipedia.org/wiki/Microsoft_PowerPoint
-[Vimwiki]: https://vimwiki.github.io
+Pandoc’s enhanced version of Markdown includes syntax for tables,
+definition lists, metadata blocks, `Div` blocks, footnotes and
+citations, embedded LaTeX (including math), Markdown inside HTML block
+elements, and much more. These enhancements, described further under
+Pandoc’s Markdown, can be disabled using the `markdown_strict` format.
 
+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 (like 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](http://pandoc.org/filters.html) to modify the intermediate AST.
 
+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.
 
-[footnotes]: http://pandoc.org/MANUAL.html#footnotes
-[tables]: http://pandoc.org/MANUAL.html#tables
-[ordered lists]: http://pandoc.org/MANUAL.html#ordered-lists
-[definition lists]: http://pandoc.org/MANUAL.html#definition-lists
-[fenced code blocks]: http://pandoc.org/MANUAL.html#fenced-code-blocks
-[superscripts and subscripts]: http://pandoc.org/MANUAL.html#superscripts-and-subscripts
-[strikeout]: http://pandoc.org/MANUAL.html#strikeout
-[metadata blocks]: http://pandoc.org/MANUAL.html#metadata-blocks
-[math]: http://pandoc.org/MANUAL.html#math
-[citations]: http://pandoc.org/MANUAL.html#citations
-[Markdown inside HTML block elements]: http://pandoc.org/MANUAL.html#extension-markdown_in_html_blocks
-[Pandoc's Markdown]: http://pandoc.org/MANUAL.html#pandocs-markdown
+</div>
 
-Installing
-----------
+## Installing
 
-Here's [how to install pandoc](INSTALL.md).
+Here’s [how to install pandoc](INSTALL.md).
 
-Documentation
--------------
+## Documentation
 
-Pandoc's website contains a full [User's Guide](https://pandoc.org/MANUAL.html).
-It is also available [here](MANUAL.txt) as pandoc-flavored Markdown.
-The website also contains some [examples of the use of
+Pandoc’s website contains a full [User’s
+Guide](https://pandoc.org/MANUAL.html). It is also available
+[here](MANUAL.txt) as pandoc-flavored Markdown. The website also
+contains some [examples of the use of
 pandoc](https://pandoc.org/demos.html) and a limited [online
 demo](https://pandoc.org/try).
 
-Contributing
-------------
-
-Pull requests, bug reports, and feature requests are welcome.  Please make
-sure to read [the contributor guidelines](CONTRIBUTING.md) before opening a
-new issue.
-
+## Contributing
 
-License
--------
+Pull requests, bug reports, and feature requests are welcome. Please
+make sure to read [the contributor guidelines](CONTRIBUTING.md) before
+opening a new issue.
 
-© 2006-2017 John MacFarlane (jgm@berkeley.edu). Released under the
-[GPL], version 2 or greater.  This software carries no warranty of
-any kind.  (See COPYRIGHT for full copyright and warranty notices.)
+## License
 
-[GPL]: http://www.gnu.org/copyleft/gpl.html "GNU General Public License"
+© 2006-2018 John MacFarlane (jgm@berkeley.edu). Released under the
+[GPL](http://www.gnu.org/copyleft/gpl.html "GNU General Public License"),
+version 2 or greater. This software carries no warranty of any kind.
+(See COPYRIGHT for full copyright and warranty notices.)
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/benchmark/benchmark-pandoc.hs b/benchmark/benchmark-pandoc.hs
--- a/benchmark/benchmark-pandoc.hs
+++ b/benchmark/benchmark-pandoc.hs
@@ -1,5 +1,6 @@
+{-# LANGUAGE TupleSections #-}
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,72 +18,69 @@
 -}
 import Text.Pandoc
 import qualified Text.Pandoc.UTF8 as UTF8
-import Data.Text (Text)
-import Data.Time (getCurrentTime)
 import qualified Data.ByteString as B
-import qualified Data.Map as Map
 import Criterion.Main
 import Criterion.Types (Config(..))
+import Data.List (intersect)
 import Data.Maybe (mapMaybe)
-import Debug.Trace (trace)
 import System.Environment (getArgs)
 
 readerBench :: Pandoc
-            -> (String, ReaderOptions -> Text -> Pandoc)
+            -> String
             -> Maybe Benchmark
-readerBench doc (name, reader) =
-  case lookup name writers of
-       Just (TextWriter writer) ->
-         let inp = either (error . show) id $ runPure
-                       $ writer def{ writerWrapText = WrapAuto} doc
-         in return $ bench (name ++ " reader") $ nf
-                 (reader def) inp
-       _ -> Debug.Trace.trace
-             ("\nCould not find writer for " ++ name ++ "\n") Nothing
+readerBench doc name =
+  case res of
+       Right (readerFun, inp) ->
+          Just $ bench (name ++ " reader")
+               $ nf (\i -> either (error . show) id $ runPure (readerFun i))
+                 inp
+       Left _ -> Nothing
+  where res = runPure $ do
+          (TextReader r, rexts)
+                     <- either (fail . show) return $ getReader name
+          (TextWriter w, wexts)
+                     <- either (fail . show) return $ getWriter name
+          inp <- w def{ writerWrapText = WrapAuto, writerExtensions = wexts }
+                  doc
+          return (r def{ readerExtensions = rexts }, inp)
 
 writerBench :: Pandoc
-            -> (String, WriterOptions -> Pandoc -> Text)
-            -> Benchmark
-writerBench doc (name, writer) = bench (name ++ " writer") $ nf
-    (writer def{ writerWrapText = WrapAuto }) doc
+            -> String
+            -> Maybe Benchmark
+writerBench doc name =
+  case res of
+       Right writerFun ->
+          Just $ bench (name ++ " writer")
+               $ nf (\d -> either (error . show) id $
+                            runPure (writerFun d)) doc
+       _ -> Nothing
+  where res = runPure $ do
+          (TextWriter w, wexts)
+                      <- either (fail . show) return $ getWriter name
+          return $ w def{ writerExtensions = wexts }
 
 main :: IO ()
 main = do
-  args <- getArgs
+  args <- filter (\x -> take 1 x /= "-") <$> getArgs
+  print args
   let matchReader (n, TextReader _) =
-        case args of
-             [] -> True
-             [x] -> x == n
-             (x:y:_) -> x == n && y == "reader"
-      matchReader (_, _) = False
+         null args || ("reader" `elem` args && n `elem` args)
+      matchReader _                 = False
   let matchWriter (n, TextWriter _) =
-        case args of
-             [] -> True
-             [x] -> x == n
-             (x:y:_) -> x == n && y == "writer"
-      matchWriter (_, _) = False
-  let matchedReaders = filter matchReader readers
-  let matchedWriters = filter matchWriter writers
+         null args || ("writer" `elem` args && n `elem` args)
+      matchWriter _                 = False
+  let matchedReaders = map fst $ (filter matchReader readers
+                                    :: [(String, Reader PandocPure)])
+  let matchedWriters = map fst $ (filter matchWriter writers
+                                    :: [(String, Writer PandocPure)])
   inp <- UTF8.toText <$> B.readFile "test/testsuite.txt"
-  lalune <- B.readFile "test/lalune.jpg"
-  movie <- B.readFile "test/movie.jpg"
-  time <- Data.Time.getCurrentTime
-  let setupFakeFiles = modifyPureState $ \st -> st{ stFiles =
-                        FileTree $ Map.fromList [
-                           ("lalune.jpg", FileInfo time lalune),
-                           ("movie.jpg", FileInfo time movie)
-                           ]}
   let opts = def
   let doc = either (error . show) id $ runPure $ readMarkdown opts inp
-  let readers' = [(n, \o d ->
-             either (error . show) id $ runPure $ r o d)
-                        | (n, TextReader r) <- matchedReaders]
   let readerBs = mapMaybe (readerBench doc)
-                 $ filter (\(n,_) -> n /="haddock") readers'
-  let writers' = [(n, \o d ->
-                   either (error . show) id $ runPure $ setupFakeFiles >> w o d)
-                        | (n, TextWriter w) <- matchedWriters]
-  let writerBs = map (writerBench doc)
-                 $ writers'
+                 $ filter (/="haddock")
+                 (matchedReaders `intersect` matchedWriters)
+                 -- we need the corresponding writer to generate
+                 -- input for the reader
+  let writerBs = mapMaybe (writerBench doc) matchedWriters
   defaultMainWith defaultConfig{ timeLimit = 6.0 }
     (writerBs ++ readerBs)
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,165 @@
+pandoc (2.1)
+
+  * Allow filters and lua filters to be interspersed (#4196).  Previously
+    we ran all lua filters before JSON filters.  Now we run filters in
+    the order they are presented on the command line, whether lua or JSON.
+    There are two incompatible API changes: The type of `applyFilters`
+    has changed, and `applyLuaFilters` has been removed.  `Filter` is
+    also now exported.
+
+  * Use latest skylighting and omit the `missingIncludes` check, fixing
+    a major performance regression in earlier releases of the 2.x series
+    (#4226).  Behavior change: If you use a custom syntax definition that
+    refers to a syntax you haven't loaded, pandoc will now complain when
+    it is highlighting the text, rather than doing a check at the start.
+    This change dramatically speeds up invocations of pandoc on short
+    inputs.
+
+  * Text.Pandoc.Class: make `FileTree` opaque (don't export
+    `FileTree` constructor).  This forces users to interact with it using
+    `insertInFileTree` and `getFileInfo`, which normalize file names.
+
+  * Markdown reader:
+
+    + Rewrite `inlinesInBalancedBrackets`.  The rewrite is much more
+      direct, avoiding `parseFromString`.  And it performs significantly
+      better; unfortunately, parsing time still increases exponentially
+      (see #1735).
+    + Avoid parsing raw tex unless `\` + letter seen.  This seems to
+      help with the performance problem, #4216.
+
+  * LaTeX reader: Simplified a check for raw tex command.
+
+  * Muse reader (Alexander Krotov):
+
+    + Enable round trip test (#4107).
+    + Automatically translate `#cover` into `#cover-image`.
+      Amusewiki uses #cover directive to specify cover image.
+
+  * Docx reader (Jesse Rosenthal):
+
+    + Allow for insertion/deletion of paragraphs (#3927).
+      If the paragraph has a deleted or inserted paragraph break (depending
+      on the track-changes setting) we hold onto it until the next
+      paragraph. This takes care of accept and reject. For this we introduce
+      a new state which holds the ils from the previous para if necessary.
+      For `--track-changes=all`, we add an empty span with class
+      `paragraph-insertion`/`paragraph-deletion` at the end of the paragraph
+      prior to the break to be inserted or deleted.
+    + Remove unused anchors (#3679).  Docx produces a lot of anchors with
+      nothing pointing to them---we now remove these to produce cleaner
+      output. Note that this has to occur at the end of the process
+      because it has to follow link/anchor rewriting.
+    + Read multiple children of `w:sdtContents`.
+    + Combine adjacent anchors.  There isn't any reason to have numerous
+      anchors in the same place, since we can't maintain docx's
+      non-nesting overlapping. So we reduce to a single anchor.
+    + Improved tests.
+
+  * Muse writer (Alexander Krotov): don't escape URIs from AST
+
+  * Docx writer:
+
+    + Removed redundant subtitle in title (Sebastian Talmon).
+    + `firstRow` table definition compatibility for Word 2016 (Sebastian
+      Talmon).  Word 2016 seems to use a default value of "1" for table
+      headers, if there is no firstRow definition (although a default
+      value of 0 is documented), so all tables get the first Row formatted
+      as header.  Setting the parameter to 0 if the table has no header
+      row fixes this for Word 2016
+    + Fix custom styles with spaces in the name (#3290).
+
+  * Powerpoint writer (Jesse Rosenthal):
+
+    + Ignore Notes div for parity with other slide outputs.
+    + Set default slidelevel correctly.  We had previously defaulted to
+      slideLevel 2. Now we use the correct behavior of defaulting to the
+      highest level header followed by content. We change an expected test
+      result to match this behavior.
+    + Split blocks correctly for linked images.
+    + Combine adjacent runs.
+    + Make inline code inherit code size.  Previously (a) the code size
+      wasn't set when we force size, and (b) the properties was set from
+      the default, instead of inheriting.
+    + Simplify `replaceNamedChildren` function.
+    + Allow linked images.  The following markdown:
+      `[![Image Title](image.jpg)](http://www.example.com)`
+      will now produce a linked image in the resulting PowerPoint file.
+    + Fix error with empty table cell.  We require an empty `<a:p>` tag,
+      even if the cell contains no paragraphs---otherwise PowerPoint
+      complains of corruption.
+    + Implement two-column slides.  This uses the columns/column div
+      format described in the pandoc manual. At the moment, only two
+      columns (half the screen each) are allowed. Custom widths are not
+      supported.
+    + Added more tests.
+
+  * Lua filters (Albert Krewinkel):
+
+    + `data/pandoc.lua`: drop 'pandoc-api-version' from Pandoc objects
+    + The current pandoc-types version is made available to Lua programs in
+      the global `PANDOC_API_VERSION`. It contains the version as a list of
+      numbers.
+    + The pandoc version available as a global `PANDOC_VERSION` (a list
+      of numbers).
+    + `data/pandoc.lua`: make `Attr` an `AstElement`.
+    + `data/pandoc.lua`: make all types subtypes of `AstElement`.
+      `Pandoc`, `Meta`, and `Citation` were just plain functions and did
+      not set a metatable on the returned value, which made it difficult
+      to amend objects of these types with new behavior. They are now
+      subtypes of AstElement, meaning that all their objects can gain
+      new features when a method is added to the behavior object
+      (e.g., `pandoc.Pandoc.behavior`).
+    + `data/pandoc.lua`: split type and behavior tables.  Clearly distinguish
+      between a type and the behavioral properties of an instance of that
+      type. The behavior of a type (and all its subtypes) can now be
+      amended by adding methods to that types `behavior` object, without
+      exposing the type objects internals.  E.g.:
+      ```lua
+      pandoc.Inline.behavior.frob = function () print'42' end
+      local str = pandoc.Str'hello'
+      str.frob() -- outputs '42'
+      ```
+    + `data/pandoc.lua`: fix Element inheritance.  Extending all elements
+      of a given type (e.g., all inline elements) was difficult, as the
+      table used to lookup unknown methods would be reset every time a
+      new element of that type was created, preventing recursive property
+      lookup. This is was changed in that all methods and attributes of
+      supertypes are now available to their subtypes.
+    + `data/pandoc.lua`: fix attribute names of Citation (#4222).  The
+      fields were named like the Haskell fields, not like the documented,
+      shorter version.  The names are changed to match the documentation
+      and Citations are given a shared metatable to enable simple
+      extensibility.
+    + `data/pandoc.lua`: drop function `pandoc.global_filter`.
+    + Bump `hslua` version to 0.9.5.  This version fixes a bug that made it
+      difficult to handle failures while getting lists or a Map from Lua.
+      A bug in pandoc, which made it necessary to always pass a tag when
+      using MetaList or MetaBlock, is fixed as a result. Using the pandoc
+      module's constructor functions for these values is now optional
+      (if still recommended).
+    + Stop exporting `pushPandocModule` (API change).  The introduction
+      of `runPandocLua` renders direct use of this function obsolete.
+    + Update generation of module docs for lua filters.
+    + `Lua.Module.Utils`: make stringify work on `MetaValues` (John
+      MacFarlane).  I'm sure this was intended in the first place,
+      but currently only `Meta` is supported.
+
+  * Improve benchmarks.
+
+    + Set the default extensions properly.
+    + Improve benchmark argument parsing.  You can now say
+      `make bench BENCHARGS="markdown latex reader"` and both the
+      markdown and latex readers will be benchmarked.
+
+  * MANUAL.txt simplify and add more structure (Mauro Bieg).
+
+  * Generate README.md from template and MANUAL.txt.
+    `make README.md` will generate the README.md after changes
+    to MANUAL.txt have been made.
+
+  * Update copyright notices to include 2018 (Albert Krewinkel).
+
 pandoc (2.0.6)
 
   * Added `jats` as an input format.
diff --git a/data/pandoc.List.lua b/data/pandoc.List.lua
--- a/data/pandoc.List.lua
+++ b/data/pandoc.List.lua
@@ -1,7 +1,7 @@
 --[[
 List.lua
 
-Copyright © 2017 Albert Krewinkel
+Copyright © 2017–2018 Albert Krewinkel
 
 Permission to use, copy, modify, and/or distribute this software for any purpose
 with or without fee is hereby granted, provided that the above copyright notice
@@ -19,7 +19,7 @@
 --- Pandoc's List type and helper methods
 -- @classmod pandoc.List
 -- @author Albert Krewinkel
--- @copyright © 2017 Albert Krewinkel
+-- @copyright © 2017–2018 Albert Krewinkel
 -- @license MIT
 local List = {
   _VERSION = "0.1.0"
diff --git a/data/pandoc.lua b/data/pandoc.lua
--- a/data/pandoc.lua
+++ b/data/pandoc.lua
@@ -1,7 +1,7 @@
 --[[
 pandoc.lua
 
-Copyright © 2017 Albert Krewinkel
+Copyright © 2017–2018 Albert Krewinkel
 
 Permission to use, copy, modify, and/or distribute this software for any purpose
 with or without fee is hereby granted, provided that the above copyright notice
@@ -20,45 +20,71 @@
 -- Lua functions for pandoc scripts.
 --
 -- @author Albert Krewinkel
--- @copyright © 2017 Albert Krewinkel
+-- @copyright © 2017–2018 Albert Krewinkel
 -- @license MIT
 local M = {
-  _VERSION = "0.3.0"
+  _VERSION = "0.4.0"
 }
 
 local List = require 'pandoc.List'
 
 ------------------------------------------------------------------------
--- The base class for pandoc's AST elements.
--- @type Element
+-- The base class for types
+-- @type Type
 -- @local
-local Element = {}
+local Type = {}
+Type.name = 'Type'
+Type.__index = Type
+Type.behavior = {
+  __type = Type,
+  new = function (obj)
+    obj = obj or {}
+    setmetatable(obj, self)
+    return obj
+  end
+}
+Type.behavior.__index = Type.behavior
 
---- Create a new element subtype
+--- Set a new behavior for the type, inheriting that of the parent type if none
+--- is specified explicitely
+-- @param behavior the behavior object for this type.
 -- @local
-function Element:make_subtype(o)
-  o = o or {}
-  setmetatable(o, self)
-  self.__index = self
-  return o
+function Type:set_behavior (behavior)
+  behavior = behavior or {}
+  behavior.__index = rawget(behavior, '__index') or behavior
+  behavior.__type = self
+  if not getmetatable(behavior) and getmetatable(self) then
+    setmetatable(behavior, getmetatable(self).behavior)
+  end
+  self.behavior = behavior
 end
 
---- Create a new element given its tag and arguments
+--- Create a new subtype, using the given table as base.
+-- @param name name of the new type
+-- @param[opt] behavior behavioral object for the new type.
+-- @return a new type
 -- @local
-function Element:new(tag, ...)
-  local element = { t = tag }
-  local content = {...}
-  -- special case for unary constructors
-  if #content == 1 then
-    element.c = content[1]
-  -- Don't set 'c' field if no further arguments were given. This is important
-  -- for nullary constructors like `Space` and `HorizontalRule`.
-  elseif #content > 0 then
-    element.c = content
+function Type:make_subtype(name, behavior)
+  local newtype = setmetatable({}, self)
+  newtype.name = name
+  newtype.__index = newtype
+  newtype:set_behavior(behavior)
+  return newtype
+end
+
+
+------------------------------------------------------------------------
+-- The base class for pandoc's AST elements.
+-- @type AstElement
+-- @local
+local AstElement = Type:make_subtype 'AstElement'
+AstElement.__call = function(t, ...)
+  local success, ret = pcall(t.constructor, ...)
+  if success then
+    return setmetatable(ret, t.behavior)
+  else
+    error(string.format('Constructor for %s failed: %s\n', t.name, ret))
   end
-  setmetatable(element, self)
-  self.__index = self
-  return element
 end
 
 --- Create a new constructor
@@ -67,32 +93,49 @@
 -- @param fn Function to be called when constructing a new element
 -- @param accessors names to use as accessors for numerical fields
 -- @return function that constructs a new element
-function Element:create_constructor(tag, fn, accessors)
-  local constr = self:make_subtype({tag = tag, getters = {}, setters = {}})
+function AstElement:create_constructor(tag, fn, accessors)
+  local constr = self:make_subtype(tag, {tag = tag, getters = {}, setters = {}})
+  behavior = constr.behavior
+  behavior.__index = function(t, k)
+    if getmetatable(t).getters[k] then
+      return getmetatable(t).getters[k](t)
+    elseif k == "t" then
+      return getmetatable(t)["tag"]
+    else
+      return getmetatable(t)[k]
+    end
+  end
+  behavior.__newindex = function(t, k, v)
+    if getmetatable(t).setters[k] then
+      getmetatable(t).setters[k](t, v)
+    else
+      rawset(t, k, v)
+    end
+  end
 
   -- Add accessors to the metatable
   if type(accessors) == "string" then
-    constr.getters[accessors] = function(elem)
+    behavior.getters[accessors] = function(elem)
       return elem.c
     end
-    constr.setters[accessors] = function(elem, v)
+    behavior.setters[accessors] = function(elem, v)
       elem.c = v
     end
   else
     for i = 1, #(accessors or {}) do
       if type(accessors[i]) == "string" then
-        constr.getters[accessors[i]] = function(elem)
+        behavior.getters[accessors[i]] = function(elem)
           return elem.c[i]
         end
-        constr.setters[accessors[i]] = function(elem, v)
+        behavior.setters[accessors[i]] = function(elem, v)
           elem.c[i] = v
         end
       else -- only two levels of nesting are supported
         for k, v in ipairs(accessors[i]) do
-          constr.getters[v] = function(elem)
+          behavior.getters[v] = function(elem)
             return elem.c[i][k]
           end
-          constr.setters[v] = function(elem, v)
+          behavior.setters[v] = function(elem, v)
             elem.c[i][k] = v
           end
         end
@@ -101,35 +144,29 @@
   end
 
   function constr:new(...)
-    local obj = fn(...)
-    setmetatable(obj, self)
-    self.__index = function(t, k)
-      if getmetatable(t).getters[k] then
-        return getmetatable(t).getters[k](t)
-      elseif k == "t" then
-        return getmetatable(t)["tag"]
-      else
-        return getmetatable(t)[k]
-      end
-    end
-    self.__newindex = function(t, k, v)
-      if getmetatable(t).setters[k] then
-        getmetatable(t).setters[k](t, v)
-      else
-        rawset(t, k, v)
-      end
-    end
-    return obj
+    return setmetatable(fn(...), self.behavior)
   end
   self.constructor = self.constructor or {}
   self.constructor[tag] = constr
   return constr
 end
 
---- Calls the constructor, creating a new element.
+--- Create a new element given its tag and arguments
 -- @local
-function Element.__call(t, ...)
-  return t:new(...)
+function AstElement.new(constr, ...)
+  local element = {}
+  local content = {...}
+  -- special case for unary constructors
+  if #content == 1 then
+    element.c = content[1]
+    -- Don't set 'c' field if no further arguments were given. This is important
+    -- for nullary constructors like `Space` and `HorizontalRule`.
+  elseif #content > 0 then
+    element.c = content
+  end
+  setmetatable(element, constr)
+  element.__index = element
+  return element
 end
 
 ------------------------------------------------------------------------
@@ -140,12 +177,11 @@
 -- @function Pandoc
 -- @tparam      {Block,...} blocks      document content
 -- @tparam[opt] Meta        meta        document meta data
-function M.Pandoc(blocks, meta)
-  meta = meta or {}
+M.Pandoc = AstElement:make_subtype'Pandoc'
+function M.Pandoc.constructor (blocks, meta)
   return {
-    ["blocks"] = List:new(blocks),
-    ["meta"] = meta,
-    ["pandoc-api-version"] = {1,17,0,5},
+    blocks = List:new(blocks),
+    meta = meta or {},
   }
 end
 
@@ -160,20 +196,18 @@
 --- `Meta`.
 -- @function Meta
 -- @tparam meta table table containing document meta information
-M.Meta = {}
-M.Meta.__call = function(t, meta)
-  return setmetatable(meta, t)
-end
-setmetatable(M.Meta, M.Meta)
+M.Meta = AstElement:make_subtype'Meta'
+M.Meta.constructor = function (meta) return meta end
 
 
 ------------------------------------------------------------------------
 -- MetaValue
 -- @section MetaValue
-M.MetaValue = Element:make_subtype{}
-M.MetaValue.__call = function(t, ...)
+M.MetaValue = AstElement:make_subtype('MetaValue')
+M.MetaValue.__call = function (t, ...)
   return t:new(...)
 end
+
 --- Meta blocks
 -- @function MetaBlocks
 -- @tparam {Block,...} blocks blocks
@@ -228,7 +262,7 @@
 -- @section Block
 
 --- Block elements
-M.Block = Element:make_subtype{}
+M.Block = AstElement:make_subtype'Block'
 M.Block.__call = function (t, ...)
   return t:new(...)
 end
@@ -246,7 +280,7 @@
 --- Creates a bullet (i.e. unordered) list.
 -- @function BulletList
 -- @tparam      {{Block,...},...} content     list of items
--- @treturn     Block block quote element
+-- @treturn     Block                         bullet list element
 M.BulletList = M.Block:create_constructor(
   "BulletList",
   function(content) return {c = content} end,
@@ -267,7 +301,7 @@
 --- Creates a definition list, containing terms and their explanation.
 -- @function DefinitionList
 -- @tparam      {{{Inline,...},{Block,...}},...} content     list of items
--- @treturn     Block block quote element
+-- @treturn     Block                  definition list element
 M.DefinitionList = M.Block:create_constructor(
   "DefinitionList",
   function(content) return {c = List:new(content)} end,
@@ -278,7 +312,7 @@
 -- @function Div
 -- @tparam      {Block,...} content     block content
 -- @tparam[opt] Attr        attr  element attributes
--- @treturn     Block                   code block element
+-- @treturn     Block                   div element
 M.Div = M.Block:create_constructor(
   "Div",
   function(content, attr)
@@ -287,7 +321,7 @@
   {{"identifier", "classes", "attributes"}, "content"}
 )
 
---- Creates a block quote element.
+--- Creates a header element.
 -- @function Header
 -- @tparam      int          level       header level
 -- @tparam      {Inline,...} content     inline content
@@ -312,7 +346,7 @@
 --- Creates a line block element.
 -- @function LineBlock
 -- @tparam      {{Inline,...},...} content    inline content
--- @treturn     Block                   block quote element
+-- @treturn     Block                   line block element
 M.LineBlock = M.Block:create_constructor(
   "LineBlock",
   function(content) return {c = List:new(content)} end,
@@ -331,7 +365,7 @@
 -- @function OrderedList
 -- @tparam      {{Block,...},...} items list items
 -- @param[opt]  listAttributes list parameters
--- @treturn     Block
+-- @treturn     Block  ordered list element
 M.OrderedList = M.Block:create_constructor(
   "OrderedList",
   function(items, listAttributes)
@@ -344,7 +378,7 @@
 --- Creates a para element.
 -- @function Para
 -- @tparam      {Inline,...} content    inline content
--- @treturn     Block                   block quote element
+-- @treturn     Block                   paragraph element
 M.Para = M.Block:create_constructor(
   "Para",
   function(content) return {c = List:new(content)} end,
@@ -354,7 +388,7 @@
 --- Creates a plain element.
 -- @function Plain
 -- @tparam      {Inline,...} content    inline content
--- @treturn     Block                   block quote element
+-- @treturn     Block                   plain element
 M.Plain = M.Block:create_constructor(
   "Plain",
   function(content) return {c = List:new(content)} end,
@@ -365,7 +399,7 @@
 -- @function RawBlock
 -- @tparam      string      format      format of content
 -- @tparam      string      text        string content
--- @treturn     Block                   block quote element
+-- @treturn     Block                   raw block element
 M.RawBlock = M.Block:create_constructor(
   "RawBlock",
   function(format, text) return {c = {format, text}} end,
@@ -379,7 +413,7 @@
 -- @tparam      {int,...}    widths     column widths
 -- @tparam      {Block,...}  headers    header row
 -- @tparam      {{Block,...}} rows      table rows
--- @treturn     Block                   block quote element
+-- @treturn     Block                   table element
 M.Table = M.Block:create_constructor(
   "Table",
   function(caption, aligns, widths, headers, rows)
@@ -402,7 +436,7 @@
 -- @section Inline
 
 --- Inline element class
-M.Inline = Element:make_subtype{}
+M.Inline = AstElement:make_subtype'Inline'
 M.Inline.__call = function (t, ...)
   return t:new(...)
 end
@@ -656,15 +690,20 @@
 
 
 ------------------------------------------------------------------------
--- Helpers
--- @section helpers
+-- Element components
+-- @section components
 
+--- Check if the first element of a pair matches the given value.
+-- @param x  key value to be checked
+-- @return function returning true iff first element of its argument matches x
+-- @local
 local function assoc_key_equals (x)
   return function (y) return y[1] == x end
 end
 
--- Lookup a value in an associative list
+--- Lookup a value in an associative list
 -- @function lookup
+-- @local
 -- @tparam {{key, value},...} alist associative list
 -- @param key key for which the associated value is to be looked up
 local function lookup(alist, key)
@@ -673,6 +712,7 @@
 
 --- Return an iterator which returns key-value pairs of an associative list.
 -- @function apairs
+-- @local
 -- @tparam {{key, value},...} alist associative list
 local apairs = function (alist)
   local i = 1
@@ -688,8 +728,9 @@
   return nxt, nil, nil
 end
 
--- AttributeList, a metatable to allow table-like access to attribute lists
+--- AttributeList, a metatable to allow table-like access to attribute lists
 -- represented by associative lists.
+-- @local
 local AttributeList = {
   __index = function (t, k)
     if type(k) == "number" then
@@ -715,10 +756,11 @@
   __pairs = apairs
 }
 
--- convert a table to an associative list. The order of key-value pairs in the
+--- Convert a table to an associative list. The order of key-value pairs in the
 -- alist is undefined. The table should either contain no numeric keys or
 -- already be an associative list.
--- @tparam table associative list or table without numeric keys.
+-- @local
+-- @tparam table tbl associative list or table without numeric keys.
 -- @treturn table associative list
 local to_alist = function (tbl)
   if #tbl ~= 0 or next(tbl) == nil then
@@ -735,36 +777,36 @@
 end
 
 -- Attr
-M.Attr = {}
-M.Attr._field_names = {identifier = 1, classes = 2, attributes = 3}
+
 --- Create a new set of attributes (Attr).
 -- @function Attr
 -- @tparam[opt] string       identifier element identifier
 -- @tparam[opt] {string,...} classes    element classes
 -- @tparam[opt] table        attributes table containing string keys and values
 -- @return element attributes
-M.Attr.__call = function(t, identifier, classes, attributes)
+M.Attr = AstElement:make_subtype'Attr'
+M.Attr.constructor = function(identifier, classes, attributes)
   identifier = identifier or ''
   classes = List:new(classes or {})
   attributes = setmetatable(to_alist(attributes or {}), AttributeList)
-  local attr = {identifier, classes, attributes}
-  setmetatable(attr, t)
-  return attr
+  return {identifier, classes, attributes}
 end
-M.Attr.__index = function(t, k)
+M.Attr.behavior._field_names = {identifier = 1, classes = 2, attributes = 3}
+M.Attr.behavior.__index = function(t, k)
   return rawget(t, k) or
     rawget(t, M.Attr._field_names[k]) or
     rawget(getmetatable(t), k)
 end
-M.Attr.__newindex = function(t, k, v)
+M.Attr.behavior.__newindex = function(t, k, v)
   if M.Attr._field_names[k] then
     rawset(t, M.Attr._field_names[k], v)
   else
     rawset(t, k, v)
   end
 end
-setmetatable(M.Attr, M.Attr)
 
+-- Citation
+M.Citation = AstElement:make_subtype'Citation'
 
 --- Creates a single citation.
 -- @function Citation
@@ -774,18 +816,14 @@
 -- @tparam[opt] {Inline,...} suffix   citation suffix
 -- @tparam[opt] int          note_num note number
 -- @tparam[opt] int          hash  hash number
-M.Citation = function(id, mode, prefix, suffix, note_num, hash)
-  prefix = prefix or {}
-  suffix = suffix or {}
-  note_num = note_num or 0
-  hash = hash or 0
+function M.Citation.constructor (id, mode, prefix, suffix, note_num, hash)
   return {
-    citationId = id,
-    citationPrefix = prefix,
-    citationSuffix = suffix,
-    citationMode = mode,
-    citationNoteNum = note_num,
-    citationHash = hash,
+    id = id,
+    mode = mode,
+    prefix = prefix or {},
+    suffix = suffix or {},
+    note_num = note_num or 0,
+    hash = hash or 0,
   }
 end
 
@@ -868,40 +906,6 @@
 --- List are numbered using upper-case alphabetic characters.
 -- @see OrderedList
 M.UpperAlpha = "UpperAlpha"
-
-
-------------------------------------------------------------------------
--- Helper Functions
--- @section helpers
-
---- Use functions defined in the global namespace to create a pandoc filter.
--- All globally defined functions which have names of pandoc elements are
--- collected into a new table.
--- @return A list of filter functions
--- @usage
--- -- within a file defining a pandoc filter:
--- function Str(text)
---   return pandoc.Str(utf8.upper(text))
--- end
---
--- return {pandoc.global_filter()}
--- -- the above is equivallent to
--- -- return {{Str = Str}}
-function M.global_filter()
-  local res = {}
-  function is_filter_function(k)
-    return M.Inline.constructor[k] or
-      M.Block.constructor[k] or
-      k == "Meta" or k == "Doc" or k == "Pandoc" or
-      k == "Block" or k == "Inline"
-  end
-  for k, v in pairs(_G) do
-    if is_filter_function(k) then
-      res[k] = v
-    end
-  end
-  return res
-end
 
 ------------------------------------------------------------------------
 -- Functions which have moved to different modules
diff --git a/man/pandoc.1 b/man/pandoc.1
--- a/man/pandoc.1
+++ b/man/pandoc.1
@@ -1,5 +1,5 @@
 .\"t
-.TH PANDOC 1 "December 27, 2017" "pandoc 2.0.6"
+.TH PANDOC 1 "January 7, 2018" "pandoc 2.1"
 .SH NAME
 pandoc - general markup converter
 .SH SYNOPSIS
@@ -9,38 +9,39 @@
 .PP
 Pandoc is a Haskell library for converting from one markup format to
 another, and a command\-line tool that uses this library.
-It can read Markdown, CommonMark, PHP Markdown Extra, GitHub\-Flavored
-Markdown, MultiMarkdown, and (subsets of) Textile, reStructuredText,
-HTML, LaTeX, MediaWiki markup, TWiki markup, TikiWiki markup, Creole
-1.0, Haddock markup, OPML, Emacs Org mode, DocBook, JATS, Muse,
-txt2tags, Vimwiki, EPUB, ODT, and Word docx; and it can write plain
-text, Markdown, CommonMark, PHP Markdown Extra, GitHub\-Flavored
-Markdown, MultiMarkdown, reStructuredText, XHTML, HTML5, LaTeX
-(including \f[C]beamer\f[] slide shows), ConTeXt, RTF, OPML, DocBook,
-JATS, OpenDocument, ODT, Word docx, GNU Texinfo, MediaWiki markup,
-DokuWiki markup, ZimWiki markup, Haddock markup, EPUB (v2 or v3),
-FictionBook2, Textile, groff man, groff ms, Emacs Org mode, AsciiDoc,
-InDesign ICML, TEI Simple, Muse, PowerPoint slide shows and Slidy,
-Slideous, DZSlides, reveal.js or S5 HTML slide shows.
+.PP
+Pandoc can read Markdown, CommonMark, PHP Markdown Extra,
+GitHub\-Flavored Markdown, MultiMarkdown, and (subsets of) Textile,
+reStructuredText, HTML, LaTeX, MediaWiki markup, TWiki markup, TikiWiki
+markup, Creole 1.0, Haddock markup, OPML, Emacs Org mode, DocBook, JATS,
+Muse, txt2tags, Vimwiki, EPUB, ODT, and Word docx.
+.PP
+Pandoc can write plain text, Markdown, CommonMark, PHP Markdown Extra,
+GitHub\-Flavored Markdown, MultiMarkdown, reStructuredText, XHTML,
+HTML5, LaTeX (including \f[C]beamer\f[] slide shows), ConTeXt, RTF,
+OPML, DocBook, JATS, OpenDocument, ODT, Word docx, GNU Texinfo,
+MediaWiki markup, DokuWiki markup, ZimWiki markup, Haddock markup, EPUB
+(v2 or v3), FictionBook2, Textile, groff man, groff ms, Emacs Org mode,
+AsciiDoc, InDesign ICML, TEI Simple, Muse, PowerPoint slide shows and
+Slidy, Slideous, DZSlides, reveal.js or S5 HTML slide shows.
 It can also produce PDF output on systems where LaTeX, ConTeXt,
 \f[C]pdfroff\f[], \f[C]wkhtmltopdf\f[], \f[C]prince\f[], or
 \f[C]weasyprint\f[] is installed.
 .PP
-Pandoc\[aq]s enhanced version of Markdown includes syntax for footnotes,
-tables, flexible ordered lists, definition lists, fenced code blocks,
-superscripts and subscripts, strikeout, metadata blocks, automatic
-tables of contents, embedded LaTeX math, citations, and Markdown inside
-HTML block elements.
-(These enhancements, described further under Pandoc\[aq]s Markdown, can
-be disabled using the \f[C]markdown_strict\f[] input or output format.)
+Pandoc\[aq]s enhanced version of Markdown includes syntax for tables,
+definition lists, metadata blocks, \f[C]Div\f[] blocks, footnotes and
+citations, embedded LaTeX (including math), Markdown inside HTML block
+elements, and much more.
+These enhancements, described further under Pandoc\[aq]s Markdown, can
+be disabled using the \f[C]markdown_strict\f[] format.
 .PP
-In contrast to most existing tools for converting Markdown to HTML,
-which use regex substitutions, 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, and a set of writers, which
-convert this native representation into a target format.
+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 (like an \f[I]abstract syntax tree\f[] 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.
 .PP
 Because pandoc\[aq]s intermediate representation of a document is less
 expressive than many of the formats it converts between, one should not
@@ -54,14 +55,9 @@
 Markdown can be expected to be lossy.
 .SS Using \f[C]pandoc\f[]
 .PP
-If no \f[I]input\-file\f[] is specified, input is read from
+If no \f[I]input\-files\f[] are specified, input is read from
 \f[I]stdin\f[].
-Otherwise, the \f[I]input\-files\f[] are concatenated (with a blank line
-between each) and used as input.
-Output goes to \f[I]stdout\f[] by default (though output to the terminal
-is disabled for the \f[C]odt\f[], \f[C]docx\f[], \f[C]epub2\f[], and
-\f[C]epub3\f[] output formats, unless it is forced using
-\f[C]\-o\ \-\f[]).
+Output goes to \f[I]stdout\f[] by default.
 For output to a file, use the \f[C]\-o\f[] option:
 .IP
 .nf
@@ -70,10 +66,10 @@
 \f[]
 .fi
 .PP
-By default, pandoc produces a document fragment, not a standalone
-document with a proper header and footer.
-To produce a standalone document, use the \f[C]\-s\f[] or
-\f[C]\-\-standalone\f[] flag:
+By default, pandoc produces a document fragment.
+To produce a standalone document (e.g.
+a valid HTML file including \f[C]<head>\f[] and \f[C]<body>\f[]), use
+the \f[C]\-s\f[] or \f[C]\-\-standalone\f[] flag:
 .IP
 .nf
 \f[C]
@@ -82,37 +78,17 @@
 .fi
 .PP
 For more information on how standalone documents are produced, see
-Templates, below.
-.PP
-Instead of a file, an absolute URI may be given.
-In this case pandoc will fetch the content using HTTP:
-.IP
-.nf
-\f[C]
-pandoc\ \-f\ html\ \-t\ markdown\ http://www.fsf.org
-\f[]
-.fi
-.PP
-It is possible to supply a custom User\-Agent string or other header
-when requesting a document from a URL:
-.IP
-.nf
-\f[C]
-pandoc\ \-f\ html\ \-t\ markdown\ \-\-request\-header\ User\-Agent:"Mozilla/5.0"\ \\
-\ \ http://www.fsf.org
-\f[]
-.fi
+Templates below.
 .PP
 If multiple input files are given, \f[C]pandoc\f[] will concatenate them
 all (with blank lines between them) before parsing.
-This feature is disabled for binary input formats such as \f[C]EPUB\f[],
-\f[C]odt\f[], and \f[C]docx\f[].
+(Use \f[C]\-\-file\-scope\f[] to parse files individually.)
+.SS Specifying formats
 .PP
 The format of the input and output can be specified explicitly using
 command\-line options.
-The input format can be specified using the \f[C]\-r/\-\-read\f[] or
-\f[C]\-f/\-\-from\f[] options, the output format using the
-\f[C]\-w/\-\-write\f[] or \f[C]\-t/\-\-to\f[] options.
+The input format can be specified using the \f[C]\-f/\-\-from\f[]
+option, the output format using the \f[C]\-t/\-\-to\f[] option.
 Thus, to convert \f[C]hello.txt\f[] from Markdown to LaTeX, you could
 type:
 .IP
@@ -130,17 +106,15 @@
 \f[]
 .fi
 .PP
-Supported output formats are listed below under the \f[C]\-t/\-\-to\f[]
-option.
-Supported input formats are listed below under the \f[C]\-f/\-\-from\f[]
-option.
-Note that the \f[C]rst\f[], \f[C]textile\f[], \f[C]latex\f[], and
-\f[C]html\f[] readers are not complete; there are some constructs that
-they do not parse.
+Supported input and output formats are listed below under Options (see
+\f[C]\-f\f[] for input formats and \f[C]\-t\f[] for output formats).
+You can also use \f[C]pandoc\ \-\-list\-input\-formats\f[] and
+\f[C]pandoc\ \-\-list\-output\-formats\f[] to print lists of supported
+formats.
 .PP
 If the input or output format is not specified explicitly,
 \f[C]pandoc\f[] will attempt to guess it from the extensions of the
-input and output filenames.
+filenames.
 Thus, for example,
 .IP
 .nf
@@ -155,7 +129,8 @@
 default to HTML.
 If no input file is specified (so that input comes from \f[I]stdin\f[]),
 or if the input files\[aq] extensions are unknown, the input format will
-be assumed to be Markdown unless explicitly specified.
+be assumed to be Markdown.
+.SS Character encoding
 .PP
 Pandoc uses the UTF\-8 character encoding for both input and output.
 If your local character encoding is not UTF\-8, you should pipe input
@@ -174,8 +149,7 @@
 .SS Creating a PDF
 .PP
 To produce a PDF, specify an output file with a \f[C]\&.pdf\f[]
-extension.
-By default, pandoc will use LaTeX to create the PDF:
+extension:
 .IP
 .nf
 \f[C]
@@ -183,10 +157,34 @@
 \f[]
 .fi
 .PP
-Production of a PDF requires that a LaTeX engine be installed (see
-\f[C]\-\-pdf\-engine\f[], below), and assumes that the following LaTeX
-packages are available: \f[C]amsfonts\f[], \f[C]amsmath\f[],
-\f[C]lm\f[], \f[C]unicode\-math\f[], \f[C]ifxetex\f[],
+By default, pandoc will use LaTeX to create the PDF, which requires that
+a LaTeX engine be installed (see \f[C]\-\-pdf\-engine\f[] below).
+.PP
+Alternatively, pandoc can use ConTeXt, \f[C]pdfroff\f[], or any of the
+following HTML/CSS\-to\-PDF\-engines, to create a PDF:
+\f[C]wkhtmltopdf\f[], \f[C]weasyprint\f[] or \f[C]prince\f[].
+To do this, specify an output file with a \f[C]\&.pdf\f[] extension, as
+before, but add the \f[C]\-\-pdf\-engine\f[] option or
+\f[C]\-t\ context\f[], \f[C]\-t\ html\f[], or \f[C]\-t\ ms\f[] to the
+command line (\f[C]\-t\ html\f[] defaults to
+\f[C]\-\-pdf\-engine=wkhtmltopdf\f[]).
+.PP
+PDF output can be controlled using variables for LaTeX (if LaTeX is
+used) and variables for ConTeXt (if ConTeXt is used).
+When using an HTML/CSS\-to\-PDF\-engine, \f[C]\-\-css\f[] affects the
+output.
+If \f[C]wkhtmltopdf\f[] is used, then the variables
+\f[C]margin\-left\f[], \f[C]margin\-right\f[], \f[C]margin\-top\f[],
+\f[C]margin\-bottom\f[], and \f[C]papersize\f[] will affect the output.
+.PP
+To debug the PDF creation, it can be useful to look at the intermediate
+representation: instead of \f[C]\-o\ test.pdf\f[], use for example
+\f[C]\-s\ \-o\ test.tex\f[] to output the generated LaTeX.
+You can then test it with \f[C]pdflatex\ test.tex\f[].
+.PP
+When using LaTeX, the following packages need to be available (they are
+included with all recent versions of TeX Live): \f[C]amsfonts\f[],
+\f[C]amsmath\f[], \f[C]lm\f[], \f[C]unicode\-math\f[], \f[C]ifxetex\f[],
 \f[C]ifluatex\f[], \f[C]listings\f[] (if the \f[C]\-\-listings\f[]
 option is used), \f[C]fancyvrb\f[], \f[C]longtable\f[],
 \f[C]booktabs\f[], \f[C]graphicx\f[] and \f[C]grffile\f[] (if the
@@ -205,24 +203,26 @@
 the template or included in any header file.
 The \f[C]natbib\f[], \f[C]biblatex\f[], \f[C]bibtex\f[], and
 \f[C]biber\f[] packages can optionally be used for citation rendering.
-These are included with all recent versions of TeX Live.
+.SS Reading from the Web
 .PP
-Alternatively, pandoc can use ConTeXt, \f[C]pdfroff\f[], or any of the
-following HTML/CSS\-to\-PDF\-engines, to create a PDF:
-\f[C]wkhtmltopdf\f[], \f[C]weasyprint\f[] or \f[C]prince\f[].
-To do this, specify an output file with a \f[C]\&.pdf\f[] extension, as
-before, but add the \f[C]\-\-pdf\-engine\f[] option or
-\f[C]\-t\ context\f[], \f[C]\-t\ html\f[], or \f[C]\-t\ ms\f[] to the
-command line (\f[C]\-t\ html\f[] defaults to
-\f[C]\-\-pdf\-engine=wkhtmltopdf\f[]).
+Instead of an input file, an absolute URI may be given.
+In this case pandoc will fetch the content using HTTP:
+.IP
+.nf
+\f[C]
+pandoc\ \-f\ html\ \-t\ markdown\ http://www.fsf.org
+\f[]
+.fi
 .PP
-PDF output can be controlled using variables for LaTeX (if LaTeX is
-used) and variables for ConTeXt (if ConTeXt is used).
-When using an HTML/CSS\-to\-PDF\-engine, \f[C]\-\-css\f[] affects the
-output.
-If \f[C]wkhtmltopdf\f[] is used, then the variables
-\f[C]margin\-left\f[], \f[C]margin\-right\f[], \f[C]margin\-top\f[],
-\f[C]margin\-bottom\f[], and \f[C]papersize\f[] will affect the output.
+It is possible to supply a custom User\-Agent string or other header
+when requesting a document from a URL:
+.IP
+.nf
+\f[C]
+pandoc\ \-f\ html\ \-t\ markdown\ \-\-request\-header\ User\-Agent:"Mozilla/5.0"\ \\
+\ \ http://www.fsf.org
+\f[]
+.fi
 .SH OPTIONS
 .SS General options
 .TP
@@ -283,9 +283,8 @@
 (\f[C]markdown_github\f[] provides deprecated and less accurate support
 for Github\-Flavored Markdown; please use \f[C]gfm\f[] instead, unless
 you use extensions that do not work with \f[C]gfm\f[].) Note that
-\f[C]odt\f[], \f[C]epub\f[], and \f[C]epub3\f[] output will not be
-directed to \f[I]stdout\f[]; an output filename must be specified using
-the \f[C]\-o/\-\-output\f[] option.
+\f[C]odt\f[], \f[C]docx\f[], and \f[C]epub\f[] output will not be
+directed to \f[I]stdout\f[] unless forced with \f[C]\-o\ \-\f[].
 Extensions can be individually enabled or disabled by appending
 \f[C]+EXTENSION\f[] or \f[C]\-EXTENSION\f[] to the format name.
 See Extensions below, for a list of extensions and their names.
@@ -386,8 +385,8 @@
 .RE
 .TP
 .B \f[C]\-\-list\-extensions\f[][\f[C]=\f[]\f[I]FORMAT\f[]]
-List supported Markdown extensions, one per line, preceded by a
-\f[C]+\f[] or \f[C]\-\f[] indicating whether it is enabled by default in
+List supported extensions, one per line, preceded by a \f[C]+\f[] or
+\f[C]\-\f[] indicating whether it is enabled by default in
 \f[I]FORMAT\f[].
 If \f[I]FORMAT\f[] is not specified, defaults for pandoc\[aq]s Markdown
 are given.
@@ -497,6 +496,9 @@
 \f[C]\-\-data\-dir\f[], above).
 .IP "3." 3
 \f[C]$PATH\f[] (executable only)
+.PP
+Filters and lua\-filters are applied in the order specified on the
+command line.
 .RE
 .TP
 .B \f[C]\-\-lua\-filter=\f[]\f[I]SCRIPT\f[]
@@ -571,6 +573,10 @@
 The author and time of change is included.
 \f[C]all\f[] is useful for scripting: only accepting changes from a
 certain reviewer, say, or before a certain date.
+If a paragraph is inserted or deleted, \f[C]track\-changes=all\f[]
+produces a span with the class
+\f[C]paragraph\-insertion\f[]/\f[C]paragraph\-deletion\f[] before the
+affected paragraph break.
 This option only affects the docx reader.
 .RS
 .RE
@@ -4068,55 +4074,6 @@
 For the most part this should give the same output as \f[C]raw_html\f[],
 but it makes it easier to write pandoc filters to manipulate groups of
 inlines.
-.SS Extension: \f[C]fenced_divs\f[]
-.PP
-Allow special fenced syntax for native \f[C]Div\f[] blocks.
-A Div starts with a fence containing at least three consecutive colons
-plus some attributes.
-The attributes may optionally be followed by another string of
-consecutive colons.
-The attribute syntax is exactly as in fenced code blocks (see Extension:
-\f[C]fenced_code_attributes\f[]).
-As with fenced code blocks, one can use either attributes in curly
-braces or a single unbraced word, which will be treated as a class name.
-The Div ends with another line containing a string of at least three
-consecutive colons.
-The fenced Div should be separated by blank lines from preceding and
-following blocks.
-.PP
-Example:
-.IP
-.nf
-\f[C]
-:::::\ {#special\ .sidebar}
-Here\ is\ a\ paragraph.
-
-And\ another.
-:::::
-\f[]
-.fi
-.PP
-Fenced divs can be nested.
-Opening fences are distinguished because they \f[I]must\f[] have
-attributes:
-.IP
-.nf
-\f[C]
-:::\ Warning\ ::::::
-This\ is\ a\ warning.
-
-:::\ Danger
-This\ is\ a\ warning\ within\ a\ warning.
-:::
-::::::::::::::::::
-\f[]
-.fi
-.PP
-Fences without attributes are always closing fences.
-Unlike with fenced code blocks, the number of colons in the closing
-fence need not match the number in the opening fence.
-However, it can be helpful for visual clarity to use fences of different
-lengths to distinguish nested divs from their parents.
 .SS Extension: \f[C]raw_tex\f[]
 .PP
 In addition to raw HTML, pandoc allows raw LaTeX, TeX, and ConTeXt to be
@@ -4464,12 +4421,67 @@
 When no \f[C]width\f[] or \f[C]height\f[] attributes are specified, the
 fallback is to look at the image resolution and the dpi metadata
 embedded in the image file.
-.SS Spans
+.SS Divs and Spans
+.PP
+Using the \f[C]native_divs\f[] and \f[C]native_spans\f[] extensions (see
+above), HTML syntax can be used as part of markdown to create native
+\f[C]Div\f[] and \f[C]Span\f[] elements in the pandoc AST (as opposed to
+raw HTML).
+However, there is also nicer syntax available:
+.SS Extension: \f[C]fenced_divs\f[]
+.PP
+Allow special fenced syntax for native \f[C]Div\f[] blocks.
+A Div starts with a fence containing at least three consecutive colons
+plus some attributes.
+The attributes may optionally be followed by another string of
+consecutive colons.
+The attribute syntax is exactly as in fenced code blocks (see Extension:
+\f[C]fenced_code_attributes\f[]).
+As with fenced code blocks, one can use either attributes in curly
+braces or a single unbraced word, which will be treated as a class name.
+The Div ends with another line containing a string of at least three
+consecutive colons.
+The fenced Div should be separated by blank lines from preceding and
+following blocks.
+.PP
+Example:
+.IP
+.nf
+\f[C]
+:::::\ {#special\ .sidebar}
+Here\ is\ a\ paragraph.
+
+And\ another.
+:::::
+\f[]
+.fi
+.PP
+Fenced divs can be nested.
+Opening fences are distinguished because they \f[I]must\f[] have
+attributes:
+.IP
+.nf
+\f[C]
+:::\ Warning\ ::::::
+This\ is\ a\ warning.
+
+:::\ Danger
+This\ is\ a\ warning\ within\ a\ warning.
+:::
+::::::::::::::::::
+\f[]
+.fi
+.PP
+Fences without attributes are always closing fences.
+Unlike with fenced code blocks, the number of colons in the closing
+fence need not match the number in the opening fence.
+However, it can be helpful for visual clarity to use fences of different
+lengths to distinguish nested divs from their parents.
 .SS Extension: \f[C]bracketed_spans\f[]
 .PP
 A bracketed sequence of inlines, as one would use to begin a link, will
-be treated as a span with attributes if it is followed immediately by
-attributes:
+be treated as a \f[C]Span\f[] with attributes if it is followed
+immediately by attributes:
 .IP
 .nf
 \f[C]
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,10 +1,10 @@
 name:            pandoc
-version:         2.0.6
+version:         2.1
 cabal-version:   >= 1.10
 build-type:      Custom
 license:         GPL
 license-file:    COPYING.md
-copyright:       (c) 2006-2017 John MacFarlane
+copyright:       (c) 2006-2018 John MacFarlane
 author:          John MacFarlane <jgm@berkeley.edu>
 maintainer:      John MacFarlane <jgm@berkeley.edu>
 bug-reports:     https://github.com/jgm/pandoc/issues
@@ -365,7 +365,7 @@
                  tagsoup >= 0.14.2 && < 0.15,
                  base64-bytestring >= 0.1 && < 1.1,
                  zlib >= 0.5 && < 0.7,
-                 skylighting >= 0.5 && < 0.6,
+                 skylighting >= 0.5.1 && < 0.6,
                  data-default >= 0.4 && < 0.8,
                  temporary >= 1.1 && < 1.3,
                  blaze-html >= 0.5 && < 0.10,
@@ -373,7 +373,7 @@
                  yaml >= 0.8.8.2 && < 0.9,
                  scientific >= 0.2 && < 0.4,
                  vector >= 0.10 && < 0.13,
-                 hslua >= 0.9.3 && < 0.10,
+                 hslua >= 0.9.5 && < 0.10,
                  hslua-module-text >= 0.1.2 && < 0.2,
                  binary >= 0.5 && < 0.10,
                  SHA >= 1.6 && < 1.7,
@@ -622,7 +622,8 @@
                   QuickCheck >= 2.4 && < 2.11,
                   containers >= 0.4.2.1 && < 0.6,
                   executable-path >= 0.0 && < 0.1,
-                  zip-archive >= 0.2.3.4 && < 0.4
+                  zip-archive >= 0.2.3.4 && < 0.4,
+                  xml >= 1.3.12 && < 1.4
   if flag(old-locale)
      build-depends: old-locale >= 1 && < 1.1,
                     time >= 1.2 && < 1.5
diff --git a/pandoc.hs b/pandoc.hs
--- a/pandoc.hs
+++ b/pandoc.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Main
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley@edu>
diff --git a/src/Text/Pandoc.hs b/src/Text/Pandoc.hs
--- a/src/Text/Pandoc.hs
+++ b/src/Text/Pandoc.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE GADTs               #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/App.hs b/src/Text/Pandoc/App.hs
--- a/src/Text/Pandoc/App.hs
+++ b/src/Text/Pandoc/App.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TupleSections       #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 {- |
    Module      : Text.Pandoc.App
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley@edu>
@@ -35,11 +35,12 @@
 module Text.Pandoc.App (
             convertWithOpts
           , Opt(..)
+          , LineEnding(..)
+          , Filter(..)
           , defaultOpts
           , parseOptions
           , options
           , applyFilters
-          , applyLuaFilters
           ) where
 import qualified Control.Exception as E
 import Control.Monad
@@ -70,8 +71,7 @@
          defConfig, Indent(..), NumberFormat(..))
 import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme,
                     pygments)
-import Skylighting.Parser (addSyntaxDefinition, missingIncludes,
-                           parseSyntaxDefinition)
+import Skylighting.Parser (addSyntaxDefinition, parseSyntaxDefinition)
 import System.Console.GetOpt
 import System.Directory (Permissions (..), doesFileExist, findExecutable,
                          getAppUserDataDirectory, getPermissions)
@@ -184,11 +184,13 @@
                          Nothing -> return Nothing
                          Just fp -> Just <$> UTF8.readFile fp
 
+  let isPandocCiteproc (JSONFilter f) = takeBaseName f == "pandoc-citeproc"
+      isPandocCiteproc _              = False
   -- --bibliography implies -F pandoc-citeproc for backwards compatibility:
   let needsCiteproc = isJust (lookup "bibliography" (optMetadata opts)) &&
                       optCiteMethod opts `notElem` [Natbib, Biblatex] &&
-                      "pandoc-citeproc" `notElem` map takeBaseName filters
-  let filters' = if needsCiteproc then "pandoc-citeproc" : filters
+                      all (not . isPandocCiteproc) filters
+  let filters' = if needsCiteproc then JSONFilter "pandoc-citeproc" : filters
                                   else filters
 
   let sources = case optInputFiles opts of
@@ -265,14 +267,6 @@
   syntaxMap <- foldM addSyntaxMap defaultSyntaxMap
                      (optSyntaxDefinitions opts)
 
-  case missingIncludes (M.elems syntaxMap) of
-       [] -> return ()
-       xs -> E.throwIO $ PandocSyntaxMapError $
-                "Missing syntax definitions:\n" ++
-                unlines (map
-                  (\(syn,dep) -> (T.unpack syn ++ " requires " ++
-                    T.unpack dep ++ " through IncludeRules.")) xs)
-
   -- We don't want to send output to the terminal if the user
   -- does 'pandoc -t docx input.txt'; though we allow them to
   -- force this with '-o -'.  On posix systems, we detect
@@ -501,10 +495,9 @@
                       then fillMediaBag
                       else return)
               >=> return . addMetadata metadata
-              >=> applyLuaFilters datadir (optLuaFilters opts) format
-              >=> maybe return extractMedia (optExtractMedia opts)
               >=> applyTransforms transforms
-              >=> applyFilters readerOpts datadir filters' [format]
+              >=> applyFilters readerOpts filters' [format]
+              >=> maybe return extractMedia (optExtractMedia opts)
               )
 
     case writer of
@@ -583,6 +576,10 @@
  where filterException :: E.SomeException -> IO a
        filterException e = E.throwIO $ PandocFilterError f (show e)
 
+data Filter = LuaFilter FilePath
+            | JSONFilter FilePath
+            deriving (Show)
+
 -- | Data structure for command line options.
 data Opt = Opt
     { optTabStop               :: Int     -- ^ Number of spaces per tab
@@ -626,8 +623,7 @@
     , optDpi                   :: Int     -- ^ Dpi
     , optWrapText              :: WrapOption  -- ^ Options for wrapping text
     , optColumns               :: Int     -- ^ Line length in characters
-    , optFilters               :: [FilePath] -- ^ Filters to apply
-    , optLuaFilters            :: [FilePath] -- ^ Lua filters to apply
+    , optFilters               :: [Filter] -- ^ Filters to apply
     , optEmailObfuscation      :: ObfuscationMethod
     , optIdentifierPrefix      :: String
     , optStripEmptyParagraphs  :: Bool -- ^ Strip empty paragraphs
@@ -700,7 +696,6 @@
     , optWrapText              = WrapAuto
     , optColumns               = 72
     , optFilters               = []
-    , optLuaFilters            = []
     , optEmailObfuscation      = NoObfuscation
     , optIdentifierPrefix      = ""
     , optStripEmptyParagraphs  = False
@@ -832,42 +827,47 @@
   -- First we check to see if a filter is found.  If not, and if it's
   -- not an absolute path, we check to see whether it's in `userdir/filters`.
   -- If not, we leave it unchanged.
-expandFilterPath :: MonadIO m => Maybe FilePath -> FilePath -> m FilePath
-expandFilterPath mbDatadir fp = liftIO $ do
-  fpExists <- doesFileExist fp
+expandFilterPath :: PandocMonad m => FilePath -> m FilePath
+expandFilterPath fp = do
+  mbDatadir <- getUserDataDir
+  fpExists <- fileExists fp
   if fpExists
      then return fp
      else case mbDatadir of
                Just datadir | isRelative fp -> do
                  let filterPath = datadir </> "filters" </> fp
-                 filterPathExists <- doesFileExist filterPath
+                 filterPathExists <- fileExists filterPath
                  if filterPathExists
                     then return filterPath
                     else return fp
                _ -> return fp
 
-applyLuaFilters :: Maybe FilePath -> [FilePath] -> String -> Pandoc
-                -> PandocIO Pandoc
-applyLuaFilters mbDatadir filters format d = do
-  expandedFilters <- mapM (expandFilterPath mbDatadir) filters
-  let go f d' = do
-        res <- runLuaFilter f format d'
-        case res of
-          Right x               -> return x
-          Left (LuaException s) -> E.throw (PandocFilterError f s)
-  foldrM ($) d $ map go expandedFilters
-
-applyFilters :: MonadIO m
-             => ReaderOptions
-             -> Maybe FilePath
-             -> [FilePath]
+applyFilters :: ReaderOptions
+             -> [Filter]
              -> [String]
              -> Pandoc
-             -> m Pandoc
-applyFilters ropts mbDatadir filters args d = do
-  expandedFilters <- mapM (expandFilterPath mbDatadir) filters
-  foldrM ($) d $ map (flip (externalFilter ropts) args) expandedFilters
+             -> PandocIO Pandoc
+applyFilters ropts filters args d = do
+  foldrM ($) d $ map (applyFilter ropts args) filters
 
+applyFilter :: ReaderOptions
+            -> [String]
+            -> Filter
+            -> Pandoc
+            -> PandocIO Pandoc
+applyFilter _ropts args (LuaFilter f) d = do
+  f' <- expandFilterPath f
+  let format = case args of
+                    (x:_) -> x
+                    _     -> error "Format not supplied for lua filter"
+  res <- runLuaFilter f' format d
+  case res of
+       Right x               -> return x
+       Left (LuaException s) -> E.throw (PandocFilterError f s)
+applyFilter ropts args (JSONFilter f) d = do
+  f' <- expandFilterPath f
+  liftIO $ externalFilter ropts f' args d
+
 readSource :: FilePath -> PandocIO Text
 readSource "-" = liftIO (UTF8.toText <$> BS.getContents)
 readSource src = case parseURI src of
@@ -968,13 +968,15 @@
 
     , Option "F" ["filter"]
                  (ReqArg
-                  (\arg opt -> return opt { optFilters = arg : optFilters opt })
+                  (\arg opt -> return opt { optFilters =
+                                    JSONFilter arg : optFilters opt })
                   "PROGRAM")
                  "" -- "External JSON filter"
 
     , Option "" ["lua-filter"]
                  (ReqArg
-                  (\arg opt -> return opt { optLuaFilters = arg : optLuaFilters opt })
+                  (\arg opt -> return opt { optFilters =
+                                    LuaFilter arg : optFilters opt })
                   "SCRIPTPATH")
                  "" -- "Lua filter"
 
@@ -1651,7 +1653,7 @@
 copyrightMessage :: String
 copyrightMessage = intercalate "\n" [
   "",
-  "Copyright (C) 2006-2017 John MacFarlane",
+  "Copyright (C) 2006-2018 John MacFarlane",
   "Web:  http://pandoc.org",
   "This is free software; see the source for copying conditions.",
   "There is no warranty, not even for merchantability or fitness",
@@ -1720,4 +1722,5 @@
 -- see https://github.com/jgm/pandoc/pull/4083
 -- using generic deriving caused long compilation times
 $(deriveJSON defaultOptions ''LineEnding)
+$(deriveJSON defaultOptions ''Filter)
 $(deriveJSON defaultOptions ''Opt)
diff --git a/src/Text/Pandoc/Asciify.hs b/src/Text/Pandoc/Asciify.hs
--- a/src/Text/Pandoc/Asciify.hs
+++ b/src/Text/Pandoc/Asciify.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2013-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2013-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Asciify
-   Copyright   : Copyright (C) 2013-2017 John MacFarlane
+   Copyright   : Copyright (C) 2013-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/BCP47.hs b/src/Text/Pandoc/BCP47.hs
--- a/src/Text/Pandoc/BCP47.hs
+++ b/src/Text/Pandoc/BCP47.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2017–2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.BCP47
-   Copyright   : Copyright (C) 2017 John MacFarlane
+   Copyright   : Copyright (C) 2017–2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/CSV.hs b/src/Text/Pandoc/CSV.hs
--- a/src/Text/Pandoc/CSV.hs
+++ b/src/Text/Pandoc/CSV.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2017–2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.CSV
-   Copyright   : Copyright (C) 2017 John MacFarlane <jgm@berkeley.edu>
+   Copyright   : Copyright (C) 2017–2018 John MacFarlane <jgm@berkeley.edu>
    License     : GNU GPL, version 2 or above
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
    Stability   : alpha
diff --git a/src/Text/Pandoc/Class.hs b/src/Text/Pandoc/Class.hs
--- a/src/Text/Pandoc/Class.hs
+++ b/src/Text/Pandoc/Class.hs
@@ -78,7 +78,7 @@
                          , getResourcePath
                          , PandocIO(..)
                          , PandocPure(..)
-                         , FileTree(..)
+                         , FileTree
                          , FileInfo(..)
                          , addToFileTree
                          , insertInFileTree
diff --git a/src/Text/Pandoc/Error.hs b/src/Text/Pandoc/Error.hs
--- a/src/Text/Pandoc/Error.hs
+++ b/src/Text/Pandoc/Error.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric      #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Error
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Extensions.hs b/src/Text/Pandoc/Extensions.hs
--- a/src/Text/Pandoc/Extensions.hs
+++ b/src/Text/Pandoc/Extensions.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Extensions
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Highlighting.hs b/src/Text/Pandoc/Highlighting.hs
--- a/src/Text/Pandoc/Highlighting.hs
+++ b/src/Text/Pandoc/Highlighting.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Highlighting
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/ImageSize.hs b/src/Text/Pandoc/ImageSize.hs
--- a/src/Text/Pandoc/ImageSize.hs
+++ b/src/Text/Pandoc/ImageSize.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings, ScopedTypeVariables, CPP #-}
 {-# OPTIONS_GHC -fno-warn-type-defaults #-}
 {-
-  Copyright (C) 2011-2017 John MacFarlane <jgm@berkeley.edu>
+  Copyright (C) 2011-2018 John MacFarlane <jgm@berkeley.edu>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
 Module      : Text.Pandoc.ImageSize
-Copyright   : Copyright (C) 2011-2017 John MacFarlane
+Copyright   : Copyright (C) 2011-2018 John MacFarlane
 License     : GNU GPL, version 2 or above
 
 Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Logging.hs b/src/Text/Pandoc/Logging.hs
--- a/src/Text/Pandoc/Logging.hs
+++ b/src/Text/Pandoc/Logging.hs
@@ -20,7 +20,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Logging
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Lua.hs b/src/Text/Pandoc/Lua.hs
--- a/src/Text/Pandoc/Lua.hs
+++ b/src/Text/Pandoc/Lua.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017–2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Lua
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017–2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -29,17 +29,16 @@
   ( LuaException (..)
   , runLuaFilter
   , runPandocLua
-  , pushPandocModule
   ) where
 
-import Control.Monad (when, (>=>))
+import Control.Monad ((>=>))
 import Foreign.Lua (FromLuaStack (peek), Lua, LuaException (..),
                     Status (OK), ToLuaStack (push))
 import Text.Pandoc.Class (PandocIO)
 import Text.Pandoc.Definition (Pandoc)
 import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
 import Text.Pandoc.Lua.Init (runPandocLua)
-import Text.Pandoc.Lua.Module.Pandoc (pushModule) -- TODO: remove
+import Text.Pandoc.Lua.Util (popValue)
 import qualified Foreign.Lua as Lua
 
 -- | Run the Lua filter in @filterPath@ for a transformation to target
@@ -63,25 +62,16 @@
       Lua.throwLuaError luaErrMsg
     else do
       newtop <- Lua.gettop
-      -- Use the implicitly defined global filter if nothing was returned
-      when (newtop - top < 1) pushGlobalFilter
-      luaFilters <- peek (-1)
+      -- Use the returned filters, or the implicitly defined global filter if
+      -- nothing was returned.
+      luaFilters <- if (newtop - top >= 1)
+                    then peek (-1)
+                    else Lua.getglobal "_G" *> fmap (:[]) popValue
       runAll luaFilters pd
  where
   registerFormat = do
     push format
     Lua.setglobal "FORMAT"
 
-pushGlobalFilter :: Lua ()
-pushGlobalFilter = do
-  Lua.newtable
-  Lua.getglobal' "pandoc.global_filter"
-  Lua.call 0 1
-  Lua.rawseti (-2) 1
-
 runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
 runAll = foldr ((>=>) . walkMWithLuaFilter) return
-
--- | DEPRECATED: Push the pandoc module to the Lua Stack.
-pushPandocModule :: Maybe FilePath -> Lua Lua.NumResults
-pushPandocModule = pushModule
diff --git a/src/Text/Pandoc/Lua/Filter.hs b/src/Text/Pandoc/Lua/Filter.hs
--- a/src/Text/Pandoc/Lua/Filter.hs
+++ b/src/Text/Pandoc/Lua/Filter.hs
@@ -164,5 +164,3 @@
         Lua.throwLuaError $
           "Error while trying to get a filter's return " ++
           "value from lua stack.\n" ++ err
-
-
diff --git a/src/Text/Pandoc/Lua/Init.hs b/src/Text/Pandoc/Lua/Init.hs
--- a/src/Text/Pandoc/Lua/Init.hs
+++ b/src/Text/Pandoc/Lua/Init.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Lua
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -35,10 +35,13 @@
 
 import Control.Monad.Trans (MonadIO (..))
 import Data.IORef (newIORef, readIORef)
+import Data.Version (Version (versionBranch))
 import Foreign.Lua (Lua, LuaException (..))
 import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
+import Paths_pandoc (version)
 import Text.Pandoc.Class (PandocIO, getCommonState, getUserDataDir, getMediaBag,
                           setMediaBag)
+import Text.Pandoc.Definition (pandocTypesVersion)
 import Text.Pandoc.Lua.Packages (LuaPackageParams (..),
                                  installPandocPackageSearcher)
 import Text.Pandoc.Lua.Util (loadScriptFromDataDir)
@@ -75,5 +78,9 @@
 initLuaState luaPkgParams = do
   Lua.openlibs
   Lua.preloadTextModule "text"
+  Lua.push (versionBranch version)
+  Lua.setglobal "PANDOC_VERSION"
+  Lua.push (versionBranch pandocTypesVersion)
+  Lua.setglobal "PANDOC_API_VERSION"
   installPandocPackageSearcher luaPkgParams
   loadScriptFromDataDir (luaPkgDataDir luaPkgParams) "init.lua"
diff --git a/src/Text/Pandoc/Lua/Module/MediaBag.hs b/src/Text/Pandoc/Lua/Module/MediaBag.hs
--- a/src/Text/Pandoc/Lua/Module/MediaBag.hs
+++ b/src/Text/Pandoc/Lua/Module/MediaBag.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Lua.Module.MediaBag
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -32,11 +32,11 @@
 import Control.Monad (zipWithM_)
 import Data.IORef (IORef, modifyIORef', readIORef)
 import Data.Maybe (fromMaybe)
-import Foreign.Lua (Lua, NumResults, liftIO)
+import Foreign.Lua (Lua, NumResults, Optional, liftIO)
 import Text.Pandoc.Class (CommonState (..), fetchItem, putCommonState,
                           runIOorExplode, setMediaBag)
 import Text.Pandoc.Lua.StackInstances ()
-import Text.Pandoc.Lua.Util (OrNil (toMaybe), addFunction)
+import Text.Pandoc.Lua.Util (addFunction)
 import Text.Pandoc.MIME (MimeType)
 
 import qualified Data.ByteString.Lazy as BL
@@ -57,12 +57,12 @@
 
 insertMediaFn :: IORef MB.MediaBag
               -> FilePath
-              -> OrNil MimeType
+              -> Optional MimeType
               -> BL.ByteString
               -> Lua NumResults
-insertMediaFn mbRef fp nilOrMime contents = do
+insertMediaFn mbRef fp optionalMime contents = do
   liftIO . modifyIORef' mbRef $
-    MB.insertMedia fp (toMaybe nilOrMime) contents
+    MB.insertMedia fp (Lua.fromOptional optionalMime) contents
   return 0
 
 lookupMediaFn :: IORef MB.MediaBag
diff --git a/src/Text/Pandoc/Lua/Module/Pandoc.hs b/src/Text/Pandoc/Lua/Module/Pandoc.hs
--- a/src/Text/Pandoc/Lua/Module/Pandoc.hs
+++ b/src/Text/Pandoc/Lua/Module/Pandoc.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Pandoc
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -34,14 +34,13 @@
 import Data.Default (Default (..))
 import Data.Maybe (fromMaybe)
 import Data.Text (pack)
-import Foreign.Lua (ToLuaStack, FromLuaStack, Lua, NumResults, liftIO)
+import Foreign.Lua (ToLuaStack, FromLuaStack, Lua, NumResults, Optional, liftIO)
 import System.Exit (ExitCode (..))
 import Text.Pandoc.Class (runIO)
 import Text.Pandoc.Definition (Block, Inline)
 import Text.Pandoc.Lua.Filter (walkInlines, walkBlocks, LuaFilter)
 import Text.Pandoc.Lua.StackInstances ()
-import Text.Pandoc.Lua.Util (OrNil (toMaybe), addFunction, addValue,
-                             loadScriptFromDataDir, raiseError)
+import Text.Pandoc.Lua.Util (addFunction, addValue, loadScriptFromDataDir)
 import Text.Pandoc.Walk (Walkable)
 import Text.Pandoc.Options (ReaderOptions (readerExtensions))
 import Text.Pandoc.Process (pipeProcess)
@@ -72,19 +71,19 @@
 walkBlock :: Block -> LuaFilter -> Lua Block
 walkBlock = walkElement
 
-readDoc :: String -> OrNil String -> Lua NumResults
+readDoc :: String -> Optional String -> Lua NumResults
 readDoc content formatSpecOrNil = do
-  let formatSpec = fromMaybe "markdown" (toMaybe formatSpecOrNil)
+  let formatSpec = fromMaybe "markdown" (Lua.fromOptional formatSpecOrNil)
   case getReader formatSpec of
-    Left  s      -> raiseError s -- Unknown reader
+    Left  s      -> Lua.raiseError s -- Unknown reader
     Right (reader, es) ->
       case reader of
         TextReader r -> do
           res <- liftIO $ runIO $ r def{ readerExtensions = es } (pack content)
           case res of
             Right pd -> (1 :: NumResults) <$ Lua.push pd -- success, push Pandoc
-            Left s   -> raiseError (show s)              -- error while reading
-        _  -> raiseError "Only string formats are supported at the moment."
+            Left s   -> Lua.raiseError (show s)              -- error while reading
+        _  -> Lua.raiseError "Only string formats are supported at the moment."
 
 -- | Pipes input through a command.
 pipeFn :: String
@@ -95,7 +94,7 @@
   (ec, output) <- liftIO $ pipeProcess Nothing command args input
   case ec of
     ExitSuccess -> 1 <$ Lua.push output
-    ExitFailure n -> raiseError (PipeError command n output)
+    ExitFailure n -> Lua.raiseError (PipeError command n output)
 
 data PipeError = PipeError
   { pipeErrorCommand :: String
diff --git a/src/Text/Pandoc/Lua/Module/Utils.hs b/src/Text/Pandoc/Lua/Module/Utils.hs
--- a/src/Text/Pandoc/Lua/Module/Utils.hs
+++ b/src/Text/Pandoc/Lua/Module/Utils.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Lua.Module.Utils
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -31,9 +31,9 @@
 
 import Control.Applicative ((<|>))
 import Foreign.Lua (FromLuaStack, Lua, LuaInteger, NumResults)
-import Text.Pandoc.Definition (Pandoc, Meta, Block, Inline)
+import Text.Pandoc.Definition (Pandoc, Meta, MetaValue, Block, Inline)
 import Text.Pandoc.Lua.StackInstances ()
-import Text.Pandoc.Lua.Util (OrNil (OrNil), addFunction)
+import Text.Pandoc.Lua.Util (addFunction)
 
 import qualified Data.Digest.Pure.SHA as SHA
 import qualified Data.ByteString.Lazy as BSL
@@ -59,8 +59,8 @@
 -- limit years to the range 1601-9999 (ISO 8601 accepts greater than
 -- or equal to 1583, but MS Word only accepts dates starting 1601).
 -- Returns nil instead of a string if the conversion failed.
-normalizeDate :: String -> Lua (OrNil String)
-normalizeDate = return . OrNil . Shared.normalizeDate
+normalizeDate :: String -> Lua (Lua.Optional String)
+normalizeDate = return . Lua.Optional . Shared.normalizeDate
 
 -- | Calculate the hash of the given contents.
 sha1 :: BSL.ByteString
@@ -76,12 +76,14 @@
   InlineElement i  -> Shared.stringify i
   BlockElement b   -> Shared.stringify b
   MetaElement m    -> Shared.stringify m
+  MetaValueElement m -> Shared.stringify m
 
 data AstElement
   = PandocElement Pandoc
   | MetaElement Meta
   | BlockElement Block
   | InlineElement Inline
+  | MetaValueElement MetaValue
   deriving (Show)
 
 instance FromLuaStack AstElement where
@@ -90,6 +92,7 @@
                      <|> (InlineElement <$> Lua.peek idx)
                      <|> (BlockElement <$> Lua.peek idx)
                      <|> (MetaElement <$> Lua.peek idx)
+                     <|> (MetaValueElement <$> Lua.peek idx)
     case res of
       Right x -> return x
       Left _ -> Lua.throwLuaError
diff --git a/src/Text/Pandoc/Lua/Packages.hs b/src/Text/Pandoc/Lua/Packages.hs
--- a/src/Text/Pandoc/Lua/Packages.hs
+++ b/src/Text/Pandoc/Lua/Packages.hs
@@ -1,5 +1,5 @@
 {-
-Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 {- |
    Module      : Text.Pandoc.Lua.Packages
-   Copyright   : Copyright © 2017 Albert Krewinkel
+   Copyright   : Copyright © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Lua/StackInstances.hs b/src/Text/Pandoc/Lua/StackInstances.hs
--- a/src/Text/Pandoc/Lua/StackInstances.hs
+++ b/src/Text/Pandoc/Lua/StackInstances.hs
@@ -1,6 +1,6 @@
 {-
-Copyright © 2012-2017 John MacFarlane <jgm@berkeley.edu>
-            2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2012-2018 John MacFarlane <jgm@berkeley.edu>
+            2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 {- |
    Module      : Text.Pandoc.Lua.StackInstances
-   Copyright   : © 2012-2017 John MacFarlane
-                 © 2017 Albert Krewinkel
+   Copyright   : © 2012-2018 John MacFarlane
+                 © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -84,12 +84,12 @@
 
 instance FromLuaStack Citation where
   peek idx = do
-    id' <- getTable idx "citationId"
-    prefix <- getTable idx "citationPrefix"
-    suffix <- getTable idx "citationSuffix"
-    mode <- getTable idx "citationMode"
-    num <- getTable idx "citationNoteNum"
-    hash <- getTable idx "citationHash"
+    id' <- getTable idx "id"
+    prefix <- getTable idx "prefix"
+    suffix <- getTable idx "suffix"
+    mode <- getTable idx "mode"
+    num <- getTable idx "note_num"
+    hash <- getTable idx "hash"
     return $ Citation id' prefix suffix mode num hash
 
 instance ToLuaStack Alignment where
diff --git a/src/Text/Pandoc/Lua/Util.hs b/src/Text/Pandoc/Lua/Util.hs
--- a/src/Text/Pandoc/Lua/Util.hs
+++ b/src/Text/Pandoc/Lua/Util.hs
@@ -1,6 +1,6 @@
 {-
-Copyright © 2012-2017 John MacFarlane <jgm@berkeley.edu>
-            2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright © 2012-2018 John MacFarlane <jgm@berkeley.edu>
+            2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
 {-# LANGUAGE FlexibleInstances #-}
 {- |
    Module      : Text.Pandoc.Lua.Util
-   Copyright   : © 2012–2017 John MacFarlane,
-                 © 2017 Albert Krewinkel
+   Copyright   : © 2012–2018 John MacFarlane,
+                 © 2017-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -37,7 +37,7 @@
   , setRawInt
   , addRawInt
   , raiseError
-  , OrNil (..)
+  , popValue
   , PushViaCall
   , pushViaCall
   , pushViaConstructor
@@ -113,21 +113,6 @@
   case resOrError of
     Left err -> Lua.throwLuaError err
     Right x -> return x
-
--- | Newtype wrapper intended to be used for optional Lua values. Nesting this
--- type is strongly discouraged and will likely lead to a wrong result.
-newtype OrNil a = OrNil { toMaybe :: Maybe a }
-
-instance FromLuaStack a => FromLuaStack (OrNil a) where
-  peek idx = do
-    noValue <- Lua.isnoneornil idx
-    if noValue
-      then return (OrNil Nothing)
-      else OrNil . Just <$> Lua.peek idx
-
-instance ToLuaStack a => ToLuaStack (OrNil a) where
-  push (OrNil Nothing)  = Lua.pushnil
-  push (OrNil (Just x)) = Lua.push x
 
 -- | Helper class for pushing a single value to the stack via a lua function.
 -- See @pushViaCall@.
diff --git a/src/Text/Pandoc/MIME.hs b/src/Text/Pandoc/MIME.hs
--- a/src/Text/Pandoc/MIME.hs
+++ b/src/Text/Pandoc/MIME.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2011-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2011-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.MIME
-   Copyright   : Copyright (C) 2011-2017 John MacFarlane
+   Copyright   : Copyright (C) 2011-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/MediaBag.hs b/src/Text/Pandoc/MediaBag.hs
--- a/src/Text/Pandoc/MediaBag.hs
+++ b/src/Text/Pandoc/MediaBag.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-
-Copyright (C) 2014-2015, 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2014-2015, 2017–2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.MediaBag
-   Copyright   : Copyright (C) 2014-2015, 2017 John MacFarlane
+   Copyright   : Copyright (C) 2014-2015, 2017–2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Options.hs b/src/Text/Pandoc/Options.hs
--- a/src/Text/Pandoc/Options.hs
+++ b/src/Text/Pandoc/Options.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE DeriveGeneric      #-}
 {-# LANGUAGE TemplateHaskell    #-}
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Options
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/PDF.hs b/src/Text/Pandoc/PDF.hs
--- a/src/Text/Pandoc/PDF.hs
+++ b/src/Text/Pandoc/PDF.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.PDF
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs
--- a/src/Text/Pandoc/Parsing.hs
+++ b/src/Text/Pandoc/Parsing.hs
@@ -6,7 +6,7 @@
 {-# LANGUAGE MultiParamTypeClasses      #-}
 {-# LANGUAGE TypeSynonymInstances       #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 
 {- |
    Module      : Text.Pandoc.Parsing
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Pretty.hs b/src/Text/Pandoc/Pretty.hs
--- a/src/Text/Pandoc/Pretty.hs
+++ b/src/Text/Pandoc/Pretty.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE CPP                        #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-
-Copyright (C) 2010-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2010-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Pretty
-   Copyright   : Copyright (C) 2010-2017 John MacFarlane
+   Copyright   : Copyright (C) 2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Process.hs b/src/Text/Pandoc/Process.hs
--- a/src/Text/Pandoc/Process.hs
+++ b/src/Text/Pandoc/Process.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2013-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2013-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Process
-   Copyright   : Copyright (C) 2013-2017 John MacFarlane
+   Copyright   : Copyright (C) 2013-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers.hs b/src/Text/Pandoc/Readers.hs
--- a/src/Text/Pandoc/Readers.hs
+++ b/src/Text/Pandoc/Readers.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE GADTs               #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/CommonMark.hs b/src/Text/Pandoc/Readers/CommonMark.hs
--- a/src/Text/Pandoc/Readers/CommonMark.hs
+++ b/src/Text/Pandoc/Readers/CommonMark.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2015-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2015-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.CommonMark
-   Copyright   : Copyright (C) 2015-2017 John MacFarlane
+   Copyright   : Copyright (C) 2015-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/Docx.hs b/src/Text/Pandoc/Readers/Docx.hs
--- a/src/Text/Pandoc/Readers/Docx.hs
+++ b/src/Text/Pandoc/Readers/Docx.hs
@@ -1,9 +1,8 @@
 {-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards     #-}
-
 {-
-Copyright (C) 2014-2017 Jesse Rosenthal <jrosenthal@jhu.edu>
+Copyright (C) 2014-2018 Jesse Rosenthal <jrosenthal@jhu.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Docx
-   Copyright   : Copyright (C) 2014-2017 Jesse Rosenthal
+   Copyright   : Copyright (C) 2014-2018 Jesse Rosenthal
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Jesse Rosenthal <jrosenthal@jhu.edu>
@@ -82,6 +81,7 @@
 import Data.Default (Default)
 import Data.List (delete, intersect)
 import qualified Data.Map as M
+import Data.Maybe (isJust)
 import Data.Sequence (ViewL (..), viewl)
 import qualified Data.Sequence as Seq
 import qualified Data.Set as Set
@@ -118,20 +118,26 @@
   throwError $ PandocSomeError "couldn't parse docx file"
 
 data DState = DState { docxAnchorMap :: M.Map String String
+                     , docxAnchorSet :: Set.Set String
+                     , docxImmedPrevAnchor :: Maybe String
                      , docxMediaBag  :: MediaBag
                      , docxDropCap   :: Inlines
                      , docxWarnings  :: [String]
                      -- keep track of (numId, lvl) values for
                      -- restarting
                      , docxListState :: M.Map (String, String) Integer
+                     , docxPrevPara  :: Inlines
                      }
 
 instance Default DState where
   def = DState { docxAnchorMap = M.empty
+               , docxAnchorSet = mempty
+               , docxImmedPrevAnchor = Nothing
                , docxMediaBag  = mempty
                , docxDropCap   = mempty
                , docxWarnings  = []
                , docxListState = M.empty
+               , docxPrevPara  = mempty
                }
 
 data DEnv = DEnv { docxOptions       :: ReaderOptions
@@ -339,9 +345,27 @@
       "Docx comment " ++ cmtId ++ " will not retain formatting"
   return $ blocksToInlines' blkList
 
+-- The majority of work in this function is done in the primed
+-- subfunction `partPartToInlines'`. We make this wrapper so that we
+-- don't have to modify `docxImmedPrevAnchor` state after every function.
 parPartToInlines :: PandocMonad m => ParPart -> DocxContext m Inlines
-parPartToInlines (PlainRun r) = runToInlines r
-parPartToInlines (Insertion _ author date runs) = do
+parPartToInlines parPart =
+  case parPart of
+    (BookMark _ anchor) | not $ anchor `elem` dummyAnchors -> do
+      inHdrBool <- asks docxInHeaderBlock
+      ils <- parPartToInlines' parPart
+      immedPrevAnchor <- gets docxImmedPrevAnchor
+      unless (isJust immedPrevAnchor || inHdrBool)
+        (modify $ \s -> s{ docxImmedPrevAnchor = Just anchor})
+      return ils
+    _ -> do
+      ils <- parPartToInlines' parPart
+      modify $ \s -> s{ docxImmedPrevAnchor = Nothing}
+      return ils
+
+parPartToInlines' :: PandocMonad m => ParPart -> DocxContext m Inlines
+parPartToInlines' (PlainRun r) = runToInlines r
+parPartToInlines' (ChangedRuns (TrackedChange Insertion (ChangeInfo _ author date)) runs) = do
   opts <- asks docxOptions
   case readerTrackChanges opts of
     AcceptChanges -> smushInlines <$> mapM runToInlines runs
@@ -350,7 +374,7 @@
       ils <- smushInlines <$> mapM runToInlines runs
       let attr = ("", ["insertion"], [("author", author), ("date", date)])
       return $ spanWith attr ils
-parPartToInlines (Deletion _ author date runs) = do
+parPartToInlines' (ChangedRuns (TrackedChange Deletion (ChangeInfo _ author date)) runs) = do
   opts <- asks docxOptions
   case readerTrackChanges opts of
     AcceptChanges -> return mempty
@@ -359,7 +383,7 @@
       ils <- smushInlines <$> mapM runToInlines runs
       let attr = ("", ["deletion"], [("author", author), ("date", date)])
       return $ spanWith attr ils
-parPartToInlines (CommentStart cmtId author date bodyParts) = do
+parPartToInlines' (CommentStart cmtId author date bodyParts) = do
   opts <- asks docxOptions
   case readerTrackChanges opts of
     AllChanges -> do
@@ -368,16 +392,16 @@
       let attr = ("", ["comment-start"], [("id", cmtId), ("author", author), ("date", date)])
       return $ spanWith attr ils
     _ -> return mempty
-parPartToInlines (CommentEnd cmtId) = do
+parPartToInlines' (CommentEnd cmtId) = do
   opts <- asks docxOptions
   case readerTrackChanges opts of
     AllChanges -> do
       let attr = ("", ["comment-end"], [("id", cmtId)])
       return $ spanWith attr mempty
     _ -> return mempty
-parPartToInlines (BookMark _ anchor) | anchor `elem` dummyAnchors =
+parPartToInlines' (BookMark _ anchor) | anchor `elem` dummyAnchors =
   return mempty
-parPartToInlines (BookMark _ anchor) =
+parPartToInlines' (BookMark _ anchor) =
   -- We record these, so we can make sure not to overwrite
   -- user-defined anchor links with header auto ids.
   do
@@ -393,27 +417,34 @@
     -- of rewriting user-defined anchor links. However, since these
     -- are not defined in pandoc, it seems like a necessary evil to
     -- avoid an extra pass.
-    let newAnchor =
-          if not inHdrBool && anchor `elem` M.elems anchorMap
-          then uniqueIdent [Str anchor] (Set.fromList $ M.elems anchorMap)
-          else anchor
-    unless inHdrBool
-      (modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap})
-    return $ spanWith (newAnchor, ["anchor"], []) mempty
-parPartToInlines (Drawing fp title alt bs ext) = do
+    immedPrevAnchor <- gets docxImmedPrevAnchor
+    case immedPrevAnchor of
+      Just prevAnchor -> do
+        unless inHdrBool
+          (modify $ \s -> s { docxAnchorMap = M.insert anchor prevAnchor anchorMap})
+        return mempty
+      Nothing -> do
+        let newAnchor =
+              if not inHdrBool && anchor `elem` M.elems anchorMap
+              then uniqueIdent [Str anchor] (Set.fromList $ M.elems anchorMap)
+              else anchor
+        unless inHdrBool
+          (modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap})
+        return $ spanWith (newAnchor, ["anchor"], []) mempty
+parPartToInlines' (Drawing fp title alt bs ext) = do
   (lift . lift) $ P.insertMedia fp Nothing bs
   return $ imageWith (extentToAttr ext) fp title $ text alt
-parPartToInlines Chart =
+parPartToInlines' Chart =
   return $ spanWith ("", ["chart"], []) $ text "[CHART]"
-parPartToInlines (InternalHyperLink anchor runs) = do
+parPartToInlines' (InternalHyperLink anchor runs) = do
   ils <- smushInlines <$> mapM runToInlines runs
   return $ link ('#' : anchor) "" ils
-parPartToInlines (ExternalHyperLink target runs) = do
+parPartToInlines' (ExternalHyperLink target runs) = do
   ils <- smushInlines <$> mapM runToInlines runs
   return $ link target "" ils
-parPartToInlines (PlainOMath exps) =
+parPartToInlines' (PlainOMath exps) =
   return $ math $ writeTeX exps
-parPartToInlines (SmartTag runs) = do
+parPartToInlines' (SmartTag runs) = do
   smushInlines <$> mapM runToInlines runs
 
 isAnchorSpan :: Inline -> Bool
@@ -532,16 +563,56 @@
       headerWith ("", delete style (pStyle pPr), []) n ils
   | otherwise = do
     ils <- (trimSps . smushInlines) <$> mapM parPartToInlines parparts
+    prevParaIls <- gets docxPrevPara
     dropIls <- gets docxDropCap
     let ils' = dropIls <> ils
     if dropCap pPr
       then do modify $ \s -> s { docxDropCap = ils' }
               return mempty
       else do modify $ \s -> s { docxDropCap = mempty }
+              let ils'' = prevParaIls <>
+                          (if isNull prevParaIls then mempty else space) <>
+                          ils'
               opts <- asks docxOptions
-              if isNull ils' && not (isEnabled Ext_empty_paragraphs opts)
-                 then return mempty
-                 else return $ parStyleToTransform pPr $ para ils'
+              case () of
+
+                _ | isNull ils'' && not (isEnabled Ext_empty_paragraphs opts) ->
+                    return mempty
+                _ | Just (TrackedChange Insertion _) <- pChange pPr
+                  , AcceptChanges <- readerTrackChanges opts -> do
+                      modify $ \s -> s {docxPrevPara = mempty}
+                      return $ parStyleToTransform pPr $ para ils''
+                _ | Just (TrackedChange Insertion _) <- pChange pPr
+                  , RejectChanges <- readerTrackChanges opts -> do
+                      modify $ \s -> s {docxPrevPara = ils''}
+                      return mempty
+                _ | Just (TrackedChange Insertion cInfo) <- pChange pPr
+                  , AllChanges <- readerTrackChanges opts
+                  , ChangeInfo _ cAuthor cDate <- cInfo -> do
+                      let attr = ("", ["paragraph-insertion"], [("author", cAuthor), ("date", cDate)])
+                          insertMark = spanWith attr mempty
+                      return $
+                        parStyleToTransform pPr $
+                        para $ ils'' <> insertMark
+                _ | Just (TrackedChange Deletion _) <- pChange pPr
+                  , AcceptChanges <- readerTrackChanges opts -> do
+                      modify $ \s -> s {docxPrevPara = ils''}
+                      return mempty
+                _ | Just (TrackedChange Deletion _) <- pChange pPr
+                  , RejectChanges <- readerTrackChanges opts -> do
+                      modify $ \s -> s {docxPrevPara = mempty}
+                      return $ parStyleToTransform pPr $ para ils''
+                _ | Just (TrackedChange Deletion cInfo) <- pChange pPr
+                  , AllChanges <- readerTrackChanges opts
+                  , ChangeInfo _ cAuthor cDate <- cInfo -> do
+                      let attr = ("", ["paragraph-deletion"], [("author", cAuthor), ("date", cDate)])
+                          insertMark = spanWith attr mempty
+                      return $
+                        parStyleToTransform pPr $
+                        para $ ils'' <> insertMark
+                _ | otherwise -> do
+                      modify $ \s -> s {docxPrevPara = mempty}
+                      return $ parStyleToTransform pPr $ para ils''
 bodyPartToBlocks (ListItem pPr numId lvl (Just levelInfo) parparts) = do
   -- We check whether this current numId has previously been used,
   -- since Docx expects us to pick up where we left off.
@@ -561,7 +632,7 @@
             ]
   modify $ \st -> st{ docxListState = M.insert (numId, lvl) start listState}
   blks <- bodyPartToBlocks (Paragraph pPr parparts)
-  return $ divWith ("", ["list-item"], kvs) blks 
+  return $ divWith ("", ["list-item"], kvs) blks
 bodyPartToBlocks (ListItem pPr _ _ _ parparts) =
   let pPr' = pPr {pStyle = "ListParagraph": pStyle pPr}
   in
@@ -603,21 +674,41 @@
 rewriteLink' :: PandocMonad m => Inline -> DocxContext m Inline
 rewriteLink' l@(Link attr ils ('#':target, title)) = do
   anchorMap <- gets docxAnchorMap
-  return $ case M.lookup target anchorMap of
-    Just newTarget -> Link attr ils ('#':newTarget, title)
-    Nothing        -> l
+  case M.lookup target anchorMap of
+    Just newTarget -> do
+      modify $ \s -> s{docxAnchorSet = Set.insert newTarget (docxAnchorSet s)}
+      return $ Link attr ils ('#':newTarget, title)
+    Nothing        -> do
+      modify $ \s -> s{docxAnchorSet = Set.insert target (docxAnchorSet s)}
+      return l
 rewriteLink' il = return il
 
 rewriteLinks :: PandocMonad m => [Block] -> DocxContext m [Block]
 rewriteLinks = mapM (walkM rewriteLink')
 
+removeOrphanAnchors'' :: PandocMonad m => Inline -> DocxContext m [Inline]
+removeOrphanAnchors'' s@(Span (ident, classes, _) ils)
+  | "anchor" `elem` classes = do
+      anchorSet <- gets docxAnchorSet
+      return $ if ident `Set.member` anchorSet
+               then [s]
+               else ils
+removeOrphanAnchors'' il = return [il]
+
+removeOrphanAnchors' :: PandocMonad m => [Inline] -> DocxContext m [Inline]
+removeOrphanAnchors' ils = liftM concat $ mapM removeOrphanAnchors'' ils
+
+removeOrphanAnchors :: PandocMonad m => [Block] -> DocxContext m [Block]
+removeOrphanAnchors = mapM (walkM removeOrphanAnchors')
+
 bodyToOutput :: PandocMonad m => Body -> DocxContext m (Meta, [Block])
 bodyToOutput (Body bps) = do
   let (metabps, blkbps) = sepBodyParts bps
   meta <- bodyPartsToMeta metabps
   blks <- smushBlocks <$> mapM bodyPartToBlocks blkbps
   blks' <- rewriteLinks $ blocksToDefinitions $ blocksToBullets $ toList blks
-  return (meta, blks')
+  blks'' <- removeOrphanAnchors blks'
+  return (meta, blks'')
 
 docxToOutput :: PandocMonad m
              => ReaderOptions
diff --git a/src/Text/Pandoc/Readers/Docx/Lists.hs b/src/Text/Pandoc/Readers/Docx/Lists.hs
--- a/src/Text/Pandoc/Readers/Docx/Lists.hs
+++ b/src/Text/Pandoc/Readers/Docx/Lists.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Jesse Rosenthal <jrosenthal@jhu.edu>
+Copyright (C) 2014-2018 Jesse Rosenthal <jrosenthal@jhu.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Docx.Lists
-   Copyright   : Copyright (C) 2014-2017 Jesse Rosenthal
+   Copyright   : Copyright (C) 2014-2018 Jesse Rosenthal
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Jesse Rosenthal <jrosenthal@jhu.edu>
diff --git a/src/Text/Pandoc/Readers/Docx/Parse.hs b/src/Text/Pandoc/Readers/Docx/Parse.hs
--- a/src/Text/Pandoc/Readers/Docx/Parse.hs
+++ b/src/Text/Pandoc/Readers/Docx/Parse.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE ViewPatterns      #-}
 
 {-
-Copyright (C) 2014-2017 Jesse Rosenthal <jrosenthal@jhu.edu>
+Copyright (C) 2014-2018 Jesse Rosenthal <jrosenthal@jhu.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
  Module : Text.Pandoc.Readers.Docx.Parse
- Copyright : Copyright (C) 2014-2017 Jesse Rosenthal
+ Copyright : Copyright (C) 2014-2018 Jesse Rosenthal
  License : GNU GPL, version 2 or above
 
  Maintainer : Jesse Rosenthal <jrosenthal@jhu.edu>
@@ -51,6 +51,9 @@
                                       , ParagraphStyle(..)
                                       , Row(..)
                                       , Cell(..)
+                                      , TrackedChange(..)
+                                      , ChangeType(..)
+                                      , ChangeInfo(..)
                                       , archiveToDocx
                                       , archiveToDocxWithWarnings
                                       ) where
@@ -118,17 +121,21 @@
   in
    concatMapM handler xs
 
-unwrapSDT :: NameSpaces -> Content -> Content
+unwrapSDT :: NameSpaces -> Content -> [Content]
 unwrapSDT ns (Elem element)
   | isElem ns "w" "sdt" element
   , Just sdtContent <- findChildByName ns "w" "sdtContent" element
-  , child : _    <- elChildren sdtContent
-  = Elem child
-unwrapSDT _ content = content
+  = map Elem $ elChildren sdtContent
+unwrapSDT _ content = [content]
 
+unwrapSDTchild :: NameSpaces -> Content -> Content
+unwrapSDTchild ns (Elem element) =
+  Elem $ element { elContent = concatMap (unwrapSDT ns) (elContent element) }
+unwrapSDTchild _ content = content
+
 walkDocument' :: NameSpaces -> XMLC.Cursor -> XMLC.Cursor
 walkDocument' ns cur =
-  let modifiedCur = XMLC.modifyContent (unwrapSDT ns) cur
+  let modifiedCur = XMLC.modifyContent (unwrapSDTchild ns) cur
   in
     case XMLC.nextDF modifiedCur of
       Just cur' -> walkDocument' ns cur'
@@ -194,12 +201,22 @@
                                      , hangingParIndent :: Maybe Integer}
                       deriving Show
 
+data ChangeType = Insertion | Deletion
+                deriving Show
+
+data ChangeInfo = ChangeInfo ChangeId Author ChangeDate
+                deriving Show
+
+data TrackedChange = TrackedChange ChangeType ChangeInfo
+                   deriving Show
+
 data ParagraphStyle = ParagraphStyle { pStyle      :: [String]
                                      , indentation :: Maybe ParIndentation
                                      , dropCap     :: Bool
                                      , pHeading    :: Maybe (String, Int)
                                      , pNumInfo    :: Maybe (String, String)
                                      , pBlockQuote :: Maybe Bool
+                                     , pChange     :: Maybe TrackedChange
                                      }
                       deriving Show
 
@@ -210,6 +227,7 @@
                                        , pHeading    = Nothing
                                        , pNumInfo    = Nothing
                                        , pBlockQuote = Nothing
+                                       , pChange     = Nothing
                                        }
 
 
@@ -237,8 +255,7 @@
 type Extent = Maybe (Double, Double)
 
 data ParPart = PlainRun Run
-             | Insertion ChangeId Author ChangeDate [Run]
-             | Deletion ChangeId Author ChangeDate [Run]
+             | ChangedRuns TrackedChange [Run]
              | CommentStart CommentId Author CommentDate [BodyPart]
              | CommentEnd CommentId
              | BookMark BookMarkId Anchor
@@ -723,19 +740,9 @@
   | isElem ns "w" "r" element =
     elemToRun ns element >>= (\r -> return $ PlainRun r)
 elemToParPart ns element
-  | isElem ns "w" "ins" element || isElem ns "w" "moveTo" element
-  , Just cId <- findAttrByName ns "w" "id" element
-  , Just cAuthor <- findAttrByName ns "w" "author" element
-  , Just cDate <- findAttrByName ns "w" "date" element = do
-    runs <- mapD (elemToRun ns) (elChildren element)
-    return $ Insertion cId cAuthor cDate runs
-elemToParPart ns element
-  | isElem ns "w" "del" element || isElem ns "w" "moveFrom" element
-  , Just cId <- findAttrByName ns "w" "id" element
-  , Just cAuthor <- findAttrByName ns "w" "author" element
-  , Just cDate <- findAttrByName ns "w" "date" element = do
-    runs <- mapD (elemToRun ns) (elChildren element)
-    return $ Deletion cId cAuthor cDate runs
+  | Just change <- getTrackedChange ns element = do
+      runs <- mapD (elemToRun ns) (elChildren element)
+      return $ ChangedRuns change runs
 elemToParPart ns element
   | isElem ns "w" "smartTag" element = do
     runs <- mapD (elemToRun ns) (elChildren element)
@@ -886,6 +893,21 @@
            = Just y
 getParStyleField _ _ _ = Nothing
 
+getTrackedChange :: NameSpaces -> Element -> Maybe TrackedChange
+getTrackedChange ns element
+  | isElem ns "w" "ins" element || isElem ns "w" "moveTo" element
+  , Just cId <- findAttrByName ns "w" "id" element
+  , Just cAuthor <- findAttrByName ns "w" "author" element
+  , Just cDate <- findAttrByName ns "w" "date" element =
+      Just $ TrackedChange Insertion (ChangeInfo cId cAuthor cDate)
+getTrackedChange ns element
+  | isElem ns "w" "del" element || isElem ns "w" "moveFrom" element
+  , Just cId <- findAttrByName ns "w" "id" element
+  , Just cAuthor <- findAttrByName ns "w" "author" element
+  , Just cDate <- findAttrByName ns "w" "date" element =
+      Just $ TrackedChange Deletion (ChangeInfo cId cAuthor cDate)
+getTrackedChange _ _ = Nothing
+
 elemToParagraphStyle :: NameSpaces -> Element -> ParStyleMap -> ParagraphStyle
 elemToParagraphStyle ns element sty
   | Just pPr <- findChildByName ns "w" "pPr" element =
@@ -909,6 +931,13 @@
       , pHeading = getParStyleField headingLev sty style
       , pNumInfo = getParStyleField numInfo sty style
       , pBlockQuote = getParStyleField isBlockQuote sty style
+      , pChange     = findChildByName ns "w" "rPr" pPr >>=
+                      filterChild (\e -> isElem ns "w" "ins" e ||
+                                         isElem ns "w" "moveTo" e ||
+                                         isElem ns "w" "del" e ||
+                                         isElem ns "w" "moveFrom" e
+                                  ) >>=
+                      getTrackedChange ns
       }
 elemToParagraphStyle _ _ _ =  defaultParagraphStyle
 
diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs
--- a/src/Text/Pandoc/Readers/HTML.hs
+++ b/src/Text/Pandoc/Readers/HTML.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE OverloadedStrings     #-}
 {-# LANGUAGE ViewPatterns          #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.HTML
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE PatternGuards         #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.LaTeX
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
@@ -280,12 +280,12 @@
 rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
                => ParserT String s m String
 rawLaTeXInline = do
-  lookAhead (try (char '\\' >> letter) <|> char '$')
+  lookAhead (try (char '\\' >> letter))
   rawLaTeXParser (inlineEnvironment <|> inlineCommand') >>= applyMacros . snd
 
 inlineCommand :: PandocMonad m => ParserT String ParserState m Inlines
 inlineCommand = do
-  lookAhead (try (char '\\' >> letter) <|> char '$')
+  lookAhead (try (char '\\' >> letter))
   fst <$> rawLaTeXParser (inlineEnvironment <|> inlineCommand')
 
 tokenize :: SourceName -> Text -> [Tok]
diff --git a/src/Text/Pandoc/Readers/LaTeX/Types.hs b/src/Text/Pandoc/Readers/LaTeX/Types.hs
--- a/src/Text/Pandoc/Readers/LaTeX/Types.hs
+++ b/src/Text/Pandoc/Readers/LaTeX/Types.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2017-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.LaTeX.Types
-   Copyright   : Copyright (C) 2017 John MacFarlane
+   Copyright   : Copyright (C) 2017-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Markdown
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
@@ -148,25 +148,19 @@
 -- | Parse a sequence of inline elements between square brackets,
 -- including inlines between balanced pairs of square brackets.
 inlinesInBalancedBrackets :: PandocMonad m => MarkdownParser m (F Inlines)
-inlinesInBalancedBrackets = do
-  char '['
-  pos <- getPosition
-  (_, raw) <- withRaw $ charsInBalancedBrackets 1
-  guard $ not $ null raw
-  parseFromString' (setPosition pos >>
-                   trimInlinesF <$> inlines) (init raw)
-
-charsInBalancedBrackets :: PandocMonad m => Int -> MarkdownParser m ()
-charsInBalancedBrackets 0 = return ()
-charsInBalancedBrackets openBrackets =
-      (char '[' >> charsInBalancedBrackets (openBrackets + 1))
-  <|> (char ']' >> charsInBalancedBrackets (openBrackets - 1))
-  <|> ((  (() <$ code)
-     <|> (() <$ escapedChar')
-     <|> (newline >> notFollowedBy blankline)
-     <|> skipMany1 (noneOf "[]`\n\\")
-     <|> (() <$ count 1 (oneOf "`\\"))
-      ) >> charsInBalancedBrackets openBrackets)
+inlinesInBalancedBrackets = try $ char '[' >> go 1
+  where go :: PandocMonad m => Int -> MarkdownParser m (F Inlines)
+        go 0 = return mempty
+        go openBrackets =
+                    (mappend <$> (bracketedSpan <|> link <|> image) <*>
+                         go openBrackets)
+                   <|> ((if openBrackets > 1
+                            then (return (B.str "]") <>)
+                            else id) <$>
+                             (char ']' >> go (openBrackets - 1)))
+                   <|> ((return (B.str "[") <>) <$>
+                             (char '[' >> go (openBrackets + 1)))
+                   <|> (mappend <$> inline <*> go openBrackets)
 
 --
 -- document structure
@@ -1120,6 +1114,7 @@
 rawTeXBlock :: PandocMonad m => MarkdownParser m (F Blocks)
 rawTeXBlock = do
   guardEnabled Ext_raw_tex
+  lookAhead $ try $ char '\\' >> letter
   result <- (B.rawBlock "context" . trim . concat <$>
                 many1 ((++) <$> (rawConTeXtEnvironment <|> conTeXtCommand)
                             <*> (blanklines <|> many spaceChar)))
@@ -1906,7 +1901,7 @@
 rawLaTeXInline' :: PandocMonad m => MarkdownParser m (F Inlines)
 rawLaTeXInline' = try $ do
   guardEnabled Ext_raw_tex
-  lookAhead (char '\\')
+  lookAhead $ try $ char '\\' >> letter
   notFollowedBy' rawConTeXtEnvironment
   s <- rawLaTeXInline
   return $ return $ B.rawInline "tex" s -- "tex" because it might be context
diff --git a/src/Text/Pandoc/Readers/MediaWiki.hs b/src/Text/Pandoc/Readers/MediaWiki.hs
--- a/src/Text/Pandoc/Readers/MediaWiki.hs
+++ b/src/Text/Pandoc/Readers/MediaWiki.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE TypeSynonymInstances #-}
 -- RelaxedPolyRec needed for inlinesBetween on GHC < 7
 {-
-  Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+  Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.MediaWiki
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/Muse.hs b/src/Text/Pandoc/Readers/Muse.hs
--- a/src/Text/Pandoc/Readers/Muse.hs
+++ b/src/Text/Pandoc/Readers/Muse.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE FlexibleContexts      #-}
 {-
-  Copyright (C) 2017 Alexander Krotov <ilabdsf@gmail.com>
+  Copyright (C) 2017-2018 Alexander Krotov <ilabdsf@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Muse
-   Copyright   : Copyright (C) 2017 Alexander Krotov
+   Copyright   : Copyright (C) 2017-2018 Alexander Krotov
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Alexander Krotov <ilabdsf@gmail.com>
@@ -179,7 +179,9 @@
 directive = do
   ext <- getOption readerExtensions
   (key, value) <- if extensionEnabled Ext_amuse ext then parseAmuseDirective else parseEmacsDirective
-  updateState $ \st -> st { stateMeta' = B.setMeta key <$> value <*> stateMeta' st }
+  updateState $ \st -> st { stateMeta' = B.setMeta (translateKey key) <$> value <*> stateMeta' st }
+  where translateKey "cover" = "cover-image"
+        translateKey x = x
 
 --
 -- block parsers
diff --git a/src/Text/Pandoc/Readers/Native.hs b/src/Text/Pandoc/Readers/Native.hs
--- a/src/Text/Pandoc/Readers/Native.hs
+++ b/src/Text/Pandoc/Readers/Native.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2011-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2011-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Native
-   Copyright   : Copyright (C) 2011-2017 John MacFarlane
+   Copyright   : Copyright (C) 2011-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/BlockStarts.hs b/src/Text/Pandoc/Readers/Org/BlockStarts.hs
--- a/src/Text/Pandoc/Readers/Org/BlockStarts.hs
+++ b/src/Text/Pandoc/Readers/Org/BlockStarts.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.BlockStarts
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/Blocks.hs b/src/Text/Pandoc/Readers/Org/Blocks.hs
--- a/src/Text/Pandoc/Readers/Org/Blocks.hs
+++ b/src/Text/Pandoc/Readers/Org/Blocks.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 {-# LANGUAGE RecordWildCards  #-}
 {- |
    Module      : Text.Pandoc.Readers.Org.Blocks
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/DocumentTree.hs b/src/Text/Pandoc/Readers/Org/DocumentTree.hs
--- a/src/Text/Pandoc/Readers/Org/DocumentTree.hs
+++ b/src/Text/Pandoc/Readers/Org/DocumentTree.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 {-# LANGUAGE ViewPatterns     #-}
 {- |
    Module      : Text.Pandoc.Readers.Org.DocumentTree
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/ExportSettings.hs b/src/Text/Pandoc/Readers/Org/ExportSettings.hs
--- a/src/Text/Pandoc/Readers/Org/ExportSettings.hs
+++ b/src/Text/Pandoc/Readers/Org/ExportSettings.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2016-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.ExportSettings
-   Copyright   : © 2016–2017 Albert Krewinkel
+   Copyright   : © 2016–2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/Inlines.hs b/src/Text/Pandoc/Readers/Org/Inlines.hs
--- a/src/Text/Pandoc/Readers/Org/Inlines.hs
+++ b/src/Text/Pandoc/Readers/Org/Inlines.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.Inlines
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/Meta.hs b/src/Text/Pandoc/Readers/Org/Meta.hs
--- a/src/Text/Pandoc/Readers/Org/Meta.hs
+++ b/src/Text/Pandoc/Readers/Org/Meta.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TupleSections    #-}
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.Meta
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/ParserState.hs b/src/Text/Pandoc/Readers/Org/ParserState.hs
--- a/src/Text/Pandoc/Readers/Org/ParserState.hs
+++ b/src/Text/Pandoc/Readers/Org/ParserState.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.ParserState
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/Parsing.hs b/src/Text/Pandoc/Readers/Org/Parsing.hs
--- a/src/Text/Pandoc/Readers/Org/Parsing.hs
+++ b/src/Text/Pandoc/Readers/Org/Parsing.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.Parsing
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/Org/Shared.hs b/src/Text/Pandoc/Readers/Org/Shared.hs
--- a/src/Text/Pandoc/Readers/Org/Shared.hs
+++ b/src/Text/Pandoc/Readers/Org/Shared.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2014-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Org.Shared
-   Copyright   : Copyright (C) 2014-2017 Albert Krewinkel
+   Copyright   : Copyright (C) 2014-2018 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.RST
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs
--- a/src/Text/Pandoc/Readers/Textile.hs
+++ b/src/Text/Pandoc/Readers/Textile.hs
@@ -1,6 +1,6 @@
 {-
 Copyright (C) 2010-2012 Paul Rivier <paul*rivier#demotera*com> | tr '*#' '.@'
-              2010-2017 John MacFarlane
+              2010-2018 John MacFarlane
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 {- |
    Module      : Text.Pandoc.Readers.Textile
    Copyright   : Copyright (C) 2010-2012 Paul Rivier
-                               2010-2017 John MacFarlane
+                               2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Paul Rivier <paul*rivier#demotera*com>
diff --git a/src/Text/Pandoc/Readers/Vimwiki.hs b/src/Text/Pandoc/Readers/Vimwiki.hs
--- a/src/Text/Pandoc/Readers/Vimwiki.hs
+++ b/src/Text/Pandoc/Readers/Vimwiki.hs
@@ -1,5 +1,5 @@
 {-
-  Copyright (C) 2017 Yuchen Pei <me@ypei.me>
+  Copyright (C) 2017-2018 Yuchen Pei <me@ypei.me>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Readers.Vimwiki
-   Copyright   : Copyright (C) 2017 Yuchen Pei
+   Copyright   : Copyright (C) 2017-2018 Yuchen Pei
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Yuchen Pei <me@ypei.me>
diff --git a/src/Text/Pandoc/SelfContained.hs b/src/Text/Pandoc/SelfContained.hs
--- a/src/Text/Pandoc/SelfContained.hs
+++ b/src/Text/Pandoc/SelfContained.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2011-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2011-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.SelfContained
-   Copyright   : Copyright (C) 2011-2017 John MacFarlane
+   Copyright   : Copyright (C) 2011-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs
--- a/src/Text/Pandoc/Shared.hs
+++ b/src/Text/Pandoc/Shared.hs
@@ -6,7 +6,7 @@
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE ViewPatterns          #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 
 {- |
    Module      : Text.Pandoc.Shared
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Slides.hs b/src/Text/Pandoc/Slides.hs
--- a/src/Text/Pandoc/Slides.hs
+++ b/src/Text/Pandoc/Slides.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Slides
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Templates.hs b/src/Text/Pandoc/Templates.hs
--- a/src/Text/Pandoc/Templates.hs
+++ b/src/Text/Pandoc/Templates.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE OverloadedStrings    #-}
 {-# LANGUAGE TypeSynonymInstances #-}
 {-
-Copyright (C) 2009-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2009-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Templates
-   Copyright   : Copyright (C) 2009-2017 John MacFarlane
+   Copyright   : Copyright (C) 2009-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Translations.hs b/src/Text/Pandoc/Translations.hs
--- a/src/Text/Pandoc/Translations.hs
+++ b/src/Text/Pandoc/Translations.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-
-Copyright (C) 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2017-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Translations
-   Copyright   : Copyright (C) 2017 John MacFarlane
+   Copyright   : Copyright (C) 2017-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/UTF8.hs b/src/Text/Pandoc/UTF8.hs
--- a/src/Text/Pandoc/UTF8.hs
+++ b/src/Text/Pandoc/UTF8.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2010-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2010-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.UTF8
-   Copyright   : Copyright (C) 2010-2017 John MacFarlane
+   Copyright   : Copyright (C) 2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/UUID.hs b/src/Text/Pandoc/UUID.hs
--- a/src/Text/Pandoc/UUID.hs
+++ b/src/Text/Pandoc/UUID.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2010-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2010-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.UUID
-   Copyright   : Copyright (C) 2010-2017 John MacFarlane
+   Copyright   : Copyright (C) 2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers.hs b/src/Text/Pandoc/Writers.hs
--- a/src/Text/Pandoc/Writers.hs
+++ b/src/Text/Pandoc/Writers.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/AsciiDoc.hs b/src/Text/Pandoc/Writers/AsciiDoc.hs
--- a/src/Text/Pandoc/Writers/AsciiDoc.hs
+++ b/src/Text/Pandoc/Writers/AsciiDoc.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.AsciiDoc
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/CommonMark.hs b/src/Text/Pandoc/Writers/CommonMark.hs
--- a/src/Text/Pandoc/Writers/CommonMark.hs
+++ b/src/Text/Pandoc/Writers/CommonMark.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2015-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2015-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.CommonMark
-   Copyright   : Copyright (C) 2015-2017 John MacFarlane
+   Copyright   : Copyright (C) 2015-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/ConTeXt.hs b/src/Text/Pandoc/Writers/ConTeXt.hs
--- a/src/Text/Pandoc/Writers/ConTeXt.hs
+++ b/src/Text/Pandoc/Writers/ConTeXt.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2007-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2007-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.ConTeXt
-   Copyright   : Copyright (C) 2007-2017 John MacFarlane
+   Copyright   : Copyright (C) 2007-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Custom.hs b/src/Text/Pandoc/Writers/Custom.hs
--- a/src/Text/Pandoc/Writers/Custom.hs
+++ b/src/Text/Pandoc/Writers/Custom.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE DeriveDataTypeable   #-}
 {-# LANGUAGE FlexibleInstances    #-}
-{- Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+{- Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Custom
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Docbook.hs b/src/Text/Pandoc/Writers/Docbook.hs
--- a/src/Text/Pandoc/Writers/Docbook.hs
+++ b/src/Text/Pandoc/Writers/Docbook.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards     #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Docbook
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
--- a/src/Text/Pandoc/Writers/Docx.hs
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -4,7 +4,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE ViewPatterns        #-}
 {-
-Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Docx
-   Copyright   : Copyright (C) 2012-2017 John MacFarlane
+   Copyright   : Copyright (C) 2012-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
@@ -763,9 +763,7 @@
 -- OpenXML elements (the main document and footnotes).
 writeOpenXML :: (PandocMonad m) => WriterOptions -> Pandoc -> WS m ([Element], [Element],[Element])
 writeOpenXML opts (Pandoc meta blocks) = do
-  let tit = docTitle meta ++ case lookupMeta "subtitle" meta of
-                                  Just (MetaBlocks [Plain xs]) -> LineBreak : xs
-                                  _ -> []
+  let tit = docTitle meta
   let auths = docAuthors meta
   let dat = docDate meta
   let abstract' = case lookupMeta "abstract" meta of
@@ -983,7 +981,7 @@
       ( mknode "w:tblPr" []
         (   mknode "w:tblStyle" [("w:val","Table")] () :
             mknode "w:tblW" [("w:type", "pct"), ("w:w", show rowwidth)] () :
-            mknode "w:tblLook" [("w:firstRow","1") | hasHeader ] () :
+            mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0") ] () :
           [ mknode "w:tblCaption" [("w:val", captionStr)] ()
           | not (null caption) ] )
       : mknode "w:tblGrid" []
@@ -1134,7 +1132,7 @@
                       modify $ \s ->
                         s{stDynamicTextProps = Set.insert sty
                               (stDynamicTextProps s)}
-                      return $ withTextProp (rCustomStyle sty)
+                      return $ withTextPropM (rStyleM sty)
                    _ -> return id
   let dirmod = case lookup "dir" kvs of
                  Just "rtl" -> local (\env -> env { envRTL = True })
diff --git a/src/Text/Pandoc/Writers/DokuWiki.hs b/src/Text/Pandoc/Writers/DokuWiki.hs
--- a/src/Text/Pandoc/Writers/DokuWiki.hs
+++ b/src/Text/Pandoc/Writers/DokuWiki.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.DokuWiki
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Clare Macrae <clare.macrae@googlemail.com>
diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs
--- a/src/Text/Pandoc/Writers/EPUB.hs
+++ b/src/Text/Pandoc/Writers/EPUB.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE PatternGuards       #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2010-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2010-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.EPUB
-   Copyright   : Copyright (C) 2010-2017 John MacFarlane
+   Copyright   : Copyright (C) 2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/FB2.hs b/src/Text/Pandoc/Writers/FB2.hs
--- a/src/Text/Pandoc/Writers/FB2.hs
+++ b/src/Text/Pandoc/Writers/FB2.hs
@@ -2,7 +2,7 @@
 
 {-
 Copyright (c) 2011-2012 Sergey Astanin
-              2012-2017 John MacFarlane
+              2012-2018 John MacFarlane
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 {- |
 Module      : Text.Pandoc.Writers.FB2
 Copyright   : Copyright (C) 2011-2012 Sergey Astanin
-                            2012-2017 John MacFarlane
+                            2012-2018 John MacFarlane
 License     : GNU GPL, version 2 or above
 
 Maintainer  : John MacFarlane
diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs
--- a/src/Text/Pandoc/Writers/HTML.hs
+++ b/src/Text/Pandoc/Writers/HTML.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE ViewPatterns        #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.HTML
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Haddock.hs b/src/Text/Pandoc/Writers/Haddock.hs
--- a/src/Text/Pandoc/Writers/Haddock.hs
+++ b/src/Text/Pandoc/Writers/Haddock.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections       #-}
 {-
-Copyright (C) 2014-2015, 2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2014-2015, 2017-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/src/Text/Pandoc/Writers/ICML.hs b/src/Text/Pandoc/Writers/ICML.hs
--- a/src/Text/Pandoc/Writers/ICML.hs
+++ b/src/Text/Pandoc/Writers/ICML.hs
@@ -4,7 +4,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.ICML
-   Copyright   : Copyright (C) 2013-2017 github.com/mb21
+   Copyright   : Copyright (C) 2013-2018 github.com/mb21
    License     : GNU GPL, version 2 or above
 
    Stability   : alpha
diff --git a/src/Text/Pandoc/Writers/JATS.hs b/src/Text/Pandoc/Writers/JATS.hs
--- a/src/Text/Pandoc/Writers/JATS.hs
+++ b/src/Text/Pandoc/Writers/JATS.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 -}
 {- |
    Module      : Text.Pandoc.Writers.JATS
-   Copyright   : Copyright (C) 2017 John MacFarlane
+   Copyright   : Copyright (C) 2017-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE PatternGuards       #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.LaTeX
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Man.hs b/src/Text/Pandoc/Writers/Man.hs
--- a/src/Text/Pandoc/Writers/Man.hs
+++ b/src/Text/Pandoc/Writers/Man.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2007-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2007-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Man
-   Copyright   : Copyright (C) 2007-2017 John MacFarlane
+   Copyright   : Copyright (C) 2007-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs
--- a/src/Text/Pandoc/Writers/Markdown.hs
+++ b/src/Text/Pandoc/Writers/Markdown.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections       #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Markdown
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/MediaWiki.hs b/src/Text/Pandoc/Writers/MediaWiki.hs
--- a/src/Text/Pandoc/Writers/MediaWiki.hs
+++ b/src/Text/Pandoc/Writers/MediaWiki.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.MediaWiki
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Ms.hs b/src/Text/Pandoc/Writers/Ms.hs
--- a/src/Text/Pandoc/Writers/Ms.hs
+++ b/src/Text/Pandoc/Writers/Ms.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2007-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2007-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Ms
-   Copyright   : Copyright (C) 2007-2017 John MacFarlane
+   Copyright   : Copyright (C) 2007-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Muse.hs b/src/Text/Pandoc/Writers/Muse.hs
--- a/src/Text/Pandoc/Writers/Muse.hs
+++ b/src/Text/Pandoc/Writers/Muse.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2017 Alexander Krotov <ilabdsf@gmail.com>
+Copyright (C) 2017-2018 Alexander Krotov <ilabdsf@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Muse
-   Copyright   : Copyright (C) 2017 Alexander Krotov
+   Copyright   : Copyright (C) 2017-2018 Alexander Krotov
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Alexander Krotov <ilabdsf@gmail.com>
@@ -377,7 +377,7 @@
              return $ "[[" <> text (escapeLink x) <> "]]"
         _ -> do contents <- inlineListToMuse txt
                 return $ "[[" <> text (escapeLink src) <> "][" <> contents <> "]]"
-  where escapeLink lnk = escapeURI (if isImageUrl lnk then "URL:" ++ lnk else lnk)
+  where escapeLink lnk = if isImageUrl lnk then "URL:" ++ lnk else lnk
         -- Taken from muse-image-regexp defined in Emacs Muse file lisp/muse-regexps.el
         imageExtensions = [".eps", ".gif", ".jpg", ".jpeg", ".pbm", ".png", ".tiff", ".xbm", ".xpm"]
         isImageUrl = (`elem` imageExtensions) . takeExtension
diff --git a/src/Text/Pandoc/Writers/Native.hs b/src/Text/Pandoc/Writers/Native.hs
--- a/src/Text/Pandoc/Writers/Native.hs
+++ b/src/Text/Pandoc/Writers/Native.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Native
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/ODT.hs b/src/Text/Pandoc/Writers/ODT.hs
--- a/src/Text/Pandoc/Writers/ODT.hs
+++ b/src/Text/Pandoc/Writers/ODT.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.ODT
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
@@ -56,7 +56,7 @@
 import Text.TeXMath
 import Text.XML.Light
 
-data ODTState = ODTState { stEntries :: [Entry]
+newtype ODTState = ODTState { stEntries :: [Entry]
                          }
 
 type O m = StateT ODTState m
@@ -224,17 +224,39 @@
          let dirname = "Formula-" ++ show (length entries) ++ "/"
          let fname = dirname ++ "content.xml"
          let entry = toEntry fname epochtime (fromStringLazy mathml)
-         modify $ \st -> st{ stEntries = entry : entries }
+         let fname' = dirname ++ "settings.xml"
+         let entry' = toEntry fname' epochtime $ documentSettings (t == InlineMath)
+         modify $ \st -> st{ stEntries = entry' : (entry : entries) }
          return $ RawInline (Format "opendocument") $ render Nothing $
-           inTags False "draw:frame" [("text:anchor-type",
-                                       if t == DisplayMath
-                                          then "paragraph"
-                                          else "as-char")
-                                     ,("style:vertical-pos", "middle")
-                                     ,("style:vertical-rel", "text")] $
+           inTags False "draw:frame" (if t == DisplayMath
+                                      then [("draw:style-name","fr2")
+                                           -- `draw:frame` does not support either
+                                           -- `style:vertical-pos` or `style:vertical-rel`,
+                                           -- therefore those attributes must go into the
+                                           -- `style:style` element
+                                           ,("text:anchor-type","paragraph")]
+                                      else [("draw:style-name","fr1")
+                                           ,("text:anchor-type","as-char")]) $
              selfClosingTag "draw:object" [("xlink:href", dirname)
                                         , ("xlink:type", "simple")
                                         , ("xlink:show", "embed")
                                         , ("xlink:actuate", "onLoad")]
 
 transformPicMath _ x = return x
+
+documentSettings :: Bool -> B.ByteString
+documentSettings isTextMode = fromStringLazy $ render Nothing
+    $ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+    $$
+    (inTags True "office:document-settings"
+      [("xmlns:office","urn:oasis:names:tc:opendocument:xmlns:office:1.0")
+      ,("xmlns:xlink","http://www.w3.org/1999/xlink")
+      ,("xmlns:config","urn:oasis:names:tc:opendocument:xmlns:config:1.0")
+      ,("xmlns:ooo","http://openoffice.org/2004/office")
+      ,("office:version","1.2")] $
+       inTagsSimple "office:settings" $
+         inTags False "config:config-item-set"
+           [("config:name", "ooo:configuration-settings")] $
+           inTags False "config:config-item" [("config:name", "IsTextMode")
+                                             ,("config:type", "boolean")] $
+                                              text $ if isTextMode then "true" else "false")
diff --git a/src/Text/Pandoc/Writers/OPML.hs b/src/Text/Pandoc/Writers/OPML.hs
--- a/src/Text/Pandoc/Writers/OPML.hs
+++ b/src/Text/Pandoc/Writers/OPML.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-
-Copyright (C) 2013-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2013-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.OPML
-   Copyright   : Copyright (C) 2013-2017 John MacFarlane
+   Copyright   : Copyright (C) 2013-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/OpenDocument.hs b/src/Text/Pandoc/Writers/OpenDocument.hs
--- a/src/Text/Pandoc/Writers/OpenDocument.hs
+++ b/src/Text/Pandoc/Writers/OpenDocument.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards     #-}
 {-
-Copyright (C) 2008-2017 Andrea Rossato <andrea.rossato@ing.unitn.it>
+Copyright (C) 2008-2018 Andrea Rossato <andrea.rossato@ing.unitn.it>
                         and John MacFarlane.
 
 This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.OpenDocument
-   Copyright   : Copyright (C) 2008-2017 Andrea Rossato and John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 Andrea Rossato and John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Andrea Rossato <andrea.rossato@ing.unitn.it>
@@ -173,6 +173,24 @@
               return $ inTags False
                   "text:span" [("text:style-name",styleName)] d
 
+formulaStyles :: [Doc]
+formulaStyles = [formulaStyle InlineMath, formulaStyle DisplayMath]
+
+formulaStyle :: MathType -> Doc
+formulaStyle mt = inTags False "style:style"
+  [("style:name", if mt == InlineMath then "fr1" else "fr2")
+  ,("style:family", "graphic")
+  ,("style:parent-style-name", "Formula")]
+  $ selfClosingTag "style:graphic-properties" $ if mt == InlineMath then
+                                                  [("style:vertical-pos", "middle")
+                                                  ,("style:vertical-rel", "text")]
+                                                else
+                                                  [("style:vertical-pos",   "middle")
+                                                  ,("style:vertical-rel",   "paragraph-content")
+                                                  ,("style:horizontal-pos", "center")
+                                                  ,("style:horizontal-rel", "paragraph-content")
+                                                  ,("style:wrap",           "none")]
+
 inHeaderTags :: PandocMonad m => Int -> Doc -> OD m Doc
 inHeaderTags i d =
   return $ inTags False "text:h" [ ("text:style-name", "Heading_20_" ++ show i)
@@ -211,7 +229,7 @@
                   meta
            b <- render' `fmap` blocksToOpenDocument opts blocks
            return (b, m)
-  let styles   = stTableStyles s ++ stParaStyles s ++
+  let styles   = stTableStyles s ++ stParaStyles s ++ formulaStyles ++
                      map snd (sortBy (flip (comparing fst)) (
                         Map.elems (stTextStyles s)))
       listStyle (n,l) = inTags True "text:list-style"
diff --git a/src/Text/Pandoc/Writers/Org.hs b/src/Text/Pandoc/Writers/Org.hs
--- a/src/Text/Pandoc/Writers/Org.hs
+++ b/src/Text/Pandoc/Writers/Org.hs
@@ -1,8 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
 Copyright (C) 2010-2015 Puneeth Chaganti <punchagan@gmail.com>
-              2010-2017 John MacFarlane <jgm@berkeley.edu>
-              2016-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+              2010-2018 John MacFarlane <jgm@berkeley.edu>
+              2016-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@
 {- |
    Module      : Text.Pandoc.Writers.Org
   Copyright    : © 2010-2015 Puneeth Chaganti <punchagan@gmail.com>
-                   2010-2017 John MacFarlane <jgm@berkeley.edu>
-                   2016-2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
+                   2010-2018 John MacFarlane <jgm@berkeley.edu>
+                   2016-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
diff --git a/src/Text/Pandoc/Writers/Powerpoint.hs b/src/Text/Pandoc/Writers/Powerpoint.hs
--- a/src/Text/Pandoc/Writers/Powerpoint.hs
+++ b/src/Text/Pandoc/Writers/Powerpoint.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE PatternGuards, MultiWayIf, OverloadedStrings #-}
 
 {-
-Copyright (C) 2017 Jesse Rosenthal <jrosenthal@jhu.edu>
+Copyright (C) 2017-2018 Jesse Rosenthal <jrosenthal@jhu.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Powerpoint
-   Copyright   : Copyright (C) 2017 Jesse Rosenthal
+   Copyright   : Copyright (C) 2017-2018 Jesse Rosenthal
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Jesse Rosenthal <jrosenthal@jhu.edu>
@@ -37,28 +37,27 @@
 import Control.Monad.State
 import Codec.Archive.Zip
 import Data.List (intercalate, stripPrefix, isPrefixOf, nub)
--- import Control.Monad (mplus)
 import Data.Default
 import Data.Time.Clock (UTCTime)
 import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds, posixSecondsToUTCTime)
 import System.FilePath.Posix (splitDirectories, splitExtension)
 import Text.XML.Light
+import qualified Text.XML.Light.Cursor as XMLC
 import Text.Pandoc.Definition
 import qualified Text.Pandoc.UTF8 as UTF8
 import Text.Pandoc.Class (PandocMonad)
 import Text.Pandoc.Error (PandocError(..))
+import Text.Pandoc.Slides (getSlideLevel)
 import qualified Text.Pandoc.Class as P
 import Text.Pandoc.Options
 import Text.Pandoc.MIME
 import Text.Pandoc.Logging
 import qualified Data.ByteString.Lazy as BL
--- import qualified Data.ByteString.Lazy.Char8 as BL8
--- import qualified Text.Pandoc.UTF8 as UTF8
 import Text.Pandoc.Walk
 import Text.Pandoc.Writers.Shared (fixDisplayMath)
 import Text.Pandoc.Writers.OOXML
 import qualified Data.Map as M
-import Data.Maybe (mapMaybe, listToMaybe)
+import Data.Maybe (mapMaybe, listToMaybe, maybeToList)
 import Text.Pandoc.ImageSize
 import Control.Applicative ((<|>))
 
@@ -88,7 +87,7 @@
                 , envOpts = opts
                 , envSlideLevel = case writerSlideLevel opts of
                                     Just n -> n
-                                    Nothing -> 2
+                                    Nothing -> getSlideLevel blks'
                 }
   runP env def $ do pres <- blocksToPresentation blks'
                     archv <- presentationToArchive pres
@@ -195,12 +194,16 @@
            | ContentSlide { contentSlideHeader :: [ParaElem]
                           , contentSlideContent :: [Shape]
                           }
+           | TwoColumnSlide { twoColumnSlideHeader :: [ParaElem]
+                            , twoColumnSlideLeft   :: [Shape]
+                            , twoColumnSlideRight  :: [Shape]
+                            }
            deriving (Show, Eq)
 
 data SlideElement = SlideElement Pixels Pixels Pixels Pixels Shape
   deriving (Show, Eq)
 
-data Shape = Pic FilePath Text.Pandoc.Definition.Attr [ParaElem]
+data Shape = Pic PicProps FilePath Text.Pandoc.Definition.Attr [ParaElem]
            | GraphicFrame [Graphic] [ParaElem]
            | TextBox [Paragraph]
   deriving (Show, Eq)
@@ -224,20 +227,6 @@
 data HeaderType = TitleHeader | SlideHeader | InternalHeader Int
                 deriving (Show, Eq)
 
--- type StartingAt = Int
-
--- data AutoNumType = ArabicNum
---                  | AlphaUpperNum
---                  | AlphaLowerNum
---                  | RomanUpperNum
---                  | RomanLowerNum
---                  deriving (Show, Eq)
-
--- data AutoNumDelim = PeriodDelim
---                   | OneParenDelim
---                   | TwoParensDelim
---                   deriving (Show, Eq)
-
 autoNumberingToType :: ListAttributes -> String
 autoNumberingToType (_, numStyle, numDelim) =
   typeString ++ delimString
@@ -322,6 +311,13 @@
                  , rPropForceSize = Nothing
                  }
 
+data PicProps = PicProps { picPropLink :: Maybe (URL, String)
+                         } deriving (Show, Eq)
+
+instance Default PicProps where
+  def = PicProps { picPropLink = Nothing
+                 }
+
 --------------------------------------------------
 
 inlinesToParElems :: Monad m => [Inline] -> P m [ParaElem]
@@ -356,7 +352,7 @@
   local (\r ->r{envRunProps = (envRunProps r){rLink = Just (url, title)}}) $
     inlinesToParElems ils
 inlineToParElems (Code _ str) = do
-  local (\r ->r{envRunProps = def{rPropCode = True}}) $
+  local (\r ->r{envRunProps = (envRunProps r){rPropCode = True}}) $
     inlineToParElems $ Str str
 inlineToParElems (Math mathtype str) =
   return [MathElem mathtype (TeXString str)]
@@ -408,10 +404,6 @@
   concatMapM blockToParagraphs blks
 -- TODO: work out the format
 blockToParagraphs (RawBlock _ _) = return []
-  -- parElems <- inlinesToParElems [Str str]
-  -- paraProps <- asks envParaProps
-  -- return [Paragraph paraProps parElems]
--- TODO: work out the format
 blockToParagraphs (Header n _ ils) = do
   slideLevel <- asks envSlideLevel
   parElems <- inlinesToParElems ils
@@ -449,8 +441,8 @@
         definition <- concatMapM (blockToParagraphs . BlockQuote) blksLst
         return $ term ++ definition
   concatMapM go entries
+blockToParagraphs (Div (_, ("notes" : []), _) _) = return []
 blockToParagraphs (Div _ blks)  = concatMapM blockToParagraphs blks
--- TODO
 blockToParagraphs blk = do
   P.report $ BlockNotRendered blk
   return []
@@ -484,9 +476,15 @@
 
 blockToShape :: PandocMonad m => Block -> P m Shape
 blockToShape (Plain (il:_)) | Image attr ils (url, _) <- il =
-      Pic url attr <$> (inlinesToParElems ils)
+      Pic def url attr <$> (inlinesToParElems ils)
 blockToShape (Para (il:_))  | Image attr ils (url, _) <- il =
-      Pic url attr <$> (inlinesToParElems ils)
+      Pic def url attr <$> (inlinesToParElems ils)
+blockToShape (Plain (il:_)) | Link _ (il':_) target <- il
+                            , Image attr ils (url, _) <- il' =
+      Pic def{picPropLink = Just target} url attr <$> (inlinesToParElems ils)
+blockToShape (Para (il:_))  | Link _ (il':_) target <- il
+                            , Image attr ils (url, _) <- il' =
+      Pic def{picPropLink = Just target} url attr <$> (inlinesToParElems ils)
 blockToShape (Table caption algn _ hdrCells rows) = do
   caption' <- inlinesToParElems caption
   pageWidth <- presSizeWidth <$> asks envPresentationSize
@@ -517,6 +515,11 @@
 blocksToShapes :: PandocMonad m => [Block] -> P m [Shape]
 blocksToShapes blks = combineShapes <$> mapM blockToShape blks
 
+isImage :: Inline -> Bool
+isImage (Image _ _ _) = True
+isImage (Link _ ((Image _ _ _) : _) _) = True
+isImage _ = False
+
 splitBlocks' :: Monad m => [Block] -> [[Block]] -> [Block] -> P m [[Block]]
 splitBlocks' cur acc [] = return $ acc ++ (if null cur then [] else [cur])
 splitBlocks' cur acc (HorizontalRule : blks) =
@@ -527,32 +530,31 @@
     LT -> splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [[h]]) blks
     EQ -> splitBlocks' [h] (acc ++ (if null cur then [] else [cur])) blks
     GT -> splitBlocks' (cur ++ [h]) acc blks
-splitBlocks' cur acc ((Para (img@(Image _ _ _):ils)) : blks) = do
+-- `blockToParagraphs` treats Plain and Para the same, so we can save
+-- some code duplication by treating them the same here.
+splitBlocks' cur acc ((Plain ils) : blks) = splitBlocks' cur acc ((Para ils) : blks)
+splitBlocks' cur acc ((Para (il:ils)) : blks) | isImage il = do
   slideLevel <- asks envSlideLevel
   case cur of
     (Header n _ _) : [] | n == slideLevel ->
                             splitBlocks' []
-                            (acc ++ [cur ++ [Para [img]]])
+                            (acc ++ [cur ++ [Para [il]]])
                             (if null ils then blks else (Para ils) : blks)
-    _ ->  splitBlocks' []
-          (acc ++ (if null cur then [] else [cur]) ++ [[Para [img]]])
-          (if null ils then blks else (Para ils) : blks)
-splitBlocks' cur acc ((Plain (img@(Image _ _ _):ils)) : blks) = do
-  slideLevel <- asks envSlideLevel
-  case cur of
-    (Header n _ _) : [] | n == slideLevel ->
-                            splitBlocks' []
-                            (acc ++ [cur ++ [Para [img]]])
-                            (if null ils then blks else (Plain ils) : blks)
-    _ ->  splitBlocks' []
-          (acc ++ (if null cur then [] else [cur]) ++ [[Para [img]]])
-          (if null ils then blks else (Plain ils) : blks)
+    _ -> splitBlocks' []
+         (acc ++ (if null cur then [] else [cur]) ++ [[Para [il]]])
+         (if null ils then blks else (Para ils) : blks)
 splitBlocks' cur acc (tbl@(Table _ _ _ _ _) : blks) = do
   slideLevel <- asks envSlideLevel
   case cur of
     (Header n _ _) : [] | n == slideLevel ->
                             splitBlocks' [] (acc ++ [cur ++ [tbl]]) blks
     _ ->  splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [[tbl]]) blks
+splitBlocks' cur acc (d@(Div (_, classes, _) _): blks) | "columns" `elem` classes =  do
+  slideLevel <- asks envSlideLevel
+  case cur of
+    (Header n _ _) : [] | n == slideLevel ->
+                            splitBlocks' [] (acc ++ [cur ++ [d]]) blks
+    _ ->  splitBlocks' [] (acc ++ (if null cur then [] else [cur]) ++ [[d]]) blks
 splitBlocks' cur acc (blk : blks) = splitBlocks' (cur ++ [blk]) acc blks
 
 splitBlocks :: Monad m => [Block] -> P m [[Block]]
@@ -565,13 +567,28 @@
       return $ TitleSlide {titleSlideHeader = hdr}
   | n == lvl = do
       hdr <- inlinesToParElems ils
-      inNoteSlide <- asks envInNoteSlide
-      shapes <- if inNoteSlide
-                then forceFontSize noteSize $ blocksToShapes blks
-                else blocksToShapes blks
-      return $ ContentSlide { contentSlideHeader = hdr
-                            , contentSlideContent = shapes
-                            }
+      -- Now get the slide without the header, and then add the header
+      -- in.
+      slide <- blocksToSlide' lvl blks
+      return $ case slide of
+        ContentSlide _ cont          -> ContentSlide hdr cont
+        TwoColumnSlide _ contL contR -> TwoColumnSlide hdr contL contR
+        slide'                       -> slide'
+blocksToSlide' _ (blk : blks)
+  | Div (_, classes, _) divBlks <- blk
+  , "columns" `elem` classes
+  , (Div (_, clsL, _) blksL) : (Div (_, clsR, _) blksR) : remaining <- divBlks
+  , "column" `elem` clsL, "column" `elem` clsR = do
+      unless (null blks)
+        (mapM (P.report . BlockNotRendered) blks >> return ())
+      unless (null remaining)
+        (mapM (P.report . BlockNotRendered) remaining >> return ())
+      shapesL <- blocksToShapes blksL
+      shapesR <- blocksToShapes blksR
+      return $ TwoColumnSlide { twoColumnSlideHeader = []
+                              , twoColumnSlideLeft = shapesL
+                              , twoColumnSlideRight = shapesR
+                              }
 blocksToSlide' _ (blk : blks) = do
       inNoteSlide <- asks envInNoteSlide
       shapes <- if inNoteSlide
@@ -755,7 +772,7 @@
 combineShapes :: [Shape] -> [Shape]
 combineShapes [] = []
 combineShapes (s : []) = [s]
-combineShapes (pic@(Pic _ _ _) : ss) = pic : combineShapes ss
+combineShapes (pic@(Pic _ _ _ _) : ss) = pic : combineShapes ss
 combineShapes ((TextBox []) : ss) = combineShapes ss
 combineShapes (s : TextBox [] : ss) = combineShapes (s : ss)
 combineShapes (s@(TextBox (p:ps)) : s'@(TextBox (p':ps')) : ss)
@@ -776,6 +793,7 @@
         (MetadataSlide _ _ _ _) -> "ppt/slideLayouts/slideLayout1.xml"
         (TitleSlide _)          -> "ppt/slideLayouts/slideLayout3.xml"
         (ContentSlide _ _)      -> "ppt/slideLayouts/slideLayout2.xml"
+        (TwoColumnSlide _ _ _)    -> "ppt/slideLayouts/slideLayout4.xml"
   distArchive <- asks envDistArchive
   root <- case findEntryByPath layoutpath distArchive of
         Just e -> case parseXMLDoc $ UTF8.toStringLazy $ fromEntry e of
@@ -787,12 +805,6 @@
                    PandocSomeError $
                    layoutpath ++ " missing in reference file"
   return root
-  -- let ns = elemToNameSpaces root
-  -- case findChild (elemName ns "p" "cSld") root of
-  --   Just element' -> return element'
-  --   Nothing       -> throwError $
-  --                    PandocSomeError $
-  --                    layoutpath ++ " not correctly formed layout file"
 
 shapeHasName :: NameSpaces -> String -> Element -> Bool
 shapeHasName ns name element
@@ -802,66 +814,28 @@
       nm == name
   | otherwise = False
 
--- getContentTitleShape :: NameSpaces -> Element -> Maybe Element
--- getContentTitleShape ns spTreeElem
---   | isElem ns "p" "spTree" spTreeElem =
---   filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns "Title 1" e)) spTreeElem
---   | otherwise = Nothing
-
--- getSubtitleShape :: NameSpaces -> Element -> Maybe Element
--- getSubtitleShape ns spTreeElem
---   | isElem ns "p" "spTree" spTreeElem =
---   filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns "Subtitle 2" e)) spTreeElem
---   | otherwise = Nothing
-
--- getDateShape :: NameSpaces -> Element -> Maybe Element
--- getDateShape ns spTreeElem
---   | isElem ns "p" "spTree" spTreeElem =
---   filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns "Date Placeholder 3" e)) spTreeElem
---   | otherwise = Nothing
-
 getContentShape :: NameSpaces -> Element -> Maybe Element
 getContentShape ns spTreeElem
   | isElem ns "p" "spTree" spTreeElem =
   filterChild (\e -> (isElem ns "p" "sp" e) && (shapeHasName ns "Content Placeholder 2" e)) spTreeElem
   | otherwise = Nothing
 
-
--- cursorHasName :: QName -> XMLC.Cursor -> Bool
--- cursorHasName nm cur = case XMLC.current cur of
---   Elem element -> case XMLC.tagName $ XMLC.getTag element of
---                        nm -> True
---                        _ -> False
---   _ -> False
-
--- fillInTxBody :: NameSpaces -> [Paragraph] -> Element -> Element
--- fillInTxBody ns paras txBodyElem
---   | isElem ns "p" "txBody" txBodyElem =
---       replaceNamedChildren ns "a" "p" (map paragraphToElement paras) txBodyElem
---   | otherwise = txBodyElem
-
--- fillInShape :: NameSpaces -> Shape -> Element -> Element
--- fillInShape ns shape spElem
---   | TextBox paras <- shape
---   , isElemn ns "p" "sp" spElem =
---       replaceNamedChildren ns "p" "txBody" (fillInTxBody ns paras sp
-
-
--- fillInShape :: NameSpaces -> Element -> Shape -> Element
--- fillInShape ns spElem (TextBox paras) = fillInParagraphs ns spElem paras
--- fillInShape _ spElem pic = spElem
-
-contentIsElem :: NameSpaces -> String -> String -> Content -> Bool
-contentIsElem ns prefix name (Elem element) = isElem ns prefix name element
-contentIsElem _ _ _ _ = False
-
-replaceNamedChildren :: NameSpaces -> String -> String -> [Element] -> Element -> Element
+replaceNamedChildren :: NameSpaces
+                   -> String
+                   -> String
+                   -> [Element]
+                   -> Element
+                   -> Element
 replaceNamedChildren ns prefix name newKids element =
-  let content = elContent element
-      content' = filter (\c -> not (contentIsElem ns prefix name c)) content
-  in
-    element{elContent = content' ++ map Elem newKids}
-
+  element { elContent = concat $ fun True $ elContent element }
+  where
+    fun :: Bool -> [Content] -> [[Content]]
+    fun _ [] = []
+    fun switch ((Elem e) : conts) | isElem ns prefix name e =
+                                      if switch
+                                      then (map Elem $ newKids) : fun False conts
+                                      else fun False conts
+    fun switch (cont : conts) = [cont] : fun switch conts
 
 ----------------------------------------------------------------
 
@@ -1060,10 +1034,11 @@
 -- Largely lifted from inlineToOpenXML' in T.P.W.Docx. Can't be easily
 -- abstracted because of some different namespaces and monads. TODO.
 makePicElement :: PandocMonad m
-               => MediaInfo
+               => PicProps
+               -> MediaInfo
                -> Text.Pandoc.Definition.Attr
                -> P m Element
-makePicElement mInfo attr = do
+makePicElement picProps mInfo attr = do
   opts <- asks envOpts
   pageWidth <- presSizeWidth <$> asks envPresentationSize
   pageHeight <- getPageHeight <$> asks envPresentationSize
@@ -1088,13 +1063,19 @@
       xoff' = if hasHeader then xoff + hXoff else xoff
       xoff'' = if hasCaption then xoff' + capX else xoff'
       yoff' = if hasHeader then hYoff + hYext else yoff
-      -- let (xemu,yemu)=((floor $ xpt * 12700), (floor $ ypt * 12700))
   let cNvPicPr = mknode "p:cNvPicPr" [] $
                  mknode "a:picLocks" [("noGrp","1")
                                      ,("noChangeAspect","1")] ()
+  -- cNvPr will contain the link information so we do that separately,
+  -- and register the link if necessary.
+  let cNvPrAttr = [("descr", mInfoFilePath mInfo), ("id","0"),("name","Picture 1")]
+  cNvPr <- case picPropLink picProps of
+    Just link -> do idNum <- registerLink link
+                    return $ mknode "p:cNvPr" cNvPrAttr $
+                      mknode "a:hlinkClick" [("r:id", "rId" ++ show idNum)] ()
+    Nothing   -> return $ mknode "p:cNvPr" cNvPrAttr ()
   let nvPicPr  = mknode "p:nvPicPr" []
-                 [ mknode "p:cNvPr"
-                   [("descr", mInfoFilePath mInfo),("id","0"),("name","Picture 1")] ()
+                 [ cNvPr
                  , cNvPicPr
                  , mknode "p:nvPr" [] ()]
   let blipFill = mknode "p:blipFill" []
@@ -1129,13 +1110,13 @@
 paraElemToElement :: PandocMonad m => ParaElem -> P m Element
 paraElemToElement Break = return $ mknode "a:br" [] ()
 paraElemToElement (Run rpr s) = do
-  let attrs =
+  let sizeAttrs = case rPropForceSize rpr of
+                    Just n -> [("sz", (show $ n * 100))]
+                    Nothing -> []
+      attrs = sizeAttrs ++
         if rPropCode rpr
         then []
-        else (case rPropForceSize rpr of
-                Just n -> [("sz", (show $ n * 100))]
-                Nothing -> []) ++
-             (if rPropBold rpr then [("b", "1")] else []) ++
+        else (if rPropBold rpr then [("b", "1")] else []) ++
              (if rPropItalics rpr then [("i", "1")] else []) ++
              (case rStrikethrough rpr of
                 Just NoStrike     -> [("strike", "noStrike")]
@@ -1219,7 +1200,7 @@
                  [mknode "a:buAutoNum" [("type", autoNumberingToType attrs')] ()]
                Nothing -> [mknode "a:buNone" [] ()]
             )
-  paras <- mapM paraElemToElement (paraElems par)
+  paras <- mapM paraElemToElement (combineParaElems $ paraElems par)
   return $ mknode "a:p" [] $ [mknode "a:pPr" attrs props] ++ paras
 
 shapeToElement :: PandocMonad m => Element -> Shape -> P m Element
@@ -1240,10 +1221,10 @@
   -- XXX: TODO
   | otherwise = return $ mknode "p:sp" [] ()
 -- XXX: TODO
-shapeToElement layout (Pic fp attr alt) = do
+shapeToElement layout (Pic picProps fp attr alt) = do
   mInfo <- registerMedia fp alt
   case mInfoExt mInfo of
-    Just _ -> makePicElement mInfo attr
+    Just _ -> makePicElement picProps mInfo attr
     Nothing -> shapeToElement layout $ TextBox [Paragraph def alt]
 shapeToElement _ (GraphicFrame tbls _) = do
   elements <- mapM graphicToElement tbls
@@ -1264,7 +1245,7 @@
 shapeToElements :: PandocMonad m => Element -> Shape -> P m [Element]
 shapeToElements layout shp = do
   case shp of
-    (Pic _ _ alt) | (not . null) alt -> do
+    (Pic _ _ _ alt) | (not . null) alt -> do
       element <- shapeToElement layout shp
       caption <- createCaption alt
       return [element, caption]
@@ -1286,12 +1267,16 @@
 
 graphicToElement :: PandocMonad m => Graphic -> P m Element
 graphicToElement (Tbl tblPr colWidths hdrCells rows) = do
-  let cellToOpenXML paras = do elements <- mapM paragraphToElement paras
-                               return $
-                                 [mknode "a:txBody" [] $
-                                  ([ mknode "a:bodyPr" [] ()
-                                   , mknode "a:lstStyle" [] ()]
-                                   ++ elements)]
+  let cellToOpenXML paras =
+        do elements <- mapM paragraphToElement paras
+           let elements' = if null elements
+                           then [mknode "a:p" [] [mknode "a:endParaRPr" [] ()]]
+                           else elements
+           return $
+             [mknode "a:txBody" [] $
+               ([ mknode "a:bodyPr" [] ()
+                , mknode "a:lstStyle" [] ()]
+                 ++ elements')]
   headers' <- mapM cellToOpenXML hdrCells
   rows' <- mapM (mapM cellToOpenXML) rows
   let borderProps = mknode "a:tcPr" [] ()
@@ -1301,9 +1286,6 @@
                                then emptyCell
                                else contents) ++ [ borderProps | border ]
   let mkrow border cells = mknode "a:tr" [("h", "0")] $ map (mkcell border) cells
-  -- let textwidth = 14400  -- 5.5 in in twips, 1/20 pt
-  -- let fullrow = 14400 -- 100% specified in pct
-  -- let rowwidth = fullrow * sum colWidths
 
   let mkgridcol w = mknode "a:gridCol"
                        [("w", show ((12700 * w) :: Integer))] ()
@@ -1343,24 +1325,6 @@
   -- XXX: TODO
   | otherwise = return $ mknode "p:sp" [] ()
 
-
--- hdrToElement :: Element -> [ParaElem] -> Element
--- hdrToElement layout paraElems
---   | ns <- elemToNameSpaces layout
---   , Just cSld <- findChild (elemName ns "p" "cSld") layout
---   , Just spTree <- findChild (elemName ns "p" "spTree") cSld
---   , Just sp <- getContentTitleShape ns spTree =
---   let hdrPara = Paragraph def paraElems
---       txBody = mknode "p:txBody" [] $
---                [mknode "a:bodyPr" [] (), mknode "a:lstStyle" [] ()] ++
---                [paragraphToElement hdrPara]
---   in
---     replaceNamedChildren ns "p" "txBody" [txBody] sp
---   -- XXX: TODO
---   | otherwise = mknode "p:sp" [] ()
--- -- XXX: TODO
--- hdrToElement _ _ = mknode "p:sp" [] ()
-
 contentToElement :: PandocMonad m => Element -> [ParaElem] -> [Shape] -> P m Element
 contentToElement layout hdrShape shapes
   | ns <- elemToNameSpaces layout
@@ -1377,6 +1341,53 @@
         spTree
 contentToElement _ _ _ = return $ mknode "p:sp" [] ()
 
+setIdx'' :: NameSpaces -> String -> Content -> Content
+setIdx'' _ idx (Elem element) =
+  let tag = XMLC.getTag element
+      attrs = XMLC.tagAttribs tag
+      idxKey = (QName "idx" Nothing Nothing)
+      attrs' = Attr idxKey idx : (filter (\a -> attrKey a /= idxKey) attrs)
+      tag' = tag {XMLC.tagAttribs = attrs'}
+  in Elem $ XMLC.setTag tag' element
+setIdx'' _ _ c = c
+
+setIdx' :: NameSpaces -> String -> XMLC.Cursor -> XMLC.Cursor
+setIdx' ns idx cur =
+  let modifiedCur = XMLC.modifyContent (setIdx'' ns idx) cur
+  in
+    case XMLC.nextDF modifiedCur of
+      Just cur' -> setIdx' ns idx cur'
+      Nothing   -> XMLC.root modifiedCur
+
+setIdx :: NameSpaces -> String -> Element -> Element
+setIdx ns idx element =
+  let cur = XMLC.fromContent (Elem element)
+      cur' = setIdx' ns idx cur
+  in
+    case XMLC.toTree cur' of
+      Elem element' -> element'
+      _             -> element
+
+twoColumnToElement :: PandocMonad m => Element -> [ParaElem] -> [Shape] -> [Shape] -> P m Element
+twoColumnToElement layout hdrShape shapesL shapesR
+  | ns <- elemToNameSpaces layout
+  , Just cSld <- findChild (elemName ns "p" "cSld") layout
+  , Just spTree <- findChild (elemName ns "p" "spTree") cSld = do
+      element <- nonBodyTextToElement layout "Title 1" hdrShape
+      let hdrShapeElements = if null hdrShape
+                             then []
+                             else [element]
+      contentElementsL <- shapesToElements layout shapesL
+      contentElementsR <- shapesToElements layout shapesR
+      let contentElementsL' = map (setIdx ns "1") contentElementsL
+          contentElementsR' = map (setIdx ns "2") contentElementsR
+      return $
+        replaceNamedChildren ns "p" "sp"
+        (hdrShapeElements ++ contentElementsL' ++ contentElementsR')
+        spTree
+twoColumnToElement _ _ _ _= return $ mknode "p:sp" [] ()
+
+
 titleToElement :: PandocMonad m => Element -> [ParaElem] -> P m Element
 titleToElement layout titleElems
   | ns <- elemToNameSpaces layout
@@ -1422,6 +1433,17 @@
       ("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"),
       ("xmlns:p", "http://schemas.openxmlformats.org/presentationml/2006/main")
     ] [mknode "p:cSld" [] [spTree]]
+slideToElement s@(TwoColumnSlide hdrElems shapesL shapesR) = do
+  layout <- getLayout s
+  spTree <- local (\env -> if null hdrElems
+                           then env
+                           else env{envSlideHasHeader=True}) $
+            twoColumnToElement layout hdrElems shapesL shapesR
+  return $ mknode "p:sld"
+    [ ("xmlns:a", "http://schemas.openxmlformats.org/drawingml/2006/main"),
+      ("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"),
+      ("xmlns:p", "http://schemas.openxmlformats.org/presentationml/2006/main")
+    ] [mknode "p:cSld" [] [spTree]]
 slideToElement s@(TitleSlide hdrElems) = do
   layout <- getLayout s
   spTree <- titleToElement layout hdrElems
@@ -1574,6 +1596,7 @@
         (MetadataSlide _ _ _ _) -> "../slideLayouts/slideLayout1.xml"
         (TitleSlide _)        -> "../slideLayouts/slideLayout3.xml"
         (ContentSlide _ _)    -> "../slideLayouts/slideLayout2.xml"
+        (TwoColumnSlide _ _ _)    -> "../slideLayouts/slideLayout4.xml"
 
   linkIds <- gets stLinkIds
   mediaIds <- gets stMediaIds
@@ -1593,11 +1616,6 @@
                            , ("Target", target)] ()
     ] ++ linkRels ++ mediaRels)
 
--- slideToSlideRelEntry :: PandocMonad m => Slide -> Int -> P m Entry
--- slideToSlideRelEntry slide idNum = do
---   let fp = "ppt/slides/_rels/slide" ++ (show idNum) ++ ".xml.rels"
---   elemToEntry fp $ slideToSlideRelElement slide
-
 slideToSldIdElement :: PandocMonad m => Slide -> Int -> P m Element
 slideToSldIdElement slide idNum = do
   let id' = show $ idNum + 255
@@ -1708,10 +1726,6 @@
     (defaults ++ mediaDefaults)
     (inheritedOverrides ++ presOverride ++ slideOverrides)
 
--- slideToElement :: Element -> Slide -> Element
--- slideToElement layout (ContentSlide _ shapes) =
---   let sps = map (shapeToElement layout) shapes
-
 presML :: String
 presML = "application/vnd.openxmlformats-officedocument.presentationml"
 
@@ -1744,3 +1758,20 @@
   | "ppt" : "slideLayouts" : _ : [] <- splitDirectories fp=
       Just $ presML ++ ".slideLayout+xml"
   | otherwise = Nothing
+
+-------------------------------------------------------
+
+combineParaElems' :: Maybe ParaElem -> [ParaElem] -> [ParaElem]
+combineParaElems' mbPElem [] = maybeToList mbPElem
+combineParaElems' Nothing (pElem : pElems) =
+  combineParaElems' (Just pElem) pElems
+combineParaElems' (Just pElem') (pElem : pElems)
+  | Run rPr' s' <- pElem'
+  , Run rPr s <- pElem
+  , rPr == rPr' =
+    combineParaElems' (Just $ Run rPr' $ s' ++ s) pElems
+  | otherwise =
+    pElem' : combineParaElems' (Just pElem) pElems
+
+combineParaElems :: [ParaElem] -> [ParaElem]
+combineParaElems = combineParaElems' Nothing
diff --git a/src/Text/Pandoc/Writers/RST.hs b/src/Text/Pandoc/Writers/RST.hs
--- a/src/Text/Pandoc/Writers/RST.hs
+++ b/src/Text/Pandoc/Writers/RST.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.RST
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/RTF.hs b/src/Text/Pandoc/Writers/RTF.hs
--- a/src/Text/Pandoc/Writers/RTF.hs
+++ b/src/Text/Pandoc/Writers/RTF.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.RTF
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Shared.hs b/src/Text/Pandoc/Writers/Shared.hs
--- a/src/Text/Pandoc/Writers/Shared.hs
+++ b/src/Text/Pandoc/Writers/Shared.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2013-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2013-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Shared
-   Copyright   : Copyright (C) 2013-2017 John MacFarlane
+   Copyright   : Copyright (C) 2013-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/TEI.hs b/src/Text/Pandoc/Writers/TEI.hs
--- a/src/Text/Pandoc/Writers/TEI.hs
+++ b/src/Text/Pandoc/Writers/TEI.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards     #-}
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Docbook
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/Texinfo.hs b/src/Text/Pandoc/Writers/Texinfo.hs
--- a/src/Text/Pandoc/Writers/Texinfo.hs
+++ b/src/Text/Pandoc/Writers/Texinfo.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-
-Copyright (C) 2008-2017 John MacFarlane
+Copyright (C) 2008-2018 John MacFarlane
               2012 Peter Wang
 
 This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Texinfo
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane
                                2012 Peter Wang
    License     : GNU GPL, version 2 or above
 
diff --git a/src/Text/Pandoc/Writers/Textile.hs b/src/Text/Pandoc/Writers/Textile.hs
--- a/src/Text/Pandoc/Writers/Textile.hs
+++ b/src/Text/Pandoc/Writers/Textile.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2010-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2010-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.Textile
-   Copyright   : Copyright (C) 2010-2017 John MacFarlane
+   Copyright   : Copyright (C) 2010-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/src/Text/Pandoc/Writers/ZimWiki.hs b/src/Text/Pandoc/Writers/ZimWiki.hs
--- a/src/Text/Pandoc/Writers/ZimWiki.hs
+++ b/src/Text/Pandoc/Writers/ZimWiki.hs
@@ -1,6 +1,6 @@
 {-
-Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>
-              2017 Alex Ivkin
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
+              2017-2018 Alex Ivkin
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 {- |
    Module      : Text.Pandoc.Writers.ZimWiki
-   Copyright   : Copyright (C) 2008-2017 John MacFarlane, 2017 Alex Ivkin
+   Copyright   : Copyright (C) 2008-2018 John MacFarlane, 2017-2018 Alex Ivkin
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Alex Ivkin <alex@ivkin.net>
diff --git a/src/Text/Pandoc/XML.hs b/src/Text/Pandoc/XML.hs
--- a/src/Text/Pandoc/XML.hs
+++ b/src/Text/Pandoc/XML.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (C) 2006-2017 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 {- |
    Module      : Text.Pandoc.XML
-   Copyright   : Copyright (C) 2006-2017 John MacFarlane
+   Copyright   : Copyright (C) 2006-2018 John MacFarlane
    License     : GNU GPL, version 2 or above
 
    Maintainer  : John MacFarlane <jgm@berkeley.edu>
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -12,5 +12,8 @@
     debug: false
 packages:
 - '.'
-extra-deps: []
-resolver: lts-10.1
+extra-deps:
+- pandoc-citeproc-0.12.2.5
+- hslua-0.9.5
+- skylighting-0.5.1
+resolver: lts-10.2
diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs
--- a/test/Tests/Lua.hs
+++ b/test/Tests/Lua.hs
@@ -2,6 +2,7 @@
 module Tests.Lua ( tests ) where
 
 import Control.Monad (when)
+import Data.Version (Version (versionBranch))
 import System.FilePath ((</>))
 import Test.Tasty (TestTree, localOption)
 import Test.Tasty.HUnit (Assertion, assertEqual, testCase)
@@ -11,8 +12,9 @@
                             header, linebreak, para, plain, rawBlock,
                             singleQuoted, space, str, strong, (<>))
 import Text.Pandoc.Class (runIOorExplode, setUserDataDir)
-import Text.Pandoc.Definition (Block, Inline, Meta, Pandoc)
+import Text.Pandoc.Definition (Block, Inline, Meta, Pandoc, pandocTypesVersion)
 import Text.Pandoc.Lua (runLuaFilter, runPandocLua)
+import Text.Pandoc.Shared (pandocVersion)
 
 import qualified Foreign.Lua as Lua
 
@@ -106,6 +108,20 @@
                      , plain (str "stringify: OK")
                      , plain (str "to_roman_numeral: OK")
                      ])
+
+  , testCase "Pandoc version is set" . runPandocLua' $ do
+      Lua.getglobal' "table.concat"
+      Lua.getglobal "PANDOC_VERSION"
+      Lua.push ("." :: String) -- seperator
+      Lua.call 2 1
+      Lua.liftIO . assertEqual "pandoc version is wrong" pandocVersion
+        =<< Lua.peek Lua.stackTop
+
+  , testCase "Pandoc types version is set" . runPandocLua' $ do
+      let versionNums = versionBranch pandocTypesVersion
+      Lua.getglobal "PANDOC_API_VERSION"
+      Lua.liftIO . assertEqual "pandoc version is wrong" versionNums
+        =<< Lua.peek Lua.stackTop
   ]
 
 assertFilterConversion :: String -> FilePath -> Pandoc -> Pandoc -> Assertion
@@ -121,18 +137,21 @@
 roundtripEqual x = (x ==) <$> roundtripped
  where
   roundtripped :: (Lua.FromLuaStack a, Lua.ToLuaStack a) => IO a
-  roundtripped = runIOorExplode $ do
-    setUserDataDir (Just "../data")
-    res <- runPandocLua $ do
-      oldSize <- Lua.gettop
-      Lua.push x
-      size <- Lua.gettop
-      when (size - oldSize /= 1) $
-        error ("not exactly one additional element on the stack: " ++ show size)
-      res <- Lua.peekEither (-1)
-      case res of
-        Left _  -> error "could not read from stack"
-        Right y -> return y
+  roundtripped = runPandocLua' $ do
+    oldSize <- Lua.gettop
+    Lua.push x
+    size <- Lua.gettop
+    when (size - oldSize /= 1) $
+      error ("not exactly one additional element on the stack: " ++ show size)
+    res <- Lua.peekEither (-1)
     case res of
-      Left e -> error (show e)
+      Left _  -> error "could not read from stack"
       Right y -> return y
+
+runPandocLua' :: Lua.Lua a -> IO a
+runPandocLua' op = runIOorExplode $ do
+  setUserDataDir (Just "../data")
+  res <- runPandocLua op
+  case res of
+    Left e -> error (show e)
+    Right x -> return x
diff --git a/test/Tests/Readers/Docx.hs b/test/Tests/Readers/Docx.hs
--- a/test/Tests/Readers/Docx.hs
+++ b/test/Tests/Readers/Docx.hs
@@ -175,6 +175,14 @@
             "inlines inside of Structured Document Tags"
             "docx/sdt_elements.docx"
             "docx/sdt_elements.native"
+          , testCompare
+            "remove anchor spans with nothing pointing to them"
+            "docx/unused_anchors.docx"
+            "docx/unused_anchors.native"
+          , testCompare
+            "collapse overlapping targets (anchor spans)"
+            "docx/overlapping_targets.docx"
+            "docx/overlapping_targets.native"
           ]
         , testGroup "blocks"
           [ testCompare
@@ -327,6 +335,18 @@
             "comments (all comments)"
             "docx/comments.docx"
             "docx/comments.native"
+          , testCompareWithOpts def{readerTrackChanges=AcceptChanges}
+            "paragraph insertion/deletion (accept)"
+            "docx/paragraph_insertion_deletion.docx"
+            "docx/paragraph_insertion_deletion_accept.native"
+          , testCompareWithOpts def{readerTrackChanges=RejectChanges}
+            "paragraph insertion/deletion (reject)"
+            "docx/paragraph_insertion_deletion.docx"
+            "docx/paragraph_insertion_deletion_reject.native"
+          , testCompareWithOpts def{readerTrackChanges=AllChanges}
+            "paragraph insertion/deletion (all)"
+            "docx/paragraph_insertion_deletion.docx"
+            "docx/paragraph_insertion_deletion_all.native"
           , testForWarningsWithOpts def{readerTrackChanges=AcceptChanges}
             "comment warnings (accept -- no warnings)"
             "docx/comments_warning.docx"
diff --git a/test/Tests/Readers/Muse.hs b/test/Tests/Readers/Muse.hs
--- a/test/Tests/Readers/Muse.hs
+++ b/test/Tests/Readers/Muse.hs
@@ -5,13 +5,13 @@
 import Data.Text (Text)
 import qualified Data.Text as T
 import Test.Tasty
--- import Test.Tasty.QuickCheck
+import Test.Tasty.QuickCheck
 import Tests.Helpers
 import Text.Pandoc
 import Text.Pandoc.Arbitrary ()
 import Text.Pandoc.Builder
 import Text.Pandoc.Shared (underlineSpan)
--- import Text.Pandoc.Walk (walk)
+import Text.Pandoc.Walk (walk)
 
 amuse :: Text -> Pandoc
 amuse = purely $ readMuse def { readerExtensions = extensionsFromList [Ext_amuse]}
@@ -27,19 +27,19 @@
 spcSep :: [Inlines] -> Inlines
 spcSep = mconcat . intersperse space
 
-{-
--- Tables and code blocks don't round-trip yet
+-- Tables and definition lists don't round-trip yet
 
-removeTables :: Block -> Block
-removeTables (Table{}) = Para [Str "table was here"]
-removeTables x = x
+makeRoundTrip :: Block -> Block
+makeRoundTrip (Table{}) = Para [Str "table was here"]
+makeRoundTrip (DefinitionList{}) = Para [Str "deflist was here"]
+makeRoundTrip x = x
 
 -- Demand that any AST produced by Muse reader and written by Muse writer can be read back exactly the same way.
 -- Currently we remove code blocks and tables and compare third rewrite to the second.
 -- First and second rewrites are not equal yet.
 roundTrip :: Block -> Bool
 roundTrip b = d'' == d'''
-  where d = walk removeTables $ Pandoc nullMeta [b]
+  where d = walk makeRoundTrip $ Pandoc nullMeta [b]
         d' = rewrite d
         d'' = rewrite d'
         d''' = rewrite d''
@@ -47,7 +47,6 @@
                   (purely $ writeMuse def { writerExtensions = extensionsFromList [Ext_amuse]
                                           , writerWrapText = WrapPreserve
                                           })
--}
 
 tests :: [TestTree]
 tests =
@@ -200,7 +199,7 @@
       ]
 
   , testGroup "Blocks"
-      [ -- testProperty "Round trip" roundTrip,
+      [ testProperty "Round trip" roundTrip,
         "Block elements end paragraphs" =:
         T.unlines [ "First paragraph"
                   , "----"
diff --git a/test/Tests/Writers/Powerpoint.hs b/test/Tests/Writers/Powerpoint.hs
--- a/test/Tests/Writers/Powerpoint.hs
+++ b/test/Tests/Writers/Powerpoint.hs
@@ -5,27 +5,35 @@
 import Control.Exception (throwIO)
 import Text.Pandoc
 import Text.Pandoc.Builder
+import Text.Pandoc.Arbitrary ()
+import Text.Pandoc.Walk
 import Test.Tasty
 import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
 import Codec.Archive.Zip
-import Data.List (isPrefixOf, isSuffixOf)
+import Text.XML.Light
+import Data.List (isPrefixOf, isSuffixOf, sort)
+import Data.Maybe (mapMaybe)
 
+getPptxArchive :: WriterOptions -> Pandoc -> IO Archive
+getPptxArchive opts pd = do
+  mbs <- runIO $
+         do setUserDataDir $ Just "../data"
+            writePowerpoint opts pd
+  case mbs of
+       Left e   -> throwIO e
+       Right bs -> return $ toArchive bs
+
 ----- Number of Slides -----------
 
 numberOfSlides :: WriterOptions -> Pandoc -> IO Int
 numberOfSlides opts pd = do
-  mbs <- runIO $
-        do setUserDataDir $ Just "../data"
-           writePowerpoint opts pd
-  case mbs of
-       Left e   -> throwIO e
-       Right bs -> do
-         let archive = toArchive bs
-         return $
-           length $
-           filter (isSuffixOf ".xml") $
-           filter (isPrefixOf "ppt/slides/slide") $
-           filesInArchive archive
+  archive <- getPptxArchive opts pd
+  return $
+    length $
+    filter (isSuffixOf ".xml") $
+    filter (isPrefixOf "ppt/slides/slide") $
+    filesInArchive archive
 
 testNumberOfSlides :: TestName -> Int -> WriterOptions -> Pandoc -> TestTree
 testNumberOfSlides name n opts pd =
@@ -44,7 +52,7 @@
     def
     (setTitle "My Title" $ doc $ para "foo")
   , testNumberOfSlides
-    "With h1 slide (using default slide-level)" 2
+    "With h1 slide (using default slide-level)" 1
     def
     (doc $ header 1 "Header" <> para "foo")
   , testNumberOfSlides
@@ -52,12 +60,12 @@
     def
     (doc $ header 1 "Header" <> header 2 "subeader" <> para "foo")
   , testNumberOfSlides
-    "With h1 slide (using default slide-level)" 2
-    def
+    "With h1 slide (using slide-level 3)" 2
+    def {writerSlideLevel= Just 3}
     (doc $ header 1 "Header" <> para "foo")
   , testNumberOfSlides
-    "With h2 slide (using default slide-level)" 2
-    def
+    "With h2 slide (using slide-level 3)" 3
+    def {writerSlideLevel= Just 3}
     (doc $ header 1 "Header" <> header 2 "subeader" <> para "foo")
   , testNumberOfSlides
     "With image slide, no header" 3
@@ -94,8 +102,68 @@
     def
     (doc $
      para "first slide" <> horizontalRule <> para "last slide")
+  , testNumberOfSlides
+    "with notes slide" 2
+    def
+    (doc $
+      para $ text "Foo" <> note (para "note text"))
   ]
 
+----- Content Types -----------
 
+
+contentTypesFileExists :: WriterOptions -> Pandoc -> TestTree
+contentTypesFileExists opts pd =
+  testCase "Existence of [Content_Types].xml file" $
+  do archive <- getPptxArchive opts pd
+     assertBool "Missing [Content_Types].xml file" $
+       "[Content_Types].xml" `elem` (filesInArchive archive)
+
+
+
+-- We want an "Override" entry for each xml file under ppt/.
+prop_ContentOverrides :: Pandoc -> IO Bool
+prop_ContentOverrides pd = do
+  -- remove Math to avoid warnings
+  let go :: Inline -> Inline
+      go (Math _ _) = Str "Math"
+      go i = i
+      pd' = walk go pd
+  archive <- getPptxArchive def pd'
+  let xmlFiles = filter ("[Content_Types].xml" /=) $
+                  filter (isSuffixOf ".xml") $
+                  filesInArchive archive
+  contentTypes <- case findEntryByPath "[Content_Types].xml" archive of
+                    Just ent -> return $ fromEntry ent
+                    Nothing  -> throwIO $
+                      PandocSomeError "Missing [Content_Types].xml file"
+  typesElem <- case parseXMLDoc contentTypes of
+                    Just element -> return $ element
+                    Nothing      -> throwIO $
+                      PandocSomeError "[Content_Types].xml cannot be parsed"
+  let ns = findAttr (QName "xmlns" Nothing Nothing) typesElem
+      overrides = findChildren (QName "Override" ns Nothing) typesElem
+      partNames = mapMaybe (findAttr (QName "PartName" Nothing Nothing)) overrides
+      -- files in content_types are absolute
+      absXmlFiles = map (\fp -> case fp of
+                                  ('/':_) -> fp
+                                  _       -> '/': fp
+                        )
+                    xmlFiles
+  return $ sort absXmlFiles == sort partNames
+
+contentOverridesTests :: TestTree
+contentOverridesTests = localOption (QuickCheckTests 20) $
+                       testProperty "Content Overrides for each XML file" $
+                       \x -> ioProperty $ prop_ContentOverrides (x :: Pandoc)
+
+contentTypeTests :: TestTree
+contentTypeTests = testGroup "[Content_Types].xml file"
+  [ contentTypesFileExists def (doc $ para "foo")
+  , contentOverridesTests
+  ]
+
 tests :: [TestTree]
-tests = [numSlideTests]
+tests = [ numSlideTests
+        , contentTypeTests
+        ]
diff --git a/test/docx/nested_anchors_in_header.native b/test/docx/nested_anchors_in_header.native
--- a/test/docx/nested_anchors_in_header.native
+++ b/test/docx/nested_anchors_in_header.native
@@ -1,4 +1,9 @@
-[Header 1 ("short-instructions",[],[]) [Str "Short",Space,Str "instructions"]
+[Header 1 ("\1086\1075\1083\1072\1074\1083\1077\1085\1080\1077",["TOCHeading"],[]) [Str "\1054\1075\1083\1072\1074\1083\1077\1085\1080\1077"]
+,Para [Link ("",[],[]) [Str "Short",Space,Str "instructions",Space,Str "1"] ("#short-instructions","")]
+,Para [Link ("",[],[]) [Str "Some",Space,Str "instructions",Space,Str "1"] ("#some-instructions","")]
+,Para [Link ("",[],[]) [Str "Remote",Space,Str "folder",Space,Str "or",Space,Str "longlonglonglonglong",Space,Str "file",Space,Str "with",Space,Str "manymanymanymany",Space,Str "letters",Space,Str "inside",Space,Str "opening",Space,Str "2"] ("#remote-folder-or-longlonglonglonglong-file-with-manymanymanymany-letters-inside-opening","")]
+,Para [Link ("",[],[]) [Str "Remote",Space,Str "folder",Space,Str "or",Space,Str "longlonglonglonglong",Space,Str "file",Space,Str "with",Space,Str "manymanymanymany",Space,Str "letters",Space,Str "inside",Space,Str "closing",Space,Str "2"] ("#remote-folder-or-longlonglonglonglong-file-with-manymanymanymany-letters-inside-closing","")]
+,Header 1 ("short-instructions",[],[]) [Str "Short",Space,Str "instructions"]
 ,Para [Link ("",[],[]) [Str "Open",Space,Str "remote",Space,Str "folder"] ("#remote-folder-or-longlonglonglonglong-file-with-manymanymanymany-letters-inside-opening","")]
 ,Para [Str "Do",Space,Str "staff"]
 ,Para [Link ("",[],[]) [Str "Close",Space,Str "remote",Space,Str "folder"] ("#remote-folder-or-longlonglonglonglong-file-with-manymanymanymany-letters-inside-closing","")]
diff --git a/test/docx/overlapping_targets.docx b/test/docx/overlapping_targets.docx
new file mode 100644
Binary files /dev/null and b/test/docx/overlapping_targets.docx differ
diff --git a/test/docx/overlapping_targets.native b/test/docx/overlapping_targets.native
new file mode 100644
--- /dev/null
+++ b/test/docx/overlapping_targets.native
@@ -0,0 +1,3 @@
+[Para [Link ("",[],[]) [Str "One",Space,Str "link",Space,Str "to",Space,Str "one",Space,Str "target."] ("#Fizz","")]
+,Para [Span ("Fizz",["anchor"],[]) [],Str "This",Space,Str "is",Space,Str "a",Space,Str "target",Space,Str "with",Space,Str "two",Space,Str "names."]
+,Para [Link ("",[],[]) [Str "Another",Space,Str "link",Space,Str "to",Space,Str "the",Space,Str "same",Space,Str "target."] ("#Fizz","")]]
diff --git a/test/docx/paragraph_insertion_deletion.docx b/test/docx/paragraph_insertion_deletion.docx
new file mode 100644
Binary files /dev/null and b/test/docx/paragraph_insertion_deletion.docx differ
diff --git a/test/docx/paragraph_insertion_deletion_accept.native b/test/docx/paragraph_insertion_deletion_accept.native
new file mode 100644
--- /dev/null
+++ b/test/docx/paragraph_insertion_deletion_accept.native
@@ -0,0 +1,2 @@
+[Para [Str "This",Space,Str "is",Space,Str "a"]
+,Para [Str "split",Space,Str "Paragraph."]]
diff --git a/test/docx/paragraph_insertion_deletion_all.native b/test/docx/paragraph_insertion_deletion_all.native
new file mode 100644
--- /dev/null
+++ b/test/docx/paragraph_insertion_deletion_all.native
@@ -0,0 +1,3 @@
+[Para [Str "This",Space,Str "is",Space,Str "a",Span ("",["paragraph-insertion"],[("author","Seeley, Jason"),("date","2017-09-17T16:39:00Z")]) []]
+,Para [Str "split",Span ("",["paragraph-deletion"],[("author","Seeley, Jason"),("date","2017-09-17T16:39:00Z")]) []]
+,Para [Str "Paragraph."]]
diff --git a/test/docx/paragraph_insertion_deletion_reject.native b/test/docx/paragraph_insertion_deletion_reject.native
new file mode 100644
--- /dev/null
+++ b/test/docx/paragraph_insertion_deletion_reject.native
@@ -0,0 +1,2 @@
+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "split"]
+,Para [Str "Paragraph."]]
diff --git a/test/docx/unused_anchors.docx b/test/docx/unused_anchors.docx
new file mode 100644
Binary files /dev/null and b/test/docx/unused_anchors.docx differ
diff --git a/test/docx/unused_anchors.native b/test/docx/unused_anchors.native
new file mode 100644
--- /dev/null
+++ b/test/docx/unused_anchors.native
@@ -0,0 +1,3 @@
+[Header 1 ("my-section",[],[]) [Str "My",Space,Str "Section"]
+,Para [Link ("",[],[]) [Str "Here",Space,Str "is",Space,Str "a",Space,Str "link."] ("#Foo","")]
+,Para [Span ("Foo",["anchor"],[]) [],Str "Here",Space,Str "is",Space,Str "the",Space,Str "target."]]
diff --git a/test/writer.opendocument b/test/writer.opendocument
--- a/test/writer.opendocument
+++ b/test/writer.opendocument
@@ -639,6 +639,8 @@
     <style:style style:name="T6" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
     <style:style style:name="T7" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-position="super 58%" /></style:style>
     <style:style style:name="T8" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
+    <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>
+    <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>
     <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Quotations">
       <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />
     </style:style>
