diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,16 +14,16 @@
 Make sure you can reproduce the bug with the latest released version of pandoc
 (or, even better, the development version).
 
-Your report should give detailed instructions for how to reproduce the problem,
-including
+Your report should give detailed, *reproducible* instructions, including
 
+  * the pandoc version (check using `pandoc -v`)
   * the exact command line used
   * the exact input used
   * the output received
   * the output you expected instead
 
 A small test case (just a few lines) is ideal.  If your input is large,
-try to whittle it down to the minimum necessary to illustrate the problem.
+try to whittle it down to a *minimum working example*.
 
 Out of scope?
 -------------
@@ -59,22 +59,22 @@
 bug. There is not yet a way to indicate priority. An up to date
 summary of issues can be found [here](https://github.com/jgm/pandoc/labels).
 
-* [enhancement] -- A feature which would be desirable. We recommend
+* [enhancement] — A feature which would be desirable. We recommend
   you discuss any proposed enhancement on pandoc-discuss before
   writing code.
-* [bug] -- A problem which needs to be fixed.
-* [minor] -- The fix should only be a couple of lines.
-* [major] -- The fix might require structural changes or in depth knowledge of
+* [bug] — A problem which needs to be fixed.
+* [minor] — The fix should only be a couple of lines.
+* [major] — The fix might require structural changes or in depth knowledge of
 the code base.
-* [reader] -- A request to add a new input format.
-* [writer] -- A request to add a new output format.
-* [docs]   -- A discrepency or ambiguity in the documentation.
-* [inprogress] -- Someone is actively working on or planning to work on the
+* [reader] — A request to add a new input format.
+* [writer] — A request to add a new output format.
+* [docs]   — A discrepency or ambiguity in the documentation.
+* [inprogress] — Someone is actively working on or planning to work on the
   ticket.
-* [more discussion needed] -- It is unclear what the correct approach
+* [more discussion needed] — It is unclear what the correct approach
   to solving the ticket is. Before starting on tickets such as this it
   would be advisable to post on the ticket.
-* [more info needed] -- We require more information from a user before
+* [more info needed] — We require more information from a user before
   we can classify a report properly.
 
 Have an idea for a new feature?
diff --git a/MANUAL.txt b/MANUAL.txt
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1,6 +1,6 @@
 % Pandoc User's Guide
 % John MacFarlane
-% October 26, 2016
+% November 30, 2016
 
 Synopsis
 ========
@@ -426,7 +426,7 @@
     footnotes and links will not work across files. Reading binary
     files (docx, odt, epub) implies `--file-scope`.
 
-`--filter=`*EXECUTABLE*
+`--filter=`*PROGRAM*
 
 :   Specify an executable to be used as a filter transforming the
     pandoc AST after the input is parsed and before the output is
@@ -450,12 +450,6 @@
     pandoc filter libraries in [PHP], [perl], and
     [javascript/node.js].
 
-    If no directory is provided pandoc will look for executable or
-    non-executable filters in the director `$DATADIR/filters`, and
-    then for executable filters in the user's `PATH`. If you want to
-    run a script in the working directory, preface the filename with
-    `./`.
-
     In order of preference, pandoc will look for filters in
 
      1. a specified full or relative path (executable or
@@ -690,17 +684,18 @@
 
 :   Deprecated synonym for `--top-level-division=chapter`.
 
-`--top-level-division=[section|chapter|part]`
+`--top-level-division=[default|section|chapter|part]`
 
 :   Treat top-level headers as the given division type in LaTeX, ConTeXt,
     DocBook, and  TEI output. The hierarchy order is part, chapter, then section;
     all headers are shifted such that the top-level header becomes the specified
-    type.  The default is `section`. When the LaTeX document class is set to
-    `report`, `book`, or `memoir` (unless the `article` option is specified),
-    `chapter` is implied as the setting for this option.  If `beamer` is the
-    output format, specifying either `chapter` or `part` will cause top-level
-    headers to become `\part{..}`, while second-level headers remain as their
-    default type.
+    type. The default behavior is to determine the best division type via
+    heuristics: unless other conditions apply, `section` is chosen. When the
+    LaTeX document class is set to `report`, `book`, or `memoir` (unless the
+    `article` option is specified), `chapter` is implied as the setting for this
+    option. If `beamer` is the output format, specifying either `chapter` or
+    `part` will cause top-level headers to become `\part{..}`, while
+    second-level headers remain as their default type.
 
 `-N`, `--number-sections`
 
@@ -1832,8 +1827,9 @@
 information to do syntax highlighting. Currently, the only output formats
 that uses this information are HTML and LaTeX. If highlighting is supported
 for your output format and language, then the code block above will appear
-highlighted, with numbered lines. (To see which languages are supported, do
-`pandoc --version`.) Otherwise, the code block above will appear as follows:
+highlighted, with numbered lines. (To see which languages are supported, type
+`pandoc --list-highlight-languages`.) Otherwise, the code block above will
+appear as follows:
 
     <pre id="mycode" class="haskell numberLines" startFrom="100">
       <code>
@@ -2356,11 +2352,28 @@
 The row of `=`s separates the header from the table body, and can be
 omitted for a headerless table. The cells of grid tables may contain
 arbitrary block elements (multiple paragraphs, code blocks, lists,
-etc.). Alignments are not supported, nor are cells that span multiple
-columns or rows. Grid tables can be created easily using [Emacs table mode].
+etc.). Cells that span multiple columns or rows are not
+supported. Grid tables can be created easily using [Emacs table mode].
 
 [Emacs table mode]: http://table.sourceforge.net/
 
+Alignments can be specified as with pipe tables, by putting
+colons at the boundaries of the separator line after the
+header:
+
+    +---------------+---------------+--------------------+
+    | Right         | Left          | Centered           |
+    +==============:+:==============+:==================:+
+    | Bananas       | $1.34         | built-in wrapper   |
+    +---------------+---------------+--------------------+
+
+For headerless tables, the colons go on the top line instead:
+
+    +--------------:+:--------------+:------------------:+
+    | Right         | Left          | Centered           |
+    +---------------+---------------+--------------------+
+
+
 #### Extension: `pipe_tables` ####
 
 Pipe tables look like this:
@@ -2719,6 +2732,10 @@
 (The semicolon is optional and there may be space after the
 colon.) This will work in all output formats that support small caps.
 
+Alternatively, you can also use the new `bracketed_spans` syntax:
+
+    [Small caps]{style="font-variant:small-caps;"}
+
 Math
 ----
 
@@ -3908,15 +3925,16 @@
 ===================
 
 Pandoc will automatically highlight syntax in [fenced code blocks] that
-are marked with a language name.  The Haskell library [highlighting-kate] is used for
-highlighting, which works in HTML, Docx, and LaTeX/PDF output.
+are marked with a language name.  The Haskell library [highlighting-kate] is
+used for highlighting, which works in HTML, Docx, and LaTeX/PDF output.
+To see a list of language names that pandoc will recognize, type
+`pandoc --list-highlight-languages`.
+
 The color scheme can be selected using the `--highlight-style` option.
 The default color scheme is `pygments`, which imitates the default color
-scheme used by the Python library pygments, but pygments is not actually
-used to do the highlighting.
-
-To see a list of language names that pandoc will recognize, type
-`pandoc --version`.
+scheme used by the Python library pygments (though pygments is not actually
+used to do the highlighting).  To see a list of highlight styles,
+type `pandoc --list-hightlight-styles`.
 
 To disable highlighting, use the `--no-highlight` option.
 
diff --git a/benchmark/benchmark-pandoc.hs b/benchmark/benchmark-pandoc.hs
--- a/benchmark/benchmark-pandoc.hs
+++ b/benchmark/benchmark-pandoc.hs
@@ -20,7 +20,6 @@
 import Criterion.Types (Config(..))
 import Data.Maybe (mapMaybe)
 import Debug.Trace (trace)
-import Text.Pandoc.Error
 
 readerBench :: Pandoc
             -> (String, ReaderOptions -> String -> IO (Either PandocError Pandoc))
diff --git a/benchmark/weigh-pandoc.hs b/benchmark/weigh-pandoc.hs
new file mode 100644
--- /dev/null
+++ b/benchmark/weigh-pandoc.hs
@@ -0,0 +1,37 @@
+import Weigh
+import Text.Pandoc
+
+main :: IO ()
+main = do
+  doc <- read <$> readFile "tests/testsuite.native"
+  mainWith $ do
+    func "Pandoc document" id doc
+    mapM_
+      (\(n,r) -> weighReader doc n (handleError . r def{ readerSmart = True }))
+      [("markdown", readMarkdown)
+      ,("html", readHtml)
+      ,("docbook", readDocBook)
+      ,("latex", readLaTeX)
+      ,("commonmark", readCommonMark)
+      ]
+    mapM_
+      (\(n,w) -> weighWriter doc n (w def))
+      [("markdown", writeMarkdown)
+      ,("html", writeHtmlString)
+      ,("docbook", writeDocbook)
+      ,("latex", writeLaTeX)
+      ,("commonmark", writeCommonMark)
+      ]
+
+weighWriter :: Pandoc -> String -> (Pandoc -> String) -> Weigh ()
+weighWriter doc name writer = func (name ++ " writer") writer doc
+
+weighReader :: Pandoc -> String -> (String -> Pandoc) -> Weigh ()
+weighReader doc name reader = do
+  case lookup name writers of
+       Just (PureStringWriter writer) ->
+         let inp = writer def{ writerWrapText = WrapAuto} doc
+         in func (name ++ " reader") reader inp
+       _ -> return () -- no writer for reader
+
+
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,285 @@
+pandoc (1.19)
+
+  * Changed resolution of filter paths.
+
+    + We now first treat the argument of `--filter` as a full (absolute
+      or relative) path, looking for a program there.  If it's found,
+      we run it.
+    + If not, and if it is a simple program name or a relative path,
+      we try resolving it relative to `$DATADIR/filters`.
+    + If this fails, then we treat it as a program name and look in
+      the user's PATH.
+    + Removed a hardcoded '/' that may have caused problems with Windows
+      paths.
+
+    Previously if you did `--filter foo` and you had `foo` in your
+    path and also an executable `foo` in your working directory,
+    the one in the path would be used. Now the one in the working
+    directory is used.
+
+    In addition, when you do `--filter foo/bar.hs`, pandoc will now
+    find a filter `$DATADIR/filters/foo/bar.hs` -- assuming there
+    isn't a `foo/bar.hs` relative to the working directory.
+
+  * Allow `file://` URIs as arguments (#3196).  Also improved default reader
+    format detection.  Previously with a URI ending in .md or .markdown,
+    pandoc would assume HTML input.  Now it treats these as markdown.
+
+  * Allow to overwrite top-level division type heuristics (#3258,
+    Albert Krewinkel).  Pandoc uses heuristics to determine the most
+    reasonable top-level division type when emitting LaTeX or Docbook markup.
+    It is now possible to overwrite this implicitly set top-level division
+    via the `top-level-division` command line parameter.
+
+  * Text.Pandoc.Options [API changes]:
+
+    + Removed `writerStandalone` field in `WriterOptions`,
+      made `writerTemplate` a `Maybe` value.  Previously setting
+      `writerStandalone = True` did nothing unless a template was
+      provided in writerTemplate.  Now a fragment will be generated
+      if `writerTemplate` is `Nothing`; otherwise, the specified
+      template will be used and standalone output generated.
+    + `Division` has been renamed `TopLevelDivision` (#3197).
+      The `Section`, `Chapter`, and `Part` constructors were
+      renamed to `TopLevelSection`, `TopLevelChapter`, and
+      `TopLevelPart`, respectively. An additional `TopLevelDefault`
+      constructor was added, which is now also the new default value of the
+      `writerTopLevelDivision` field in `WriterOptions`.
+
+  * Improved error if they give wrong arg to `--top-level-division`.
+
+  * Use new module from texmath to lookup MS font codepoints in Docx
+    reader.  Removed unexported module Text.Pandoc.Readers.Docx.Fonts.
+    Its code now lives in texmath (0.9).
+
+  * DocBook reader: Fixed xref lookup (#3243).
+    It previously only worked when the qnames lacked the docbook
+    namespace URI.
+
+  * HTML reader:
+
+    + Improved table parsing (#3027).  We now check explicitly for non-1
+      rowspan or colspan attributes, and fail when we encounter them.
+      Previously we checked that each row had the same number of cells,
+      but that could be true even with rowspans/colspans.
+      And there are cases where it isn't true in tables that
+      we can handle fine -- e.g. when a tr element is empty.
+      So now we just pad rows with empty cells when needed.
+    + Treat `<math>` as MathML by default unless something else
+      is explicitly specified in xmlns.  Provided it parses as MathML,
+      of course.  Also fixed default which should be to inline math if no
+      display attribute is used.
+    + Only treat "a" element as link if it has href (#3226).  Otherwise
+      treat as span.
+
+  * Docx reader (Jesse Rosenthal):
+
+    + Add a placeholder value for CHART.  We wrap `[CHART]` in a
+      `<span class="chart">`. Note that it maps to inlines because, in docx,
+      anything in a drawing tag can be part of a larger paragraph.
+    + Be more specific in parsing images We not only want `w:drawing`,
+      because that could also include charts. Now we specify
+      `w:drawing/pic:pic`. This shouldn't change behavior at all, but it's
+      a first step toward allowing other sorts of drawing data as well.
+    + Abstract out function to avoid code repetition.
+    + Update tests for img title and alt (#3204).
+    + Handle Alt text and titles in images.  We use the "description" field
+      as alt text and the "title" field as title. These can be accessed
+      through the "Format Picture" dialog in Word.
+    + Docx reader utils: handle empty namespace in `elemName`.
+      Previously, if given an empty namespace `(elemName ns "" "foo")`
+      `elemName` would output a QName with a `Just ""` namespace. This is
+      never what we want. Now we output a `Nothing`. If someone *does* want a
+      `Just ""` in the namespace, they can enter the QName value explicitly.
+
+  * ODT reader/writer:
+
+    + Inline code when text has a special style (Hubert Plociniczak).  When
+      a piece of text has a text `Source_Text` then we assume that this is a
+      piece of the document that represents a code that needs to be inlined.
+      Adapted the writer to also reflect that change. Previously it was just
+      writing a 'preformatted' text using a non-distinguishable font style.
+      Code blocks are still not recognized by the ODT reader.  That's a
+      separate issue.
+    + Infer table's caption from the paragraph (#3224, Hubert Plociniczak).
+      ODT's reader always put empty captions for the parsed tables. This commit
+
+      1. checks paragraphs that follow the table definition
+      2. treats specially a paragraph with a style named 'Table'
+      3. does some postprocessing of the paragraphs that combines
+         tables followed immediately by captions
+
+      The ODT writer used the `TableCaption` style for the caption
+      paragraph. This commit follows the OpenOffice approach which
+      allows for appending captions to table but uses a built-in style
+      named `Table` instead of `TableCaption`. Users of a custom
+      `reference.odt` should change the style's name from `TableCaption`
+      to `Table`.
+
+  * ODT reader: Infer tables' header props from rows (#3199, Hubert
+    Plociniczak).  ODT reader simply provided an empty header list
+    which meant that the contents of the whole table, even if not empty,
+    was simply ignored.  While we still do not infer headers we at least
+    have to provide default properties of columns.
+
+  * Markdown reader:
+
+    + Allow reference link labels starting with `@...` if `citations`
+      extension disabled (#3209).  Example:  in
+
+        [link text][@a]
+
+        [@a]: url
+
+    `link text` isn't hyperlinked because `[@a]` is parsed as a citation.
+    Previously this happened whether or not the `citations` extension was
+    enabled. Now it happens only if the `citations` extension is enabled.
+    + Allow alignments to be specified in Markdown grid tables.  For example,
+
+         +---------------+---------------+--------------------+
+         | Right         | Left          | Centered           |
+         +==============:+:==============+:==================:+
+         | Bananas       | $1.34         | built-in wrapper   |
+         +---------------+---------------+--------------------+
+
+    + Allow Small Caps elements to be created using bracketed spans
+      (as they already can be using HTML-syntax spans) (#3191, Kolen Cheung).
+
+  * LaTeX reader:
+
+    + Don't treat `\vspace` and `\hspace` as block commands (#3256).
+      Fixed an error which came up, for example, with `\vspace`
+      inside a caption.  (Captions expect inlines.)
+    + Improved table handling.  We can now parse all of the tables emitted
+      by pandoc in our tests.  The only thing we don't get yet are
+      alignments and column widths in more complex tables.  See #2669.
+    + Limited support for minipage.
+    + Allow for `[]`s inside LaTeX optional args.  Fixes cases like:
+
+        \begin{center}
+        \begin{tikzpicture}[baseline={([yshift=+-.5ex]current bounding box.center)}, level distance=24pt]
+        \Tree [.{S} [.NP John\index{i} ] [.VP [.V likes ] [.NP himself\index{i,*j} ]]]
+        \end{tikzpicture}
+        \end{center}
+    + Handle BVerbatim from fancyvrb (#3203).
+    + Handle hungarumlaut (#3201).
+    + Allow beamer-style `<...>` options in raw LaTeX (also in Markdown)
+      (#3184).  This allows use of things like `\only<2,3>{my content}` in
+      Markdown that is going to be converted to beamer.
+
+  * Use pre-wrap for code in dzslides template (Nicolas Porcel).
+    Otherwise overly long code will appear on every slide.
+
+  * Org reader (Albert Krewinkel):
+
+    + Respect column width settings (#3246).  Table column properties can
+      optionally specify a column's width with which it is displayed in
+      the buffer. Some exporters, notably the ODT exporter in org-mode v9.0,
+      use these values to calculate relative column widths. The org reader now
+      implements the same behavior.  Note that the org-mode LaTeX and HTML
+      exporters in Emacs don't support this feature yet, which should be kept
+      in mind by users who use the column widths parameters.
+    + Allow HTML attribs on non-figure images (#3222).  Images which are the
+      only element in a paragraph can still be given HTML attributes, even if
+      the image does not have a caption and is hence not a figure.
+      The following will add set the `width` attribute of the image to `50%`:
+
+        #+ATTR_HTML: :width 50%
+        [[file:image.jpg]]
+
+    + Support `ATTR_HTML` for special blocks (#3182).
+      Special blocks (i.e. blocks with unrecognized names) can be prefixed
+      with an `ATTR_HTML` block attribute.  The attributes defined in that
+      meta-directive are added to the `Div` which is used to represent the
+      special block.
+    + Support the `todo` export option.  The `todo` export option allows to
+      toggle the inclusion of TODO keywords in the output.  Setting this to
+      `nil` causes TODO keywords to be dropped from headlines.  The default
+      is to include the keywords.
+    + Add support for todo-markers.  Headlines can have optional todo-markers
+      which can be controlled via the `#+TODO`, `#+SEQ_TODO`, or `#+TYP_TODO`
+      meta directive.  Multiple such directives can be given, each adding a
+      new set of recognized todo-markers.  If no custom todo-markers are
+      defined, the default `TODO` and `DONE` markers are used.  Todo-markers
+      are conceptually separate from headline text and are hence excluded
+      when autogenerating headline IDs.  The markers are rendered as spans
+      and labelled with two classes: One class is the markers name, the other
+      signals the todo-state of the marker (either `todo` or `done`).
+
+  * LaTeX writer:
+
+    + Use `\autocites*` when "suppress-author" citation used.
+    + Ensure that simple tables have simple cells (#2666).  If cells contain
+      more than a single Plain or Para, then we need to set nonzero widths
+      and put contents into minipages.
+    + Remove invalid inlines in sections (#3218, Hubert Plociniczak).
+
+  * Markdown writer:
+
+    + Fix calculation of column widths for aligned multiline tables
+      (#1911, Björn Peemöller).  This also fixes excessive CPU and memory
+      usage for tables when `--columns` is set in such a way that cells
+      must be very tiny.  Now cells are guaranteed to be big enough so that
+      single words don't need to line break, even if this pushes the
+      line length above the column width.
+    + Use bracketed form for native spans when `bracketed_spans`
+      enabled (#3229).
+    + Fixed inconsistent spacing issue (#3232).  Previously a tight bullet
+      sublist got rendered with a blank line after, while a tight ordered
+      sublist did not.  Now we don't get the blank line in either case.
+    + Fix escaping of spaces in super/subscript (#3225).  Previously two
+      backslashes were inserted, which gave a literal backslash.
+    + Adjust widths in Markdown grid tables so that they match on round-trip.
+
+  * Docx writer:
+
+    + Give full detail when there are errors converting tex math.
+    + Handle title text in images (Jesse Rosenthal).  We already handled alt
+      text.  This just puts the image "title" into the docx "title" attr.
+    + Fixed XML markup for empty cells (#3238).  Previously the Compact
+      style wasn't being applied properly to empty cells.
+
+  * HTML writer:
+
+    + Updated `renderHtml` import from blaze-html.
+
+  * Text.Pandoc.Pretty:
+
+    + Fixed some bugs that caused blank lines in tables (#3251).
+      The bugs caused spurious blank lines in grid tables when we
+      had things like ``blankline $$ blankline``.
+    + Add exported function `minOffet` [API change] (Björn Peemöller).
+    + Added error message for illegal call to `block` (Björn Peemöller).
+
+  * Text.Pandoc.Shared:
+
+    + Put `warn` in MonadIO.
+    + `fetchItem`:  Better handling of protocol-relative URL (#2635).
+      If URL starts with `//` and there is no "base URL" (as there
+      would be if a URL were used on the command line), then default
+      to http:.
+
+  * Export Text.Pandoc.getDefaultExtensions [API change] (#3178).
+
+  * In --version, trap error in `getAppUserDataDirectory` (#3241).
+    This fixes a crash with `pandoc --version` on unusual systems with
+    no real user (e.g. SQL Server 2016).
+
+  * Added weigh-pandoc for memory usage diagnostics (#3169).
+
+  * Use correct mime types for woff and woff2 (#3228).
+
+  * Remove make_travis_yml.hs (#3235, Kolen Cheung).
+
+  * changelog:  Moved an item that was misplaced in the 1.17.2 section to
+    the 1.18 section where it belongs.
+
+  * CONTRIBUTING.md: minor change in wording and punctuation (#3252,
+    Kolen Cheung).
+
+  * Further revisions to manual for `--version` changes (#3244).
+
+
 pandoc (1.18)
 
   * Added `--list-input-formats`, `--list-output-formats`,
@@ -261,6 +543,9 @@
       This allows figure placement defaults to be changed by the user
       in the template.
 
+  * HTML writer (slide show formats): In slide shows, don't change slide title
+    to level 1 header (#2221).
+
   * TEI writer: remove heuristic to detect book template (Albert Krewinkel).
     TEI doesn't have `<book>` elements but only generic `<divN>` division
     elements. Checking the template for a trailing `</book>` is nonsensical.
@@ -462,7 +747,6 @@
       LaTeX environments that MathJax can handle get passed through.
       This patch also causes raw LaTeX environments to be treated
       as math, when possible, with MathML and WebTeX output.
-    + In slide shows, don't change slide title to level 1 header (#2221).
 
   * Markdown writer:  use raw HTML for simple, pipe tables with linebreaks
     (#2993).  Markdown line breaks involve a newline, and simple and pipe
diff --git a/data/odt/styles.xml b/data/odt/styles.xml
--- a/data/odt/styles.xml
+++ b/data/odt/styles.xml
@@ -133,7 +133,7 @@
       style:font-size-complex="12pt"
       style:font-style-complex="italic" />
     </style:style>
-    <style:style style:name="TableCaption" style:family="paragraph"
+    <style:style style:name="Table" style:family="paragraph"
     style:parent-style-name="Caption" style:class="extra">
     </style:style>
     <style:style style:name="FigureCaption" style:family="paragraph"
@@ -237,6 +237,13 @@
       style:font-name-complex="Courier New"
       style:font-size-complex="10pt" />
     </style:style>
+    <style:style style:name="Source_Text" style:family="text">
+      <style:text-properties style:font-name="Courier New"
+      fo:font-size="10pt" style:font-name-asian="Courier New"
+      style:font-size-asian="10pt"
+      style:font-name-complex="Courier New"
+      style:font-size-complex="10pt" />
+    </style:style>
     <style:style style:name="Definition_20_Term"
     style:display-name="Definition Term" style:family="paragraph"
     style:parent-style-name="Standard"
@@ -381,6 +388,7 @@
       style:font-name-asian="Courier New"
       style:font-name-complex="Courier New" />
     </style:style>
+
     <style:style style:name="Internet_20_link"
     style:display-name="Internet link" style:family="text">
       <style:text-properties fo:color="#000080"
diff --git a/data/templates/default.dzslides b/data/templates/default.dzslides
--- a/data/templates/default.dzslides
+++ b/data/templates/default.dzslides
@@ -12,7 +12,7 @@
   <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$">
 $endif$
   <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
-  <style type="text/css">code{white-space: pre;}</style>
+  <style type="text/css">code{white-space: pre-wrap;}</style>
 $if(quotes)$
   <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style>
 $endif$
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 "October 26, 2016" "pandoc 1.18"
+.TH PANDOC 1 "November 30, 2016" "pandoc 1.19"
 .SH NAME
 pandoc - general markup converter
 .SH SYNOPSIS
@@ -446,7 +446,7 @@
 .RS
 .RE
 .TP
-.B \f[C]\-\-filter=\f[]\f[I]EXECUTABLE\f[]
+.B \f[C]\-\-filter=\f[]\f[I]PROGRAM\f[]
 Specify an executable to be used as a filter transforming the pandoc AST
 after the input is parsed and before the output is written.
 The executable should read JSON from stdin and write JSON to stdout.
@@ -480,12 +480,6 @@
 There are also pandoc filter libraries in PHP, perl, and
 javascript/node.js.
 .PP
-If no directory is provided pandoc will look for executable or
-non\-executable filters in the director \f[C]$DATADIR/filters\f[], and
-then for executable filters in the user\[aq]s \f[C]PATH\f[].
-If you want to run a script in the working directory, preface the
-filename with \f[C]\&./\f[].
-.PP
 In order of preference, pandoc will look for filters in
 .IP "1." 3
 a specified full or relative path (executable or non\-executable)
@@ -773,12 +767,13 @@
 .RS
 .RE
 .TP
-.B \f[C]\-\-top\-level\-division=[section|chapter|part]\f[]
+.B \f[C]\-\-top\-level\-division=[default|section|chapter|part]\f[]
 Treat top\-level headers as the given division type in LaTeX, ConTeXt,
 DocBook, and TEI output.
 The hierarchy order is part, chapter, then section; all headers are
 shifted such that the top\-level header becomes the specified type.
-The default is \f[C]section\f[].
+The default behavior is to determine the best division type via
+heuristics: unless other conditions apply, \f[C]section\f[] is chosen.
 When the LaTeX document class is set to \f[C]report\f[], \f[C]book\f[],
 or \f[C]memoir\f[] (unless the \f[C]article\f[] option is specified),
 \f[C]chapter\f[] is implied as the setting for this option.
@@ -2277,8 +2272,9 @@
 and LaTeX.
 If highlighting is supported for your output format and language, then
 the code block above will appear highlighted, with numbered lines.
-(To see which languages are supported, do \f[C]pandoc\ \-\-version\f[].)
-Otherwise, the code block above will appear as follows:
+(To see which languages are supported, type
+\f[C]pandoc\ \-\-list\-highlight\-languages\f[].) Otherwise, the code
+block above will appear as follows:
 .IP
 .nf
 \f[C]
@@ -2913,9 +2909,31 @@
 be omitted for a headerless table.
 The cells of grid tables may contain arbitrary block elements (multiple
 paragraphs, code blocks, lists, etc.).
-Alignments are not supported, nor are cells that span multiple columns
-or rows.
+Cells that span multiple columns or rows are not supported.
 Grid tables can be created easily using Emacs table mode.
+.PP
+Alignments can be specified as with pipe tables, by putting colons at
+the boundaries of the separator line after the header:
+.IP
+.nf
+\f[C]
++\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
+|\ Right\ \ \ \ \ \ \ \ \ |\ Left\ \ \ \ \ \ \ \ \ \ |\ Centered\ \ \ \ \ \ \ \ \ \ \ |
++==============:+:==============+:==================:+
+|\ Bananas\ \ \ \ \ \ \ |\ $1.34\ \ \ \ \ \ \ \ \ |\ built\-in\ wrapper\ \ \ |
++\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
+\f[]
+.fi
+.PP
+For headerless tables, the colons go on the top line instead:
+.IP
+.nf
+\f[C]
++\-\-\-\-\-\-\-\-\-\-\-\-\-\-:+:\-\-\-\-\-\-\-\-\-\-\-\-\-\-+:\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-:+
+|\ Right\ \ \ \ \ \ \ \ \ |\ Left\ \ \ \ \ \ \ \ \ \ |\ Centered\ \ \ \ \ \ \ \ \ \ \ |
++\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
+\f[]
+.fi
 .SS Extension: \f[C]pipe_tables\f[]
 .PP
 Pipe tables look like this:
@@ -3388,6 +3406,14 @@
 .PP
 (The semicolon is optional and there may be space after the colon.) This
 will work in all output formats that support small caps.
+.PP
+Alternatively, you can also use the new \f[C]bracketed_spans\f[] syntax:
+.IP
+.nf
+\f[C]
+[Small\ caps]{style="font\-variant:small\-caps;"}
+\f[]
+.fi
 .SS Math
 .SS Extension: \f[C]tex_math_dollars\f[]
 .PP
@@ -4890,14 +4916,16 @@
 are marked with a language name.
 The Haskell library highlighting\-kate is used for highlighting, which
 works in HTML, Docx, and LaTeX/PDF output.
+To see a list of language names that pandoc will recognize, type
+\f[C]pandoc\ \-\-list\-highlight\-languages\f[].
+.PP
 The color scheme can be selected using the \f[C]\-\-highlight\-style\f[]
 option.
 The default color scheme is \f[C]pygments\f[], which imitates the
-default color scheme used by the Python library pygments, but pygments
-is not actually used to do the highlighting.
-.PP
-To see a list of language names that pandoc will recognize, type
-\f[C]pandoc\ \-\-version\f[].
+default color scheme used by the Python library pygments (though
+pygments is not actually used to do the highlighting).
+To see a list of highlight styles, type
+\f[C]pandoc\ \-\-list\-hightlight\-styles\f[].
 .PP
 To disable highlighting, use the \f[C]\-\-no\-highlight\f[] option.
 .SH CUSTOM STYLES IN DOCX OUTPUT
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,5 +1,5 @@
 Name:            pandoc
-Version:         1.18
+Version:         1.19
 Cabal-Version:   >= 1.10
 Build-Type:      Custom
 License:         GPL
@@ -236,6 +236,10 @@
   Description:   Build trypandoc cgi executable.
   Default:       False
 
+Flag weigh-pandoc
+  Description:   Build weigh-pandoc to measure memory usage.
+  Default:       False
+
 Flag https
   Description:   Enable support for downloading of resources over https.
   Default:       True
@@ -263,7 +267,7 @@
                  text >= 0.11 && < 1.3,
                  zip-archive >= 0.2.3.4 && < 0.4,
                  HTTP >= 4000.0.5 && < 4000.4,
-                 texmath >= 0.8.6.5 && < 0.9,
+                 texmath >= 0.9 && < 0.10,
                  xml >= 1.3.12 && < 1.4,
                  random >= 1 && < 1.2,
                  extensible-exceptions >= 0.1 && < 0.2,
@@ -384,7 +388,6 @@
   Other-Modules:   Text.Pandoc.Readers.Docx.Lists,
                    Text.Pandoc.Readers.Docx.Combine,
                    Text.Pandoc.Readers.Docx.Parse,
-                   Text.Pandoc.Readers.Docx.Fonts,
                    Text.Pandoc.Readers.Docx.Util,
                    Text.Pandoc.Readers.Docx.StyleMap,
                    Text.Pandoc.Readers.Odt.Base,
@@ -471,6 +474,22 @@
     Buildable:     True
   else
     Buildable:     False
+
+Executable weigh-pandoc
+  Main-Is:         weigh-pandoc.hs
+  Hs-Source-Dirs:  benchmark
+  if impl(ghc < 7.10)
+     Hs-Source-Dirs: prelude
+     Other-Modules:  Prelude
+  if flag(weigh-pandoc)
+     Build-Depends:   pandoc,
+                      base >= 4.2 && < 5,
+                      weigh >= 0.0 && < 0.1
+     Buildable:       True
+  else
+    Buildable:     False
+  Ghc-Options:   -rtsopts -Wall -fno-warn-unused-do-bind
+  Default-Language: Haskell98
 
 Test-Suite test-pandoc
   Type:           exitcode-stdio-1.0
diff --git a/pandoc.hs b/pandoc.hs
--- a/pandoc.hs
+++ b/pandoc.hs
@@ -115,46 +115,33 @@
 
 externalFilter :: FilePath -> [String] -> Pandoc -> IO Pandoc
 externalFilter f args' d = do
-      mbexe <- if '/' `elem` f
-                  -- don't check PATH if filter name has a path
-                  then return Nothing
-                  -- we catch isDoesNotExistError because this will
-                  -- be triggered if PATH not set:
-                  else E.catch (findExecutable f)
-                                 (\e -> if isDoesNotExistError e
-                                           then return Nothing
-                                           else throwIO e)
-      (f', args'') <- case mbexe of
-                           Just x  -> return (x, args')
-                           Nothing -> do
-                             exists <- doesFileExist f
-                             if exists
-                                then do
-                                  isExecutable <- executable `fmap`
-                                                    getPermissions f
-                                  return $
-                                    case map toLower $ takeExtension f of
-                                         _ | isExecutable -> (f, args')
-                                         ".py"  -> ("python", f:args')
-                                         ".hs"  -> ("runhaskell", f:args')
-                                         ".pl"  -> ("perl", f:args')
-                                         ".rb"  -> ("ruby", f:args')
-                                         ".php" -> ("php", f:args')
-                                         ".js"  -> ("node", f:args')
-                                         _      -> (f, args')
-                                else err 85 $ "Filter " ++ f ++ " not found"
-      when (f' /= f) $ do
-          mbExe <- findExecutable f'
-          when (isNothing mbExe) $
-            err 83 $ "Error running filter " ++ f ++ "\n" ++
-                      show f' ++ " not found in path."
-      (exitcode, outbs, errbs) <- E.handle filterException $
-                                    pipeProcess Nothing f' args'' $ encode d
-      unless (B.null errbs) $ B.hPutStr stderr errbs
-      case exitcode of
-           ExitSuccess    -> return $ either error id $ eitherDecode' outbs
-           ExitFailure ec -> err 83 $ "Error running filter " ++ f ++ "\n" ++
-                                       "Filter returned error status " ++ show ec
+  exists <- doesFileExist f
+  isExecutable <- if exists
+                     then executable <$> getPermissions f
+                     else return True
+  let (f', args'') = if exists
+                        then case map toLower (takeExtension f) of
+                                  _ | isExecutable -> ("." </> f, args')
+                                  ".py"  -> ("python", f:args')
+                                  ".hs"  -> ("runhaskell", f:args')
+                                  ".pl"  -> ("perl", f:args')
+                                  ".rb"  -> ("ruby", f:args')
+                                  ".php" -> ("php", f:args')
+                                  ".js"  -> ("node", f:args')
+                                  _      -> (f, args')
+                        else (f, args')
+  unless (exists && isExecutable) $ do
+    mbExe <- findExecutable f'
+    when (isNothing mbExe) $
+      err 83 $ "Error running filter " ++ f ++  ":\n" ++
+               "Could not find executable '" ++ f' ++ "'."
+  (exitcode, outbs, errbs) <- E.handle filterException $
+                              pipeProcess Nothing f' args'' $ encode d
+  unless (B.null errbs) $ B.hPutStr stderr errbs
+  case exitcode of
+       ExitSuccess    -> return $ either error id $ eitherDecode' outbs
+       ExitFailure ec -> err 83 $ "Error running filter " ++ f ++ "\n" ++
+                                  "Filter returned error status " ++ show ec
  where filterException :: E.SomeException -> IO a
        filterException e = err 83 $ "Error running filter " ++ f ++ "\n" ++
                                        show e
@@ -194,7 +181,7 @@
     , optHtmlQTags         :: Bool    -- ^ Use <q> tags in HTML
     , optHighlight         :: Bool    -- ^ Highlight source code
     , optHighlightStyle    :: Style   -- ^ Style to use for highlighted code
-    , optTopLevelDivision  :: Division -- ^ Type of the top-level divisions
+    , optTopLevelDivision  :: TopLevelDivision -- ^ Type of the top-level divisions
     , optHTMLMathMethod    :: HTMLMathMethod -- ^ Method to print HTML math
     , optReferenceODT      :: Maybe FilePath -- ^ Path of reference.odt
     , optReferenceDocx     :: Maybe FilePath -- ^ Path of reference.docx
@@ -259,7 +246,7 @@
     , optHtmlQTags             = False
     , optHighlight             = True
     , optHighlightStyle        = pygments
-    , optTopLevelDivision      = Section
+    , optTopLevelDivision      = TopLevelDefault
     , optHTMLMathMethod        = PlainMath
     , optReferenceODT          = Nothing
     , optReferenceDocx         = Nothing
@@ -611,14 +598,17 @@
                  (NoArg
                   (\opt -> do warn $ "--chapters is deprecated. " ++
                                      "Use --top-level-division=chapter instead."
-                              return opt { optTopLevelDivision = Chapter }))
+                              return opt { optTopLevelDivision = TopLevelChapter }))
                  "" -- "Use chapter for top-level sections in LaTeX, DocBook"
 
     , Option "" ["top-level-division"]
                  (ReqArg
-                  (\arg opt -> case safeRead (uppercaseFirstLetter arg) of
-                      Just dvsn -> return opt { optTopLevelDivision = dvsn }
-                      _         -> err 76 "could not parse top-level division")
+                  (\arg opt -> do
+                      let tldName = "TopLevel" ++ uppercaseFirstLetter arg
+                      case safeRead tldName of
+                        Just tlDiv -> return opt { optTopLevelDivision = tlDiv }
+                        _       -> err 76 ("Top-level division must be " ++
+                                           "section,  chapter, part, or default"))
                    "[section|chapter|part]")
                  "" -- "Use top-level division type in LaTeX, ConTeXt, DocBook"
 
@@ -975,7 +965,10 @@
                  (NoArg
                   (\_ -> do
                      prg <- getProgName
-                     defaultDatadir <- getAppUserDataDirectory "pandoc"
+                     defaultDatadir <- E.catch
+                            (getAppUserDataDirectory "pandoc")
+                            (\e -> let _ = (e :: E.SomeException)
+                                   in  return "")
                      UTF8.hPutStrLn stdout (prg ++ " " ++ pandocVersion ++
                        compileInfo ++ "\nDefault user data directory: " ++
                        defaultDatadir ++ copyrightMessage)
@@ -1019,6 +1012,8 @@
     ".xhtml"    -> "html"
     ".html"     -> "html"
     ".htm"      -> "html"
+    ".md"       -> "markdown"
+    ".markdown" -> "markdown"
     ".tex"      -> "latex"
     ".latex"    -> "latex"
     ".ltx"      -> "latex"
@@ -1106,19 +1101,22 @@
 applyTransforms :: [Transform] -> Pandoc -> IO Pandoc
 applyTransforms transforms d = return $ foldr ($) d transforms
 
-  -- First we check to see if a filter is a path. If it isn't, we
-  -- check to see whether it's in `userdir/filters`. If not, we leave
-  -- it unchanged.
+  -- 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 :: Maybe FilePath -> FilePath -> IO FilePath
-expandFilterPath mbDatadir fp
-  | '/' `elem` fp = return fp
-  | Just datadir <- mbDatadir = do
-      let filterPath = (datadir </> "filters" </> fp)
-      filterPathExists <- doesFileExist filterPath
-      if filterPathExists
-        then return filterPath
-        else return fp
-  | otherwise = return fp
+expandFilterPath mbDatadir fp = do
+  fpExists <- doesFileExist fp
+  if fpExists
+     then return fp
+     else case mbDatadir of
+               Just datadir | isRelative fp -> do
+                 let filterPath = (datadir </> "filters" </> fp)
+                 filterPathExists <- doesFileExist filterPath
+                 if filterPathExists
+                    then return filterPath
+                    else return fp
+               _ -> return fp
 
 applyFilters :: Maybe FilePath -> [FilePath] -> [String] -> Pandoc -> IO Pandoc
 applyFilters mbDatadir filters args d = do
@@ -1294,18 +1292,18 @@
   let standalone' = standalone || not (isTextFormat format) || pdfOutput
 
   templ <- case templatePath of
-                _ | not standalone' -> return ""
+                _ | not standalone' -> return Nothing
                 Nothing -> do
                            deftemp <- getDefaultTemplate datadir format
                            case deftemp of
                                  Left e   -> throwIO e
-                                 Right t  -> return t
+                                 Right t  -> return (Just t)
                 Just tp -> do
                            -- strip off extensions
                            let tp' = case takeExtension tp of
                                           ""   -> tp <.> format
                                           _    -> tp
-                           E.catch (UTF8.readFile tp')
+                           Just <$> E.catch (UTF8.readFile tp')
                              (\e -> if isDoesNotExistError e
                                        then E.catch
                                              (readDataFileUTF8 datadir
@@ -1375,6 +1373,8 @@
       readSource src = case parseURI src of
                             Just u | uriScheme u `elem` ["http:","https:"] ->
                                        readURI src
+                                   | uriScheme u == "file:" ->
+                                       UTF8.readFile (uriPath u)
                             _       -> UTF8.readFile src
       readURI src = do
         res <- openURL src
@@ -1416,8 +1416,7 @@
     _  -> do pairs <- mapM (\s -> sourceToDoc [s]) sources
              return (mconcat $ map fst pairs, mconcat $ map snd pairs)
 
-  let writerOptions = def { writerStandalone       = standalone',
-                            writerTemplate         = templ,
+  let writerOptions = def { writerTemplate         = templ,
                             writerVariables        = variables'',
                             writerTabStop          = tabStop,
                             writerTableOfContents  = toc,
diff --git a/src/Text/Pandoc.hs b/src/Text/Pandoc.hs
--- a/src/Text/Pandoc.hs
+++ b/src/Text/Pandoc.hs
@@ -123,6 +123,7 @@
                -- * Miscellaneous
                , getReader
                , getWriter
+               , getDefaultExtensions
                , ToJsonFilter(..)
                , pandocVersion
              ) where
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
@@ -498,8 +498,8 @@
            ,("wmv","video/x-ms-wmv")
            ,("wmx","video/x-ms-wmx")
            ,("wmz","application/x-ms-wmz")
-           ,("woff","application/x-font-woff")
-           ,("woff2","application/x-font-woff2")
+           ,("woff","application/font-woff")
+           ,("woff2","font/woff2")
            ,("wp5","application/wordperfect5.1")
            ,("wpd","application/wordperfect")
            ,("wrl","model/vrml")
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
@@ -43,7 +43,7 @@
                            , HTMLSlideVariant (..)
                            , EPUBVersion (..)
                            , WrapOption (..)
-                           , Division (..)
+                           , TopLevelDivision (..)
                            , WriterOptions (..)
                            , TrackChanges (..)
                            , ReferenceLocation (..)
@@ -341,10 +341,12 @@
                 deriving (Show, Read, Eq, Data, Typeable, Generic)
 
 -- | Options defining the type of top-level headers.
-data Division = Part              -- ^ Top-level headers become parts
-              | Chapter           -- ^ Top-level headers become chapters
-              | Section           -- ^ Top-level headers become sections
-              deriving (Show, Read, Eq, Ord, Data, Typeable, Generic)
+data TopLevelDivision = TopLevelPart      -- ^ Top-level headers become parts
+                      | TopLevelChapter   -- ^ Top-level headers become chapters
+                      | TopLevelSection   -- ^ Top-level headers become sections
+                      | TopLevelDefault   -- ^ Top-level type is determined via
+                                          --   heuristics
+                      deriving (Show, Read, Eq, Data, Typeable, Generic)
 
 -- | Locations for footnotes and references in markdown output
 data ReferenceLocation = EndOfBlock    -- ^ End of block
@@ -354,8 +356,7 @@
 
 -- | Options for writers
 data WriterOptions = WriterOptions
-  { writerStandalone       :: Bool   -- ^ Include header and footer
-  , writerTemplate         :: String -- ^ Template to use in standalone mode
+  { writerTemplate         :: Maybe String -- ^ Template to use
   , writerVariables        :: [(String, String)] -- ^ Variables to set in template
   , writerTabStop          :: Int    -- ^ Tabstop for conversion btw spaces and tabs
   , writerTableOfContents  :: Bool   -- ^ Include table of contents
@@ -382,7 +383,7 @@
   , writerHtmlQTags        :: Bool       -- ^ Use @<q>@ tags for quotes in HTML
   , writerBeamer           :: Bool       -- ^ Produce beamer LaTeX slide show
   , writerSlideLevel       :: Maybe Int  -- ^ Force header level of slides
-  , writerTopLevelDivision :: Division   -- ^ Type of top-level divisions
+  , writerTopLevelDivision :: TopLevelDivision -- ^ Type of top-level divisions
   , writerListings         :: Bool       -- ^ Use listings package for code
   , writerHighlight        :: Bool       -- ^ Highlight source code
   , writerHighlightStyle   :: Style      -- ^ Style to use for highlighting
@@ -403,8 +404,7 @@
   } deriving (Show, Data, Typeable, Generic)
 
 instance Default WriterOptions where
-  def = WriterOptions { writerStandalone       = False
-                      , writerTemplate         = ""
+  def = WriterOptions { writerTemplate         = Nothing
                       , writerVariables        = []
                       , writerTabStop          = 4
                       , writerTableOfContents  = False
@@ -430,7 +430,7 @@
                       , writerHtmlQTags        = False
                       , writerBeamer           = False
                       , writerSlideLevel       = Nothing
-                      , writerTopLevelDivision = Section
+                      , writerTopLevelDivision = TopLevelDefault
                       , writerListings         = False
                       , writerHighlight        = False
                       , writerHighlightStyle   = pygments
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
@@ -46,6 +46,7 @@
      , beforeNonBlank
      , nowrap
      , offset
+     , minOffset
      , height
      , lblock
      , cblock
@@ -75,8 +76,9 @@
 
 where
 import Data.Sequence (Seq, fromList, (<|), singleton, mapWithIndex, viewl, ViewL(..))
+import qualified Data.Sequence as Seq
 import Data.Foldable (toList)
-import Data.List (intercalate)
+import Data.List (intersperse)
 import Data.String
 import Control.Monad.State
 import Data.Char (isSpace)
@@ -120,7 +122,7 @@
 
 -- | True if the document is empty.
 isEmpty :: Doc -> Bool
-isEmpty = null . toList . unDoc
+isEmpty = Seq.null . unDoc
 
 -- | The empty document.
 empty :: Doc
@@ -270,10 +272,15 @@
           | otherwise -> renderDoc d >> renderList xs
     []                -> renderList xs
 
+renderList [BlankLines _] = return ()
+
+renderList (BlankLines m : BlankLines n : xs) =
+  renderList (BlankLines (max m n) : xs)
+
 renderList (BlankLines num : xs) = do
   st <- get
   case output st of
-     _ | newlines st > num || null xs -> return ()
+     _ | newlines st > num -> return ()
        | otherwise -> replicateM_ (1 + num - newlines st) (outp (-1) "\n")
   renderList xs
 
@@ -320,28 +327,30 @@
 renderList (Block i1 s1 : BreakingSpace : Block i2 s2 : xs) =
   renderList (mergeBlocks True (IsBlock i1 s1) (IsBlock i2 s2) : xs)
 
-renderList (Block width lns : xs) = do
+renderList (Block _width lns : xs) = do
   st <- get
   let oldPref = prefix st
   case column st - realLength oldPref of
         n | n > 0 -> modify $ \s -> s{ prefix = oldPref ++ replicate n ' ' }
         _         -> return ()
-  renderDoc $ blockToDoc width lns
+  renderList $ intersperse CarriageReturn (map (Text 0) lns)
   modify $ \s -> s{ prefix = oldPref }
   renderList xs
 
 mergeBlocks :: Bool -> IsBlock -> IsBlock -> D
 mergeBlocks addSpace (IsBlock w1 lns1) (IsBlock w2 lns2) =
   Block (w1 + w2 + if addSpace then 1 else 0) $
-     zipWith (\l1 l2 -> pad w1 l1 ++ l2) (lns1 ++ empties) (map sp lns2 ++ empties)
-    where empties = replicate (abs $ length lns1 - length lns2) ""
+     zipWith (\l1 l2 -> pad w1 l1 ++ l2) lns1' (map sp lns2')
+    where (lns1', lns2') = case (length lns1, length lns2) of
+                                (x, y) | x > y -> (lns1,
+                                                   lns2 ++ replicate (x - y) "")
+                                       | x < y -> (lns1 ++ replicate (y - x) "",
+                                                   lns2)
+                                       | otherwise -> (lns1, lns2)
           pad n s = s ++ replicate (n - realLength s) ' '
           sp "" = ""
           sp xs = if addSpace then (' ' : xs) else xs
 
-blockToDoc :: Int -> [String] -> Doc
-blockToDoc _ lns = text $ intercalate "\n" lns
-
 offsetOf :: D -> Int
 offsetOf (Text o _)       = o
 offsetOf (Block w _)      = w
@@ -419,9 +428,9 @@
                 []    -> 0
                 os    -> maximum os
 
-block :: (String -> String) -> Int -> Doc -> Doc
-block filler width = Doc . singleton . Block width .
-                      map filler . chop width . render (Just width)
+-- | Returns the minimal width of a 'Doc' when reflowed at breakable spaces.
+minOffset :: Doc -> Int
+minOffset d = maximum (0: map realLength (lines $ render (Just 0) d))
 
 -- | @lblock n d@ is a block of width @n@ characters, with
 -- text derived from @d@ and aligned to the left.
@@ -440,13 +449,19 @@
 height :: Doc -> Int
 height = length . lines . render Nothing
 
+block :: (String -> String) -> Int -> Doc -> Doc
+block filler width d
+  | width < 1 && not (isEmpty d) = error "Text.Pandoc.Pretty.block: width < 1"
+  | otherwise                    = Doc $ singleton $ Block width $ map filler
+                                 $ chop width $ render (Just width) d
+
 chop :: Int -> String -> [String]
 chop _ [] = []
 chop n cs = case break (=='\n') cs of
                   (xs, ys)     -> if len <= n
                                      then case ys of
                                              []     -> [xs]
-                                             (_:[]) -> [xs, ""]
+                                             ['\n'] -> [xs]
                                              (_:zs) -> xs : chop n zs
                                      else take n xs : chop n (drop n xs ++ ys)
                                    where len = realLength xs
diff --git a/src/Text/Pandoc/Readers/DocBook.hs b/src/Text/Pandoc/Readers/DocBook.hs
--- a/src/Text/Pandoc/Readers/DocBook.hs
+++ b/src/Text/Pandoc/Readers/DocBook.hs
@@ -964,9 +964,11 @@
             content <- dbContent <$> get
             let linkend = attrValue "linkend" e
             let title = case attrValue "endterm" e of
-                            ""      -> maybe "???" xrefTitleByElem (findElementById linkend content)
-                            endterm -> maybe "???" strContent (findElementById endterm content)
-            return $ link ('#' : linkend) "" (singleton (Str title))
+                            ""      -> maybe "???" xrefTitleByElem
+                                         (findElementById linkend content)
+                            endterm -> maybe "???" strContent
+                                         (findElementById endterm content)
+            return $ link ('#' : linkend) "" (text title)
         "email" -> return $ link ("mailto:" ++ strContent e) ""
                           $ str $ strContent e
         "uri" -> return $ link (strContent e) "" $ str $ strContent e
@@ -1050,4 +1052,4 @@
           where
             xrefLabel = attrValue "xreflabel" el
             descendantContent name = maybe "???" strContent
-                                   . findElement (QName name Nothing Nothing)
+                                   . filterElementName (\n -> qName n == name)
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
@@ -317,10 +317,11 @@
 runToInlines (Endnote bps) = do
   blksList <- smushBlocks <$> (mapM bodyPartToBlocks bps)
   return $ note blksList
-runToInlines (InlineDrawing fp bs ext) = do
+runToInlines (InlineDrawing fp title alt bs ext) = do
   mediaBag <- gets docxMediaBag
   modify $ \s -> s { docxMediaBag = insertMedia fp Nothing bs mediaBag }
-  return $ imageWith (extentToAttr ext) fp "" ""
+  return $ imageWith (extentToAttr ext) fp title $ text alt
+runToInlines InlineChart = return $ spanWith ("", ["chart"], []) $ text "[CHART]"
 
 extentToAttr :: Extent -> Attr
 extentToAttr (Just (w, h)) =
@@ -401,10 +402,12 @@
     unless inHdrBool
       (modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap})
     return $ spanWith (newAnchor, ["anchor"], []) mempty
-parPartToInlines (Drawing fp bs ext) = do
+parPartToInlines (Drawing fp title alt bs ext) = do
   mediaBag <- gets docxMediaBag
   modify $ \s -> s { docxMediaBag = insertMedia fp Nothing bs mediaBag }
-  return $ imageWith (extentToAttr ext) fp "" ""
+  return $ imageWith (extentToAttr ext) fp title $ text alt
+parPartToInlines Chart = do
+  return $ spanWith ("", ["chart"], []) $ text "[CHART]"
 parPartToInlines (InternalHyperLink anchor runs) = do
   ils <- smushInlines <$> mapM runToInlines runs
   return $ link ('#' : anchor) "" ils
diff --git a/src/Text/Pandoc/Readers/Docx/Fonts.hs b/src/Text/Pandoc/Readers/Docx/Fonts.hs
deleted file mode 100644
--- a/src/Text/Pandoc/Readers/Docx/Fonts.hs
+++ /dev/null
@@ -1,238 +0,0 @@
-{-
-Copyright (C) 2014 Matthew Pickering <matthewtpickering@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
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--}
-
-{- |
-   Module      : Text.Pandoc.Readers.Docx.Fonts
-   Copyright   : Copyright (C) 2014 Matthew Pickering
-   License     : GNU GPL, version 2 or above
-
-   Maintainer  : Matthew Pickering <matthewtpickering@gmail.com>
-   Stability   : alpha
-   Portability : portable
-
-Utilities to convert between font codepoints and unicode characters.
--}
-module Text.Pandoc.Readers.Docx.Fonts (getUnicode, Font(..)) where
-
-
--- | Enumeration of recognised fonts
-data Font = Symbol -- ^ <http://en.wikipedia.org/wiki/Symbol_(typeface) Adobe Symbol>
-          deriving (Show, Eq)
-
--- | Given a font and codepoint, returns the corresponding unicode
--- character
-getUnicode :: Font -> Char -> Maybe Char
-getUnicode Symbol c = lookup c symbol
-
--- Generated from lib/fonts/symbol.txt
-symbol :: [(Char, Char)]
-symbol =
-  [ (' ',' ')
-  , (' ','\160')
-  , ('!','!')
-  , ('"','\8704')
-  , ('#','#')
-  , ('$','\8707')
-  , ('%','%')
-  , ('&','&')
-  , ('\'','\8715')
-  , ('(','(')
-  , (')',')')
-  , ('*','\8727')
-  , ('+','+')
-  , (',',',')
-  , ('-','\8722')
-  , ('.','.')
-  , ('/','/')
-  , ('0','0')
-  , ('1','1')
-  , ('2','2')
-  , ('3','3')
-  , ('4','4')
-  , ('5','5')
-  , ('6','6')
-  , ('7','7')
-  , ('8','8')
-  , ('9','9')
-  , (':',':')
-  , (';',';')
-  , ('<','<')
-  , ('=','=')
-  , ('>','>')
-  , ('?','?')
-  , ('@','\8773')
-  , ('A','\913')
-  , ('B','\914')
-  , ('C','\935')
-  , ('D','\916')
-  , ('D','\8710')
-  , ('E','\917')
-  , ('F','\934')
-  , ('G','\915')
-  , ('H','\919')
-  , ('I','\921')
-  , ('J','\977')
-  , ('K','\922')
-  , ('L','\923')
-  , ('M','\924')
-  , ('N','\925')
-  , ('O','\927')
-  , ('P','\928')
-  , ('Q','\920')
-  , ('R','\929')
-  , ('S','\931')
-  , ('T','\932')
-  , ('U','\933')
-  , ('V','\962')
-  , ('W','\937')
-  , ('W','\8486')
-  , ('X','\926')
-  , ('Y','\936')
-  , ('Z','\918')
-  , ('[','[')
-  , ('\\','\8756')
-  , (']',']')
-  , ('^','\8869')
-  , ('_','_')
-  , ('`','\63717')
-  , ('a','\945')
-  , ('b','\946')
-  , ('c','\967')
-  , ('d','\948')
-  , ('e','\949')
-  , ('f','\966')
-  , ('g','\947')
-  , ('h','\951')
-  , ('i','\953')
-  , ('j','\981')
-  , ('k','\954')
-  , ('l','\955')
-  , ('m','\181')
-  , ('m','\956')
-  , ('n','\957')
-  , ('o','\959')
-  , ('p','\960')
-  , ('q','\952')
-  , ('r','\961')
-  , ('s','\963')
-  , ('t','\964')
-  , ('u','\965')
-  , ('v','\982')
-  , ('w','\969')
-  , ('x','\958')
-  , ('y','\968')
-  , ('z','\950')
-  , ('{','{')
-  , ('|','|')
-  , ('}','}')
-  , ('~','\8764')
-  , ('\160','\8364')
-  , ('\161','\978')
-  , ('\162','\8242')
-  , ('\163','\8804')
-  , ('\164','\8260')
-  , ('\164','\8725')
-  , ('\165','\8734')
-  , ('\166','\402')
-  , ('\167','\9827')
-  , ('\168','\9830')
-  , ('\169','\9829')
-  , ('\170','\9824')
-  , ('\171','\8596')
-  , ('\172','\8592')
-  , ('\173','\8593')
-  , ('\174','\8594')
-  , ('\175','\8595')
-  , ('\176','\176')
-  , ('\177','\177')
-  , ('\178','\8243')
-  , ('\179','\8805')
-  , ('\180','\215')
-  , ('\181','\8733')
-  , ('\182','\8706')
-  , ('\183','\8226')
-  , ('\184','\247')
-  , ('\185','\8800')
-  , ('\186','\8801')
-  , ('\187','\8776')
-  , ('\188','\8230')
-  , ('\189','\63718')
-  , ('\190','\63719')
-  , ('\191','\8629')
-  , ('\192','\8501')
-  , ('\193','\8465')
-  , ('\194','\8476')
-  , ('\195','\8472')
-  , ('\196','\8855')
-  , ('\197','\8853')
-  , ('\198','\8709')
-  , ('\199','\8745')
-  , ('\200','\8746')
-  , ('\201','\8835')
-  , ('\202','\8839')
-  , ('\203','\8836')
-  , ('\204','\8834')
-  , ('\205','\8838')
-  , ('\206','\8712')
-  , ('\207','\8713')
-  , ('\208','\8736')
-  , ('\209','\8711')
-  , ('\210','\63194')
-  , ('\211','\63193')
-  , ('\212','\63195')
-  , ('\213','\8719')
-  , ('\214','\8730')
-  , ('\215','\8901')
-  , ('\216','\172')
-  , ('\217','\8743')
-  , ('\218','\8744')
-  , ('\219','\8660')
-  , ('\220','\8656')
-  , ('\221','\8657')
-  , ('\222','\8658')
-  , ('\223','\8659')
-  , ('\224','\9674')
-  , ('\225','\9001')
-  , ('\226','\63720')
-  , ('\227','\63721')
-  , ('\228','\63722')
-  , ('\229','\8721')
-  , ('\230','\63723')
-  , ('\231','\63724')
-  , ('\232','\63725')
-  , ('\233','\63726')
-  , ('\234','\63727')
-  , ('\235','\63728')
-  , ('\236','\63729')
-  , ('\237','\63730')
-  , ('\238','\63731')
-  , ('\239','\63732')
-  , ('\241','\9002')
-  , ('\242','\8747')
-  , ('\243','\8992')
-  , ('\244','\63733')
-  , ('\245','\8993')
-  , ('\246','\63734')
-  , ('\247','\63735')
-  , ('\248','\63736')
-  , ('\249','\63737')
-  , ('\250','\63738')
-  , ('\251','\63739')
-  , ('\252','\63740')
-  , ('\253','\63741')
-  , ('\254','\63742')]
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
@@ -67,7 +67,7 @@
 import Control.Monad.Except
 import Text.Pandoc.Shared (safeRead, filteredFilesFromArchive)
 import Text.TeXMath.Readers.OMML (readOMML)
-import Text.Pandoc.Readers.Docx.Fonts (getUnicode, Font(..))
+import Text.TeXMath.Unicode.Fonts (getUnicode, stringToFont, Font(..))
 import Text.TeXMath (Exp)
 import Text.Pandoc.Readers.Docx.Util
 import Data.Char (readLitChar, ord, chr, isDigit)
@@ -215,14 +215,16 @@
              | BookMark BookMarkId Anchor
              | InternalHyperLink Anchor [Run]
              | ExternalHyperLink URL [Run]
-             | Drawing FilePath B.ByteString Extent
+             | Drawing FilePath String String B.ByteString Extent -- title, alt
+             | Chart                                              -- placeholder for now
              | PlainOMath [Exp]
              deriving Show
 
 data Run = Run RunStyle [RunElem]
          | Footnote [BodyPart]
          | Endnote [BodyPart]
-         | InlineDrawing FilePath B.ByteString Extent
+         | InlineDrawing FilePath String String B.ByteString Extent -- title, alt
+         | InlineChart          -- placeholder
            deriving Show
 
 data RunElem = TextRun String | LnBrk | Tab | SoftHyphen | NoBreakHyphen
@@ -645,16 +647,31 @@
         Nothing -> throwError DocxError
     Nothing -> throwError DocxError
 
+getTitleAndAlt :: NameSpaces -> Element -> (String, String)
+getTitleAndAlt ns element =
+  let mbDocPr = findChild (elemName ns "wp" "inline") element >>=
+                findChild (elemName ns "wp" "docPr")
+      title = case mbDocPr >>= findAttr (elemName ns "" "title") of
+                Just title' -> title'
+                Nothing     -> ""
+      alt = case mbDocPr >>= findAttr (elemName ns "" "descr") of
+              Just alt' -> alt'
+              Nothing   -> ""
+  in (title, alt)
+
 elemToParPart :: NameSpaces -> Element -> D ParPart
 elemToParPart ns element
   | isElem ns "w" "r" element
-  , Just drawingElem <- findChild (elemName ns "w" "drawing") element =
-    let a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
-        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) element
+  , Just drawingElem <- findChild (elemName ns "w" "drawing") element
+  , pic_ns <- "http://schemas.openxmlformats.org/drawingml/2006/picture"
+  , Just picElem <- findElement (QName "pic" (Just pic_ns) (Just "pic")) drawingElem
+  = let (title, alt) = getTitleAndAlt ns drawingElem
+        a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
+        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) picElem
                   >>= findAttr (elemName ns "r" "embed")
     in
      case drawing of
-       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp bs $ elemToExtent drawingElem)
+       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp title alt bs $ elemToExtent drawingElem)
        Nothing -> throwError WrongElem
 -- The below is an attempt to deal with images in deprecated vml format.
 elemToParPart ns element
@@ -664,9 +681,17 @@
                   >>= findAttr (elemName ns "r" "id")
     in
      case drawing of
-       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp bs Nothing)
+       -- Todo: check out title and attr for deprecated format.
+       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
        Nothing -> throwError WrongElem
+-- Chart
 elemToParPart ns element
+  | isElem ns "w" "r" element
+  , Just drawingElem <- findChild (elemName ns "w" "drawing") element
+  , c_ns <- "http://schemas.openxmlformats.org/drawingml/2006/chart"
+  , Just _ <- findElement (QName "chart" (Just c_ns) (Just "c")) drawingElem
+  = return Chart                       
+elemToParPart ns element
   | isElem ns "w" "r" element =
     elemToRun ns element >>= (\r -> return $ PlainRun r)
 elemToParPart ns element
@@ -750,16 +775,24 @@
 
 childElemToRun :: NameSpaces -> Element -> D Run
 childElemToRun ns element
-  | isElem ns "w" "drawing" element =
-    let a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
-        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) element
+  | isElem ns "w" "drawing" element
+  , pic_ns <- "http://schemas.openxmlformats.org/drawingml/2006/picture"
+  , Just picElem <- findElement (QName "pic" (Just pic_ns) (Just "pic")) element
+  = let (title, alt) = getTitleAndAlt ns element
+        a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
+        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) picElem
                   >>= findAttr (QName "embed" (lookup "r" ns) (Just "r"))
     in
      case drawing of
        Just s -> expandDrawingId s >>=
-                 (\(fp, bs) -> return $ InlineDrawing fp bs $ elemToExtent element)
+                 (\(fp, bs) -> return $ InlineDrawing fp title alt bs $ elemToExtent element)
        Nothing -> throwError WrongElem
 childElemToRun ns element
+  | isElem ns "w" "drawing" element
+  , c_ns <- "http://schemas.openxmlformats.org/drawingml/2006/chart"
+  , Just _ <- findElement (QName "chart" (Just c_ns) (Just "c")) element
+  = return InlineChart
+childElemToRun ns element
   | isElem ns "w" "footnoteReference" element
   , Just fnId <- findAttr (elemName ns "w" "id") element = do
     notes <- asks envNotes
@@ -987,10 +1020,6 @@
     lowerFromPrivate ('F':xs) = '0':xs
     lowerFromPrivate xs = xs
 getSymChar _ _ = TextRun ""
-
-stringToFont :: String -> Maybe Font
-stringToFont "Symbol" = Just Symbol
-stringToFont _ = Nothing
 
 elemToRunElems :: NameSpaces -> Element -> D [RunElem]
 elemToRunElems ns element
diff --git a/src/Text/Pandoc/Readers/Docx/Util.hs b/src/Text/Pandoc/Readers/Docx/Util.hs
--- a/src/Text/Pandoc/Readers/Docx/Util.hs
+++ b/src/Text/Pandoc/Readers/Docx/Util.hs
@@ -18,7 +18,8 @@
 attrToNSPair _ = Nothing
 
 elemName :: NameSpaces -> String -> String -> QName
-elemName ns prefix name = QName name (lookup prefix ns) (Just prefix)
+elemName ns prefix name =
+  QName name (lookup prefix ns) (if null prefix then Nothing else Just prefix)
 
 isElem :: NameSpaces -> String -> String -> Element -> Bool
 isElem ns prefix name element =
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
@@ -435,17 +435,20 @@
   rowsLs <- many pTBody
   rows'  <- pOptInTag "tfoot" $ many pTr
   TagClose _ <- pSatisfy (~== TagClose "table")
-  let rows = (concat rowsLs) ++ rows'
+  let rows'' = (concat rowsLs) ++ rows'
   -- fail on empty table
-  guard $ not $ null head' && null rows
+  guard $ not $ null head' && null rows''
   let isSinglePlain x = case B.toList x of
                              []        -> True
                              [Plain _] -> True
                              _         -> False
-  let isSimple = all isSinglePlain $ concat (head':rows)
-  let cols = length $ if null head' then head rows else head'
-  -- fail if there are colspans or rowspans
-  guard $ all (\r -> length r == cols) rows
+  let isSimple = all isSinglePlain $ concat (head':rows'')
+  let cols = length $ if null head' then head rows'' else head'
+  -- add empty cells to short rows
+  let addEmpties r = case length r - cols of
+                           n | n > 1 -> r ++ replicate n []
+                             | otherwise -> r
+  let rows = addEmpties rows''
   let aligns = replicate cols AlignDefault
   let widths = if null widths'
                   then if isSimple
@@ -471,10 +474,17 @@
   skipMany pBlank
   manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank
 
+noColOrRowSpans :: Tag String -> Bool
+noColOrRowSpans t = isNullOrOne "colspan" && isNullOrOne "rowspan"
+  where isNullOrOne x = case fromAttrib x t of
+                              ""  -> True
+                              "1" -> True
+                              _   -> False
+
 pCell :: String -> TagParser [Blocks]
 pCell celltype = try $ do
   skipMany pBlank
-  res <- pInTags celltype block
+  res <- pInTags' celltype noColOrRowSpans block
   skipMany pBlank
   return [res]
 
@@ -599,19 +609,31 @@
   pSelfClosing (=="br") (const True)
   return B.linebreak
 
+-- Unlike fromAttrib from tagsoup, this distinguishes
+-- between a missing attribute and an attribute with empty content.
+maybeFromAttrib :: String -> Tag String -> Maybe String
+maybeFromAttrib name (TagOpen _ attrs) = lookup name attrs
+maybeFromAttrib _ _ = Nothing
+
 pLink :: TagParser Inlines
 pLink = try $ do
   tag <- pSatisfy $ tagOpenLit "a" (const True)
-  mbBaseHref <- baseHref <$> getState
-  let url' = fromAttrib "href" tag
-  let url = case (parseURIReference url', mbBaseHref) of
-                 (Just rel, Just bs) -> show (rel `nonStrictRelativeTo` bs)
-                 _                   -> url'
   let title = fromAttrib "title" tag
-  let uid = fromAttrib "id" tag
+  -- take id from id attribute if present, otherwise name
+  let uid = maybe (fromAttrib "name" tag) id $ maybeFromAttrib "id" tag
   let cls = words $ fromAttrib "class" tag
   lab <- trimInlines . mconcat <$> manyTill inline (pCloses "a")
-  return $ B.linkWith (uid, cls, []) (escapeURI url) title lab
+  -- check for href; if href, then a link, otherwise a span
+  case maybeFromAttrib "href" tag of
+       Nothing   ->
+         return $ B.spanWith (uid, cls, []) lab
+       Just url' -> do
+         mbBaseHref <- baseHref <$> getState
+         let url = case (parseURIReference url', mbBaseHref) of
+                        (Just rel, Just bs) ->
+                          show (rel `nonStrictRelativeTo` bs)
+                        _                   -> url'
+         return $ B.linkWith (uid, cls, []) (escapeURI url) title lab
 
 pImage :: TagParser Inlines
 pImage = do
@@ -666,24 +688,30 @@
 pMath :: Bool -> TagParser Inlines
 pMath inCase = try $ do
   open@(TagOpen _ attr) <- pSatisfy $ tagOpen (=="math") (const True)
-  unless (inCase) (guard (maybe False  (== mathMLNamespace) (lookup "xmlns" attr)))
+  -- we'll assume math tags are MathML unless specially marked
+  -- otherwise...
+  unless inCase $
+    guard (maybe True (== mathMLNamespace) (lookup "xmlns" attr))
   contents <- manyTill pAnyTag (pSatisfy (~== TagClose "math"))
-  let math = mathMLToTeXMath $
-              (renderTags $ [open] ++ contents ++ [TagClose "math"])
-  let constructor =
-        maybe B.math (\x -> if (x == "inline") then B.math else B.displayMath)
-          (lookup "display" attr)
-  return $ either (const mempty)
-            (\x -> if null x then mempty else constructor x) math
+  case mathMLToTeXMath (renderTags $ [open] ++ contents ++ [TagClose "math"]) of
+       Left _   -> return $ B.spanWith ("",["math"],attr) $ B.text $
+                             innerText contents
+       Right [] -> return mempty
+       Right x  -> return $ case lookup "display" attr of
+                                 Just "block" -> B.displayMath x
+                                 _            -> B.math x
 
 pInlinesInTags :: String -> (Inlines -> Inlines)
                -> TagParser Inlines
 pInlinesInTags tagtype f = extractSpaces f <$> pInTags tagtype inline
 
-pInTags :: (Monoid a) => String -> TagParser a
-        -> TagParser a
-pInTags tagtype parser = try $ do
-  pSatisfy (~== TagOpen tagtype [])
+pInTags :: (Monoid a) => String -> TagParser a -> TagParser a
+pInTags tagtype parser = pInTags' tagtype (const True) parser
+
+pInTags' :: (Monoid a) => String -> (Tag String -> Bool) -> TagParser a
+                       -> TagParser a
+pInTags' tagtype tagtest parser = try $ do
+  pSatisfy (\t -> t ~== TagOpen tagtype [] && tagtest t)
   mconcat <$> manyTill parser (pCloses tagtype <|> eof)
 
 -- parses p, preceeded by an optional opening tag
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
@@ -340,6 +340,7 @@
   , ("closing", skipopts *> closing)
   --
   , ("hrule", pure horizontalRule)
+  , ("strut", pure mempty)
   , ("rule", skipopts *> tok *> tok *> pure horizontalRule)
   , ("item", skipopts *> looseItem)
   , ("documentclass", skipopts *> braced *> preamble)
@@ -366,7 +367,6 @@
   , "ignore"
   , "hyperdef"
   , "markboth", "markright", "markleft"
-  , "hspace", "vspace"
   , "newpage"
   ]
 
@@ -422,7 +422,8 @@
   star <- option "" (string "*")
   let name' = name ++ star
   let raw = do
-        rawargs <- withRaw (skipopts *> option "" dimenarg *> many braced)
+        rawargs <- withRaw
+               (skipangles *> skipopts *> option "" dimenarg *> many braced)
         let rawcommand = '\\' : name ++ star ++ snd rawargs
         transformed <- applyMacros' rawcommand
         if transformed /= rawcommand
@@ -523,6 +524,7 @@
   , ("copyright", lit "©")
   , ("textasciicircum", lit "^")
   , ("textasciitilde", lit "~")
+  , ("H", try $ tok >>= accent hungarumlaut)
   , ("`", option (str "`") $ try $ tok >>= accent grave)
   , ("'", option (str "'") $ try $ tok >>= accent acute)
   , ("^", option (str "^") $ try $ tok >>= accent circ)
@@ -762,6 +764,21 @@
 umlaut 'u' = "ü"
 umlaut c   = [c]
 
+hungarumlaut :: Char -> String
+hungarumlaut 'A' = "A̋"
+hungarumlaut 'E' = "E̋"
+hungarumlaut 'I' = "I̋"
+hungarumlaut 'O' = "Ő"
+hungarumlaut 'U' = "Ű"
+hungarumlaut 'Y' = "ӳ"
+hungarumlaut 'a' = "a̋"
+hungarumlaut 'e' = "e̋"
+hungarumlaut 'i' = "i̋"
+hungarumlaut 'o' = "ő"
+hungarumlaut 'u' = "ű"
+hungarumlaut 'y' = "ӳ"
+hungarumlaut c   = [c]
+
 dot :: Char -> String
 dot 'C' = "Ċ"
 dot 'c' = "ċ"
@@ -861,13 +878,25 @@
 
 rawopt :: LP String
 rawopt = do
-  contents <- bracketed (many1 (noneOf "]") <|> try (string "\\]"))
+  contents <- bracketed (many1 (noneOf "[]") <|> try (string "\\]") <|>
+                   try (string "\\[") <|> rawopt)
   optional sp
   return $ "[" ++ contents ++ "]"
 
 skipopts :: LP ()
 skipopts = skipMany rawopt
 
+-- opts in angle brackets are used in beamer
+rawangle :: LP ()
+rawangle = try $ do
+  char '<'
+  skipMany (noneOf ">")
+  char '>'
+  return ()
+
+skipangles :: LP ()
+skipangles = skipMany rawangle
+
 inlineText :: LP Inlines
 inlineText = str <$> many1 inlineChar
 
@@ -932,8 +961,8 @@
   withRaw $ try $ do
              string "\\begin"
              name <- braced'
-             guard $ name `elem` ["verbatim", "Verbatim", "lstlisting",
-                                  "minted", "alltt", "comment"]
+             guard $ name `elem` ["verbatim", "Verbatim", "BVerbatim",
+                                  "lstlisting", "minted", "alltt", "comment"]
              manyTill anyChar (try $ string $ "\\end{" ++ name ++ "}")
 
 blob' :: IncludeParser
@@ -1067,11 +1096,13 @@
   [ ("document", env "document" blocks <* skipMany anyChar)
   , ("abstract", mempty <$ (env "abstract" blocks >>= addMeta "abstract"))
   , ("letter", env "letter" letterContents)
+  , ("minipage", env "minipage" $
+         skipopts *> spaces' *> optional braced *> spaces' *> blocks)
   , ("figure", env "figure" $
          resetCaption *> skipopts *> blocks >>= addImageCaption)
   , ("center", env "center" blocks)
   , ("longtable",  env "longtable" $
-         resetCaption *> skipopts *> blocks >>= addTableCaption)
+         resetCaption *> simpTable False >>= addTableCaption)
   , ("table",  env "table" $
          resetCaption *> skipopts *> blocks >>= addTableCaption)
   , ("tabular*", env "tabular" $ simpTable True)
@@ -1088,14 +1119,8 @@
         verbEnv "code"))
   , ("comment", mempty <$ verbEnv "comment")
   , ("verbatim", codeBlock <$> verbEnv "verbatim")
-  , ("Verbatim",   do options <- option [] keyvals
-                      let kvs = [ (if k == "firstnumber"
-                                      then "startFrom"
-                                      else k, v) | (k,v) <- options ]
-                      let classes = [ "numberLines" |
-                                      lookup "numbers" options == Just "left" ]
-                      let attr = ("",classes,kvs)
-                      codeBlockWith attr <$> verbEnv "Verbatim")
+  , ("Verbatim", fancyverbEnv "Verbatim")
+  , ("BVerbatim", fancyverbEnv "BVerbatim")
   , ("lstlisting", do options <- option [] keyvals
                       let kvs = [ (if k == "firstnumber"
                                       then "startFrom"
@@ -1206,6 +1231,17 @@
   res <- manyTill anyChar endEnv
   return $ stripTrailingNewlines res
 
+fancyverbEnv :: String -> LP Blocks
+fancyverbEnv name = do
+  options <- option [] keyvals
+  let kvs = [ (if k == "firstnumber"
+                  then "startFrom"
+                  else k, v) | (k,v) <- options ]
+  let classes = [ "numberLines" |
+                  lookup "numbers" options == Just "left" ]
+  let attr = ("",classes,kvs)
+  codeBlockWith attr <$> verbEnv name
+
 orderedList' :: LP Blocks
 orderedList' = do
   optional sp
@@ -1346,22 +1382,30 @@
     -- booktabs rules:
     controlSeq "toprule" <|>
     controlSeq "bottomrule" <|>
-    controlSeq "midrule"
+    controlSeq "midrule" <|>
+    controlSeq "endhead" <|>
+    controlSeq "endfirsthead"
   spaces'
   optional $ bracketed (many1 (satisfy (/=']')))
   return ()
 
 lbreak :: LP ()
-lbreak = () <$ try (spaces' *> controlSeq "\\" <* spaces')
+lbreak = () <$ try (spaces' *>
+                    (controlSeq "\\" <|> controlSeq "tabularnewline") <*
+                    spaces')
 
 amp :: LP ()
-amp = () <$ try (spaces' *> char '&')
+amp = () <$ try (spaces' *> char '&' <* spaces')
 
 parseTableRow :: Int  -- ^ number of columns
               -> LP [Blocks]
 parseTableRow cols = try $ do
   let tableCellInline = notFollowedBy (amp <|> lbreak) >> inline
-  let tableCell = (plain . trimInlines . mconcat) <$> many tableCellInline
+  let minipage = try $ controlSeq "begin" *> string "{minipage}" *>
+          env "minipage"
+          (skipopts *> spaces' *> optional braced *> spaces' *> blocks)
+  let tableCell = minipage <|>
+            ((plain . trimInlines . mconcat) <$> many tableCellInline)
   cells' <- sepBy1 tableCell amp
   let numcells = length cells'
   guard $ numcells <= cols && numcells >= 1
@@ -1380,9 +1424,17 @@
   skipopts
   aligns <- parseAligns
   let cols = length aligns
-  optional hline
-  header' <- option [] $ try (parseTableRow cols <* lbreak <* hline)
-  rows <- sepEndBy (parseTableRow cols) (lbreak <* optional hline)
+  optional $ controlSeq "caption" *> skipopts *> setCaption
+  optional lbreak
+  spaces'
+  skipMany hline
+  spaces'
+  header' <- option [] $ try (parseTableRow cols <* lbreak <* many1 hline)
+  spaces'
+  rows <- sepEndBy (parseTableRow cols) (lbreak <* optional (skipMany hline))
+  spaces'
+  optional $ controlSeq "caption" *> skipopts *> setCaption
+  optional lbreak
   spaces'
   let header'' = if null header'
                     then replicate cols mempty
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
@@ -1271,14 +1271,22 @@
 gridTableSplitLine indices line = map removeFinalBar $ tail $
   splitStringByIndices (init indices) $ trimr line
 
-gridPart :: Char -> Parser [Char] st (Int, Int)
+gridPart :: Char -> Parser [Char] st ((Int, Int), Alignment)
 gridPart ch = do
+  leftColon <- option False (True <$ char ':')
   dashes <- many1 (char ch)
+  rightColon <- option False (True <$ char ':')
   char '+'
-  let lengthDashes = length dashes
-  return (lengthDashes, lengthDashes + 1)
+  let lengthDashes = length dashes + (if leftColon then 1 else 0) +
+                       (if rightColon then 1 else 0)
+  let alignment = case (leftColon, rightColon) of
+                       (True, True)   -> AlignCenter
+                       (True, False)  -> AlignLeft
+                       (False, True)  -> AlignRight
+                       (False, False) -> AlignDefault
+  return ((lengthDashes, lengthDashes + 1), alignment)
 
-gridDashedLines :: Char -> Parser [Char] st [(Int,Int)]
+gridDashedLines :: Char -> Parser [Char] st [((Int, Int), Alignment)]
 gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline
 
 removeFinalBar :: String -> String
@@ -1296,19 +1304,17 @@
   optional blanklines
   dashes <- gridDashedLines '-'
   rawContent  <- if headless
-                    then return $ repeat ""
-                    else many1
-                         (notFollowedBy (gridTableSep '=') >> char '|' >>
-                           many1Till anyChar newline)
-  if headless
-     then return ()
-     else gridTableSep '=' >> return ()
-  let lines'   = map snd dashes
+                    then return []
+                    else many1 (try (char '|' >> anyLine))
+  underDashes <- if headless
+                    then return dashes
+                    else gridDashedLines '='
+  guard $ length dashes == length underDashes
+  let lines'   = map (snd . fst) underDashes
   let indices  = scanl (+) 0 lines'
-  let aligns   = replicate (length lines') AlignDefault
-  -- RST does not have a notion of alignments
+  let aligns   = map snd underDashes
   let rawHeads = if headless
-                    then replicate (length dashes) ""
+                    then replicate (length underDashes) ""
                     else map (unlines . map trim) $ transpose
                        $ map (gridTableSplitLine indices) rawContent
   heads <- fmap sequence $ mapM (parseFromString parseBlocks . trim) rawHeads
@@ -1317,7 +1323,7 @@
 gridTableRawLine :: [Int] -> MarkdownParser [String]
 gridTableRawLine indices = do
   char '|'
-  line <- many1Till anyChar newline
+  line <- anyLine
   return (gridTableSplitLine indices line)
 
 -- | Parse row of grid table.
@@ -1758,7 +1764,13 @@
   guardEnabled Ext_bracketed_spans
   (lab,_) <- reference
   attr <- attributes
-  return $ B.spanWith attr <$> lab
+  let (ident,classes,keyvals) = attr
+  case lookup "style" keyvals of
+       Just s | null ident && null classes &&
+            map toLower (filter (`notElem` " \t;") s) ==
+                 "font-variant:small-caps"
+         -> return $ B.smallcaps <$> lab
+       _ -> return $ B.spanWith attr <$> lab
 
 regLink :: (Attr -> String -> String -> Inlines -> Inlines)
         -> F Inlines -> MarkdownParser (F Inlines)
@@ -1774,7 +1786,8 @@
 referenceLink constructor (lab, raw) = do
   sp <- (True <$ lookAhead (char ' ')) <|> return False
   (_,raw') <- option (mempty, "") $
-      lookAhead (try (spnl >> normalCite >> return (mempty, "")))
+      lookAhead (try (guardEnabled Ext_citations >>
+                      spnl >> normalCite >> return (mempty, "")))
       <|>
       try (spnl >> reference)
   when (raw' == "") $ guardEnabled Ext_shortcut_reference_links
diff --git a/src/Text/Pandoc/Readers/Odt/ContentReader.hs b/src/Text/Pandoc/Readers/Odt/ContentReader.hs
--- a/src/Text/Pandoc/Readers/Odt/ContentReader.hs
+++ b/src/Text/Pandoc/Readers/Odt/ContentReader.hs
@@ -44,7 +44,7 @@
 
 import qualified Data.ByteString.Lazy   as B
 import qualified Data.Map               as M
-import           Data.List                     ( find )
+import           Data.List                     ( find, intercalate )
 import           Data.Maybe
 
 import qualified Text.XML.Light         as XML
@@ -263,8 +263,13 @@
 --------------------------------------------------------------------------------
 
 --
-readStyleByName :: OdtReader _x Style
-readStyleByName = findAttr NsText "style-name" >>? getStyleByName
+readStyleByName :: OdtReader _x (StyleName, Style)
+readStyleByName =
+  findAttr NsText "style-name" >>? keepingTheValue getStyleByName >>^ liftE
+  where
+    liftE :: (StyleName, Fallible Style) -> Fallible (StyleName, Style)
+    liftE (name, Right v) = Right (name, v)
+    liftE (_, Left v)     = Left v
 
 --
 isStyleToTrace :: OdtReader Style Bool
@@ -275,7 +280,10 @@
 withNewStyle a = proc x -> do
   fStyle <- readStyleByName -< ()
   case fStyle of
-    Right style -> do
+    Right (styleName, _) | isCodeStyle styleName -> do
+      inlines <- a -< x
+      arr inlineCode -<< inlines
+    Right (_, style) -> do
       mFamily    <- arr styleFamily -< style
       fTextProps <- arr ( maybeToChoice
                         . textProperties
@@ -301,7 +309,13 @@
             Left _ -> a -< x
         Left _     -> a -< x
     Left _         -> a -< x
+  where
+    isCodeStyle :: StyleName -> Bool
+    isCodeStyle "Source_Text" = True
+    isCodeStyle _             = False
 
+    inlineCode :: Inlines -> Inlines
+    inlineCode = code . intercalate "" . map stringify . toList
 
 type PropertyTriple = (ReaderState, TextProperties, Maybe StyleFamily)
 type InlineModifier = Inlines -> Inlines
@@ -327,7 +341,7 @@
         let getVPos = Just . verticalPosition
         in  case lookupPreviousValueM getVPos triple of
               Nothing      -> ignore
-              Just oldVPos -> getVPosModifier' (oldVPos,verticalPosition textProps)
+              Just oldVPos -> getVPosModifier' (oldVPos, verticalPosition textProps)
 
     getVPosModifier' (oldVPos , newVPos   ) | oldVPos == newVPos = ignore
     getVPosModifier' ( _      , VPosSub   )                      = subscript
@@ -401,12 +415,18 @@
   fStyle <- readStyleByName -< blocks
   case fStyle of
     Left   _    -> reader -< blocks
-    Right style -> do
+    Right (styleName, _) | isTableCaptionStyle styleName -> do
+      blocks' <- reader   -< blocks
+      arr tableCaptionP  -< blocks'
+    Right (_, style) -> do
       let modifier = getParaModifier style
-      blocks' <- reader -< blocks
-      arr modifier -<< blocks'
-
-
+      blocks' <- reader   -<  blocks
+      arr modifier        -<< blocks'
+  where
+    isTableCaptionStyle :: StyleName -> Bool
+    isTableCaptionStyle "Table" = True
+    isTableCaptionStyle _       = False
+    tableCaptionP b = divWith ("", ["caption"], []) b
 
 type ListConstructor = [Blocks] -> Blocks
 
@@ -695,7 +715,7 @@
                         ( findAttrWithDefault NsText "identifier" ""     )
                         ( readAttrWithDefault NsText "number" 0          )
                       )
-                      ( matchChildContent [] read_plain_text                 )
+                      ( matchChildContent [] read_plain_text             )
   where
    makeCitation :: String -> Int -> [Citation]
    makeCitation citeId num = [Citation citeId [] [] NormalCitation num 0]
@@ -708,10 +728,17 @@
 --
 read_table        :: BlockMatcher
 read_table         = matchingElement NsTable "table"
-                     $ liftA (simpleTable [])
+                     $ liftA simpleTable'
                      $ matchChildContent'  [ read_table_row
                                            ]
 
+-- | A simple table without a caption or headers
+-- | Infers the number of headers from rows
+simpleTable' :: [[Blocks]] -> Blocks
+simpleTable' []         = simpleTable [] []
+simpleTable' (x : rest) = simpleTable (fmap (const defaults) x) (x : rest)
+  where defaults = fromList []
+
 --
 read_table_row    :: ElementMatcher [[Blocks]]
 read_table_row     = matchingElement NsTable "table-row"
@@ -883,6 +910,15 @@
                                ]
             >>^ doc
 
+post_process :: Pandoc -> Pandoc
+post_process (Pandoc m blocks) =
+  Pandoc m (post_process' blocks)
+
+post_process' :: [Block] -> [Block]
+post_process' ((Table _ a w h r) : (Div ("", ["caption"], _) [Para inlines] ) : xs) =
+  (Table inlines a w h r) : ( post_process' xs )
+post_process' bs = bs
+
 read_body :: OdtReader _x (Pandoc, MediaBag)
 read_body = executeIn NsOffice "body"
           $ executeIn NsOffice "text"
@@ -890,4 +926,4 @@
           $ proc inlines -> do
              txt   <- read_text     -< inlines
              state <- getExtraState -< ()
-             returnA                -< (txt, getMediaBag state)
+             returnA                -< (post_process txt, getMediaBag state)
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
@@ -37,9 +37,11 @@
   , commentLineStart
   , bulletListStart
   , orderedListStart
+  , endOfBlock
   ) where
 
-import           Text.Pandoc.Readers.Org.Parsing
+import Control.Monad ( void )
+import Text.Pandoc.Readers.Org.Parsing
 
 -- | Horizontal Line (five -- dashes or more)
 hline :: OrgParser ()
@@ -110,3 +112,25 @@
          , (++) <$> string "fn:"
                 <*> many1Till (noneOf "\n\r\t ") (char ']')
          ]
+
+-- | Succeeds if the parser is at the end of a block.
+endOfBlock :: OrgParser ()
+endOfBlock = lookAhead . try $ do
+    void blankline <|> anyBlockStart
+ where
+   -- Succeeds if there is a new block starting at this position.
+   anyBlockStart :: OrgParser ()
+   anyBlockStart = try . choice $
+     [ exampleLineStart
+     , hline
+     , metaLineStart
+     , commentLineStart
+     , void noteMarker
+     , void tableStart
+     , void drawerStart
+     , void headerStart
+     , void latexEnvStart
+     , void bulletListStart
+     , void orderedListStart
+     ]
+
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
@@ -46,10 +46,11 @@
 import           Text.Pandoc.Builder ( Inlines, Blocks )
 import           Text.Pandoc.Definition
 import           Text.Pandoc.Options
-import           Text.Pandoc.Shared ( compactify', compactify'DL )
+import           Text.Pandoc.Shared ( compactify', compactify'DL, safeRead )
 
 import           Control.Monad ( foldM, guard, mzero, void )
 import           Data.Char ( isSpace, toLower, toUpper)
+import           Data.Default ( Default )
 import           Data.List ( foldl', isPrefixOf )
 import           Data.Maybe ( fromMaybe, isNothing )
 import           Data.Monoid ((<>))
@@ -90,6 +91,7 @@
 -- | Org mode headline (i.e. a document subtree).
 data Headline = Headline
   { headlineLevel      :: Int
+  , headlineTodoMarker :: Maybe TodoMarker
   , headlineText       :: Inlines
   , headlineTags       :: [Tag]
   , headlineProperties :: Properties
@@ -107,6 +109,7 @@
 headline lvl = try $ do
   level <- headerStart
   guard (lvl <= level)
+  todoKw <- optionMaybe todoKeyword
   title <- trimInlinesF . mconcat <$> manyTill inline endOfTitle
   tags  <- option [] headerTags
   newline
@@ -119,6 +122,7 @@
     children' <- sequence children
     return $ Headline
       { headlineLevel = level
+      , headlineTodoMarker = todoKw
       , headlineText = title'
       , headlineTags = tags
       , headlineProperties = properties
@@ -193,11 +197,30 @@
 
 headlineToHeader :: Headline -> OrgParser Blocks
 headlineToHeader (Headline {..}) = do
-  let text        = tagTitle headlineText headlineTags
+  exportTodoKeyword <- getExportSetting exportWithTodoKeywords
+  let todoText    = if exportTodoKeyword
+                    then case headlineTodoMarker of
+                      Just kw -> todoKeywordToInlines kw <> B.space
+                      Nothing -> mempty
+                    else mempty
+  let text        = tagTitle (todoText <> headlineText) headlineTags
   let propAttr    = propertiesToAttr headlineProperties
   attr           <- registerHeader propAttr headlineText
   return $ B.headerWith attr headlineLevel text
 
+todoKeyword :: OrgParser TodoMarker
+todoKeyword = try $ do
+  taskStates <- activeTodoMarkers <$> getState
+  let kwParser tdm = try $ (tdm <$ string (todoMarkerName tdm) <* spaceChar)
+  choice (map kwParser taskStates)
+
+todoKeywordToInlines :: TodoMarker -> Inlines
+todoKeywordToInlines tdm =
+  let todoText  = todoMarkerName tdm
+      todoState = map toLower . show $ todoMarkerState tdm
+      classes = [todoState, todoText]
+  in B.spanWith (mempty, classes, mempty) (B.str todoText)
+
 propertiesToAttr :: Properties -> Attr
 propertiesToAttr properties =
   let
@@ -272,6 +295,17 @@
   , blockAttrKeyValues :: [(String, String)]
   }
 
+-- | Convert BlockAttributes into pandoc Attr
+attrFromBlockAttributes :: BlockAttributes -> Attr
+attrFromBlockAttributes (BlockAttributes{..}) =
+  let
+    ident   = fromMaybe mempty $ lookup "id" blockAttrKeyValues
+    classes = case lookup "class" blockAttrKeyValues of
+                Nothing     -> []
+                Just clsStr -> words clsStr
+    kv      = filter ((`notElem` ["id", "class"]) . fst) blockAttrKeyValues
+  in (ident, classes, kv)
+
 stringyMetaAttribute :: (String -> Bool) -> OrgParser (String, String)
 stringyMetaAttribute attrCheck = try $ do
   metaLineStart
@@ -342,24 +376,26 @@
   blockAttrs <- blockAttributes
   blkType <- blockHeaderStart
   ($ blkType) $
-    case blkType of
+    case (map toLower blkType) of
       "export"  -> exportBlock
       "comment" -> rawBlockLines (const mempty)
-      "html"    -> rawBlockLines (return . (B.rawBlock blkType))
-      "latex"   -> rawBlockLines (return . (B.rawBlock blkType))
-      "ascii"   -> rawBlockLines (return . (B.rawBlock blkType))
+      "html"    -> rawBlockLines (return . B.rawBlock (lowercase blkType))
+      "latex"   -> rawBlockLines (return . B.rawBlock (lowercase blkType))
+      "ascii"   -> rawBlockLines (return . B.rawBlock (lowercase blkType))
       "example" -> rawBlockLines (return . exampleCode)
       "quote"   -> parseBlockLines (fmap B.blockQuote)
       "verse"   -> verseBlock
       "src"     -> codeBlock blockAttrs
-      _         -> parseBlockLines (fmap $ B.divWith (mempty, [blkType], mempty))
+      _         -> parseBlockLines $
+                   let (ident, classes, kv) = attrFromBlockAttributes blockAttrs
+                   in fmap $ B.divWith (ident, classes ++ [blkType], kv)
  where
    blockHeaderStart :: OrgParser String
-   blockHeaderStart = try $ do
-     skipSpaces
-     blockType <- stringAnyCase "#+begin_" *> orgArgWord
-     return (map toLower blockType)
+   blockHeaderStart = try $ skipSpaces *> stringAnyCase "#+begin_" *> orgArgWord
 
+   lowercase :: String -> String
+   lowercase = map toLower
+
 rawBlockLines :: (String   -> F Blocks) -> String -> OrgParser (F Blocks)
 rawBlockLines f blockType = (ignHeaders *> (f <$> rawBlockContent blockType))
 
@@ -583,31 +619,33 @@
 -- Figures
 --
 
--- | Figures (Image on a line by itself, preceded by name and/or caption)
+-- | Figures or an image paragraph (i.e. an image on a line by itself). Only
+-- images with a caption attribute are interpreted as figures.
 figure :: OrgParser (F Blocks)
 figure = try $ do
   figAttrs <- blockAttributes
-  src <- skipSpaces *> selfTarget <* skipSpaces <* newline
+  src <- skipSpaces *> selfTarget <* skipSpaces <* endOfParagraph
   case cleanLinkString src of
     Nothing     -> mzero
     Just imgSrc -> do
-      guard (not . isNothing . blockAttrCaption $ figAttrs)
       guard (isImageFilename imgSrc)
-      return $ figureBlock figAttrs imgSrc
+      let isFigure = not . isNothing $ blockAttrCaption figAttrs
+      return $ imageBlock isFigure figAttrs imgSrc
  where
    selfTarget :: OrgParser String
    selfTarget = try $ char '[' *> linkTarget <* char ']'
 
-   figureBlock :: BlockAttributes -> String -> (F Blocks)
-   figureBlock figAttrs imgSrc =
+   imageBlock :: Bool -> BlockAttributes -> String -> F Blocks
+   imageBlock isFigure figAttrs imgSrc =
      let
        figName    = fromMaybe mempty $ blockAttrName figAttrs
        figLabel   = fromMaybe mempty $ blockAttrLabel figAttrs
        figCaption = fromMaybe mempty $ blockAttrCaption figAttrs
        figKeyVals = blockAttrKeyValues figAttrs
        attr       = (figLabel, mempty, figKeyVals)
+       figTitle   = (if isFigure then withFigPrefix else id) figName
      in
-       B.para . B.imageWith attr imgSrc (withFigPrefix figName) <$> figCaption
+       B.para . B.imageWith attr imgSrc figTitle <$> figCaption
 
    withFigPrefix :: String -> String
    withFigPrefix cs =
@@ -615,7 +653,11 @@
      then cs
      else "fig:" ++ cs
 
+-- | Succeeds if looking at the end of the current paragraph
+endOfParagraph :: OrgParser ()
+endOfParagraph = try $ skipSpaces *> newline *> endOfBlock
 
+
 --
 -- Examples
 --
@@ -646,18 +688,24 @@
 --
 -- Tables
 --
+data ColumnProperty = ColumnProperty
+  { columnAlignment :: Maybe Alignment
+  , columnRelWidth  :: Maybe Int
+  } deriving (Show, Eq)
 
+instance Default ColumnProperty where
+  def = ColumnProperty Nothing Nothing
+
 data OrgTableRow = OrgContentRow (F [Blocks])
-                 | OrgAlignRow [Alignment]
+                 | OrgAlignRow [ColumnProperty]
                  | OrgHlineRow
 
 -- OrgTable is strongly related to the pandoc table ADT.  Using the same
 -- (i.e. pandoc-global) ADT would mean that the reader would break if the
 -- global structure was to be changed, which would be bad.  The final table
--- should be generated using a builder function.  Column widths aren't
--- implemented yet, so they are not tracked here.
+-- should be generated using a builder function.
 data OrgTable = OrgTable
-  { orgTableAlignments :: [Alignment]
+  { orgTableColumnProperties :: [ColumnProperty]
   , orgTableHeader     :: [Blocks]
   , orgTableRows       :: [[Blocks]]
   }
@@ -674,8 +722,20 @@
 orgToPandocTable :: OrgTable
                  -> Inlines
                  -> Blocks
-orgToPandocTable (OrgTable aligns heads lns) caption =
-  B.table caption (zip aligns $ repeat 0) heads lns
+orgToPandocTable (OrgTable colProps heads lns) caption =
+  let totalWidth = if any (not . isNothing) (map columnRelWidth colProps)
+                   then Just . sum $ map (fromMaybe 1 . columnRelWidth) colProps
+                   else Nothing
+  in B.table caption (map (convertColProp totalWidth) colProps) heads lns
+ where
+   convertColProp :: Maybe Int -> ColumnProperty -> (Alignment, Double)
+   convertColProp totalWidth colProp =
+     let
+       align' = fromMaybe AlignDefault $ columnAlignment colProp
+       width' = fromMaybe 0 $ (\w t -> (fromIntegral w / fromIntegral t))
+                              <$> (columnRelWidth colProp)
+                              <*> totalWidth
+     in (align', width')
 
 tableRows :: OrgParser [OrgTableRow]
 tableRows = try $ many (tableAlignRow <|> tableHline <|> tableContentRow)
@@ -691,22 +751,22 @@
 tableAlignRow :: OrgParser OrgTableRow
 tableAlignRow = try $ do
   tableStart
-  cells <- many1Till tableAlignCell newline
+  colProps <- many1Till columnPropertyCell newline
   -- Empty rows are regular (i.e. content) rows, not alignment rows.
-  guard $ any (/= AlignDefault) cells
-  return $ OrgAlignRow cells
+  guard $ any (/= def) colProps
+  return $ OrgAlignRow colProps
 
-tableAlignCell :: OrgParser Alignment
-tableAlignCell =
-  choice [ try $ emptyCell *> return AlignDefault
-         , try $ skipSpaces
-                   *> char '<'
-                   *> tableAlignFromChar
-                   <* many digit
-                   <* char '>'
-                   <* emptyCell
-         ] <?> "alignment info"
-    where emptyCell = try $ skipSpaces *> endOfCell
+columnPropertyCell :: OrgParser ColumnProperty
+columnPropertyCell = emptyCell <|> propCell <?> "alignment info"
+ where
+   emptyCell = ColumnProperty Nothing Nothing <$ (try $ skipSpaces *> endOfCell)
+   propCell = try $ ColumnProperty
+                 <$> (skipSpaces
+                      *> char '<'
+                      *> optionMaybe tableAlignFromChar)
+                 <*> (optionMaybe (many1 digit >>= safeRead)
+                      <* char '>'
+                      <* emptyCell)
 
 tableAlignFromChar :: OrgParser Alignment
 tableAlignFromChar = try $
@@ -728,7 +788,8 @@
  where emptyTable = OrgTable mempty mempty mempty
 
 normalizeTable :: OrgTable -> OrgTable
-normalizeTable (OrgTable aligns heads rows) = OrgTable aligns' heads rows
+normalizeTable (OrgTable colProps heads rows) =
+  OrgTable colProps' heads rows
  where
    refRow = if heads /= mempty
             then heads
@@ -737,7 +798,7 @@
                    _     -> mempty
    cols = length refRow
    fillColumns base padding = take cols $ base ++ repeat padding
-   aligns' = fillColumns aligns AlignDefault
+   colProps' = fillColumns colProps def
 
 -- One or more horizontal rules after the first content line mark the previous
 -- line as a header.  All other horizontal lines are discarded.
@@ -747,7 +808,7 @@
 rowToContent orgTable row =
   case row of
     OrgHlineRow       -> return singleRowPromotedToHeader
-    OrgAlignRow as    -> return . setAligns $ as
+    OrgAlignRow props -> return . setProperties $ props
     OrgContentRow cs  -> appendToBody cs
  where
    singleRowPromotedToHeader :: OrgTable
@@ -756,8 +817,8 @@
             orgTable{ orgTableHeader = b , orgTableRows = [] }
      _   -> orgTable
 
-   setAligns :: [Alignment] -> OrgTable
-   setAligns aligns = orgTable{ orgTableAlignments = aligns }
+   setProperties :: [ColumnProperty] -> OrgTable
+   setProperties ps = orgTable{ orgTableColumnProperties = ps }
 
    appendToBody :: F [Blocks] -> F OrgTable
    appendToBody frow = do
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
@@ -77,7 +77,7 @@
   , ignoredSetting "timestamp"
   , ignoredSetting "title"
   , ignoredSetting "toc"
-  , ignoredSetting "todo"
+  , booleanSetting "todo" (\val es -> es { exportWithTodoKeywords = val })
   , ignoredSetting "|"
   ] <?> "export setting"
 
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
@@ -33,7 +33,7 @@
   , linkTarget
   ) where
 
-import           Text.Pandoc.Readers.Org.BlockStarts
+import           Text.Pandoc.Readers.Org.BlockStarts ( endOfBlock, noteMarker )
 import           Text.Pandoc.Readers.Org.ParserState
 import           Text.Pandoc.Readers.Org.Parsing
 import           Text.Pandoc.Readers.Org.Shared
@@ -152,18 +152,7 @@
 endline :: OrgParser (F Inlines)
 endline = try $ do
   newline
-  notFollowedBy blankline
-  notFollowedBy' exampleLineStart
-  notFollowedBy' hline
-  notFollowedBy' noteMarker
-  notFollowedBy' tableStart
-  notFollowedBy' drawerStart
-  notFollowedBy' headerStart
-  notFollowedBy' metaLineStart
-  notFollowedBy' latexEnvStart
-  notFollowedBy' commentLineStart
-  notFollowedBy' bulletListStart
-  notFollowedBy' orderedListStart
+  notFollowedBy' endOfBlock
   decEmphasisNewlinesCount
   guard =<< newlinesCountWithinLimits
   updateLastPreCharPos
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
@@ -42,11 +42,11 @@
 import           Text.Pandoc.Builder ( Blocks, Inlines )
 import           Text.Pandoc.Definition
 
-import           Control.Monad ( mzero )
+import           Control.Monad ( mzero, void )
 import           Data.Char ( toLower )
 import           Data.List ( intersperse )
 import qualified Data.Map as M
-import           Data.Monoid ((<>))
+import           Data.Monoid ( (<>) )
 import           Network.HTTP ( urlEncode )
 
 -- | Returns the current meta, respecting export options.
@@ -144,8 +144,11 @@
 optionLine = try $ do
   key <- metaKey
   case key of
-    "link"    -> parseLinkFormat >>= uncurry addLinkFormat
-    "options" -> exportSettings
+    "link"     -> parseLinkFormat >>= uncurry addLinkFormat
+    "options"  -> exportSettings
+    "todo"     -> todoSequence >>= updateState . registerTodoSequence
+    "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
+    "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
     _         -> mzero
 
 addLinkFormat :: String
@@ -179,3 +182,35 @@
 
 inlinesTillNewline :: OrgParser (F Inlines)
 inlinesTillNewline = trimInlinesF . mconcat <$> manyTill inline newline
+
+--
+-- ToDo Sequences and Keywords
+--
+todoSequence :: OrgParser TodoSequence
+todoSequence = try $ do
+  todoKws <- todoKeywords
+  doneKws <- optionMaybe $ todoDoneSep *> todoKeywords
+  newline
+  -- There must be at least one DONE keyword. The last TODO keyword is taken if
+  -- necessary.
+  case doneKws of
+    Just done  -> return $ keywordsToSequence todoKws done
+    Nothing    -> case reverse todoKws of
+                    []     -> mzero  -- no keywords present
+                    (x:xs) -> return $ keywordsToSequence (reverse xs) [x]
+
+ where
+   todoKeywords :: OrgParser [String]
+   todoKeywords = try $
+     let keyword = many1 nonspaceChar <* skipSpaces
+         endOfKeywords = todoDoneSep <|> void newline
+     in manyTill keyword (lookAhead endOfKeywords)
+
+   todoDoneSep :: OrgParser ()
+   todoDoneSep = void . try $ skipSpaces *> char '|' <* skipSpaces1
+
+   keywordsToSequence :: [String] -> [String] -> TodoSequence
+   keywordsToSequence todo done =
+     let todoMarkers = map (TodoMarker Todo) todo
+         doneMarkers = map (TodoMarker Done) done
+     in todoMarkers ++ doneMarkers
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
@@ -34,6 +34,11 @@
   , OrgNoteRecord
   , HasReaderOptions (..)
   , HasQuoteContext (..)
+  , TodoMarker (..)
+  , TodoSequence
+  , TodoState (..)
+  , activeTodoMarkers
+  , registerTodoSequence
   , F(..)
   , askF
   , asksF
@@ -72,6 +77,20 @@
 -- link-type, the corresponding function transforms the given link string.
 type OrgLinkFormatters = M.Map String (String -> String)
 
+-- | The states in which a todo item can be
+data TodoState = Todo | Done
+  deriving (Eq, Ord, Show)
+
+-- | A ToDo keyword like @TODO@ or @DONE@.
+data TodoMarker = TodoMarker
+  { todoMarkerState :: TodoState
+  , todoMarkerName  :: String
+  }
+  deriving (Show, Eq)
+
+-- | Collection of todo markers in the order in which items should progress
+type TodoSequence = [TodoMarker]
+
 -- | Org-mode parser state
 data OrgParserState = OrgParserState
   { orgStateAnchorIds            :: [String]
@@ -88,6 +107,7 @@
   , orgStateNotes'               :: OrgNoteTable
   , orgStateOptions              :: ReaderOptions
   , orgStateParserContext        :: ParserContext
+  , orgStateTodoSequences        :: [TodoSequence]
   }
 
 data OrgParserLocal = OrgParserLocal { orgLocalQuoteContext :: QuoteContext }
@@ -133,12 +153,31 @@
   , orgStateNotes' = []
   , orgStateOptions = def
   , orgStateParserContext = NullState
+  , orgStateTodoSequences = []
   }
 
 optionsToParserState :: ReaderOptions -> OrgParserState
 optionsToParserState opts =
   def { orgStateOptions = opts }
 
+registerTodoSequence :: TodoSequence -> OrgParserState -> OrgParserState
+registerTodoSequence todoSeq st =
+  let curSeqs = orgStateTodoSequences st
+  in st{ orgStateTodoSequences = todoSeq : curSeqs }
+
+-- | Get the current todo/done sequences. If no custom todo sequences have been
+-- defined, return a list containing just the default todo/done sequence.
+activeTodoSequences :: OrgParserState -> [TodoSequence]
+activeTodoSequences st =
+  let curSeqs = orgStateTodoSequences st
+  in if null curSeqs
+     then [[ TodoMarker Todo "TODO" , TodoMarker Done "DONE" ]]
+     else curSeqs
+
+activeTodoMarkers :: OrgParserState -> TodoSequence
+activeTodoMarkers = concat . activeTodoSequences
+
+
 --
 -- Export Settings
 --
@@ -166,6 +205,7 @@
   , exportWithAuthor      :: Bool -- ^ Include author in final meta-data
   , exportWithCreator     :: Bool -- ^ Include creator in final meta-data
   , exportWithEmail       :: Bool -- ^ Include email in final meta-data
+  , exportWithTodoKeywords :: Bool -- ^ Keep TODO keywords in headers
   }
 
 instance Default ExportSettings where
@@ -183,6 +223,7 @@
   , exportWithAuthor = True
   , exportWithCreator = True
   , exportWithEmail = True
+  , exportWithTodoKeywords = True
   }
 
 
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
@@ -127,6 +127,7 @@
 import System.FilePath ( (</>), takeExtension, dropExtension)
 import Data.Generics (Typeable, Data)
 import qualified Control.Monad.State as S
+import Control.Monad.Trans (MonadIO (..))
 import qualified Control.Exception as E
 import Control.Monad (msum, unless, MonadPlus(..))
 import Text.Pandoc.Pretty (charWidth)
@@ -924,6 +925,10 @@
           case parseURIReference' s' of
                Just u' -> openURL $ show $ u' `nonStrictRelativeTo` u
                Nothing -> openURL s' -- will throw error
+       (Nothing, s'@('/':'/':_)) ->  -- protocol-relative URI
+          case parseURIReference' s' of
+               Just u' -> openURL $ show $ u' `nonStrictRelativeTo` httpcolon
+               Nothing -> openURL s' -- will throw error
        (Nothing, s') ->
           case parseURI s' of  -- requires absolute URI
                -- We don't want to treat C:/ as a scheme:
@@ -934,6 +939,11 @@
   where readLocalFile f = do
           cont <- BS.readFile f
           return (cont, mime)
+        httpcolon = URI{ uriScheme = "http:",
+                         uriAuthority = Nothing,
+                         uriPath = "",
+                         uriQuery = "",
+                         uriFragment = "" }
         dropFragmentAndQuery = takeWhile (\c -> c /= '?' && c /= '#')
         fp = unEscapeString $ dropFragmentAndQuery s
         mime = case takeExtension fp of
@@ -974,7 +984,7 @@
              UTF8.toString `fmap` lookup hContentType (responseHeaders resp))
 #else
   | otherwise = E.try $ getBodyAndMimeType `fmap` browse
-              (do S.liftIO $ UTF8.hPutStrLn stderr $ "Fetching " ++ u ++ "..."
+              (do liftIO $ UTF8.hPutStrLn stderr $ "Fetching " ++ u ++ "..."
                   setOutHandler $ const (return ())
                   setAllowRedirects True
                   request (getRequest' u'))
@@ -997,10 +1007,10 @@
   exitWith $ ExitFailure exitCode
   return undefined
 
-warn :: String -> IO ()
-warn msg = do
+warn :: MonadIO m => String -> m ()
+warn msg = liftIO $ do
   name <- getProgName
-  UTF8.hPutStrLn stderr $ name ++ ": " ++ msg
+  UTF8.hPutStrLn stderr $ "[" ++ name ++ " warning] " ++ msg
 
 mapLeft :: (a -> b) -> Either a c -> Either b c
 mapLeft f (Left x) = Left (f x)
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
@@ -92,12 +92,13 @@
   let main = render colwidth body
   let context  = defField "body" main
                $ defField "toc"
-                  (writerTableOfContents opts && writerStandalone opts)
+                  (writerTableOfContents opts &&
+                   writerTemplate opts /= Nothing)
                $ defField "titleblock" titleblock
                $ metadata'
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Escape special characters for AsciiDoc.
 escapeString :: String -> String
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
@@ -56,9 +56,9 @@
                      (inlinesToCommonMark opts)
                      meta
         context = defField "body" main $ metadata
-        rendered = if writerStandalone opts
-                      then renderTemplate' (writerTemplate opts) context
-                      else main
+        rendered = case writerTemplate opts of
+                        Nothing  -> main
+                        Just tpl -> renderTemplate' tpl context
 
 processNotes :: Inline -> State [[Block]] Inline
 processNotes (Note bs) = do
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
@@ -84,9 +84,10 @@
   let context =   defField "toc" (writerTableOfContents options)
                 $ defField "placelist" (intercalate ("," :: String) $
                      take (writerTOCDepth options +
-                           if writerTopLevelDivision options < Section
-                           then 0
-                           else 1)
+                           case writerTopLevelDivision options of
+                             TopLevelPart    -> 0
+                             TopLevelChapter -> 0
+                             _               -> 1)
                        ["chapter","section","subsection","subsubsection",
                         "subsubsubsection","subsubsubsubsection"])
                 $ defField "body" main
@@ -97,9 +98,9 @@
                     getField "lang" context)
                 $ defField "context-dir" (toContextDir $ getField "dir" context)
                 $ context
-  return $ if writerStandalone options
-              then renderTemplate' (writerTemplate options) context'
-              else main
+  return $ case writerTemplate options of
+                Nothing  -> main
+                Just tpl -> renderTemplate' tpl context'
 
 toContextDir :: Maybe String -> String
 toContextDir (Just "rtl") = "r2l"
@@ -423,9 +424,10 @@
   st <- get
   let opts = stOptions st
   let level' = case writerTopLevelDivision opts of
-                 Part    -> hdrLevel - 2
-                 Chapter -> hdrLevel - 1
-                 Section -> hdrLevel
+                 TopLevelPart    -> hdrLevel - 2
+                 TopLevelChapter -> hdrLevel - 1
+                 TopLevelSection -> hdrLevel
+                 TopLevelDefault -> hdrLevel
   let ident' = toLabel ident
   let (section, chapter) = if "unnumbered" `elem` classes
                               then (text "subject", text "title")
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
@@ -202,11 +202,9 @@
   Lua.close lua
   setForeignEncoding enc
   let body = rendered
-  if writerStandalone opts
-     then do
-       let context' = setField "body" body context
-       return $ renderTemplate' (writerTemplate opts) context'
-     else return body
+  case writerTemplate opts of
+       Nothing  -> return body
+       Just tpl -> return $ renderTemplate' tpl $ setField "body" body context
 
 docToCustom :: LuaState -> WriterOptions -> Pandoc -> IO String
 docToCustom lua opts (Pandoc (Meta metamap) blocks) = do
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
@@ -80,15 +80,17 @@
                     then Just $ writerColumns opts
                     else Nothing
       render'  = render colwidth
-      opts'    = if ("/book>" `isSuffixOf` (trimr $ writerTemplate opts) &&
-                     writerTopLevelDivision opts >= Section)
-                    then opts{ writerTopLevelDivision = Chapter }
+      opts'    = if (maybe False (("/book>" `isSuffixOf`) . trimr)
+                            (writerTemplate opts) &&
+                     TopLevelDefault == writerTopLevelDivision opts)
+                    then opts{ writerTopLevelDivision = TopLevelChapter }
                     else opts
       -- The numbering here follows LaTeX's internal numbering
       startLvl = case writerTopLevelDivision opts' of
-                   Part    -> -1
-                   Chapter -> 0
-                   Section -> 1
+                   TopLevelPart    -> -1
+                   TopLevelChapter -> 0
+                   TopLevelSection -> 1
+                   TopLevelDefault -> 1
       auths'   = map (authorToDocbook opts) $ docAuthors meta
       meta'    = B.setMeta "author" auths' meta
       Just metadata = metaToJSON opts
@@ -102,9 +104,9 @@
                                         MathML _ -> True
                                         _        -> False)
               $ metadata
-  in  if writerStandalone opts
-         then renderTemplate' (writerTemplate opts) context
-         else main
+  in  case writerTemplate opts of
+           Nothing   -> main
+           Just tpl  -> renderTemplate' tpl context
 
 -- | Convert an Element to Docbook.
 elementToDocbook :: WriterOptions -> Int -> Element -> Doc
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
@@ -894,7 +894,7 @@
                     [ mknode "w:tcBorders" []
                       $ mknode "w:bottom" [("w:val","single")] ()
                     , mknode "w:vAlign" [("w:val","bottom")] () ]
-  let emptyCell = [mknode "w:p" [] [pCustomStyle "Compact"]]
+  let emptyCell = [mknode "w:p" [] [mknode "w:pPr" [] [pCustomStyle "Compact"]]]
   let mkcell border contents = mknode "w:tc" []
                             $ [ borderProps | border ] ++
                             if null contents
@@ -1115,7 +1115,10 @@
   when (displayType == DisplayBlock) setFirstPara
   case writeOMML displayType <$> readTeX str of
         Right r -> return [r]
-        Left  _ -> inlinesToOpenXML opts (texMathToInlines mathType str)
+        Left  e -> do
+          warn $ "Cannot convert the following TeX math, skipping:\n" ++ str ++
+                 "\n" ++ e
+          inlinesToOpenXML opts (texMathToInlines mathType str)
 inlineToOpenXML' opts (Cite _ lst) = inlinesToOpenXML opts lst
 inlineToOpenXML' opts (Code attrs str) = do
   let unhighlighted = intercalate [br] `fmap`
@@ -1169,7 +1172,7 @@
                         M.insert src i extlinks }
               return i
   return [ mknode "w:hyperlink" [("r:id",id')] contents ]
-inlineToOpenXML' opts (Image attr alt (src, _)) = do
+inlineToOpenXML' opts (Image attr alt (src, title)) = do
   -- first, check to see if we've already done this image
   pageWidth <- asks envPrintWidth
   imgs <- gets stImages
@@ -1180,7 +1183,7 @@
                fetchItem' (writerMediaBag opts) (writerSourceURL opts) src
       case res of
         Left (_ :: E.SomeException) -> do
-          liftIO $ warn $ "Could not find image `" ++ src ++ "', skipping..."
+          warn $ "Could not find image `" ++ src ++ "', skipping..."
           -- emit alt text
           inlinesToOpenXML opts alt
         Right (img, mt) -> do
@@ -1220,7 +1223,7 @@
                  mknode "wp:inline" []
                   [ mknode "wp:extent" [("cx",show xemu),("cy",show yemu)] ()
                   , mknode "wp:effectExtent" [("b","0"),("l","0"),("r","0"),("t","0")] ()
-                  , mknode "wp:docPr" [("descr",stringify alt),("id","1"),("name","Picture")] ()
+                  , mknode "wp:docPr" [("descr",stringify alt), ("title", title), ("id","1"),("name","Picture")] ()
                   , graphic ]
           let imgext = case mt >>= extensionFromMimeType of
                             Just x    -> '.':x
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
@@ -42,7 +42,6 @@
 import Text.Pandoc.Definition
 import Text.Pandoc.Options ( WriterOptions(
                                 writerTableOfContents
-                              , writerStandalone
                               , writerTemplate
                               , writerWrapText), WrapOption(..) )
 import Text.Pandoc.Shared ( escapeURI, linesToPara, removeFormatting
@@ -102,9 +101,9 @@
   let context = defField "body" main
                 $ defField "toc" (writerTableOfContents opts)
                 $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Escape special characters for DokuWiki.
 escapeString :: String -> String
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
@@ -342,7 +342,6 @@
            : ("css", "stylesheet.css")
            : writerVariables opts
   let opts' = opts{ writerEmailObfuscation = NoObfuscation
-                  , writerStandalone = True
                   , writerSectionDivs = True
                   , writerHtml5 = epub3
                   , writerVariables = vars
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
@@ -77,7 +77,7 @@
          -> Pandoc           -- ^ document to convert
          -> IO String        -- ^ FictionBook2 document (not encoded yet)
 writeFB2 opts (Pandoc meta blocks) = flip evalStateT newFB $ do
-     modify (\s -> s { writerOptions = opts { writerStandalone = True } })
+     modify (\s -> s { writerOptions = opts })
      desc <- description meta
      fp <- frontpage meta
      secs <- renderSections 1 blocks
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
@@ -1,5 +1,4 @@
 {-# LANGUAGE OverloadedStrings, CPP, ViewPatterns, ScopedTypeVariables #-}
-{-# OPTIONS_GHC -fno-warn-deprecations #-}
 {-
 Copyright (C) 2006-2015 John MacFarlane <jgm@berkeley.edu>
 
@@ -62,7 +61,7 @@
 #endif
 import qualified Text.Blaze.XHtml1.Transitional as H
 import qualified Text.Blaze.XHtml1.Transitional.Attributes as A
-import Text.Blaze.Renderer.String (renderHtml)
+import Text.Blaze.Html.Renderer.String (renderHtml)
 import Text.TeXMath
 import Text.XML.Light.Output
 import Text.XML.Light (unode, elChildren, unqual)
@@ -103,17 +102,19 @@
 writeHtmlString :: WriterOptions -> Pandoc -> String
 writeHtmlString opts d =
   let (body, context) = evalState (pandocToHtml opts d) defaultWriterState
-  in  if writerStandalone opts
-         then inTemplate opts context body
-         else renderHtml body
+  in  case writerTemplate opts of
+           Nothing  -> renderHtml body
+           Just tpl -> renderTemplate' tpl $
+                         defField "body" (renderHtml body) context
 
 -- | Convert Pandoc document to Html structure.
 writeHtml :: WriterOptions -> Pandoc -> Html
 writeHtml opts d =
   let (body, context) = evalState (pandocToHtml opts d) defaultWriterState
-  in  if writerStandalone opts
-         then inTemplate opts context body
-         else body
+  in  case writerTemplate opts of
+           Nothing  -> body
+           Just tpl -> renderTemplate' tpl $
+                         defField "body" (renderHtml body) context
 
 -- result is (title, authors, date, toc, body, new variables)
 pandocToHtml :: WriterOptions
@@ -194,14 +195,6 @@
                   defField "html5" (writerHtml5 opts) $
                   metadata
   return (thebody, context)
-
-inTemplate :: TemplateTarget a
-           => WriterOptions
-           -> Value
-           -> Html
-           -> a
-inTemplate opts context body = renderTemplate' (writerTemplate opts)
-                             $ defField "body" (renderHtml body) context
 
 -- | Like Text.XHtml's identifier, but adds the writerIdentifierPrefix
 prefixedId :: WriterOptions -> String -> Attribute
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
@@ -73,9 +73,9 @@
                meta
   let context  = defField "body" main
                $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+          Nothing  -> return main
+          Just tpl -> return $ renderTemplate' tpl context
 
 -- | Return haddock representation of notes.
 notesToHaddock :: WriterOptions -> [[Block]] -> State WriterState Doc
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
@@ -141,9 +141,9 @@
               $ defField "parStyles"  (render' $ parStylesToDoc st)
               $ defField "hyperlinks" (render' $ hyperlinksToDoc $ links st)
               $ metadata
-  return $ if writerStandalone opts
-              then renderTemplate' (writerTemplate opts) context
-              else main
+  return $ case writerTemplate opts of
+                Nothing  -> main
+                Just tpl -> renderTemplate' tpl context
 
 -- | Auxilary functions for parStylesToDoc and charStylesToDoc.
 contains :: String -> (String, (String, String)) -> [(String, String)]
@@ -534,13 +534,13 @@
   res  <- liftIO $ fetchItem (writerSourceURL opts) src
   imgS <- case res of
             Left (_) -> do
-              liftIO $ warn $ "Could not find image `" ++ src ++ "', skipping..."
+              warn $ "Could not find image `" ++ src ++ "', skipping..."
               return def
             Right (img, _) -> do
               case imageSize img of
                 Right size -> return size
                 Left msg   -> do
-                  return $ warn $ "Could not determine image size in `" ++
+                  warn $ "Could not determine image size in `" ++
                     src ++ "': " ++ msg
                   return def
   let (ow, oh) = sizeInPoints imgS
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
@@ -88,7 +88,10 @@
                 stTable = False, stStrikeout = False,
                 stUrl = False, stGraphics = False,
                 stLHS = False,
-                stBook = writerTopLevelDivision options < Section,
+                stBook = (case writerTopLevelDivision options of
+                           TopLevelPart    -> True
+                           TopLevelChapter -> True
+                           _               -> False),
                 stCsquotes = False, stHighlighting = False,
                 stIncremental = writerIncremental options,
                 stInternalLinks = [], stUsesEuro = False }
@@ -106,7 +109,7 @@
   let isInternalLink (Link _ _ ('#':xs,_))  = [xs]
       isInternalLink _                      = []
   modify $ \s -> s{ stInternalLinks = query isInternalLink blocks' }
-  let template = writerTemplate options
+  let template = maybe "" id $ writerTemplate options
   -- set stBook depending on documentclass
   let colwidth = if writerWrapText options == WrapAuto
                     then Just $ writerColumns options
@@ -243,9 +246,9 @@
                                       Just "rtl" -> True
                                       _          -> False)
         $ context
-  return $ if writerStandalone options
-              then renderTemplate' template context'
-              else main
+  return $ case writerTemplate options of
+                Nothing  -> main
+                Just tpl -> renderTemplate' tpl context'
 
 -- | Convert Elements to LaTeX
 elementToLaTeX :: WriterOptions -> Element -> State WriterState Doc
@@ -635,7 +638,14 @@
   -- scale factor compensates for extra space between columns
   -- so the whole table isn't larger than columnwidth
   let scaleFactor = 0.97 ** fromIntegral (length aligns)
-  let widths' = map (scaleFactor *) widths
+  let isSimple [Plain _] = True
+      isSimple [Para  _] = True
+      isSimple _         = False
+  -- simple tables have to have simple cells:
+  let widths' = if not (all isSimple cols)
+                   then replicate (length aligns)
+                          (0.97 / fromIntegral (length aligns))
+                   else map (scaleFactor *) widths
   cells <- mapM (tableCellToLaTeX header) $ zip3 widths' aligns cols
   return $ hsep (intersperse "&" cells) <> "\\tabularnewline"
 
@@ -733,14 +743,16 @@
 sectionHeader unnumbered ident level lst = do
   txt <- inlineListToLaTeX lst
   plain <- stringToLaTeX TextString $ concatMap stringify lst
-  let noNote (Note _) = Str ""
-      noNote x        = x
-  let lstNoNotes = walk noNote lst
+  let removeInvalidInline (Note _)      = []
+      removeInvalidInline (Span (id', _, _) _) | not (null id') = []
+      removeInvalidInline (Image _ _ _) = []
+      removeInvalidInline x             = [x]
+  let lstNoNotes = foldr (mappend . (\x -> walkM removeInvalidInline x)) mempty lst
   txtNoNotes <- inlineListToLaTeX lstNoNotes
   -- footnotes in sections don't work (except for starred variants)
   -- unless you specify an optional argument:
   -- \section[mysec]{mysec\footnote{blah}}
-  optional <- if unnumbered || lstNoNotes == lst
+  optional <- if unnumbered || lstNoNotes == lst || lstNoNotes == []
                  then return empty
                  else do
                    return $ brackets txtNoNotes
@@ -751,15 +763,18 @@
                          <> braces (text plain))
   book <- gets stBook
   opts <- gets stOptions
-  let topLevelDivision = min (if book then Chapter else Section)
-                             (writerTopLevelDivision opts)
-  let level' = if writerBeamer opts && topLevelDivision < Section
+  let topLevelDivision = if book && writerTopLevelDivision opts == TopLevelDefault
+                         then TopLevelChapter
+                         else writerTopLevelDivision opts
+  let level' = if writerBeamer opts &&
+                  topLevelDivision `elem` [TopLevelPart, TopLevelChapter]
                -- beamer has parts but no chapters
                then if level == 1 then -1 else level - 1
                else case topLevelDivision of
-                 Part    -> level - 2
-                 Chapter -> level - 1
-                 Section -> level
+                      TopLevelPart    -> level - 2
+                      TopLevelChapter -> level - 1
+                      TopLevelSection -> level
+                      TopLevelDefault -> level
   let sectionType = case level' of
                           -1 -> "part"
                           0  -> "chapter"
@@ -1104,8 +1119,9 @@
   return $ text cmd <> foldl' (<>) empty args
     where
        cmd = case citationMode c of
-                  AuthorInText -> "\\textcites"
-                  _            -> "\\autocites"
+                  SuppressAuthor -> "\\autocites*"
+                  AuthorInText   -> "\\textcites"
+                  NormalCitation -> "\\autocites"
        convertOne Citation { citationId = k
                            , citationPrefix = p
                            , citationSuffix = s
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
@@ -88,9 +88,9 @@
               $ defField "hyphenate" True
               $ defField "pandoc-version" pandocVersion
               $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Return man representation of notes.
 notesToMan :: WriterOptions -> [[Block]] -> State WriterState Doc
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
@@ -71,6 +71,7 @@
                            , envPlain          :: Bool
                            , envRefShortcutable :: Bool
                            , envBlockLevel      :: Int
+                           , envEscapeSpaces   :: Bool
                            }
 
 instance Default WriterEnv
@@ -78,6 +79,7 @@
                         , envPlain          = False
                         , envRefShortcutable = True
                         , envBlockLevel      = 0
+                        , envEscapeSpaces    = False
                         }
 
 data WriterState = WriterState { stNotes :: Notes
@@ -182,17 +184,17 @@
   let title' = maybe empty text $ getField "title" metadata
   let authors' = maybe [] (map text) $ getField "author" metadata
   let date' = maybe empty text $ getField "date" metadata
-  let titleblock = case writerStandalone opts of
-                        True | isPlain ->
-                                plainTitleBlock title' authors' date'
-                             | isEnabled Ext_yaml_metadata_block opts ->
-                                 yamlMetadataBlock metadata
-                             | isEnabled Ext_pandoc_title_block opts ->
-                                 pandocTitleBlock title' authors' date'
-                             | isEnabled Ext_mmd_title_block opts ->
-                                 mmdTitleBlock metadata
-                             | otherwise -> empty
-                        False -> empty
+  let titleblock = case writerTemplate opts of
+                        Just _ | isPlain ->
+                                 plainTitleBlock title' authors' date'
+                               | isEnabled Ext_yaml_metadata_block opts ->
+                                   yamlMetadataBlock metadata
+                               | isEnabled Ext_pandoc_title_block opts ->
+                                   pandocTitleBlock title' authors' date'
+                               | isEnabled Ext_mmd_title_block opts ->
+                                   mmdTitleBlock metadata
+                               | otherwise -> empty
+                        Nothing -> empty
   let headerBlocks = filter isHeaderBlock blocks
   let toc = if writerTableOfContents opts
                then tableOfContents opts headerBlocks
@@ -214,9 +216,9 @@
                      then id
                      else defField "titleblock" (render' titleblock))
                $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Return markdown representation of reference key table.
 refsToMarkdown :: WriterOptions -> Refs -> MD Doc
@@ -590,20 +592,32 @@
 
 pandocTable :: WriterOptions -> Bool -> [Alignment] -> [Double]
             -> [Doc] -> [[Doc]] -> MD Doc
-pandocTable opts headless aligns widths rawHeaders rawRows =  do
+pandocTable opts headless aligns widths rawHeaders rawRows = do
   let isSimple = all (==0) widths
   let alignHeader alignment = case alignment of
                                 AlignLeft    -> lblock
                                 AlignCenter  -> cblock
                                 AlignRight   -> rblock
                                 AlignDefault -> lblock
-  let numChars = maximum . map offset
-  let widthsInChars = if isSimple
-                         then map ((+2) . numChars)
-                              $ transpose (rawHeaders : rawRows)
-                         else map
-                              (floor . (fromIntegral (writerColumns opts) *))
-                              widths
+  -- Number of characters per column necessary to output every cell
+  -- without requiring a line break.
+  -- The @+2@ is needed for specifying the alignment.
+  let numChars    = (+ 2) . maximum . map offset
+  -- Number of characters per column necessary to output every cell
+  -- without requiring a line break *inside a word*.
+  -- The @+2@ is needed for specifying the alignment.
+  let minNumChars = (+ 2) . maximum . map minOffset
+  let columns = transpose (rawHeaders : rawRows)
+  -- minimal column width without wrapping a single word
+  let noWordWrapWidth
+        | writerWrapText opts == WrapAuto
+                              = fromIntegral $ maximum (map minNumChars columns)
+        | otherwise           = fromIntegral $ maximum (map    numChars columns)
+  let relWidth w = floor $ max (fromIntegral (writerColumns opts) * w)
+                               (noWordWrapWidth * w / minimum widths)
+  let widthsInChars
+        | isSimple  = map numChars columns
+        | otherwise = map relWidth widths
   let makeRow = hcat . intersperse (lblock 1 (text " ")) .
                    (zipWith3 alignHeader aligns widthsInChars)
   let rows' = map makeRow rawRows
@@ -630,12 +644,13 @@
 
 gridTable :: WriterOptions -> Bool -> [Alignment] -> [Double]
           -> [Doc] -> [[Doc]] -> MD Doc
-gridTable opts headless _aligns widths headers' rawRows =  do
+gridTable opts headless aligns widths headers' rawRows =  do
   let numcols = length headers'
   let widths' = if all (==0) widths
                    then replicate numcols (1.0 / fromIntegral numcols)
                    else widths
-  let widthsInChars = map (floor . (fromIntegral (writerColumns opts) *)) widths'
+  let widthsInChars = map
+         ((\x -> x - 3) . floor . (fromIntegral (writerColumns opts) *)) widths'
   let hpipeBlocks blocks = hcat [beg, middle, end]
         where h       = maximum (1 : map height blocks)
               sep'    = lblock 3 $ vcat (map text $ replicate h " | ")
@@ -645,29 +660,52 @@
   let makeRow = hpipeBlocks . zipWith lblock widthsInChars
   let head' = makeRow headers'
   let rows' = map (makeRow . map chomp) rawRows
-  let border ch = char '+' <> char ch <>
-                  (hcat $ intersperse (char ch <> char '+' <> char ch) $
-                          map (\l -> text $ replicate l ch) widthsInChars) <>
-                  char ch <> char '+'
-  let body = vcat $ intersperse (border '-') rows'
+  let borderpart ch align widthInChars =
+        let widthInChars' = if widthInChars < 1 then 1 else widthInChars
+        in (if (align == AlignLeft || align == AlignCenter)
+               then char ':'
+               else char ch) <>
+           text (replicate widthInChars' ch) <>
+           (if (align == AlignRight || align == AlignCenter)
+               then char ':'
+               else char ch)
+  let border ch aligns' widthsInChars' =
+        char '+' <>
+        hcat (intersperse (char '+') (zipWith (borderpart ch)
+                aligns' widthsInChars')) <> char '+'
+  let body = vcat $ intersperse (border '-' (repeat AlignDefault) widthsInChars)
+                    rows'
   let head'' = if headless
                   then empty
-                  else head' $$ border '='
-  return $ border '-' $$ head'' $$ body $$ border '-'
+                  else head' $$ border '=' aligns widthsInChars
+  if headless
+     then return $
+           border '-' aligns widthsInChars $$
+           body $$
+           border '-' (repeat AlignDefault) widthsInChars
+     else return $
+           border '-' (repeat AlignDefault) widthsInChars $$
+           head'' $$
+           body $$
+           border '-' (repeat AlignDefault) widthsInChars
 
+itemEndsWithTightList :: [Block] -> Bool
+itemEndsWithTightList bs =
+  case bs of
+        [Plain _, BulletList xs]    -> isTightList xs
+        [Plain _, OrderedList _ xs] -> isTightList xs
+        _ -> False
+
 -- | Convert bullet list item (list of blocks) to markdown.
 bulletListItemToMarkdown :: WriterOptions -> [Block] -> MD Doc
-bulletListItemToMarkdown opts items = do
-  contents <- blockListToMarkdown opts items
+bulletListItemToMarkdown opts bs = do
+  contents <- blockListToMarkdown opts bs
   let sps = replicate (writerTabStop opts - 2) ' '
   let start = text ('-' : ' ' : sps)
-  -- remove trailing blank line if it is a tight list
-  let contents' = case reverse items of
-                       (BulletList xs:_) | isTightList xs ->
-                            chomp contents <> cr
-                       (OrderedList _ xs:_) | isTightList xs ->
-                            chomp contents <> cr
-                       _ -> contents
+  -- remove trailing blank line if item ends with a tight list
+  let contents' = if itemEndsWithTightList bs
+                     then chomp contents <> cr
+                     else contents
   return $ hang (writerTabStop opts) start $ contents' <> cr
 
 -- | Convert ordered list item (a list of blocks) to markdown.
@@ -675,13 +713,17 @@
                           -> String        -- ^ list item marker
                           -> [Block]       -- ^ list item (list of blocks)
                           -> MD Doc
-orderedListItemToMarkdown opts marker items = do
-  contents <- blockListToMarkdown opts items
+orderedListItemToMarkdown opts marker bs = do
+  contents <- blockListToMarkdown opts bs
   let sps = case length marker - writerTabStop opts of
                    n | n > 0 -> text $ replicate n ' '
                    _         -> text " "
   let start = text marker <> sps
-  return $ hang (writerTabStop opts) start $ contents <> cr
+  -- remove trailing blank line if item ends with a tight list
+  let contents' = if itemEndsWithTightList bs
+                     then chomp contents <> cr
+                     else contents
+  return $ hang (writerTabStop opts) start $ contents' <> cr
 
 -- | Convert definition list item (label, list of blocks) to markdown.
 definitionListItemToMarkdown :: WriterOptions
@@ -823,21 +865,22 @@
 isRight (Right _) = True
 isRight (Left  _) = False
 
-escapeSpaces :: Inline -> Inline
-escapeSpaces (Str s) = Str $ substitute " " "\\ " s
-escapeSpaces Space = Str "\\ "
-escapeSpaces SoftBreak = Str "\\ "
-escapeSpaces x = x
-
 -- | Convert Pandoc inline element to markdown.
 inlineToMarkdown :: WriterOptions -> Inline -> MD Doc
 inlineToMarkdown opts (Span attrs ils) = do
   plain <- asks envPlain
   contents <- inlineListToMarkdown opts ils
-  return $ if not plain &&
-              (isEnabled Ext_raw_html opts || isEnabled Ext_native_spans opts)
-              then tagWithAttrs "span" attrs <> contents <> text "</span>"
-              else contents
+  return $ case plain of
+                True -> contents
+                False | isEnabled Ext_bracketed_spans opts ->
+                        "[" <> contents <> "]" <>
+                          if attrs == nullAttr
+                             then "{}"
+                             else linkAttributes opts attrs
+                      | isEnabled Ext_raw_html opts ||
+                        isEnabled Ext_native_spans opts ->
+                        tagWithAttrs "span" attrs <> contents <> text "</span>"
+                      | otherwise -> contents
 inlineToMarkdown opts (Emph lst) = do
   plain <- asks envPlain
   contents <- inlineListToMarkdown opts lst
@@ -858,31 +901,33 @@
               else if isEnabled Ext_raw_html opts
                        then "<s>" <> contents <> "</s>"
                        else contents
-inlineToMarkdown opts (Superscript lst) = do
-  contents <- inlineListToMarkdown opts $ walk escapeSpaces lst
-  return $ if isEnabled Ext_superscript opts
-              then "^" <> contents <> "^"
-              else if isEnabled Ext_raw_html opts
-                       then "<sup>" <> contents <> "</sup>"
-                       else case (render Nothing contents) of
-                                 ds | all (\d -> d >= '0' && d <= '9') ds
-                                   -> text (map toSuperscript ds)
-                                 _ -> contents
-                        where toSuperscript '1' = '\x00B9'
-                              toSuperscript '2' = '\x00B2'
-                              toSuperscript '3' = '\x00B3'
-                              toSuperscript c = chr (0x2070 + (ord c - 48))
-inlineToMarkdown opts (Subscript lst) = do
-  contents <- inlineListToMarkdown opts $ walk escapeSpaces lst
-  return $ if isEnabled Ext_subscript opts
-              then "~" <> contents <> "~"
-              else if isEnabled Ext_raw_html opts
-                       then "<sub>" <> contents <> "</sub>"
-                       else case (render Nothing contents) of
-                                 ds | all (\d -> d >= '0' && d <= '9') ds
-                                   -> text (map toSubscript ds)
-                                 _ -> contents
-                        where toSubscript c = chr (0x2080 + (ord c - 48))
+inlineToMarkdown opts (Superscript lst) =
+  local (\env -> env {envEscapeSpaces = True}) $ do
+    contents <- inlineListToMarkdown opts lst
+    return $ if isEnabled Ext_superscript opts
+                then "^" <> contents <> "^"
+                else if isEnabled Ext_raw_html opts
+                         then "<sup>" <> contents <> "</sup>"
+                         else case (render Nothing contents) of
+                                   ds | all (\d -> d >= '0' && d <= '9') ds
+                                     -> text (map toSuperscript ds)
+                                   _ -> contents
+                          where toSuperscript '1' = '\x00B9'
+                                toSuperscript '2' = '\x00B2'
+                                toSuperscript '3' = '\x00B3'
+                                toSuperscript c = chr (0x2070 + (ord c - 48))
+inlineToMarkdown opts (Subscript lst) =
+  local (\env -> env {envEscapeSpaces = True}) $ do
+    contents <- inlineListToMarkdown opts lst
+    return $ if isEnabled Ext_subscript opts
+                then "~" <> contents <> "~"
+                else if isEnabled Ext_raw_html opts
+                         then "<sub>" <> contents <> "</sub>"
+                         else case (render Nothing contents) of
+                                   ds | all (\d -> d >= '0' && d <= '9') ds
+                                     -> text (map toSubscript ds)
+                                   _ -> contents
+                          where toSubscript c = chr (0x2080 + (ord c - 48))
 inlineToMarkdown opts (SmallCaps lst) = do
   plain <- asks envPlain
   if not plain &&
@@ -959,12 +1004,16 @@
           if isEnabled Ext_escaped_line_breaks opts
              then "\\" <> cr
              else "  " <> cr
-inlineToMarkdown _ Space = return space
-inlineToMarkdown opts SoftBreak = return $
-  case writerWrapText opts of
-       WrapNone     -> space
-       WrapAuto     -> space
-       WrapPreserve -> cr
+inlineToMarkdown _ Space = do
+  escapeSpaces <- asks envEscapeSpaces
+  return $ if escapeSpaces then "\\ " else space
+inlineToMarkdown opts SoftBreak = do
+  escapeSpaces <- asks envEscapeSpaces
+  let space' = if escapeSpaces then "\\ " else space
+  return $ case writerWrapText opts of
+                WrapNone     -> space'
+                WrapAuto     -> space'
+                WrapPreserve -> cr
 inlineToMarkdown opts (Cite [] lst) = inlineListToMarkdown opts lst
 inlineToMarkdown opts (Cite (c:cs) lst)
   | not (isEnabled Ext_citations opts) = inlineListToMarkdown opts lst
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
@@ -79,9 +79,9 @@
   let main = body ++ notes
   let context = defField "body" main
                 $ defField "toc" (writerTableOfContents opts) metadata
-  return $ if writerStandalone opts
-     then renderTemplate' (writerTemplate opts) context
-     else main
+  return $ case writerTemplate opts of
+                Nothing  -> main
+                Just tpl -> renderTemplate' tpl context
 
 -- | Escape special characters for MediaWiki.
 escapeString :: String -> String
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
@@ -27,10 +27,6 @@
    Portability : portable
 
 Conversion of a 'Pandoc' document to a string representation.
-
-Note:  If @writerStandalone@ is @False@, only the document body
-is represented; otherwise, the full 'Pandoc' document, including the
-metadata.
 -}
 module Text.Pandoc.Writers.Native ( writeNative )
 where
@@ -75,8 +71,8 @@
   let colwidth = if writerWrapText opts == WrapAuto
                     then Just $ writerColumns opts
                     else Nothing
-      withHead = if writerStandalone opts
-                    then \bs -> text ("Pandoc (" ++ show meta ++ ")") $$
+      withHead = case writerTemplate opts of
+                      Just _  -> \bs -> text ("Pandoc (" ++ show meta ++ ")") $$
                                   bs $$ cr
-                    else id
+                      Nothing -> id
   in  render colwidth $ withHead $ prettyList $ map prettyBlock blocks
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
@@ -56,9 +56,9 @@
                       meta'
       main     = render colwidth $ vcat (map (elementToOPML opts) elements)
       context = defField "body" main metadata
-  in  if writerStandalone opts
-         then renderTemplate' (writerTemplate opts) context
-         else main
+  in  case writerTemplate opts of
+           Nothing  -> main
+           Just tpl -> renderTemplate' tpl context
 
 writeHtmlInlines :: [Inline] -> String
 writeHtmlInlines ils = trim $ writeHtmlString def
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
@@ -196,9 +196,9 @@
       context = defField "body" body
               $ defField "automatic-styles" (render' automaticStyles)
               $ metadata
-  in  if writerStandalone opts
-         then renderTemplate' (writerTemplate opts) context
-         else body
+  in  case writerTemplate opts of
+           Nothing  -> body
+           Just tpl -> renderTemplate' tpl context
 
 withParagraphStyle :: WriterOptions -> String -> [Block] -> State WriterState Doc
 withParagraphStyle  o s (b:bs)
@@ -336,7 +336,7 @@
         mapM_ addParaStyle . newPara $ paraHStyles ++ paraStyles
         captionDoc <- if null c
                       then return empty
-                      else withParagraphStyle o "TableCaption" [Para c]
+                      else withParagraphStyle o "Table" [Para c]
         th <- if all null h
                  then return empty
                  else colHeadsToOpenDocument o name (map fst paraHStyles) h
@@ -392,7 +392,7 @@
     Subscript   l -> withTextStyle Sub    $ inlinesToOpenDocument o l
     SmallCaps   l -> withTextStyle SmallC $ inlinesToOpenDocument o l
     Quoted    t l -> inQuotes t <$> inlinesToOpenDocument o l
-    Code      _ s -> withTextStyle Pre $ inTextStyle $ preformatted s
+    Code      _ s -> inlinedCode $ preformatted s
     Math      t s -> inlinesToOpenDocument o (texMathToInlines t s)
     Cite      _ l -> inlinesToOpenDocument o l
     RawInline f s -> if f == Format "opendocument"
@@ -403,6 +403,7 @@
     Note        l  -> mkNote l
     where
       preformatted s = handleSpaces $ escapeStringForXML s
+      inlinedCode s = return $ inTags False "text:span" [("text:style-name", "Source_Text")] s
       mkLink   s t = inTags False "text:a" [ ("xlink:type" , "simple")
                                            , ("xlink:href" , s       )
                                            , ("office:name", t       )
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
@@ -78,9 +78,9 @@
   let context = defField "body" main
               $ defField "math" hasMath
               $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Return Org representation of notes.
 notesToOrg :: [[Block]] -> State WriterState Doc
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
@@ -81,9 +81,9 @@
                 (fmap (render colwidth) . blockListToRST)
                 (fmap (trimr . render colwidth) . inlineListToRST)
                 $ deleteMeta "title" $ deleteMeta "subtitle" meta
-  body <- blockListToRST' True $ if writerStandalone opts
-                                    then normalizeHeadings 1 blocks
-                                    else blocks
+  body <- blockListToRST' True $ case writerTemplate opts of
+                                      Just _  -> normalizeHeadings 1 blocks
+                                      Nothing -> blocks
   notes <- liftM (reverse . stNotes) get >>= notesToRST
   -- note that the notes may contain refs, so we do them first
   refs <- liftM (reverse . stLinks) get >>= refsToRST
@@ -99,9 +99,9 @@
               $ defField "math" hasMath
               $ defField "rawtex" rawTeX
               $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
   where
     normalizeHeadings lev (Header l a i:bs) =
       Header lev a i:normalizeHeadings (lev+1) cont ++ normalizeHeadings lev bs'
@@ -268,7 +268,7 @@
           then map ((+2) . numChars) $ transpose (headers' : rawRows)
           else map (floor . (fromIntegral (writerColumns opts) *)) widths
   let hpipeBlocks blocks = hcat [beg, middle, end]
-        where h      = maximum (1 : map height blocks)
+        where h      = height (hcat blocks)
               sep'   = lblock 3 $ vcat (map text $ replicate h " | ")
               beg    = lblock 2 $ vcat (map text $ replicate h "| ")
               end    = lblock 2 $ vcat (map text $ replicate h " |")
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
@@ -107,11 +107,11 @@
                           (tableOfContents $ filter isTOCHeader blocks)
                     else id)
               $ metadata
-  in  if writerStandalone options
-         then renderTemplate' (writerTemplate options) context
-         else case reverse body of
-                ('\n':_) -> body
-                _        -> body ++ "\n"
+  in  case writerTemplate options of
+           Just tpl -> renderTemplate' tpl context
+           Nothing  -> case reverse body of
+                            ('\n':_) -> body
+                            _        -> body ++ "\n"
 
 -- | Construct table of contents from list of header blocks.
 tableOfContents :: [Block] -> String
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
@@ -49,6 +49,7 @@
 import Text.Pandoc.UTF8 (toStringLazy)
 import qualified Data.Traversable as Traversable
 import Data.List ( groupBy )
+import Data.Maybe ( isJust )
 
 -- | Create JSON value for template from a 'Meta' and an association list
 -- of variables, specified at the command line or in the writer.
@@ -62,7 +63,7 @@
            -> Meta
            -> m Value
 metaToJSON opts blockWriter inlineWriter (Meta metamap)
-  | writerStandalone opts = do
+  | isJust (writerTemplate opts) = do
     let baseContext = foldl (\acc (x,y) -> setField x y acc) (Object H.empty)
                       $ writerVariables opts
     renderedMap <- Traversable.mapM
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
@@ -61,9 +61,10 @@
                     else Nothing
       render' = render colwidth
       startLvl = case writerTopLevelDivision opts of
-                   Part    -> -1
-                   Chapter -> 0
-                   Section -> 1
+                   TopLevelPart    -> -1
+                   TopLevelChapter -> 0
+                   TopLevelSection -> 1
+                   TopLevelDefault -> 1
       auths'   = map (authorToTEI opts) $ docAuthors meta
       meta'    = B.setMeta "author" auths' meta
       Just metadata = metaToJSON opts
@@ -77,9 +78,9 @@
                                         MathML _ -> True
                                         _        -> False)
               $ metadata
-  in  if writerStandalone opts
-         then renderTemplate' (writerTemplate opts) context
-         else main
+  in  case writerTemplate opts of
+           Nothing  -> main
+           Just tpl -> renderTemplate' tpl context
 
 -- | Convert an Element to TEI.
 elementToTEI :: WriterOptions -> Int -> Element -> Doc
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
@@ -93,9 +93,9 @@
               $ defField "superscript" (stSuperscript st)
               $ defField "strikeout" (stStrikeout st)
               $ metadata
-  if writerStandalone options
-     then return $ renderTemplate' (writerTemplate options) context
-     else return body
+  case writerTemplate options of
+       Nothing  -> return body
+       Just tpl -> return $ renderTemplate' tpl context
 
 -- | Escape things as needed for Texinfo.
 stringToTexinfo :: String -> String
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
@@ -65,9 +65,9 @@
   notes <- liftM (unlines . reverse . stNotes) get
   let main = body ++ if null notes then "" else ("\n\n" ++ notes)
   let context = defField "body" main metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Nothing  -> return main
+       Just tpl -> return $ renderTemplate' tpl context
 
 withUseTags :: State WriterState a -> State WriterState a
 withUseTags action = do
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
@@ -32,7 +32,7 @@
 
 module Text.Pandoc.Writers.ZimWiki ( writeZimWiki ) where
 import Text.Pandoc.Definition
-import Text.Pandoc.Options ( WriterOptions(writerTableOfContents, writerStandalone, writerTemplate, writerWrapText), WrapOption(..) )
+import Text.Pandoc.Options ( WriterOptions(writerTableOfContents, writerTemplate, writerWrapText), WrapOption(..) )
 import Text.Pandoc.Shared ( escapeURI, linesToPara, removeFormatting, trimr
                           , substitute )
 import Text.Pandoc.Writers.Shared ( defField, metaToJSON )
@@ -71,9 +71,9 @@
   let context = defField "body" main
                 $ defField "toc" (writerTableOfContents opts)
                 $ metadata
-  if writerStandalone opts
-     then return $ renderTemplate' (writerTemplate opts) context
-     else return main
+  case writerTemplate opts of
+       Just tpl -> return $ renderTemplate' tpl context
+       Nothing  -> return main
 
 -- | Escape special characters for ZimWiki.
 escapeString :: String -> String
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -8,6 +8,7 @@
 packages:
 - '.'
 extra-deps:
+- texmath-0.9
 - doctemplates-0.1.0.2
 - pandoc-types-1.17.0.4
-resolver: lts-7.5
+resolver: lts-7.9
diff --git a/tests/Tests/Helpers.hs b/tests/Tests/Helpers.hs
--- a/tests/Tests/Helpers.hs
+++ b/tests/Tests/Helpers.hs
@@ -57,11 +57,11 @@
   toString :: a -> String
 
 instance ToString Pandoc where
-  toString d = writeNative def{ writerStandalone = s } $ toPandoc d
+  toString d = writeNative def{ writerTemplate = s } $ toPandoc d
    where s = case d of
                   (Pandoc (Meta m) _)
-                    | M.null m  -> False
-                    | otherwise -> True
+                    | M.null m  -> Nothing
+                    | otherwise -> Just "" -- need this to get meta output
 
 instance ToString Blocks where
   toString = writeNative def . toPandoc
diff --git a/tests/Tests/Readers/Docx.hs b/tests/Tests/Readers/Docx.hs
--- a/tests/Tests/Readers/Docx.hs
+++ b/tests/Tests/Readers/Docx.hs
@@ -26,11 +26,11 @@
 noNorm = NoNormPandoc
 
 instance ToString NoNormPandoc where
-  toString d = writeNative def{ writerStandalone = s } $ toPandoc d
+  toString d = writeNative def{ writerTemplate = s } $ toPandoc d
    where s = case d of
                   NoNormPandoc (Pandoc (Meta m) _)
-                    | M.null m  -> False
-                    | otherwise -> True
+                    | M.null m  -> Nothing
+                    | otherwise -> Just "" -- need this to get meta output
 
 instance ToPandoc NoNormPandoc where
   toPandoc = unNoNorm
diff --git a/tests/Tests/Readers/HTML.hs b/tests/Tests/Readers/HTML.hs
--- a/tests/Tests/Readers/HTML.hs
+++ b/tests/Tests/Readers/HTML.hs
@@ -26,4 +26,8 @@
             "<head><base href=\"http://www.w3schools.com/images/\" ></head><body><img src=\"http://example.com/stickman.gif\" alt=\"Stickman\"></head>" =?>
             plain (image "http://example.com/stickman.gif" "" (text "Stickman"))
           ]
+        , testGroup "anchors"
+          [ test html "anchor without href" $ "<a name=\"anchor\"/>" =?>
+            plain (spanWith ("anchor",[],[]) mempty)
+          ]
         ]
diff --git a/tests/Tests/Readers/Odt.hs b/tests/Tests/Readers/Odt.hs
--- a/tests/Tests/Readers/Odt.hs
+++ b/tests/Tests/Readers/Odt.hs
@@ -41,11 +41,11 @@
   deriving ( Show )
 
 instance ToString NoNormPandoc where
-  toString d = writeNative def{ writerStandalone = s } $ toPandoc d
+  toString d = writeNative def{ writerTemplate = s } $ toPandoc d
    where s = case d of
                   NoNormPandoc (Pandoc (Meta m) _)
-                    | M.null m  -> False
-                    | otherwise -> True
+                    | M.null m  -> Nothing
+                    | otherwise -> Just "" -- need this for Meta output
 
 instance ToPandoc NoNormPandoc where
   toPandoc = unNoNorm
@@ -149,6 +149,7 @@
                                   , "image"
                                   , "imageIndex"
                                   , "imageWithCaption"
+                                  , "inlinedCode"
                                   , "orderedListMixed"
                                   , "orderedListRoman"
                                   , "orderedListSimple"
@@ -156,6 +157,7 @@
                                   , "referenceToListItem"
                                   , "referenceToText"
                                   , "simpleTable"
+                                  , "simpleTableWithCaption"
 --                                , "table"
                                   , "unicode"
                                   , "unorderedList"
diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs
--- a/tests/Tests/Readers/Org.hs
+++ b/tests/Tests/Readers/Org.hs
@@ -188,14 +188,30 @@
           "=is_subst = True=" =?>
           para (code "is_subst = True")
 
-      , "Image" =:
-          "[[./sunset.jpg]]" =?>
-          (para $ image "./sunset.jpg" "" "")
+      , testGroup "Images"
+        [ "Image" =:
+            "[[./sunset.jpg]]" =?>
+            (para $ image "./sunset.jpg" "" "")
 
-      , "Image with explicit file: prefix" =:
-          "[[file:sunrise.jpg]]" =?>
-          (para $ image "sunrise.jpg" "" "")
+        , "Image with explicit file: prefix" =:
+            "[[file:sunrise.jpg]]" =?>
+            (para $ image "sunrise.jpg" "" "")
 
+        , "Multiple images within a paragraph" =:
+            unlines [ "[[file:sunrise.jpg]]"
+                    , "[[file:sunset.jpg]]"
+                    ] =?>
+            (para $ (image "sunrise.jpg" "" "")
+                 <> softbreak
+                 <> (image "sunset.jpg" "" ""))
+
+        , "Image with html attributes" =:
+            unlines [ "#+ATTR_HTML: :width 50%"
+                    , "[[file:guinea-pig.gif]]"
+                    ] =?>
+            (para $ imageWith ("", [], [("width", "50%")]) "guinea-pig.gif" "" "")
+        ]
+
       , "Explicit link" =:
           "[[http://zeitlens.com/][pseudo-random /nonsense/]]" =?>
           (para $ link "http://zeitlens.com/" ""
@@ -685,6 +701,12 @@
                       , "#+email: no-mail-please@example.com"
                       ] =?>
               Pandoc nullMeta mempty
+
+          , "disable inclusion of todo keywords" =:
+              unlines [ "#+OPTIONS: todo:nil"
+                      , "** DONE todo export"
+                      ] =?>
+              headerWith ("todo-export", [], []) 2 "todo export"
           ]
       ]
 
@@ -693,139 +715,179 @@
           "Paragraph\n" =?>
           para "Paragraph"
 
-      , "First Level Header" =:
-          "* Headline\n" =?>
-          headerWith ("headline", [], []) 1 "Headline"
+      , testGroup "headers" $
+        [ "First Level Header" =:
+            "* Headline\n" =?>
+            headerWith ("headline", [], []) 1 "Headline"
 
-      , "Third Level Header" =:
-          "*** Third Level Headline\n" =?>
-          headerWith ("third-level-headline", [], [])
-                     3
-                     ("Third" <> space <> "Level" <> space <> "Headline")
+        , "Third Level Header" =:
+            "*** Third Level Headline\n" =?>
+            headerWith ("third-level-headline", [], [])
+                       3
+                       ("Third" <> space <> "Level" <> space <> "Headline")
 
-      , "Compact Headers with Paragraph" =:
-          unlines [ "* First Level"
-                  , "** Second Level"
-                  , "   Text"
-                  ] =?>
-          mconcat [ headerWith ("first-level", [], [])
-                               1
-                               ("First" <> space <> "Level")
-                  , headerWith ("second-level", [], [])
-                               2
-                               ("Second" <> space <> "Level")
-                  , para "Text"
-                  ]
+        , "Compact Headers with Paragraph" =:
+            unlines [ "* First Level"
+                    , "** Second Level"
+                    , "   Text"
+                    ] =?>
+            mconcat [ headerWith ("first-level", [], [])
+                                 1
+                                 ("First" <> space <> "Level")
+                    , headerWith ("second-level", [], [])
+                                 2
+                                 ("Second" <> space <> "Level")
+                    , para "Text"
+                    ]
 
-      , "Separated Headers with Paragraph" =:
-          unlines [ "* First Level"
-                  , ""
-                  , "** Second Level"
-                  , ""
-                  , "   Text"
-                  ] =?>
-          mconcat [ headerWith ("first-level", [], [])
-                               1
-                               ("First" <> space <> "Level")
-                  , headerWith ("second-level", [], [])
-                               2
-                               ("Second" <> space <> "Level")
-                  , para "Text"
-                  ]
+        , "Separated Headers with Paragraph" =:
+            unlines [ "* First Level"
+                    , ""
+                    , "** Second Level"
+                    , ""
+                    , "   Text"
+                    ] =?>
+            mconcat [ headerWith ("first-level", [], [])
+                                 1
+                                 ("First" <> space <> "Level")
+                    , headerWith ("second-level", [], [])
+                                 2
+                                 ("Second" <> space <> "Level")
+                    , para "Text"
+                    ]
 
-      , "Headers not preceded by a blank line" =:
-          unlines [ "** eat dinner"
-                  , "Spaghetti and meatballs tonight."
-                  , "** walk dog"
-                  ] =?>
-          mconcat [ headerWith ("eat-dinner", [], [])
-                               2
-                               ("eat" <> space <> "dinner")
-                  , para $ spcSep [ "Spaghetti", "and", "meatballs", "tonight." ]
-                  , headerWith ("walk-dog", [], [])
-                               2
-                               ("walk" <> space <> "dog")
-                  ]
+        , "Headers not preceded by a blank line" =:
+            unlines [ "** eat dinner"
+                    , "Spaghetti and meatballs tonight."
+                    , "** walk dog"
+                    ] =?>
+            mconcat [ headerWith ("eat-dinner", [], [])
+                                 2
+                                 ("eat" <> space <> "dinner")
+                    , para $ spcSep [ "Spaghetti", "and", "meatballs", "tonight." ]
+                    , headerWith ("walk-dog", [], [])
+                                 2
+                                 ("walk" <> space <> "dog")
+                    ]
 
-      , "Tagged headers" =:
-          unlines [ "* Personal       :PERSONAL:"
-                  , "** Call Mom      :@PHONE:"
-                  , "** Call John     :@PHONE:JOHN: "
-                  ] =?>
-          let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
-          in mconcat [ headerWith ("personal", [], [])
-                                  1
-                                  ("Personal" <> tagSpan "PERSONAL")
-                     , headerWith ("call-mom", [], [])
-                                  2
-                                  ("Call Mom" <> tagSpan "@PHONE")
-                     , headerWith ("call-john", [], [])
-                                  2
-                                  ("Call John" <> tagSpan "@PHONE" <> tagSpan "JOHN")
-                     ]
+        , testGroup "Todo keywords"
+          [ "Header with known todo keyword" =:
+              "* TODO header" =?>
+              let todoSpan = spanWith ("", ["todo", "TODO"], []) "TODO"
+              in headerWith ("header", [], []) 1 (todoSpan <> space <> "header")
 
-      , "Untagged header containing colons" =:
-          "* This: is not: tagged" =?>
-          headerWith ("this-is-not-tagged", [], []) 1 "This: is not: tagged"
+          , "Header marked as done" =:
+              "* DONE header" =?>
+              let todoSpan = spanWith ("", ["done", "DONE"], []) "DONE"
+              in headerWith ("header", [], []) 1 (todoSpan <> space <> "header")
 
-      , "Header starting with strokeout text" =:
-          unlines [ "foo"
-                  , ""
-                  , "* +thing+ other thing"
-                  ] =?>
-          mconcat [ para "foo"
-                  , headerWith ("thing-other-thing", [], [])
-                               1
-                               ((strikeout "thing") <> " other thing")
-                  ]
+          , "Header with unknown todo keyword" =:
+              "* WAITING header" =?>
+              headerWith ("waiting-header", [], []) 1 "WAITING header"
 
-      , "Comment Trees" =:
-          unlines [ "* COMMENT A comment tree"
-                  , "  Not much going on here"
-                  , "** This will be dropped"
-                  , "* Comment tree above"
-                  ] =?>
-          headerWith ("comment-tree-above", [], []) 1 "Comment tree above"
+          , "Custom todo keywords" =:
+              unlines [ "#+TODO: WAITING CANCELLED"
+                      , "* WAITING compile"
+                      , "* CANCELLED lunch"
+                      ] =?>
+              let todoSpan = spanWith ("", ["todo", "WAITING"], []) "WAITING"
+                  doneSpan = spanWith ("", ["done", "CANCELLED"], []) "CANCELLED"
+              in headerWith ("compile", [], []) 1 (todoSpan <> space <> "compile")
+              <> headerWith ("lunch", [], []) 1 (doneSpan <> space <> "lunch")
 
-      , "Nothing but a COMMENT header" =:
-          "* COMMENT Test" =?>
-          (mempty::Blocks)
+          , "Custom todo keywords with multiple done-states" =:
+              unlines [ "#+TODO: WAITING | DONE CANCELLED "
+                      , "* WAITING compile"
+                      , "* CANCELLED lunch"
+                      , "* DONE todo-feature"
+                      ] =?>
+              let waiting = spanWith ("", ["todo", "WAITING"], []) "WAITING"
+                  cancelled = spanWith ("", ["done", "CANCELLED"], []) "CANCELLED"
+                  done = spanWith ("", ["done", "DONE"], []) "DONE"
+              in headerWith ("compile", [], []) 1 (waiting <> space <> "compile")
+              <> headerWith ("lunch", [], []) 1 (cancelled <> space <> "lunch")
+              <> headerWith ("todo-feature", [], []) 1 (done <> space <> "todo-feature")
+          ]
 
-      , "Tree with :noexport:" =:
-          unlines [ "* Should be ignored :archive:noexport:old:"
-                  , "** Old stuff"
-                  , "   This is not going to be exported"
-                  ] =?>
-          (mempty::Blocks)
+        , "Tagged headers" =:
+            unlines [ "* Personal       :PERSONAL:"
+                    , "** Call Mom      :@PHONE:"
+                    , "** Call John     :@PHONE:JOHN: "
+                    ] =?>
+            let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
+            in mconcat [ headerWith ("personal", [], [])
+                                    1
+                                    ("Personal" <> tagSpan "PERSONAL")
+                       , headerWith ("call-mom", [], [])
+                                    2
+                                    ("Call Mom" <> tagSpan "@PHONE")
+                       , headerWith ("call-john", [], [])
+                                    2
+                                    ("Call John" <> tagSpan "@PHONE" <> tagSpan "JOHN")
+                       ]
 
-      , "Subtree with :noexport:" =:
-          unlines [ "* Exported"
-                  , "** This isn't exported :noexport:"
-                  , "*** This neither"
-                  , "** But this is"
-                  ] =?>
-          mconcat [ headerWith ("exported", [], []) 1 "Exported"
-                  , headerWith ("but-this-is", [], []) 2 "But this is"
-                  ]
+        , "Untagged header containing colons" =:
+            "* This: is not: tagged" =?>
+            headerWith ("this-is-not-tagged", [], []) 1 "This: is not: tagged"
 
-      , "Preferences are treated as header attributes" =:
-          unlines [ "* foo"
-                  , "  :PROPERTIES:"
-                  , "  :custom_id: fubar"
-                  , "  :bar: baz"
-                  , "  :END:"
-                  ] =?>
-          headerWith ("fubar", [], [("bar", "baz")]) 1 "foo"
+        , "Header starting with strokeout text" =:
+            unlines [ "foo"
+                    , ""
+                    , "* +thing+ other thing"
+                    ] =?>
+            mconcat [ para "foo"
+                    , headerWith ("thing-other-thing", [], [])
+                                 1
+                                 ((strikeout "thing") <> " other thing")
+                    ]
 
+        , "Comment Trees" =:
+            unlines [ "* COMMENT A comment tree"
+                    , "  Not much going on here"
+                    , "** This will be dropped"
+                    , "* Comment tree above"
+                    ] =?>
+            headerWith ("comment-tree-above", [], []) 1 "Comment tree above"
 
-      , "Headers marked with a unnumbered property get a class of the same name" =:
-          unlines [ "* Not numbered"
-                  , "  :PROPERTIES:"
-                  , "  :UNNUMBERED: t"
-                  , "  :END:"
-                  ] =?>
-          headerWith ("not-numbered", ["unnumbered"], []) 1 "Not numbered"
+        , "Nothing but a COMMENT header" =:
+            "* COMMENT Test" =?>
+            (mempty::Blocks)
 
+        , "Tree with :noexport:" =:
+            unlines [ "* Should be ignored :archive:noexport:old:"
+                    , "** Old stuff"
+                    , "   This is not going to be exported"
+                    ] =?>
+            (mempty::Blocks)
+
+        , "Subtree with :noexport:" =:
+            unlines [ "* Exported"
+                    , "** This isn't exported :noexport:"
+                    , "*** This neither"
+                    , "** But this is"
+                    ] =?>
+            mconcat [ headerWith ("exported", [], []) 1 "Exported"
+                    , headerWith ("but-this-is", [], []) 2 "But this is"
+                    ]
+
+        , "Preferences are treated as header attributes" =:
+            unlines [ "* foo"
+                    , "  :PROPERTIES:"
+                    , "  :custom_id: fubar"
+                    , "  :bar: baz"
+                    , "  :END:"
+                    ] =?>
+            headerWith ("fubar", [], [("bar", "baz")]) 1 "foo"
+
+
+        , "Headers marked with a unnumbered property get a class of the same name" =:
+            unlines [ "* Not numbered"
+                    , "  :PROPERTIES:"
+                    , "  :UNNUMBERED: t"
+                    , "  :END:"
+                    ] =?>
+            headerWith ("not-numbered", ["unnumbered"], []) 1 "Not numbered"
+      ]
       , "Paragraph starting with an asterisk" =:
           "*five" =?>
           para "*five"
@@ -1578,6 +1640,15 @@
                   , "#+end_html"
                   ] =?>
           rawBlock "html" "\n<span>boring</span>\n\n"
+
+      , "Accept `ATTR_HTML` attributes for generic block" =:
+          unlines [ "#+ATTR_HTML: :title hello, world :id test :class fun code"
+                  , "#+BEGIN_TEST"
+                  , "nonsense"
+                  , "#+END_TEST"
+                  ] =?>
+          let attr = ("test", ["fun", "code", "TEST"], [("title", "hello, world")])
+          in divWith attr (para "nonsense")
 
       , "Non-letter chars in source block parameters" =:
           unlines [ "#+BEGIN_SRC C :tangle xxxx.c :city Zürich"
diff --git a/tests/Tests/Writers/Docbook.hs b/tests/Tests/Writers/Docbook.hs
--- a/tests/Tests/Writers/Docbook.hs
+++ b/tests/Tests/Writers/Docbook.hs
@@ -236,11 +236,13 @@
                       <> header 2 (text "header2")
                       <> header 3 (text "header3")
 
-              docbookTopLevelDiv :: (ToPandoc a) => Division -> a -> String
+              docbookTopLevelDiv :: (ToPandoc a)
+                                 => TopLevelDivision -> a -> String
               docbookTopLevelDiv division =
                 docbookWithOpts def{ writerTopLevelDivision = division }
             in
-            [ test (docbookTopLevelDiv Section) "sections as top-level" $ headers =?>
+            [ test (docbookTopLevelDiv TopLevelSection) "sections as top-level" $
+              headers =?>
               unlines [ "<sect1>"
                       , "  <title>header1</title>"
                       , "  <sect2>"
@@ -253,7 +255,8 @@
                       , "  </sect2>"
                       , "</sect1>"
                       ]
-            , test (docbookTopLevelDiv Chapter) "chapters as top-level" $ headers =?>
+            , test (docbookTopLevelDiv TopLevelChapter) "chapters as top-level" $
+              headers =?>
               unlines [ "<chapter>"
                       , "  <title>header1</title>"
                       , "  <sect1>"
@@ -266,7 +269,8 @@
                       , "  </sect1>"
                       , "</chapter>"
                       ]
-            , test (docbookTopLevelDiv Part) "parts as top-level" $ headers =?>
+            , test (docbookTopLevelDiv TopLevelPart) "parts as top-level" $
+              headers =?>
               unlines [ "<part>"
                       , "  <title>header1</title>"
                       , "  <chapter>"
@@ -278,6 +282,20 @@
                       , "    </sect1>"
                       , "  </chapter>"
                       , "</part>"
+                      ]
+            , test (docbookTopLevelDiv TopLevelDefault) "default top-level" $
+              headers =?>
+              unlines [ "<sect1>"
+                      , "  <title>header1</title>"
+                      , "  <sect2>"
+                      , "    <title>header2</title>"
+                      , "    <sect3>"
+                      , "      <title>header3</title>"
+                      , "      <para>"
+                      , "      </para>"
+                      , "    </sect3>"
+                      , "  </sect2>"
+                      , "</sect1>"
                       ]
             ]
           ]
diff --git a/tests/Tests/Writers/LaTeX.hs b/tests/Tests/Writers/LaTeX.hs
--- a/tests/Tests/Writers/LaTeX.hs
+++ b/tests/Tests/Writers/LaTeX.hs
@@ -88,44 +88,63 @@
                       <> header 2 (text "header2")
                       <> header 3 (text "header3")
 
-              latexTopLevelDiv :: (ToPandoc a) => Division -> a -> String
+              latexTopLevelDiv :: (ToPandoc a) => TopLevelDivision -> a -> String
               latexTopLevelDiv division =
                 latexWithOpts def{ writerTopLevelDivision = division }
 
-              beamerTopLevelDiv :: (ToPandoc a) => Division -> a -> String
+              beamerTopLevelDiv :: (ToPandoc a)
+                                => TopLevelDivision -> a -> String
               beamerTopLevelDiv division =
                 latexWithOpts def { writerTopLevelDivision = division
                                   , writerBeamer = True }
             in
-            [ test (latexTopLevelDiv Section) "sections as top-level" $ headers =?>
+            [ test (latexTopLevelDiv TopLevelSection)
+                   "sections as top-level" $ headers =?>
               unlines [ "\\section{header1}\n"
                       , "\\subsection{header2}\n"
                       , "\\subsubsection{header3}"
                       ]
-            , test (latexTopLevelDiv Chapter) "chapters as top-level" $ headers =?>
+            , test (latexTopLevelDiv TopLevelChapter)
+                   "chapters as top-level" $ headers =?>
               unlines [ "\\chapter{header1}\n"
                       , "\\section{header2}\n"
                       , "\\subsection{header3}"
                       ]
-            , test (latexTopLevelDiv Part) "parts as top-level" $ headers =?>
+            , test (latexTopLevelDiv TopLevelPart)
+                   "parts as top-level" $ headers =?>
               unlines [ "\\part{header1}\n"
                       , "\\chapter{header2}\n"
                       , "\\section{header3}"
                       ]
-            , test (beamerTopLevelDiv Section) "sections as top-level in beamer" $ headers =?>
+            , test (latexTopLevelDiv TopLevelDefault)
+                   "default top-level" $ headers =?>
               unlines [ "\\section{header1}\n"
                       , "\\subsection{header2}\n"
                       , "\\subsubsection{header3}"
                       ]
-            , test (beamerTopLevelDiv Chapter) "chapters are as part in beamer" $ headers =?>
+            , test (beamerTopLevelDiv TopLevelSection)
+                   "sections as top-level in beamer" $ headers =?>
+              unlines [ "\\section{header1}\n"
+                      , "\\subsection{header2}\n"
+                      , "\\subsubsection{header3}"
+                      ]
+            , test (beamerTopLevelDiv TopLevelChapter)
+                   "chapters are as part in beamer" $ headers =?>
               unlines [ "\\part{header1}\n"
                       , "\\section{header2}\n"
                       , "\\subsection{header3}"
                       ]
-            , test (beamerTopLevelDiv Part) "parts as top-level in beamer" $ headers =?>
+            , test (beamerTopLevelDiv TopLevelPart)
+                   "parts as top-level in beamer" $ headers =?>
               unlines [ "\\part{header1}\n"
                       , "\\section{header2}\n"
                       , "\\subsection{header3}"
+                      ]
+            , test (beamerTopLevelDiv TopLevelDefault)
+                   "default top-level in beamer" $ headers =?>
+              unlines [ "\\section{header1}\n"
+                      , "\\subsection{header2}\n"
+                      , "\\subsubsection{header3}"
                       ]
             ]
           ]
diff --git a/tests/Tests/Writers/Native.hs b/tests/Tests/Writers/Native.hs
--- a/tests/Tests/Writers/Native.hs
+++ b/tests/Tests/Writers/Native.hs
@@ -8,7 +8,7 @@
 
 p_write_rt :: Pandoc -> Bool
 p_write_rt d =
-  read (writeNative def{ writerStandalone = True } d) == d
+  read (writeNative def{ writerTemplate = Just "" } d) == d
 
 p_write_blocks_rt :: [Block] -> Bool
 p_write_blocks_rt bs = length bs > 20 ||
diff --git a/tests/Tests/Writers/RST.hs b/tests/Tests/Writers/RST.hs
--- a/tests/Tests/Writers/RST.hs
+++ b/tests/Tests/Writers/RST.hs
@@ -47,8 +47,7 @@
               [ "foo"
               , "==="]
           -- note: heading normalization is only done in standalone mode
-          , test (writeRST def{ writerStandalone = True,
-                                writerTemplate = "$body$\n" } . toPandoc)
+          , test (writeRST def{ writerTemplate = Just "$body$\n" } . toPandoc)
             "heading levels" $
               header 1 (text "Header 1") <>
               header 3 (text "Header 2") <>
@@ -78,8 +77,7 @@
               , ""
               , "Header 2"
               , "--------"]
-          , test (writeRST def{ writerStandalone = True,
-                                writerTemplate = "$body$\n" } . toPandoc)
+          , test (writeRST def{ writerTemplate = Just "$body$\n" } . toPandoc)
             "minimal heading levels" $
               header 2 (text "Header 1") <>
               header 3 (text "Header 2") <>
diff --git a/tests/docbook-xref.native b/tests/docbook-xref.native
--- a/tests/docbook-xref.native
+++ b/tests/docbook-xref.native
@@ -2,9 +2,9 @@
 [Header 1 ("ch01",[],[]) [Str "XRef",Space,Str "Samples"]
 ,Para [Str "This",Space,Str "paragraph",Space,Str "demonstrates",Space,Str "several",Space,Str "features",Space,Str "of",SoftBreak,Str "XRef."]
 ,BulletList
- [[Para [Str "A",Space,Str "straight",Space,Str "link",Space,Str "generates",Space,Str "the",SoftBreak,Str "cross-reference",Space,Str "text:",Space,Link ("",[],[]) [Str "The Second Chapter"] ("#ch02",""),Str "."]]
- ,[Para [Str "A",Space,Str "link",Space,Str "to",Space,Str "an",Space,Str "element",Space,Str "with",Space,Str "an",SoftBreak,Str "XRefLabel:",SoftBreak,Link ("",[],[]) [Str "Chapter the Third"] ("#ch03",""),Str "."]]
- ,[Para [Str "A",Space,Str "link",Space,Str "with",Space,Str "an",SoftBreak,Str "EndTerm:",SoftBreak,Link ("",[],[]) [Str "Chapter 4"] ("#ch04",""),Str "."]]
+ [[Para [Str "A",Space,Str "straight",Space,Str "link",Space,Str "generates",Space,Str "the",SoftBreak,Str "cross-reference",Space,Str "text:",Space,Link ("",[],[]) [Str "The",Space,Str "Second",Space,Str "Chapter"] ("#ch02",""),Str "."]]
+ ,[Para [Str "A",Space,Str "link",Space,Str "to",Space,Str "an",Space,Str "element",Space,Str "with",Space,Str "an",SoftBreak,Str "XRefLabel:",SoftBreak,Link ("",[],[]) [Str "Chapter",Space,Str "the",Space,Str "Third"] ("#ch03",""),Str "."]]
+ ,[Para [Str "A",Space,Str "link",Space,Str "with",Space,Str "an",SoftBreak,Str "EndTerm:",SoftBreak,Link ("",[],[]) [Str "Chapter",Space,Str "4"] ("#ch04",""),Str "."]]
  ,[Para [Str "A",Space,Str "link",Space,Str "to",Space,Str "an",SoftBreak,Str "cmdsynopsis",Space,Str "element:",Space,Link ("",[],[]) [Str "chgrp"] ("#cmd01",""),Str "."]]
  ,[Para [Str "A",Space,Str "link",Space,Str "to",Space,Str "an",SoftBreak,Str "funcsynopsis",Space,Str "element:",Space,Link ("",[],[]) [Str "max"] ("#func01",""),Str "."]]]
 ,Header 1 ("ch02",[],[]) [Str "The",Space,Str "Second",Space,Str "Chapter"]
diff --git a/tests/docx/image.docx b/tests/docx/image.docx
Binary files a/tests/docx/image.docx and b/tests/docx/image.docx differ
diff --git a/tests/docx/image_no_embed.native b/tests/docx/image_no_embed.native
--- a/tests/docx/image_no_embed.native
+++ b/tests/docx/image_no_embed.native
@@ -1,2 +1,2 @@
 [Para [Str "An",Space,Str "image:"]
-,Para [Image ("",[],[("width","6.5in"),("height","5.508333333333334in")]) [] ("media/image1.jpg","")]]
+,Para [Image ("",[],[("width","6.5in"),("height","5.508333333333334in")]) [Str "He",Space,Str "realizes",Space,Str "he's",Space,Str "making",Space,Str "the",Space,Str "file-size",Space,Str "too",Space,Str "big."] ("media/image1.jpg","An unhappy fish.")]]
diff --git a/tests/docx/image_no_embed_writer.native b/tests/docx/image_no_embed_writer.native
--- a/tests/docx/image_no_embed_writer.native
+++ b/tests/docx/image_no_embed_writer.native
@@ -1,2 +1,2 @@
 [Para [Str "An",Space,Str "image:"]
-,Para [Image ("",[],[("width","0.4166666666666667in"),("height","0.4166666666666667in")]) [] ("media/rId25.jpg","")]]
+,Para [Image ("",[],[("width","0.4166666666666667in"),("height","0.4166666666666667in")]) [Str "He",Space,Str "realizes",Space,Str "he's",Space,Str "making",Space,Str "the",Space,Str "file-size",Space,Str "too",Space,Str "big."] ("media/rId25.jpg","An unhappy fish.")]]
diff --git a/tests/docx/inline_images.docx b/tests/docx/inline_images.docx
Binary files a/tests/docx/inline_images.docx and b/tests/docx/inline_images.docx differ
diff --git a/tests/docx/inline_images.native b/tests/docx/inline_images.native
--- a/tests/docx/inline_images.native
+++ b/tests/docx/inline_images.native
@@ -1,2 +1,2 @@
-[Para [Str "This",Space,Str "picture",Space,Image ("",[],[("width","0.8888888888888888in"),("height","0.8888888888888888in")]) [] ("media/image1.jpg",""),Space,Str "is",Space,Str "an",Space,Str "identicon."]
-,Para [Str "Here",Space,Str "is",Space,Link ("",[],[]) [Str "one",Space,Image ("",[],[("width","0.8888888888888888in"),("height","0.8888888888888888in")]) [] ("media/image2.jpg",""),Space,Str "that"] ("http://www.google.com",""),Space,Str "links."]]
+[Para [Str "This",Space,Str "picture",Space,Image ("",[],[("width","0.8888888888888888in"),("height","0.8888888888888888in")]) [Str "This",Space,Str "one",Space,Str "is",Space,Str "green",Space,Str "and",Space,Str "looks",Space,Str "like",Space,Str "Sideshow",Space,Str "Bob."] ("media/image1.jpg","First identicon"),Space,Str "is",Space,Str "an",Space,Str "identicon."]
+,Para [Str "Here",Space,Str "is",Space,Link ("",[],[]) [Str "one",Space,Image ("",[],[("width","0.8888888888888888in"),("height","0.8888888888888888in")]) [Str "This",Space,Str "one",Space,Str "is",Space,Str "reddish,",Space,Str "and",Space,Str "looks",Space,Str "like",Space,Str "a",Space,Str "heart",Space,Str "that",Space,Str "has",Space,Str "leaked",Space,Str "out."] ("media/image2.jpg","Second identicon"),Space,Str "that"] ("http://www.google.com",""),Space,Str "links."]]
diff --git a/tests/epub/features.native b/tests/epub/features.native
--- a/tests/epub/features.native
+++ b/tests/epub/features.native
@@ -75,6 +75,7 @@
  ,Div ("content-mathml-001.xhtml#mathml-027",["section","ctest"],[])
   [Header 2 ("",[],[]) [Span ("",["nature"],[]) [Str "[REQUIRED]"],SoftBreak,Span ("",["test-id"],[]) [Str "mathml-027"],Str "Elementary",Space,Str "math:",Space,Str "long",Space,Str "division",Space,Str "notation"]
   ,Para [Str "Tests",Space,Str "whether",Space,Code ("",[],[]) "mlongdiv",Space,Str "elements",Space,Str "(from",Space,Str "elementary",Space,Str "math)",Space,Str "are",Space,Str "supported."]
+  ,Plain [Span ("",["math"],[("xmlns","http://www.w3.org/1998/Math/MathML")]) [SoftBreak,Str "3",SoftBreak,Str "435.3",SoftBreak,Str "1306",SoftBreak,Str "12",SoftBreak,Str "10",SoftBreak,Str "9",SoftBreak,Str "16",SoftBreak,Str "15",SoftBreak,Str "1.0",SoftBreak,Str "9",SoftBreak,Str "1",SoftBreak]]
   ,Para [Str "The",Space,Str "test",Space,Str "passes",Space,Str "if",Space,Str "the",Space,Str "rendering",Space,Str "looks",Space,Str "like",Space,Str "the",Space,Str "following",Space,Str "image:",Space,Str "."]]]
 ,Para [Span ("content-switch-001.xhtml",[],[]) []]
 ,Div ("content-switch-001.xhtml#epub-switch",["section"],[])
diff --git a/tests/markdown-reader-more.native b/tests/markdown-reader-more.native
--- a/tests/markdown-reader-more.native
+++ b/tests/markdown-reader-more.native
@@ -6,6 +6,8 @@
 ,Plain [RawInline (Format "tex") "\\placeformula "]
 ,RawBlock (Format "context") "\\startformula\n   L_{1} = L_{2}\n   \\stopformula"
 ,RawBlock (Format "context") "\\start[a2]\n\\start[a2]\n\\stop[a2]\n\\stop[a2]"
+,Header 2 ("raw-latex-environments",[],[]) [Str "Raw",Space,Str "LaTeX",Space,Str "environments"]
+,RawBlock (Format "latex") "\\begin{center}\n\\begin{tikzpicture}[baseline={([yshift=+-.5ex]current bounding box.center)}, level distance=24pt]\n\\Tree [.{S} [.NP John\\index{i} ] [.VP [.V likes ] [.NP himself\\index{i,*j} ]]]\n\\end{tikzpicture}\n\\end{center}"
 ,Header 2 ("urls-with-spaces-and-punctuation",[],[]) [Str "URLs",Space,Str "with",Space,Str "spaces",Space,Str "and",Space,Str "punctuation"]
 ,Para [Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("bar%20baz","title")]
 ,Para [Link ("",[],[]) [Str "baz"] ("/foo%20foo",""),Space,Link ("",[],[]) [Str "bam"] ("/foo%20fee",""),Space,Link ("",[],[]) [Str "bork"] ("/foo/zee%20zob","title")]
@@ -105,6 +107,28 @@
   ,[Para [Str "f"]]]]
 ,Para [Str "Headless"]
 ,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.2638888888888889,0.16666666666666666,0.18055555555555555]
+ [[]
+ ,[]
+ ,[]]
+ [[[Para [Str "r1",Space,Str "a",SoftBreak,Str "r1",Space,Str "bis"]]
+  ,[Para [Str "b",SoftBreak,Str "b",Space,Str "2"]]
+  ,[Para [Str "c",SoftBreak,Str "c",Space,Str "2"]]]
+ ,[[Para [Str "r2",Space,Str "d"]]
+  ,[Para [Str "e"]]
+  ,[Para [Str "f"]]]]
+,Para [Str "With",Space,Str "alignments"]
+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.2638888888888889,0.16666666666666666,0.18055555555555555]
+ [[Plain [Str "col",Space,Str "1"]]
+ ,[Plain [Str "col",Space,Str "2"]]
+ ,[Plain [Str "col",Space,Str "3"]]]
+ [[[Para [Str "r1",Space,Str "a",SoftBreak,Str "r1",Space,Str "bis"]]
+  ,[Para [Str "b",SoftBreak,Str "b",Space,Str "2"]]
+  ,[Para [Str "c",SoftBreak,Str "c",Space,Str "2"]]]
+ ,[[Para [Str "r2",Space,Str "d"]]
+  ,[Para [Str "e"]]
+  ,[Para [Str "f"]]]]
+,Para [Str "Headless",Space,Str "with",Space,Str "alignments"]
+,Table [] [AlignRight,AlignLeft,AlignCenter] [0.2638888888888889,0.16666666666666666,0.18055555555555555]
  [[]
  ,[]
  ,[]]
diff --git a/tests/markdown-reader-more.txt b/tests/markdown-reader-more.txt
--- a/tests/markdown-reader-more.txt
+++ b/tests/markdown-reader-more.txt
@@ -28,6 +28,14 @@
 \stop[a2]
 \stop[a2]
 
+## Raw LaTeX environments
+
+\begin{center}
+\begin{tikzpicture}[baseline={([yshift=+-.5ex]current bounding box.center)}, level distance=24pt]
+\Tree [.{S} [.NP John\index{i} ] [.VP [.V likes ] [.NP himself\index{i,*j} ]]]
+\end{tikzpicture}
+\end{center}
+
 ## URLs with spaces and punctuation
 
 [foo](/bar and baz)
@@ -206,6 +214,26 @@
 Headless
 
 +------------------+-----------+------------+
+| r1 a             | b         | c          |
+| r1 bis           | b 2       | c 2        |
++------------------+-----------+------------+
+| r2 d             | e         | f          |
++------------------+-----------+------------+
+
+With alignments
+
++------------------+-----------+------------+
+| col 1            | col 2     | col 3      |
++=================:+:==========+:==========:+
+| r1 a             | b         | c          |
+| r1 bis           | b 2       | c 2        |
++------------------+-----------+------------+
+| r2 d             | e         | f          |
++------------------+-----------+------------+
+
+Headless with alignments
+
++-----------------:+:----------+:----------:+
 | r1 a             | b         | c          |
 | r1 bis           | b 2       | c 2        |
 +------------------+-----------+------------+
diff --git a/tests/odt/native/inlinedCode.native b/tests/odt/native/inlinedCode.native
new file mode 100644
--- /dev/null
+++ b/tests/odt/native/inlinedCode.native
@@ -0,0 +1,1 @@
+[Para [Str "Here",Space,Str "comes",Space,Code ("",[],[]) "inlined code",Space,Str "text",Space,Str "and",Space,Code ("",[],[]) "an another",Space,Str "one."]]
diff --git a/tests/odt/native/simpleTable.native b/tests/odt/native/simpleTable.native
--- a/tests/odt/native/simpleTable.native
+++ b/tests/odt/native/simpleTable.native
@@ -1,1 +1,1 @@
-[Table [] [] [] [] [[[Plain [Str "Content"]],[Plain [Str "More",Space,Str "content"]]]],Para []]
+[Table [] [AlignDefault,AlignDefault] [0.0,0.0] [[],[]] [[[Plain [Str "Content"]],[Plain [Str "More",Space,Str "content"]]]],Para []]
diff --git a/tests/odt/native/simpleTableWithCaption.native b/tests/odt/native/simpleTableWithCaption.native
new file mode 100644
--- /dev/null
+++ b/tests/odt/native/simpleTableWithCaption.native
@@ -0,0 +1,1 @@
+[Table [Str "Table",Space,Str "1:",Space,Str "Some",Space,Str "caption",Space,Str "for",Space,Str "a",Space,Str "table"] [AlignDefault,AlignDefault] [0.0,0.0] [[],[]] [[[Plain [Str "Content"]],[Plain [Str "More",Space,Str "content"]]]],Para []]
diff --git a/tests/odt/odt/inlinedCode.odt b/tests/odt/odt/inlinedCode.odt
new file mode 100644
Binary files /dev/null and b/tests/odt/odt/inlinedCode.odt differ
diff --git a/tests/odt/odt/simpleTableWithCaption.odt b/tests/odt/odt/simpleTableWithCaption.odt
new file mode 100644
Binary files /dev/null and b/tests/odt/odt/simpleTableWithCaption.odt differ
diff --git a/tests/tables.opendocument b/tests/tables.opendocument
--- a/tests/tables.opendocument
+++ b/tests/tables.opendocument
@@ -63,8 +63,7 @@
     </table:table-cell>
   </table:table-row>
 </table:table>
-<text:p text:style-name="TableCaption">Demonstration of simple table
-syntax.</text:p>
+<text:p text:style-name="Table">Demonstration of simple table syntax.</text:p>
 <text:p text:style-name="First_20_paragraph">Simple table without
 caption:</text:p>
 <table:table table:name="Table2" table:style-name="Table2">
@@ -197,8 +196,7 @@
     </table:table-cell>
   </table:table-row>
 </table:table>
-<text:p text:style-name="TableCaption">Demonstration of simple table
-syntax.</text:p>
+<text:p text:style-name="Table">Demonstration of simple table syntax.</text:p>
 <text:p text:style-name="First_20_paragraph">Multiline table with
 caption:</text:p>
 <table:table table:name="Table4" table:style-name="Table4">
@@ -253,8 +251,8 @@
     </table:table-cell>
   </table:table-row>
 </table:table>
-<text:p text:style-name="TableCaption">Here's the caption. It may span
-multiple lines.</text:p>
+<text:p text:style-name="Table">Here's the caption. It may span multiple
+lines.</text:p>
 <text:p text:style-name="First_20_paragraph">Multiline table without
 caption:</text:p>
 <table:table table:name="Table5" table:style-name="Table5">
diff --git a/tests/writer.markdown b/tests/writer.markdown
--- a/tests/writer.markdown
+++ b/tests/writer.markdown
@@ -210,7 +210,6 @@
     -   Fee
     -   Fie
     -   Foe
-
 3.  Third
 
 Same thing but with paragraphs:
diff --git a/tests/writer.opendocument b/tests/writer.opendocument
--- a/tests/writer.opendocument
+++ b/tests/writer.opendocument
@@ -668,47 +668,37 @@
     <style:style style:name="T35" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>
     <style:style style:name="T36" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>
     <style:style style:name="T37" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>
-    <style:style style:name="T38" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
-    <style:style style:name="T39" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
-    <style:style style:name="T40" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
-    <style:style style:name="T41" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
-    <style:style style:name="T42" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
+    <style:style style:name="T38" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
+    <style:style style:name="T39" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
+    <style:style style:name="T40" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
+    <style:style style:name="T41" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
+    <style:style style:name="T42" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-line-through-style="solid" /></style:style>
     <style:style style:name="T43" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T44" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T45" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T46" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T47" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T48" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>
-    <style:style style:name="T49" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
-    <style:style style:name="T50" 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="T51" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
-    <style:style style:name="T52" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
-    <style:style style:name="T53" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
-    <style:style style:name="T54" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
-    <style:style style:name="T55" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
+    <style:style style:name="T44" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
+    <style:style style:name="T45" 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="T46" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
+    <style:style style:name="T47" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
+    <style:style style:name="T48" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
+    <style:style style:name="T49" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
+    <style:style style:name="T50" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T51" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T52" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T53" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T54" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T55" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T56" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T57" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T58" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T58" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
     <style:style style:name="T59" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T60" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T61" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T62" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T63" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T64" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
-    <style:style style:name="T65" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
+    <style:style style:name="T64" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
+    <style:style style:name="T65" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T66" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T67" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
+    <style:style style:name="T67" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
     <style:style style:name="T68" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T69" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T70" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T71" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T72" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T73" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T74" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T75" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></style:style>
-    <style:style style:name="T76" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T77" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
-    <style:style style:name="T78" style:family="text"><style:text-properties style:font-name="Courier New" style:font-name-asian="Courier New" style:font-name-complex="Courier New" /></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>
@@ -1358,22 +1348,22 @@
 <text:p text:style-name="Text_20_body">So is
 <text:span text:style-name="T37">this</text:span> word.</text:p>
 <text:p text:style-name="Text_20_body">This is code:
-<text:span text:style-name="T38">&gt;</text:span>,
-<text:span text:style-name="T39">$</text:span>,
-<text:span text:style-name="T40">\</text:span>,
-<text:span text:style-name="T41">\$</text:span>,
-<text:span text:style-name="T42">&lt;html&gt;</text:span>.</text:p>
-<text:p text:style-name="Text_20_body"><text:span text:style-name="T43">This</text:span><text:span text:style-name="T44">
-</text:span><text:span text:style-name="T45">is</text:span><text:span text:style-name="T46">
-</text:span><text:span text:style-name="T47">strikeout</text:span><text:span text:style-name="T48">.</text:span></text:p>
+<text:span text:style-name="Source_Text">&gt;</text:span>,
+<text:span text:style-name="Source_Text">$</text:span>,
+<text:span text:style-name="Source_Text">\</text:span>,
+<text:span text:style-name="Source_Text">\$</text:span>,
+<text:span text:style-name="Source_Text">&lt;html&gt;</text:span>.</text:p>
+<text:p text:style-name="Text_20_body"><text:span text:style-name="T38">This</text:span><text:span text:style-name="T39">
+</text:span><text:span text:style-name="T40">is</text:span><text:span text:style-name="T41">
+</text:span><text:span text:style-name="T42">strikeout</text:span><text:span text:style-name="T43">.</text:span></text:p>
 <text:p text:style-name="Text_20_body">Superscripts:
-a<text:span text:style-name="T49">bc</text:span>d
-a<text:span text:style-name="T50">hello</text:span>
-a<text:span text:style-name="T51">hello there</text:span>.</text:p>
+a<text:span text:style-name="T44">bc</text:span>d
+a<text:span text:style-name="T45">hello</text:span>
+a<text:span text:style-name="T46">hello there</text:span>.</text:p>
 <text:p text:style-name="Text_20_body">Subscripts:
-H<text:span text:style-name="T52">2</text:span>O,
-H<text:span text:style-name="T53">23</text:span>O,
-H<text:span text:style-name="T54">many of them</text:span>O.</text:p>
+H<text:span text:style-name="T47">2</text:span>O,
+H<text:span text:style-name="T48">23</text:span>O,
+H<text:span text:style-name="T49">many of them</text:span>O.</text:p>
 <text:p text:style-name="Text_20_body">These should not be superscripts or
 subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</text:p>
 <text:p text:style-name="Horizontal_20_Line" />
@@ -1387,7 +1377,7 @@
 <text:p text:style-name="Text_20_body">‘He said, “I want to go.”’ Were you
 alive in the 70’s?</text:p>
 <text:p text:style-name="Text_20_body">Here is some quoted
-‘<text:span text:style-name="T55">code</text:span>’ and a
+‘<text:span text:style-name="Source_Text">code</text:span>’ and a
 “<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">quoted
 link</text:span></text:a>”.</text:p>
 <text:p text:style-name="Text_20_body">Some dashes: one—two — three—four —
@@ -1405,16 +1395,16 @@
     <text:p text:style-name="P51">2 + 2 = 4</text:p>
   </text:list-item>
   <text:list-item>
-    <text:p text:style-name="P51"><text:span text:style-name="T56">x</text:span> ∈ <text:span text:style-name="T57">y</text:span></text:p>
+    <text:p text:style-name="P51"><text:span text:style-name="T50">x</text:span> ∈ <text:span text:style-name="T51">y</text:span></text:p>
   </text:list-item>
   <text:list-item>
-    <text:p text:style-name="P51"><text:span text:style-name="T58">α</text:span> ∧ <text:span text:style-name="T59">ω</text:span></text:p>
+    <text:p text:style-name="P51"><text:span text:style-name="T52">α</text:span> ∧ <text:span text:style-name="T53">ω</text:span></text:p>
   </text:list-item>
   <text:list-item>
     <text:p text:style-name="P51">223</text:p>
   </text:list-item>
   <text:list-item>
-    <text:p text:style-name="P51"><text:span text:style-name="T60">p</text:span>-Tree</text:p>
+    <text:p text:style-name="P51"><text:span text:style-name="T54">p</text:span>-Tree</text:p>
   </text:list-item>
   <text:list-item>
     <text:p text:style-name="P51">Here’s some display math:
@@ -1422,18 +1412,18 @@
   </text:list-item>
   <text:list-item>
     <text:p text:style-name="P51">Here’s one that has a line break in it:
-    <text:span text:style-name="T61">α</text:span> + <text:span text:style-name="T62">ω</text:span> × <text:span text:style-name="T63">x</text:span><text:span text:style-name="T64">2</text:span>.</text:p>
+    <text:span text:style-name="T55">α</text:span> + <text:span text:style-name="T56">ω</text:span> × <text:span text:style-name="T57">x</text:span><text:span text:style-name="T58">2</text:span>.</text:p>
   </text:list-item>
 </text:list>
 <text:p text:style-name="First_20_paragraph">These shouldn’t be math:</text:p>
 <text:list text:style-name="L27">
   <text:list-item>
     <text:p text:style-name="P52">To get the famous equation, write
-    <text:span text:style-name="T65">$e = mc^2$</text:span>.</text:p>
+    <text:span text:style-name="Source_Text">$e = mc^2$</text:span>.</text:p>
   </text:list-item>
   <text:list-item>
     <text:p text:style-name="P52">$22,000 is a
-    <text:span text:style-name="T66">lot</text:span> of money. So is $34,000.
+    <text:span text:style-name="T59">lot</text:span> of money. So is $34,000.
     (It worked if “lot” is emphasized.)</text:p>
   </text:list-item>
   <text:list-item>
@@ -1441,11 +1431,11 @@
   </text:list-item>
   <text:list-item>
     <text:p text:style-name="P52">Escaped
-    <text:span text:style-name="T67">$</text:span>: $73
-    <text:span text:style-name="T68">this</text:span><text:span text:style-name="T69">
-    </text:span><text:span text:style-name="T70">should</text:span><text:span text:style-name="T71">
-    </text:span><text:span text:style-name="T72">be</text:span><text:span text:style-name="T73">
-    </text:span><text:span text:style-name="T74">emphasized</text:span>
+    <text:span text:style-name="Source_Text">$</text:span>: $73
+    <text:span text:style-name="T60">this</text:span><text:span text:style-name="T61">
+    </text:span><text:span text:style-name="T62">should</text:span><text:span text:style-name="T63">
+    </text:span><text:span text:style-name="T64">be</text:span><text:span text:style-name="T65">
+    </text:span><text:span text:style-name="T66">emphasized</text:span>
     23$.</text:p>
   </text:list-item>
 </text:list>
@@ -1570,7 +1560,7 @@
 <text:p text:style-name="P56">Blockquoted:
 <text:a xlink:type="simple" xlink:href="http://example.com/" office:name=""><text:span text:style-name="Definition">http://example.com/</text:span></text:a></text:p>
 <text:p text:style-name="First_20_paragraph">Auto-links should not occur here:
-<text:span text:style-name="T75">&lt;http://example.com/&gt;</text:span></text:p>
+<text:span text:style-name="Source_Text">&lt;http://example.com/&gt;</text:span></text:p>
 <text:p text:style-name="P57">or here: &lt;http://example.com/&gt;</text:p>
 <text:p text:style-name="Horizontal_20_Line" />
 <text:h text:style-name="Heading_20_1" text:outline-level="1">Images</text:h>
@@ -1595,14 +1585,15 @@
 items).</text:p><text:p text:style-name="P58"><text:s text:c="2" />{ &lt;code&gt; }</text:p><text:p text:style-name="Footnote">If
 you want, you can indent every line, but you can also be lazy and just indent
 the first line of each block.</text:p></text:note-body></text:note> This
-should <text:span text:style-name="T76">not</text:span> be a footnote
+should <text:span text:style-name="T67">not</text:span> be a footnote
 reference, because it contains a space.[^my note] Here is an inline
 note.<text:note text:id="ftn2" text:note-class="footnote"><text:note-citation>3</text:note-citation><text:note-body><text:p text:style-name="Footnote">This
-is <text:span text:style-name="T77">easier</text:span> to type. Inline notes
+is <text:span text:style-name="T68">easier</text:span> to type. Inline notes
 may contain
 <text:a xlink:type="simple" xlink:href="http://google.com" office:name=""><text:span text:style-name="Definition">links</text:span></text:a>
-and <text:span text:style-name="T78">]</text:span> verbatim characters, as
-well as [bracketed text].</text:p></text:note-body></text:note></text:p>
+and <text:span text:style-name="Source_Text">]</text:span> verbatim
+characters, as well as [bracketed
+text].</text:p></text:note-body></text:note></text:p>
 <text:p text:style-name="P59">Notes can go in
 quotes.<text:note text:id="ftn3" text:note-class="footnote"><text:note-citation>4</text:note-citation><text:note-body><text:p text:style-name="Footnote">In
 quote.</text:p></text:note-body></text:note></text:p>
diff --git a/tests/writer.opml b/tests/writer.opml
--- a/tests/writer.opml
+++ b/tests/writer.opml
@@ -35,7 +35,7 @@
   </outline>
   <outline text="Ordered" _note="Tight:&#10;&#10;1.  First&#10;2.  Second&#10;3.  Third&#10;&#10;and:&#10;&#10;1.  One&#10;2.  Two&#10;3.  Three&#10;&#10;Loose using tabs:&#10;&#10;1.  First&#10;&#10;2.  Second&#10;&#10;3.  Third&#10;&#10;and using spaces:&#10;&#10;1.  One&#10;&#10;2.  Two&#10;&#10;3.  Three&#10;&#10;Multiple paragraphs:&#10;&#10;1.  Item 1, graf one.&#10;&#10;    Item 1. graf two. The quick brown fox jumped over the lazy&#10;    dog’s back.&#10;&#10;2.  Item 2.&#10;&#10;3.  Item 3.&#10;&#10;">
   </outline>
-  <outline text="Nested" _note="-   Tab&#10;    -   Tab&#10;        -   Tab&#10;&#10;Here’s another:&#10;&#10;1.  First&#10;2.  Second:&#10;    -   Fee&#10;    -   Fie&#10;    -   Foe&#10;&#10;3.  Third&#10;&#10;Same thing but with paragraphs:&#10;&#10;1.  First&#10;&#10;2.  Second:&#10;&#10;    -   Fee&#10;    -   Fie&#10;    -   Foe&#10;&#10;3.  Third&#10;&#10;">
+  <outline text="Nested" _note="-   Tab&#10;    -   Tab&#10;        -   Tab&#10;&#10;Here’s another:&#10;&#10;1.  First&#10;2.  Second:&#10;    -   Fee&#10;    -   Fie&#10;    -   Foe&#10;3.  Third&#10;&#10;Same thing but with paragraphs:&#10;&#10;1.  First&#10;&#10;2.  Second:&#10;&#10;    -   Fee&#10;    -   Fie&#10;    -   Foe&#10;&#10;3.  Third&#10;&#10;">
   </outline>
   <outline text="Tabs and spaces" _note="-   this is a list item indented with tabs&#10;&#10;-   this is a list item indented with spaces&#10;&#10;    -   this is an example list item indented with tabs&#10;&#10;    -   this is an example list item indented with spaces&#10;&#10;">
   </outline>
diff --git a/tests/writer.plain b/tests/writer.plain
--- a/tests/writer.plain
+++ b/tests/writer.plain
@@ -215,7 +215,6 @@
     -   Fee
     -   Fie
     -   Foe
-
 3.  Third
 
 Same thing but with paragraphs:
