summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT8
-rw-r--r--INSTALL45
-rw-r--r--MakeManPage.hs10
-rw-r--r--README812
-rw-r--r--Setup.hs53
-rw-r--r--changelog567
-rw-r--r--default.csl747
-rw-r--r--dzslides/template.html514
-rw-r--r--epub.css20
-rw-r--r--man/man1/markdown2pdf.1170
-rw-r--r--man/man1/markdown2pdf.1.md120
-rw-r--r--man/man1/pandoc.1827
-rw-r--r--man/man5/pandoc_markdown.5120
-rw-r--r--pandoc.cabal256
-rw-r--r--reference.docxbin0 -> 8299 bytes
-rw-r--r--s5/default/blank.gifbin0 -> 49 bytes
-rw-r--r--s5/default/bodybg.gifbin0 -> 10119 bytes
-rw-r--r--s5/default/iepngfix.htc42
-rw-r--r--s5/default/slides.css3
-rw-r--r--s5/default/slides.js553
-rw-r--r--s5/default/slides.min.js1
-rw-r--r--slidy/graphics/fold-dim.gifbin0 -> 56 bytes
-rw-r--r--slidy/graphics/fold.gifbin0 -> 56 bytes
-rw-r--r--slidy/graphics/nofold-dim.gifbin0 -> 48 bytes
-rw-r--r--slidy/graphics/unfold-dim.gifbin0 -> 59 bytes
-rw-r--r--slidy/graphics/unfold.gifbin0 -> 59 bytes
-rw-r--r--slidy/scripts/slidy.js.gzbin0 -> 12801 bytes
-rw-r--r--slidy/slidy.min.js1
-rw-r--r--slidy/styles/slidy.css (renamed from slidy/slidy.css)4
-rw-r--r--src/Tests/Arbitrary.hs10
-rw-r--r--src/Tests/Helpers.hs12
-rw-r--r--src/Tests/Old.hs8
-rw-r--r--src/Tests/Readers/LaTeX.hs80
-rw-r--r--src/Tests/Readers/Markdown.hs43
-rw-r--r--src/Tests/Readers/RST.hs14
-rw-r--r--src/Tests/Writers/ConTeXt.hs6
-rw-r--r--src/Tests/Writers/HTML.hs4
-rw-r--r--src/Tests/Writers/Markdown.hs4
-rw-r--r--src/Text/Pandoc.hs61
-rw-r--r--src/Text/Pandoc/Biblio.hs75
-rw-r--r--src/Text/Pandoc/CharacterReferences.hs72
-rw-r--r--src/Text/Pandoc/Highlighting.hs78
-rw-r--r--src/Text/Pandoc/ImageSize.hs151
-rw-r--r--src/Text/Pandoc/MIME.hs3
-rw-r--r--src/Text/Pandoc/PDF.hs136
-rw-r--r--src/Text/Pandoc/Parsing.hs138
-rw-r--r--src/Text/Pandoc/Pretty.hs135
-rw-r--r--src/Text/Pandoc/Readers/HTML.hs38
-rw-r--r--src/Text/Pandoc/Readers/LaTeX.hs1790
-rw-r--r--src/Text/Pandoc/Readers/Markdown.hs219
-rw-r--r--src/Text/Pandoc/Readers/RST.hs53
-rw-r--r--src/Text/Pandoc/Readers/TeXMath.hs19
-rw-r--r--src/Text/Pandoc/Readers/Textile.hs5
-rw-r--r--src/Text/Pandoc/S5.hs69
-rw-r--r--src/Text/Pandoc/SelfContained.hs162
-rw-r--r--src/Text/Pandoc/Shared.hs105
-rw-r--r--src/Text/Pandoc/Slides.hs57
-rw-r--r--src/Text/Pandoc/Templates.hs6
-rw-r--r--src/Text/Pandoc/Writers/AsciiDoc.hs367
-rw-r--r--src/Text/Pandoc/Writers/ConTeXt.hs110
-rw-r--r--src/Text/Pandoc/Writers/Docbook.hs59
-rw-r--r--src/Text/Pandoc/Writers/Docx.hs666
-rw-r--r--src/Text/Pandoc/Writers/EPUB.hs177
-rw-r--r--src/Text/Pandoc/Writers/HTML.hs549
-rw-r--r--src/Text/Pandoc/Writers/LaTeX.hs424
-rw-r--r--src/Text/Pandoc/Writers/Man.hs12
-rw-r--r--src/Text/Pandoc/Writers/Markdown.hs33
-rw-r--r--src/Text/Pandoc/Writers/MediaWiki.hs12
-rw-r--r--src/Text/Pandoc/Writers/ODT.hs12
-rw-r--r--src/Text/Pandoc/Writers/OpenDocument.hs25
-rw-r--r--src/Text/Pandoc/Writers/Org.hs14
-rw-r--r--src/Text/Pandoc/Writers/RST.hs23
-rw-r--r--src/Text/Pandoc/Writers/RTF.hs14
-rw-r--r--src/Text/Pandoc/Writers/Texinfo.hs8
-rw-r--r--src/Text/Pandoc/Writers/Textile.hs30
-rw-r--r--src/Text/Pandoc/XML.hs25
-rw-r--r--src/markdown2pdf.hs256
-rw-r--r--src/pandoc.hs738
-rw-r--r--templates/default.asciidoc26
-rw-r--r--templates/default.beamer141
-rw-r--r--templates/default.context65
-rw-r--r--templates/default.docbook5
-rw-r--r--templates/default.dzslides115
-rw-r--r--templates/default.html46
-rw-r--r--templates/default.html556
-rw-r--r--templates/default.latex23
-rw-r--r--templates/default.opendocument2
-rw-r--r--templates/default.rst2
-rw-r--r--templates/default.s519
-rw-r--r--templates/default.slidy29
-rw-r--r--templates/epub-coverimage.html14
-rw-r--r--templates/epub-page.html18
-rw-r--r--templates/epub-titlepage.html22
-rw-r--r--tests/biblio.bib2
-rw-r--r--tests/chicago-author-date.csl747
-rw-r--r--tests/html-reader.html1
-rw-r--r--tests/ieee.csl423
-rw-r--r--tests/latex-reader.native75
-rw-r--r--tests/lhs-test.html42
-rw-r--r--tests/lhs-test.html+lhs42
-rw-r--r--tests/lhs-test.latex42
-rw-r--r--tests/lhs-test.latex+lhs10
-rw-r--r--tests/lhs-test.markdown3
-rw-r--r--tests/lhs-test.nohl.html23
-rw-r--r--tests/lhs-test.nohl.html+lhs23
-rw-r--r--tests/markdown-citations.chicago-author-date.txt16
-rw-r--r--tests/markdown-citations.ieee.txt24
-rw-r--r--tests/markdown-citations.mhra.txt30
-rw-r--r--tests/markdown-citations.txt14
-rw-r--r--tests/markdown-reader-more.native20
-rw-r--r--tests/markdown-reader-more.txt10
-rw-r--r--tests/mhra.csl767
-rw-r--r--tests/rst-reader.native33
-rw-r--r--tests/rst-reader.rst29
-rw-r--r--tests/s5.basic.html23
-rw-r--r--tests/s5.fancy.html23
-rw-r--r--tests/s5.inserts.html9
-rw-r--r--tests/tables.asciidoc71
-rw-r--r--tests/testsuite.native40
-rw-r--r--tests/testsuite.txt4
-rw-r--r--tests/textile-reader.native16
-rw-r--r--tests/writer.asciidoc656
-rw-r--r--tests/writer.context274
-rw-r--r--tests/writer.docbook162
-rw-r--r--tests/writer.html58
-rw-r--r--tests/writer.latex10
-rw-r--r--tests/writer.man5
-rw-r--r--tests/writer.markdown81
-rw-r--r--tests/writer.mediawiki52
-rw-r--r--tests/writer.native40
-rw-r--r--tests/writer.opendocument104
-rw-r--r--tests/writer.rst18
-rw-r--r--tests/writer.rtf4
133 files changed, 10972 insertions, 5617 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index 050eb07c0..51c7fb82a 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,5 +1,5 @@
Pandoc
-Copyright (C) 2006-2010 John MacFarlane <jgm at berkeley dot edu>
+Copyright (C) 2006-2012 John MacFarlane <jgm at berkeley dot edu>
This code is released under the [GPL], version 2 or later:
@@ -92,3 +92,9 @@ http://legroom.net/software
Released under the GPL.
+------------------------------------------------------------------------
+The dzslides template contains javascript and CSS from Paul Rouget's
+dzslides template.
+http://github.com/apulrouget/dzslides
+
+Released under the Do What the Fuck You Want To Public License.
diff --git a/INSTALL b/INSTALL
index ea47c94e6..7a63989c5 100644
--- a/INSTALL
+++ b/INSTALL
@@ -15,11 +15,6 @@ the [cabal-install] build tool.
cabal install pandoc
- If you want support for source code syntax highlighting, set
- the `highlighting` flag:
-
- cabal install -fhighlighting pandoc
-
This procedure will install the released version of pandoc,
which will be downloaded automatically from HackageDB.
If you want to install a modified or development version
@@ -51,8 +46,7 @@ quick install, but this information may be of use to packagers.
For more details, see the [Cabal User's Guide].
1. Install dependencies: in addition to the [Haskell platform],
-you will need [zip-archive] and (if you want syntax highlighting)
-[highlighting-kate].
+you will need [zip-archive], [blaze-html], and [highlighting-kate].
2. Configure:
@@ -70,13 +64,10 @@ you will need [zip-archive] and (if you want syntax highlighting)
- `executable`: build the pandoc executable (default yes)
- `library`: build the pandoc library (default yes)
- - `wrappers`: build the wrapper `markdown2pdf` (default yes)
- - `highlighting`: compile with syntax highlighting support (increases
- the size of the executable) (default no)
So, for example,
- --flags="-executable -wrappers highlighting"
+ --flags="-executable"
tells Cabal to build the library but not the executables,
and to compile with syntax highlighting support.
@@ -103,7 +94,39 @@ you will need [zip-archive] and (if you want syntax highlighting)
generate a script that can be run to register the package at
install time.
+Creating a relocatable Windows binary
+-------------------------------------
+
+On Windows it is possible to compile pandoc such that it
+(and its data files) are "relocatable." You can put the relocatable
+binary in any directory (even on a USB drive), and it will look for its
+data files there.
+
+ cabal install --flags="embed_data_files" citeproc-hs
+ cabal install --flags="executable -library" --datasubdir=
+
+You can find `pandoc.exe` in `dist/build/pandoc`. Copy this wherever
+you please, and copy the following data files to the same place:
+
+ README
+ COPYRIGHT
+ COPYING
+ reference.odt
+ reference.docx
+ epub.css
+ default.csl
+ templates/
+ data/
+ s5/
+ slidy/
+ dzslides/
+ pcre-license.txt
+ pcre3.dll
+
+This is essentially what the binary installer does.
+
[zip-archive]: http://hackage.haskell.org/package/zip-archive
[highlighting-kate]: http://hackage.haskell.org/package/highlighting-kate
+[blaze-html]: http://hackage.haskell.org/package/blaze-html
[Cabal User's Guide]: http://www.haskell.org/cabal/release/latest/doc/users-guide/builders.html#setup-configure-paths
diff --git a/MakeManPage.hs b/MakeManPage.hs
index 06a31934c..ca9307c3e 100644
--- a/MakeManPage.hs
+++ b/MakeManPage.hs
@@ -24,16 +24,6 @@ main = do
meta manBlocks
makeManPage verbose ("man" </> "man5" </> "pandoc_markdown.5")
meta syntaxBlocks
- let markdown2pdfpage = "man" </> "man1" </> "markdown2pdf.1"
- modDeps <- modifiedDependencies markdown2pdfpage [markdown2pdfpage <.> "md"]
- unless (null modDeps) $ do
- mpdfContents <- liftM toString $ B.readFile $ markdown2pdfpage <.> "md"
- templ <- liftM toString $ B.readFile $ "templates" </> "default.man"
- let doc = readMarkdown defaultParserState{ stateStandalone = True }
- mpdfContents
- writeManPage markdown2pdfpage templ doc
- when verbose $
- putStrLn $ "Created " ++ markdown2pdfpage
makeManPage :: Bool -> FilePath -> Meta -> [Block] -> IO ()
makeManPage verbose page meta blocks = do
diff --git a/README b/README
index ed7e6ad8f..fb1d0a488 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
% Pandoc User's Guide
% John MacFarlane
-% July 30, 2011
+% January 27, 2012
Synopsis
========
@@ -14,9 +14,11 @@ Pandoc is a [Haskell] library for converting from one markup format to
another, and a command-line tool that uses this library. It can read
[markdown] and (subsets of) [Textile], [reStructuredText], [HTML],
and [LaTeX]; and it can write plain text, [markdown], [reStructuredText],
-[HTML], [LaTeX], [ConTeXt], [RTF], [DocBook XML], [OpenDocument XML], [ODT],
-[GNU Texinfo], [MediaWiki markup], [EPUB], [Textile], [groff man] pages,
-[Emacs Org-Mode], and [Slidy] or [S5] HTML slide shows.
+[XHTML], [HTML 5], [LaTeX] (including [beamer] slide shows),
+[ConTeXt], [RTF], [DocBook XML], [OpenDocument XML], [ODT], [Word docx], [GNU
+Texinfo], [MediaWiki markup], [EPUB], [Textile], [groff man] pages, [Emacs
+Org-Mode], [AsciiDoc], and [Slidy], [DZSlides], or [S5] HTML slide shows. It
+can also produce [PDF] output on systems where LaTeX is installed.
Pandoc's enhanced version of markdown includes syntax for footnotes,
tables, flexible ordered lists, definition lists, delimited code blocks,
@@ -33,14 +35,15 @@ representation of the document, and a set of writers, which convert
this native representation into a target format. Thus, adding an input
or output format requires only adding a reader or writer.
-Using Pandoc
-------------
+Using `pandoc`
+--------------
If no *input-file* is specified, input is read from *stdin*.
Otherwise, the *input-files* are concatenated (with a blank
line between each) and used as input. Output goes to *stdout* by
-default (though output to *stdout* is disabled for the `odt` and
-`epub` output formats). For output to a file, use the `-o` option:
+default (though output to *stdout* is disabled for the `odt`, `docx`,
+and `epub` output formats). For output to a file, use the
+`-o` option:
pandoc -o output.html input.txt
@@ -88,37 +91,25 @@ should pipe input and output through `iconv`:
iconv -t utf-8 input.txt | pandoc | iconv -f utf-8
-Wrappers
-========
-
-`markdown2pdf`
+Creating a PDF
--------------
-The standard Pandoc installation includes `markdown2pdf`, a wrapper
-around `pandoc` and `pdflatex` that produces PDFs directly from markdown
-sources. The default behavior of `markdown2pdf` is to create a file with
-the same base name as the first argument and the extension `pdf`; thus,
-for example,
-
- markdown2pdf sample.txt endnotes.txt
-
-will produce `sample.pdf`. (If `sample.pdf` exists already,
-it will be backed up before being overwritten.) An output file
-name can be specified explicitly using the `-o` option:
+Earlier versions of pandoc came with a program, `markdown2pdf`, that
+used pandoc and pdflatex to produce a PDF. This is no longer needed,
+since `pandoc` can now produce `pdf` output itself. To produce a PDF, simply
+specify an output file with a `.pdf` extension. Pandoc will create a latex
+file and use pdflatex (or another engine, see `--latex-engine`) to convert it
+to PDF:
- markdown2pdf -o book.pdf chap1 chap2
+ pandoc test.txt -o test.pdf
-If no input file is specified, input will be taken from *stdin*.
-All of `pandoc`'s options will work with `markdown2pdf` as well.
-
-`markdown2pdf` assumes that `pdflatex` is in the path. It also
-assumes that the following LaTeX packages are available:
-`unicode`, `fancyhdr` (if you have verbatim text in footnotes),
-`graphicx` (if you use images), `array` (if you use tables),
-and `ulem` (if you use strikeout text). If they are not already
-included in your LaTeX distribution, you can get them from
-[CTAN]. A full [TeX Live] or [MacTeX] distribution will have all of
-these packages.
+Production of a PDF requires that a LaTeX engine be installed (see
+`--latex-engine`, below), and assumes that the following LaTeX packages are
+available: `amssymb`, `amsmath`, `ifxetex`, `ifluatex`, `listings` (if the
+`--listings` option is used), `fancyvrb`, `enumerate`, `ctable`, `url`,
+`graphicx`, `hyperref`, `ulem`, `babel` (if the `lang` variable is set),
+`fontspec` (if `xelatex` or `lualatex` is used as the LaTeX engine), `xltxtra`
+and `xunicode` (if `xelatex` is used).
`hsmarkdown`
------------
@@ -139,6 +130,9 @@ problems with its simulation of symbolic links.
Options
=======
+General options
+---------------
+
`-f` *FORMAT*, `-r` *FORMAT*, `--from=`*FORMAT*, `--read=`*FORMAT*
: Specify input format. *FORMAT* can be `native` (native Haskell),
`json` (JSON version of native AST), `markdown` (markdown),
@@ -151,34 +145,49 @@ Options
`-t` *FORMAT*, `-w` *FORMAT*, `--to=`*FORMAT*, `--write=`*FORMAT*
: Specify output format. *FORMAT* can be `native` (native Haskell),
`json` (JSON version of native AST), `plain` (plain text),
- `markdown` (markdown), `rst` (reStructuredText),
- `html` (HTML), `latex` (LaTeX), `context` (ConTeXt), `man` (groff man),
- `mediawiki` (MediaWiki markup), `textile` (Textile), `org` (Emacs
- Org-Mode), `texinfo` (GNU Texinfo), `docbook` (DocBook XML),
- `opendocument` (OpenDocument XML), `odt` (OpenOffice text document),
- `epub` (EPUB book), `slidy` (Slidy HTML and javascript slide show),
- `s5` (S5 HTML and javascript slide show), or `rtf` (rich text
- format). Note that `odt` and `epub` output will not be directed to
- *stdout*; an output filename must be specified using the `-o/--output`
- option. If `+lhs` is appended to `markdown`, `rst`, `latex`, or `html`,
- the output will be rendered as literate Haskell source:
- see [Literate Haskell support](#literate-haskell-support),
- below.
-
-`-s`, `--standalone`
-: Produce output with an appropriate header and footer (e.g. a
- standalone HTML, LaTeX, or RTF file, not a fragment).
+ `markdown` (markdown), `rst` (reStructuredText), `html` (XHTML 1),
+ `html5` (HTML 5), `latex` (LaTeX), `beamer` (LaTeX beamer slide show),
+ `context` (ConTeXt), `man` (groff man), `mediawiki` (MediaWiki markup),
+ `textile` (Textile), `org` (Emacs Org-Mode), `texinfo` (GNU Texinfo),
+ `docbook` (DocBook XML), `opendocument` (OpenDocument XML), `odt`
+ (OpenOffice text document), `docx` (Word docx), `epub` (EPUB book),
+ `asciidoc` (AsciiDoc), `slidy` (Slidy HTML and javascript slide show),
+ `dzslides` (HTML5 + javascript slide show), `s5` (S5 HTML and javascript
+ slide show), or `rtf` (rich text format). Note that `odt` and `epub`
+ output will not be directed to *stdout*; an output filename must
+ be specified using the `-o/--output` option. If `+lhs` is appended
+ to `markdown`, `rst`, `latex`, `html`, or `html5`, the output will
+ be rendered as literate Haskell source: see [Literate Haskell
+ support](#literate-haskell-support), below.
`-o` *FILE*, `--output=`*FILE*
: Write output to *FILE* instead of *stdout*. If *FILE* is
`-`, output will go to *stdout*. (Exception: if the output
- format is `odt` or `epub`, output to stdout is disabled.)
+ format is `odt`, `docx`, or `epub`, output to stdout is disabled.)
-`-p`, `--preserve-tabs`
-: Preserve tabs instead of converting them to spaces (the default).
+`--data-dir=`*DIRECTORY*
+: Specify the user data directory to search for pandoc data files.
+ If this option is not specified, the default user data directory
+ will be used:
-`--tab-stop=`*NUMBER*
-: Specify the number of spaces per tab (default is 4).
+ $HOME/.pandoc
+
+ in unix and
+
+ C:\Documents And Settings\USERNAME\Application Data\pandoc
+
+ in Windows. A `reference.odt`, `reference.docx`, `default.csl`,
+ `epub.css`, `templates`, `slidy`, or `s5` directory placed in this
+ directory will override pandoc's normal defaults.
+
+`-v`, `--version`
+: Print version.
+
+`-h`, `--help`
+: Show usage message.
+
+Reader options
+--------------
`--strict`
: Use strict markdown syntax, with no pandoc extensions or variants.
@@ -186,142 +195,55 @@ Options
equivalents in standard markdown (e.g. definition lists or strikeout
text) will be parsed as raw HTML.
-`--normalize`
-: Normalize the document after reading: merge adjacent
- `Str` or `Emph` elements, for example, and remove repeated `Space`s.
-
-`--reference-links`
-: Use reference-style links, rather than inline links, in writing markdown
- or reStructuredText. By default inline links are used.
-
`-R`, `--parse-raw`
: Parse untranslatable HTML codes and LaTeX environments as raw HTML
or LaTeX, instead of ignoring them. Affects only HTML and LaTeX
input. Raw HTML can be printed in markdown, reStructuredText, HTML, Slidy,
- and S5 output; raw LaTeX can be printed in markdown, reStructuredText,
- LaTeX, and ConTeXt output. The default is for the readers to omit
- untranslatable HTML codes and LaTeX environments. (The LaTeX reader
- does pass through untranslatable LaTeX *commands*, even if `-R` is not
- specified.)
+ DZSlides, and S5 output; raw LaTeX can be printed in markdown,
+ reStructuredText, LaTeX, and ConTeXt output. The default is for the
+ readers to omit untranslatable HTML codes and LaTeX environments.
+ (The LaTeX reader does pass through untranslatable LaTeX *commands*,
+ even if `-R` is not specified.)
`-S`, `--smart`
: Produce typographically correct output, converting straight quotes
- to curly quotes, `---` and `--` to dashes, ande `...` to ellipses.
- Nonbreaking spaces are inserted after certain abbreviations, such
- as "Mr." (Note: This option is significant only when the input format is
- `markdown` or `textile`. It is selected automatically when the input
- format is `textile` or the output format is `latex` or `context`.)
-
-`-5`, `--html5`
-: Produce HTML5 instead of HTML4. This option has no effect for writers
- other than `html`.
-
-`-m` [*URL*], `--latexmathml`[=*URL*]
-: Use the [LaTeXMathML] script to display embedded TeX math in HTML output.
- To insert a link to a local copy of the `LaTeXMathML.js` script,
- provide a *URL*. If no *URL* is provided, the contents of the
- script will be inserted directly into the HTML header, preserving
- portability at the price of efficiency. If you plan to use math on
- several pages, it is much better to link to a copy of the script,
- so it can be cached.
-
-`--mathml`[=*URL*]
-: Convert TeX math to MathML. In standalone mode, a small javascript
- (or a link to such a script if a *URL* is supplied) will be inserted that
- allows the MathML to be viewed on some browsers.
-
-`--jsmath`[=*URL*]
-: Use [jsMath] to display embedded TeX math in HTML output.
- The *URL* should point to the jsMath load script (e.g.
- `jsMath/easy/load.js`); if provided, it will be linked to in
- the header of standalone HTML documents. If a *URL* is not provided,
- no link to the jsMath load script will be inserted; it is then
- up to the author to provide such a link in the HTML template.
-
-`--mathjax`[=*URL*]
-: Use [MathJax] to display embedded TeX math in HTML output.
- The *URL* should point to the `MathJax.js` load script.
- If a *URL* is not provided, a link to the MathJax CDN will
- be inserted.
-
-`--gladtex`
-: Enclose TeX math in `<eq>` tags in HTML output. These can then
- be processed by [gladTeX] to produce links to images of the typeset
- formulas.
-
-`--mimetex`[=*URL*]
-: Render TeX math using the [mimeTeX] CGI script. If *URL* is not
- specified, it is assumed that the script is at `/cgi-bin/mimetex.cgi`.
-
-`--webtex`[=*URL*]
-: Render TeX formulas using an external script that converts TeX
- formulas to images. The formula will be concatenated with the URL
- provided. If *URL* is not specified, the Google Chart API will be used.
-
-`-i`, `--incremental`
-: Make list items in Slidy or S5 display incrementally (one by one).
- The default is for lists to be displayed all at once.
-
-`--offline`
-: Include all the CSS and javascript needed for a Slidy or S5 slide
- show in the output, so that the slide show will work even when no
- internet connection is available.
-
-`--chapters`
-: Treat top-level headers as chapters in LaTeX, ConTeXt, and DocBook
- output.
-
-`-N`, `--number-sections`
-: Number section headings in LaTeX, ConTeXt, or HTML output.
- By default, sections are not numbered.
+ to curly quotes, `---` to em-dashes, `--` to en-dashes, and
+ `...` to ellipses. Nonbreaking spaces are inserted after certain
+ abbreviations, such as "Mr." (Note: This option is significant only when
+ the input format is `markdown` or `textile`. It is selected automatically
+ when the input format is `textile` or the output format is `latex` or
+ `context`.)
+
+`--old-dashes`
+: Selects the pandoc <= 1.8.2.1 behavior for parsing smart dashes: `-` before
+ a numeral is an en-dash, and `--` is an em-dash. This option is selected
+ automatically for `textile` input.
-`--listings`
-: Use listings package for LaTeX code blocks
-
-`--section-divs`
-: Wrap sections in `<div>` tags (or `<section>` tags in HTML5),
- and attach identifiers to the enclosing `<div>` (or `<section>`)
- rather than the header itself.
- See [Section identifiers](#header-identifiers-in-html), below.
-
-`--no-wrap`
-: Disable text wrapping in output. By default, text is wrapped
- appropriately for the output format.
-
-`--columns`=*NUMBER*
-: Specify length of lines in characters (for text wrapping).
-
-`--ascii`
-: Use only ascii characters in output. Currently supported only
- for HTML output (which uses numerical entities instead of
- UTF-8 when this option is selected).
-
-`--email-obfuscation=`*none|javascript|references*
-: Specify a method for obfuscating `mailto:` links in HTML documents.
- *none* leaves `mailto:` links as they are. *javascript* obfuscates
- them using javascript. *references* obfuscates them by printing their
- letters as decimal or hexadecimal character references.
- If `--strict` is specified, *references* is used regardless of the
- presence of this option.
-
-`--id-prefix`=*STRING*
-: Specify a prefix to be added to all automatically generated identifiers
- in HTML output. This is useful for preventing duplicate identifiers
- when generating fragments to be included in other pages.
+`--base-header-level=`*NUMBER*
+: Specify the base level for headers (defaults to 1).
`--indented-code-classes=`*CLASSES*
: Specify classes to use for indented code blocks--for example,
`perl,numberLines` or `haskell`. Multiple classes may be separated
by spaces or commas.
-`--toc`, `--table-of-contents`
-: Include an automatically generated table of contents (or, in
- the case of `latex`, `context`, and `rst`, an instruction to create
- one) in the output document. This option has no effect on `man`,
- `docbook`, `slidy`, or `s5` output.
+`--normalize`
+: Normalize the document after reading: merge adjacent
+ `Str` or `Emph` elements, for example, and remove repeated `Space`s.
-`--base-header-level=`*NUMBER*
-: Specify the base level for headers (defaults to 1).
+`-p`, `--preserve-tabs`
+: Preserve tabs instead of converting them to spaces (the default).
+
+`--tab-stop=`*NUMBER*
+: Specify the number of spaces per tab (default is 4).
+
+General writer options
+----------------------
+
+`-s`, `--standalone`
+: Produce output with an appropriate header and footer (e.g. a
+ standalone HTML, LaTeX, or RTF file, not a fragment). This option
+ is set automatically for `pdf`, `epub`, `docx`, and `odt` output.
`--template=`*FILE*
: Use *FILE* as a custom template for the generated document. Implies
@@ -341,8 +263,31 @@ Options
pandoc automatically sets the variables used in the default
templates.
-`-c` *URL*, `--css=`*URL*
-: Link to a CSS style sheet.
+`-D` *FORMAT*, `--print-default-template=`*FORMAT*
+: Print the default template for an output *FORMAT*. (See `-t`
+ for a list of possible *FORMAT*s.)
+
+`--no-wrap`
+: Disable text wrapping in output. By default, text is wrapped
+ appropriately for the output format.
+
+`--columns`=*NUMBER*
+: Specify length of lines in characters (for text wrapping).
+
+`--toc`, `--table-of-contents`
+: Include an automatically generated table of contents (or, in
+ the case of `latex`, `context`, and `rst`, an instruction to create
+ one) in the output document. This option has no effect on `man`,
+ `docbook`, `slidy`, or `s5` output.
+
+`--no-highlight`
+: Disables syntax highlighting for code blocks and inlines, even when
+ a language attribute is given.
+
+`--highlight-style`=*STYLE*
+: Specifies the coloring style to be used in highlighted source code.
+ Options are `pygments` (the default), `kate`, `monochrome`,
+ `espresso`, `haddock`, and `tango`.
`-H` *FILE*, `--include-in-header=`*FILE*
: Include contents of *FILE*, verbatim, at the end of the header.
@@ -366,6 +311,95 @@ Options
repeatedly to include multiple files. They will be included in the
order specified. Implies `--standalone`.
+Options affecting specific writers
+----------------------------------
+
+`--self-contained`
+: Produce a standalone HTML file with no external dependencies, using
+ `data:` URIs to incorporate the contents of linked scripts, stylesheets,
+ images, and videos. The resulting file should be "self-contained,"
+ in the sense that it needs no external files and no net access to be
+ displayed properly by a browser. This option works only with HTML output
+ formats, including `html`, `html5`, `html+lhs`, `html5+lhs`, `s5`,
+ `slidy`, and `dzslides`. Scripts, images, and stylesheets at absolute URLs
+ will be downloaded; those at relative URLs will be sought first relative
+ to the working directory, then relative to the user data directory (see
+ `--data-dir`), and finally relative to pandoc's default data directory.
+
+`--offline`
+: Deprecated synonym for `--self-contained`.
+
+`-5`, `--html5`
+: Produce HTML5 instead of HTML4. This option has no effect for writers
+ other than `html`. (*Deprecated:* Use the `html5` output format instead.)
+
+`--ascii`
+: Use only ascii characters in output. Currently supported only
+ for HTML output (which uses numerical entities instead of
+ UTF-8 when this option is selected).
+
+`--reference-links`
+: Use reference-style links, rather than inline links, in writing markdown
+ or reStructuredText. By default inline links are used.
+
+`--atx-headers`
+: Use ATX style headers in markdown output. The default is to use
+ setext-style headers for levels 1-2, and then ATX headers.
+
+`--chapters`
+: Treat top-level headers as chapters in LaTeX, ConTeXt, and DocBook
+ output. When the LaTeX template uses the report, book, or
+ memoir class, this option is implied. If `--beamer` is used,
+ top-level headers will become `\part{..}`.
+
+`-N`, `--number-sections`
+: Number section headings in LaTeX, ConTeXt, or HTML output.
+ By default, sections are not numbered.
+
+`--listings`
+: Use listings package for LaTeX code blocks
+
+`-i`, `--incremental`
+: Make list items in slide shows display incrementally (one by one).
+ The default is for lists to be displayed all at once.
+
+`--slide-level`=*NUMBER*
+: Specifies that headers with the specified level create
+ slides (for `beamer`, `s5`, `slidy`, `dzslides`). Headers
+ above this level in the hierarchy are used to divide the
+ slide show into sections; headers below this level create
+ subheads within a slide. The default is to set the slide level
+ based on the contents of the document; see
+ [Structuring the slide show](#structuring-the-slide-show), below.
+
+`--section-divs`
+: Wrap sections in `<div>` tags (or `<section>` tags in HTML5),
+ and attach identifiers to the enclosing `<div>` (or `<section>`)
+ rather than the header itself.
+ See [Section identifiers](#header-identifiers-in-html-latex-and-context), below.
+
+`--email-obfuscation=`*none|javascript|references*
+: Specify a method for obfuscating `mailto:` links in HTML documents.
+ *none* leaves `mailto:` links as they are. *javascript* obfuscates
+ them using javascript. *references* obfuscates them by printing their
+ letters as decimal or hexadecimal character references.
+ If `--strict` is specified, *references* is used regardless of the
+ presence of this option.
+
+`--id-prefix`=*STRING*
+: Specify a prefix to be added to all automatically generated identifiers
+ in HTML output. This is useful for preventing duplicate identifiers
+ when generating fragments to be included in other pages.
+
+`-T` *STRING*, `--title-prefix=`*STRING*
+: Specify *STRING* as a prefix at the beginning of the title
+ that appears in the HTML header (but not in the title as it
+ appears at the beginning of the HTML body). Implies
+ `--standalone`.
+
+`-c` *URL*, `--css=`*URL*
+: Link to a CSS style sheet.
+
`--reference-odt=`*FILE*
: Use the specified file as a style reference in producing an ODT.
For best results, the reference ODT should be a modified version
@@ -376,10 +410,20 @@ Options
`--data-dir`). If this is not found either, sensible defaults will be
used.
+`--reference-docx=`*FILE*
+: Use the specified file as a style reference in producing a docx file.
+ For best results, the reference docx should be a modified version
+ of a docx file produced using pandoc. The contents of the reference docx
+ are ignored, but its stylesheets are used in the new docx. If no
+ reference docx is specified on the command line, pandoc will look
+ for a file `reference.docx` in the user data directory (see
+ `--data-dir`). If this is not found either, sensible defaults will be
+ used.
+
`--epub-stylesheet=`*FILE*
: Use the specified CSS file to style the EPUB. If no stylesheet
is specified, pandoc will look for a file `epub.css` in the
- user data directory (see `--data-dir`, below). If it is not
+ user data directory (see `--data-dir`). If it is not
found there, sensible defaults will be used.
`--epub-cover-image=`*FILE*
@@ -397,25 +441,57 @@ Options
By default, pandoc will include the following metadata elements:
`<dc:title>` (from the document title), `<dc:creator>` (from the
- document authors), `<dc:language>` (from the locale), and
- `<dc:identifier id="BookId">` (a randomly generated UUID). Any of
- these may be overridden by elements in the metadata file.
+ document authors), `<dc:date>` (from the document date, which should
+ be in [ISO 8601 format]), `<dc:language>` (from the `lang`
+ variable, or, if is not set, the locale), and `<dc:identifier
+ id="BookId">` (a randomly generated UUID). Any of these may be
+ overridden by elements in the metadata file.
+
+`--epub-embed-font=`*FILE*
+: Embed the specified font in the EPUB. This option can be repeated
+ to embed multiple fonts. To use embedded fonts, you
+ will need to add declarations like the following to your CSS (see
+ ``--epub-stylesheet`):
+
+ @font-face {
+ font-family: DejaVuSans;
+ font-style: normal;
+ font-weight: normal;
+ src:url("DejaVuSans-Regular.ttf");
+ }
+ @font-face {
+ font-family: DejaVuSans;
+ font-style: normal;
+ font-weight: bold;
+ src:url("DejaVuSans-Bold.ttf");
+ }
+ @font-face {
+ font-family: DejaVuSans;
+ font-style: italic;
+ font-weight: normal;
+ src:url("DejaVuSans-Oblique.ttf");
+ }
+ @font-face {
+ font-family: DejaVuSans;
+ font-style: italic;
+ font-weight: bold;
+ src:url("DejaVuSans-BoldOblique.ttf");
+ }
+ body { font-family: "DejaVuSans"; }
-`-D` *FORMAT*, `--print-default-template=`*FORMAT*
-: Print the default template for an output *FORMAT*. (See `-t`
- for a list of possible *FORMAT*s.)
+`--latex-engine=`*pdflatex|lualatex|xelatex*
+: Use the specified LaTeX engine when producing PDF output.
+ The default is `pdflatex`. If the engine is not in your PATH,
+ the full path of the engine may be specified here.
-`-T` *STRING*, `--title-prefix=`*STRING*
-: Specify *STRING* as a prefix at the beginning of the title
- that appears in the HTML header (but not in the title as it
- appears at the beginning of the HTML body). Implies
- `--standalone`.
+Citations
+---------
`--bibliography=`*FILE*
: Specify bibliography database to be used in resolving
citations. The database type will be determined from the
extension of *FILE*, which may be `.mods` (MODS format),
- `.bib` (BibTeX format), `.bbx` (BibLaTeX format),
+ `.bib` (BibTeX/BibLaTeX format),
`.ris` (RIS format), `.enl` (EndNote format),
`.xml` (EndNote XML format), `.wos` (ISI format),
`.medline` (MEDLINE format), `.copac` (Copac format),
@@ -438,26 +514,76 @@ Options
user data directory (see `--data-dir`), or, if that is
not present, the Chicago author-date style.
+`--citation-abbreviations=`*FILE*
+: Specify a file containing abbreviations for journal titles and
+ other bibliographic fields (indicated by setting `form="short"`
+ in the CSL node for the field). The format is described at
+ <http://citationstylist.org/2011/10/19/abbreviations-for-zotero-test-release/>.
+ Here is a short example:
+
+ { "default": {
+ "container-title": {
+ "Lloyd's Law Reports": "Lloyd's Rep",
+ "Estates Gazette": "EG",
+ "Scots Law Times": "SLT"
+ }
+ }
+ }
+
`--natbib`
: Use natbib for citations in LaTeX output.
`--biblatex`
: Use biblatex for citations in LaTeX output.
-`--data-dir=`*DIRECTORY*
-: Specify the user data directory to search for pandoc data files.
- If this option is not specified, the default user data directory
- will be used:
+Math rendering in HTML
+----------------------
- $HOME/.pandoc
+`-m` [*URL*], `--latexmathml`[=*URL*]
+: Use the [LaTeXMathML] script to display embedded TeX math in HTML output.
+ To insert a link to a local copy of the `LaTeXMathML.js` script,
+ provide a *URL*. If no *URL* is provided, the contents of the
+ script will be inserted directly into the HTML header, preserving
+ portability at the price of efficiency. If you plan to use math on
+ several pages, it is much better to link to a copy of the script,
+ so it can be cached.
- in unix and
+`--mathml`[=*URL*]
+: Convert TeX math to MathML (in `docbook` as well as `html` and `html5`).
+ In standalone `html` output, a small javascript (or a link to such a
+ script if a *URL* is supplied) will be inserted that allows the MathML to
+ be viewed on some browsers.
- C:\Documents And Settings\USERNAME\Application Data\pandoc
+`--jsmath`[=*URL*]
+: Use [jsMath] to display embedded TeX math in HTML output.
+ The *URL* should point to the jsMath load script (e.g.
+ `jsMath/easy/load.js`); if provided, it will be linked to in
+ the header of standalone HTML documents. If a *URL* is not provided,
+ no link to the jsMath load script will be inserted; it is then
+ up to the author to provide such a link in the HTML template.
- in Windows. A `reference.odt`, `epub.css`, `templates` directory,
- or `s5` directory placed in this directory will override pandoc's
- normal defaults.
+`--mathjax`[=*URL*]
+: Use [MathJax] to display embedded TeX math in HTML output.
+ The *URL* should point to the `MathJax.js` load script.
+ If a *URL* is not provided, a link to the MathJax CDN will
+ be inserted.
+
+`--gladtex`
+: Enclose TeX math in `<eq>` tags in HTML output. These can then
+ be processed by [gladTeX] to produce links to images of the typeset
+ formulas.
+
+`--mimetex`[=*URL*]
+: Render TeX math using the [mimeTeX] CGI script. If *URL* is not
+ specified, it is assumed that the script is at `/cgi-bin/mimetex.cgi`.
+
+`--webtex`[=*URL*]
+: Render TeX formulas using an external script that converts TeX
+ formulas to images. The formula will be concatenated with the URL
+ provided. If *URL* is not specified, the Google Chart API will be used.
+
+Options for wrapper scripts
+---------------------------
`--dump-args`
: Print information about command-line arguments to *stdout*, then exit.
@@ -479,12 +605,6 @@ Options
pandoc -o foo.html -s
-`-v`, `--version`
-: Print version.
-
-`-h`, `--help`
-: Show usage message.
-
[LaTeXMathML]: http://math.etsu.edu/LaTeXMathML/
[jsMath]: http://www.math.union.edu/~dpvc/jsmath/
[MathJax]: http://www.mathjax.org/
@@ -542,12 +662,20 @@ depending on the output format, but include:
`date`
: date of document, as specified in title block
`lang`
-: language code for HTML documents
+: language code for HTML or LaTeX documents
`slidy-url`
: base URL for Slidy documents (defaults to
`http://www.w3.org/Talks/Tools/Slidy2`)
`s5-url`
: base URL for S5 documents (defaults to `ui/default`)
+`font-size`
+: font size (10pt, 11pt, 12pt) for LaTeX documents
+`documentclass`
+: document class for LaTeX documents
+`theme`
+: theme for LaTeX beamer documents
+`colortheme`
+: colortheme for LaTeX beamer documents
Variables may be set at the command line using the `-V/--variable`
option. This allows users to include custom variables in their
@@ -622,7 +750,7 @@ Paragraphs
A paragraph is one or more lines of text followed by one or more blank line.
Newlines are treated as spaces, so you can reflow your paragraphs as you like.
If you need a hard line break, put two or more spaces at the end of a line,
-or or type a backslash followed by a newline.
+or type a backslash followed by a newline.
Headers
-------
@@ -668,13 +796,13 @@ wrapping). Consider, for example:
#22, for example, and #5.
-### Header identifiers in HTML ###
+### Header identifiers in HTML, LaTeX, and ConTeXt ###
*Pandoc extension*.
-Each header element in pandoc's HTML output is given a unique
-identifier. This identifier is based on the text of the header. To
-derive the identifier from the header text,
+Each header element in pandoc's HTML and ConTeXt output is given a
+unique identifier. This identifier is based on the text of the header.
+To derive the identifier from the header text,
- Remove all formatting, links, etc.
- Remove all punctuation, except underscores, hyphens, and periods.
@@ -706,10 +834,10 @@ also make it easy to provide links from one section of a document to
another. A link to this section, for example, might look like this:
See the section on
- [header identifiers](#header-identifiers-in-html).
+ [header identifiers][#header-identifiers-in-html].
Note, however, that this method of providing links to sections works
-only in HTML.
+only in HTML, LaTeX, and ConTeXt formats.
If the `--section-divs` option is specified, then each section will
be wrapped in a `div` (or a `section`, if `--html5` was specified),
@@ -786,9 +914,9 @@ Note: blank lines in the verbatim text need not begin with four spaces.
In addition to standard indented code blocks, Pandoc supports
*delimited* code blocks. These begin with a row of three or more
-tildes (`~`) and end with a row of tildes that must be at least
-as long as the starting row. Everything between the tilde-lines
-is treated as code. No indentation is necessary:
+tildes (`~`) or backticks (`` ` ``) and end with a row of tildes or
+backticks that must be at least as long as the starting row. Everything
+between these lines is treated as code. No indentation is necessary:
~~~~~~~
if (a > 3) {
@@ -799,8 +927,8 @@ is treated as code. No indentation is necessary:
Like regular code blocks, delimited code blocks must be separated
from surrounding text by blank lines.
-If the code itself contains a row of tildes, just use a longer
-row of tildes at the start and end:
+If the code itself contains a row of tildes or backticks, just use a longer
+row of tildes or backticks at the start and end:
~~~~~~~~~~~~~~~~
~~~~~~~~~~
@@ -808,31 +936,44 @@ row of tildes at the start and end:
~~~~~~~~~~
~~~~~~~~~~~~~~~~
-Optionally, you may specify the language of the code block using
+Optionally, you may attach attributes to the code block using
this syntax:
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.haskell .numberLines}
+ ~~~~ {#mycode .haskell .numberLines startFrom="100"}
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
- qsort (filter (>= x) xs)
+ qsort (filter (>= x) xs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Some output formats can use this information to do syntax highlighting.
-Currently, the only output format that uses this information is HTML.
-
-If pandoc has been compiled with syntax highlighting support, then the
-code block above will appear highlighted, with numbered lines. (To see
-which languages are supported, do `pandoc --version`.)
-
-If pandoc has not been compiled with syntax highlighting support, the
-code block above will appear as follows:
+Here `mycode` is an identifier, `haskell` and `numberLines` are classes, and
+`startFrom` is an attribute with value `100`. Some output formats can use this
+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:
- <pre class="haskell">
+ <pre id="mycode" class="haskell numberLines" startFrom="100">
<code>
...
</code>
</pre>
+A shortcut form can also be used for specifying the language of
+the code block:
+
+ ```haskell
+ qsort [] = []
+ ```
+
+This is equivalent to:
+
+ ``` {.haskell}
+ qsort [] = []
+ ```
+
+To prevent all highlighting, use the `--no-highlight` flag.
+To set the highlighting style, use `--highlight-style`.
Lists
-----
@@ -1025,9 +1166,11 @@ Pandoc supports definition lists, using a syntax inspired by
Each term must fit on one line, which may optionally be followed by
a blank line, and must be followed by one or more definitions.
A definition begins with a colon or tilde, which may be indented one
-or two spaces. A term may have multiple definitions, and each definition
-may consist of one or more block elements (paragraph, code block, list,
-etc.), each indented four spaces or one tab stop.
+or two spaces. The body of the definition (including the first line,
+aside from the colon or tilde) should be indented four spaces. A term may have
+multiple definitions, and each definition may consist of one or more block
+elements (paragraph, code block, list, etc.), each indented four spaces or one
+tab stop.
If you leave space after the definition (as in the example above),
the blocks of the definitions will be considered paragraphs. In some
@@ -1132,10 +1275,9 @@ of one big list:
<!-- -->
- a. uno
- b. dos
- c. tres
-
+ 1. uno
+ 2. dos
+ 3. tres
Horizontal rules
----------------
@@ -1500,6 +1642,9 @@ reStructuredText
~ It will be rendered using an interpreted text role `:math:`, as described
[here](http://www.american.edu/econ/itex2mml/mathhack.rst).
+AsciiDoc
+ ~ It will be rendered as `latexmath:[...]`.
+
Texinfo
~ It will be rendered inside a `@math` command.
@@ -1512,16 +1657,24 @@ MediaWiki
Textile
~ It will be rendered inside `<span class="math">` tags.
-RTF, Docbook, OpenDocument, ODT
+RTF, OpenDocument, ODT
~ It will be rendered, if possible, using unicode characters,
and will otherwise appear verbatim.
-HTML, Slidy, S5, EPUB
+Docbook
+ ~ If the `--mathml` flag is used, it will be rendered using mathml
+ in an `inlineequation` or `informalequation` tag. Otherwise it
+ will be rendered, if possible, using unicode characters.
+
+Docx
+ ~ It will be rendered using OMML math markup.
+
+HTML, Slidy, DZSlides, S5, EPUB
~ The way math is rendered in HTML will depend on the
command-line options selected:
1. The default is to render TeX math as far as possible using unicode
- characters, as with RTF, Docbook, and OpenDocument output. Formulas
+ characters, as with RTF, DocBook, and OpenDocument output. Formulas
are put inside a `span` with `class="math"`, so that they may be
styled differently from the surrounding text if needed.
@@ -1563,11 +1716,11 @@ HTML, Slidy, S5, EPUB
Raw HTML
--------
-Markdown allows you to insert raw HTML anywhere in a document
+Markdown allows you to insert raw HTML (or DocBook) anywhere in a document
(except verbatim contexts, where `<`, `>`, and `&` are interpreted
literally).
-The raw HTML is passed through unchanged in HTML, S5, Slidy, EPUB,
+The raw HTML is passed through unchanged in HTML, S5, Slidy, DZSlides, EPUB,
Markdown, and Textile output, and suppressed in other formats.
*Pandoc extension*.
@@ -1608,7 +1761,6 @@ markdown with HTML block elements. For example, one can surround
a block of markdown text with `<div>` tags without preventing it
from being interpreted as markdown.
-
Raw TeX
-------
@@ -1809,18 +1961,17 @@ Pandoc can automatically generate citations and a bibliography in a number of
styles (using Andrea Rossato's `hs-citeproc`). In order to use this feature,
you will need a bibliographic database in one of the following formats:
- Format File extension
- ------------ --------------
- MODS .mods
- BibTeX .bib
- BibLaTeX .bbx
- RIS .ris
- EndNote .enl
- EndNote XML .xml
- ISI .wos
- MEDLINE .medline
- Copac .copac
- JSON citeproc .json
+ Format File extension
+ ------------ --------------
+ MODS .mods
+ BibTeX/BibLaTeX .bib
+ RIS .ris
+ EndNote .enl
+ EndNote XML .xml
+ ISI .wos
+ MEDLINE .medline
+ Copac .copac
+ JSON citeproc .json
You will need to specify the bibliography file using the `--bibliography`
command-line option (which may be repeated if you have several
@@ -1869,61 +2020,110 @@ document with an appropriate header:
The bibliography will be inserted after this header.
-Producing HTML slide shows with Pandoc
-======================================
+Producing slide shows with Pandoc
+=================================
You can use Pandoc to produce an HTML + javascript slide presentation
-that can be viewed via a web browser. There are two ways to do this,
-using [S5] or [Slidy].
+that can be viewed via a web browser. There are three ways to do this,
+using [S5], [DZSlides], or [Slidy]. You can also produce a PDF slide
+show using LaTeX [beamer].
-Here's the markdown source for a simple slide show, `eating.txt`:
+Here's the markdown source for a simple slide show, `habits.txt`:
- % Eating Habits
+ % Habits
% John Doe
% March 22, 2005
# In the morning
+ ## Getting up
+
+ - Turn off alarm
+ - Get out of bed
+
+ ## Breakfast
+
- Eat eggs
- Drink coffee
# In the evening
+ ## Dinner
+
- Eat spaghetti
- Drink wine
- --------------------------
+ ------------------
![picture of spaghetti](images/spaghetti.jpg)
+ ## Going to sleep
+
+ - Get in bed
+ - Count sheep
+
To produce the slide show, simply type
- pandoc -w s5 -s eating.txt > eating.html
+ pandoc -t s5 -s habits.txt -o habits.html
-for S5, or
+for S5,
- pandoc -w slidy -s eating.txt > eating.html
+ pandoc -t slidy -s habits.txt -o habits.html
-for Slidy.
+for Slidy,
-A title page is constructed automatically from the document's title
-block. Each level-one header and horizontal rule begins a new slide.
+ pandoc -t dzslides -s habits.txt -o habits.html
-The file produced by pandoc with the `-s/--standalone` option embeds a
-link to javascripts and CSS files, which are assumed to be available at
-the relative path `ui/default` (for S5) or at the Slidy website at
-`w3.org` (for Slidy). (These paths can be changed by setting the
-`slidy-url` or `s5-url` variables; see `--variable`, above.)
-If the `--offline` option is specified, the
-scripts and CSS will be included directly in the generated file, so that
-it may be used offline.
+for DZSlides, or
-You can change the style of the slides by putting customized CSS files
-in `$DATADIR/s5/default` (for S5) or `$DATADIR/slidy` (for Slidy),
-where `$DATADIR` is the user data directory (see `--data-dir`, above).
-The originals may be found in pandoc's system data directory (generally
-`$CABALDIR/pandoc-VERSION/s5/default`). Pandoc will look there for any
-files it does not find in the user data directory.
+ pandoc -t beamer habits.txt -o habits.pdf
+
+for beamer.
+
+With all HTML slide formats, the `--self-contained` option can be used to
+produce a single file that contains all of the data necessary to display the
+slide show, including linked scripts, stylesheets, images, and videos.
+
+Structuring the slide show
+--------------------------
+
+By default, the *slide level* is the highest header level in
+the hierarchy that is followed immediately by content, and not another
+header, somewhere in the document. In the example above, level 1 headers
+are always followed by level 2 headers, which are followed by content,
+so 2 is the slide level. This default can be overridden using
+the `--slide-level` option.
+
+The document is carved up into slides according to the following
+rules:
+
+ * A horizontal rule always starts a new slide.
+
+ * A header at the slide level always starts a new slide.
+
+ * Headers *below* the slide level in the hierarchy create
+ headers *within* a slide.
+
+ * Headers *above* the slide level in the hierarchy create
+ "title slides," which just contain the section title
+ and help to break the slide show into sections.
+
+ * A title page is constructed automatically from the document's title
+ block, if present. (In the case of beamer, this can be disabled
+ by commenting out some lines in the default template.)
+
+These rules are designed to support many different styles of slide show. If
+you don't care about structuring your slides into sections and subsections,
+you can just use level 1 headers for all each slide. (In that case, level 1
+will be the slide level.) But you can also structure the slide show into
+sections, as in the example above.
+
+For Slidy and S5, the file produced by pandoc with the `-s/--standalone`
+option embeds a link to javascripts and CSS files, which are assumed to
+be available at the relative path `s5/default` (for S5) or at the Slidy
+website at `w3.org` (for Slidy). (These paths can be changed by setting
+the `slidy-url` or `s5-url` variables; see `--variable`, above.) For DZSlides,
+the (relatively short) javascript and css are included in the file by default.
Incremental lists
-----------------
@@ -1940,19 +2140,37 @@ all at once with the `-i` option), put it in a block quote:
In this way incremental and nonincremental lists can be mixed in
a single document.
+Styling the slides
+------------------
+
+You can change the style of HTML slides by putting customized CSS files
+in `$DATADIR/s5/default` (for S5) or `$DATADIR/slidy` (for Slidy),
+where `$DATADIR` is the user data directory (see `--data-dir`, above).
+The originals may be found in pandoc's system data directory (generally
+`$CABALDIR/pandoc-VERSION/s5/default`). Pandoc will look there for any
+files it does not find in the user data directory.
+
+For dzslides, the CSS is included in the HTML file itself, and may
+be modified there.
+
+To style beamer slides, you can specify a beamer "theme" or "colortheme"
+using the `-V` option:
+
+ pandoc -t beamer habits.txt -V theme:Warsaw -o habits.pdf
+
Literate Haskell support
========================
If you append `+lhs` to an appropriate input or output format (`markdown`,
-`rst`, or `latex` for input or output; `html` for output only), pandoc
-will treat the document as literate Haskell source. This means that
+`rst`, or `latex` for input or output; `html` or `html5` for output only),
+pandoc will treat the document as literate Haskell source. This means that
- In markdown input, "bird track" sections will be parsed as Haskell
code rather than block quotations. Text between `\begin{code}`
and `\end{code}` will also be treated as Haskell code.
- - In markdown output, code blocks with class `haskell` will be
- rendered using bird tracks, and block quotations will be
+ - In markdown output, code blocks with classes `haskell` and `literate`
+ will be rendered using bird tracks, and block quotations will be
indented one space, so they will not be treated as Haskell code.
In addition, headers will be rendered setext-style (with underlines)
rather than atx-style (with '#' characters). (This is because ghc
@@ -1995,14 +2213,18 @@ Other contributors include Recai Oktaş, Paulo Tanimoto, Peter Wang,
Andrea Rossato, Eric Kow, infinity0x, Luke Plant, shreevatsa.public,
Puneeth Chaganti, Paul Rivier, rodja.trappe, Bradley Kuhn, thsutton,
Nathan Gass, Jonathan Daugherty, Jérémy Bobbio, Justin Bogner, qerub,
-Christopher Sawicki, Kelsey Hightower.
+Christopher Sawicki, Kelsey Hightower, Masayoshi Takahashi, Antoine
+Latter, Ralf Stephan, Eric Seidel, B. Scott Michel.
[markdown]: http://daringfireball.net/projects/markdown/
[reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html
[S5]: http://meyerweb.com/eric/tools/s5/
[Slidy]: http://www.w3.org/Talks/Tools/Slidy/
[HTML]: http://www.w3.org/TR/html40/
+[HTML 5]: http://www.w3.org/TR/html5/
+[XHTML]: http://www.w3.org/TR/xhtml1/
[LaTeX]: http://www.latex-project.org/
+[beamer]: http://www.tex.ac.uk/CTAN/macros/latex/contrib/beamer
[ConTeXt]: http://www.pragma-ade.nl/
[RTF]: http://en.wikipedia.org/wiki/Rich_Text_Format
[DocBook XML]: http://www.docbook.org/
@@ -2014,6 +2236,10 @@ Christopher Sawicki, Kelsey Hightower.
[Haskell]: http://www.haskell.org/
[GNU Texinfo]: http://www.gnu.org/software/texinfo/
[Emacs Org-Mode]: http://orgmode.org
+[AsciiDoc]: http://www.methods.co.nz/asciidoc/
[EPUB]: http://www.idpf.org/
[GPL]: http://www.gnu.org/copyleft/gpl.html "GNU General Public License"
-
+[DZSlides]: http://paulrouget.com/dzslides/
+[ISO 8601 format]: http://www.w3.org/TR/NOTE-datetime
+[Word docx]: http://www.microsoft.com/interop/openup/openxml/default.aspx
+[PDF]: http://www.adobe.com/pdf/
diff --git a/Setup.hs b/Setup.hs
index 056987e84..2ee9e29a9 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -6,6 +6,7 @@ import Distribution.PackageDescription
import Distribution.Simple.LocalBuildInfo
(LocalBuildInfo(..), absoluteInstallDirs)
import Distribution.Verbosity ( Verbosity, silent )
+import Distribution.Simple.GHC (ghcPackageDbOptions)
import Distribution.Simple.InstallDirs (mandir, bindir, CopyDest (NoCopyDest))
import Distribution.Simple.Utils (copyFiles)
import Control.Exception ( bracket_ )
@@ -24,14 +25,11 @@ main = do
defaultMainWithHooks $ simpleUserHooks {
runTests = runTestSuite
, postBuild = makeManPages
- , postCopy = \ _ flags pkg lbi -> do
+ , postCopy = \ _ flags pkg lbi ->
installManpages pkg lbi (fromFlag $ copyVerbosity flags)
(fromFlag $ copyDest flags)
- installScripts pkg lbi (fromFlag $ copyVerbosity flags)
- (fromFlag $ copyDest flags)
- , postInst = \ _ flags pkg lbi -> do
+ , postInst = \ _ flags pkg lbi ->
installManpages pkg lbi (fromFlag $ installVerbosity flags) NoCopyDest
- installScripts pkg lbi (fromFlag $ installVerbosity flags) NoCopyDest
}
exitWith ExitSuccess
@@ -49,39 +47,42 @@ runTestSuite args _ pkg lbi = do
-- | Build man pages from markdown sources in man/
makeManPages :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
-makeManPages _ flags _ _ = do
- let verbosity = fromFlag $ buildVerbosity flags
+makeManPages _ flags _ lbi = do
ds1 <- modifiedDependencies (manDir </> "man1" </> "pandoc.1")
["README", manDir </> "man1" </> "pandoc.1.template"]
- ds2 <- modifiedDependencies (manDir </> "man1" </> "markdown2pdf.1")
- [manDir </> "man1" </> "markdown2pdf.1.md"]
- ds3 <- modifiedDependencies (manDir </> "man5" </> "pandoc_markdown.5")
+ ds2 <- modifiedDependencies (manDir </> "man5" </> "pandoc_markdown.5")
["README", manDir </> "man5" </> "pandoc_markdown.5.template"]
- let cmd = "runghc -package-conf=dist/package.conf.inplace MakeManPage.hs"
- let cmd' = if verbosity == silent
- then cmd
- else cmd ++ " --verbose"
+
+ let distPref = fromFlag (buildDistPref flags)
+ packageDB =
+ withPackageDB lbi
+ ++ [SpecificPackageDB $ distPref </> "package.conf.inplace"]
+
+ verbosity = fromFlag $ buildVerbosity flags
+
+ args = makeGhcArgs (ghcPackageDbOptions packageDB)
+ ++ ["MakeManPage.hs"]
+ args' = if verbosity == silent
+ then args
+ else args ++ ["--verbose"]
-- Don't run MakeManPage.hs unless we have to
- unless (null ds1 && null ds2 && null ds3) $
- runCommand cmd' >>= waitForProcess >>= exitWith
+ unless (null ds1 && null ds2) $ do
+ rawSystem "runghc" args' >>= exitWith
+
+-- format arguments to runghc that we wish to pass to ghc
+-- normally runghc gets it right, unless the argument does
+-- not begin with a '-' charecter, so we need to give clear
+-- directions.
+makeGhcArgs :: [String] -> [String]
+makeGhcArgs = map ("--ghc-arg="++)
manpages :: [FilePath]
manpages = ["man1" </> "pandoc.1"
- ,"man1" </> "markdown2pdf.1"
,"man5" </> "pandoc_markdown.5"]
manDir :: FilePath
manDir = "man"
-installScripts :: PackageDescription -> LocalBuildInfo
- -> Verbosity -> CopyDest -> IO ()
-installScripts pkg lbi verbosity copy =
- copyFiles verbosity (bindir (absoluteInstallDirs pkg lbi copy))
- (zip (repeat ".") (wrappers \\ exes))
- where exes = map exeName $ filter isBuildable $ executables pkg
- isBuildable = buildable . buildInfo
- wrappers = ["markdown2pdf"]
-
installManpages :: PackageDescription -> LocalBuildInfo
-> Verbosity -> CopyDest -> IO ()
installManpages pkg lbi verbosity copy =
diff --git a/changelog b/changelog
index 4d8e22861..b75d47f1c 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,570 @@
+pandoc (1.9.1.1)
+
+ * Better handling of raw latex environments in markdown. Now
+
+ \begin{equation}
+ a_1
+ \end{equation}
+
+ turns into a raw latex block as expected.
+
+ * Improvements to LaTeX reader:
+
+ + Skip options after block commands.
+ + Correctly handle `{\\}` in braced.
+ + Added a needed 'try'.
+ + Citations: add `, ` to suffix if it doesn't start with space or
+ punctuation. Otherwise we get no space between the year and the
+ suffix in author-date styles.
+
+ * Added two needed data files for S5. This fixes a problem with
+ `pandoc -t s5 --self-contained`. Also removed `slides.min.js`,
+ which was no longer being used.
+
+ * Fixed some minor problems in `reference.docx`:
+ name on "Date" style, `xCs` instead of `xIs`.
+
+ * Fixed a problem creating docx files using a reference docx
+ modified using Word. The problem seems to be that Word
+ modifies `_rels/.rels`, changing the Type of the Relationship to
+ `docProps/core.xml`. Pandoc now changes this back to the correct
+ value if it has been altered, fixing the problem.
+
+ * Fixed html5 template so it works properly with highlighting.
+
+pandoc (1.9.1)
+
+ * LaTeX reader:
+
+ + Fixed regression in 1.9; properly handle escaped $ in latex math.
+ + Put LaTeX verse environments in blockquotes.
+
+ * Markdown reader:
+
+ + Limit nesting of strong/emph. This avoids exponential lookahead
+ in parasitic cases, like `a**a*a**a*a**a*a**a*a**a*a**a*a**a*a**`.
+ + Improved attributes syntax (inn code blocks/spans):
+ (1) Attributes can contain line breaks. (2) Values in key-value
+ attributes can be surrounded by either double or single quotes, or
+ left unquoted if they contain no spaces.
+
+ * Don't wrap headers in markdown or RST writers.
+
+ * Added `stateMaxNestingLevel` to `ParserState`.
+ We set this to 6, so you can still have `Emph` inside `Emph`,
+ just not indefinitely.
+
+ * More efficient implementation of `nowrap` in `Text.Pandoc.Pretty`.
+
+ * `Text.Pandoc.PDF`: Only run latex twice if `\tableofcontents`
+ is present.
+
+ * Require highlighting-kate >= 0.5.0.2, texmath >= 0.6.0.2.
+
+pandoc (1.9.0.5)
+
+ * Changed cabal file so that build-depends for the test program
+ are not required unless the tests flag is used.
+
+ * LaTeX writer: insert `{}` between adjacent hyphens so they don't
+ form ligatures (dashes) in code spans.
+
+pandoc (1.9.0.4)
+
+ * Raised version bound on test-framework to avoid problems
+ compiling tests on GHC 7.4.1.
+
+ * LaTeX reader: Use raw LaTeX as fallback inline text for Cites,
+ so citations don't just disappear unless you process with
+ citeproc. Ignore `\bibliographystyle`, `\nocite`.
+
+ * Simplified tex2pdf; it will always run latex twice to
+ resolve table of contents and hyperrefs.
+
+pandoc (1.9.0.3)
+
+ * Require Cabal >= 1.10.
+ * Tweaked cabal file to meet Cabal 1.10 requirements.
+
+pandoc (1.9.0.2)
+
+ * Allow build with json 0.4 or 0.5. Otherwise we can't build with
+ ghc 6.12.
+
+pandoc (1.9)
+
+ [new features]
+
+ * Added a Microsoft Word `docx` writer. The writer includes support
+ for highlighted code and for math (which is converted from TeX to OMML,
+ Office's native math markup language, using texmath's new OMML module).
+ A new option `--reference-docx` allows the user to customize the
+ styles.
+
+ * Added an `asciidoc` writer (<http://www.methods.co.nz/asciidoc/>).
+
+ * Better support for slide shows:
+
+ + Added a `dzslides` writer. DZSlides is a lightweight HTML5/javascript
+ slide show format due to Paul Rouget (<http://paulrouget.com/dzslides/>).
+
+ + Added a LaTeX `beamer` writer. Beamer is a LaTeX package for creating
+ slide presentations.
+
+ + New, flexible rules for dividing documents into sections and slides
+ (see the "Structuring the slide show" in the User's Guide). These
+ are backward-compatible with the old rules, but they allow slide
+ shows to be organized into sections and subsections containing
+ multiple slides.
+
+ + A new `--slide-level` option allows users to override defaults
+ and select a slide level below the first header level with content.
+
+ * A new `--self-contained` option produces HTML output that does not
+ depend on an internet connection or the presence of any external
+ files. Linked images, CSS, and javascript is downloaded (or fetched
+ locally) and encoded in `data:` URIs. This is useful for making portable
+ `HTML slide shows. The --offline` option has been deprecated and is now
+ `treated as a synonym or --self-contained`.
+
+ * Support for PDF output:
+
+ + Removed the old `markdown2pdf`.
+ + `pandoc` can now create PDFs (assuming you have latex and a set of
+ appropriate packages installed): just specify an output file with the
+ `.pdf` extension.
+ + A new option `--latex-engine` allows you to specify `pdflatex`,
+ `xelatex`, or `lualatex` as the processor.
+
+ * Highlighting changes:
+
+ + Syntax highlighting is now a standard feature; the `highlighting`
+ flag is no longer needed when compiling.
+ + A new `--no-highlight` option allows highlighting to be disabled.
+ + Highlighting now works in `docx`, `latex`, and `epub`, as well as
+ `html`, `html5`, `dzslides`, `s5`, and `slidy`.
+ + A new `--highlight-style` option selects between various highlighting
+ color themes.
+
+ * Internal links to sections now work in ConTeXt and LaTeX as well as HTML.
+
+ * LaTeX `\include` and `\usepackage` commands are now processed,
+ provided the files are in the working directory.
+
+ * EPUB improvements:
+
+ + Internal and external links now work in EPUB.
+ + Raw HTML is allowed.
+ + New `--epub-embed-font` option.
+ + Customizable templates for EPUB pages offer more control over
+ formatting: `epub-page.html`, `epub-coverimage.html`,
+ `epub-titlepage.html`.
+
+ * `--mathml` now works with DocBook.
+
+ * Added support for math in RST reader and writer. Inline math uses the
+ `` :math:`...` `` construct. Display math uses
+
+ .. math:: ...
+
+ or if the math is multiline,
+
+ .. math::
+
+ ...
+
+ These constructions are now supported now by `rst2latex.py`.
+
+ * Github syntax for fenced code blocks is supported in pandoc's
+ markdown. You can now write
+
+ ```ruby
+ x = 2
+ ```
+
+ instead of
+
+ ~~~ {.ruby}
+ x = 2
+ ~~~~
+
+ * Easier scripting: a new `toJsonFilter` function makes it easier to
+ write Haskell scripts to manipulate the Pandoc AST.
+
+ [behavior changes]
+
+ * Fixed parsing of consecutive lists in markdown.
+ Pandoc previously behaved like Markdown.pl for consecutive
+ lists of different styles. Thus, the following would be parsed
+ as a single ordered list, rather than an ordered list followed
+ by an unordered list:
+
+ 1. one
+ 2. two
+
+ - one
+ - two
+
+ This change makes pandoc behave more sensibly, parsing this as
+ two lists. Any change in list type (ordered/unordered) or in
+ list number style will trigger a new list. Thus, the following
+ will also be parsed as two lists:
+
+ 1. one
+ 2. two
+
+ a. one
+ b. two
+
+ Since we regard this as a bug in Markdown.pl, and not something
+ anyone would ever rely on, we do not preserve the old behavior
+ even when `--strict` is selected.
+
+ * Dashes work differently with `--smart`: `---` is always em-dash,
+ and `--` is always en-dash. Pandoc no longer tries to guess when
+ `-` should be en-dash. *Note:* This may change how existing documents
+ look when processed with pandoc. A new option, `--old-dashes`,
+ is provided for legacy documents.
+
+ * The markdown writer now uses setext headers for levels 1-2.
+ The old behavior (ATX headers for all levels) can be restored
+ using the new `--atx-headers` option.
+
+ * Links are now allowed in markdown image captions. They are also
+ allowed in links, but will appear there as regular text. So,
+
+ [link with [link](/url)](/url)
+
+ will turn into
+
+ <p><a href="/url">link with link</a></p>
+
+ * Improved handling of citations using `citeproc-hs-0.3.4`.
+ Added `--citation-abbreviations` option.
+
+ * Citation keys can no longer end with a punctuation character.
+ This means that `@item1.` will be parsed as a citation with key
+ 'item1', followed by a period, instead of a citation with key
+ 'item1.', as was the case previously.
+
+ * In HTML output, citations are now put in a span with class `citation`.
+
+ * The markdown reader now recognizes DocBook block and inline tags.
+ It was always possible to include raw DocBook tags in a markdown
+ document, but now pandoc will be able to distinguish block from
+ inline tags and behave accordingly. Thus, for example,
+
+ <sidebar>
+ hello
+ </sidebar>
+
+ will not be wrapped in `<para>` tags.
+
+ * The LaTeX parser has been completely rewritten; it is now much more
+ accurate, robust, and extensible. However, there are two important
+ changes in how it treats unknown LaTeX. (1) Previously, unknown
+ environments became BlockQuote elements; now, they are treated
+ as "transparent", so `\begin{unknown}xyz\end{unknown}` is the
+ same as `xyz`. (2) Previously, arguments of unknown commands
+ were passed through with their braces; now the braces are stripped
+ off.
+
+ * `--smart` is no longer selected automatically with `man` output.
+
+ * The deprecated `--xetex` option has been removed.
+
+ * The `--html5`/`-5` option has been deprecated. Use `-t html5`
+ instead. `html5` and `html5+lhs` are now separate output formats.
+
+ * Single quotes are no longer escaped in HTML output. They do not
+ need to be escaped outside of attributes.
+
+ * Pandoc will no longer transform leading newlines in code
+ blocks to `<br/>` tags.
+
+ * The ODT writer now sizes images appropriately, using the image
+ size and DPI information embedded in the image.
+
+ * `--standalone` is once again implicitly for a non-text output format
+ (ODT, EPUB). You can again do `pandoc test.txt -o test.odt`
+ and get a standalone ODT file.
+
+ * The Docbook writer now uses `<sect1>`, `<sect2>`, etc. instead of
+ `<section>`.
+
+ * The HTML writer now uses `<del>` for strikeout.
+
+ * In HTML output with `--section-divs`, the classes `section` and
+ `level[1,2,..6]` are put on the `div` tags so they can be styled.
+ In HTML 5 output with `--section-divs`, the classes
+ `level[1,2,...6]` are put on `section` tags.
+
+ * EPUB writer changes:
+
+ + The `lang` variable now sets the language
+ in the metadata (if it is not set, we default to the locale).
+ + EPUB: UTF-8 is used rather than decimal entities.
+
+ * Added `titleslide` class to title slide in S5 template.
+
+ * In HTML, EPUB, and docx metadata, the date is normalized into
+ YYYY-MM-DD format if possible. (This is required for validation.)
+
+ * Attributes in highlighted code blocks are now preserved in HTML.
+ The container element will have the classes, id, and key-value attributes
+ you specified in the delimited code block. Previously these were stripped
+ off.
+
+ * The reference backlink in the HTML writer no longer has a special
+ `footnoteBacklink` class.
+
+ * The HTML template has been split into `html` and `html5` templates.
+
+ * Author and date are treated more consistently in HTML templates.
+ Authors are now `<h2>`, date `<h3>`.
+
+ * URLs are hyphenated in the ConTeXt writer (B. Scott Michel).
+
+ * In `Text.Pandoc.Builder`, `+++` has been replaced by `<>`.
+
+ [bug fixes]
+
+ * Better support for combining characters and East Asian wide characters
+ in markdown and reST.
+
+ * Better handling of single quotes with `--smart`.
+ Previously `D'oh l'*aide*` would be parsed with left and right single
+ quotes instead of apostrophes. This kind of error is now fixed.
+
+ * Highlighting: Use `reads` instead of `read` for better error handling.
+ Fixes crash on `startNum="abc"`.
+
+ * Added blank comment after directives in rst template.
+
+ * Unescape entities in citation `refId`. The `refId`s coming
+ from citeproc contain XML numeric entities, and these don't match with the
+ citation keys parsed by pandoc. Solution is to unescape them.
+
+ * HTML reader: Fixed bug parsing tables with both thead and tbody.
+
+ * Markdown reader:
+
+ + Better handling of escapes in link URLs and titles.
+ + Fixed backslash escapes in reference links.
+ + Fixed bug in table/hrule parsing, by checking that the top
+ line of a table is not followed by a blank line. This bug caused
+ slowdowns on some files with hrules and tables, as pandoc tried to
+ interpret the hrules as the tops of multiline tables.
+ + Fixed bug in code block attribute parser. Previously the ID attribute
+ got lost if it didn't come first. Now attributes can come in any order.
+
+ * RST reader: allow footnotes followed by newline without space characters.
+
+ * LaTeX reader:
+
+ + Ignore empty groups {}, { }.
+ + LaTeX reader: Handle \@.
+ + LaTeX reader: Don't crash on commands like `\itemsep`.
+ + LaTeX reader: Better handling of letter environments.
+
+ * RST writer: Fixed bug involving empty table cells. isSimple was being
+ calculated in a way that assumed there were no non-empty cells.
+
+ * ConTeXt writer:
+
+ + Made `--toc` work even without `--number-sections`.
+ + Escape # in link URLs.
+ + Use buffering for footnotes containing code blocks.
+ + Changed 'descr' to 'description', fixed alignment.
+
+ * LaTeX writer:
+
+ + Escape euro character.
+ + Don't escape ~ inside href{...}.
+ + Escape # in href URLs.
+ + Improved detection of book classes. We now check the
+ `documentclass` variable, and if that is not set, we look through
+ the template itself. Also, we have added the KOMA classes scrreprt
+ and scrbook. You can now make a book using
+ `pandoc -V documentclass:book mybook.txt -o mybook.pdf`
+ + LHS files now set the "listings" variable, so that the definition
+ of the `code` environment will be included in the template.
+ + Links are colored blue by default (this can be changed by
+ modifying `hyperref` settings in the template).
+ + Added `lang` variable to LaTeX template.
+
+ * HTML writer:
+
+ + Fixed bug in HTML template with html5 and mathml.
+ + Don't use self-closing img, br, hr tags for HTML5.
+ + Use `<section>` for footnotes if HTML5.
+ + Update HTML templates to use Content-Style-Type meta tag.
+ + Use separate variables for meta-date, meta-author.
+ This makes footnotes work in author and date fields.
+ + Use 'vertical-align:middle' in WebTeX math for better alignment.
+
+ * S5/slidy writer: Make footnotes appear on separate slide at end.
+
+ * MIME: Added 'layout-cache' to getMimeType. This ensures that the
+ META-INF/manifest.xml for ODT files will have everything it needs, so
+ that ODT files modified by LibreOffice can be used as `--reference-odt`.
+
+ * `Text.Pandoc.Templates`: Return empty string for json template.
+
+ * `Text.Pandoc.Biblio`:
+
+ + Expand citations recursively inside nested inlines.
+ + Treat `\160` as space when parsing locator and suffix.
+ This fixes a bug with "p. 33" when `--smart` is used. Previously
+ the whole "p. 33" would be included in the suffix, with no locator.
+ + Put whole author-in-text citation in a Cite. Previously just the
+ date and other info went in the Cite.
+ + Don't add comma+space to prefix if it ends in punctuation.
+
+ * Updated chicago-author-date.csl. The old version did not work
+ properly for edited volumes with no author.
+
+ * EPUB writer:
+
+ + Add date to EPUB titlepage and metadata.
+ + Added TOC identifier in EPUB page template.
+ + Don't generate superfluous file `cover-image.jpg`.
+
+ [under the hood improvements]
+
+ * Modified `make_osx_package.sh` to use cabal-dev.
+ Items are no longer installed as root.
+ Man pages are zipped and given proper permissions.
+
+ * Modified windows installer generater to use cabal-dev.
+
+ * Setup: Making man pages now works with cabal-dev (at least on OSX). In
+ Setup.hs we now invoke 'runghc' in a way that points it to the correct
+ package databases, instead of always falling back to the default user
+ package db.
+
+ * Updated to work with GHC 7.4.1.
+
+ * Removed dependency on old-time.
+
+ * Removed dependency on dlist.
+
+ * New slidy directory for "self-contained."
+
+ * TeXMath writer: Use unicode thin spaces for thin spaces.
+
+ * Markdown citations: don't strip off initial space in locator.
+
+ [API changes]
+
+ * Removed `Apostrophe`, `EmDash`, `EnDash`, and `Ellipses`
+ from the native `Inline` type in pandoc-types. Now we use `Str`
+ elements with unicode.
+
+ * Improvements to `Text.Pandoc.Builder`:
+
+ + `Inlines` and `Blocks` are now newtypes (not synonyms for
+ sequences).
+ + Instances are defined for `IsString`, `Show`, `Read`, `Monoid`,
+ and a new `Listable` class, which allows these to be manipulated
+ to some extent like lists. Monoid append includes automatic
+ normalization.
+ + `+++` has been replaced by `<>` (mappend).
+
+ * Use blaze-html instead of xhtml for HTML generation.
+ This changes the type of `writeHtml`.
+
+ * `Text.Pandoc.Shared`:
+
+ + Added `warn` and `err`.
+ + Removed `unescapeURI`, modified `escapeURI`.
+ (See under [behavior changes], above.)
+
+ * Changes in URI escaping: Previously the readers escaped URIs by
+ converting unicode characters to octets and then percent encoding.
+ Now unicode characters are left as they are, and `escapeURI` only
+ percent-encodes space characters. This gives more readable
+ URIs, and works well with modern user agents. URIs are no longer unescaped
+ at all on conversion to `markdown`, `asciidoc`, `rst`, `org`.
+
+ * New module `Text.Pandoc.SelfContained`.
+
+ * New module `Text.Pandoc.Docx`.
+
+ * New module `Text.Pandoc.PDF`.
+
+ * Added `writerBeamer` to `WriterOptions`.
+
+ * Added `normalizeDate` to `Text.Pandoc.Shared`.
+
+ * Added `splitStringWithIndices` in `Text.Pandoc.Shared`.
+ This is like `splitWithIndices`, but it is sensitive to distinctions
+ between wide, combining, and regular characters.
+
+ * `Text.Pandoc.Pretty`:
+
+ + Added `chomp` combinator.
+ + Added `beforeNonBreak` combinator. This allows you to include
+ something conditionally on it being before a nonblank.
+ Used for RST inline math.
+ + Added `charWidth` function. All characters marked W or F in the unicode
+ spec EastAsianWidth.txt get width 2.
+ + Added `realLength`, based on `charWidth`. `realLength` is now
+ used in calculating offsets.
+
+ * New module `Text.Pandoc.Slides`, for common functions for breaking
+ a document into slides.
+
+ * Removed `Text.Pandoc.S5`, which is no longer needed.
+
+ * Removed `Text.Pandoc.CharacterReferences`. Moved
+ `characterReference` to `Text.Pandoc.Parsing`.
+ `decodeCharacterReferences` is replaced by `fromEntities`
+ in `Text.Pandoc.XML`.
+
+ * Added `Text.Pandoc.ImageSize`. This is intened for use
+ in `docx` and `odt` writers, so the size and dpi of images
+ can be calculated.
+
+ * Removed `writerAscii` in `WriterOptions`.
+
+ * Added `writerHighlight` to `WriterOptions`.
+
+ * Added `DZSlides` to `HTMLSlideVariant`.
+
+ * `writeEPUB` has a new argument for font files to embed.
+
+ * Added `stateLastStrPos` to `ParserState`. This lets us keep track
+ of whether we're parsing the position immediately after a regular
+ (non-space, non-symbol) string, which is useful for distinguishing
+ apostrophes from single quote starts.
+
+ * `Text.Pandoc.Parsing`:
+
+ + `escaped` now returns a `Char`.
+ + Removed `charsInBalanced'`, added a character parser as
+ a parameter of `charsInBalanced`. This is needed for
+ proper handling of escapes, etc.
+ + Added `withRaw`.
+
+ * Added `toEntities` to `Text.Pandoc.XML`.
+
+ * `Text.Pandoc.Readers.LaTeX`:
+
+ + Export `handleIncludes`.
+ + Export `rawLaTeXBlock` instead of `rawLaTeXEnvironment'`.
+
+ * Added `ToJsonFilter` class and `toJsonFilter` function to
+ `Text.Pandoc`, deprecating the old `jsonFilter` function.
+
+ * `Text.Pandoc.Highlighting`:
+
+ + Removed `highlightHtml`, `defaultHighlightingCss`.
+ + Export `formatLaTeXInline`, `formatLaTeXBlock`, and `highlight`, plus
+ key functions from highlighting-kate.
+ + Changed types of highlighting function. `highlight` returns a
+ `Maybe`, not an `Either`.
+
pandoc (1.8.2.1)
* Relaxed cabal consntraints for test-framework (S. Trofimovich).
diff --git a/default.csl b/default.csl
index f16f82305..dea707114 100644
--- a/default.csl
+++ b/default.csl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" page-range-format="chicago">
+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
<info>
<title>Chicago Manual of Style (Author-Date format)</title>
<id>http://www.zotero.org/styles/chicago-author-date</id>
@@ -8,362 +8,415 @@
<name>Julian Onions</name>
<email>julian.onions@gmail.com</email>
</author>
+ <contributor>
+ <name>Sebastian Karcher</name>
+ </contributor>
<category citation-format="author-date"/>
<category field="generic-base"/>
- <updated>2009-12-04T20:22:16+00:00</updated>
+ <updated>2011-11-17T22:01:05+00:00</updated>
<summary>The author-date variant of the Chicago style</summary>
<link href="http://www.chicagomanualofstyle.org/tools_citationguide.html" rel="documentation"/>
+ <rights>This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
</info>
- <macro name="secondary-contributors">
- <choose>
- <if match="none" type="chapter">
- <group delimiter=". ">
- <choose>
- <if variable="author">
- <names variable="editor">
- <label form="verb-short" prefix=" " suffix=". " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </if>
- </choose>
- <choose>
- <if match="any" variable="author editor">
- <names variable="translator">
- <label form="verb-short" prefix=" " suffix=". " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </if>
- </choose>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="container-contributors">
- <choose>
- <if type="chapter">
- <group delimiter=", " prefix=",">
- <choose>
- <if variable="author">
- <names variable="editor">
- <label form="verb-short" prefix=" " suffix=". " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
+ <macro name="secondary-contributors">
+ <choose>
+ <if type="chapter paper-conference" match="none">
+ <group delimiter=". ">
+ <choose>
+ <if variable="author">
+ <names variable="editor">
+ <label form="verb-short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ <choose>
+ <if variable="author editor" match="any">
+ <names variable="translator">
+ <label form="verb-short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-contributors">
+ <choose>
+ <if type="chapter paper-conference" match="any">
+ <group prefix="," delimiter=", ">
+ <choose>
+ <if variable="author">
+ <names variable="editor">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ <choose>
+ <if variable="container-author">
+ <group>
+ <names variable="container-author">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=" " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ <choose>
+ <if variable="author editor" match="any">
+ <names variable="translator">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="anon">
+ <text term="anonymous" form="short" text-case="capitalize-first" suffix="." strip-periods="true"/>
+ </macro>
+ <macro name="editor">
+ <names variable="editor">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", " suffix="." strip-periods="true"/>
+ </names>
+ </macro>
+ <macro name="translator">
+ <names variable="translator">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="verb-short" prefix=", " suffix="." strip-periods="true"/>
+ </names>
+ </macro>
+ <macro name="recipient">
+ <choose>
+ <if type="personal_communication">
+ <choose>
+ <if variable="genre">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ <else>
+ <text term="letter" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ <names variable="recipient" delimiter=", ">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="contributors">
+ <names variable="author">
+ <name and="text" name-as-sort-order="first" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="verb-short" prefix=", " suffix="." text-case="lowercase" strip-periods="true"/>
+ <substitute>
+ <text macro="editor"/>
+ <text macro="translator"/>
+ <text macro="anon"/>
+ </substitute>
+ </names>
+ <text macro="recipient"/>
+ </macro>
+ <macro name="contributors-short">
+ <names variable="author">
+ <name form="short" and="text" delimiter=", " initialize-with=". "/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <text macro="anon"/>
+ </substitute>
+ </names>
+ </macro>
+ <macro name="interviewer">
+ <names variable="interviewer" delimiter=", ">
+ <label form="verb" prefix=" " text-case="capitalize-first" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="archive">
+ <group delimiter=". ">
+ <text variable="archive_location" text-case="capitalize-first"/>
+ <text variable="archive"/>
+ <text variable="archive-place"/>
+ </group>
+ </macro>
+ <macro name="access">
+ <group delimiter=". ">
+ <choose>
+ <if type="graphic report" match="any">
+ <text macro="archive"/>
</if>
- </choose>
- <choose>
- <if match="any" variable="author editor">
- <names variable="translator">
- <label form="verb-short" prefix=" " suffix=". " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
+ <else-if type="bill book graphic legal_case motion_picture report song article-magazine article-newspaper thesis chapter paper-conference" match="none">
+ <text macro="archive"/>
+ </else-if>
+ </choose>
+ <text variable="DOI" prefix="doi:"/>
+ <choose>
+ <if type="legal_case" match="none">
+ <text variable="URL"/>
</if>
- </choose>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="anon">
- <choose>
- <if match="none" variable="author editor translator">
- <text form="short" term="anonymous" text-case="capitalize-first" />
- </if>
- </choose>
- </macro>
- <macro name="editor">
- <names variable="editor">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="short" prefix=", " suffix="." />
- </names>
- </macro>
- <macro name="translator">
- <names variable="translator">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="verb-short" prefix=", " suffix="." />
- </names>
- </macro>
- <macro name="recipient">
- <choose>
- <if type="personal_communication">
- <choose>
- <if variable="genre">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- <else>
- <text term="letter" text-case="capitalize-first" />
- </else>
- </choose>
- </if>
- </choose>
- <names delimiter=", " variable="recipient">
- <label form="verb" prefix=" " suffix=" " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
- </macro>
- <macro name="contributors">
- <names variable="author">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="verb-short" prefix=", " suffix="." text-case="lowercase" />
- <substitute>
- <text macro="editor" />
- <text macro="translator" />
- </substitute>
- </names>
- <text macro="anon" />
- <text macro="recipient" />
- </macro>
- <macro name="contributors-short">
- <names variable="author">
- <name and="text" delimiter=", " form="short" />
- <substitute>
- <names variable="editor" />
- <names variable="translator" />
- </substitute>
- </names>
- <text macro="anon" />
- </macro>
- <macro name="interviewer">
- <names delimiter=", " variable="interviewer">
- <label form="verb" prefix=" " suffix=" " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </macro>
- <macro name="archive">
- <group delimiter=". ">
- <text text-case="capitalize-first" variable="archive_location" />
- <text variable="archive" />
- <text variable="archive-place" />
- </group>
- </macro>
- <macro name="access">
- <group delimiter=". ">
+ </choose>
+ </group>
+ </macro>
+ <macro name="title">
<choose>
- <if match="any" type="graphic report">
- <text macro="archive" />
- </if>
- <else-if match="none" type="book thesis chapter article-journal article-newspaper article-magazine">
- <text macro="archive" />
- </else-if>
+ <if variable="title" match="none">
+ <choose>
+ <if type="personal_communication" match="none">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <text variable="title" font-style="italic"/>
+ </else-if>
+ <else>
+ <text variable="title" quotes="true"/>
+ </else>
</choose>
- <text prefix="doi:" variable="DOI" />
- <text variable="URL" />
- </group>
- </macro>
- <macro name="title">
- <choose>
- <if match="none" variable="title">
- <choose>
- <if match="none" type="personal_communication">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- </choose>
- </if>
- <else-if type="book">
- <text font-style="italic" variable="title" />
- </else-if>
- <else>
- <text variable="title" />
- </else>
- </choose>
- </macro>
- <macro name="edition">
- <choose>
- <if match="any" type="book chapter">
- <choose>
- <if is-numeric="edition">
- <group delimiter=" ">
- <number form="ordinal" variable="edition" />
- <text form="short" suffix="." term="edition" />
+ </macro>
+ <macro name="edition">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short" suffix="." strip-periods="true"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition" suffix="."/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="locators">
+ <choose>
+ <if type="article-journal">
+ <text variable="volume" prefix=" "/>
+ <text variable="issue" prefix=" (" suffix=")"/>
+ </if>
+ <else-if type="legal_case">
+ <text variable="volume" prefix=", "/>
+ <text variable="container-title" prefix=" "/>
+ <text variable="page" prefix=" "/>
+ </else-if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <group prefix=". " delimiter=". ">
+ <group>
+ <text term="volume" form="short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ <group>
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" prefix=" " suffix="." plural="true" strip-periods="true"/>
+ </group>
</group>
- </if>
- <else>
- <text suffix="." variable="edition" />
- </else>
- </choose>
- </if>
- </choose>
- </macro>
- <macro name="locators">
- <choose>
- <if type="article-journal">
- <text prefix=" " variable="volume" />
- <text prefix=", no. " variable="issue" />
- </if>
- <else-if type="book">
- <group delimiter=". " prefix=". ">
- <group>
- <text form="short" suffix=". " term="volume" text-case="capitalize-first" />
- <number form="numeric" variable="volume" />
- </group>
- <group>
- <number form="numeric" variable="number-of-volumes" />
- <text form="short" plural="true" prefix=" " suffix="." term="volume" />
- </group>
- </group>
- </else-if>
- </choose>
- </macro>
- <macro name="locators-chapter">
- <choose>
- <if type="chapter">
- <group prefix=", ">
- <text suffix=":" variable="volume" />
- <text variable="page" />
- </group>
- </if>
- </choose>
- </macro>
- <macro name="locators-article">
- <choose>
- <if type="article-newspaper">
- <group delimiter=", " prefix=", ">
- <group>
- <text suffix=" " variable="edition" />
- <text prefix=" " term="edition" />
- </group>
- <group>
- <text form="short" suffix=". " term="section" />
- <text variable="section" />
- </group>
- </group>
- </if>
- <else-if type="article-journal">
- <text prefix=": " variable="page" />
- </else-if>
- </choose>
- </macro>
- <macro name="point-locators">
- <group>
+ </else-if>
+ <else-if type="chapter paper-conference" match="any">
+ <choose>
+ <if variable="page" match="none">
+ <group prefix=". ">
+ <text term="volume" form="short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ </if>
+ </choose>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="locators-chapter">
<choose>
- <if locator="page" match="none">
- <label form="short" suffix=" " variable="locator" />
- </if>
+ <if type="chapter paper-conference" match="any">
+ <choose>
+ <if variable="page">
+ <group prefix=", ">
+ <text variable="volume" suffix=":"/>
+ <text variable="page"/>
+ </group>
+ </if>
+ </choose>
+ </if>
</choose>
- <text variable="locator" />
- </group>
- </macro>
- <macro name="container-prefix">
- <text term="in" text-case="capitalize-first" />
- </macro>
- <macro name="container-title">
- <choose>
- <if type="chapter">
- <text macro="container-prefix" suffix=" " />
- </if>
- </choose>
- <text font-style="italic" variable="container-title" />
- </macro>
- <macro name="publisher">
- <group delimiter=": ">
- <text variable="publisher-place" />
- <text variable="publisher" />
- </group>
- </macro>
- <macro name="date">
- <date variable="issued">
- <date-part name="year" />
- </date>
- </macro>
- <macro name="day-month">
- <date variable="issued">
- <date-part name="month" />
- <date-part name="day" prefix=" " />
- </date>
- </macro>
- <macro name="collection-title">
- <text variable="collection-title" />
- <text prefix=" " variable="collection-number" />
- </macro>
- <macro name="event">
- <group>
- <text suffix=" " term="presented at" />
- <text variable="event" />
- </group>
- </macro>
- <macro name="description">
- <group delimiter=". ">
- <text macro="interviewer" />
- <text text-case="capitalize-first" variable="medium" />
- </group>
- <choose>
- <if match="none" variable="title"> </if>
- <else-if type="thesis"> </else-if>
- <else>
- <text prefix=". " text-case="capitalize-first" variable="genre" />
- </else>
- </choose>
- </macro>
- <macro name="issue">
- <choose>
- <if type="article-journal">
- <text macro="day-month" prefix=" (" suffix=")" />
- </if>
- <else-if type="speech">
- <group delimiter=", " prefix=" ">
- <text macro="event" />
- <text macro="day-month" />
- <text variable="event-place" />
- </group>
- </else-if>
- <else-if match="any" type="article-newspaper article-magazine">
- <text macro="day-month" prefix=", " />
- </else-if>
- <else>
- <group delimiter=", " prefix=". ">
- <choose>
- <if type="thesis">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- </choose>
- <text macro="publisher" />
- <text macro="day-month" />
- </group>
- </else>
- </choose>
- </macro>
- <citation
- disambiguate-add-givenname="true"
- disambiguate-add-names="true"
- disambiguate-add-year-suffix="true"
- et-al-min="4"
- et-al-subsequent-min="4"
- et-al-subsequent-use-first="1"
- et-al-use-first="1">
- <layout delimiter="; " prefix="(" suffix=")">
- <group delimiter=", ">
- <group delimiter=" ">
- <text macro="contributors-short" />
- <text macro="date" />
- </group>
- <text macro="point-locators" />
+ </macro>
+ <macro name="locators-article">
+ <choose>
+ <if type="article-newspaper">
+ <group prefix=", " delimiter=", ">
+ <group>
+ <text variable="edition" suffix=" "/>
+ <text term="edition" prefix=" "/>
+ </group>
+ <group>
+ <text term="section" form="short" suffix=". " strip-periods="true"/>
+ <text variable="section"/>
+ </group>
+ </group>
+ </if>
+ <else-if type="article-journal">
+ <text variable="page" prefix=": "/>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="point-locators">
+ <choose>
+ <if variable="locator">
+ <choose>
+ <if locator="page" match="none">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song" match="any">
+ <choose>
+ <if variable="volume">
+ <group>
+ <text term="volume" form="short" text-case="lowercase" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ <label variable="locator" form="short" prefix=", " suffix=" "/>
+ </group>
+ </if>
+ <else>
+ <label variable="locator" form="short" suffix=" "/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <number variable="volume" form="numeric" suffix=":"/>
+ </else-if>
+ </choose>
+ <text variable="locator"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-prefix">
+ <text term="in" text-case="capitalize-first"/>
+ </macro>
+ <macro name="container-title">
+ <choose>
+ <if type="chapter paper-conference" match="any">
+ <text macro="container-prefix" suffix=" "/>
+ </if>
+ </choose>
+ <choose>
+ <if type="legal_case" match="none">
+ <text variable="container-title" font-style="italic"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="publisher">
+ <group delimiter=": ">
+ <text variable="publisher-place"/>
+ <text variable="publisher"/>
</group>
- </layout>
- </citation>
- <bibliography
- entry-spacing="0"
- et-al-min="11"
- et-al-use-first="7"
- hanging-indent="true"
- subsequent-author-substitute="---">
- <sort>
- <key macro="contributors" />
- <key variable="issued" />
- <key variable="title" />
- </sort>
- <layout suffix=".">
- <text macro="contributors" suffix=". " />
- <text macro="date" suffix=". " />
- <text macro="title" />
- <text macro="description" />
- <text macro="secondary-contributors" prefix=". " />
- <text macro="container-title" prefix=". " />
- <text macro="container-contributors" />
- <text macro="locators-chapter" />
- <text macro="edition" prefix=". " />
- <text macro="locators" />
- <text macro="collection-title" prefix=". " />
- <text macro="issue" />
- <text macro="locators-article" />
- <text macro="access" prefix=". " />
- </layout>
- </bibliography>
-</style>
+ </macro>
+ <macro name="date">
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </macro>
+ <macro name="day-month">
+ <date variable="issued">
+ <date-part name="month"/>
+ <date-part name="day" prefix=" "/>
+ </date>
+ </macro>
+ <macro name="collection-title">
+ <text variable="collection-title"/>
+ <text variable="collection-number" prefix=" "/>
+ </macro>
+ <macro name="event">
+ <group>
+ <text term="presented at" suffix=" "/>
+ <text variable="event"/>
+ </group>
+ </macro>
+ <macro name="description">
+ <choose>
+ <if type="interview">
+ <group delimiter=". ">
+ <text macro="interviewer"/>
+ <text variable="medium" text-case="capitalize-first"/>
+ </group>
+ </if>
+ <else>
+ <text variable="medium" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ <choose>
+ <if variable="title" match="none"/>
+ <else-if type="thesis"/>
+ <else>
+ <text variable="genre" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="issue">
+ <choose>
+ <if type="article-journal">
+ <text macro="day-month" prefix=" (" suffix=")"/>
+ </if>
+ <else-if type="legal_case">
+ <text variable="authority" prefix=". "/>
+ </else-if>
+ <else-if type="speech">
+ <group prefix=" " delimiter=", ">
+ <text macro="event"/>
+ <text macro="day-month"/>
+ <text variable="event-place"/>
+ </group>
+ </else-if>
+ <else-if type="article-newspaper article-magazine" match="any">
+ <text macro="day-month" prefix=", "/>
+ </else-if>
+ <else>
+ <group prefix=". " delimiter=", ">
+ <choose>
+ <if type="thesis">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ <text macro="publisher"/>
+ </group>
+ </else>
+ </choose>
+ </macro>
+ <citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="primary-name">
+ <layout prefix="(" suffix=")" delimiter="; ">
+ <group delimiter=", ">
+ <group delimiter=" ">
+ <text macro="contributors-short"/>
+ <text macro="date"/>
+ </group>
+ <text macro="point-locators"/>
+ </group>
+ </layout>
+ </citation>
+ <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="———" entry-spacing="0">
+ <sort>
+ <key macro="contributors"/>
+ <key variable="issued"/>
+ </sort>
+ <layout suffix=".">
+ <text macro="contributors" suffix=". "/>
+ <text macro="date" suffix=". "/>
+ <text macro="title"/>
+ <text macro="description"/>
+ <text macro="secondary-contributors" prefix=". "/>
+ <text macro="container-title" prefix=". "/>
+ <text macro="container-contributors"/>
+ <text macro="locators-chapter"/>
+ <text macro="edition" prefix=". "/>
+ <text macro="locators"/>
+ <text macro="collection-title" prefix=". "/>
+ <text macro="issue"/>
+ <text macro="locators-article"/>
+ <text macro="access" prefix=". "/>
+ </layout>
+ </bibliography>
+</style> \ No newline at end of file
diff --git a/dzslides/template.html b/dzslides/template.html
new file mode 100644
index 000000000..591664f30
--- /dev/null
+++ b/dzslides/template.html
@@ -0,0 +1,514 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<title>The Title Of Your Presentation</title>
+
+<!-- Your Slides -->
+<!-- One section is one slide -->
+
+<section>
+ <!-- This is the first slide -->
+ <h1>My Presentation</h1>
+ <footer>by John Doe</footer>
+</section>
+
+<section>
+ <h2>Part one</h2>
+</section>
+
+<section>
+ <h3>An incremental list</h3>
+ <ul class="incremental">
+ <li>Item 1
+ <li>Item 2
+ <li>Item 3
+ </ul>
+</section>
+
+<section>
+ <q>
+ Soothe us with sweet lies. Is that a cooking show? No! I want to
+ live! There are still too many things I don't own!
+ </q>
+</section>
+
+<section>
+ <h2>Part two</h2>
+</section>
+
+<section>
+ <h3>An image</h3>
+ <img src="http://placekitten.com/g/800/600">
+</section>
+
+<section>
+ <h3>A video</h3>
+ <video src="http://videos-cdn.mozilla.net/brand/Mozilla_Firefox_Manifesto_v0.2_640.webm" poster="http://www.mozilla.org/images/about/poster.jpg"></video>
+</section>
+
+<section>
+ <h2>End!</h2>
+</section>
+
+<!-- Your Style -->
+<!-- Define the style of your presentation -->
+
+<!-- Maybe a font from http://www.google.com/webfonts ? -->
+<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet'>
+
+<style>
+ html { background-color: black; }
+ body { background-color: white; }
+ /* A section is a slide. It's size is 800x600, and this will never change */
+ section {
+ /* The font from Google */
+ font-family: 'Oswald', arial, serif;
+ font-size: 40px;
+ }
+ h1, h2 {
+ margin-top: 200px;
+ text-align: center;
+ font-size: 80px;
+ }
+ h3 {
+ margin: 100px 0 50px 100px;
+ }
+
+ ul {
+ margin: 50px 200px;
+ }
+
+ q {
+ display: inline-block;
+ width: 700px;
+ height: 600px;
+ background-color: black;
+ color: white;
+ font-size: 60px;
+ padding: 50px;
+ }
+
+ img, video {
+ width: 800px;
+ height: 600px;
+ position: absolute;
+ top: 0;
+ background-color: black;
+ z-index: -1;
+ }
+
+ footer {
+ position: absolute;
+ bottom: 10px;
+ right: 20px;
+ }
+
+ /* Transition effect */
+ /* Feel free to change the transition effect for original
+ animations. See here:
+ https://developer.mozilla.org/en/CSS/CSS_transitions
+ How to use CSS3 Transitions: */
+ section {
+ -moz-transition: left 400ms linear 0s;
+ -webkit-transition: left 400ms linear 0s;
+ -ms-transition: left 400ms linear 0s;
+ transition: left 400ms linear 0s;
+ }
+
+ /* Before */
+ section { left: -150%; }
+ /* Now */
+ section[aria-selected] { left: 0; }
+ /* After */
+ section[aria-selected] ~ section { left: +150%; }
+
+ /* Incremental elements */
+
+ /* By default, visible */
+ .incremental > * { opacity: 1; }
+
+ /* The current item */
+ .incremental > *[aria-selected] { color: red; opacity: 1; }
+
+ /* The items to-be-selected */
+ .incremental > *[aria-selected] ~ * { opacity: 0.2; }
+
+</style>
+
+<!-- {{{{ dzslides core
+#
+#
+# __ __ __ . __ ___ __
+# | \ / /__` | | | \ |__ /__`
+# |__/ /_ .__/ |___ | |__/ |___ .__/ core :€
+#
+#
+# The following block of code is not supposed to be edited.
+# But if you want to change the behavior of these slides,
+# feel free to hack it!
+#
+-->
+
+<!-- Default Style -->
+<style>
+ * { margin: 0; padding: 0; }
+ details { display: none; }
+ body {
+ width: 800px; height: 600px;
+ margin-left: -400px; margin-top: -300px;
+ position: absolute; top: 50%; left: 50%;
+ overflow: hidden;
+ }
+ section {
+ position: absolute;
+ pointer-events: none;
+ width: 100%; height: 100%;
+ }
+ section[aria-selected] { pointer-events: auto; }
+ html { overflow: hidden; }
+ body { display: none; }
+ body.loaded { display: block; }
+ .incremental {visibility: hidden; }
+ .incremental[active] {visibility: visible; }
+</style>
+
+<script>
+ var Dz = {
+ remoteWindows: [],
+ idx: -1,
+ step: 0,
+ slides: null,
+ params: {
+ autoplay: "1"
+ }
+ };
+
+ Dz.init = function() {
+ document.body.className = "loaded";
+ this.slides = $$("body > section");
+ this.setupParams();
+ this.onhashchange();
+ this.setupTouchEvents();
+ this.onresize();
+ }
+
+ Dz.setupParams = function() {
+ var p = window.location.search.substr(1).split('&');
+ p.forEach(function(e, i, a) {
+ var keyVal = e.split('=');
+ Dz.params[keyVal[0]] = decodeURIComponent(keyVal[1]);
+ });
+ }
+
+ Dz.onkeydown = function(aEvent) {
+ // Don't intercept keyboard shortcuts
+ if (aEvent.altKey
+ || aEvent.ctrlKey
+ || aEvent.metaKey
+ || aEvent.shiftKey) {
+ return;
+ }
+ if ( aEvent.keyCode == 37 // left arrow
+ || aEvent.keyCode == 38 // up arrow
+ || aEvent.keyCode == 33 // page up
+ ) {
+ aEvent.preventDefault();
+ this.back();
+ }
+ if ( aEvent.keyCode == 39 // right arrow
+ || aEvent.keyCode == 40 // down arrow
+ || aEvent.keyCode == 34 // page down
+ ) {
+ aEvent.preventDefault();
+ this.forward();
+ }
+ if (aEvent.keyCode == 35) { // end
+ aEvent.preventDefault();
+ this.goEnd();
+ }
+ if (aEvent.keyCode == 36) { // home
+ aEvent.preventDefault();
+ this.goStart();
+ }
+ if (aEvent.keyCode == 32) { // space
+ aEvent.preventDefault();
+ this.toggleContent();
+ }
+ }
+
+ /* Touch Events */
+
+ Dz.setupTouchEvents = function() {
+ var orgX, newX;
+ var tracking = false;
+
+ var db = document.body;
+ db.addEventListener("touchstart", start.bind(this), false);
+ db.addEventListener("touchmove", move.bind(this), false);
+
+ function start(aEvent) {
+ aEvent.preventDefault();
+ tracking = true;
+ orgX = aEvent.changedTouches[0].pageX;
+ }
+
+ function move(aEvent) {
+ if (!tracking) return;
+ newX = aEvent.changedTouches[0].pageX;
+ if (orgX - newX > 100) {
+ tracking = false;
+ this.forward();
+ } else {
+ if (orgX - newX < -100) {
+ tracking = false;
+ this.back();
+ }
+ }
+ }
+ }
+
+ /* Adapt the size of the slides to the window */
+
+ Dz.onresize = function() {
+ var db = document.body;
+ var sx = db.clientWidth / window.innerWidth;
+ var sy = db.clientHeight / window.innerHeight;
+ var transform = "scale(" + (1/Math.max(sx, sy)) + ")";
+
+ db.style.MozTransform = transform;
+ db.style.WebkitTransform = transform;
+ db.style.OTransform = transform;
+ db.style.msTransform = transform;
+ db.style.transform = transform;
+ }
+
+
+ Dz.getDetails = function(aIdx) {
+ var s = $("section:nth-of-type(" + aIdx + ")");
+ var d = s.$("details");
+ return d ? d.innerHTML : "";
+ }
+
+ Dz.onmessage = function(aEvent) {
+ var argv = aEvent.data.split(" "), argc = argv.length;
+ argv.forEach(function(e, i, a) { a[i] = decodeURIComponent(e) });
+ var win = aEvent.source;
+ if (argv[0] === "REGISTER" && argc === 1) {
+ this.remoteWindows.push(win);
+ this.postMsg(win, "REGISTERED", document.title, this.slides.length);
+ this.postMsg(win, "CURSOR", this.idx + "." + this.step);
+ return;
+ }
+ if (argv[0] === "BACK" && argc === 1)
+ this.back();
+ if (argv[0] === "FORWARD" && argc === 1)
+ this.forward();
+ if (argv[0] === "START" && argc === 1)
+ this.goStart();
+ if (argv[0] === "END" && argc === 1)
+ this.goEnd();
+ if (argv[0] === "TOGGLE_CONTENT" && argc === 1)
+ this.toggleContent();
+ if (argv[0] === "SET_CURSOR" && argc === 2)
+ window.location.hash = "#" + argv[1];
+ if (argv[0] === "GET_CURSOR" && argc === 1)
+ this.postMsg(win, "CURSOR", this.idx + "." + this.step);
+ if (argv[0] === "GET_NOTES" && argc === 1)
+ this.postMsg(win, "NOTES", this.getDetails(this.idx));
+ }
+
+ Dz.toggleContent = function() {
+ // If a Video is present in this new slide, play it.
+ // If a Video is present in the previous slide, stop it.
+ var s = $("section[aria-selected]");
+ if (s) {
+ var video = s.$("video");
+ if (video) {
+ if (video.ended || video.paused) {
+ video.play();
+ } else {
+ video.pause();
+ }
+ }
+ }
+ }
+
+ Dz.setCursor = function(aIdx, aStep) {
+ // If the user change the slide number in the URL bar, jump
+ // to this slide.
+ aStep = (aStep != 0 && typeof aStep !== "undefined") ? "." + aStep : ".0";
+ window.location.hash = "#" + aIdx + aStep;
+ }
+
+ Dz.onhashchange = function() {
+ var cursor = window.location.hash.split("#"),
+ newidx = 1,
+ newstep = 0;
+ if (cursor.length == 2) {
+ newidx = ~~cursor[1].split(".")[0];
+ newstep = ~~cursor[1].split(".")[1];
+ if (newstep > Dz.slides[newidx - 1].$$('.incremental > *').length) {
+ newstep = 0;
+ newidx++;
+ }
+ }
+ if (newidx != this.idx) {
+ this.setSlide(newidx);
+ }
+ if (newstep != this.step) {
+ this.setIncremental(newstep);
+ }
+ for (var i = 0; i < this.remoteWindows.length; i++) {
+ this.postMsg(this.remoteWindows[i], "CURSOR", this.idx + "." + this.step);
+ }
+ }
+
+ Dz.back = function() {
+ if (this.idx == 1 && this.step == 0) {
+ return;
+ }
+ if (this.step == 0) {
+ this.setCursor(this.idx - 1,
+ this.slides[this.idx - 2].$$('.incremental > *').length);
+ } else {
+ this.setCursor(this.idx, this.step - 1);
+ }
+ }
+
+ Dz.forward = function() {
+ if (this.idx >= this.slides.length &&
+ this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
+ return;
+ }
+ if (this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
+ this.setCursor(this.idx + 1, 0);
+ } else {
+ this.setCursor(this.idx, this.step + 1);
+ }
+ }
+
+ Dz.goStart = function() {
+ this.setCursor(1, 0);
+ }
+
+ Dz.goEnd = function() {
+ var lastIdx = this.slides.length;
+ var lastStep = this.slides[lastIdx - 1].$$('.incremental > *').length;
+ this.setCursor(lastIdx, lastStep);
+ }
+
+ Dz.setSlide = function(aIdx) {
+ this.idx = aIdx;
+ var old = $("section[aria-selected]");
+ var next = $("section:nth-of-type("+ this.idx +")");
+ if (old) {
+ old.removeAttribute("aria-selected");
+ var video = old.$("video");
+ if (video) {
+ video.pause();
+ }
+ }
+ if (next) {
+ next.setAttribute("aria-selected", "true");
+ var video = next.$("video");
+ if (video && !!+this.params.autoplay) {
+ video.play();
+ }
+ } else {
+ // That should not happen
+ this.idx = -1;
+ // console.warn("Slide doesn't exist.");
+ }
+ }
+
+ Dz.setIncremental = function(aStep) {
+ this.step = aStep;
+ var old = this.slides[this.idx - 1].$('.incremental > *[aria-selected]');
+ if (old) {
+ old.removeAttribute('aria-selected');
+ }
+ var incrementals = this.slides[this.idx - 1].$$('.incremental');
+ if (this.step <= 0) {
+ incrementals.forEach(function(aNode) {
+ aNode.removeAttribute('active');
+ });
+ return;
+ }
+ var next = this.slides[this.idx - 1].$$('.incremental > *')[this.step - 1];
+ if (next) {
+ next.setAttribute('aria-selected', true);
+ next.parentNode.setAttribute('active', true);
+ var found = false;
+ incrementals.forEach(function(aNode) {
+ if (aNode != next.parentNode)
+ if (found)
+ aNode.removeAttribute('active');
+ else
+ aNode.setAttribute('active', true);
+ else
+ found = true;
+ });
+ } else {
+ setCursor(this.idx, 0);
+ }
+ return next;
+ }
+
+ Dz.postMsg = function(aWin, aMsg) { // [arg0, [arg1...]]
+ aMsg = [aMsg];
+ for (var i = 2; i < arguments.length; i++)
+ aMsg.push(encodeURIComponent(arguments[i]));
+ aWin.postMessage(aMsg.join(" "), "*");
+ }
+
+ window.onload = Dz.init.bind(Dz);
+ window.onkeydown = Dz.onkeydown.bind(Dz);
+ window.onresize = Dz.onresize.bind(Dz);
+ window.onhashchange = Dz.onhashchange.bind(Dz);
+ window.onmessage = Dz.onmessage.bind(Dz);
+</script>
+
+
+<script> // Helpers
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function (oThis) {
+
+ // closest thing possible to the ECMAScript 5 internal IsCallable
+ // function
+ if (typeof this !== "function")
+ throw new TypeError(
+ "Function.prototype.bind - what is trying to be fBound is not callable"
+ );
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply( this instanceof fNOP ? this : oThis || window,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+ }
+
+ var $ = (HTMLElement.prototype.$ = function(aQuery) {
+ return this.querySelector(aQuery);
+ }).bind(document);
+
+ var $$ = (HTMLElement.prototype.$$ = function(aQuery) {
+ return this.querySelectorAll(aQuery);
+ }).bind(document);
+
+ NodeList.prototype.forEach = function(fun) {
+ if (typeof fun !== "function") throw new TypeError();
+ for (var i = 0; i < this.length; i++) {
+ fun.call(this, this[i]);
+ }
+ }
+
+</script>
+<!-- vim: set fdm=marker: }}} -->
diff --git a/epub.css b/epub.css
index 1774066cc..6737f5cc7 100644
--- a/epub.css
+++ b/epub.css
@@ -9,3 +9,23 @@ h5 { text-align: center; }
h6 { text-align: center; }
h1.title { }
h2.author { }
+h3.date { }
+/* For source-code highlighting */
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
+ { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
+td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
+td.sourceCode { padding-left: 5px; }
+pre.sourceCode { }
+code.sourceCode span.kw { color: #007020; font-weight: bold; }
+code.sourceCode span.dt { color: #902000; }
+code.sourceCode span.dv { color: #40a070; }
+code.sourceCode span.bn { color: #40a070; }
+code.sourceCode span.fl { color: #40a070; }
+code.sourceCode span.ch { color: #4070a0; }
+code.sourceCode span.st { color: #4070a0; }
+code.sourceCode span.co { color: #60a0b0; font-style: italic; }
+code.sourceCode span.ot { color: #007020; }
+code.sourceCode span.al { color: red; font-weight: bold; }
+code.sourceCode span.fu { color: #06287e; }
+code.sourceCode span.re { }
+code.sourceCode span.er { color: red; font-weight: bold; }
diff --git a/man/man1/markdown2pdf.1 b/man/man1/markdown2pdf.1
deleted file mode 100644
index 20c566c8d..000000000
--- a/man/man1/markdown2pdf.1
+++ /dev/null
@@ -1,170 +0,0 @@
-.TH MARKDOWN2PDF 1 "January 29, 2011" "Pandoc User Manuals"
-.SH NAME
-.PP
-markdown2pdf - converts markdown-formatted text to PDF, using pdflatex
-.SH SYNOPSIS
-.PP
-markdown2pdf [\f[I]options\f[]] [\f[I]input-file\f[]]...
-.SH DESCRIPTION
-.PP
-\f[C]markdown2pdf\f[] converts \f[I]input-file\f[] (or text from
-standard input) from markdown-formatted plain text to PDF, using
-\f[C]pandoc\f[] and \f[C]pdflatex\f[].
-If no output filename is specified (using the \f[C]-o\f[] option), the
-name of the output file is derived from the input file; thus, for
-example, if the input file is \f[I]hello.txt\f[], the output file will
-be \f[I]hello.pdf\f[].
-If the input is read from STDIN and no output filename is specified, the
-output file will be named \f[I]stdin.pdf\f[].
-If multiple input files are specified, they will be concatenated before
-conversion, and the name of the output file will be derived from the
-first input file.
-.PP
-Input is assumed to be in the UTF-8 character encoding.
-If your local character encoding is not UTF-8, you should pipe input
-through \f[C]iconv\f[]:
-.IP
-.nf
-\f[C]
-iconv\ -t\ utf-8\ input.txt\ |\ markdown2pdf
-\f[]
-.fi
-.PP
-\f[C]markdown2pdf\f[] assumes that the \f[C]unicode\f[], \f[C]array\f[],
-\f[C]fancyvrb\f[], \f[C]graphicx\f[], and \f[C]ulem\f[] packages are in
-latex\[aq]s search path.
-If these packages are not included in your latex setup, they can be
-obtained from \f[C]http://ctan.org\f[].
-.SH OPTIONS
-.TP
-.B -o \f[I]FILE\f[], --output=\f[I]FILE\f[]
-Write output to \f[I]FILE\f[].
-.RS
-.RE
-.TP
-.B --strict
-Use strict markdown syntax, with no extensions or variants.
-.RS
-.RE
-.TP
-.B -N, --number-sections
-Number section headings in LaTeX output.
-(Default is not to number them.)
-.RS
-.RE
-.TP
-.B --listings
-Use listings package for LaTeX code blocks
-.RS
-.RE
-.TP
-.B --template=\f[I]FILE\f[]
-Use \f[I]FILE\f[] as a custom template for the generated document.
-Implies \f[C]-s\f[].
-See the section TEMPLATES in \f[C]pandoc\f[](1) for information about
-template syntax.
-Use \f[C]pandoc\ -D\ latex\f[] to print the default LaTeX template.
-.RS
-.RE
-.TP
-.B -V KEY=VAL, --variable=\f[I]KEY:VAL\f[]
-Set the template variable KEY to the value VAL when rendering the
-document in standalone mode.
-Use this to set the font size when using the default LaTeX template:
-\f[C]-V\ fontsize=12pt\f[].
-.RS
-.RE
-.TP
-.B -H \f[I]FILE\f[], --include-in-header=\f[I]FILE\f[]
-Include (LaTeX) contents of \f[I]FILE\f[] at the end of the header.
-Implies \f[C]-s\f[].
-.RS
-.RE
-.TP
-.B -B \f[I]FILE\f[], --include-before-body=\f[I]FILE\f[]
-Include (LaTeX) contents of \f[I]FILE\f[] at the beginning of the
-document body.
-.RS
-.RE
-.TP
-.B -A \f[I]FILE\f[], --include-after-body=\f[I]FILE\f[]
-Include (LaTeX) contents of \f[I]FILE\f[] at the end of the document
-body.
-.RS
-.RE
-.TP
-.B --bibliography=\f[I]FILE\f[]
-Specify bibliography database to be used in resolving citations.
-The database type will be determined from the extension of
-\f[I]FILE\f[], which may be \f[C].xml\f[] (MODS format), \f[C].bib\f[]
-(BibTeX format), or \f[C].json\f[] (citeproc JSON).
-.RS
-.RE
-.TP
-.B --csl=\f[I]FILE\f[]
-Specify CSL style to be used in formatting citations and the
-bibliography.
-If \f[I]FILE\f[] is not found, pandoc will look for it in
-.RS
-.IP
-.nf
-\f[C]
-$HOME/.csl
-\f[]
-.fi
-.PP
-in unix and
-.IP
-.nf
-\f[C]
-C:\\Documents\ And\ Settings\\USERNAME\\Application\ Data\\csl
-\f[]
-.fi
-.PP
-in Windows.
-If the \f[C]--csl\f[] option is not specified, pandoc will use a default
-style: either \f[C]default.csl\f[] in the user data directory (see
-\f[C]--data-dir\f[]), or, if that is not present, the Chicago
-author-date style.
-.RE
-.TP
-.B --data-dir\f[I]=DIRECTORY\f[]
-Specify the user data directory to search for pandoc data files.
-If this option is not specified, the default user data directory will be
-used:
-.RS
-.IP
-.nf
-\f[C]
-$HOME/.pandoc
-\f[]
-.fi
-.PP
-in unix and
-.IP
-.nf
-\f[C]
-C:\\Documents\ And\ Settings\\USERNAME\\Application\ Data\\pandoc
-\f[]
-.fi
-.PP
-in Windows.
-A \f[C]reference.odt\f[], \f[C]epub.css\f[], \f[C]templates\f[]
-directory, or \f[C]s5\f[] directory placed in this directory will
-override pandoc\[aq]s normal defaults.
-.RE
-.TP
-.B --xetex
-Use xelatex instead of pdflatex to create the PDF.
-.RS
-.RE
-.TP
-.B --luatex
-Use lualatex instead of pdflatex to create the PDF.
-.RS
-.RE
-.SH SEE ALSO
-.PP
-\f[C]pandoc\f[](1), \f[C]pdflatex\f[](1)
-.SH AUTHORS
-John MacFarlane, Paulo Tanimoto, and Recai Oktas.
diff --git a/man/man1/markdown2pdf.1.md b/man/man1/markdown2pdf.1.md
deleted file mode 100644
index 8b8da6880..000000000
--- a/man/man1/markdown2pdf.1.md
+++ /dev/null
@@ -1,120 +0,0 @@
-% MARKDOWN2PDF(1) Pandoc User Manuals
-% John MacFarlane, Paulo Tanimoto, and Recai Oktas
-% January 29, 2011
-
-# NAME
-
-markdown2pdf - converts markdown-formatted text to PDF, using pdflatex
-
-# SYNOPSIS
-
-markdown2pdf [*options*] [*input-file*]...
-
-# DESCRIPTION
-
-`markdown2pdf` converts *input-file* (or text from standard
-input) from markdown-formatted plain text to PDF, using `pandoc`
-and `pdflatex`. If no output filename is specified (using the `-o`
-option), the name of the output file is derived from the input file;
-thus, for example, if the input file is *hello.txt*, the output file
-will be *hello.pdf*. If the input is read from STDIN and no output
-filename is specified, the output file will be named *stdin.pdf*. If
-multiple input files are specified, they will be concatenated before
-conversion, and the name of the output file will be derived from the
-first input file.
-
-Input is assumed to be in the UTF-8 character encoding. If your
-local character encoding is not UTF-8, you should pipe input
-through `iconv`:
-
- iconv -t utf-8 input.txt | markdown2pdf
-
-`markdown2pdf` assumes that the `unicode`, `array`, `fancyvrb`,
-`graphicx`, and `ulem` packages are in latex's search path. If these
-packages are not included in your latex setup, they can be obtained from
-<http://ctan.org>.
-
-# OPTIONS
-
--o *FILE*, \--output=*FILE*
-: Write output to *FILE*.
-
-\--strict
-: Use strict markdown syntax, with no extensions or variants.
-
--N, \--number-sections
-: Number section headings in LaTeX output. (Default is not to number them.)
-
-\--listings
-: Use listings package for LaTeX code blocks
-
-\--template=*FILE*
-: Use *FILE* as a custom template for the generated document. Implies
- `-s`. See the section TEMPLATES in `pandoc`(1) for information about
- template syntax. Use `pandoc -D latex` to print the default LaTeX
- template.
-
--V KEY=VAL, \--variable=*KEY:VAL*
-: Set the template variable KEY to the value VAL when rendering the
- document in standalone mode. Use this to set the font size when
- using the default LaTeX template: `-V fontsize=12pt`.
-
--H *FILE*, \--include-in-header=*FILE*
-: Include (LaTeX) contents of *FILE* at the end of the header. Implies
- `-s`.
-
--B *FILE*, \--include-before-body=*FILE*
-: Include (LaTeX) contents of *FILE* at the beginning of the document body.
-
--A *FILE*, \--include-after-body=*FILE*
-: Include (LaTeX) contents of *FILE* at the end of the document body.
-
-\--bibliography=*FILE*
-: Specify bibliography database to be used in resolving
- citations. The database type will be determined from the
- extension of *FILE*, which may be `.xml` (MODS format),
- `.bib` (BibTeX format), or `.json` (citeproc JSON).
-
-\--csl=*FILE*
-: Specify [CSL] style to be used in formatting citations and
- the bibliography. If *FILE* is not found, pandoc will look
- for it in
-
- $HOME/.csl
-
- in unix and
-
- C:\Documents And Settings\USERNAME\Application Data\csl
-
- in Windows. If the `--csl` option is not specified, pandoc
- will use a default style: either `default.csl` in the
- user data directory (see `--data-dir`), or, if that is
- not present, the Chicago author-date style.
-
-\--data-dir*=DIRECTORY*
-: Specify the user data directory to search for pandoc data files.
- If this option is not specified, the default user data directory
- will be used:
-
- $HOME/.pandoc
-
- in unix and
-
- C:\Documents And Settings\USERNAME\Application Data\pandoc
-
- in Windows. A `reference.odt`, `epub.css`, `templates` directory,
- or `s5` directory placed in this directory will override pandoc's
- normal defaults.
-
-\--xetex
-: Use xelatex instead of pdflatex to create the PDF.
-
-\--luatex
-: Use lualatex instead of pdflatex to create the PDF.
-
-# SEE ALSO
-
-`pandoc`(1), `pdflatex`(1)
-
-[CSL]: CitationStyles.org
-
diff --git a/man/man1/pandoc.1 b/man/man1/pandoc.1
index 702e684ed..d7f3227a3 100644
--- a/man/man1/pandoc.1
+++ b/man/man1/pandoc.1
@@ -1,4 +1,4 @@
-.TH PANDOC 1 "July 30, 2011" "Pandoc"
+.TH PANDOC 1 "January 27, 2012" "Pandoc"
.SH NAME
pandoc - general markup converter
.SH SYNOPSIS
@@ -10,9 +10,11 @@ Pandoc is a Haskell library for converting from one markup format to
another, and a command-line tool that uses this library.
It can read markdown and (subsets of) Textile, reStructuredText, HTML,
and LaTeX; and it can write plain text, markdown, reStructuredText,
-HTML, LaTeX, ConTeXt, RTF, DocBook XML, OpenDocument XML, ODT, GNU
-Texinfo, MediaWiki markup, EPUB, Textile, groff man pages, Emacs
-Org-Mode, and Slidy or S5 HTML slide shows.
+XHTML, HTML 5, LaTeX (including beamer slide shows), ConTeXt, RTF,
+DocBook XML, OpenDocument XML, ODT, Word docx, GNU Texinfo, MediaWiki
+markup, EPUB, Textile, groff man pages, Emacs Org-Mode, AsciiDoc, and
+Slidy, DZSlides, or S5 HTML slide shows.
+It can also produce PDF output on systems where LaTeX is installed.
.PP
Pandoc\[aq]s enhanced version of markdown includes syntax for footnotes,
tables, flexible ordered lists, definition lists, delimited code blocks,
@@ -29,15 +31,15 @@ native representation of the document, and a set of writers, which
convert this native representation into a target format.
Thus, adding an input or output format requires only adding a reader or
writer.
-.SS Using Pandoc
+.SS Using \f[C]pandoc\f[]
.PP
If no \f[I]input-file\f[] is specified, input is read from
\f[I]stdin\f[].
Otherwise, the \f[I]input-files\f[] are concatenated (with a blank line
between each) and used as input.
Output goes to \f[I]stdout\f[] by default (though output to
-\f[I]stdout\f[] is disabled for the \f[C]odt\f[] and \f[C]epub\f[]
-output formats).
+\f[I]stdout\f[] is disabled for the \f[C]odt\f[], \f[C]docx\f[], and
+\f[C]epub\f[] output formats).
For output to a file, use the \f[C]-o\f[] option:
.IP
.nf
@@ -116,7 +118,45 @@ output through \f[C]iconv\f[]:
iconv\ -t\ utf-8\ input.txt\ |\ pandoc\ |\ iconv\ -f\ utf-8
\f[]
.fi
+.SS Creating a PDF
+.PP
+Earlier versions of pandoc came with a program, \f[C]markdown2pdf\f[],
+that used pandoc and pdflatex to produce a PDF.
+This is no longer needed, since \f[C]pandoc\f[] can now produce
+\f[C]pdf\f[] output itself.
+To produce a PDF, simply specify an output file with a \f[C].pdf\f[]
+extension.
+Pandoc will create a latex file and use pdflatex (or another engine, see
+\f[C]--latex-engine\f[]) to convert it to PDF:
+.IP
+.nf
+\f[C]
+pandoc\ test.txt\ -o\ test.pdf
+\f[]
+.fi
+.PP
+Production of a PDF requires that a LaTeX engine be installed (see
+\f[C]--latex-engine\f[], below), and assumes that the following LaTeX
+packages are available: \f[C]amssymb\f[], \f[C]amsmath\f[],
+\f[C]ifxetex\f[], \f[C]ifluatex\f[], \f[C]listings\f[] (if the
+\f[C]--listings\f[] option is used), \f[C]fancyvrb\f[],
+\f[C]enumerate\f[], \f[C]ctable\f[], \f[C]url\f[], \f[C]graphicx\f[],
+\f[C]hyperref\f[], \f[C]ulem\f[], \f[C]babel\f[] (if the \f[C]lang\f[]
+variable is set), \f[C]fontspec\f[] (if \f[C]xelatex\f[] or
+\f[C]lualatex\f[] is used as the LaTeX engine), \f[C]xltxtra\f[] and
+\f[C]xunicode\f[] (if \f[C]xelatex\f[] is used).
+.SS \f[C]hsmarkdown\f[]
+.PP
+A user who wants a drop-in replacement for \f[C]Markdown.pl\f[] may
+create a symbolic link to the \f[C]pandoc\f[] executable called
+\f[C]hsmarkdown\f[].
+When invoked under the name \f[C]hsmarkdown\f[], \f[C]pandoc\f[] will
+behave as if the \f[C]--strict\f[] flag had been selected, and no
+command-line options will be recognized.
+However, this approach does not work under Cygwin, due to problems with
+its simulation of symbolic links.
.SH OPTIONS
+.SS General options
.TP
.B \f[C]-f\f[] \f[I]FORMAT\f[], \f[C]-r\f[] \f[I]FORMAT\f[],
\f[C]--from=\f[]\f[I]FORMAT\f[], \f[C]--read=\f[]\f[I]FORMAT\f[]
@@ -137,46 +177,72 @@ Specify output format.
\f[I]FORMAT\f[] can be \f[C]native\f[] (native Haskell), \f[C]json\f[]
(JSON version of native AST), \f[C]plain\f[] (plain text),
\f[C]markdown\f[] (markdown), \f[C]rst\f[] (reStructuredText),
-\f[C]html\f[] (HTML), \f[C]latex\f[] (LaTeX), \f[C]context\f[]
+\f[C]html\f[] (XHTML 1), \f[C]html5\f[] (HTML 5), \f[C]latex\f[]
+(LaTeX), \f[C]beamer\f[] (LaTeX beamer slide show), \f[C]context\f[]
(ConTeXt), \f[C]man\f[] (groff man), \f[C]mediawiki\f[] (MediaWiki
markup), \f[C]textile\f[] (Textile), \f[C]org\f[] (Emacs Org-Mode),
\f[C]texinfo\f[] (GNU Texinfo), \f[C]docbook\f[] (DocBook XML),
\f[C]opendocument\f[] (OpenDocument XML), \f[C]odt\f[] (OpenOffice text
-document), \f[C]epub\f[] (EPUB book), \f[C]slidy\f[] (Slidy HTML and
-javascript slide show), \f[C]s5\f[] (S5 HTML and javascript slide show),
-or \f[C]rtf\f[] (rich text format).
+document), \f[C]docx\f[] (Word docx), \f[C]epub\f[] (EPUB book),
+\f[C]asciidoc\f[] (AsciiDoc), \f[C]slidy\f[] (Slidy HTML and javascript
+slide show), \f[C]dzslides\f[] (HTML5 + javascript slide show),
+\f[C]s5\f[] (S5 HTML and javascript slide show), or \f[C]rtf\f[] (rich
+text format).
Note that \f[C]odt\f[] and \f[C]epub\f[] output will not be directed to
\f[I]stdout\f[]; an output filename must be specified using the
\f[C]-o/--output\f[] option.
If \f[C]+lhs\f[] is appended to \f[C]markdown\f[], \f[C]rst\f[],
-\f[C]latex\f[], or \f[C]html\f[], the output will be rendered as
-literate Haskell source: see Literate Haskell support, below.
-.RS
-.RE
-.TP
-.B \f[C]-s\f[], \f[C]--standalone\f[]
-Produce output with an appropriate header and footer (e.g.
-a standalone HTML, LaTeX, or RTF file, not a fragment).
+\f[C]latex\f[], \f[C]html\f[], or \f[C]html5\f[], the output will be
+rendered as literate Haskell source: see Literate Haskell support,
+below.
.RS
.RE
.TP
.B \f[C]-o\f[] \f[I]FILE\f[], \f[C]--output=\f[]\f[I]FILE\f[]
Write output to \f[I]FILE\f[] instead of \f[I]stdout\f[].
If \f[I]FILE\f[] is \f[C]-\f[], output will go to \f[I]stdout\f[].
-(Exception: if the output format is \f[C]odt\f[] or \f[C]epub\f[],
-output to stdout is disabled.)
+(Exception: if the output format is \f[C]odt\f[], \f[C]docx\f[], or
+\f[C]epub\f[], output to stdout is disabled.)
.RS
.RE
.TP
-.B \f[C]-p\f[], \f[C]--preserve-tabs\f[]
-Preserve tabs instead of converting them to spaces (the default).
+.B \f[C]--data-dir=\f[]\f[I]DIRECTORY\f[]
+Specify the user data directory to search for pandoc data files.
+If this option is not specified, the default user data directory will be
+used:
+.RS
+.IP
+.nf
+\f[C]
+$HOME/.pandoc
+\f[]
+.fi
+.PP
+in unix and
+.IP
+.nf
+\f[C]
+C:\\Documents\ And\ Settings\\USERNAME\\Application\ Data\\pandoc
+\f[]
+.fi
+.PP
+in Windows.
+A \f[C]reference.odt\f[], \f[C]reference.docx\f[], \f[C]default.csl\f[],
+\f[C]epub.css\f[], \f[C]templates\f[], \f[C]slidy\f[], or \f[C]s5\f[]
+directory placed in this directory will override pandoc\[aq]s normal
+defaults.
+.RE
+.TP
+.B \f[C]-v\f[], \f[C]--version\f[]
+Print version.
.RS
.RE
.TP
-.B \f[C]--tab-stop=\f[]\f[I]NUMBER\f[]
-Specify the number of spaces per tab (default is 4).
+.B \f[C]-h\f[], \f[C]--help\f[]
+Show usage message.
.RS
.RE
+.SS Reader options
.TP
.B \f[C]--strict\f[]
Use strict markdown syntax, with no pandoc extensions or variants.
@@ -186,27 +252,13 @@ definition lists or strikeout text) will be parsed as raw HTML.
.RS
.RE
.TP
-.B \f[C]--normalize\f[]
-Normalize the document after reading: merge adjacent \f[C]Str\f[] or
-\f[C]Emph\f[] elements, for example, and remove repeated
-\f[C]Space\f[]s.
-.RS
-.RE
-.TP
-.B \f[C]--reference-links\f[]
-Use reference-style links, rather than inline links, in writing markdown
-or reStructuredText.
-By default inline links are used.
-.RS
-.RE
-.TP
.B \f[C]-R\f[], \f[C]--parse-raw\f[]
Parse untranslatable HTML codes and LaTeX environments as raw HTML or
LaTeX, instead of ignoring them.
Affects only HTML and LaTeX input.
-Raw HTML can be printed in markdown, reStructuredText, HTML, Slidy, and
-S5 output; raw LaTeX can be printed in markdown, reStructuredText,
-LaTeX, and ConTeXt output.
+Raw HTML can be printed in markdown, reStructuredText, HTML, Slidy,
+DZSlides, and S5 output; raw LaTeX can be printed in markdown,
+reStructuredText, LaTeX, and ConTeXt output.
The default is for the readers to omit untranslatable HTML codes and
LaTeX environments.
(The LaTeX reader does pass through untranslatable LaTeX
@@ -216,8 +268,8 @@ LaTeX environments.
.TP
.B \f[C]-S\f[], \f[C]--smart\f[]
Produce typographically correct output, converting straight quotes to
-curly quotes, \f[C]---\f[] and \f[C]--\f[] to dashes, ande \f[C]...\f[]
-to ellipses.
+curly quotes, \f[C]---\f[] to em-dashes, \f[C]--\f[] to en-dashes, and
+\f[C]...\f[] to ellipses.
Nonbreaking spaces are inserted after certain abbreviations, such as
"Mr." (Note: This option is significant only when the input format is
\f[C]markdown\f[] or \f[C]textile\f[].
@@ -226,108 +278,79 @@ or the output format is \f[C]latex\f[] or \f[C]context\f[].)
.RS
.RE
.TP
-.B \f[C]-5\f[], \f[C]--html5\f[]
-Produce HTML5 instead of HTML4.
-This option has no effect for writers other than \f[C]html\f[].
-.RS
-.RE
-.TP
-.B \f[C]-m\f[] [\f[I]URL\f[]], \f[C]--latexmathml\f[][=\f[I]URL\f[]]
-Use the LaTeXMathML script to display embedded TeX math in HTML output.
-To insert a link to a local copy of the \f[C]LaTeXMathML.js\f[] script,
-provide a \f[I]URL\f[].
-If no \f[I]URL\f[] is provided, the contents of the script will be
-inserted directly into the HTML header, preserving portability at the
-price of efficiency.
-If you plan to use math on several pages, it is much better to link to a
-copy of the script, so it can be cached.
-.RS
-.RE
-.TP
-.B \f[C]--mathml\f[][=\f[I]URL\f[]]
-Convert TeX math to MathML.
-In standalone mode, a small javascript (or a link to such a script if a
-\f[I]URL\f[] is supplied) will be inserted that allows the MathML to be
-viewed on some browsers.
-.RS
-.RE
-.TP
-.B \f[C]--jsmath\f[][=\f[I]URL\f[]]
-Use jsMath to display embedded TeX math in HTML output.
-The \f[I]URL\f[] should point to the jsMath load script (e.g.
-\f[C]jsMath/easy/load.js\f[]); if provided, it will be linked to in the
-header of standalone HTML documents.
-If a \f[I]URL\f[] is not provided, no link to the jsMath load script
-will be inserted; it is then up to the author to provide such a link in
-the HTML template.
-.RS
-.RE
-.TP
-.B \f[C]--mathjax\f[][=\f[I]URL\f[]]
-Use MathJax to display embedded TeX math in HTML output.
-The \f[I]URL\f[] should point to the \f[C]MathJax.js\f[] load script.
-If a \f[I]URL\f[] is not provided, a link to the MathJax CDN will be
-inserted.
+.B \f[C]--old-dashes\f[]
+Selects the pandoc <= 1.8.2.1 behavior for parsing smart dashes:
+\f[C]-\f[] before a numeral is an en-dash, and \f[C]--\f[] is an
+em-dash.
+This option is selected automatically for \f[C]textile\f[] input.
.RS
.RE
.TP
-.B \f[C]--gladtex\f[]
-Enclose TeX math in \f[C]<eq>\f[] tags in HTML output.
-These can then be processed by gladTeX to produce links to images of the
-typeset formulas.
+.B \f[C]--base-header-level=\f[]\f[I]NUMBER\f[]
+Specify the base level for headers (defaults to 1).
.RS
.RE
.TP
-.B \f[C]--mimetex\f[][=\f[I]URL\f[]]
-Render TeX math using the mimeTeX CGI script.
-If \f[I]URL\f[] is not specified, it is assumed that the script is at
-\f[C]/cgi-bin/mimetex.cgi\f[].
+.B \f[C]--indented-code-classes=\f[]\f[I]CLASSES\f[]
+Specify classes to use for indented code blocks--for example,
+\f[C]perl,numberLines\f[] or \f[C]haskell\f[].
+Multiple classes may be separated by spaces or commas.
.RS
.RE
.TP
-.B \f[C]--webtex\f[][=\f[I]URL\f[]]
-Render TeX formulas using an external script that converts TeX formulas
-to images.
-The formula will be concatenated with the URL provided.
-If \f[I]URL\f[] is not specified, the Google Chart API will be used.
+.B \f[C]--normalize\f[]
+Normalize the document after reading: merge adjacent \f[C]Str\f[] or
+\f[C]Emph\f[] elements, for example, and remove repeated
+\f[C]Space\f[]s.
.RS
.RE
.TP
-.B \f[C]-i\f[], \f[C]--incremental\f[]
-Make list items in Slidy or S5 display incrementally (one by one).
-The default is for lists to be displayed all at once.
+.B \f[C]-p\f[], \f[C]--preserve-tabs\f[]
+Preserve tabs instead of converting them to spaces (the default).
.RS
.RE
.TP
-.B \f[C]--offline\f[]
-Include all the CSS and javascript needed for a Slidy or S5 slide show
-in the output, so that the slide show will work even when no internet
-connection is available.
+.B \f[C]--tab-stop=\f[]\f[I]NUMBER\f[]
+Specify the number of spaces per tab (default is 4).
.RS
.RE
+.SS General writer options
.TP
-.B \f[C]--chapters\f[]
-Treat top-level headers as chapters in LaTeX, ConTeXt, and DocBook
-output.
+.B \f[C]-s\f[], \f[C]--standalone\f[]
+Produce output with an appropriate header and footer (e.g.
+a standalone HTML, LaTeX, or RTF file, not a fragment).
+This option is set automatically for \f[C]pdf\f[], \f[C]epub\f[],
+\f[C]docx\f[], and \f[C]odt\f[] output.
.RS
.RE
.TP
-.B \f[C]-N\f[], \f[C]--number-sections\f[]
-Number section headings in LaTeX, ConTeXt, or HTML output.
-By default, sections are not numbered.
+.B \f[C]--template=\f[]\f[I]FILE\f[]
+Use \f[I]FILE\f[] as a custom template for the generated document.
+Implies \f[C]--standalone\f[].
+See Templates below for a description of template syntax.
+If no extension is specified, an extension corresponding to the writer
+will be added, so that \f[C]--template=special\f[] looks for
+\f[C]special.html\f[] for HTML output.
+If the template is not found, pandoc will search for it in the user data
+directory (see \f[C]--data-dir\f[]).
+If this option is not used, a default template appropriate for the
+output format will be used (see \f[C]-D/--print-default-template\f[]).
.RS
.RE
.TP
-.B \f[C]--listings\f[]
-Use listings package for LaTeX code blocks
+.B \f[C]-V\f[] \f[I]KEY=VAL\f[], \f[C]--variable=\f[]\f[I]KEY:VAL\f[]
+Set the template variable \f[I]KEY\f[] to the value \f[I]VAL\f[] when
+rendering the document in standalone mode.
+This is generally only useful when the \f[C]--template\f[] option is
+used to specify a custom template, since pandoc automatically sets the
+variables used in the default templates.
.RS
.RE
.TP
-.B \f[C]--section-divs\f[]
-Wrap sections in \f[C]<div>\f[] tags (or \f[C]<section>\f[] tags in
-HTML5), and attach identifiers to the enclosing \f[C]<div>\f[] (or
-\f[C]<section>\f[]) rather than the header itself.
-See Section identifiers, below.
+.B \f[C]-D\f[] \f[I]FORMAT\f[],
+\f[C]--print-default-template=\f[]\f[I]FORMAT\f[]
+Print the default template for an output \f[I]FORMAT\f[].
+(See \f[C]-t\f[] for a list of possible \f[I]FORMAT\f[]s.)
.RS
.RE
.TP
@@ -342,40 +365,6 @@ Specify length of lines in characters (for text wrapping).
.RS
.RE
.TP
-.B \f[C]--ascii\f[]
-Use only ascii characters in output.
-Currently supported only for HTML output (which uses numerical entities
-instead of UTF-8 when this option is selected).
-.RS
-.RE
-.TP
-.B \f[C]--email-obfuscation=\f[]\f[I]none|javascript|references\f[]
-Specify a method for obfuscating \f[C]mailto:\f[] links in HTML
-documents.
-\f[I]none\f[] leaves \f[C]mailto:\f[] links as they are.
-\f[I]javascript\f[] obfuscates them using javascript.
-\f[I]references\f[] obfuscates them by printing their letters as decimal
-or hexadecimal character references.
-If \f[C]--strict\f[] is specified, \f[I]references\f[] is used
-regardless of the presence of this option.
-.RS
-.RE
-.TP
-.B \f[C]--id-prefix\f[]=\f[I]STRING\f[]
-Specify a prefix to be added to all automatically generated identifiers
-in HTML output.
-This is useful for preventing duplicate identifiers when generating
-fragments to be included in other pages.
-.RS
-.RE
-.TP
-.B \f[C]--indented-code-classes=\f[]\f[I]CLASSES\f[]
-Specify classes to use for indented code blocks--for example,
-\f[C]perl,numberLines\f[] or \f[C]haskell\f[].
-Multiple classes may be separated by spaces or commas.
-.RS
-.RE
-.TP
.B \f[C]--toc\f[], \f[C]--table-of-contents\f[]
Include an automatically generated table of contents (or, in the case of
\f[C]latex\f[], \f[C]context\f[], and \f[C]rst\f[], an instruction to
@@ -385,36 +374,17 @@ This option has no effect on \f[C]man\f[], \f[C]docbook\f[],
.RS
.RE
.TP
-.B \f[C]--base-header-level=\f[]\f[I]NUMBER\f[]
-Specify the base level for headers (defaults to 1).
+.B \f[C]--no-highlight\f[]
+Disables syntax highlighting for code blocks and inlines, even when a
+language attribute is given.
.RS
.RE
.TP
-.B \f[C]--template=\f[]\f[I]FILE\f[]
-Use \f[I]FILE\f[] as a custom template for the generated document.
-Implies \f[C]--standalone\f[].
-See Templates below for a description of template syntax.
-If no extension is specified, an extension corresponding to the writer
-will be added, so that \f[C]--template=special\f[] looks for
-\f[C]special.html\f[] for HTML output.
-If the template is not found, pandoc will search for it in the user data
-directory (see \f[C]--data-dir\f[]).
-If this option is not used, a default template appropriate for the
-output format will be used (see \f[C]-D/--print-default-template\f[]).
-.RS
-.RE
-.TP
-.B \f[C]-V\f[] \f[I]KEY=VAL\f[], \f[C]--variable=\f[]\f[I]KEY:VAL\f[]
-Set the template variable \f[I]KEY\f[] to the value \f[I]VAL\f[] when
-rendering the document in standalone mode.
-This is generally only useful when the \f[C]--template\f[] option is
-used to specify a custom template, since pandoc automatically sets the
-variables used in the default templates.
-.RS
-.RE
-.TP
-.B \f[C]-c\f[] \f[I]URL\f[], \f[C]--css=\f[]\f[I]URL\f[]
-Link to a CSS style sheet.
+.B \f[C]--highlight-style\f[]=\f[I]STYLE\f[]
+Specifies the coloring style to be used in highlighted source code.
+Options are \f[C]pygments\f[] (the default), \f[C]kate\f[],
+\f[C]monochrome\f[], \f[C]espresso\f[], \f[C]haddock\f[], and
+\f[C]tango\f[].
.RS
.RE
.TP
@@ -453,6 +423,137 @@ They will be included in the order specified.
Implies \f[C]--standalone\f[].
.RS
.RE
+.SS Options affecting specific writers
+.TP
+.B \f[C]--self-contained\f[]
+Produce a standalone HTML file with no external dependencies, using
+\f[C]data:\f[] URIs to incorporate the contents of linked scripts,
+stylesheets, images, and videos.
+The resulting file should be "self-contained," in the sense that it
+needs no external files and no net access to be displayed properly by a
+browser.
+This option works only with HTML output formats, including
+\f[C]html\f[], \f[C]html5\f[], \f[C]html+lhs\f[], \f[C]html5+lhs\f[],
+\f[C]s5\f[], \f[C]slidy\f[], and \f[C]dzslides\f[].
+Scripts, images, and stylesheets at absolute URLs will be downloaded;
+those at relative URLs will be sought first relative to the working
+directory, then relative to the user data directory (see
+\f[C]--data-dir\f[]), and finally relative to pandoc\[aq]s default data
+directory.
+.RS
+.RE
+.TP
+.B \f[C]--offline\f[]
+Deprecated synonym for \f[C]--self-contained\f[].
+.RS
+.RE
+.TP
+.B \f[C]-5\f[], \f[C]--html5\f[]
+Produce HTML5 instead of HTML4.
+This option has no effect for writers other than \f[C]html\f[].
+(\f[I]Deprecated:\f[] Use the \f[C]html5\f[] output format instead.)
+.RS
+.RE
+.TP
+.B \f[C]--ascii\f[]
+Use only ascii characters in output.
+Currently supported only for HTML output (which uses numerical entities
+instead of UTF-8 when this option is selected).
+.RS
+.RE
+.TP
+.B \f[C]--reference-links\f[]
+Use reference-style links, rather than inline links, in writing markdown
+or reStructuredText.
+By default inline links are used.
+.RS
+.RE
+.TP
+.B \f[C]--atx-headers\f[]
+Use ATX style headers in markdown output.
+The default is to use setext-style headers for levels 1-2, and then ATX
+headers.
+.RS
+.RE
+.TP
+.B \f[C]--chapters\f[]
+Treat top-level headers as chapters in LaTeX, ConTeXt, and DocBook
+output.
+When the LaTeX template uses the report, book, or memoir class, this
+option is implied.
+If \f[C]--beamer\f[] is used, top-level headers will become
+\f[C]\\part{..}\f[].
+.RS
+.RE
+.TP
+.B \f[C]-N\f[], \f[C]--number-sections\f[]
+Number section headings in LaTeX, ConTeXt, or HTML output.
+By default, sections are not numbered.
+.RS
+.RE
+.TP
+.B \f[C]--listings\f[]
+Use listings package for LaTeX code blocks
+.RS
+.RE
+.TP
+.B \f[C]-i\f[], \f[C]--incremental\f[]
+Make list items in slide shows display incrementally (one by one).
+The default is for lists to be displayed all at once.
+.RS
+.RE
+.TP
+.B \f[C]--slide-level\f[]=\f[I]NUMBER\f[]
+Specifies that headers with the specified level create slides (for
+\f[C]beamer\f[], \f[C]s5\f[], \f[C]slidy\f[], \f[C]dzslides\f[]).
+Headers above this level in the hierarchy are used to divide the slide
+show into sections; headers below this level create subheads within a
+slide.
+The default is to set the slide level based on the contents of the
+document; see Structuring the slide show, below.
+.RS
+.RE
+.TP
+.B \f[C]--section-divs\f[]
+Wrap sections in \f[C]<div>\f[] tags (or \f[C]<section>\f[] tags in
+HTML5), and attach identifiers to the enclosing \f[C]<div>\f[] (or
+\f[C]<section>\f[]) rather than the header itself.
+See Section identifiers, below.
+.RS
+.RE
+.TP
+.B \f[C]--email-obfuscation=\f[]\f[I]none|javascript|references\f[]
+Specify a method for obfuscating \f[C]mailto:\f[] links in HTML
+documents.
+\f[I]none\f[] leaves \f[C]mailto:\f[] links as they are.
+\f[I]javascript\f[] obfuscates them using javascript.
+\f[I]references\f[] obfuscates them by printing their letters as decimal
+or hexadecimal character references.
+If \f[C]--strict\f[] is specified, \f[I]references\f[] is used
+regardless of the presence of this option.
+.RS
+.RE
+.TP
+.B \f[C]--id-prefix\f[]=\f[I]STRING\f[]
+Specify a prefix to be added to all automatically generated identifiers
+in HTML output.
+This is useful for preventing duplicate identifiers when generating
+fragments to be included in other pages.
+.RS
+.RE
+.TP
+.B \f[C]-T\f[] \f[I]STRING\f[], \f[C]--title-prefix=\f[]\f[I]STRING\f[]
+Specify \f[I]STRING\f[] as a prefix at the beginning of the title that
+appears in the HTML header (but not in the title as it appears at the
+beginning of the HTML body).
+Implies \f[C]--standalone\f[].
+.RS
+.RE
+.TP
+.B \f[C]-c\f[] \f[I]URL\f[], \f[C]--css=\f[]\f[I]URL\f[]
+Link to a CSS style sheet.
+.RS
+.RE
.TP
.B \f[C]--reference-odt=\f[]\f[I]FILE\f[]
Use the specified file as a style reference in producing an ODT.
@@ -467,11 +568,23 @@ If this is not found either, sensible defaults will be used.
.RS
.RE
.TP
+.B \f[C]--reference-docx=\f[]\f[I]FILE\f[]
+Use the specified file as a style reference in producing a docx file.
+For best results, the reference docx should be a modified version of a
+docx file produced using pandoc.
+The contents of the reference docx are ignored, but its stylesheets are
+used in the new docx.
+If no reference docx is specified on the command line, pandoc will look
+for a file \f[C]reference.docx\f[] in the user data directory (see
+\f[C]--data-dir\f[]).
+If this is not found either, sensible defaults will be used.
+.RS
+.RE
+.TP
.B \f[C]--epub-stylesheet=\f[]\f[I]FILE\f[]
Use the specified CSS file to style the EPUB.
If no stylesheet is specified, pandoc will look for a file
-\f[C]epub.css\f[] in the user data directory (see \f[C]--data-dir\f[],
-below).
+\f[C]epub.css\f[] in the user data directory (see \f[C]--data-dir\f[]).
If it is not found there, sensible defaults will be used.
.RS
.RE
@@ -499,34 +612,68 @@ For example:
.PP
By default, pandoc will include the following metadata elements:
\f[C]<dc:title>\f[] (from the document title), \f[C]<dc:creator>\f[]
-(from the document authors), \f[C]<dc:language>\f[] (from the locale),
-and \f[C]<dc:identifier\ id="BookId">\f[] (a randomly generated UUID).
+(from the document authors), \f[C]<dc:date>\f[] (from the document date,
+which should be in ISO 8601 format), \f[C]<dc:language>\f[] (from the
+\f[C]lang\f[] variable, or, if is not set, the locale), and
+\f[C]<dc:identifier\ id="BookId">\f[] (a randomly generated UUID).
Any of these may be overridden by elements in the metadata file.
.RE
.TP
-.B \f[C]-D\f[] \f[I]FORMAT\f[],
-\f[C]--print-default-template=\f[]\f[I]FORMAT\f[]
-Print the default template for an output \f[I]FORMAT\f[].
-(See \f[C]-t\f[] for a list of possible \f[I]FORMAT\f[]s.)
+.B \f[C]--epub-embed-font=\f[]\f[I]FILE\f[]
+Embed the specified font in the EPUB.
+This option can be repeated to embed multiple fonts.
+To use embedded fonts, you will need to add declarations like the
+following to your CSS (see `\f[C]--epub-stylesheet\f[]):
.RS
+.IP
+.nf
+\f[C]
+\@font-face\ {
+font-family:\ DejaVuSans;
+font-style:\ normal;
+font-weight:\ normal;
+src:url("DejaVuSans-Regular.ttf");
+}
+\@font-face\ {
+font-family:\ DejaVuSans;
+font-style:\ normal;
+font-weight:\ bold;
+src:url("DejaVuSans-Bold.ttf");
+}
+\@font-face\ {
+font-family:\ DejaVuSans;
+font-style:\ italic;
+font-weight:\ normal;
+src:url("DejaVuSans-Oblique.ttf");
+}
+\@font-face\ {
+font-family:\ DejaVuSans;
+font-style:\ italic;
+font-weight:\ bold;
+src:url("DejaVuSans-BoldOblique.ttf");
+}
+body\ {\ font-family:\ "DejaVuSans";\ }
+\f[]
+.fi
.RE
.TP
-.B \f[C]-T\f[] \f[I]STRING\f[], \f[C]--title-prefix=\f[]\f[I]STRING\f[]
-Specify \f[I]STRING\f[] as a prefix at the beginning of the title that
-appears in the HTML header (but not in the title as it appears at the
-beginning of the HTML body).
-Implies \f[C]--standalone\f[].
+.B \f[C]--latex-engine=\f[]\f[I]pdflatex|lualatex|xelatex\f[]
+Use the specified LaTeX engine when producing PDF output.
+The default is \f[C]pdflatex\f[].
+If the engine is not in your PATH, the full path of the engine may be
+specified here.
.RS
.RE
+.SS Citations
.TP
.B \f[C]--bibliography=\f[]\f[I]FILE\f[]
Specify bibliography database to be used in resolving citations.
The database type will be determined from the extension of
\f[I]FILE\f[], which may be \f[C].mods\f[] (MODS format), \f[C].bib\f[]
-(BibTeX format), \f[C].bbx\f[] (BibLaTeX format), \f[C].ris\f[] (RIS
-format), \f[C].enl\f[] (EndNote format), \f[C].xml\f[] (EndNote XML
-format), \f[C].wos\f[] (ISI format), \f[C].medline\f[] (MEDLINE format),
-\f[C].copac\f[] (Copac format), or \f[C].json\f[] (citeproc JSON).
+(BibTeX/BibLaTeX format), \f[C].ris\f[] (RIS format), \f[C].enl\f[]
+(EndNote format), \f[C].xml\f[] (EndNote XML format), \f[C].wos\f[] (ISI
+format), \f[C].medline\f[] (MEDLINE format), \f[C].copac\f[] (Copac
+format), or \f[C].json\f[] (citeproc JSON).
If you want to use multiple bibliographies, just use this option
repeatedly.
.RS
@@ -559,6 +706,29 @@ style: either \f[C]default.csl\f[] in the user data directory (see
author-date style.
.RE
.TP
+.B \f[C]--citation-abbreviations=\f[]\f[I]FILE\f[]
+Specify a file containing abbreviations for journal titles and other
+bibliographic fields (indicated by setting \f[C]form="short"\f[] in the
+CSL node for the field).
+The format is described at
+\f[C]http://citationstylist.org/2011/10/19/abbreviations-for-zotero-test-release/\f[].
+Here is a short example:
+.RS
+.IP
+.nf
+\f[C]
+{\ "default":\ {
+\ \ \ \ "container-title":\ {
+\ \ \ \ \ \ \ \ \ \ \ \ "Lloyd\[aq]s\ Law\ Reports":\ "Lloyd\[aq]s\ Rep",
+\ \ \ \ \ \ \ \ \ \ \ \ "Estates\ Gazette":\ "EG",
+\ \ \ \ \ \ \ \ \ \ \ \ "Scots\ Law\ Times":\ "SLT"
+\ \ \ \ }
+\ \ }
+}
+\f[]
+.fi
+.RE
+.TP
.B \f[C]--natbib\f[]
Use natbib for citations in LaTeX output.
.RS
@@ -568,33 +738,71 @@ Use natbib for citations in LaTeX output.
Use biblatex for citations in LaTeX output.
.RS
.RE
+.SS Math rendering in HTML
.TP
-.B \f[C]--data-dir=\f[]\f[I]DIRECTORY\f[]
-Specify the user data directory to search for pandoc data files.
-If this option is not specified, the default user data directory will be
-used:
+.B \f[C]-m\f[] [\f[I]URL\f[]], \f[C]--latexmathml\f[][=\f[I]URL\f[]]
+Use the LaTeXMathML script to display embedded TeX math in HTML output.
+To insert a link to a local copy of the \f[C]LaTeXMathML.js\f[] script,
+provide a \f[I]URL\f[].
+If no \f[I]URL\f[] is provided, the contents of the script will be
+inserted directly into the HTML header, preserving portability at the
+price of efficiency.
+If you plan to use math on several pages, it is much better to link to a
+copy of the script, so it can be cached.
+.RS
+.RE
+.TP
+.B \f[C]--mathml\f[][=\f[I]URL\f[]]
+Convert TeX math to MathML (in \f[C]docbook\f[] as well as \f[C]html\f[]
+and \f[C]html5\f[]).
+In standalone \f[C]html\f[] output, a small javascript (or a link to
+such a script if a \f[I]URL\f[] is supplied) will be inserted that
+allows the MathML to be viewed on some browsers.
+.RS
+.RE
+.TP
+.B \f[C]--jsmath\f[][=\f[I]URL\f[]]
+Use jsMath to display embedded TeX math in HTML output.
+The \f[I]URL\f[] should point to the jsMath load script (e.g.
+\f[C]jsMath/easy/load.js\f[]); if provided, it will be linked to in the
+header of standalone HTML documents.
+If a \f[I]URL\f[] is not provided, no link to the jsMath load script
+will be inserted; it is then up to the author to provide such a link in
+the HTML template.
+.RS
+.RE
+.TP
+.B \f[C]--mathjax\f[][=\f[I]URL\f[]]
+Use MathJax to display embedded TeX math in HTML output.
+The \f[I]URL\f[] should point to the \f[C]MathJax.js\f[] load script.
+If a \f[I]URL\f[] is not provided, a link to the MathJax CDN will be
+inserted.
+.RS
+.RE
+.TP
+.B \f[C]--gladtex\f[]
+Enclose TeX math in \f[C]<eq>\f[] tags in HTML output.
+These can then be processed by gladTeX to produce links to images of the
+typeset formulas.
+.RS
+.RE
+.TP
+.B \f[C]--mimetex\f[][=\f[I]URL\f[]]
+Render TeX math using the mimeTeX CGI script.
+If \f[I]URL\f[] is not specified, it is assumed that the script is at
+\f[C]/cgi-bin/mimetex.cgi\f[].
.RS
-.IP
-.nf
-\f[C]
-$HOME/.pandoc
-\f[]
-.fi
-.PP
-in unix and
-.IP
-.nf
-\f[C]
-C:\\Documents\ And\ Settings\\USERNAME\\Application\ Data\\pandoc
-\f[]
-.fi
-.PP
-in Windows.
-A \f[C]reference.odt\f[], \f[C]epub.css\f[], \f[C]templates\f[]
-directory, or \f[C]s5\f[] directory placed in this directory will
-override pandoc\[aq]s normal defaults.
.RE
.TP
+.B \f[C]--webtex\f[][=\f[I]URL\f[]]
+Render TeX formulas using an external script that converts TeX formulas
+to images.
+The formula will be concatenated with the URL provided.
+If \f[I]URL\f[] is not specified, the Google Chart API will be used.
+.RS
+.RE
+.SS Options for wrapper scripts
+.TP
.B \f[C]--dump-args\f[]
Print information about command-line arguments to \f[I]stdout\f[], then
exit.
@@ -630,16 +838,6 @@ pandoc\ -o\ foo.html\ -s
\f[]
.fi
.RE
-.TP
-.B \f[C]-v\f[], \f[C]--version\f[]
-Print version.
-.RS
-.RE
-.TP
-.B \f[C]-h\f[], \f[C]--help\f[]
-Show usage message.
-.RS
-.RE
.SH TEMPLATES
.PP
When the \f[C]-s/--standalone\f[] option is used, pandoc uses a template
@@ -725,7 +923,7 @@ date of document, as specified in title block
.RE
.TP
.B \f[C]lang\f[]
-language code for HTML documents
+language code for HTML or LaTeX documents
.RS
.RE
.TP
@@ -739,6 +937,26 @@ base URL for Slidy documents (defaults to
base URL for S5 documents (defaults to \f[C]ui/default\f[])
.RS
.RE
+.TP
+.B \f[C]font-size\f[]
+font size (10pt, 11pt, 12pt) for LaTeX documents
+.RS
+.RE
+.TP
+.B \f[C]documentclass\f[]
+document class for LaTeX documents
+.RS
+.RE
+.TP
+.B \f[C]theme\f[]
+theme for LaTeX beamer documents
+.RS
+.RE
+.TP
+.B \f[C]colortheme\f[]
+colortheme for LaTeX beamer documents
+.RS
+.RE
.PP
Variables may be set at the command line using the
\f[C]-V/--variable\f[] option.
@@ -790,34 +1008,49 @@ modifying your custom templates accordingly.
An easy way to do this is to fork the pandoc-templates repository
(\f[C]http://github.com/jgm/pandoc-templates\f[]) and merge in changes
after each pandoc release.
-.SH PRODUCING HTML SLIDE SHOWS WITH PANDOC
+.SH PRODUCING SLIDE SHOWS WITH PANDOC
.PP
You can use Pandoc to produce an HTML + javascript slide presentation
that can be viewed via a web browser.
-There are two ways to do this, using S5 or Slidy.
+There are three ways to do this, using S5, DZSlides, or Slidy.
+You can also produce a PDF slide show using LaTeX beamer.
.PP
Here\[aq]s the markdown source for a simple slide show,
-\f[C]eating.txt\f[]:
+\f[C]habits.txt\f[]:
.IP
.nf
\f[C]
-%\ Eating\ Habits
+%\ Habits
%\ John\ Doe
%\ March\ 22,\ 2005
#\ In\ the\ morning
+##\ Getting\ up
+
+-\ Turn\ off\ alarm
+-\ Get\ out\ of\ bed
+
+##\ Breakfast
+
-\ Eat\ eggs
-\ Drink\ coffee
#\ In\ the\ evening
+##\ Dinner
+
-\ Eat\ spaghetti
-\ Drink\ wine
---------------------------
+------------------
![picture\ of\ spaghetti](images/spaghetti.jpg)
+
+##\ Going\ to\ sleep
+
+-\ Get\ in\ bed
+-\ Count\ sheep
\f[]
.fi
.PP
@@ -825,42 +1058,83 @@ To produce the slide show, simply type
.IP
.nf
\f[C]
-pandoc\ -w\ s5\ -s\ eating.txt\ >\ eating.html
+pandoc\ -t\ s5\ -s\ habits.txt\ -o\ habits.html
+\f[]
+.fi
+.PP
+for S5,
+.IP
+.nf
+\f[C]
+pandoc\ -t\ slidy\ -s\ habits.txt\ -o\ habits.html
\f[]
.fi
.PP
-for S5, or
+for Slidy,
.IP
.nf
\f[C]
-pandoc\ -w\ slidy\ -s\ eating.txt\ >\ eating.html
+pandoc\ -t\ dzslides\ -s\ habits.txt\ -o\ habits.html
\f[]
.fi
.PP
-for Slidy.
+for DZSlides, or
+.IP
+.nf
+\f[C]
+pandoc\ -t\ beamer\ habits.txt\ -o\ habits.pdf
+\f[]
+.fi
+.PP
+for beamer.
+.PP
+With all HTML slide formats, the \f[C]--self-contained\f[] option can be
+used to produce a single file that contains all of the data necessary to
+display the slide show, including linked scripts, stylesheets, images,
+and videos.
+.SS Structuring the slide show
+.PP
+By default, the \f[I]slide level\f[] is the highest header level in the
+hierarchy that is followed immediately by content, and not another
+header, somewhere in the document.
+In the example above, level 1 headers are always followed by level 2
+headers, which are followed by content, so 2 is the slide level.
+This default can be overridden using the \f[C]--slide-level\f[] option.
.PP
+The document is carved up into slides according to the following rules:
+.IP \[bu] 2
+A horizontal rule always starts a new slide.
+.IP \[bu] 2
+A header at the slide level always starts a new slide.
+.IP \[bu] 2
+Headers \f[I]below\f[] the slide level in the hierarchy create headers
+\f[I]within\f[] a slide.
+.IP \[bu] 2
+Headers \f[I]above\f[] the slide level in the hierarchy create "title
+slides," which just contain the section title and help to break the
+slide show into sections.
+.IP \[bu] 2
A title page is constructed automatically from the document\[aq]s title
-block.
-Each level-one header and horizontal rule begins a new slide.
+block, if present.
+(In the case of beamer, this can be disabled by commenting out some
+lines in the default template.)
+.PP
+These rules are designed to support many different styles of slide show.
+If you don\[aq]t care about structuring your slides into sections and
+subsections, you can just use level 1 headers for all each slide.
+(In that case, level 1 will be the slide level.)
+ But you can also structure the slide show into sections, as in the
+example above.
.PP
-The file produced by pandoc with the \f[C]-s/--standalone\f[] option
-embeds a link to javascripts and CSS files, which are assumed to be
-available at the relative path \f[C]ui/default\f[] (for S5) or at the
-Slidy website at \f[C]w3.org\f[] (for Slidy).
+For Slidy and S5, the file produced by pandoc with the
+\f[C]-s/--standalone\f[] option embeds a link to javascripts and CSS
+files, which are assumed to be available at the relative path
+\f[C]s5/default\f[] (for S5) or at the Slidy website at \f[C]w3.org\f[]
+(for Slidy).
(These paths can be changed by setting the \f[C]slidy-url\f[] or
\f[C]s5-url\f[] variables; see \f[C]--variable\f[], above.)
- If the \f[C]--offline\f[] option is specified, the scripts and CSS will
-be included directly in the generated file, so that it may be used
-offline.
-.PP
-You can change the style of the slides by putting customized CSS files
-in \f[C]$DATADIR/s5/default\f[] (for S5) or \f[C]$DATADIR/slidy\f[] (for
-Slidy), where \f[C]$DATADIR\f[] is the user data directory (see
-\f[C]--data-dir\f[], above).
-The originals may be found in pandoc\[aq]s system data directory
-(generally \f[C]$CABALDIR/pandoc-VERSION/s5/default\f[]).
-Pandoc will look there for any files it does not find in the user data
-directory.
+ For DZSlides, the (relatively short) javascript and css are included in
+the file by default.
.SS Incremental lists
.PP
By default, these writers produces lists that display "all at once." If
@@ -879,12 +1153,34 @@ with the \f[C]-i\f[] option), put it in a block quote:
.PP
In this way incremental and nonincremental lists can be mixed in a
single document.
+.SS Styling the slides
+.PP
+You can change the style of HTML slides by putting customized CSS files
+in \f[C]$DATADIR/s5/default\f[] (for S5) or \f[C]$DATADIR/slidy\f[] (for
+Slidy), where \f[C]$DATADIR\f[] is the user data directory (see
+\f[C]--data-dir\f[], above).
+The originals may be found in pandoc\[aq]s system data directory
+(generally \f[C]$CABALDIR/pandoc-VERSION/s5/default\f[]).
+Pandoc will look there for any files it does not find in the user data
+directory.
+.PP
+For dzslides, the CSS is included in the HTML file itself, and may be
+modified there.
+.PP
+To style beamer slides, you can specify a beamer "theme" or "colortheme"
+using the \f[C]-V\f[] option:
+.IP
+.nf
+\f[C]
+pandoc\ -t\ beamer\ habits.txt\ -V\ theme:Warsaw\ -o\ habits.pdf
+\f[]
+.fi
.SH LITERATE HASKELL SUPPORT
.PP
If you append \f[C]+lhs\f[] to an appropriate input or output format
(\f[C]markdown\f[], \f[C]rst\f[], or \f[C]latex\f[] for input or output;
-\f[C]html\f[] for output only), pandoc will treat the document as
-literate Haskell source.
+\f[C]html\f[] or \f[C]html5\f[] for output only), pandoc will treat the
+document as literate Haskell source.
This means that
.IP \[bu] 2
In markdown input, "bird track" sections will be parsed as Haskell code
@@ -892,9 +1188,10 @@ rather than block quotations.
Text between \f[C]\\begin{code}\f[] and \f[C]\\end{code}\f[] will also
be treated as Haskell code.
.IP \[bu] 2
-In markdown output, code blocks with class \f[C]haskell\f[] will be
-rendered using bird tracks, and block quotations will be indented one
-space, so they will not be treated as Haskell code.
+In markdown output, code blocks with classes \f[C]haskell\f[] and
+\f[C]literate\f[] will be rendered using bird tracks, and block
+quotations will be indented one space, so they will not be treated as
+Haskell code.
In addition, headers will be rendered setext-style (with underlines)
rather than atx-style (with \[aq]#\[aq] characters).
(This is because ghc treats \[aq]#\[aq] characters in column 1 as
@@ -944,7 +1241,9 @@ This software carries no warranty of any kind.
Andrea Rossato, Eric Kow, infinity0x, Luke Plant, shreevatsa.public,
Puneeth Chaganti, Paul Rivier, rodja.trappe, Bradley Kuhn, thsutton,
Nathan Gass, Jonathan Daugherty, Jérémy Bobbio, Justin Bogner, qerub,
-Christopher Sawicki, Kelsey Hightower.
+Christopher Sawicki, Kelsey Hightower, Masayoshi Takahashi, Antoine
+Latter, Ralf Stephan, Eric Seidel, B.
+Scott Michel.
.SH PANDOC'S MARKDOWN
For a complete description of pandoc's extensions to standard markdown,
see \f[C]pandoc_markdown\f[] (5).
diff --git a/man/man5/pandoc_markdown.5 b/man/man5/pandoc_markdown.5
index 418b532e3..ad6c41e5d 100644
--- a/man/man5/pandoc_markdown.5
+++ b/man/man5/pandoc_markdown.5
@@ -1,5 +1,5 @@
.\"t
-.TH PANDOC_MARKDOWN 5 "July 30, 2011" "Pandoc"
+.TH PANDOC_MARKDOWN 5 "January 27, 2012" "Pandoc"
.SH NAME
pandoc_markdown - markdown syntax for pandoc(1)
.SH DESCRIPTION
@@ -39,7 +39,7 @@ line.
Newlines are treated as spaces, so you can reflow your paragraphs as you
like.
If you need a hard line break, put two or more spaces at the end of a
-line, or or type a backslash followed by a newline.
+line, or type a backslash followed by a newline.
.SH HEADERS
.PP
There are two kinds of headers, Setext and atx.
@@ -98,12 +98,12 @@ I\ like\ several\ of\ their\ flavors\ of\ ice\ cream:
#22,\ for\ example,\ and\ #5.
\f[]
.fi
-.SS Header identifiers in HTML
+.SS Header identifiers in HTML, LaTeX, and ConTeXt
.PP
\f[I]Pandoc extension\f[].
.PP
-Each header element in pandoc\[aq]s HTML output is given a unique
-identifier.
+Each header element in pandoc\[aq]s HTML and ConTeXt output is given a
+unique identifier.
This identifier is based on the text of the header.
To derive the identifier from the header text,
.IP \[bu] 2
@@ -175,12 +175,12 @@ A link to this section, for example, might look like this:
.nf
\f[C]
See\ the\ section\ on
-[header\ identifiers](#header-identifiers-in-html).
+[header\ identifiers][#header-identifiers-in-html].
\f[]
.fi
.PP
Note, however, that this method of providing links to sections works
-only in HTML.
+only in HTML, LaTeX, and ConTeXt formats.
.PP
If the \f[C]--section-divs\f[] option is specified, then each section
will be wrapped in a \f[C]div\f[] (or a \f[C]section\f[], if
@@ -275,9 +275,10 @@ Note: blank lines in the verbatim text need not begin with four spaces.
.PP
In addition to standard indented code blocks, Pandoc supports
\f[I]delimited\f[] code blocks.
-These begin with a row of three or more tildes (\f[C]~\f[]) and end with
-a row of tildes that must be at least as long as the starting row.
-Everything between the tilde-lines is treated as code.
+These begin with a row of three or more tildes (\f[C]~\f[]) or backticks
+(\f[C]`\f[]) and end with a row of tildes or backticks that must be at
+least as long as the starting row.
+Everything between these lines is treated as code.
No indentation is necessary:
.IP
.nf
@@ -293,8 +294,8 @@ if\ (a\ >\ 3)\ {
Like regular code blocks, delimited code blocks must be separated from
surrounding text by blank lines.
.PP
-If the code itself contains a row of tildes, just use a longer row of
-tildes at the start and end:
+If the code itself contains a row of tildes or backticks, just use a
+longer row of tildes or backticks at the start and end:
.IP
.nf
\f[C]
@@ -306,38 +307,63 @@ code\ including\ tildes
\f[]
.fi
.PP
-Optionally, you may specify the language of the code block using this
+Optionally, you may attach attributes to the code block using this
syntax:
.IP
.nf
\f[C]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ {.haskell\ .numberLines}
+~~~~\ {#mycode\ .haskell\ .numberLines\ startFrom="100"}
qsort\ []\ \ \ \ \ =\ []
qsort\ (x:xs)\ =\ qsort\ (filter\ (<\ x)\ xs)\ ++\ [x]\ ++
-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ qsort\ (filter\ (>=\ x)\ xs)\
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ qsort\ (filter\ (>=\ x)\ xs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\f[]
.fi
.PP
+Here \f[C]mycode\f[] is an identifier, \f[C]haskell\f[] and
+\f[C]numberLines\f[] are classes, and \f[C]startFrom\f[] is an attribute
+with value \f[C]100\f[].
Some output formats can use this information to do syntax highlighting.
-Currently, the only output format that uses this information is HTML.
-.PP
-If pandoc has been compiled with syntax highlighting support, then the
-code block above will appear highlighted, with numbered lines.
+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 \f[C]pandoc\ --version\f[].)
-.PP
-If pandoc has not been compiled with syntax highlighting support, the
-code block above will appear as follows:
+ Otherwise, the code block above will appear as follows:
.IP
.nf
\f[C]
-<pre\ class="haskell">
+<pre\ id="mycode"\ class="haskell\ numberLines"\ startFrom="100">
\ \ <code>
\ \ ...
\ \ </code>
</pre>
\f[]
.fi
+.PP
+A shortcut form can also be used for specifying the language of the code
+block:
+.IP
+.nf
+\f[C]
+```haskell
+qsort\ []\ =\ []
+```
+\f[]
+.fi
+.PP
+This is equivalent to:
+.IP
+.nf
+\f[C]
+```\ {.haskell}
+qsort\ []\ =\ []
+```
+\f[]
+.fi
+.PP
+To prevent all highlighting, use the \f[C]--no-highlight\f[] flag.
+To set the highlighting style, use \f[C]--highlight-style\f[].
.SH LISTS
.SS Bullet lists
.PP
@@ -567,6 +593,8 @@ Each term must fit on one line, which may optionally be followed by a
blank line, and must be followed by one or more definitions.
A definition begins with a colon or tilde, which may be indented one or
two spaces.
+The body of the definition (including the first line, aside from the
+colon or tilde) should be indented four spaces.
A term may have multiple definitions, and each definition may consist of
one or more block elements (paragraph, code block, list, etc.)
, each indented four spaces or one tab stop.
@@ -698,9 +726,9 @@ one big list:
<!--\ -->
-a.\ \ uno
-b.\ \ dos
-c.\ \ tres
+1.\ \ uno
+2.\ \ dos
+3.\ \ tres
\f[]
.fi
.SH HORIZONTAL RULES
@@ -1178,6 +1206,11 @@ described here.
.RS
.RE
.TP
+.B AsciiDoc
+It will be rendered as \f[C]latexmath:[...]\f[].
+.RS
+.RE
+.TP
.B Texinfo
It will be rendered inside a \f[C]\@math\f[] command.
.RS
@@ -1198,19 +1231,31 @@ It will be rendered inside \f[C]<span\ class="math">\f[] tags.
.RS
.RE
.TP
-.B RTF, Docbook, OpenDocument, ODT
+.B RTF, OpenDocument, ODT
It will be rendered, if possible, using unicode characters, and will
otherwise appear verbatim.
.RS
.RE
.TP
-.B HTML, Slidy, S5, EPUB
+.B Docbook
+If the \f[C]--mathml\f[] flag is used, it will be rendered using mathml
+in an \f[C]inlineequation\f[] or \f[C]informalequation\f[] tag.
+Otherwise it will be rendered, if possible, using unicode characters.
+.RS
+.RE
+.TP
+.B Docx
+It will be rendered using OMML math markup.
+.RS
+.RE
+.TP
+.B HTML, Slidy, DZSlides, S5, EPUB
The way math is rendered in HTML will depend on the command-line options
selected:
.RS
.IP "1." 3
The default is to render TeX math as far as possible using unicode
-characters, as with RTF, Docbook, and OpenDocument output.
+characters, as with RTF, DocBook, and OpenDocument output.
Formulas are put inside a \f[C]span\f[] with \f[C]class="math"\f[], so
that they may be styled differently from the surrounding text if needed.
.IP "2." 3
@@ -1260,12 +1305,12 @@ If no URL is specified, the Google Chart API will be used
.RE
.SH RAW HTML
.PP
-Markdown allows you to insert raw HTML anywhere in a document (except
-verbatim contexts, where \f[C]<\f[], \f[C]>\f[], and \f[C]&\f[] are
-interpreted literally).
+Markdown allows you to insert raw HTML (or DocBook) anywhere in a
+document (except verbatim contexts, where \f[C]<\f[], \f[C]>\f[], and
+\f[C]&\f[] are interpreted literally).
.PP
-The raw HTML is passed through unchanged in HTML, S5, Slidy, EPUB,
-Markdown, and Textile output, and suppressed in other formats.
+The raw HTML is passed through unchanged in HTML, S5, Slidy, DZSlides,
+EPUB, Markdown, and Textile output, and suppressed in other formats.
.PP
\f[I]Pandoc extension\f[].
.PP
@@ -1575,16 +1620,11 @@ T}@T{
\&.mods
T}
T{
-BibTeX
+BibTeX/BibLaTeX
T}@T{
\&.bib
T}
T{
-BibLaTeX
-T}@T{
-\&.bbx
-T}
-T{
RIS
T}@T{
\&.ris
diff --git a/pandoc.cabal b/pandoc.cabal
index 757254c36..7420416c8 100644
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,26 +1,26 @@
Name: pandoc
-Version: 1.8.2.1
-Cabal-Version: >= 1.6
+Version: 1.9.1.1
+Cabal-Version: >= 1.10
Build-Type: Custom
License: GPL
License-File: COPYING
-Copyright: (c) 2006-2011 John MacFarlane
+Copyright: (c) 2006-2012 John MacFarlane
Author: John MacFarlane <jgm@berkeley.edu>
Maintainer: John MacFarlane <jgm@berkeley.edu>
Bug-Reports: https://github.com/jgm/pandoc/issues
Stability: alpha
Homepage: http://johnmacfarlane.net/pandoc
Category: Text
-Tested-With: GHC == 6.12.3, GHC == 7.0.3
+Tested-With: GHC == 6.12.1, GHC == 7.0.4, GHC == 7.4.1
Synopsis: Conversion between markup formats
Description: Pandoc is a Haskell library for converting from one markup
format to another, and a command-line tool that uses
this library. It can read markdown and (subsets of)
reStructuredText, HTML, LaTeX and Textile, and it can write
markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook,
- OpenDocument, ODT, RTF, MediaWiki, Textile, groff man pages,
- plain text, Emacs Org-Mode, EPUB, and S5 and Slidy HTML
- slide shows.
+ OpenDocument, ODT, Word docx, RTF, MediaWiki, Textile,
+ groff man pages, plain text, Emacs Org-Mode, AsciiDoc, EPUB,
+ and S5 and Slidy HTML slide shows.
.
Pandoc extends standard markdown syntax with footnotes,
embedded LaTeX, definition lists, tables, and other
@@ -37,45 +37,59 @@ Description: Pandoc is a Haskell library for converting from one markup
only adding a reader or writer.
Data-Files:
-- templates
- templates/default.html, templates/default.docbook,
+ templates/default.html, templates/default.html5,
+ templates/default.docbook, templates/default.beamer,
templates/default.opendocument, templates/default.latex,
templates/default.context, templates/default.texinfo,
templates/default.man, templates/default.markdown,
templates/default.rst, templates/default.plain,
templates/default.mediawiki, templates/default.rtf,
templates/default.s5, templates/default.slidy,
- templates/default.textile, templates/default.org
+ templates/default.dzslides, templates/default.asciidoc,
+ templates/default.textile, templates/default.org,
+ templates/epub-titlepage.html, templates/epub-page.html,
+ templates/epub-coverimage.html,
-- data for ODT writer
reference.odt,
+ -- data for docx writer
+ reference.docx,
-- stylesheet for EPUB writer
epub.css,
-- data for LaTeXMathML writer
data/LaTeXMathML.js,
data/MathMLinHTML.js,
-- data for S5 writer
- s5/default/slides.min.js,
+ s5/default/slides.js,
s5/default/s5-core.css,
s5/default/framing.css,
s5/default/pretty.css,
s5/default/opera.css,
s5/default/outline.css,
s5/default/print.css,
+ s5/default/slides.css,
+ s5/default/iepngfix.htc,
+ s5/default/blank.gif,
+ s5/default/bodybg.gif,
-- data for slidy writer
- slidy/slidy.css,
- slidy/slidy.min.js,
+ slidy/styles/slidy.css,
+ slidy/scripts/slidy.js.gz,
+ slidy/graphics/fold.gif,
+ slidy/graphics/unfold.gif,
+ slidy/graphics/nofold-dim.gif,
+ slidy/graphics/unfold-dim.gif,
+ slidy/graphics/fold-dim.gif,
+ -- data for dzslides writer
+ dzslides/template.html,
-- data for citeproc
default.csl,
-- documentation
README, INSTALL, COPYRIGHT, BUGS, changelog
Extra-Source-Files:
- -- sources for man pages
- man/man1/markdown2pdf.1.md,
-- code to create pandoc.1 man page
MakeManPage.hs,
man/man1/pandoc.1.template,
man/man5/pandoc_markdown.5.template,
-- generated man pages (produced post-build)
- man/man1/markdown2pdf.1,
man/man1/pandoc.1,
man/man5/pandoc_markdown.5,
-- benchmarks
@@ -121,6 +135,7 @@ Extra-Source-Files:
tests/tables.native,
tests/tables.opendocument,
tests/tables.org,
+ tests/tables.asciidoc,
tests/tables.texinfo,
tests/tables.rst,
tests/tables.rtf,
@@ -140,6 +155,7 @@ Extra-Source-Files:
tests/writer.native,
tests/writer.opendocument,
tests/writer.org,
+ tests/writer.asciidoc,
tests/writer.rst,
tests/writer.rtf,
tests/writer.texinfo,
@@ -152,85 +168,77 @@ Extra-Source-Files:
tests/lhs-test.latex+lhs,
tests/lhs-test.html,
tests/lhs-test.html+lhs,
- tests/lhs-test.nohl.html,
- tests/lhs-test.nohl.html+lhs,
tests/lhs-test.fragment.html+lhs
Extra-Tmp-Files: man/man1/pandoc.1,
- man/man1/markdown2pdf.1,
man/man5/pandoc_markdown.5
Source-repository head
type: git
location: git://github.com/jgm/pandoc.git
-Flag threaded
- Description: Compile markdown2pdf with -threaded option.
- Default: True
-Flag highlighting
- Description: Compile in support for syntax highlighting of code blocks.
- Default: False
Flag executable
Description: Build the pandoc executable.
Default: True
Flag library
Description: Build the pandoc library.
Default: True
-Flag wrappers
- Description: Build the wrappers (markdown2pdf).
- Default: True
Flag tests
Description: Build test-pandoc.
Default: False
-Flag benchmarks
- Description: Build benchmark-pandoc.
- Default: False
Library
- -- Note: the following material must be in both Library and Executable stanzas.
+ -- Note: the following is duplicated in all stanzas.
-- It needs to be duplicated because of the library & executable flags.
-- BEGIN DUPLICATED SECTION
Build-Depends: containers >= 0.1 && < 0.5,
- parsec >= 2.1 && < 3.2,
- xhtml >= 3000.0 && < 3000.3,
+ parsec >= 3.1 && < 3.2,
+ blaze-html >= 0.4.3.0 && < 0.5,
mtl >= 1.1 && < 2.1,
network >= 2 && < 2.4,
- filepath >= 1.1 && < 1.3,
- process >= 1 && < 1.1,
+ filepath >= 1.1 && < 1.4,
+ process >= 1 && < 1.2,
directory >= 1 && < 1.2,
bytestring >= 0.9 && < 1.0,
zip-archive >= 0.1.1.7 && < 0.2,
utf8-string >= 0.3 && < 0.4,
- old-time >= 1 && < 1.1,
- HTTP >= 4000.0.5 && < 4000.2,
- texmath >= 0.5 && < 0.6,
- xml >= 1.3.5 && < 1.4,
+ old-locale >= 1 && < 1.1,
+ time >= 1.2 && < 1.5,
+ HTTP >= 4000.0.5 && < 4000.3,
+ texmath >= 0.6.0.2 && < 0.7,
+ xml >= 1.3.12 && < 1.4,
random >= 1 && < 1.1,
extensible-exceptions >= 0.1 && < 0.2,
- citeproc-hs >= 0.3.1 && < 0.4,
- pandoc-types == 1.8.*,
- json >= 0.4 && < 0.5,
- dlist >= 0.4 && < 0.6,
- tagsoup >= 0.12 && < 0.13,
- base64-bytestring >= 0.1 && < 0.2
+ citeproc-hs >= 0.3.4 && < 0.4,
+ pandoc-types >= 1.9.0.2 && < 1.10,
+ json >= 0.4 && < 0.6,
+ tagsoup >= 0.12.5 && < 0.13,
+ base64-bytestring >= 0.1 && < 0.2,
+ zlib >= 0.5 && <= 0.6,
+ highlighting-kate >= 0.5.0.2 && < 0.6,
+ temporary >= 1.1 && < 1.2
if impl(ghc >= 6.10)
Build-depends: base >= 4 && < 5, syb >= 0.1 && < 0.4
else
Build-depends: base >= 3 && < 4
- if flag(highlighting)
- Build-depends: highlighting-kate >= 0.2.9 && < 0.3
- cpp-options: -D_HIGHLIGHTING
if impl(ghc >= 6.12)
- Ghc-Options: -O2 -Wall -fno-warn-unused-do-bind
+ Ghc-Options: -O2 -Wall -fno-warn-unused-do-bind -dno-debug-output
else
Ghc-Options: -O2 -Wall
- Ghc-Prof-Options: -auto-all -caf-all
- Extensions: CPP
+ if impl(ghc >= 7.0.1)
+ Ghc-Prof-Options: -auto-all -caf-all -rtsopts
+ else
+ Ghc-Prof-Options: -auto-all -caf-all
+ Default-Language: Haskell98
+ Default-Extensions: CPP
+ Other-Extensions: PatternGuards, OverloadedStrings,
+ ScopedTypeVariables, GeneralizedNewtypeDeriving,
+ RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances,
+ FlexibleInstances
Hs-Source-Dirs: src
-- END DUPLICATED SECTION
Exposed-Modules: Text.Pandoc,
Text.Pandoc.Pretty,
- Text.Pandoc.CharacterReferences,
Text.Pandoc.Shared,
Text.Pandoc.Parsing,
Text.Pandoc.Highlighting,
@@ -252,18 +260,23 @@ Library
Text.Pandoc.Writers.Markdown,
Text.Pandoc.Writers.RST,
Text.Pandoc.Writers.Org,
+ Text.Pandoc.Writers.AsciiDoc,
Text.Pandoc.Writers.Textile,
Text.Pandoc.Writers.MediaWiki,
Text.Pandoc.Writers.RTF,
Text.Pandoc.Writers.ODT,
+ Text.Pandoc.Writers.Docx,
Text.Pandoc.Writers.EPUB,
- Text.Pandoc.S5,
- Text.Pandoc.Templates
- Text.Pandoc.Biblio
+ Text.Pandoc.PDF,
+ Text.Pandoc.Templates,
+ Text.Pandoc.Biblio,
+ Text.Pandoc.SelfContained
Other-Modules: Text.Pandoc.XML,
Text.Pandoc.UTF8,
Text.Pandoc.MIME,
Text.Pandoc.UUID,
+ Text.Pandoc.ImageSize,
+ Text.Pandoc.Slides,
Paths_pandoc
if flag(library)
@@ -272,91 +285,128 @@ Library
Buildable: False
Executable pandoc
- -- Note: the following material must be in both Library and Executable stanzas.
+ -- Note: the following is duplicated in all stanzas.
-- It needs to be duplicated because of the library & executable flags.
-- BEGIN DUPLICATED SECTION
Build-Depends: containers >= 0.1 && < 0.5,
- parsec >= 2.1 && < 3.2,
- xhtml >= 3000.0 && < 3000.3,
+ parsec >= 3.1 && < 3.2,
+ blaze-html >= 0.4.3.0 && < 0.5,
mtl >= 1.1 && < 2.1,
network >= 2 && < 2.4,
- filepath >= 1.1 && < 1.3,
- process >= 1 && < 1.1,
+ filepath >= 1.1 && < 1.4,
+ process >= 1 && < 1.2,
directory >= 1 && < 1.2,
bytestring >= 0.9 && < 1.0,
zip-archive >= 0.1.1.7 && < 0.2,
utf8-string >= 0.3 && < 0.4,
- old-time >= 1 && < 1.1,
- HTTP >= 4000.0.5 && < 4000.2,
- texmath >= 0.5 && < 0.6,
- xml >= 1.3.5 && < 1.4,
+ old-locale >= 1 && < 1.1,
+ time >= 1.2 && < 1.5,
+ HTTP >= 4000.0.5 && < 4000.3,
+ texmath >= 0.6.0.2 && < 0.7,
+ xml >= 1.3.12 && < 1.4,
random >= 1 && < 1.1,
extensible-exceptions >= 0.1 && < 0.2,
- citeproc-hs >= 0.3.1 && < 0.4,
- pandoc-types == 1.8.*,
- json >= 0.4 && < 0.5,
- dlist >= 0.4 && < 0.6,
- tagsoup >= 0.12 && < 0.13,
- base64-bytestring >= 0.1 && < 0.2
+ citeproc-hs >= 0.3.4 && < 0.4,
+ pandoc-types >= 1.9.0.2 && < 1.10,
+ json >= 0.4 && < 0.6,
+ tagsoup >= 0.12.5 && < 0.13,
+ base64-bytestring >= 0.1 && < 0.2,
+ zlib >= 0.5 && <= 0.6,
+ highlighting-kate >= 0.5.0.2 && < 0.6,
+ temporary >= 1.1 && < 1.2
if impl(ghc >= 6.10)
Build-depends: base >= 4 && < 5, syb >= 0.1 && < 0.4
else
Build-depends: base >= 3 && < 4
- if flag(highlighting)
- Build-depends: highlighting-kate >= 0.2.9 && < 0.3
- cpp-options: -D_HIGHLIGHTING
if impl(ghc >= 6.12)
- Ghc-Options: -O2 -Wall -fno-warn-unused-do-bind
+ Ghc-Options: -O2 -Wall -fno-warn-unused-do-bind -dno-debug-output
else
Ghc-Options: -O2 -Wall
- Ghc-Prof-Options: -auto-all -caf-all
- Extensions: CPP
+ if impl(ghc >= 7.0.1)
+ Ghc-Prof-Options: -auto-all -caf-all -rtsopts
+ else
+ Ghc-Prof-Options: -auto-all -caf-all
+ Default-Language: Haskell98
+ Default-Extensions: CPP
+ Other-Extensions: PatternGuards, OverloadedStrings,
+ ScopedTypeVariables, GeneralizedNewtypeDeriving,
+ RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances,
+ FlexibleInstances
Hs-Source-Dirs: src
-- END DUPLICATED SECTION
Main-Is: pandoc.hs
- if flag(executable) || flag(wrappers)
- Buildable: True
- else
- Buildable: False
-
-Executable markdown2pdf
- Hs-Source-Dirs: src
- Main-Is: markdown2pdf.hs
- if flag(threaded)
- Ghc-Options: -Wall -threaded
- else
- Ghc-Options: -Wall
- Ghc-Prof-Options: -auto-all
- Extensions: CPP
- if flag(wrappers)
+ if flag(executable)
Buildable: True
else
Buildable: False
Executable test-pandoc
- Hs-Source-Dirs: src
Main-Is: test-pandoc.hs
- if flag(highlighting)
- cpp-options: -D_HIGHLIGHTING
- if impl(ghc >= 7)
- cpp-options: -D_LIT=lit
+ -- Note: the following is duplicated in all stanzas.
+ -- It needs to be duplicated because of the library & executable flags.
+ -- BEGIN DUPLICATED SECTION
+ Build-Depends: containers >= 0.1 && < 0.5,
+ parsec >= 3.1 && < 3.2,
+ blaze-html >= 0.4.3.0 && < 0.5,
+ mtl >= 1.1 && < 2.1,
+ network >= 2 && < 2.4,
+ filepath >= 1.1 && < 1.4,
+ process >= 1 && < 1.2,
+ directory >= 1 && < 1.2,
+ bytestring >= 0.9 && < 1.0,
+ zip-archive >= 0.1.1.7 && < 0.2,
+ utf8-string >= 0.3 && < 0.4,
+ old-locale >= 1 && < 1.1,
+ time >= 1.2 && < 1.5,
+ HTTP >= 4000.0.5 && < 4000.3,
+ texmath >= 0.6.0.2 && < 0.7,
+ xml >= 1.3.12 && < 1.4,
+ random >= 1 && < 1.1,
+ extensible-exceptions >= 0.1 && < 0.2,
+ citeproc-hs >= 0.3.4 && < 0.4,
+ pandoc-types >= 1.9.0.2 && < 1.10,
+ json >= 0.4 && < 0.6,
+ tagsoup >= 0.12.5 && < 0.13,
+ base64-bytestring >= 0.1 && < 0.2,
+ zlib >= 0.5 && <= 0.6,
+ highlighting-kate >= 0.5.0.2 && < 0.6,
+ temporary >= 1.1 && < 1.2
+ if impl(ghc >= 6.10)
+ Build-depends: base >= 4 && < 5, syb >= 0.1 && < 0.4
else
- cpp-options: -D_LIT=$lit
+ Build-depends: base >= 3 && < 4
+ if impl(ghc >= 6.12)
+ Ghc-Options: -O2 -Wall -fno-warn-unused-do-bind -dno-debug-output
+ else
+ Ghc-Options: -O2 -Wall
+ if impl(ghc >= 7.0.1)
+ Ghc-Prof-Options: -auto-all -caf-all -rtsopts
+ else
+ Ghc-Prof-Options: -auto-all -caf-all
+ Default-Language: Haskell98
+ Default-Extensions: CPP
+ Other-Extensions: PatternGuards, OverloadedStrings,
+ ScopedTypeVariables, GeneralizedNewtypeDeriving,
+ RelaxedPolyRec, DeriveDataTypeable, TypeSynonymInstances,
+ FlexibleInstances
+ Hs-Source-Dirs: src
+ -- END DUPLICATED SECTION
if !flag(tests)
Buildable: False
else
- if impl(ghc >= 6.12)
- Ghc-Options: -Wall -fno-warn-unused-do-bind
+ Buildable: True
+ if impl(ghc >= 7)
+ cpp-options: -D_LIT=lit
else
- Ghc-Options: -Wall
- Extensions: CPP
- Build-Depends: base >= 4 && < 5, Diff, test-framework >= 0.3 && < 0.5,
+ cpp-options: -D_LIT=$lit
+ Other-Extensions: TemplateHaskell, QuasiQuotes
+ Build-Depends: Diff, test-framework >= 0.3 && < 0.6,
test-framework-hunit >= 0.2 && < 0.3,
test-framework-quickcheck2 >= 0.2.9 && < 0.3,
QuickCheck >= 2.4 && < 2.6,
HUnit >= 1.2 && < 1.3,
- template-haskell >= 2.4 && < 2.6,
+ template-haskell >= 2.4 && < 2.8,
ansi-terminal == 0.5.*
Other-Modules: Tests.Old
Tests.Helpers
diff --git a/reference.docx b/reference.docx
new file mode 100644
index 000000000..c321408d1
--- /dev/null
+++ b/reference.docx
Binary files differ
diff --git a/s5/default/blank.gif b/s5/default/blank.gif
new file mode 100644
index 000000000..75b945d25
--- /dev/null
+++ b/s5/default/blank.gif
Binary files differ
diff --git a/s5/default/bodybg.gif b/s5/default/bodybg.gif
new file mode 100644
index 000000000..5f448a16f
--- /dev/null
+++ b/s5/default/bodybg.gif
Binary files differ
diff --git a/s5/default/iepngfix.htc b/s5/default/iepngfix.htc
new file mode 100644
index 000000000..bba2db756
--- /dev/null
+++ b/s5/default/iepngfix.htc
@@ -0,0 +1,42 @@
+<public:component>
+<public:attach event="onpropertychange" onevent="doFix()" />
+
+<script>
+
+// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
+// Free usage permitted as long as this notice remains intact.
+
+// This must be a path to a blank image. That's all the configuration you need here.
+var blankImg = 'ui/default/blank.gif';
+
+var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+
+function filt(s, m) {
+ if (filters[f]) {
+ filters[f].enabled = s ? true : false;
+ if (s) with (filters[f]) { src = s; sizingMethod = m }
+ } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
+}
+
+function doFix() {
+ if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
+ (event && !/(background|src)/.test(event.propertyName))) return;
+
+ if (tagName == 'IMG') {
+ if ((/\.png$/i).test(src)) {
+ filt(src, 'image'); // was 'scale'
+ src = blankImg;
+ } else if (src.indexOf(blankImg) < 0) filt();
+ } else if (style.backgroundImage) {
+ if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
+ var s = RegExp.$1;
+ style.backgroundImage = '';
+ filt(s, 'crop');
+ } else filt();
+ }
+}
+
+doFix();
+
+</script>
+</public:component> \ No newline at end of file
diff --git a/s5/default/slides.css b/s5/default/slides.css
new file mode 100644
index 000000000..0786d7dbd
--- /dev/null
+++ b/s5/default/slides.css
@@ -0,0 +1,3 @@
+@import url(s5-core.css); /* required to make the slide show run at all */
+@import url(framing.css); /* sets basic placement and size of slide components */
+@import url(pretty.css); /* stuff that makes the slides look better than blah */ \ No newline at end of file
diff --git a/s5/default/slides.js b/s5/default/slides.js
new file mode 100644
index 000000000..38fe8531c
--- /dev/null
+++ b/s5/default/slides.js
@@ -0,0 +1,553 @@
+// S5 v1.1 slides.js -- released into the Public Domain
+//
+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
+// about all the wonderful and talented contributors to this code!
+
+var undef;
+var slideCSS = '';
+var snum = 0;
+var smax = 1;
+var incpos = 0;
+var number = undef;
+var s5mode = true;
+var defaultView = 'slideshow';
+var controlVis = 'visible';
+
+var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;
+var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
+var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
+
+function hasClass(object, className) {
+ if (!object.className) return false;
+ return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
+}
+
+function hasValue(object, value) {
+ if (!object) return false;
+ return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
+}
+
+function removeClass(object,className) {
+ if (!object) return;
+ object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
+}
+
+function addClass(object,className) {
+ if (!object || hasClass(object, className)) return;
+ if (object.className) {
+ object.className += ' '+className;
+ } else {
+ object.className = className;
+ }
+}
+
+function GetElementsWithClassName(elementName,className) {
+ var allElements = document.getElementsByTagName(elementName);
+ var elemColl = new Array();
+ for (var i = 0; i< allElements.length; i++) {
+ if (hasClass(allElements[i], className)) {
+ elemColl[elemColl.length] = allElements[i];
+ }
+ }
+ return elemColl;
+}
+
+function isParentOrSelf(element, id) {
+ if (element == null || element.nodeName=='BODY') return false;
+ else if (element.id == id) return true;
+ else return isParentOrSelf(element.parentNode, id);
+}
+
+function nodeValue(node) {
+ var result = "";
+ if (node.nodeType == 1) {
+ var children = node.childNodes;
+ for (var i = 0; i < children.length; ++i) {
+ result += nodeValue(children[i]);
+ }
+ }
+ else if (node.nodeType == 3) {
+ result = node.nodeValue;
+ }
+ return(result);
+}
+
+function slideLabel() {
+ var slideColl = GetElementsWithClassName('*','slide');
+ var list = document.getElementById('jumplist');
+ smax = slideColl.length;
+ for (var n = 0; n < smax; n++) {
+ var obj = slideColl[n];
+
+ var did = 'slide' + n.toString();
+ obj.setAttribute('id',did);
+ if (isOp) continue;
+
+ var otext = '';
+ var menu = obj.firstChild;
+ if (!menu) continue; // to cope with empty slides
+ while (menu && menu.nodeType == 3) {
+ menu = menu.nextSibling;
+ }
+ if (!menu) continue; // to cope with slides with only text nodes
+
+ var menunodes = menu.childNodes;
+ for (var o = 0; o < menunodes.length; o++) {
+ otext += nodeValue(menunodes[o]);
+ }
+ list.options[list.length] = new Option(n + ' : ' + otext, n);
+ }
+}
+
+function currentSlide() {
+ var cs;
+ if (document.getElementById) {
+ cs = document.getElementById('currentSlide');
+ } else {
+ cs = document.currentSlide;
+ }
+ cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
+ '<span id="csSep">\/<\/span> ' +
+ '<span id="csTotal">' + (smax-1) + '<\/span>';
+ if (snum == 0) {
+ cs.style.visibility = 'hidden';
+ } else {
+ cs.style.visibility = 'visible';
+ }
+}
+
+function go(step) {
+ if (document.getElementById('slideProj').disabled || step == 0) return;
+ var jl = document.getElementById('jumplist');
+ var cid = 'slide' + snum;
+ var ce = document.getElementById(cid);
+ if (incrementals[snum].length > 0) {
+ for (var i = 0; i < incrementals[snum].length; i++) {
+ removeClass(incrementals[snum][i], 'current');
+ removeClass(incrementals[snum][i], 'incremental');
+ }
+ }
+ if (step != 'j') {
+ snum += step;
+ lmax = smax - 1;
+ if (snum > lmax) snum = lmax;
+ if (snum < 0) snum = 0;
+ } else
+ snum = parseInt(jl.value);
+ var nid = 'slide' + snum;
+ var ne = document.getElementById(nid);
+ if (!ne) {
+ ne = document.getElementById('slide0');
+ snum = 0;
+ }
+ if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
+ if (incrementals[snum].length > 0 && incpos == 0) {
+ for (var i = 0; i < incrementals[snum].length; i++) {
+ if (hasClass(incrementals[snum][i], 'current'))
+ incpos = i + 1;
+ else
+ addClass(incrementals[snum][i], 'incremental');
+ }
+ }
+ if (incrementals[snum].length > 0 && incpos > 0)
+ addClass(incrementals[snum][incpos - 1], 'current');
+ ce.style.visibility = 'hidden';
+ ne.style.visibility = 'visible';
+ jl.selectedIndex = snum;
+ currentSlide();
+ number = 0;
+}
+
+function goTo(target) {
+ if (target >= smax || target == snum) return;
+ go(target - snum);
+}
+
+function subgo(step) {
+ if (step > 0) {
+ removeClass(incrementals[snum][incpos - 1],'current');
+ removeClass(incrementals[snum][incpos], 'incremental');
+ addClass(incrementals[snum][incpos],'current');
+ incpos++;
+ } else {
+ incpos--;
+ removeClass(incrementals[snum][incpos],'current');
+ addClass(incrementals[snum][incpos], 'incremental');
+ addClass(incrementals[snum][incpos - 1],'current');
+ }
+}
+
+function toggle() {
+ var slideColl = GetElementsWithClassName('*','slide');
+ var slides = document.getElementById('slideProj');
+ var outline = document.getElementById('outlineStyle');
+ if (!slides.disabled) {
+ slides.disabled = true;
+ outline.disabled = false;
+ s5mode = false;
+ fontSize('1em');
+ for (var n = 0; n < smax; n++) {
+ var slide = slideColl[n];
+ slide.style.visibility = 'visible';
+ }
+ } else {
+ slides.disabled = false;
+ outline.disabled = true;
+ s5mode = true;
+ fontScale();
+ for (var n = 0; n < smax; n++) {
+ var slide = slideColl[n];
+ slide.style.visibility = 'hidden';
+ }
+ slideColl[snum].style.visibility = 'visible';
+ }
+}
+
+function showHide(action) {
+ var obj = GetElementsWithClassName('*','hideme')[0];
+ switch (action) {
+ case 's': obj.style.visibility = 'visible'; break;
+ case 'h': obj.style.visibility = 'hidden'; break;
+ case 'k':
+ if (obj.style.visibility != 'visible') {
+ obj.style.visibility = 'visible';
+ } else {
+ obj.style.visibility = 'hidden';
+ }
+ break;
+ }
+}
+
+// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
+function keys(key) {
+ if (!key) {
+ key = event;
+ key.which = key.keyCode;
+ }
+ if (key.which == 84) {
+ toggle();
+ return;
+ }
+ if (s5mode) {
+ switch (key.which) {
+ case 10: // return
+ case 13: // enter
+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
+ if (key.target && isParentOrSelf(key.target, 'controls')) return;
+ if(number != undef) {
+ goTo(number);
+ break;
+ }
+ case 32: // spacebar
+ case 34: // page down
+ case 39: // rightkey
+ case 40: // downkey
+ if(number != undef) {
+ go(number);
+ } else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
+ go(1);
+ } else {
+ subgo(1);
+ }
+ break;
+ case 33: // page up
+ case 37: // leftkey
+ case 38: // upkey
+ if(number != undef) {
+ go(-1 * number);
+ } else if (!incrementals[snum] || incpos <= 0) {
+ go(-1);
+ } else {
+ subgo(-1);
+ }
+ break;
+ case 36: // home
+ goTo(0);
+ break;
+ case 35: // end
+ goTo(smax-1);
+ break;
+ case 67: // c
+ showHide('k');
+ break;
+ }
+ if (key.which < 48 || key.which > 57) {
+ number = undef;
+ } else {
+ if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
+ if (key.target && isParentOrSelf(key.target, 'controls')) return;
+ number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
+ }
+ }
+ return false;
+}
+
+function clicker(e) {
+ number = undef;
+ var target;
+ if (window.event) {
+ target = window.event.srcElement;
+ e = window.event;
+ } else target = e.target;
+ if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;
+ if (!e.which || e.which == 1) {
+ if (!incrementals[snum] || incpos >= incrementals[snum].length) {
+ go(1);
+ } else {
+ subgo(1);
+ }
+ }
+}
+
+function findSlide(hash) {
+ var target = null;
+ var slides = GetElementsWithClassName('*','slide');
+ for (var i = 0; i < slides.length; i++) {
+ var targetSlide = slides[i];
+ if ( (targetSlide.name && targetSlide.name == hash)
+ || (targetSlide.id && targetSlide.id == hash) ) {
+ target = targetSlide;
+ break;
+ }
+ }
+ while(target != null && target.nodeName != 'BODY') {
+ if (hasClass(target, 'slide')) {
+ return parseInt(target.id.slice(5));
+ }
+ target = target.parentNode;
+ }
+ return null;
+}
+
+function slideJump() {
+ if (window.location.hash == null) return;
+ var sregex = /^#slide(\d+)$/;
+ var matches = sregex.exec(window.location.hash);
+ var dest = null;
+ if (matches != null) {
+ dest = parseInt(matches[1]);
+ } else {
+ dest = findSlide(window.location.hash.slice(1));
+ }
+ if (dest != null)
+ go(dest - snum);
+}
+
+function fixLinks() {
+ var thisUri = window.location.href;
+ thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
+ var aelements = document.getElementsByTagName('A');
+ for (var i = 0; i < aelements.length; i++) {
+ var a = aelements[i].href;
+ var slideID = a.match('\#slide[0-9]{1,2}');
+ if ((slideID) && (slideID[0].slice(0,1) == '#')) {
+ var dest = findSlide(slideID[0].slice(1));
+ if (dest != null) {
+ if (aelements[i].addEventListener) {
+ aelements[i].addEventListener("click", new Function("e",
+ "if (document.getElementById('slideProj').disabled) return;" +
+ "go("+dest+" - snum); " +
+ "if (e.preventDefault) e.preventDefault();"), true);
+ } else if (aelements[i].attachEvent) {
+ aelements[i].attachEvent("onclick", new Function("",
+ "if (document.getElementById('slideProj').disabled) return;" +
+ "go("+dest+" - snum); " +
+ "event.returnValue = false;"));
+ }
+ }
+ }
+ }
+}
+
+function externalLinks() {
+ if (!document.getElementsByTagName) return;
+ var anchors = document.getElementsByTagName('a');
+ for (var i=0; i<anchors.length; i++) {
+ var anchor = anchors[i];
+ if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
+ anchor.target = '_blank';
+ addClass(anchor,'external');
+ }
+ }
+}
+
+function createControls() {
+ var controlsDiv = document.getElementById("controls");
+ if (!controlsDiv) return;
+ var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';
+ var hideDiv, hideList = '';
+ if (controlVis == 'hidden') {
+ hideDiv = hider;
+ } else {
+ hideList = hider;
+ }
+ controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' +
+ '<div id="navLinks">' +
+ '<a accesskey="t" id="toggle" href="javascript:toggle();">&#216;<\/a>' +
+ '<a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;<\/a>' +
+ '<a accesskey="x" id="next" href="javascript:go(1);">&raquo;<\/a>' +
+ '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' +
+ '<\/div><\/form>';
+ if (controlVis == 'hidden') {
+ var hidden = document.getElementById('navLinks');
+ } else {
+ var hidden = document.getElementById('jumplist');
+ }
+ addClass(hidden,'hideme');
+}
+
+function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers
+ if (!s5mode) return false;
+ var vScale = 22; // both yield 32 (after rounding) at 1024x768
+ var hScale = 32; // perhaps should auto-calculate based on theme's declared value?
+ if (window.innerHeight) {
+ var vSize = window.innerHeight;
+ var hSize = window.innerWidth;
+ } else if (document.documentElement.clientHeight) {
+ var vSize = document.documentElement.clientHeight;
+ var hSize = document.documentElement.clientWidth;
+ } else if (document.body.clientHeight) {
+ var vSize = document.body.clientHeight;
+ var hSize = document.body.clientWidth;
+ } else {
+ var vSize = 700; // assuming 1024x768, minus chrome and such
+ var hSize = 1024; // these do not account for kiosk mode or Opera Show
+ }
+ var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
+ fontSize(newSize + 'px');
+ if (isGe) { // hack to counter incremental reflow bugs
+ var obj = document.getElementsByTagName('body')[0];
+ obj.style.display = 'none';
+ obj.style.display = 'block';
+ }
+}
+
+function fontSize(value) {
+ if (!(s5ss = document.getElementById('s5ss'))) {
+ if (!isIE) {
+ document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
+ s5ss.setAttribute('media','screen, projection');
+ s5ss.setAttribute('id','s5ss');
+ } else {
+ document.createStyleSheet();
+ document.s5ss = document.styleSheets[document.styleSheets.length - 1];
+ }
+ }
+ if (!isIE) {
+ while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
+ s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));
+ } else {
+ document.s5ss.addRule('body','font-size: ' + value + ' !important;');
+ }
+}
+
+function notOperaFix() {
+ slideCSS = document.getElementById('slideProj').href;
+ var slides = document.getElementById('slideProj');
+ var outline = document.getElementById('outlineStyle');
+ slides.setAttribute('media','screen');
+ outline.disabled = true;
+ if (isGe) {
+ slides.setAttribute('href','null'); // Gecko fix
+ slides.setAttribute('href',slideCSS); // Gecko fix
+ }
+ if (isIE && document.styleSheets && document.styleSheets[0]) {
+ document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');
+ document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');
+ document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');
+ }
+}
+
+function getIncrementals(obj) {
+ var incrementals = new Array();
+ if (!obj)
+ return incrementals;
+ var children = obj.childNodes;
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ if (hasClass(child, 'incremental')) {
+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {
+ removeClass(child, 'incremental');
+ for (var j = 0; j < child.childNodes.length; j++) {
+ if (child.childNodes[j].nodeType == 1) {
+ addClass(child.childNodes[j], 'incremental');
+ }
+ }
+ } else {
+ incrementals[incrementals.length] = child;
+ removeClass(child,'incremental');
+ }
+ }
+ if (hasClass(child, 'show-first')) {
+ if (child.nodeName == 'OL' || child.nodeName == 'UL') {
+ removeClass(child, 'show-first');
+ if (child.childNodes[isGe].nodeType == 1) {
+ removeClass(child.childNodes[isGe], 'incremental');
+ }
+ } else {
+ incrementals[incrementals.length] = child;
+ }
+ }
+ incrementals = incrementals.concat(getIncrementals(child));
+ }
+ return incrementals;
+}
+
+function createIncrementals() {
+ var incrementals = new Array();
+ for (var i = 0; i < smax; i++) {
+ incrementals[i] = getIncrementals(document.getElementById('slide'+i));
+ }
+ return incrementals;
+}
+
+function defaultCheck() {
+ var allMetas = document.getElementsByTagName('meta');
+ for (var i = 0; i< allMetas.length; i++) {
+ if (allMetas[i].name == 'defaultView') {
+ defaultView = allMetas[i].content;
+ }
+ if (allMetas[i].name == 'controlVis') {
+ controlVis = allMetas[i].content;
+ }
+ }
+}
+
+// Key trap fix, new function body for trap()
+function trap(e) {
+ if (!e) {
+ e = event;
+ e.which = e.keyCode;
+ }
+ try {
+ modifierKey = e.ctrlKey || e.altKey || e.metaKey;
+ }
+ catch(e) {
+ modifierKey = false;
+ }
+ return modifierKey || e.which == 0;
+}
+
+function startup() {
+ defaultCheck();
+ if (!isOp)
+ createControls();
+ slideLabel();
+ fixLinks();
+ externalLinks();
+ fontScale();
+ if (!isOp) {
+ notOperaFix();
+ incrementals = createIncrementals();
+ slideJump();
+ if (defaultView == 'outline') {
+ toggle();
+ }
+ document.onkeyup = keys;
+ document.onkeypress = trap;
+ document.onclick = clicker;
+ }
+}
+
+window.onload = startup;
+window.onresize = function(){setTimeout('fontScale()', 50);} \ No newline at end of file
diff --git a/s5/default/slides.min.js b/s5/default/slides.min.js
deleted file mode 100644
index 84bd3507f..000000000
--- a/s5/default/slides.min.js
+++ /dev/null
@@ -1 +0,0 @@
-var undef;var slideCSS="";var snum=0;var smax=1;var incpos=0;var number=undef;var s5mode=true;var defaultView="slideshow";var controlVis="visible";var isIE=navigator.appName=="Microsoft Internet Explorer"&&navigator.userAgent.indexOf("Opera")<1?1:0;var isOp=navigator.userAgent.indexOf("Opera")>-1?1:0;var isGe=navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("Safari")<1?1:0;function hasClass(a,b){if(!a.className){return false}return(a.className.search("(^|\\s)"+b+"(\\s|$)")!=-1)}function hasValue(a,b){if(!a){return false}return(a.search("(^|\\s)"+b+"(\\s|$)")!=-1)}function removeClass(a,b){if(!a){return}a.className=a.className.replace(new RegExp("(^|\\s)"+b+"(\\s|$)"),RegExp.$1+RegExp.$2)}function addClass(a,b){if(!a||hasClass(a,b)){return}if(a.className){a.className+=" "+b}else{a.className=b}}function GetElementsWithClassName(a,c){var d=document.getElementsByTagName(a);var e=new Array();for(var b=0;b<d.length;b++){if(hasClass(d[b],c)){e[e.length]=d[b]}}return e}function isParentOrSelf(a,b){if(a==null||a.nodeName=="BODY"){return false}else{if(a.id==b){return true}else{return isParentOrSelf(a.parentNode,b)}}}function nodeValue(d){var a="";if(d.nodeType==1){var c=d.childNodes;for(var b=0;b<c.length;++b){a+=nodeValue(c[b])}}else{if(d.nodeType==3){a=d.nodeValue}}return(a)}function slideLabel(){var f=GetElementsWithClassName("*","slide");var g=document.getElementById("jumplist");smax=f.length;for(var c=0;c<smax;c++){var e=f[c];var i="slide"+c.toString();e.setAttribute("id",i);if(isOp){continue}var d="";var b=e.firstChild;if(!b){continue}while(b&&b.nodeType==3){b=b.nextSibling}if(!b){continue}var h=b.childNodes;for(var a=0;a<h.length;a++){d+=nodeValue(h[a])}g.options[g.length]=new Option(c+" : "+d,c)}}function currentSlide(){var a;if(document.getElementById){a=document.getElementById("currentSlide")}else{a=document.currentSlide}a.innerHTML='<span id="csHere">'+snum+'</span> <span id="csSep">/</span> <span id="csTotal">'+(smax-1)+"</span>";if(snum==0){a.style.visibility="hidden"}else{a.style.visibility="visible"}}function go(c){if(document.getElementById("slideProj").disabled||c==0){return}var b=document.getElementById("jumplist");var g="slide"+snum;var e=document.getElementById(g);if(incrementals[snum].length>0){for(var a=0;a<incrementals[snum].length;a++){removeClass(incrementals[snum][a],"current");removeClass(incrementals[snum][a],"incremental")}}if(c!="j"){snum+=c;lmax=smax-1;if(snum>lmax){snum=lmax}if(snum<0){snum=0}}else{snum=parseInt(b.value)}var f="slide"+snum;var d=document.getElementById(f);if(!d){d=document.getElementById("slide0");snum=0}if(c<0){incpos=incrementals[snum].length}else{incpos=0}if(incrementals[snum].length>0&&incpos==0){for(var a=0;a<incrementals[snum].length;a++){if(hasClass(incrementals[snum][a],"current")){incpos=a+1}else{addClass(incrementals[snum][a],"incremental")}}}if(incrementals[snum].length>0&&incpos>0){addClass(incrementals[snum][incpos-1],"current")}e.style.visibility="hidden";d.style.visibility="visible";b.selectedIndex=snum;currentSlide();number=0}function goTo(a){if(a>=smax||a==snum){return}go(a-snum)}function subgo(a){if(a>0){removeClass(incrementals[snum][incpos-1],"current");removeClass(incrementals[snum][incpos],"incremental");addClass(incrementals[snum][incpos],"current");incpos++}else{incpos--;removeClass(incrementals[snum][incpos],"current");addClass(incrementals[snum][incpos],"incremental");addClass(incrementals[snum][incpos-1],"current")}}function toggle(){var b=GetElementsWithClassName("*","slide");var d=document.getElementById("slideProj");var c=document.getElementById("outlineStyle");if(!d.disabled){d.disabled=true;c.disabled=false;s5mode=false;fontSize("1em");for(var e=0;e<smax;e++){var a=b[e];a.style.visibility="visible"}}else{d.disabled=false;c.disabled=true;s5mode=true;fontScale();for(var e=0;e<smax;e++){var a=b[e];a.style.visibility="hidden"}b[snum].style.visibility="visible"}}function showHide(a){var b=GetElementsWithClassName("*","hideme")[0];switch(a){case"s":b.style.visibility="visible";break;case"h":b.style.visibility="hidden";break;case"k":if(b.style.visibility!="visible"){b.style.visibility="visible"}else{b.style.visibility="hidden"}break}}function keys(a){if(!a){a=event;a.which=a.keyCode}if(a.which==84){toggle();return}if(s5mode){switch(a.which){case 10:case 13:if(window.event&&isParentOrSelf(window.event.srcElement,"controls")){return}if(a.target&&isParentOrSelf(a.target,"controls")){return}if(number!=undef){goTo(number);break}case 32:case 34:case 39:case 40:if(number!=undef){go(number)}else{if(!incrementals[snum]||incpos>=incrementals[snum].length){go(1)}else{subgo(1)}}break;case 33:case 37:case 38:if(number!=undef){go(-1*number)}else{if(!incrementals[snum]||incpos<=0){go(-1)}else{subgo(-1)}}break;case 36:goTo(0);break;case 35:goTo(smax-1);break;case 67:showHide("k");break}if(a.which<48||a.which>57){number=undef}else{if(window.event&&isParentOrSelf(window.event.srcElement,"controls")){return}if(a.target&&isParentOrSelf(a.target,"controls")){return}number=(((number!=undef)?number:0)*10)+(a.which-48)}}return false}function clicker(b){number=undef;var a;if(window.event){a=window.event.srcElement;b=window.event}else{a=b.target}if(a.getAttribute("href")!=null||hasValue(a.rel,"external")||isParentOrSelf(a,"controls")||isParentOrSelf(a,"embed")||isParentOrSelf(a,"object")){return true}if(!b.which||b.which==1){if(!incrementals[snum]||incpos>=incrementals[snum].length){go(1)}else{subgo(1)}}}function findSlide(d){var c=null;var b=GetElementsWithClassName("*","slide");for(var a=0;a<b.length;a++){var e=b[a];if((e.name&&e.name==d)||(e.id&&e.id==d)){c=e;break}}while(c!=null&&c.nodeName!="BODY"){if(hasClass(c,"slide")){return parseInt(c.id.slice(5))}c=c.parentNode}return null}function slideJump(){if(window.location.hash==null){return}var b=/^#slide(\d+)$/;var c=b.exec(window.location.hash);var a=null;if(c!=null){a=parseInt(c[1])}else{a=findSlide(window.location.hash.slice(1))}if(a!=null){go(a-snum)}}function fixLinks(){var f=window.location.href;f=f.slice(0,f.length-window.location.hash.length);var g=document.getElementsByTagName("A");for(var e=0;e<g.length;e++){var b=g[e].href;var d=b.match("#slide[0-9]{1,2}");if((d)&&(d[0].slice(0,1)=="#")){var c=findSlide(d[0].slice(1));if(c!=null){if(g[e].addEventListener){g[e].addEventListener("click",new Function("e","if (document.getElementById('slideProj').disabled) return;go("+c+" - snum); if (e.preventDefault) e.preventDefault();"),true)}else{if(g[e].attachEvent){g[e].attachEvent("onclick",new Function("","if (document.getElementById('slideProj').disabled) return;go("+c+" - snum); event.returnValue = false;"))}}}}}}function externalLinks(){if(!document.getElementsByTagName){return}var c=document.getElementsByTagName("a");for(var b=0;b<c.length;b++){var a=c[b];if(a.getAttribute("href")&&hasValue(a.rel,"external")){a.target="_blank";addClass(a,"external")}}}function createControls(){var e=document.getElementById("controls");if(!e){return}var c=" onmouseover=\"showHide('s');\" onmouseout=\"showHide('h');\"";var d,a="";if(controlVis=="hidden"){d=c}else{a=c}e.innerHTML='<form action="#" id="controlForm"'+d+'><div id="navLinks"><a accesskey="t" id="toggle" href="javascript:toggle();">&#216;</a><a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;</a><a accesskey="x" id="next" href="javascript:go(1);">&raquo;</a><div id="navList"'+a+'><select id="jumplist" onchange="go(\'j\');"></select></div></div></form>';if(controlVis=="hidden"){var b=document.getElementById("navLinks")}else{var b=document.getElementById("jumplist")}addClass(b,"hideme")}function fontScale(){if(!s5mode){return false}var f=22;var a=32;if(window.innerHeight){var c=window.innerHeight;var e=window.innerWidth}else{if(document.documentElement.clientHeight){var c=document.documentElement.clientHeight;var e=document.documentElement.clientWidth}else{if(document.body.clientHeight){var c=document.body.clientHeight;var e=document.body.clientWidth}else{var c=700;var e=1024}}}var b=Math.min(Math.round(c/f),Math.round(e/a));fontSize(b+"px");if(isGe){var d=document.getElementsByTagName("body")[0];d.style.display="none";d.style.display="block"}}function fontSize(a){if(!(s5ss=document.getElementById("s5ss"))){if(!isIE){document.getElementsByTagName("head")[0].appendChild(s5ss=document.createElement("style"));s5ss.setAttribute("media","screen, projection");s5ss.setAttribute("id","s5ss")}else{document.createStyleSheet();document.s5ss=document.styleSheets[document.styleSheets.length-1]}}if(!isIE){while(s5ss.lastChild){s5ss.removeChild(s5ss.lastChild)}s5ss.appendChild(document.createTextNode("body {font-size: "+a+" !important;}"))}else{document.s5ss.addRule("body","font-size: "+a+" !important;")}}function notOperaFix(){slideCSS=document.getElementById("slideProj").href;var b=document.getElementById("slideProj");var a=document.getElementById("outlineStyle");b.setAttribute("media","screen");a.disabled=true;if(isGe){b.setAttribute("href","null");b.setAttribute("href",slideCSS)}if(isIE&&document.styleSheets&&document.styleSheets[0]){document.styleSheets[0].addRule("img","behavior: url(ui/default/iepngfix.htc)");document.styleSheets[0].addRule("div","behavior: url(ui/default/iepngfix.htc)");document.styleSheets[0].addRule(".slide","behavior: url(ui/default/iepngfix.htc)")}}function getIncrementals(e){var d=new Array();if(!e){return d}var c=e.childNodes;for(var b=0;b<c.length;b++){var f=c[b];if(hasClass(f,"incremental")){if(f.nodeName=="OL"||f.nodeName=="UL"){removeClass(f,"incremental");for(var a=0;a<f.childNodes.length;a++){if(f.childNodes[a].nodeType==1){addClass(f.childNodes[a],"incremental")}}}else{d[d.length]=f;removeClass(f,"incremental")}}if(hasClass(f,"show-first")){if(f.nodeName=="OL"||f.nodeName=="UL"){removeClass(f,"show-first");if(f.childNodes[isGe].nodeType==1){removeClass(f.childNodes[isGe],"incremental")}}else{d[d.length]=f}}d=d.concat(getIncrementals(f))}return d}function createIncrementals(){var b=new Array();for(var a=0;a<smax;a++){b[a]=getIncrementals(document.getElementById("slide"+a))}return b}function defaultCheck(){var a=document.getElementsByTagName("meta");for(var b=0;b<a.length;b++){if(a[b].name=="defaultView"){defaultView=a[b].content}if(a[b].name=="controlVis"){controlVis=a[b].content}}}function trap(a){if(!a){a=event;a.which=a.keyCode}try{modifierKey=a.ctrlKey||a.altKey||a.metaKey}catch(a){modifierKey=false}return modifierKey||a.which==0}function startup(){defaultCheck();if(!isOp){createControls()}slideLabel();fixLinks();externalLinks();fontScale();if(!isOp){notOperaFix();incrementals=createIncrementals();slideJump();if(defaultView=="outline"){toggle()}document.onkeyup=keys;document.onkeypress=trap;document.onclick=clicker}}window.onload=startup;window.onresize=function(){setTimeout("fontScale()",50)}; \ No newline at end of file
diff --git a/slidy/graphics/fold-dim.gif b/slidy/graphics/fold-dim.gif
new file mode 100644
index 000000000..346fcbf3e
--- /dev/null
+++ b/slidy/graphics/fold-dim.gif
Binary files differ
diff --git a/slidy/graphics/fold.gif b/slidy/graphics/fold.gif
new file mode 100644
index 000000000..133e594fd
--- /dev/null
+++ b/slidy/graphics/fold.gif
Binary files differ
diff --git a/slidy/graphics/nofold-dim.gif b/slidy/graphics/nofold-dim.gif
new file mode 100644
index 000000000..996fb5eda
--- /dev/null
+++ b/slidy/graphics/nofold-dim.gif
Binary files differ
diff --git a/slidy/graphics/unfold-dim.gif b/slidy/graphics/unfold-dim.gif
new file mode 100644
index 000000000..bee567117
--- /dev/null
+++ b/slidy/graphics/unfold-dim.gif
Binary files differ
diff --git a/slidy/graphics/unfold.gif b/slidy/graphics/unfold.gif
new file mode 100644
index 000000000..0753ae4d2
--- /dev/null
+++ b/slidy/graphics/unfold.gif
Binary files differ
diff --git a/slidy/scripts/slidy.js.gz b/slidy/scripts/slidy.js.gz
new file mode 100644
index 000000000..72bbd63d0
--- /dev/null
+++ b/slidy/scripts/slidy.js.gz
Binary files differ
diff --git a/slidy/slidy.min.js b/slidy/slidy.min.js
deleted file mode 100644
index ef9ae454d..000000000
--- a/slidy/slidy.min.js
+++ /dev/null
@@ -1 +0,0 @@
-var w3c_slidy={ns_pos:(typeof window.pageYOffset!="undefined"),khtml:((navigator.userAgent).indexOf("KHTML")>=0?true:false),opera:((navigator.userAgent).indexOf("Opera")>=0?true:false),ipad:((navigator.userAgent).indexOf("iPad")>=0?true:false),iphone:((navigator.userAgent).indexOf("iPhone")>=0?true:false),ie:(typeof document.all!="undefined"&&!this.opera),ie6:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 6")!=-1),ie7:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 7")!=-1),ie8:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 8")!=-1),ie9:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 9")!=-1),keyboardless:(this.ipad||this.iphone),is_xhtml:/xml/.test(document.contentType),slide_number:0,slide_number_element:null,slides:[],notes:[],backgrounds:[],toolbar:null,title:null,last_shown:null,eos:null,toc:null,outline:null,selected_text_len:0,view_all:0,want_toolbar:true,mouse_click_enabled:true,scroll_hack:0,disable_slide_click:false,lang:"en",help_anchor:null,help_page:"http://www.w3.org/Talks/Tools/Slidy2/help/help.html",help_text:"Navigate with mouse click, space bar, Cursor Left/Right, or Pg Up and Pg Dn. Use S and B to change font size.",size_index:0,size_adjustment:0,sizes:new Array("10pt","12pt","14pt","16pt","18pt","20pt","22pt","24pt","26pt","28pt","30pt","32pt"),last_width:0,last_height:0,objects:[],set_up:function(){var a=function(){w3c_slidy.init()};if(typeof window.addEventListener!="undefined"){window.addEventListener("load",a,false)}else{window.attachEvent("onload",a)}},hide_slides:function(){if(document.body&&!w3c_slidy.initialized){document.body.style.visibility="hidden"}else{setTimeout(w3c_slidy.hide_slides,50)}},ie_hack:function(){window.resizeBy(0,-1);window.resizeBy(0,1)},init:function(){document.body.style.visibility="visible";this.init_localization();this.add_toolbar();this.wrap_implicit_slides();this.collect_slides();this.collect_notes();this.collect_backgrounds();this.objects=document.body.getElementsByTagName("object");this.patch_anchors();this.slide_number=this.find_slide_number(location.href);window.offscreenbuffering=true;this.size_adjustment=this.find_size_adjust();this.time_left=this.find_duration();this.hide_image_toolbar();this.init_outliner();this.title=document.title;this.is_xhtml=(document.body.tagName=="BODY"?false:true);if(this.slides.length>0){var a=this.slides[this.slide_number];if(this.slide_number>0){this.set_visibility_all_incremental("visible");this.last_shown=this.previous_incremental_item(null);this.set_eos_status(true)}else{this.last_shown=null;this.set_visibility_all_incremental("hidden");this.set_eos_status(!this.next_incremental_item(this.last_shown))}this.set_location();this.add_class(this.slides[0],"first-slide");w3c_slidy.show_slide(a)}this.toc=this.table_of_contents();this.add_initial_prompt();if(!this.keyboardless){this.add_listener(document.body,"click",this.mouse_button_click)}this.add_listener(document,"keydown",this.key_down);this.add_listener(document,"keypress",this.key_press);this.add_listener(window,"resize",this.resized);this.add_listener(window,"scroll",this.scrolled);this.add_listener(window,"unload",this.unloaded);this.single_slide_view();this.resized();if(this.ie7){setTimeout(w3c_slidy.ie_hack,100)}this.show_toolbar();setInterval(function(){w3c_slidy.check_location()},200);w3c_slidy.initialized=true},table_of_contents:function(){var c=this.create_element("div");this.add_class(c,"slidy_toc hidden");var k=this.create_element("div");this.add_class(k,"toc-heading");k.innerHTML=this.localize("Table of Contents");c.appendChild(k);var f=null;for(var d=0;d<this.slides.length;++d){var g=this.has_class(this.slides[d],"title");var e=document.createTextNode((d+1)+". ");c.appendChild(e);var h=this.create_element("a");h.setAttribute("href","#("+(d+1)+")");if(g){this.add_class(h,"titleslide")}var b=document.createTextNode(this.slide_name(d));h.appendChild(b);h.onclick=w3c_slidy.toc_click;h.onkeydown=w3c_slidy.toc_key_down;h.previous=f;if(f){f.next=h}c.appendChild(h);if(d==0){c.first=h}if(d<this.slides.length-1){var j=this.create_element("br");c.appendChild(j)}f=h}c.focus=function(){if(this.first){this.first.focus()}};c.onmouseup=w3c_slidy.mouse_button_up;c.onclick=function(a){a||(a=window.event);if(w3c_slidy.selected_text_len<=0){w3c_slidy.hide_table_of_contents(true)}w3c_slidy.stop_propagation(a);if(a.cancel!=undefined){a.cancel=true}if(a.returnValue!=undefined){a.returnValue=false}return false};document.body.insertBefore(c,document.body.firstChild);return c},is_shown_toc:function(){return !w3c_slidy.has_class(w3c_slidy.toc,"hidden")},show_table_of_contents:function(){w3c_slidy.remove_class(w3c_slidy.toc,"hidden");var a=w3c_slidy.toc;a.focus();if(w3c_slidy.ie7&&w3c_slidy.slide_number==0){setTimeout(w3c_slidy.ie_hack,100)}},hide_table_of_contents:function(a){w3c_slidy.add_class(w3c_slidy.toc,"hidden");if(a&&!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}},toggle_table_of_contents:function(){if(w3c_slidy.is_shown_toc()){w3c_slidy.hide_table_of_contents(true)}else{w3c_slidy.show_table_of_contents()}},toc_click:function(d){if(!d){d=window.event}var c=w3c_slidy.get_target(d);if(c&&c.nodeType==1){var b=c.getAttribute("href");if(b){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.find_slide_number(b);a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_location();w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.show_slide(a);try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(d){}}}w3c_slidy.hide_table_of_contents(true);if(w3c_slidy.ie7){w3c_slidy.ie_hack()}w3c_slidy.stop_propagation(d);return w3c_slidy.cancel(d)},toc_key_down:function(d){var b;if(!d){var d=window.event}if(window.event){b=window.event.keyCode}else{if(d.which){b=d.which}else{return true}}if(!b){return true}if(d.ctrlKey||d.altKey){return true}if(b==13){var c=this.getAttribute("href");if(c){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.find_slide_number(c);a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_location();w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.show_slide(a);try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(f){}}w3c_slidy.hide_table_of_contents(true);if(self.ie7){w3c_slidy.ie_hack()}return w3c_slidy.cancel(d)}if(b==40&&this.next){this.next.focus();return w3c_slidy.cancel(d)}if(b==38&&this.previous){this.previous.focus();return w3c_slidy.cancel(d)}return true},before_print:function(){this.show_all_slides();this.hide_toolbar();alert("before print")},after_print:function(){if(!this.view_all){this.single_slide_view();this.show_toolbar()}alert("after print")},print_slides:function(){this.before_print();window.print();this.after_print()},toggle_view:function(){if(this.view_all){this.single_slide_view();this.show_toolbar();this.view_all=0}else{this.show_all_slides();this.hide_toolbar();this.view_all=1}},show_all_slides:function(){this.remove_class(document.body,"single_slide");this.set_visibility_all_incremental("visible")},single_slide_view:function(){this.add_class(document.body,"single_slide");this.set_visibility_all_incremental("visible");this.last_shown=this.previous_incremental_item(null)},hide_image_toolbar:function(){if(!this.ns_pos){var a=document.getElementsByTagName("IMG");for(var b=0;b<a.length;++b){a[b].setAttribute("galleryimg","no")}}},unloaded:function(a){},is_KHTML:function(){var a=navigator.userAgent;return(a.indexOf("KHTML")>=0?true:false)},slide_name:function(c){var b=null;var a=this.slides[c];var d=this.find_heading(a);if(d){b=this.extract_text(d)}if(!b){b=this.title+"("+(c+1)+")"}b.replace(/\&/g,"&amp;");b.replace(/\</g,"&lt;");b.replace(/\>/g,"&gt;");return b},find_heading:function(a){if(!a||a.nodeType!=1){return null}if(a.nodeName=="H1"||a.nodeName=="h1"){return a}var b=a.firstChild;while(b){a=this.find_heading(b);if(a){return a}b=b.nextSibling}return null},extract_text:function(a){if(!a){return""}if(a.nodeType==3){return a.nodeValue}if(a.nodeType==1){a=a.firstChild;var b="";while(a){b=b+this.extract_text(a);a=a.nextSibling}return b}return""},find_copyright:function(){var a,c;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="copyright"){return c}}return null},find_size_adjust:function(){var a,c,e;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="font-size-adjustment"){return 1*c}}return 1},find_duration:function(){var a,c,e;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="duration"){return 60000*c}}return null},replace_by_non_breaking_space:function(b){for(var a=0;a<b.length;++a){b[a]=160}},init_outliner:function(){var a=document.getElementsByTagName("li");for(var b=0;b<a.length;++b){var c=a[b];if(!this.has_class(c.parentNode,"outline")){continue}c.onclick=this.outline_click;if(this.foldable(c)){c.foldable=true;c.onfocus=function(){w3c_slidy.outline=this};c.onblur=function(){w3c_slidy.outline=null};if(!c.getAttribute("tabindex")){c.setAttribute("tabindex","0")}if(this.has_class(c,"expand")){this.unfold(c)}else{this.fold(c)}}else{this.add_class(c,"nofold");c.visible=true;c.foldable=false}}},foldable:function(b){if(!b||b.nodeType!=1){return false}var a=b.firstChild;while(a){if(a.nodeType==1&&this.is_block(a)){return true}a=a.nextSibling}return false},fold:function(b){if(b){this.remove_class(b,"unfolded");this.add_class(b,"folded")}var a=b?b.firstChild:null;while(a){if(a.nodeType==1&&this.is_block(a)){w3c_slidy.add_class(a,"hidden")}a=a.nextSibling}b.visible=false},unfold:function(b){if(b){this.add_class(b,"unfolded");this.remove_class(b,"folded")}var a=b?b.firstChild:null;while(a){if(a.nodeType==1&&this.is_block(a)){w3c_slidy.remove_class(a,"hidden")}a=a.nextSibling}b.visible=true},outline_click:function(c){if(!c){c=window.event}var a=false;var b=w3c_slidy.get_target(c);while(b&&b.visible==undefined){b=b.parentNode}if(!b){return true}if(c.which){a=(c.which==3)}else{if(c.button){a=(c.button==2)}}if(!a&&b.visible!=undefined){if(b.foldable){if(b.visible){w3c_slidy.fold(b)}else{w3c_slidy.unfold(b)}}w3c_slidy.stop_propagation(c);c.cancel=true;c.returnValue=false}return false},add_initial_prompt:function(){var a=this.create_element("div");a.setAttribute("class","initial_prompt");var b=this.create_element("p");a.appendChild(b);b.setAttribute("class","help");if(this.keyboardless){b.innerHTML="Tap footer to move to next slide"}else{b.innerHTML="Space or Right Arrow to move to next slide, click help below for more details"}this.add_listener(a,"click",function(c){document.body.removeChild(a);w3c_slidy.stop_propagation(c);if(c.cancel!=undefined){c.cancel=true}if(c.returnValue!=undefined){c.returnValue=false}return false});document.body.appendChild(a);this.initial_prompt=a;setTimeout(function(){document.body.removeChild(a)},5000)},add_toolbar:function(){var a,i;this.toolbar=this.create_element("div");this.toolbar.setAttribute("class","toolbar");if(this.ns_pos||!this.ie6){var k=this.create_element("div");k.setAttribute("style","float: right; text-align: right");a=this.create_element("span");a.innerHTML=this.localize("slide")+" n/m";k.appendChild(a);this.toolbar.appendChild(k);var e=this.create_element("div");e.setAttribute("style","text-align: left");this.eos=this.create_element("span");this.eos.innerHTML="* ";e.appendChild(this.eos);var g=this.create_element("a");g.setAttribute("href",this.help_page);g.setAttribute("title",this.localize(this.help_text));g.innerHTML=this.localize("help?");e.appendChild(g);this.help_anchor=g;var d=document.createTextNode(" ");e.appendChild(d);var f=this.create_element("a");f.setAttribute("href","javascript:w3c_slidy.toggle_table_of_contents()");f.setAttribute("title",this.localize("table of contents"));f.innerHTML=this.localize("contents?");e.appendChild(f);var b=document.createTextNode(" ");e.appendChild(b);var h=this.find_copyright();if(h){var j=this.create_element("span");j.className="copyright";j.innerHTML=h;e.appendChild(j)}this.toolbar.setAttribute("tabindex","0");this.toolbar.appendChild(e)}else{this.toolbar.style.position=(this.ie7?"fixed":"absolute");this.toolbar.style.zIndex="200";this.toolbar.style.width="99.9%";this.toolbar.style.height="1.2em";this.toolbar.style.top="auto";this.toolbar.style.bottom="0";this.toolbar.style.left="0";this.toolbar.style.right="0";this.toolbar.style.textAlign="left";this.toolbar.style.fontSize="60%";this.toolbar.style.color="red";this.toolbar.borderWidth=0;this.toolbar.className="toolbar";this.toolbar.style.background="rgb(240,240,240)";var c=this.create_element("span");c.innerHTML="&nbsp;&nbsp;*&nbsp;";this.toolbar.appendChild(c);this.eos=c;var g=this.create_element("a");g.setAttribute("href",this.help_page);g.setAttribute("title",this.localize(this.help_text));g.innerHTML=this.localize("help?");this.toolbar.appendChild(g);this.help_anchor=g;var d=document.createTextNode(" ");this.toolbar.appendChild(d);var f=this.create_element("a");f.setAttribute("href","javascript:toggleTableOfContents()");f.setAttribute("title",this.localize("table of contents".localize));f.innerHTML=this.localize("contents?");this.toolbar.appendChild(f);var b=document.createTextNode(" ");this.toolbar.appendChild(b);var h=this.find_copyright();if(h){var j=this.create_element("span");j.innerHTML=h;j.style.color="black";j.style.marginLeft="0.5em";this.toolbar.appendChild(j)}a=this.create_element("div");a.style.position="absolute";a.style.width="auto";a.style.height="1.2em";a.style.top="auto";a.style.bottom=0;a.style.right="0";a.style.textAlign="right";a.style.color="red";a.style.background="rgb(240,240,240)";a.innerHTML=this.localize("slide")+" n/m";this.toolbar.appendChild(a)}this.toolbar.onclick=function(m){if(!m){m=window.event}var l=m.target;if(!l&&m.srcElement){l=m.srcElement}if(l&&l.nodeType==3){l=l.parentNode}w3c_slidy.stop_propagation(m);if(l&&l.nodeName.toLowerCase()!="a"){w3c_slidy.mouse_button_click(m)}};this.slide_number_element=a;this.set_eos_status(false);document.body.appendChild(this.toolbar)},wrap_implicit_slides:function(){var a,d,c,b,f;var e=document.getElementsByTagName("h1");if(!e){return}for(a=0;a<e.length;++a){d=e[a];if(d.parentNode!=document.body){continue}c=d.nextSibling;f=document.createElement("div");this.add_class(f,"slide");document.body.replaceChild(f,d);f.appendChild(d);while(c){if(c.nodeType==1&&(c.nodeName=="H1"||c.nodeName=="h1"||c.nodeName=="DIV"||c.nodeName=="div")){break}b=c.nextSibling;c=document.body.removeChild(c);f.appendChild(c);c=b}}},collect_slides:function(){var e=new Array();var d=document.body.getElementsByTagName("div");for(var c=0;c<d.length;++c){div=d.item(c);if(this.has_class(div,"slide")){e[e.length]=div;this.add_class(div,"hidden");var b=document.createElement("br");div.appendChild(b);var a=document.createElement("br");div.appendChild(a)}else{if(this.has_class(div,"background")){div.style.display="block"}}}this.slides=e},collect_notes:function(){var b=new Array();var c=document.body.getElementsByTagName("div");for(var a=0;a<c.length;++a){div=c.item(a);if(this.has_class(div,"handout")){b[b.length]=div;this.add_class(div,"hidden")}}this.notes=b},collect_backgrounds:function(){var c=new Array();var b=document.body.getElementsByTagName("div");for(var a=0;a<b.length;++a){div=b.item(a);if(this.has_class(div,"background")){c[c.length]=div;this.add_class(div,"hidden")}}this.backgrounds=c},patch_anchors:function(){var a=w3c_slidy;var c=function(g){if(a.page_address(this.href)==a.page_address(location.href)){var f=a.find_slide_number(this.href);if(f!=a.slide_number){var e=a.slides[a.slide_number];a.hide_slide(e);a.slide_number=f;e=a.slides[a.slide_number];a.show_slide(e);a.set_location()}}else{w3c_slidy.stop_propagation(g)}this.blur();a.disable_slide_click=true};var d=document.body.getElementsByTagName("a");for(var b=0;b<d.length;++b){if(window.addEventListener){d[b].addEventListener("click",c,false)}else{d[b].attachEvent("onclick",c)}}},show_slide_number:function(){var a=w3c_slidy.get_timer();w3c_slidy.slide_number_element.innerHTML=a+w3c_slidy.localize("slide")+" "+(w3c_slidy.slide_number+1)+"/"+w3c_slidy.slides.length},check_location:function(){var b=location.hash;if(w3c_slidy.slide_number>0&&(b==""||b=="#")){w3c_slidy.goto_slide(0)}else{if(b.length>2&&b!="#("+(w3c_slidy.slide_number+1)+")"){var a=parseInt(location.hash.substr(2));if(!isNaN(a)){w3c_slidy.goto_slide(a-1)}}}if(w3c_slidy.time_left&&w3c_slidy.slide_number>0){w3c_slidy.show_slide_number();if(w3c_slidy.time_left>0){w3c_slidy.time_left-=200}}},get_timer:function(){var c="";if(w3c_slidy.time_left){var b,a;a=Math.floor(w3c_slidy.time_left/1000);b=Math.floor(a/60);a=a%60;c=(b?b+"m":"")+a+"s "}return c},set_location:function(){var a=w3c_slidy.page_address(location.href);var b="#("+(w3c_slidy.slide_number+1)+")";if(w3c_slidy.slide_number>=0){a=a+b}if(w3c_slidy.ie&&(w3c_slidy.ie6||w3c_slidy.ie7)){w3c_slidy.push_hash(b)}if(a!=location.href){location.href=a}if(this.khtml){b="("+(w3c_slidy.slide_number+1)+")"}if(!this.ie&&location.hash!=b&&location.hash!=""){location.hash=b}document.title=w3c_slidy.title+" ("+(w3c_slidy.slide_number+1)+")";w3c_slidy.show_slide_number()},page_address:function(b){var a=b.indexOf("#");if(a<0){a=b.indexOf("%23")}if(a<0){return b}return b.substr(0,a)},on_frame_loaded:function(b){location.hash=b;var a=w3c_slidy.page_address(location.href);location.href=a+b},push_hash:function(b){if(b==""){b="#(1)"}window.location.hash=b;var a=document.getElementById("historyFrame").contentWindow.document;a.open("javascript:'<html></html>'");a.write('<html><head><script type="text/javascript">window.parent.w3c_slidy.on_frame_loaded(\''+(b)+"');\74/script></head><body>hello mum</body></html>");a.close()},find_slide_number:function(e){var c=e.indexOf("#");if(c<0){return 0}var b=unescape(e.substr(c+1));var f=document.getElementById(b);if(!f){var d=/\((\d)+\)/;if(b.match(d)){var a=parseInt(b.substring(1,b.length-1));if(a>this.slides.length){a=1}if(--a<0){a=0}return a}d=/\[(\d)+\]/;if(b.match(d)){var a=parseInt(b.substring(1,b.length-1));if(a>this.slides.length){a=1}if(--a<0){a=0}return a}return 0}while(true){if(f.nodeName.toLowerCase()=="div"&&this.has_class(f,"slide")){break}f=f.parentNode;if(!f){return 0}}for(c=0;c<slides.length;++c){if(slides[c]==f){return c}}return 0},previous_slide:function(b){if(!w3c_slidy.view_all){var a;if((b||w3c_slidy.slide_number==0)&&w3c_slidy.last_shown!=null){w3c_slidy.last_shown=w3c_slidy.hide_previous_item(w3c_slidy.last_shown);w3c_slidy.set_eos_status(false)}else{if(w3c_slidy.slide_number>0){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slide_number-1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null);w3c_slidy.set_eos_status(true);w3c_slidy.show_slide(a)}}w3c_slidy.set_location();if(!w3c_slidy.ns_pos){w3c_slidy.refresh_toolbar(200)}}},next_slide:function(c){if(!w3c_slidy.view_all){var a,b=w3c_slidy.last_shown;if(c||w3c_slidy.slide_number==w3c_slidy.slides.length-1){w3c_slidy.last_shown=w3c_slidy.reveal_next_item(w3c_slidy.last_shown)}if((!c||w3c_slidy.last_shown==null)&&w3c_slidy.slide_number<w3c_slidy.slides.length-1){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slide_number+1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.show_slide(a)}else{if(!w3c_slidy.last_shown){if(b&&c){w3c_slidy.last_shown=b}}}w3c_slidy.set_location();w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));if(!w3c_slidy.ns_pos){w3c_slidy.refresh_toolbar(200)}}},first_slide:function(){if(!w3c_slidy.view_all){var a;if(w3c_slidy.slide_number!=0){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=0;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.show_slide(a)}w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.set_location()}},last_slide:function(){if(!w3c_slidy.view_all){var a;w3c_slidy.last_shown=null;if(w3c_slidy.last_shown==null&&w3c_slidy.slide_number<w3c_slidy.slides.length-1){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slides.length-1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null);w3c_slidy.show_slide(a)}else{w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null)}w3c_slidy.set_eos_status(true);w3c_slidy.set_location()}},set_eos_status:function(a){if(this.eos){this.eos.style.color=(a?"rgb(240,240,240)":"red")}},goto_slide:function(b){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=b;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));document.title=w3c_slidy.title+" ("+(w3c_slidy.slide_number+1)+")";w3c_slidy.show_slide(a);w3c_slidy.show_slide_number()},show_slide:function(a){this.sync_background(a);window.scrollTo(0,0);this.remove_class(a,"hidden")},hide_slide:function(a){this.add_class(a,"hidden")},sync_background:function(a){var e;var g;if(a.currentStyle){g=a.currentStyle.backgroundColor}else{if(document.defaultView){var f=document.defaultView.getComputedStyle(a,null);if(f){g=f.getPropertyValue("background-color")}else{g="transparent"}}else{g=="transparent"}}if(g=="transparent"||g.indexOf("rgba")>=0||g.indexOf("opacity")>=0){var c=this.get_class_list(a);for(var d=0;d<this.backgrounds.length;d++){e=this.backgrounds[d];var b=this.get_class_list(e);if(this.matching_background(c,b)){this.remove_class(e,"hidden")}else{this.add_class(e,"hidden")}}}else{this.hide_backgrounds()}},hide_backgrounds:function(){for(var a=0;a<this.backgrounds.length;a++){background=this.backgrounds[a];this.add_class(background,"hidden")}},matching_background:function(c,b){var d,e,f,a;f=/\w+/g;a=b.match(f);for(d=e=0;d<a.length;d++){if(a[d]=="hidden"){continue}if(a[d]=="background"){continue}++e}if(e==0){return true}a=c.match(f);for(d=e=0;d<a.length;d++){if(a[d]=="hidden"){continue}if(this.has_token(b,a[d])){return true}}return false},resized:function(){var c=0;if(typeof(window.innerWidth)=="number"){c=window.innerWidth}else{if(document.documentElement&&document.documentElement.clientWidth){c=document.documentElement.clientWidth}else{if(document.body&&document.body.clientWidth){c=document.body.clientWidth}}}var b=0;if(typeof(window.innerHeight)=="number"){b=window.innerHeight}else{if(document.documentElement&&document.documentElement.clientHeight){b=document.documentElement.clientHeight}else{if(document.body&&document.body.clientHeight){b=document.body.clientHeight}}}if(b&&(c/b>1.05*1024/768)){c=b*1024/768}if(c!=w3c_slidy.last_width||b!=w3c_slidy.last_height){if(c>=1100){w3c_slidy.size_index=5}else{if(c>=1000){w3c_slidy.size_index=4}else{if(c>=800){w3c_slidy.size_index=3}else{if(c>=600){w3c_slidy.size_index=2}else{if(c){w3c_slidy.size_index=0}}}}}if(0<=w3c_slidy.size_index+w3c_slidy.size_adjustment&&w3c_slidy.size_index+w3c_slidy.size_adjustment<w3c_slidy.sizes.length){w3c_slidy.size_index=w3c_slidy.size_index+w3c_slidy.size_adjustment}w3c_slidy.adjust_object_dimensions(c,b);if(document.body.style.fontSize!=w3c_slidy.sizes[w3c_slidy.size_index]){document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index]}w3c_slidy.last_width=c;w3c_slidy.last_height=b;if(w3c_slidy.ns_pos){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a)}w3c_slidy.refresh_toolbar(200)}},scrolled:function(){if(w3c_slidy.toolbar&&!w3c_slidy.ns_pos&&!w3c_slidy.ie7){w3c_slidy.hack_offset=w3c_slidy.scroll_x_offset();w3c_slidy.toolbar.style.display="none";if(w3c_slidy.scrollhack==0&&!w3c_slidy.view_all){setTimeout(function(){w3c_slidy.show_toolbar()},1000);w3c_slidy.scrollhack=1}}},hide_toolbar:function(){w3c_slidy.add_class(w3c_slidy.toolbar,"hidden");window.focus()},refresh_toolbar:function(a){if(!w3c_slidy.ns_pos&&!w3c_slidy.ie7){w3c_slidy.hide_toolbar();setTimeout(function(){w3c_slidy.show_toolbar()},a)}},show_toolbar:function(){if(w3c_slidy.want_toolbar){w3c_slidy.toolbar.style.display="block";if(!w3c_slidy.ns_pos){var b=w3c_slidy.scroll_x_offset();w3c_slidy.toolbar.style.left=b;w3c_slidy.toolbar.style.right=b;w3c_slidy.toolbar.style.bottom=0}w3c_slidy.remove_class(w3c_slidy.toolbar,"hidden")}w3c_slidy.scrollhack=0;try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(a){}},toggle_toolbar:function(){if(!w3c_slidy.view_all){if(w3c_slidy.has_class(w3c_slidy.toolbar,"hidden")){w3c_slidy.remove_class(w3c_slidy.toolbar,"hidden");w3c_slidy.want_toolbar=1}else{w3c_slidy.add_class(w3c_slidy.toolbar,"hidden");w3c_slidy.want_toolbar=0}}},scroll_x_offset:function(){if(window.pageXOffset){return self.pageXOffset}if(document.documentElement&&document.documentElement.scrollLeft){return document.documentElement.scrollLeft}if(document.body){return document.body.scrollLeft}return 0},scroll_y_offset:function(){if(window.pageYOffset){return self.pageYOffset}if(document.documentElement&&document.documentElement.scrollTop){return document.documentElement.scrollTop}if(document.body){return document.body.scrollTop}return 0},optimize_font_size:function(){var a=w3c_slidy.slides[w3c_slidy.slide_number];var d=a.scrollHeight;var b=getWindowHeight();var c=100*d/b;alert("window utilization = "+c+"% (doc "+d+" win "+b+")")},get_doc_height:function(a){if(!a){a=document}if(a&&a.body&&a.body.offsetHeight){return a.body.offsetHeight}if(a&&a.body&&a.body.scrollHeight){return a.body.scrollHeight}alert("couldn't determine document height")},get_window_height:function(){if(typeof(window.innerHeight)=="number"){return window.innerHeight}if(document.documentElement&&document.documentElement.clientHeight){return document.documentElement.clientHeight}if(document.body&&document.body.clientHeight){return document.body.clientHeight}},document_height:function(){var a,b;a=document.body.scrollHeight;b=document.body.offsetHeight;if(a&&b){return(a>b?a:b)}return 0},smaller:function(){if(w3c_slidy.size_index>0){--w3c_slidy.size_index}w3c_slidy.toolbar.style.display="none";document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index];var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a);setTimeout(function(){w3c_slidy.show_toolbar()},50)},bigger:function(){if(w3c_slidy.size_index<w3c_slidy.sizes.length-1){++w3c_slidy.size_index}w3c_slidy.toolbar.style.display="none";document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index];var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a);setTimeout(function(){w3c_slidy.show_toolbar()},50)},adjust_object_dimensions:function(c,k){for(var e=0;e<w3c_slidy.objects.length;e++){var d=this.objects[e];var b=d.getAttribute("type");if(b=="image/svg+xml"||b=="application/x-shockwave-flash"){if(!d.initialWidth){d.initialWidth=d.getAttribute("width")}if(!d.initialHeight){d.initialHeight=d.getAttribute("height")}if(d.initialWidth&&d.initialWidth.charAt(d.initialWidth.length-1)=="%"){var j=parseInt(d.initialWidth.slice(0,d.initialWidth.length-1));var a=c*(j/100);d.setAttribute("width",a)}if(d.initialHeight&&d.initialHeight.charAt(d.initialHeight.length-1)=="%"){var f=parseInt(d.initialHeight.slice(0,d.initialHeight.length-1));var g=k*(f/100);d.setAttribute("height",g)}}}},key_press:function(a){if(!a){a=window.event}if(!w3c_slidy.key_wanted){return w3c_slidy.cancel(a)}return true},key_down:function(d){var c,e,a;w3c_slidy.key_wanted=true;if(!d){d=window.event}if(window.event){c=window.event.keyCode;e=window.event.srcElement}else{if(d.which){c=d.which;e=d.target}else{return true}}if(!c){return true}if(!w3c_slidy.slidy_chrome(e)&&w3c_slidy.special_element(e)){return true}if(d.ctrlKey||d.altKey||d.metaKey){return true}if(w3c_slidy.is_shown_toc()&&c!=9&&c!=16&&c!=38&&c!=40){w3c_slidy.hide_table_of_contents(true);if(c==27||c==84||c==67){return w3c_slidy.cancel(d)}}if(c==34){if(w3c_slidy.view_all){return true}w3c_slidy.next_slide(false);return w3c_slidy.cancel(d)}else{if(c==33){if(w3c_slidy.view_all){return true}w3c_slidy.previous_slide(false);return w3c_slidy.cancel(d)}else{if(c==32){w3c_slidy.next_slide(true);return w3c_slidy.cancel(d)}else{if(c==37){w3c_slidy.previous_slide(!d.shiftKey);return w3c_slidy.cancel(d)}else{if(c==36){w3c_slidy.first_slide();return w3c_slidy.cancel(d)}else{if(c==35){w3c_slidy.last_slide();return w3c_slidy.cancel(d)}else{if(c==39){w3c_slidy.next_slide(!d.shiftKey);return w3c_slidy.cancel(d)}else{if(c==13){if(w3c_slidy.outline){if(w3c_slidy.outline.visible){w3c_slidy.fold(w3c_slidy.outline)}else{w3c_slidy.unfold(w3c_slidy.outline)}return w3c_slidy.cancel(d)}}else{if(c==188){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==190){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==189||c==109){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==187||c==191||c==107){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==83){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==66){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==90){w3c_slidy.last_slide();return w3c_slidy.cancel(d)}else{if(c==70){w3c_slidy.toggle_toolbar();return w3c_slidy.cancel(d)}else{if(c==65){w3c_slidy.toggle_view();return w3c_slidy.cancel(d)}else{if(c==75){w3c_slidy.mouse_click_enabled=!w3c_slidy.mouse_click_enabled;var b=(w3c_slidy.mouse_click_enabled?"enabled":"disabled")+" mouse click advance";alert(w3c_slidy.localize(b));return w3c_slidy.cancel(d)}else{if(c==84||c==67){if(w3c_slidy.toc){w3c_slidy.toggle_table_of_contents()}return w3c_slidy.cancel(d)}else{if(c==72){window.location=w3c_slidy.help_page;return w3c_slidy.cancel(d)}}}}}}}}}}}}}}}}}}}}return true},create_element:function(a){if(this.xhtml&&(typeof document.createElementNS!="undefined")){return document.createElementNS("http://www.w3.org/1999/xhtml",a)}return document.createElement(a)},get_element_style:function(d,b,c){if(d.currentStyle){return d.currentStyle[b]}else{if(window.getComputedStyle){var a=window.getComputedStyle(d,"");return a.getPropertyValue(c)}}return""},has_token:function(e,c){if(e){var d=/\w+/g;var a=e.match(d);for(var b=0;b<a.length;b++){if(a[b]==c){return true}}}return false},get_class_list:function(a){if(typeof a.className!="undefined"){return a.className}return a.getAttribute("class")},has_class:function(b,a){if(b.nodeType!=1){return false}var c=new RegExp("(^| )"+a+"W*");if(typeof b.className!="undefined"){return c.test(b.className)}return c.test(b.getAttribute("class"))},remove_class:function(b,a){var d=new RegExp("(^| )"+a+"W*");var c="";if(typeof b.className!="undefined"){c=b.className;if(c){c=c.replace(d,"");b.className=c}}else{c=b.getAttribute("class");if(c){c=c.replace(d,"");b.setAttribute("class",c)}}},add_class:function(b,a){if(!this.has_class(b,a)){if(typeof b.className!="undefined"){b.className+=" "+a}else{var c=b.getAttribute("class");c=c?c+" "+a:a;b.setAttribute("class",c)}}},incremental_elements:null,okay_for_incremental:function(a){if(!this.incremental_elements){var b=new Array();b.p=true;b.pre=true;b.li=true;b.blockquote=true;b.dt=true;b.dd=true;b.h2=true;b.h3=true;b.h4=true;b.h5=true;b.h6=true;b.span=true;b.address=true;b.table=true;b.tr=true;b.th=true;b.td=true;b.img=true;b.object=true;this.incremental_elements=b}return this.incremental_elements[a.toLowerCase()]},next_incremental_item:function(c){var b=this.is_xhtml?"br":"BR";var a=w3c_slidy.slides[w3c_slidy.slide_number];for(;;){c=w3c_slidy.next_node(a,c);if(c==null||c.parentNode==null){break}if(c.nodeType==1){if(c.nodeName==b){continue}if(w3c_slidy.has_class(c,"incremental")&&w3c_slidy.okay_for_incremental(c.nodeName)){return c}if(w3c_slidy.has_class(c.parentNode,"incremental")&&!w3c_slidy.has_class(c,"non-incremental")){return c}}}return c},previous_incremental_item:function(c){var b=this.is_xhtml?"br":"BR";var a=w3c_slidy.slides[w3c_slidy.slide_number];for(;;){c=w3c_slidy.previous_node(a,c);if(c==null||c.parentNode==null){break}if(c.nodeType==1){if(c.nodeName==b){continue}if(w3c_slidy.has_class(c,"incremental")&&w3c_slidy.okay_for_incremental(c.nodeName)){return c}if(w3c_slidy.has_class(c.parentNode,"incremental")&&!w3c_slidy.has_class(c,"non-incremental")){return c}}}return c},set_visibility_all_incremental:function(b){var a=this.next_incremental_item(null);if(b=="hidden"){while(a){w3c_slidy.add_class(a,"invisible");a=w3c_slidy.next_incremental_item(a)}}else{while(a){w3c_slidy.remove_class(a,"invisible");a=w3c_slidy.next_incremental_item(a)}}},reveal_next_item:function(a){a=w3c_slidy.next_incremental_item(a);if(a&&a.nodeType==1){w3c_slidy.remove_class(a,"invisible")}return a},hide_previous_item:function(a){if(a&&a.nodeType==1){w3c_slidy.add_class(a,"invisible")}return this.previous_incremental_item(a)},next_node:function(a,b){if(b==null){return a.firstChild}if(b.firstChild){return b.firstChild}if(b.nextSibling){return b.nextSibling}for(;;){b=b.parentNode;if(!b||b==a){break}if(b&&b.nextSibling){return b.nextSibling}}return null},previous_node:function(a,b){if(b==null){b=a.lastChild;if(b){while(b.lastChild){b=b.lastChild}}return b}if(b.previousSibling){b=b.previousSibling;while(b.lastChild){b=b.lastChild}return b}if(b.parentNode!=a){return b.parentNode}return null},previous_sibling_element:function(a){a=a.previousSibling;while(a&&a.nodeType!=1){a=a.previousSibling}return a},next_sibling_element:function(a){a=a.nextSibling;while(a&&a.nodeType!=1){a=a.nextSibling}return a},first_child_element:function(a){var b;for(b=a.firstChild;b;b=b.nextSibling){if(b.nodeType==1){break}}return b},first_tag:function(b,a){var c;if(!this.is_xhtml){a=a.toUpperCase()}for(c=b.firstChild;c;c=c.nextSibling){if(c.nodeType==1&&c.nodeName==a){break}}return c},hide_selection:function(){if(window.getSelection){var b=window.getSelection();if(b.rangeCount>0){var a=b.getRangeAt(0);a.collapse(false)}}else{var c=document.selection.createRange();c.collapse(false)}},get_selected_text:function(){try{if(window.getSelection){return window.getSelection().toString()}if(document.getSelection){return document.getSelection().toString()}if(document.selection){return document.selection.createRange().text}}catch(a){}return""},mouse_button_up:function(a){w3c_slidy.selected_text_len=w3c_slidy.get_selected_text().length},mouse_button_click:function(g){var c=false;var b=false;var d=false;var f;if(!g){var g=window.event}if(g.target){f=g.target}else{if(g.srcElement){f=g.srcElement}}if(f.nodeType==3){f=f.parentNode}if(g.which){b=(g.which==1);d=(g.which==2);c=(g.which==3)}else{if(g.button){if(g.button==4){d=true}c=(g.button==2)}else{b=true}}if(w3c_slidy.selected_text_len>0){w3c_slidy.stop_propagation(g);g.cancel=true;g.returnValue=false;return false}w3c_slidy.hide_table_of_contents(false);var a=f.nodeName.toLowerCase();if(w3c_slidy.mouse_click_enabled&&b&&!w3c_slidy.special_element(f)&&!f.onclick){w3c_slidy.next_slide(true);w3c_slidy.stop_propagation(g);g.cancel=true;g.returnValue=false;return false}return true},special_element:function(b){var a=b.nodeName.toLowerCase();return b.onkeydown||b.onclick||a=="a"||a=="embed"||a=="object"||a=="video"||a=="audio"||a=="input"||a=="textarea"||a=="select"||a=="option"},slidy_chrome:function(a){while(a){if(a==w3c_slidy.toc||a==w3c_slidy.toolbar||w3c_slidy.has_class(a,"outline")){return true}a=a.parentNode}return false},get_key:function(b){var a;if(typeof window.event!="undefined"){a=window.event.keyCode}else{if(b.which){a=b.which}}return a},get_target:function(b){var a;if(!b){b=window.event}if(b.target){a=b.target}else{if(b.srcElement){a=b.srcElement}}if(a.nodeType!=1){a=a.parentNode}return a},is_block:function(b){var a=b.nodeName.toLowerCase();return a=="ol"||a=="ul"||a=="p"||a=="li"||a=="table"||a=="pre"||a=="h1"||a=="h2"||a=="h3"||a=="h4"||a=="h5"||a=="h6"||a=="blockquote"||a=="address"},add_listener:function(a,c,b){if(window.addEventListener){a.addEventListener(c,b,false)}else{a.attachEvent("on"+c,b)}},stop_propagation:function(a){a=a?a:window.event;a.cancelBubble=true;if(a.stopPropagation){a.stopPropagation()}return true},cancel:function(a){if(a){a.cancel=true;a.returnValue=false;if(a.preventDefault){a.preventDefault()}}w3c_slidy.key_wanted=false;return false},strings_es:{slide:"pág.","help?":"Ayuda","contents?":"Índice","table of contents":"tabla de contenidos","Table of Contents":"Tabla de Contenidos","restart presentation":"Reiniciar presentación","restart?":"Inicio"},help_es:"Utilice el ratón, barra espaciadora, teclas Izda/Dcha, o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",strings_ca:{slide:"pàg..","help?":"Ajuda","contents?":"Índex","table of contents":"taula de continguts","Table of Contents":"Taula de Continguts","restart presentation":"Reiniciar presentació","restart?":"Inici"},help_ca:"Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",strings_cs:{slide:"snímek","help?":"nápověda","contents?":"obsah","table of contents":"obsah prezentace","Table of Contents":"Obsah prezentace","restart presentation":"znovu spustit prezentaci","restart?":"restart"},help_cs:"Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se dá zvětšit a zmenšit pomocí kláves B a S.",strings_nl:{slide:"pagina","help?":"Help?","contents?":"Inhoud?","table of contents":"inhoudsopgave","Table of Contents":"Inhoudsopgave","restart presentation":"herstart presentatie","restart?":"Herstart?"},help_nl:"Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",strings_de:{slide:"Seite","help?":"Hilfe","contents?":"Übersicht","table of contents":"Inhaltsverzeichnis","Table of Contents":"Inhaltsverzeichnis","restart presentation":"Präsentation neu starten","restart?":"Neustart"},help_de:"Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",strings_pl:{slide:"slajd","help?":"pomoc?","contents?":"spis treści?","table of contents":"spis treści","Table of Contents":"Spis Treści","restart presentation":"Restartuj prezentację","restart?":"restart?"},help_pl:"Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawolub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",strings_fr:{slide:"page","help?":"Aide","contents?":"Index","table of contents":"table des matières","Table of Contents":"Table des matières","restart presentation":"Recommencer l'exposé","restart?":"Début"},help_fr:"Naviguez avec la souris, la barre d'espace, les flèches gauche/droite ou les touches Pg Up, Pg Dn. Utilisez les touches S et B pour modifier la taille de la police.",strings_hu:{slide:"oldal","help?":"segítség","contents?":"tartalom","table of contents":"tartalomjegyzék","Table of Contents":"Tartalomjegyzék","restart presentation":"bemutató újraindítása","restart?":"újraindítás"},help_hu:"Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét.",strings_it:{slide:"pag.","help?":"Aiuto","contents?":"Indice","table of contents":"indice","Table of Contents":"Indice","restart presentation":"Ricominciare la presentazione","restart?":"Inizio"},help_it:"Navigare con mouse, barra spazio, frecce sinistra/destra o PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",strings_el:{slide:"σελίδα","help?":"βοήθεια;","contents?":"περιεχόμενα;","table of contents":"πίνακας περιεχομένων","Table of Contents":"Πίνακας Περιεχομένων","restart presentation":"επανεκκίνηση παρουσίασης","restart?":"επανεκκίνηση;"},help_el:"Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε το μέγεθος της γραμματοσειράς.",strings_ja:{slide:"スライド","help?":"ヘルプ","contents?":"目次","table of contents":"目次を表示","Table of Contents":"目次","restart presentation":"最初から再生","restart?":"最初から"},help_ja:"マウス左クリック ・ スペース ・ 左右キー または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更",strings_zh:{slide:"幻灯片","help?":"帮助?","contents?":"内容?","table of contents":"目录","Table of Contents":"目录","restart presentation":"重新启动展示","restart?":"重新启动?"},help_zh:"用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. 用 S, B 改变字体大小.",strings_ru:{slide:"слайд","help?":"помощь?","contents?":"содержание?","table of contents":"оглавление","Table of Contents":"Оглавление","restart presentation":"перезапустить презентацию","restart?":"перезапуск?"},help_ru:"Перемещайтесь кликая мышкой, используя клавишу пробел, стрелкивлево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",strings_sv:{slide:"sida","help?":"hjälp","contents?":"innehåll","table of contents":"innehållsförteckning","Table of Contents":"Innehållsförteckning","restart presentation":"visa presentationen från början","restart?":"börja om"},help_sv:"Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. Använd tangenterna S och B för att ändra textens storlek.",strings:{},localize:function(d){if(d==""){return d}var b,c=w3c_slidy.strings[w3c_slidy.lang];if(c){b=c[d];if(b){return b}}var a=w3c_slidy.lang.split("-");if(a.length>1){c=w3c_slidy.strings[a[0]];if(c){b=c[d];if(b){return b}}}return d},init_localization:function(){var b=w3c_slidy;var a=w3c_slidy.help_text;this.strings={es:this.strings_es,ca:this.strings_ca,cs:this.strings_cs,nl:this.strings_nl,de:this.strings_de,pl:this.strings_pl,fr:this.strings_fr,hu:this.strings_hu,it:this.strings_it,el:this.strings_el,jp:this.strings_ja,zh:this.strings_zh,ru:this.strings_ru,sv:this.strings_sv},b.strings_es[a]=b.help_es;b.strings_ca[a]=b.help_ca;b.strings_cs[a]=b.help_cs;b.strings_nl[a]=b.help_nl;b.strings_de[a]=b.help_de;b.strings_pl[a]=b.help_pl;b.strings_fr[a]=b.help_fr;b.strings_hu[a]=b.help_hu;b.strings_it[a]=b.help_it;b.strings_el[a]=b.help_el;b.strings_ja[a]=b.help_ja;b.strings_zh[a]=b.help_zh;b.strings_ru[a]=b.help_ru;b.strings_sv[a]=b.help_sv;w3c_slidy.lang=document.body.parentNode.getAttribute("lang");if(!w3c_slidy.lang){w3c_slidy.lang=document.body.parentNode.getAttribute("xml:lang")}if(!w3c_slidy.lang){w3c_slidy.lang="en"}}};if(w3c_slidy.ie6||w3c_slidy.ie7){document.write("<iframe id='historyFrame' src='javascript:\"<html></html>\"' height='1' width='1' style='position:absolute;left:-800px'></iframe>")}w3c_slidy.set_up();setTimeout(w3c_slidy.hide_slides,50); \ No newline at end of file
diff --git a/slidy/slidy.css b/slidy/styles/slidy.css
index 96e3da76b..0197e64d0 100644
--- a/slidy/slidy.css
+++ b/slidy/styles/slidy.css
@@ -160,6 +160,10 @@ div.toc-heading {
text-align: center;
}
+img {
+ image-rendering: optimize-quality;
+}
+
pre {
font-size: 80%;
font-weight: bold;
diff --git a/src/Tests/Arbitrary.hs b/src/Tests/Arbitrary.hs
index f5a44ceab..9d65e1f1f 100644
--- a/src/Tests/Arbitrary.hs
+++ b/src/Tests/Arbitrary.hs
@@ -1,5 +1,5 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, ScopedTypeVariables #-}
-- provides Arbitrary instance for Pandoc types
module Tests.Arbitrary ()
where
@@ -22,10 +22,10 @@ arbAttr = do
return (id',classes,keyvals)
instance Arbitrary Inlines where
- arbitrary = liftM fromList arbitrary
+ arbitrary = liftM (fromList :: [Inline] -> Inlines) arbitrary
instance Arbitrary Blocks where
- arbitrary = liftM fromList arbitrary
+ arbitrary = liftM (fromList :: [Block] -> Blocks) arbitrary
instance Arbitrary Inline where
arbitrary = resize 3 $ arbInline 2
@@ -41,10 +41,6 @@ arbInline :: Int -> Gen Inline
arbInline n = frequency $ [ (60, liftM Str realString)
, (60, return Space)
, (10, liftM2 Code arbAttr realString)
- , (5, return EmDash)
- , (5, return EnDash)
- , (5, return Apostrophe)
- , (5, return Ellipses)
, (5, elements [ RawInline "html" "<a id=\"eek\">"
, RawInline "latex" "\\my{command}" ])
] ++ [ x | x <- nesters, n > 1]
diff --git a/src/Tests/Helpers.hs b/src/Tests/Helpers.hs
index b8d6b83a7..66879efed 100644
--- a/src/Tests/Helpers.hs
+++ b/src/Tests/Helpers.hs
@@ -69,17 +69,15 @@ test fn name (input, expected) =
vividize :: (DI,String) -> String
vividize (B,s) = s
-vividize (_,s) = vivid s
+vividize (F,s) = s
+vividize (S,s) = setSGRCode [SetColor Background Dull Red
+ , SetColor Foreground Vivid White] ++ s
+ ++ setSGRCode [Reset]
property :: QP.Testable a => TestName -> a -> Test
property = testProperty
-vivid :: String -> String
-vivid s = setSGRCode [SetColor Background Dull Red
- , SetColor Foreground Vivid White] ++ s
- ++ setSGRCode [Reset]
-
-infix 6 =?>
+infix 5 =?>
(=?>) :: a -> b -> (a,b)
x =?> y = (x, y)
diff --git a/src/Tests/Old.hs b/src/Tests/Old.hs
index cb1417ffa..1ec32a30d 100644
--- a/src/Tests/Old.hs
+++ b/src/Tests/Old.hs
@@ -13,7 +13,6 @@ import Data.Algorithm.Diff
import Text.Pandoc.Shared ( normalize, defaultWriterOptions )
import Text.Pandoc.Writers.Native ( writeNative )
import Text.Pandoc.Readers.Native ( readNative )
-import Text.Pandoc.Highlighting ( languages )
import Prelude hiding ( readFile )
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.UTF8 (toString)
@@ -105,7 +104,7 @@ tests = [ testGroup "markdown"
]
, testGroup "other writers" $ map (\f -> testGroup f $ writerTests f)
[ "docbook", "opendocument" , "context" , "texinfo"
- , "man" , "plain" , "mediawiki", "rtf", "org"
+ , "man" , "plain" , "mediawiki", "rtf", "org", "asciidoc"
]
]
@@ -121,10 +120,7 @@ lhsWriterTests format
]
where
t n f = test n ["--columns=78", "-r", "native", "-s", "-w", f]
- "lhs-test.native" ("lhs-test" <.> ext f)
- ext f = if null languages && format == "html"
- then "nohl" <.> f
- else f
+ "lhs-test.native" ("lhs-test" <.> f)
lhsReaderTest :: String -> Test
lhsReaderTest format =
diff --git a/src/Tests/Readers/LaTeX.hs b/src/Tests/Readers/LaTeX.hs
index 6d28441f8..d60026b20 100644
--- a/src/Tests/Readers/LaTeX.hs
+++ b/src/Tests/Readers/LaTeX.hs
@@ -11,7 +11,7 @@ import Text.Pandoc
latex :: String -> Pandoc
latex = readLaTeX defaultParserState
-infix 5 =:
+infix 4 =:
(=:) :: ToString c
=> String -> (String, c) -> Test
(=:) = test latex
@@ -35,10 +35,15 @@ tests = [ testGroup "basic"
"\\subsubsection{header}" =?> header 3 "header"
, "emph" =:
"\\section{text \\emph{emph}}" =?>
- header 1 ("text" +++ space +++ emph "emph")
+ header 1 ("text" <> space <> emph "emph")
, "link" =:
"\\section{text \\href{/url}{link}}" =?>
- header 1 ("text" +++ space +++ link "/url" "" "link")
+ header 1 ("text" <> space <> link "/url" "" "link")
+ ]
+
+ , testGroup "math"
+ [ "escaped $" =:
+ "$x=\\$4$" =?> para (math "x=\\$4")
]
, testGroup "space and comments"
@@ -64,98 +69,101 @@ baseCitation = Citation{ citationId = "item1"
, citationNoteNum = 0
, citationHash = 0 }
+rt :: String -> Inlines
+rt = rawInline "latex"
+
natbibCitations :: Test
natbibCitations = testGroup "natbib"
[ "citet" =: "\\citet{item1}"
- =?> para (cite [baseCitation] empty)
+ =?> para (cite [baseCitation] (rt "\\citet{item1}"))
, "suffix" =: "\\citet[p.~30]{item1}"
=?> para
- (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] empty)
+ (cite [baseCitation{ citationSuffix = toList $ text ", p.\160\&30" }] (rt "\\citet[p.~30]{item1}"))
, "suffix long" =: "\\citet[p.~30, with suffix]{item1}"
=?> para (cite [baseCitation{ citationSuffix =
- toList $ text "p.\160\&30, with suffix" }] empty)
+ toList $ text ", p.\160\&30, with suffix" }] (rt "\\citet[p.~30, with suffix]{item1}"))
, "multiple" =: "\\citeauthor{item1} \\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"
=?> para (cite [baseCitation{ citationMode = AuthorInText }
,baseCitation{ citationMode = SuppressAuthor
- , citationSuffix = [Str "p.\160\&30"]
+ , citationSuffix = [Str ",",Space,Str "p.\160\&30"]
, citationId = "item2" }
,baseCitation{ citationId = "item3"
, citationPrefix = [Str "see",Space,Str "also"]
, citationMode = NormalCitation }
- ] empty)
+ ] (rt "\\citetext{\\citeyear{item1}; \\citeyear[p.~30]{item2}; \\citealp[see also][]{item3}}"))
, "group" =: "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
, citationPrefix = [Str "see"]
- , citationSuffix = [Str "p.\160\&34",EnDash,Str "35"] }
+ , citationSuffix = [Str ",",Space,Str "p.\160\&34\8211\&35"] }
,baseCitation{ citationMode = NormalCitation
, citationId = "item3"
, citationPrefix = [Str "also"]
- , citationSuffix = [Str "chap.",Space,Str "3"] }
- ] empty)
+ , citationSuffix = [Str ",",Space,Str "chap.",Space,Str "3"] }
+ ] (rt "\\citetext{\\citealp[see][p.~34--35]{item1}; \\citealp[also][chap. 3]{item3}}"))
, "suffix and locator" =: "\\citep[pp.~33, 35--37, and nowhere else]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
- , citationSuffix = [Str "pp.\160\&33,",Space,Str "35",EnDash,Str "37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] empty)
+ , citationSuffix = [Str ",",Space,Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\citep[pp.~33, 35--37, and nowhere else]{item1}"))
, "suffix only" =: "\\citep[and nowhere else]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
- , citationSuffix = toList $ text "and nowhere else" }] empty)
+ , citationSuffix = toList $ text ", and nowhere else" }] (rt "\\citep[and nowhere else]{item1}"))
, "no author" =: "\\citeyearpar{item1}, and now Doe with a locator \\citeyearpar[p.~44]{item2}"
- =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] empty +++
- text ", and now Doe with a locator " +++
+ =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\citeyearpar{item1}") <>
+ text ", and now Doe with a locator " <>
cite [baseCitation{ citationMode = SuppressAuthor
- , citationSuffix = [Str "p.\160\&44"]
- , citationId = "item2" }] empty)
+ , citationSuffix = [Str ",",Space,Str "p.\160\&44"]
+ , citationId = "item2" }] (rt "\\citeyearpar[p.~44]{item2}"))
, "markup" =: "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
, citationPrefix = [Emph [Str "see"]]
- , citationSuffix = [Str "p.",Space,
- Strong [Str "32"]] }] empty)
+ , citationSuffix = [Str ",",Space,Str "p.",Space,
+ Strong [Str "32"]] }] (rt "\\citep[\\emph{see}][p. \\textbf{32}]{item1}"))
]
biblatexCitations :: Test
biblatexCitations = testGroup "biblatex"
[ "textcite" =: "\\textcite{item1}"
- =?> para (cite [baseCitation] empty)
+ =?> para (cite [baseCitation] (rt "\\textcite{item1}"))
, "suffix" =: "\\textcite[p.~30]{item1}"
=?> para
- (cite [baseCitation{ citationSuffix = toList $ text "p.\160\&30" }] empty)
+ (cite [baseCitation{ citationSuffix = toList $ text ", p.\160\&30" }] (rt "\\textcite[p.~30]{item1}"))
, "suffix long" =: "\\textcite[p.~30, with suffix]{item1}"
=?> para (cite [baseCitation{ citationSuffix =
- toList $ text "p.\160\&30, with suffix" }] empty)
+ toList $ text ", p.\160\&30, with suffix" }] (rt "\\textcite[p.~30, with suffix]{item1}"))
, "multiple" =: "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"
=?> para (cite [baseCitation{ citationMode = AuthorInText }
,baseCitation{ citationMode = NormalCitation
- , citationSuffix = [Str "p.\160\&30"]
+ , citationSuffix = [Str ",",Space,Str "p.\160\&30"]
, citationId = "item2" }
,baseCitation{ citationId = "item3"
, citationPrefix = [Str "see",Space,Str "also"]
, citationMode = NormalCitation }
- ] empty)
+ ] (rt "\\textcites{item1}[p.~30]{item2}[see also][]{item3}"))
, "group" =: "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
, citationPrefix = [Str "see"]
- , citationSuffix = [Str "p.\160\&34",EnDash,Str "35"] }
+ , citationSuffix = [Str ",",Space,Str "p.\160\&34\8211\&35"] }
,baseCitation{ citationMode = NormalCitation
, citationId = "item3"
, citationPrefix = [Str "also"]
- , citationSuffix = [Str "chap.",Space,Str "3"] }
- ] empty)
+ , citationSuffix = [Str ",",Space,Str "chap.",Space,Str "3"] }
+ ] (rt "\\autocites[see][p.~34--35]{item1}[also][chap. 3]{item3}"))
, "suffix and locator" =: "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
- , citationSuffix = [Str "pp.\160\&33,",Space,Str "35",EnDash,Str "37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] empty)
+ , citationSuffix = [Str ",",Space,Str "pp.\160\&33,",Space,Str "35\8211\&37,",Space,Str "and",Space,Str "nowhere",Space, Str "else"] }] (rt "\\autocite[pp.~33, 35--37, and nowhere else]{item1}"))
, "suffix only" =: "\\autocite[and nowhere else]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
- , citationSuffix = toList $ text "and nowhere else" }] empty)
+ , citationSuffix = toList $ text ", and nowhere else" }] (rt "\\autocite[and nowhere else]{item1}"))
, "no author" =: "\\autocite*{item1}, and now Doe with a locator \\autocite*[p.~44]{item2}"
- =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] empty +++
- text ", and now Doe with a locator " +++
+ =?> para (cite [baseCitation{ citationMode = SuppressAuthor }] (rt "\\autocite*{item1}") <>
+ text ", and now Doe with a locator " <>
cite [baseCitation{ citationMode = SuppressAuthor
- , citationSuffix = [Str "p.\160\&44"]
- , citationId = "item2" }] empty)
+ , citationSuffix = [Str ",",Space,Str "p.\160\&44"]
+ , citationId = "item2" }] (rt "\\autocite*[p.~44]{item2}"))
, "markup" =: "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"
=?> para (cite [baseCitation{ citationMode = NormalCitation
, citationPrefix = [Emph [Str "see"]]
- , citationSuffix = [Str "p.",Space,
- Strong [Str "32"]] }] empty)
+ , citationSuffix = [Str ",",Space,Str "p.",Space,
+ Strong [Str "32"]] }] (rt "\\autocite[\\emph{see}][p. \\textbf{32}]{item1}"))
, "parencite" =: "\\parencite{item1}"
- =?> para (cite [baseCitation{ citationMode = NormalCitation }] empty)
+ =?> para (cite [baseCitation{ citationMode = NormalCitation }] (rt "\\parencite{item1}"))
]
diff --git a/src/Tests/Readers/Markdown.hs b/src/Tests/Readers/Markdown.hs
index 941762bd0..5ad974adf 100644
--- a/src/Tests/Readers/Markdown.hs
+++ b/src/Tests/Readers/Markdown.hs
@@ -8,7 +8,6 @@ import Tests.Arbitrary()
import Text.Pandoc.Builder
-- import Text.Pandoc.Shared ( normalize )
import Text.Pandoc
-import Data.Sequence (singleton)
markdown :: String -> Pandoc
markdown = readMarkdown defaultParserState{ stateStandalone = True }
@@ -16,7 +15,7 @@ markdown = readMarkdown defaultParserState{ stateStandalone = True }
markdownSmart :: String -> Pandoc
markdownSmart = readMarkdown defaultParserState{ stateSmart = True }
-infix 5 =:
+infix 4 =:
(=:) :: ToString c
=> String -> (String, c) -> Test
(=:) = test markdown
@@ -44,29 +43,49 @@ tests = [ testGroup "inline code"
"`*` {.haskell .special x=\"7\"}"
=?> para (codeWith ("",["haskell","special"],[("x","7")]) "*")
]
+ , testGroup "backslash escapes"
+ [ "in URL" =:
+ "[hi](/there\\))"
+ =?> para (link "/there)" "" "hi")
+ , "in title" =:
+ "[hi](/there \"a\\\"a\")"
+ =?> para (link "/there" "a\"a" "hi")
+ , "in reference link title" =:
+ "[hi]\n\n[hi]: /there (a\\)a)"
+ =?> para (link "/there" "a)a" "hi")
+ , "in reference link URL" =:
+ "[hi]\n\n[hi]: /there\\.0"
+ =?> para (link "/there.0" "" "hi")
+ ]
, testGroup "smart punctuation"
[ test markdownSmart "quote before ellipses"
("'...hi'"
- =?> para (singleQuoted (singleton Ellipses +++ "hi")))
+ =?> para (singleQuoted ("…hi")))
+ , test markdownSmart "apostrophe before emph"
+ ("D'oh! A l'*aide*!"
+ =?> para ("D’oh! A l’" <> emph "aide" <> "!"))
+ , test markdownSmart "apostrophe in French"
+ ("À l'arrivée de la guerre, le thème de l'«impossibilité du socialisme»"
+ =?> para ("À l’arrivée de la guerre, le thème de l’«impossibilité du socialisme»"))
]
, testGroup "mixed emphasis and strong"
[ "emph and strong emph alternating" =:
"*xxx* ***xxx*** xxx\n*xxx* ***xxx*** xxx"
- =?> para (emph "xxx" +++ space +++ strong (emph "xxx") +++
- space +++ "xxx" +++ space +++
- emph "xxx" +++ space +++ strong (emph "xxx") +++
- space +++ "xxx")
+ =?> para (emph "xxx" <> space <> strong (emph "xxx") <>
+ space <> "xxx" <> space <>
+ emph "xxx" <> space <> strong (emph "xxx") <>
+ space <> "xxx")
, "emph with spaced strong" =:
"*x **xx** x*"
- =?> para (emph ("x" +++ space +++ strong "xx" +++ space +++ "x"))
+ =?> para (emph ("x" <> space <> strong "xx" <> space <> "x"))
]
, testGroup "footnotes"
[ "indent followed by newline and flush-left text" =:
"[^1]\n\n[^1]: my note\n\n \nnot in note\n"
- =?> para (note (para "my note")) +++ para "not in note"
+ =?> para (note (para "my note")) <> para "not in note"
, "indent followed by newline and indented text" =:
"[^1]\n\n[^1]: my note\n \n in note\n"
- =?> para (note (para "my note" +++ para "in note"))
+ =?> para (note (para "my note" <> para "in note"))
, "recursive note" =:
"[^1]\n\n[^1]: See [^1]\n"
=?> para (note (para "See [^1]"))
@@ -76,9 +95,9 @@ tests = [ testGroup "inline code"
"inverse bird tracks and html" $
"> a\n\n< b\n\n<div>\n"
=?> codeBlockWith ("",["sourceCode","literate","haskell"],[]) "a"
- +++
+ <>
codeBlockWith ("",["sourceCode","haskell"],[]) "b"
- +++
+ <>
rawBlock "html" "<div>\n\n"
]
-- the round-trip properties frequently fail
diff --git a/src/Tests/Readers/RST.hs b/src/Tests/Readers/RST.hs
index 4b8c9301b..3269092a6 100644
--- a/src/Tests/Readers/RST.hs
+++ b/src/Tests/Readers/RST.hs
@@ -11,15 +11,15 @@ import Text.Pandoc
rst :: String -> Pandoc
rst = readRST defaultParserState{ stateStandalone = True }
-infix 5 =:
+infix 4 =:
(=:) :: ToString c
=> String -> (String, c) -> Test
(=:) = test rst
tests :: [Test]
tests = [ "line block with blank line" =:
- "| a\n|\n| b" =?> para (str "a" +++ linebreak +++
- linebreak +++ str " " +++ str "b")
+ "| a\n|\n| b" =?> para (str "a" <> linebreak <>
+ linebreak <> str " " <> str "b")
, "field list" =:
[_LIT|
:Hostname: media08
@@ -51,10 +51,10 @@ tests = [ "line block with blank line" =:
, "URLs with following punctuation" =:
("http://google.com, http://yahoo.com; http://foo.bar.baz.\n" ++
"http://foo.bar/baz_(bam) (http://foo.bar)") =?>
- para (link "http://google.com" "" "http://google.com" +++ ", " +++
- link "http://yahoo.com" "" "http://yahoo.com" +++ "; " +++
- link "http://foo.bar.baz" "" "http://foo.bar.baz" +++ ". " +++
+ para (link "http://google.com" "" "http://google.com" <> ", " <>
+ link "http://yahoo.com" "" "http://yahoo.com" <> "; " <>
+ link "http://foo.bar.baz" "" "http://foo.bar.baz" <> ". " <>
link "http://foo.bar/baz_(bam)" "" "http://foo.bar/baz_(bam)"
- +++ " (" +++ link "http://foo.bar" "" "http://foo.bar" +++ ")")
+ <> " (" <> link "http://foo.bar" "" "http://foo.bar" <> ")")
]
diff --git a/src/Tests/Writers/ConTeXt.hs b/src/Tests/Writers/ConTeXt.hs
index 704571e95..506ff698f 100644
--- a/src/Tests/Writers/ConTeXt.hs
+++ b/src/Tests/Writers/ConTeXt.hs
@@ -26,7 +26,7 @@ which is in turn shorthand for
test context "my test" (X,Y)
-}
-infix 5 =:
+infix 4 =:
(=:) :: (ToString a, ToPandoc a)
=> String -> (a, String) -> Test
(=:) = test context
@@ -43,9 +43,7 @@ tests = [ testGroup "inline code"
]
, testGroup "headers"
[ "level 1" =:
- header 1 "My header" =?> "\\subject{My header}"
- , property "header 1 property" $ \ils ->
- context' (header 1 ils) == "\\subject{" ++ context' ils ++ "}"
+ header 1 "My header" =?> "\\section[my-header]{My header}"
]
, testGroup "bullet lists"
[ "nested" =:
diff --git a/src/Tests/Writers/HTML.hs b/src/Tests/Writers/HTML.hs
index 3e1e0ddc2..8561aa421 100644
--- a/src/Tests/Writers/HTML.hs
+++ b/src/Tests/Writers/HTML.hs
@@ -23,7 +23,7 @@ which is in turn shorthand for
test html "my test" (X,Y)
-}
-infix 5 =:
+infix 4 =:
(=:) :: (ToString a, ToPandoc a)
=> String -> (a, String) -> Test
(=:) = test html
@@ -40,7 +40,7 @@ tests = [ testGroup "inline code"
]
, testGroup "images"
[ "alt with formatting" =:
- image "/url" "title" ("my " +++ emph "image")
+ image "/url" "title" ("my " <> emph "image")
=?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"
]
]
diff --git a/src/Tests/Writers/Markdown.hs b/src/Tests/Writers/Markdown.hs
index 70266a683..d90dc83b1 100644
--- a/src/Tests/Writers/Markdown.hs
+++ b/src/Tests/Writers/Markdown.hs
@@ -22,13 +22,13 @@ which is in turn shorthand for
test markdown "my test" (X,Y)
-}
-infix 5 =:
+infix 4 =:
(=:) :: (ToString a, ToPandoc a)
=> String -> (a, String) -> Test
(=:) = test markdown
tests :: [Test]
tests = [ "indented code after list"
- =: (orderedList [ para "one" +++ para "two" ] +++ codeBlock "test")
+ =: (orderedList [ para "one" <> para "two" ] <> codeBlock "test")
=?> "1. one\n\n two\n\n<!-- -->\n\n test"
]
diff --git a/src/Text/Pandoc.hs b/src/Text/Pandoc.hs
index ef8560284..878f0e0dd 100644
--- a/src/Text/Pandoc.hs
+++ b/src/Text/Pandoc.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE ScopedTypeVariables, FlexibleInstances #-}
{-
Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
@@ -94,8 +95,10 @@ module Text.Pandoc
, writeTextile
, writeRTF
, writeODT
+ , writeDocx
, writeEPUB
, writeOrg
+ , writeAsciiDoc
-- * Writer options used in writers
, WriterOptions (..)
, HTMLSlideVariant (..)
@@ -109,6 +112,7 @@ module Text.Pandoc
-- * Miscellaneous
, rtfEmbedImage
, jsonFilter
+ , ToJsonFilter(..)
) where
import Text.Pandoc.Definition
@@ -127,6 +131,7 @@ import Text.Pandoc.Writers.ConTeXt
import Text.Pandoc.Writers.Texinfo
import Text.Pandoc.Writers.HTML
import Text.Pandoc.Writers.ODT
+import Text.Pandoc.Writers.Docx
import Text.Pandoc.Writers.EPUB
import Text.Pandoc.Writers.Docbook
import Text.Pandoc.Writers.OpenDocument
@@ -135,6 +140,7 @@ import Text.Pandoc.Writers.RTF
import Text.Pandoc.Writers.MediaWiki
import Text.Pandoc.Writers.Textile
import Text.Pandoc.Writers.Org
+import Text.Pandoc.Writers.AsciiDoc
import Text.Pandoc.Templates
import Text.Pandoc.Parsing
import Text.Pandoc.Shared
@@ -164,20 +170,28 @@ readers = [("native" , \_ -> readNative)
]
-- | Association list of formats and writers (omitting the
--- binary writers, odt and epub).
+-- binary writers, odt, docx, and epub).
writers :: [ ( String, WriterOptions -> Pandoc -> String ) ]
writers = [("native" , writeNative)
,("json" , \_ -> encodeJSON)
,("html" , writeHtmlString)
+ ,("html5" , \o ->
+ writeHtmlString o{ writerHtml5 = True })
,("html+lhs" , \o ->
writeHtmlString o{ writerLiterateHaskell = True })
+ ,("html5+lhs" , \o ->
+ writeHtmlString o{ writerLiterateHaskell = True,
+ writerHtml5 = True })
,("s5" , writeHtmlString)
,("slidy" , writeHtmlString)
+ ,("dzslides" , writeHtmlString)
,("docbook" , writeDocbook)
,("opendocument" , writeOpenDocument)
,("latex" , writeLaTeX)
,("latex+lhs" , \o ->
writeLaTeX o{ writerLiterateHaskell = True })
+ ,("beamer" , \o ->
+ writeLaTeX o{ writerBeamer = True })
,("context" , writeConTeXt)
,("texinfo" , writeTexinfo)
,("man" , writeMan)
@@ -192,10 +206,55 @@ writers = [("native" , writeNative)
,("textile" , writeTextile)
,("rtf" , writeRTF)
,("org" , writeOrg)
+ ,("asciidoc" , writeAsciiDoc)
]
+{-# DEPRECATED jsonFilter "Use toJsonFilter instead" #-}
-- | Converts a transformation on the Pandoc AST into a function
-- that reads and writes a JSON-encoded string. This is useful
-- for writing small scripts.
jsonFilter :: (Pandoc -> Pandoc) -> String -> String
jsonFilter f = encodeJSON . f . decodeJSON
+
+-- | 'toJsonFilter' convert a function into a filter that reads pandoc's json output
+-- from stdin, transforms it by walking the AST and applying the specified
+-- function, and writes the result as json to stdout. Usage example:
+--
+-- > -- capitalize.hs
+-- > -- compile with: ghc --make capitalize
+-- > -- run with: pandoc -t json | ./capitalize | pandoc -f json
+-- >
+-- > import Text.Pandoc
+-- > import Data.Char (toUpper)
+-- >
+-- > main :: IO ()
+-- > main = toJsonFilter capitalizeStrings
+-- >
+-- > capitalizeStrings :: Inline -> Inline
+-- > capitalizeStrings (Str s) = Str $ map toUpper s
+-- > capitalizeStrings x = x
+--
+-- The function can be any type @(a -> a)@, @(a -> IO a)@, @(a -> [a])@,
+-- or @(a -> IO [a])@, where @a@ is an instance of 'Data'.
+-- So, for example, @a@ can be 'Pandoc', 'Inline', 'Block', ['Inline'],
+-- ['Block'], 'Meta', 'ListNumberStyle', 'Alignment', 'ListNumberDelim',
+-- 'QuoteType', etc. See 'Text.Pandoc.Definition'.
+class ToJsonFilter a where
+ toJsonFilter :: a -> IO ()
+
+instance (Data a) => ToJsonFilter (a -> a) where
+ toJsonFilter f = getContents
+ >>= putStr . encodeJSON . (bottomUp f :: Pandoc -> Pandoc) . decodeJSON
+
+instance (Data a) => ToJsonFilter (a -> IO a) where
+ toJsonFilter f = getContents >>= (bottomUpM f :: Pandoc -> IO Pandoc) . decodeJSON
+ >>= putStr . encodeJSON
+
+instance (Data a) => ToJsonFilter (a -> [a]) where
+ toJsonFilter f = getContents
+ >>= putStr . encodeJSON . (bottomUp (concatMap f) :: Pandoc -> Pandoc) . decodeJSON
+
+instance (Data a) => ToJsonFilter (a -> IO [a]) where
+ toJsonFilter f = getContents
+ >>= (bottomUpM (fmap concat . mapM f) :: Pandoc -> IO Pandoc) . decodeJSON
+ >>= putStr . encodeJSON
diff --git a/src/Text/Pandoc/Biblio.hs b/src/Text/Pandoc/Biblio.hs
index d65c9de1c..c8e87b2a0 100644
--- a/src/Text/Pandoc/Biblio.hs
+++ b/src/Text/Pandoc/Biblio.hs
@@ -31,7 +31,7 @@ module Text.Pandoc.Biblio ( processBiblio ) where
import Data.List
import Data.Unique
-import Data.Char ( isDigit, isPunctuation )
+import Data.Char ( isDigit )
import qualified Data.Map as M
import Text.CSL hiding ( Cite(..), Citation(..) )
import qualified Text.CSL as CSL ( Cite(..) )
@@ -43,11 +43,15 @@ import Control.Monad
-- | Process a 'Pandoc' document by adding citations formatted
-- according to a CSL style, using 'citeproc' from citeproc-hs.
-processBiblio :: FilePath -> [Reference] -> Pandoc -> IO Pandoc
-processBiblio cslfile r p
+processBiblio :: FilePath -> Maybe FilePath -> [Reference] -> Pandoc
+ -> IO Pandoc
+processBiblio cslfile abrfile r p
= if null r then return p
else do
csl <- readCSLFile cslfile
+ abbrevs <- case abrfile of
+ Just f -> readJsonAbbrevFile f
+ Nothing -> return []
p' <- bottomUpM setHash p
let (nts,grps) = if styleClass csl == "note"
then let cits = queryWith getCite p'
@@ -55,29 +59,36 @@ processBiblio cslfile r p
needNt = cits \\ concat ncits
in (,) needNt $ getNoteCitations needNt p'
else (,) [] $ queryWith getCitation p'
- result = citeproc procOpts csl r (setNearNote csl $
+ style = csl { styleAbbrevs = abbrevs }
+ result = citeproc procOpts style r (setNearNote style $
map (map toCslCite) grps)
cits_map = M.fromList $ zip grps (citations result)
- biblioList = map (renderPandoc' csl) (bibliography result)
- Pandoc m b = bottomUp (procInlines $ processCite csl cits_map) p'
+ biblioList = map (renderPandoc' style) (bibliography result)
+ Pandoc m b = bottomUp (procInlines $ processCite style cits_map) p'
return . generateNotes nts . Pandoc m $ b ++ biblioList
-- | Substitute 'Cite' elements with formatted citations.
processCite :: Style -> M.Map [Citation] [FormattedOutput] -> [Inline] -> [Inline]
+processCite s cs (Cite t _ : rest) =
+ case M.lookup t cs of
+ Just (x:xs) ->
+ if isTextualCitation t
+ then renderPandoc s [x] ++
+ if null xs
+ then processCite s cs rest
+ else [Space, Cite t (renderPandoc s xs)]
+ ++ processCite s cs rest
+ else Cite t (renderPandoc s (x:xs)) : processCite s cs rest
+ _ -> Str ("Error processing " ++ show t) : processCite s cs rest
+processCite s cs (x:xs) = x : processCite s cs xs
processCite _ _ [] = []
-processCite s cs (i:is)
- | Cite t _ <- i = process t ++ processCite s cs is
- | otherwise = i : processCite s cs is
- where
- addNt t x = if null x then [] else [Cite t $ renderPandoc s x]
- process t = case M.lookup t cs of
- Just x -> if isTextualCitation t && x /= []
- then renderPandoc s [head x] ++
- if tail x /= []
- then Space : addNt t (tail x)
- else []
- else [Cite t $ renderPandoc s x]
- Nothing -> [Str ("Error processing " ++ show t)]
+
+procInlines :: ([Inline] -> [Inline]) -> Block -> Block
+procInlines f b
+ | Plain inls <- b = Plain $ f inls
+ | Para inls <- b = Para $ f inls
+ | Header i inls <- b = Header i $ f inls
+ | otherwise = b
isTextualCitation :: [Citation] -> Bool
isTextualCitation (c:_) = citationMode c == AuthorInText
@@ -112,13 +123,6 @@ setHash (Citation i p s cm nn _)
generateNotes :: [Inline] -> Pandoc -> Pandoc
generateNotes needNote = bottomUp (mvCiteInNote needNote)
-procInlines :: ([Inline] -> [Inline]) -> Block -> Block
-procInlines f b
- | Plain inls <- b = Plain $ f inls
- | Para inls <- b = Para $ f inls
- | Header i inls <- b = Header i $ f inls
- | otherwise = b
-
mvCiteInNote :: [Inline] -> Block -> Block
mvCiteInNote is = procInlines mvCite
where
@@ -143,9 +147,8 @@ mvCiteInNote is = procInlines mvCite
| otherwise = toCapital (i ++ [Str "."])
checkPt i
- | Cite c o : xs <- i
- , endWithPunct o, startWithPunct xs
- , endWithPunct o = Cite c (initInline o) : checkPt xs
+ | Cite c o : xs <- i , endWithPunct o, startWithPunct xs
+ = Cite c (initInline o) : checkPt xs
| x:xs <- i = x : checkPt xs
| otherwise = []
checkNt = bottomUp $ procInlines checkPt
@@ -165,13 +168,9 @@ toCslCite c
AuthorInText -> (True, False)
SuppressAuthor -> (False,True )
NormalCitation -> (False,False)
- s' = case s of
- [] -> []
- (Str (y:_) : _) | isPunctuation y -> s
- _ -> Str "," : Space : s
in emptyCite { CSL.citeId = citationId c
, CSL.citePrefix = PandocText $ citationPrefix c
- , CSL.citeSuffix = PandocText $ s'
+ , CSL.citeSuffix = PandocText $ s
, CSL.citeLabel = la
, CSL.citeLocator = lo
, CSL.citeNoteNumber = show $ citationNoteNum c
@@ -182,9 +181,13 @@ toCslCite c
locatorWords :: [Inline] -> (String, [Inline])
locatorWords inp =
- case parse pLocatorWords "suffix" inp of
+ case parse pLocatorWords "suffix" $ breakup inp of
Right r -> r
Left _ -> ("",inp)
+ where breakup [] = []
+ breakup (Str x : xs) = map Str (splitup x) ++ breakup xs
+ breakup (x : xs) = x : breakup xs
+ splitup = groupBy (\x y -> x /= '\160' && y /= '\160')
pLocatorWords :: GenParser Inline st (String, [Inline])
pLocatorWords = do
@@ -201,7 +204,7 @@ pMatch condition = try $ do
return t
pSpace :: GenParser Inline st Inline
-pSpace = pMatch (== Space)
+pSpace = pMatch (\t -> t == Space || t == Str "\160")
pLocator :: GenParser Inline st String
pLocator = try $ do
diff --git a/src/Text/Pandoc/CharacterReferences.hs b/src/Text/Pandoc/CharacterReferences.hs
deleted file mode 100644
index 8157d94d3..000000000
--- a/src/Text/Pandoc/CharacterReferences.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-{-
-Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-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.CharacterReferences
- Copyright : Copyright (C) 2006-2010 John MacFarlane
- License : GNU GPL, version 2 or above
-
- Maintainer : John MacFarlane <jgm@berkeley.edu>
- Stability : alpha
- Portability : portable
-
-Functions for parsing character references.
--}
-module Text.Pandoc.CharacterReferences (
- characterReference,
- decodeCharacterReferences,
- ) where
-import Text.ParserCombinators.Parsec
-import Text.HTML.TagSoup.Entity ( lookupNamedEntity, lookupNumericEntity )
-import Data.Maybe ( fromMaybe )
-
--- | Parse character entity.
-characterReference :: GenParser Char st Char
-characterReference = try $ do
- char '&'
- character <- numRef <|> entity
- char ';'
- return character
-
-numRef :: GenParser Char st Char
-numRef = do
- char '#'
- num <- hexNum <|> decNum
- return $ fromMaybe '?' $ lookupNumericEntity num
-
-hexNum :: GenParser Char st [Char]
-hexNum = do
- x <- oneOf "Xx"
- num <- many1 hexDigit
- return (x:num)
-
-decNum :: GenParser Char st [Char]
-decNum = many1 digit
-
-entity :: GenParser Char st Char
-entity = do
- body <- many1 alphaNum
- return $ fromMaybe '?' $ lookupNamedEntity body
-
--- | Convert entities in a string to characters.
-decodeCharacterReferences :: String -> String
-decodeCharacterReferences str =
- case parse (many (characterReference <|> anyChar)) str str of
- Left err -> error $ "\nError: " ++ show err
- Right result -> result
-
diff --git a/src/Text/Pandoc/Highlighting.hs b/src/Text/Pandoc/Highlighting.hs
index 5ddaf1379..4fb799cf1 100644
--- a/src/Text/Pandoc/Highlighting.hs
+++ b/src/Text/Pandoc/Highlighting.hs
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Text.Pandoc.Highlighting
Copyright : Copyright (C) 2008 John MacFarlane
- License : GNU GPL, version 2 or above
+ License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
Stability : alpha
@@ -28,47 +28,49 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Exports functions for syntax highlighting.
-}
-module Text.Pandoc.Highlighting ( languages, highlightHtml, defaultHighlightingCss, languagesByExtension ) where
-import Text.XHtml
+module Text.Pandoc.Highlighting ( languages
+ , languagesByExtension
+ , highlight
+ , formatLaTeXInline
+ , formatLaTeXBlock
+ , styleToLaTeX
+ , formatHtmlInline
+ , formatHtmlBlock
+ , styleToCss
+ , pygments
+ , espresso
+ , tango
+ , kate
+ , monochrome
+ , haddock
+ , Style
+ ) where
import Text.Pandoc.Definition
-#ifdef _HIGHLIGHTING
-import Text.Highlighting.Kate ( languages, highlightAs, formatAsXHtml, FormatOption (..), defaultHighlightingCss, languagesByExtension )
+import Text.Highlighting.Kate
import Data.List (find)
import Data.Maybe (fromMaybe)
import Data.Char (toLower)
-highlightHtml :: Bool -- ^ True if inline HTML
- -> Attr -- ^ Attributes of the Code or CodeBlock
- -> String -- ^ Raw contents of the Code or CodeBlock
- -> Either String Html -- ^ An error or the formatted Html
-highlightHtml inline (_, classes, keyvals) rawCode =
- let firstNum = read $ fromMaybe "1" $ lookup "startFrom" keyvals
- fmtOpts = [OptNumberFrom firstNum] ++
- [OptInline | inline] ++
- case find (`elem` ["number","numberLines","number-lines"]) classes of
- Nothing -> []
- Just _ -> [OptNumberLines]
- addBirdTracks = "literate" `elem` classes
- lcLanguages = map (map toLower) languages
- in case find (\c -> (map toLower c) `elem` lcLanguages) classes of
- Nothing -> Left "Unknown or unsupported language"
- Just language -> case highlightAs language rawCode of
- Left err -> Left err
- Right hl -> Right $ formatAsXHtml fmtOpts language $
- if addBirdTracks
- then map ((["Special"],"> "):) hl
- else hl
+lcLanguages :: [String]
+lcLanguages = map (map toLower) languages
-#else
-defaultHighlightingCss :: String
-defaultHighlightingCss = ""
+highlight :: (FormatOptions -> [SourceLine] -> a) -- ^ Formatter
+ -> Attr -- ^ Attributes of the CodeBlock
+ -> String -- ^ Raw contents of the CodeBlock
+ -> Maybe a -- ^ Maybe the formatted result
+highlight formatter (_, classes, keyvals) rawCode =
+ let firstNum = case reads (fromMaybe "1" $ lookup "startFrom" keyvals) of
+ ((n,_):_) -> n
+ [] -> 1
+ fmtOpts = defaultFormatOpts{
+ startNumber = firstNum,
+ numberLines = any (`elem`
+ ["number","numberLines", "number-lines"]) classes }
+ lcclasses = map (map toLower) classes
+ in case find (`elem` lcLanguages) lcclasses of
+ Nothing -> Nothing
+ Just language -> Just
+ $ formatter fmtOpts{ codeClasses = [language],
+ containerClasses = classes }
+ $ highlightAs language rawCode
-languages :: [String]
-languages = []
-
-languagesByExtension :: String -> [String]
-languagesByExtension _ = []
-
-highlightHtml :: Bool -> Attr -> String -> Either String Html
-highlightHtml _ _ _ = Left "Pandoc was not compiled with support for highlighting"
-#endif
diff --git a/src/Text/Pandoc/ImageSize.hs b/src/Text/Pandoc/ImageSize.hs
new file mode 100644
index 000000000..d48c6a5ae
--- /dev/null
+++ b/src/Text/Pandoc/ImageSize.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
+{-
+ Copyright (C) 2011 John MacFarlane <jgm@berkeley.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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.ImageSize
+Copyright : Copyright (C) 2011 John MacFarlane
+License : GNU GPL, version 2 or above
+
+Maintainer : John MacFarlane <jgm@berkeley.edu>
+Stability : alpha
+Portability : portable
+
+Functions for determining the size of a PNG, JPEG, or GIF image.
+-}
+module Text.Pandoc.ImageSize ( ImageType(..), imageType, imageSize,
+ sizeInPixels, sizeInPoints, readImageSize ) where
+import Data.ByteString.Lazy (ByteString, unpack)
+import qualified Data.ByteString.Lazy.Char8 as B
+import Control.Monad
+import Data.Bits
+
+-- quick and dirty functions to get image sizes
+-- algorithms borrowed from wwwis.pl
+
+data ImageType = Png | Gif | Jpeg deriving Show
+
+data ImageSize = ImageSize{
+ pxX :: Integer
+ , pxY :: Integer
+ , dpiX :: Integer
+ , dpiY :: Integer
+ } deriving (Read, Show, Eq)
+
+
+readImageSize :: FilePath -> IO (Maybe ImageSize)
+readImageSize fp = imageSize `fmap` B.readFile fp
+
+imageType :: ByteString -> Maybe ImageType
+imageType img = case B.take 4 img of
+ "\x89\x50\x4e\x47" -> return Png
+ "\x47\x49\x46\x38" -> return Gif
+ "\xff\xd8\xff\xe0" -> return Jpeg
+ _ -> fail "Unknown image type"
+
+imageSize :: ByteString -> Maybe ImageSize
+imageSize img = do
+ t <- imageType img
+ case t of
+ Png -> pngSize img
+ Gif -> gifSize img
+ Jpeg -> jpegSize img
+
+sizeInPixels :: ImageSize -> (Integer, Integer)
+sizeInPixels s = (pxX s, pxY s)
+
+sizeInPoints :: ImageSize -> (Integer, Integer)
+sizeInPoints s = (pxX s * 72 `div` dpiX s, pxY s * 72 `div` dpiY s)
+
+pngSize :: ByteString -> Maybe ImageSize
+pngSize img = do
+ let (h, rest) = B.splitAt 8 img
+ guard $ h == "\x8a\x4d\x4e\x47\x0d\x0a\x1a\x0a" ||
+ h == "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
+ let (i, rest') = B.splitAt 4 $ B.drop 4 rest
+ guard $ i == "MHDR" || i == "IHDR"
+ let (sizes, rest'') = B.splitAt 8 rest'
+ (x,y) <- case map fromIntegral $ unpack $ sizes of
+ ([w1,w2,w3,w4,h1,h2,h3,h4] :: [Integer]) -> return
+ ((shift w1 24) + (shift w2 16) + (shift w3 8) + w4,
+ (shift h1 24) + (shift h2 16) + (shift h3 8) + h4)
+ _ -> fail "PNG parse error"
+ let (dpix, dpiy) = findpHYs rest''
+ return $ ImageSize { pxX = x, pxY = y, dpiX = dpix, dpiY = dpiy }
+
+findpHYs :: ByteString -> (Integer, Integer)
+findpHYs x =
+ if B.null x || "IDAT" `B.isPrefixOf` x
+ then (72,72) -- default, no pHYs
+ else if "pHYs" `B.isPrefixOf` x
+ then let [x1,x2,x3,x4,y1,y2,y3,y4,u] = map fromIntegral
+ $ unpack $ B.take 9 $ B.drop 4 x
+ factor = if u == 1 -- dots per meter
+ then \z -> z * 254 `div` 10000
+ else const 72
+ in ( factor $ (shift x1 24) + (shift x2 16) + (shift x3 8) + x4,
+ factor $ (shift y1 24) + (shift y2 16) + (shift y3 8) + y4 )
+ else findpHYs $ B.drop 1 x -- read another byte
+
+gifSize :: ByteString -> Maybe ImageSize
+gifSize img = do
+ let (h, rest) = B.splitAt 6 img
+ guard $ h == "GIF87a" || h == "GIF89a"
+ case map fromIntegral $ unpack $ B.take 4 rest of
+ [w2,w1,h2,h1] -> return ImageSize {
+ pxX = shift w1 8 + w2,
+ pxY = shift h1 8 + h2,
+ dpiX = 72,
+ dpiY = 72
+ }
+ _ -> fail "GIF parse error"
+
+jpegSize :: ByteString -> Maybe ImageSize
+jpegSize img = do
+ let (hdr, rest) = B.splitAt 4 img
+ guard $ hdr == "\xff\xd8\xff\xe0"
+ guard $ B.length rest >= 14
+ let [dpiDensity,dpix1,dpix2,dpiy1,dpiy2] = map fromIntegral
+ $ unpack $ B.take 5 $ B.drop 9 $ rest
+ let factor = case dpiDensity of
+ 1 -> id
+ 2 -> \x -> (x * 254 `div` 10)
+ _ -> const 72
+ let dpix = factor (shift dpix1 8 + dpix2)
+ let dpiy = factor (shift dpiy1 8 + dpiy2)
+ (w,h) <- findJpegSize rest
+ return $ ImageSize { pxX = w, pxY = h, dpiX = dpix, dpiY = dpiy }
+
+findJpegSize :: ByteString -> Maybe (Integer,Integer)
+findJpegSize bs = do
+ let bs' = B.dropWhile (=='\xff') $ B.dropWhile (/='\xff') bs
+ case B.uncons bs' of
+ Just (c,bs'') | c >= '\xc0' && c <= '\xc3' -> do
+ case map fromIntegral $ unpack $ B.take 4 $ B.drop 3 bs'' of
+ [h1,h2,w1,w2] -> return (shift w1 8 + w2, shift h1 8 + h2)
+ _ -> fail "JPEG parse error"
+ Just (_,bs'') -> do
+ case map fromIntegral $ unpack $ B.take 2 bs'' of
+ [c1,c2] -> do
+ let len = shift c1 8 + c2
+ -- skip variables
+ findJpegSize $ B.drop len bs''
+ _ -> fail "JPEG parse error"
+ Nothing -> fail "Did not find length record"
+
+
diff --git a/src/Text/Pandoc/MIME.hs b/src/Text/Pandoc/MIME.hs
index c52a4c475..d3df2f2e1 100644
--- a/src/Text/Pandoc/MIME.hs
+++ b/src/Text/Pandoc/MIME.hs
@@ -35,6 +35,7 @@ import qualified Data.Map as M
-- | Determine mime type appropriate for file path.
getMimeType :: FilePath -> Maybe String
+getMimeType "layout-cache" = Just "application/binary" -- in ODT
getMimeType f = M.lookup (map toLower $ drop 1 $ takeExtension f) mimeTypes
where mimeTypes = M.fromList -- List borrowed from happstack-server.
[("gz","application/x-gzip")
@@ -294,6 +295,7 @@ getMimeType f = M.lookup (map toLower $ drop 1 $ takeExtension f) mimeTypes
,("oth","application/vnd.oasis.opendocument.text-web")
,("otp","application/vnd.oasis.opendocument.presentation-template")
,("ots","application/vnd.oasis.opendocument.spreadsheet-template")
+ ,("otf","application/x-font-opentype")
,("ott","application/vnd.oasis.opendocument.text-template")
,("oza","application/x-oz-application")
,("p","text/x-pascal")
@@ -427,6 +429,7 @@ getMimeType f = M.lookup (map toLower $ drop 1 $ takeExtension f) mimeTypes
,("ts","text/texmacs")
,("tsp","application/dsptype")
,("tsv","text/tab-separated-values")
+ ,("ttf","application/x-font-truetype")
,("txt","text/plain")
,("udeb","application/x-debian-package")
,("uls","text/iuls")
diff --git a/src/Text/Pandoc/PDF.hs b/src/Text/Pandoc/PDF.hs
new file mode 100644
index 000000000..cc19e1c50
--- /dev/null
+++ b/src/Text/Pandoc/PDF.hs
@@ -0,0 +1,136 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-
+Copyright (C) 2012 John MacFarlane <jgm@berkeley.edu>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+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.PDF
+ Copyright : Copyright (C) 2012 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm@berkeley.edu>
+ Stability : alpha
+ Portability : portable
+
+Conversion of LaTeX documents to PDF.
+-}
+module Text.Pandoc.PDF ( tex2pdf ) where
+
+import System.IO.Temp
+import Data.ByteString.Lazy (ByteString)
+import qualified Data.ByteString.Lazy as B
+import qualified Data.ByteString.Lazy.Char8 as BC
+import System.Exit (ExitCode (..))
+import System.FilePath
+import System.Directory
+import System.Process
+import Control.Exception (evaluate)
+import System.IO (hClose)
+import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO)
+import Text.Pandoc.UTF8 as UTF8
+import Control.Monad (unless)
+import Data.List (isInfixOf)
+
+tex2pdf :: String -- ^ tex program (pdflatex, lualatex, xelatex)
+ -> String -- ^ latex source
+ -> IO (Either ByteString ByteString)
+tex2pdf program source = withSystemTempDirectory "tex2pdf" $ \tmpdir ->
+ tex2pdf' tmpdir program source
+
+tex2pdf' :: FilePath -- ^ temp directory for output
+ -> String -- ^ tex program
+ -> String -- ^ tex source
+ -> IO (Either ByteString ByteString)
+tex2pdf' tmpDir program source = do
+ let numruns = if "\\tableofcontents" `isInfixOf` source
+ then 2
+ else 1
+ (exit, log', mbPdf) <- runTeXProgram program numruns tmpDir source
+ let msg = "Error producing PDF from TeX source."
+ case (exit, mbPdf) of
+ (ExitFailure _, _) -> return $ Left $
+ msg <> "\n" <> extractMsg log'
+ (ExitSuccess, Nothing) -> return $ Left msg
+ (ExitSuccess, Just pdf) -> return $ Right pdf
+
+(<>) :: ByteString -> ByteString -> ByteString
+(<>) = B.append
+
+-- parsing output
+
+extractMsg :: ByteString -> ByteString
+extractMsg log' = do
+ let msg' = dropWhile (not . ("!" `BC.isPrefixOf`)) $ BC.lines log'
+ let (msg'',rest) = break ("l." `BC.isPrefixOf`) msg'
+ let lineno = take 1 rest
+ if null msg'
+ then log'
+ else BC.unlines (msg'' ++ lineno)
+
+-- running tex programs
+
+-- Run a TeX program on an input bytestring and return (exit code,
+-- contents of stdout, contents of produced PDF if any). Rerun
+-- a fixed number of times to resolve references.
+runTeXProgram :: String -> Int -> FilePath -> String
+ -> IO (ExitCode, ByteString, Maybe ByteString)
+runTeXProgram program runsLeft tmpDir source = do
+ let file = tmpDir </> "input.tex"
+ exists <- doesFileExist file
+ unless exists $ UTF8.writeFile file source
+ let programArgs = ["-halt-on-error", "-interaction", "nonstopmode",
+ "-output-directory", tmpDir, file]
+ (exit, out, err) <- readCommand program programArgs
+ if runsLeft > 1
+ then runTeXProgram program (runsLeft - 1) tmpDir source
+ else do
+ let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir
+ pdfExists <- doesFileExist pdfFile
+ pdf <- if pdfExists
+ then Just `fmap` B.readFile pdfFile
+ else return Nothing
+ return (exit, out <> err, pdf)
+
+-- utility functions
+
+-- Run a command and return exitcode, contents of stdout, and
+-- contents of stderr. (Based on
+-- 'readProcessWithExitCode' from 'System.Process'.)
+readCommand :: FilePath -- ^ command to run
+ -> [String] -- ^ any arguments
+ -> IO (ExitCode,ByteString,ByteString) -- ^ exit, stdout, stderr
+readCommand cmd args = do
+ (Just inh, Just outh, Just errh, pid) <-
+ createProcess (proc cmd args){ std_in = CreatePipe,
+ std_out = CreatePipe,
+ std_err = CreatePipe }
+ outMVar <- newEmptyMVar
+ -- fork off a thread to start consuming stdout
+ out <- B.hGetContents outh
+ _ <- forkIO $ evaluate (B.length out) >> putMVar outMVar ()
+ -- fork off a thread to start consuming stderr
+ err <- B.hGetContents errh
+ _ <- forkIO $ evaluate (B.length err) >> putMVar outMVar ()
+ -- now write and flush any input
+ hClose inh -- done with stdin
+ -- wait on the output
+ takeMVar outMVar
+ takeMVar outMVar
+ hClose outh
+ -- wait on the process
+ ex <- waitForProcess pid
+ return (ex, out, err)
diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs
index eaf0c0f67..725621ce2 100644
--- a/src/Text/Pandoc/Parsing.hs
+++ b/src/Text/Pandoc/Parsing.hs
@@ -42,15 +42,16 @@ module Text.Pandoc.Parsing ( (>>~),
parseFromString,
lineClump,
charsInBalanced,
- charsInBalanced',
romanNumeral,
emailAddress,
uri,
withHorizDisplacement,
+ withRaw,
nullBlock,
failIfStrict,
failUnlessLHS,
escaped,
+ characterReference,
anyOrderedListMarker,
orderedListMarker,
charRef,
@@ -78,7 +79,6 @@ import Text.Pandoc.Definition
import Text.Pandoc.Generic
import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
import Text.ParserCombinators.Parsec
-import Text.Pandoc.CharacterReferences ( characterReference )
import Data.Char ( toLower, toUpper, ord, isAscii, isAlphaNum, isDigit, isPunctuation )
import Data.List ( intercalate, transpose )
import Network.URI ( parseURI, URI (..), isAllowedInURI )
@@ -86,6 +86,7 @@ import Control.Monad ( join, liftM, guard )
import Text.Pandoc.Shared
import qualified Data.Map as M
import Text.TeXMath.Macros (applyMacros, Macro, parseMacroDefinitions)
+import Text.HTML.TagSoup.Entity ( lookupEntity )
-- | Like >>, but returns the operation on the left.
-- (Suggested by Tillmann Rendel on Haskell-cafe list.)
@@ -174,29 +175,23 @@ lineClump = blanklines
-- | Parse a string of characters between an open character
-- and a close character, including text between balanced
-- pairs of open and close, which must be different. For example,
--- @charsInBalanced '(' ')'@ will parse "(hello (there))"
--- and return "hello (there)". Stop if a blank line is
--- encountered.
-charsInBalanced :: Char -> Char -> GenParser Char st String
-charsInBalanced open close = try $ do
+-- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"
+-- and return "hello (there)".
+charsInBalanced :: Char -> Char -> GenParser Char st Char
+ -> GenParser Char st String
+charsInBalanced open close parser = try $ do
char open
- raw <- many $ (many1 (satisfy $ \c ->
- c /= open && c /= close && c /= '\n'))
- <|> (do res <- charsInBalanced open close
- return $ [open] ++ res ++ [close])
- <|> try (string "\n" >>~ notFollowedBy' blanklines)
+ let isDelim c = c == open || c == close
+ raw <- many $ many1 (notFollowedBy (satisfy isDelim) >> parser)
+ <|> (do res <- charsInBalanced open close parser
+ return $ [open] ++ res ++ [close])
char close
return $ concat raw
--- | Like @charsInBalanced@, but allow blank lines in the content.
-charsInBalanced' :: Char -> Char -> GenParser Char st String
-charsInBalanced' open close = try $ do
- char open
- raw <- many $ (many1 (satisfy $ \c -> c /= open && c /= close))
- <|> (do res <- charsInBalanced' open close
- return $ [open] ++ res ++ [close])
- char close
- return $ concat raw
+-- old charsInBalanced would be:
+-- charsInBalanced open close (noneOf "\n" <|> char '\n' >> notFollowedBy blankline)
+-- old charsInBalanced' would be:
+-- charsInBalanced open close anyChar
-- Auxiliary functions for romanNumeral:
@@ -306,6 +301,23 @@ withHorizDisplacement parser = do
pos2 <- getPosition
return (result, sourceColumn pos2 - sourceColumn pos1)
+-- | Applies a parser and returns the raw string that was parsed,
+-- along with the value produced by the parser.
+withRaw :: GenParser Char st a -> GenParser Char st (a, [Char])
+withRaw parser = do
+ pos1 <- getPosition
+ inp <- getInput
+ result <- parser
+ pos2 <- getPosition
+ let (l1,c1) = (sourceLine pos1, sourceColumn pos1)
+ let (l2,c2) = (sourceLine pos2, sourceColumn pos2)
+ let inplines = take ((l2 - l1) + 1) $ lines inp
+ let raw = case inplines of
+ [] -> error "raw: inplines is null" -- shouldn't happen
+ [l] -> take (c2 - c1) l
+ ls -> unlines (init ls) ++ take (c2 - 1) (last ls)
+ return (result, raw)
+
-- | Parses a character and returns 'Null' (so that the parser can move on
-- if it gets stuck).
nullBlock :: GenParser Char st Block
@@ -319,17 +331,21 @@ failIfStrict = do
-- | Fail unless we're in literate haskell mode.
failUnlessLHS :: GenParser tok ParserState ()
-failUnlessLHS = do
- state <- getState
- if stateLiterateHaskell state then return () else fail "Literate haskell feature"
+failUnlessLHS = getState >>= guard . stateLiterateHaskell
-- | Parses backslash, then applies character parser.
escaped :: GenParser Char st Char -- ^ Parser for character to escape
- -> GenParser Char st Inline
-escaped parser = try $ do
- char '\\'
- result <- parser
- return (Str [result])
+ -> GenParser Char st Char
+escaped parser = try $ char '\\' >> parser
+
+-- | Parse character entity.
+characterReference :: GenParser Char st Char
+characterReference = try $ do
+ char '&'
+ ent <- many1Till nonspaceChar (char ';')
+ case lookupEntity ent of
+ Just c -> return c
+ Nothing -> fail "entity not found"
-- | Parses an uppercase roman numeral and returns (UpperRoman, number).
upperRoman :: GenParser Char st (ListNumberStyle, Int)
@@ -512,7 +528,7 @@ gridTableWith block tableCaption headless =
gridTableSplitLine :: [Int] -> String -> [String]
gridTableSplitLine indices line = map removeFinalBar $ tail $
- splitByIndices (init indices) $ removeTrailingSpace line
+ splitStringByIndices (init indices) $ removeTrailingSpace line
gridPart :: Char -> GenParser Char st (Int, Int)
gridPart ch = do
@@ -598,7 +614,7 @@ readWith :: GenParser t ParserState a -- ^ parser
-> a
readWith parser state input =
case runParser parser state "source" input of
- Left err -> error $ "\nError:\n" ++ show err
+ Left err' -> error $ "\nError:\n" ++ show err'
Right result -> result
-- | Parse a string with @parser@ (for testing).
@@ -613,6 +629,8 @@ data ParserState = ParserState
{ stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
stateParserContext :: ParserContext, -- ^ Inside list?
stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
+ stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph
+ stateLastStrPos :: Maybe SourcePos, -- ^ Position after last str parsed
stateKeys :: KeyTable, -- ^ List of reference keys
stateCitations :: [String], -- ^ List of available citations
stateNotes :: NoteTable, -- ^ List of notes
@@ -623,6 +641,9 @@ data ParserState = ParserState
stateDate :: [Inline], -- ^ Date of document
stateStrict :: Bool, -- ^ Use strict markdown syntax?
stateSmart :: Bool, -- ^ Use smart typography?
+ stateOldDashes :: Bool, -- ^ Use pandoc <= 1.8.2.1 behavior
+ -- in parsing dashes; -- is em-dash;
+ -- before numeral is en-dash
stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
stateColumns :: Int, -- ^ Number of columns in terminal
stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
@@ -640,6 +661,8 @@ defaultParserState =
ParserState { stateParseRaw = False,
stateParserContext = NullState,
stateQuoteContext = NoQuote,
+ stateMaxNestingLevel = 6,
+ stateLastStrPos = Nothing,
stateKeys = M.empty,
stateCitations = [],
stateNotes = [],
@@ -650,6 +673,7 @@ defaultParserState =
stateDate = [],
stateStrict = False,
stateSmart = False,
+ stateOldDashes = False,
stateLiterateHaskell = False,
stateColumns = 80,
stateHeaderTable = [],
@@ -714,7 +738,7 @@ smartPunctuation inlineParser = do
choice [ quoted inlineParser, apostrophe, dash, ellipses ]
apostrophe :: GenParser Char ParserState Inline
-apostrophe = (char '\'' <|> char '\8217') >> return Apostrophe
+apostrophe = (char '\'' <|> char '\8217') >> return (Str "\x2019")
quoted :: GenParser Char ParserState Inline
-> GenParser Char ParserState Inline
@@ -761,8 +785,12 @@ charOrRef cs =
return c)
singleQuoteStart :: GenParser Char ParserState ()
-singleQuoteStart = do
+singleQuoteStart = do
failIfInQuoteContext InSingleQuote
+ pos <- getPosition
+ st <- getState
+ -- single quote start can't be right after str
+ guard $ stateLastStrPos st /= Just pos
try $ do charOrRef "'\8216\145"
notFollowedBy (oneOf ")!],;:-? \t\n")
notFollowedBy (char '.') <|> lookAhead (string "..." >> return ())
@@ -789,22 +817,42 @@ doubleQuoteEnd = do
ellipses :: GenParser Char st Inline
ellipses = do
- try (charOrRef "…\133") <|> try (string "..." >> return '…')
- return Ellipses
-
-dash :: GenParser Char st Inline
-dash = enDash <|> emDash
+ try (charOrRef "\8230\133") <|> try (string "..." >> return '…')
+ return (Str "\8230")
+
+dash :: GenParser Char ParserState Inline
+dash = do
+ oldDashes <- stateOldDashes `fmap` getState
+ if oldDashes
+ then emDashOld <|> enDashOld
+ else Str `fmap` (hyphenDash <|> emDash <|> enDash)
+
+-- Two hyphens = en-dash, three = em-dash
+hyphenDash :: GenParser Char st String
+hyphenDash = do
+ try $ string "--"
+ option "\8211" (char '-' >> return "\8212")
+
+emDash :: GenParser Char st String
+emDash = do
+ try (charOrRef "\8212\151")
+ return "\8212"
-enDash :: GenParser Char st Inline
+enDash :: GenParser Char st String
enDash = do
- try (charOrRef "–\150") <|>
+ try (charOrRef "\8212\151")
+ return "\8211"
+
+enDashOld :: GenParser Char st Inline
+enDashOld = do
+ try (charOrRef "\8211\150") <|>
try (char '-' >> lookAhead (satisfy isDigit) >> return '–')
- return EnDash
+ return (Str "\8211")
-emDash :: GenParser Char st Inline
-emDash = do
- try (charOrRef "—\151") <|> (try $ string "--" >> optional (char '-') >> return '—')
- return EmDash
+emDashOld :: GenParser Char st Inline
+emDashOld = do
+ try (charOrRef "\8212\151") <|> (try $ string "--" >> optional (char '-') >> return '-')
+ return (Str "\8212")
--
-- Macros
diff --git a/src/Text/Pandoc/Pretty.hs b/src/Text/Pandoc/Pretty.hs
index 54d65af6f..bf78b2594 100644
--- a/src/Text/Pandoc/Pretty.hs
+++ b/src/Text/Pandoc/Pretty.hs
@@ -42,6 +42,7 @@ module Text.Pandoc.Pretty (
, flush
, nest
, hang
+ , beforeNonBlank
, nowrap
, offset
, height
@@ -59,16 +60,20 @@ module Text.Pandoc.Pretty (
, hsep
, vcat
, vsep
+ , chomp
, inside
, braces
, brackets
, parens
, quotes
, doubleQuotes
+ , charWidth
+ , realLength
)
where
-import Data.DList (DList, fromList, toList, cons, singleton)
+import Data.Sequence (Seq, fromList, (<|), singleton, mapWithIndex)
+import Data.Foldable (toList)
import Data.List (intercalate)
import Data.Monoid
import Data.String
@@ -90,6 +95,7 @@ type DocState a = State (RenderState a) ()
data D = Text Int String
| Block Int [String]
| Prefixed String Doc
+ | BeforeNonBlank Doc
| Flush Doc
| BreakingSpace
| CarriageReturn
@@ -97,7 +103,7 @@ data D = Text Int String
| BlankLine
deriving (Show)
-newtype Doc = Doc { unDoc :: DList D }
+newtype Doc = Doc { unDoc :: Seq D }
deriving (Monoid)
instance Show Doc where
@@ -106,6 +112,14 @@ instance Show Doc where
instance IsString Doc where
fromString = text
+isBlank :: D -> Bool
+isBlank BreakingSpace = True
+isBlank CarriageReturn = True
+isBlank NewLine = True
+isBlank BlankLine = True
+isBlank (Text _ (c:_)) = isSpace c
+isBlank _ = False
+
-- | True if the document is empty.
isEmpty :: Doc -> Bool
isEmpty = null . toList . unDoc
@@ -114,9 +128,17 @@ isEmpty = null . toList . unDoc
empty :: Doc
empty = mempty
--- | @a <> b@ is the result of concatenating @a@ with @b@.
-(<>) :: Doc -> Doc -> Doc
+#if MIN_VERSION_base(4,5,0)
+-- (<>) is defined in Data.Monoid
+#else
+infixr 6 <>
+
+-- | An infix synonym for 'mappend'.
+-- @a <> b@ is the result of concatenating @a@ with @b@.
+(<>) :: Monoid m => m -> m -> m
(<>) = mappend
+{-# INLINE (<>) #-}
+#endif
-- | Concatenate a list of 'Doc's.
cat :: [Doc] -> Doc
@@ -128,6 +150,7 @@ hcat = mconcat
-- | Concatenate a list of 'Doc's, putting breakable spaces
-- between them.
+infixr 6 <+>
(<+>) :: Doc -> Doc -> Doc
(<+>) x y = if isEmpty x
then y
@@ -140,6 +163,7 @@ hcat = mconcat
hsep :: [Doc] -> Doc
hsep = foldr (<+>) empty
+infixr 5 $$
-- | @a $$ b@ puts @a@ above @b@.
($$) :: Doc -> Doc -> Doc
($$) x y = if isEmpty x
@@ -148,6 +172,7 @@ hsep = foldr (<+>) empty
then x
else x <> cr <> y
+infixr 5 $+$
-- | @a $$ b@ puts @a@ above @b@, with a blank line between.
($+$) :: Doc -> Doc -> Doc
($+$) x y = if isEmpty x
@@ -164,6 +189,17 @@ vcat = foldr ($$) empty
vsep :: [Doc] -> Doc
vsep = foldr ($+$) empty
+-- | Chomps trailing blank space off of a 'Doc'.
+chomp :: Doc -> Doc
+chomp d = Doc (fromList dl')
+ where dl = toList (unDoc d)
+ dl' = reverse $ dropWhile removeable $ reverse dl
+ removeable BreakingSpace = True
+ removeable CarriageReturn = True
+ removeable NewLine = True
+ removeable BlankLine = True
+ removeable _ = False
+
outp :: (IsString a, Monoid a)
=> Int -> String -> DocState a
outp off s | off <= 0 = do
@@ -172,7 +208,7 @@ outp off s | off <= 0 = do
when (column st' == 0 && usePrefix st' && not (null rawpref)) $ do
let pref = reverse $ dropWhile isSpace $ reverse rawpref
modify $ \st -> st{ output = fromString pref : output st
- , column = column st + length pref }
+ , column = column st + realLength pref }
when (off < 0) $ do
modify $ \st -> st { output = fromString s : output st
, column = 0
@@ -182,7 +218,7 @@ outp off s = do
let pref = prefix st'
when (column st' == 0 && usePrefix st' && not (null pref)) $ do
modify $ \st -> st{ output = fromString pref : output st
- , column = column st + length pref }
+ , column = column st + realLength pref }
modify $ \st -> st{ output = fromString s : output st
, column = column st + off
, newlines = 0 }
@@ -229,6 +265,12 @@ renderList (Flush d : xs) = do
modify $ \s -> s{ usePrefix = oldUsePrefix }
renderList xs
+renderList (BeforeNonBlank d : xs) =
+ case xs of
+ (x:_) | isBlank x -> renderList xs
+ | otherwise -> renderDoc d >> renderList xs
+ [] -> renderList xs
+
renderList (BlankLine : xs) = do
st <- get
case output st of
@@ -283,7 +325,7 @@ renderList (b1@Block{} : BreakingSpace : b2@Block{} : xs) =
renderList (Block width lns : xs) = do
st <- get
let oldPref = prefix st
- case column st - length oldPref of
+ case column st - realLength oldPref of
n | n > 0 -> modify $ \s -> s{ prefix = oldPref ++ replicate n ' ' }
_ -> return ()
renderDoc $ blockToDoc width lns
@@ -295,7 +337,7 @@ mergeBlocks addSpace (Block w1 lns1) (Block 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) ""
- pad n s = s ++ replicate (n - length s) ' '
+ pad n s = s ++ replicate (n - realLength s) ' '
sp "" = ""
sp xs = if addSpace then (' ' : xs) else xs
mergeBlocks _ _ _ = error "mergeBlocks tried on non-Block!"
@@ -312,13 +354,13 @@ offsetOf _ = 0
-- | A literal string.
text :: String -> Doc
text = Doc . toChunks
- where toChunks :: String -> DList D
+ where toChunks :: String -> Seq D
toChunks [] = mempty
toChunks s = case break (=='\n') s of
- ([], _:ys) -> NewLine `cons` toChunks ys
- (xs, _:ys) -> Text (length xs) xs `cons`
- NewLine `cons` toChunks ys
- (xs, []) -> singleton $ Text (length xs) xs
+ ([], _:ys) -> NewLine <| toChunks ys
+ (xs, _:ys) -> Text (realLength xs) xs <|
+ (NewLine <| toChunks ys)
+ (xs, []) -> singleton $ Text (realLength xs) xs
-- | A character.
char :: Char -> Doc
@@ -359,15 +401,20 @@ nest ind = prefixed (replicate ind ' ')
hang :: Int -> Doc -> Doc -> Doc
hang ind start doc = start <> nest ind doc
+-- | @beforeNonBlank d@ conditionally includes @d@ unless it is
+-- followed by blank space.
+beforeNonBlank :: Doc -> Doc
+beforeNonBlank d = Doc $ singleton (BeforeNonBlank d)
+
-- | Makes a 'Doc' non-reflowable.
nowrap :: Doc -> Doc
-nowrap doc = Doc $ fromList $ map replaceSpace $ toList $ unDoc doc
- where replaceSpace BreakingSpace = Text 1 " "
- replaceSpace x = x
+nowrap doc = Doc $ mapWithIndex replaceSpace $ unDoc doc
+ where replaceSpace _ BreakingSpace = Text 1 " "
+ replaceSpace _ x = x
-- | Returns the width of a 'Doc'.
offset :: Doc -> Int
-offset d = case map length . lines . render Nothing $ d of
+offset d = case map realLength . lines . render Nothing $ d of
[] -> 0
os -> maximum os
@@ -382,11 +429,11 @@ lblock = block id
-- | Like 'lblock' but aligned to the right.
rblock :: Int -> Doc -> Doc
-rblock w = block (\s -> replicate (w - length s) ' ' ++ s) w
+rblock w = block (\s -> replicate (w - realLength s) ' ' ++ s) w
-- | Like 'lblock' but aligned centered.
cblock :: Int -> Doc -> Doc
-cblock w = block (\s -> replicate ((w - length s) `div` 2) ' ' ++ s) w
+cblock w = block (\s -> replicate ((w - realLength s) `div` 2) ' ' ++ s) w
-- | Returns the height of a block or other 'Doc'.
height :: Doc -> Int
@@ -401,7 +448,7 @@ chop n cs = case break (=='\n') cs of
(_:[]) -> [xs, ""]
(_:zs) -> xs : chop n zs
else take n xs : chop n (drop n xs ++ ys)
- where len = length xs
+ where len = realLength xs
-- | Encloses a 'Doc' inside a start and end 'Doc'.
inside :: Doc -> Doc -> Doc -> Doc
@@ -427,3 +474,51 @@ quotes = inside (char '\'') (char '\'')
-- | Wraps a 'Doc' in double quotes.
doubleQuotes :: Doc -> Doc
doubleQuotes = inside (char '"') (char '"')
+
+-- | Returns width of a character in a monospace font: 0 for a combining
+-- character, 1 for a regular character, 2 for an East Asian wide character.
+charWidth :: Char -> Int
+charWidth c =
+ case c of
+ _ | c < '\x0300' -> 1
+ | c >= '\x0300' && c <= '\x036F' -> 0 -- combining
+ | c >= '\x0370' && c <= '\x10FC' -> 1
+ | c >= '\x1100' && c <= '\x115F' -> 2
+ | c >= '\x1160' && c <= '\x11A2' -> 1
+ | c >= '\x11A3' && c <= '\x11A7' -> 2
+ | c >= '\x11A8' && c <= '\x11F9' -> 1
+ | c >= '\x11FA' && c <= '\x11FF' -> 2
+ | c >= '\x1200' && c <= '\x2328' -> 1
+ | c >= '\x2329' && c <= '\x232A' -> 2
+ | c >= '\x232B' && c <= '\x2E31' -> 1
+ | c >= '\x2E80' && c <= '\x303E' -> 2
+ | c == '\x303F' -> 1
+ | c >= '\x3041' && c <= '\x3247' -> 2
+ | c >= '\x3248' && c <= '\x324F' -> 1 -- ambiguous
+ | c >= '\x3250' && c <= '\x4DBF' -> 2
+ | c >= '\x4DC0' && c <= '\x4DFF' -> 1
+ | c >= '\x4E00' && c <= '\xA4C6' -> 2
+ | c >= '\xA4D0' && c <= '\xA95F' -> 1
+ | c >= '\xA960' && c <= '\xA97C' -> 2
+ | c >= '\xA980' && c <= '\xABF9' -> 1
+ | c >= '\xAC00' && c <= '\xD7FB' -> 2
+ | c >= '\xD800' && c <= '\xDFFF' -> 1
+ | c >= '\xE000' && c <= '\xF8FF' -> 1 -- ambiguous
+ | c >= '\xF900' && c <= '\xFAFF' -> 2
+ | c >= '\xFB00' && c <= '\xFDFD' -> 1
+ | c >= '\xFE00' && c <= '\xFE0F' -> 1 -- ambiguous
+ | c >= '\xFE10' && c <= '\xFE19' -> 2
+ | c >= '\xFE20' && c <= '\xFE26' -> 1
+ | c >= '\xFE30' && c <= '\xFE6B' -> 2
+ | c >= '\xFE70' && c <= '\x16A38' -> 1
+ | c >= '\x1B000' && c <= '\x1B001' -> 2
+ | c >= '\x1D000' && c <= '\x1F1FF' -> 1
+ | c >= '\x1F200' && c <= '\x1F251' -> 2
+ | c >= '\x1F300' && c <= '\x1F773' -> 1
+ | c >= '\x20000' && c <= '\x3FFFD' -> 2
+ | otherwise -> 1
+
+-- | Get real length of string, taking into account combining and double-wide
+-- characters.
+realLength :: String -> Int
+realLength = sum . map charWidth
diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs
index 7c882f680..43165ceb1 100644
--- a/src/Text/Pandoc/Readers/HTML.hs
+++ b/src/Text/Pandoc/Readers/HTML.hs
@@ -215,6 +215,7 @@ pSimpleTable = try $ do
TagOpen _ _ <- pSatisfy (~== TagOpen "table" [])
skipMany pBlank
head' <- option [] $ pOptInTag "thead" $ pInTags "tr" (pCell "th")
+ skipMany pBlank
rows <- pOptInTag "tbody"
$ many1 $ try $ skipMany pBlank >> pInTags "tr" (pCell "td")
skipMany pBlank
@@ -420,8 +421,12 @@ pTagContents =
pStr <|> pSpace <|> smartPunctuation pTagContents <|> pSymbol <|> pBad
pStr :: GenParser Char ParserState Inline
-pStr = liftM Str $ many1 $ satisfy $ \c ->
- not (isSpace c) && not (isSpecial c) && not (isBad c)
+pStr = do
+ result <- many1 $ satisfy $ \c ->
+ not (isSpace c) && not (isSpecial c) && not (isBad c)
+ pos <- getPosition
+ updateState $ \s -> s{ stateLastStrPos = Just pos }
+ return $ Str result
isSpecial :: Char -> Bool
isSpecial '"' = True
@@ -502,16 +507,35 @@ blockHtmlTags = ["address", "blockquote", "body", "center", "dir", "div",
"dt", "frameset", "li", "tbody", "td", "tfoot",
"th", "thead", "tr", "script", "style"]
+-- We want to allow raw docbook in markdown documents, so we
+-- include docbook block tags here too.
+blockDocBookTags :: [String]
+blockDocBookTags = ["calloutlist", "bibliolist", "glosslist", "itemizedlist",
+ "orderedlist", "segmentedlist", "simplelist",
+ "variablelist", "caution", "important", "note", "tip",
+ "warning", "address", "literallayout", "programlisting",
+ "programlistingco", "screen", "screenco", "screenshot",
+ "synopsis", "example", "informalexample", "figure",
+ "informalfigure", "table", "informaltable", "para",
+ "simpara", "formalpara", "equation", "informalequation",
+ "figure", "screenshot", "mediaobject", "qandaset",
+ "procedure", "task", "cmdsynopsis", "funcsynopsis",
+ "classsynopsis", "blockquote", "epigraph", "msgset",
+ "sidebar", "title"]
+
+blockTags :: [String]
+blockTags = blockHtmlTags ++ blockDocBookTags
+
isInlineTag :: Tag String -> Bool
-isInlineTag t = tagOpen (`notElem` blockHtmlTags) (const True) t ||
- tagClose (`notElem` blockHtmlTags) t ||
+isInlineTag t = tagOpen (`notElem` blockTags) (const True) t ||
+ tagClose (`notElem` blockTags) t ||
tagComment (const True) t
isBlockTag :: Tag String -> Bool
isBlockTag t = tagOpen (`elem` blocktags) (const True) t ||
tagClose (`elem` blocktags) t ||
tagComment (const True) t
- where blocktags = blockHtmlTags ++ eitherBlockOrInline
+ where blocktags = blockTags ++ eitherBlockOrInline
isTextTag :: Tag String -> Bool
isTextTag = tagText (const True)
@@ -546,8 +570,8 @@ t `closes` t2 |
t `elem` ["h1","h2","h3","h4","h5","h6","dl","ol","ul","table","div","p"] &&
t2 `elem` ["h1","h2","h3","h4","h5","h6","p" ] = True -- not "div"
t1 `closes` t2 |
- t1 `elem` blockHtmlTags &&
- t2 `notElem` (blockHtmlTags ++ eitherBlockOrInline) = True
+ t1 `elem` blockTags &&
+ t2 `notElem` (blockTags ++ eitherBlockOrInline) = True
_ `closes` _ = False
--- parsers for use in markdown, textile readers
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
index 02c7361d7..5e69347b6 100644
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -1,5 +1,5 @@
{-
-Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2012 John MacFarlane <jgm@berkeley.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,8 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Text.Pandoc.Readers.LaTeX
- Copyright : Copyright (C) 2006-2010 John MacFarlane
- License : GNU GPL, version 2 or above
+ Copyright : Copyright (C) 2006-2012 John MacFarlane
+ License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
Stability : alpha
@@ -27,20 +27,26 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Conversion of LaTeX to 'Pandoc' document.
-}
-module Text.Pandoc.Readers.LaTeX (
- readLaTeX,
- rawLaTeXInline,
- rawLaTeXEnvironment'
+module Text.Pandoc.Readers.LaTeX ( readLaTeX,
+ rawLaTeXInline,
+ rawLaTeXBlock,
+ handleIncludes
) where
-import Text.ParserCombinators.Parsec
+import Text.ParserCombinators.Parsec hiding ((<|>), space, many, optional)
import Text.Pandoc.Definition
import Text.Pandoc.Shared
import Text.Pandoc.Parsing
-import Data.Maybe ( fromMaybe )
-import Data.Char ( chr, toUpper )
-import Data.List ( intercalate, isPrefixOf, isSuffixOf )
+import qualified Text.Pandoc.UTF8 as UTF8
+import Data.Char ( chr, ord )
import Control.Monad
+import Text.Pandoc.Builder
+import Data.Char (isLetter, isPunctuation, isSpace)
+import Control.Applicative
+import Data.Monoid
+import System.FilePath (replaceExtension)
+import Data.List (intercalate)
+import qualified Data.Map as M
-- | Parse LaTeX from string and return 'Pandoc' document.
readLaTeX :: ParserState -- ^ Parser state, including options for parser
@@ -48,985 +54,867 @@ readLaTeX :: ParserState -- ^ Parser state, including options for parser
-> Pandoc
readLaTeX = readWith parseLaTeX
--- characters with special meaning
-specialChars :: [Char]
-specialChars = "\\`$%^&_~#{}[]\n \t|<>'\"-"
-
---
--- utility functions
---
-
--- | Returns text between brackets and its matching pair.
-bracketedText :: Char -> Char -> GenParser Char st [Char]
-bracketedText openB closeB = do
- result <- charsInBalanced' openB closeB
- return $ [openB] ++ result ++ [closeB]
-
--- | Returns an option or argument of a LaTeX command.
-optOrArg :: GenParser Char st [Char]
-optOrArg = try $ spaces >> (bracketedText '{' '}' <|> bracketedText '[' ']')
+parseLaTeX :: LP Pandoc
+parseLaTeX = do
+ bs <- blocks
+ eof
+ st <- getState
+ let title' = stateTitle st
+ let authors' = stateAuthors st
+ let date' = stateDate st
+ return $ Pandoc (Meta title' authors' date') $ toList bs
--- | True if the string begins with '{'.
-isArg :: [Char] -> Bool
-isArg ('{':_) = True
-isArg _ = False
+type LP = GenParser Char ParserState
--- | Returns list of options and arguments of a LaTeX command.
-commandArgs :: GenParser Char st [[Char]]
-commandArgs = many optOrArg
+anyControlSeq :: LP String
+anyControlSeq = do
+ char '\\'
+ next <- option '\n' anyChar
+ name <- case next of
+ '\n' -> return ""
+ c | isLetter c -> (c:) <$> (many letter <* optional sp)
+ | otherwise -> return [c]
+ return name
--- | Parses LaTeX command, returns (name, star, list of options or arguments).
-command :: GenParser Char st ([Char], [Char], [[Char]])
-command = do
+controlSeq :: String -> LP String
+controlSeq name = try $ do
char '\\'
- name <- many1 letter
- star <- option "" (string "*") -- some commands have starred versions
- args <- commandArgs
- return (name, star, args)
-
-begin :: [Char] -> GenParser Char st [Char]
-begin name = try $ do
- string "\\begin"
- spaces
- char '{'
- string name
- char '}'
- optional commandArgs
- spaces
+ case name of
+ "" -> mzero
+ [c] | not (isLetter c) -> string [c]
+ cs -> string cs <* optional sp
return name
-end :: [Char] -> GenParser Char st [Char]
-end name = try $ do
- string "\\end"
- spaces
+sp :: LP ()
+sp = skipMany1 $ satisfy (\c -> c == ' ' || c == '\t')
+ <|> (try $ newline >>~ lookAhead anyChar >>~ notFollowedBy blankline)
+
+isLowerHex :: Char -> Bool
+isLowerHex x = x >= '0' && x <= '9' || x >= 'a' && x <= 'f'
+
+tildeEscape :: LP Char
+tildeEscape = try $ do
+ string "^^"
+ c <- satisfy (\x -> x >= '\0' && x <= '\128')
+ d <- if isLowerHex c
+ then option "" $ count 1 (satisfy isLowerHex)
+ else return ""
+ if null d
+ then case ord c of
+ x | x >= 64 && x <= 127 -> return $ chr (x - 64)
+ | otherwise -> return $ chr (x + 64)
+ else return $ chr $ read ('0':'x':c:d)
+
+comment :: LP ()
+comment = do
+ char '%'
+ skipMany (satisfy (/='\n'))
+ newline
+ return ()
+
+grouped :: Monoid a => LP a -> LP a
+grouped parser = try $ char '{' *> (mconcat <$> manyTill parser (char '}'))
+
+braced :: LP String
+braced = char '{' *> (concat <$> manyTill
+ ( many1 (satisfy (\c -> c /= '\\' && c /= '}' && c /= '{'))
+ <|> try (string "\\}")
+ <|> try (string "\\{")
+ <|> try (string "\\\\")
+ <|> ((\x -> "{" ++ x ++ "}") <$> braced)
+ <|> count 1 anyChar
+ ) (char '}'))
+
+bracketed :: Monoid a => LP a -> LP a
+bracketed parser = try $ char '[' *> (mconcat <$> manyTill parser (char ']'))
+
+trim :: String -> String
+trim = removeLeadingTrailingSpace
+
+mathDisplay :: LP String -> LP Inlines
+mathDisplay p = displayMath <$> (try p >>= applyMacros' . trim)
+
+mathInline :: LP String -> LP Inlines
+mathInline p = math <$> (try p >>= applyMacros')
+
+mathChars :: LP String
+mathChars = concat <$>
+ many ( many1 (satisfy (\c -> c /= '$' && c /='\\'))
+ <|> (\c -> ['\\',c]) <$> (try $ char '\\' *> anyChar)
+ )
+
+double_quote :: LP Inlines
+double_quote = (doubleQuoted . mconcat) <$>
+ (try $ string "``" *> manyTill inline (try $ string "''"))
+
+single_quote :: LP Inlines
+single_quote = char '`' *>
+ ( try ((singleQuoted . mconcat) <$>
+ manyTill inline (try $ char '\'' >> notFollowedBy letter))
+ <|> lit "`")
+
+inline :: LP Inlines
+inline = (mempty <$ comment)
+ <|> (space <$ sp)
+ <|> inlineText
+ <|> inlineCommand
+ <|> grouped inline
+ <|> (char '-' *> option (str "-")
+ ((char '-') *> option (str "–") (str "—" <$ char '-')))
+ <|> double_quote
+ <|> single_quote
+ <|> (str "’" <$ char '\'')
+ <|> (str "\160" <$ char '~')
+ <|> (mathDisplay $ string "$$" *> mathChars <* string "$$")
+ <|> (mathInline $ char '$' *> mathChars <* char '$')
+ <|> (superscript <$> (char '^' *> tok))
+ <|> (subscript <$> (char '_' *> tok))
+ <|> (failUnlessLHS *> char '|' *> doLHSverb)
+ <|> (str <$> count 1 tildeEscape)
+ <|> (str <$> string "]")
+ <|> (str <$> string "#") -- TODO print warning?
+ <|> (str <$> string "&") -- TODO print warning?
+ -- <|> (str <$> count 1 (satisfy (\c -> c /= '\\' && c /='\n' && c /='}' && c /='{'))) -- eat random leftover characters
+
+inlines :: LP Inlines
+inlines = mconcat <$> many (notFollowedBy (char '}') *> inline)
+
+block :: LP Blocks
+block = (mempty <$ comment)
+ <|> (mempty <$ ((spaceChar <|> blankline) *> spaces))
+ <|> environment
+ <|> mempty <$ macro -- TODO improve macros, make them work everywhere
+ <|> blockCommand
+ <|> grouped block
+ <|> paragraph
+ <|> (mempty <$ char '&') -- loose & in table environment
+
+
+blocks :: LP Blocks
+blocks = mconcat <$> many block
+
+blockCommand :: LP Blocks
+blockCommand = try $ do
+ name <- anyControlSeq
+ star <- option "" (string "*" <* optional sp)
+ let name' = name ++ star
+ case M.lookup name' blockCommands of
+ Just p -> p
+ Nothing -> case M.lookup name blockCommands of
+ Just p -> p
+ Nothing -> mzero
+
+inBrackets :: Inlines -> Inlines
+inBrackets x = (str "[") <> x <> (str "]")
+
+-- eat an optional argument and one or more arguments in braces
+ignoreInlines :: String -> (String, LP Inlines)
+ignoreInlines name = (name, doraw <|> (mempty <$ optargs))
+ where optargs = skipopts *> skipMany (try $ optional sp *> braced)
+ contseq = '\\':name
+ doraw = (rawInline "latex" . (contseq ++) . snd) <$>
+ (getState >>= guard . stateParseRaw >> (withRaw optargs))
+
+ignoreBlocks :: String -> (String, LP Blocks)
+ignoreBlocks name = (name, doraw <|> (mempty <$ optargs))
+ where optargs = skipopts *> skipMany (try $ optional sp *> braced)
+ contseq = '\\':name
+ doraw = (rawBlock "latex" . (contseq ++) . snd) <$>
+ (getState >>= guard . stateParseRaw >> (withRaw optargs))
+
+blockCommands :: M.Map String (LP Blocks)
+blockCommands = M.fromList $
+ [ ("par", mempty <$ skipopts)
+ , ("title", mempty <$ (skipopts *> tok >>= addTitle))
+ , ("subtitle", mempty <$ (skipopts *> tok >>= addSubtitle))
+ , ("author", mempty <$ (skipopts *> authors))
+ -- -- in letter class, temp. store address & sig as title, author
+ , ("address", mempty <$ (skipopts *> tok >>= addTitle))
+ , ("signature", mempty <$ (skipopts *> authors))
+ , ("date", mempty <$ (skipopts *> tok >>= addDate))
+ -- sectioning
+ , ("chapter", updateState (\s -> s{ stateHasChapters = True }) *> section 0)
+ , ("section", section 1)
+ , ("subsection", section 2)
+ , ("subsubsection", section 3)
+ , ("paragraph", section 4)
+ , ("subparagraph", section 5)
+ -- beamer slides
+ , ("frametitle", section 3)
+ , ("framesubtitle", section 4)
+ -- letters
+ , ("opening", (para . trimInlines) <$> (skipopts *> tok))
+ , ("closing", skipopts *> closing)
+ --
+ , ("rule", skipopts *> tok *> tok *> pure horizontalRule)
+ , ("begin", mzero) -- these are here so they won't be interpreted as inline
+ , ("end", mzero)
+ , ("item", skipopts *> loose_item)
+ , ("documentclass", skipopts *> braced *> preamble)
+ ] ++ map ignoreBlocks
+ -- these commands will be ignored unless --parse-raw is specified,
+ -- in which case they will appear as raw latex blocks
+ [ "newcommand", "renewcommand", "newenvironment", "renewenvironment"
+ -- newcommand, etc. should be parsed by macro, but we need this
+ -- here so these aren't parsed as inline commands to ignore
+ , "special", "pdfannot", "pdfstringdef"
+ , "bibliography", "bibliographystyle"
+ , "maketitle", "makeindex", "makeglossary"
+ , "addcontentsline", "addtocontents", "addtocounter"
+ -- \ignore{} is used conventionally in literate haskell for definitions
+ -- that are to be processed by the compiler but not printed.
+ , "ignore"
+ , "hyperdef"
+ , "noindent"
+ , "markboth", "markright", "markleft"
+ , "hspace", "vspace"
+ ]
+
+addTitle :: Inlines -> LP ()
+addTitle tit = updateState (\s -> s{ stateTitle = toList tit })
+
+addSubtitle :: Inlines -> LP ()
+addSubtitle tit = updateState (\s -> s{ stateTitle = stateTitle s ++
+ toList (str ":" <> linebreak <> tit) })
+
+authors :: LP ()
+authors = try $ do
char '{'
- string name
+ let oneAuthor = mconcat <$>
+ many1 (notFollowedBy' (controlSeq "and") >> inline)
+ auths <- sepBy oneAuthor (controlSeq "and")
char '}'
- return name
+ updateState (\s -> s { stateAuthors = map (normalizeSpaces . toList) auths })
+
+addDate :: Inlines -> LP ()
+addDate dat = updateState (\s -> s{ stateDate = toList dat })
+
+section :: Int -> LP Blocks
+section lvl = do
+ hasChapters <- stateHasChapters `fmap` getState
+ let lvl' = if hasChapters then lvl + 1 else lvl
+ skipopts
+ contents <- grouped inline
+ return $ header lvl' contents
+
+inlineCommand :: LP Inlines
+inlineCommand = try $ do
+ name <- anyControlSeq
+ guard $ not $ isBlockCommand name
+ parseRaw <- stateParseRaw `fmap` getState
+ star <- option "" (string "*")
+ let name' = name ++ star
+ case M.lookup name' inlineCommands of
+ Just p -> p
+ Nothing -> case M.lookup name inlineCommands of
+ Just p -> p
+ Nothing
+ | parseRaw ->
+ (rawInline "latex" . (('\\':name') ++)) <$>
+ (withRaw (skipopts *> many braced)
+ >>= applyMacros' . snd)
+ | otherwise -> return mempty
+
+isBlockCommand :: String -> Bool
+isBlockCommand s = maybe False (const True) $ M.lookup s blockCommands
+
+inlineCommands :: M.Map String (LP Inlines)
+inlineCommands = M.fromList $
+ [ ("emph", emph <$> tok)
+ , ("textit", emph <$> tok)
+ , ("textsc", smallcaps <$> tok)
+ , ("sout", strikeout <$> tok)
+ , ("textsuperscript", superscript <$> tok)
+ , ("textsubscript", subscript <$> tok)
+ , ("textbackslash", lit "\\")
+ , ("backslash", lit "\\")
+ , ("textbf", strong <$> tok)
+ , ("ldots", lit "…")
+ , ("dots", lit "…")
+ , ("mdots", lit "…")
+ , ("sim", lit "~")
+ , ("label", inBrackets <$> tok)
+ , ("ref", inBrackets <$> tok)
+ , ("(", mathInline $ manyTill anyChar (try $ string "\\)"))
+ , ("[", mathDisplay $ manyTill anyChar (try $ string "\\]"))
+ , ("ensuremath", mathInline $ braced)
+ , ("P", lit "¶")
+ , ("S", lit "§")
+ , ("$", lit "$")
+ , ("%", lit "%")
+ , ("&", lit "&")
+ , ("#", lit "#")
+ , ("_", lit "_")
+ , ("{", lit "{")
+ , ("}", lit "}")
+ -- old TeX commands
+ , ("em", emph <$> inlines)
+ , ("it", emph <$> inlines)
+ , ("sl", emph <$> inlines)
+ , ("bf", strong <$> inlines)
+ , ("rm", inlines)
+ , ("itshape", emph <$> inlines)
+ , ("slshape", emph <$> inlines)
+ , ("scshape", smallcaps <$> inlines)
+ , ("bfseries", strong <$> inlines)
+ , ("/", pure mempty) -- italic correction
+ , ("cc", lit "ç")
+ , ("cC", lit "Ç")
+ , ("aa", lit "å")
+ , ("AA", lit "Å")
+ , ("ss", lit "ß")
+ , ("o", lit "ø")
+ , ("O", lit "Ø")
+ , ("L", lit "Ł")
+ , ("l", lit "ł")
+ , ("ae", lit "æ")
+ , ("AE", lit "Æ")
+ , ("pounds", lit "£")
+ , ("euro", lit "€")
+ , ("copyright", lit "©")
+ , ("`", option (str "`") $ try $ tok >>= accent grave)
+ , ("'", option (str "'") $ try $ tok >>= accent acute)
+ , ("^", option (str "^") $ try $ tok >>= accent hat)
+ , ("~", option (str "~") $ try $ tok >>= accent circ)
+ , ("\"", option (str "\"") $ try $ tok >>= accent umlaut)
+ , (".", option (str ".") $ try $ tok >>= accent dot)
+ , ("=", option (str "=") $ try $ tok >>= accent macron)
+ , ("i", lit "i")
+ , ("\\", linebreak <$ (optional (bracketed inline) *> optional sp))
+ , (",", pure mempty)
+ , ("@", pure mempty)
+ , (" ", lit "\160")
+ , ("ps", pure $ str "PS." <> space)
+ , ("TeX", lit "TeX")
+ , ("LaTeX", lit "LaTeX")
+ , ("bar", lit "|")
+ , ("textless", lit "<")
+ , ("textgreater", lit ">")
+ , ("thanks", (note . mconcat) <$> (char '{' *> manyTill block (char '}')))
+ , ("footnote", (note . mconcat) <$> (char '{' *> manyTill block (char '}')))
+ , ("verb", doverb)
+ , ("lstinline", doverb)
+ , ("texttt", (code . stringify . toList) <$> tok)
+ , ("url", (unescapeURL <$> braced) >>= \url ->
+ pure (link url "" (codeWith ("",["url"],[]) url)))
+ , ("href", (unescapeURL <$> braced <* optional sp) >>= \url ->
+ tok >>= \lab ->
+ pure (link url "" lab))
+ , ("includegraphics", skipopts *> (unescapeURL <$> braced) >>=
+ (\src -> pure (image src "" (str "image"))))
+ , ("cite", citation "cite" NormalCitation False)
+ , ("citep", citation "citep" NormalCitation False)
+ , ("citep*", citation "citep*" NormalCitation False)
+ , ("citeal", citation "citeal" NormalCitation False)
+ , ("citealp", citation "citealp" NormalCitation False)
+ , ("citealp*", citation "citealp*" NormalCitation False)
+ , ("autocite", citation "autocite" NormalCitation False)
+ , ("footcite", citation "footcite" NormalCitation False)
+ , ("parencite", citation "parencite" NormalCitation False)
+ , ("supercite", citation "supercite" NormalCitation False)
+ , ("footcitetext", citation "footcitetext" NormalCitation False)
+ , ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
+ , ("citeyear", citation "citeyear" SuppressAuthor False)
+ , ("autocite*", citation "autocite*" SuppressAuthor False)
+ , ("cite*", citation "cite*" SuppressAuthor False)
+ , ("parencite*", citation "parencite*" SuppressAuthor False)
+ , ("textcite", citation "textcite" AuthorInText False)
+ , ("citet", citation "citet" AuthorInText False)
+ , ("citet*", citation "citet*" AuthorInText False)
+ , ("citealt", citation "citealt" AuthorInText False)
+ , ("citealt*", citation "citealt*" AuthorInText False)
+ , ("textcites", citation "textcites" AuthorInText True)
+ , ("cites", citation "cites" NormalCitation True)
+ , ("autocites", citation "autocites" NormalCitation True)
+ , ("footcites", citation "footcites" NormalCitation True)
+ , ("parencites", citation "parencites" NormalCitation True)
+ , ("supercites", citation "supercites" NormalCitation True)
+ , ("footcitetexts", citation "footcitetexts" NormalCitation True)
+ , ("Autocite", citation "Autocite" NormalCitation False)
+ , ("Footcite", citation "Footcite" NormalCitation False)
+ , ("Parencite", citation "Parencite" NormalCitation False)
+ , ("Supercite", citation "Supercite" NormalCitation False)
+ , ("Footcitetext", citation "Footcitetext" NormalCitation False)
+ , ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
+ , ("Citeyear", citation "Citeyear" SuppressAuthor False)
+ , ("Autocite*", citation "Autocite*" SuppressAuthor False)
+ , ("Cite*", citation "Cite*" SuppressAuthor False)
+ , ("Parencite*", citation "Parencite*" SuppressAuthor False)
+ , ("Textcite", citation "Textcite" AuthorInText False)
+ , ("Textcites", citation "Textcites" AuthorInText True)
+ , ("Cites", citation "Cites" NormalCitation True)
+ , ("Autocites", citation "Autocites" NormalCitation True)
+ , ("Footcites", citation "Footcites" NormalCitation True)
+ , ("Parencites", citation "Parencites" NormalCitation True)
+ , ("Supercites", citation "Supercites" NormalCitation True)
+ , ("Footcitetexts", citation "Footcitetexts" NormalCitation True)
+ , ("citetext", complexNatbibCitation NormalCitation)
+ , ("citeauthor", (try (tok *> optional sp *> controlSeq "citetext") *>
+ complexNatbibCitation AuthorInText)
+ <|> citation "citeauthor" AuthorInText False)
+ ] ++ map ignoreInlines
+ -- these commands will be ignored unless --parse-raw is specified,
+ -- in which case they will appear as raw latex blocks:
+ [ "index", "nocite" ]
+
+unescapeURL :: String -> String
+unescapeURL ('\\':x:xs) | isEscapable x = x:unescapeURL xs
+ where isEscapable '%' = True
+ isEscapable '#' = True
+ isEscapable _ = False
+unescapeURL (x:xs) = x:unescapeURL xs
+unescapeURL [] = ""
+
+doverb :: LP Inlines
+doverb = do
+ marker <- anyChar
+ code <$> manyTill (satisfy (/='\n')) (char marker)
+
+doLHSverb :: LP Inlines
+doLHSverb = codeWith ("",["haskell"],[]) <$> manyTill (satisfy (/='\n')) (char '|')
+
+lit :: String -> LP Inlines
+lit = pure . str
+
+accent :: (Char -> Char) -> Inlines -> LP Inlines
+accent f ils =
+ case toList ils of
+ (Str (x:xs) : ys) -> return $ fromList $ (Str (f x : xs) : ys)
+ [] -> mzero
+ _ -> return ils
+
+grave :: Char -> Char
+grave 'A' = 'À'
+grave 'E' = 'È'
+grave 'I' = 'Ì'
+grave 'O' = 'Ò'
+grave 'U' = 'Ù'
+grave 'a' = 'à'
+grave 'e' = 'è'
+grave 'i' = 'ì'
+grave 'o' = 'ò'
+grave 'u' = 'ù'
+grave c = c
+
+acute :: Char -> Char
+acute 'A' = 'Á'
+acute 'E' = 'É'
+acute 'I' = 'Í'
+acute 'O' = 'Ó'
+acute 'U' = 'Ú'
+acute 'a' = 'á'
+acute 'e' = 'é'
+acute 'i' = 'í'
+acute 'o' = 'ó'
+acute 'u' = 'ú'
+acute c = c
+
+hat :: Char -> Char
+hat 'A' = 'Â'
+hat 'E' = 'Ê'
+hat 'I' = 'Î'
+hat 'O' = 'Ô'
+hat 'U' = 'Û'
+hat 'a' = 'ã'
+hat 'e' = 'ê'
+hat 'i' = 'î'
+hat 'o' = 'ô'
+hat 'u' = 'û'
+hat c = c
+
+circ :: Char -> Char
+circ 'A' = 'Ã'
+circ 'O' = 'Õ'
+circ 'o' = 'õ'
+circ 'N' = 'Ñ'
+circ 'n' = 'ñ'
+circ c = c
+
+umlaut :: Char -> Char
+umlaut 'A' = 'Ä'
+umlaut 'E' = 'Ë'
+umlaut 'I' = 'Ï'
+umlaut 'O' = 'Ö'
+umlaut 'U' = 'Ü'
+umlaut 'a' = 'ä'
+umlaut 'e' = 'ë'
+umlaut 'i' = 'ï'
+umlaut 'o' = 'ö'
+umlaut 'u' = 'ü'
+umlaut c = c
+
+dot :: Char -> Char
+dot 'C' = 'Ċ'
+dot 'c' = 'ċ'
+dot 'E' = 'Ė'
+dot 'e' = 'ė'
+dot 'G' = 'Ġ'
+dot 'g' = 'ġ'
+dot 'I' = 'İ'
+dot 'Z' = 'Ż'
+dot 'z' = 'ż'
+dot c = c
+
+macron :: Char -> Char
+macron 'A' = 'Ā'
+macron 'E' = 'Ē'
+macron 'I' = 'Ī'
+macron 'O' = 'Ō'
+macron 'U' = 'Ū'
+macron 'a' = 'ā'
+macron 'e' = 'ē'
+macron 'i' = 'ī'
+macron 'o' = 'ō'
+macron 'u' = 'ū'
+macron c = c
+
+tok :: LP Inlines
+tok = try $ grouped inline <|> inlineCommand <|> str <$> (count 1 $ inlineChar)
+
+opt :: LP Inlines
+opt = bracketed inline <* optional sp
+
+skipopts :: LP ()
+skipopts = skipMany opt
+
+inlineText :: LP Inlines
+inlineText = str <$> many1 inlineChar
+
+inlineChar :: LP Char
+inlineChar = satisfy $ \c ->
+ not (c == '\\' || c == '$' || c == '%' || c == '^' || c == '_' ||
+ c == '&' || c == '~' || c == '#' || c == '{' || c == '}' ||
+ c == '^' || c == '\'' || c == '`' || c == '-' || c == ']' ||
+ c == ' ' || c == '\t' || c == '\n' )
+
+environment :: LP Blocks
+environment = do
+ controlSeq "begin"
+ name <- braced
+ case M.lookup name environments of
+ Just p -> p <|> rawEnv name
+ Nothing -> rawEnv name
+
+rawEnv :: String -> LP Blocks
+rawEnv name = do
+ let addBegin x = "\\begin{" ++ name ++ "}" ++ x
+ parseRaw <- stateParseRaw `fmap` getState
+ if parseRaw
+ then (rawBlock "latex" . addBegin) <$>
+ (withRaw (env name blocks) >>= applyMacros' . snd)
+ else env name blocks
+
+-- | Replace "include" commands with file contents.
+handleIncludes :: String -> IO String
+handleIncludes [] = return []
+handleIncludes ('\\':xs) =
+ case runParser include defaultParserState "input" ('\\':xs) of
+ Right (fs, rest) -> do let getfile f = catch (UTF8.readFile f)
+ (\_ -> return "")
+ yss <- mapM getfile fs
+ (intercalate "\n" yss ++) `fmap`
+ handleIncludes rest
+ _ -> case runParser (verbCmd <|> verbatimEnv) defaultParserState
+ "input" ('\\':xs) of
+ Right (r, rest) -> (r ++) `fmap` handleIncludes rest
+ _ -> ('\\':) `fmap` handleIncludes xs
+handleIncludes (x:xs) = (x:) `fmap` handleIncludes xs
+
+include :: LP ([FilePath], String)
+include = do
+ name <- controlSeq "include" <|> controlSeq "usepackage"
+ skipopts
+ fs <- (splitBy (==',')) <$> braced
+ rest <- getInput
+ let fs' = if name == "include"
+ then map (flip replaceExtension ".tex") fs
+ else map (flip replaceExtension ".sty") fs
+ return (fs', rest)
+
+verbCmd :: LP (String, String)
+verbCmd = do
+ (_,r) <- withRaw $ do
+ controlSeq "verb"
+ c <- anyChar
+ manyTill anyChar (char c)
+ rest <- getInput
+ return (r, rest)
+
+verbatimEnv :: LP (String, String)
+verbatimEnv = do
+ (_,r) <- withRaw $ do
+ controlSeq "begin"
+ name <- braced
+ guard $ name == "verbatim" || name == "Verbatim" ||
+ name == "lstlisting"
+ verbEnv name
+ rest <- getInput
+ return (r,rest)
--- | Returns a list of block elements containing the contents of an
--- environment.
-environment :: [Char] -> GenParser Char ParserState [Block]
-environment name = try $ begin name >> spaces >> manyTill block (end name) >>~ spaces
+rawLaTeXBlock :: GenParser Char ParserState String
+rawLaTeXBlock = snd <$> withRaw (environment <|> blockCommand)
-anyEnvironment :: GenParser Char ParserState Block
-anyEnvironment = try $ do
- string "\\begin"
- spaces
- char '{'
- name <- many letter
- star <- option "" (string "*") -- some environments have starred variants
- char '}'
- optional commandArgs
+rawLaTeXInline :: GenParser Char ParserState Inline
+rawLaTeXInline = do
+ (res, raw) <- withRaw inlineCommand
+ if res == mempty
+ then return (Str "")
+ else RawInline "latex" <$> (applyMacros' raw)
+
+environments :: M.Map String (LP Blocks)
+environments = M.fromList
+ [ ("document", env "document" blocks <* skipMany anyChar)
+ , ("letter", env "letter" letter_contents)
+ , ("center", env "center" blocks)
+ , ("tabular", env "tabular" simpTable)
+ , ("quote", blockQuote <$> env "quote" blocks)
+ , ("quotation", blockQuote <$> env "quotation" blocks)
+ , ("verse", blockQuote <$> env "verse" blocks)
+ , ("itemize", bulletList <$> listenv "itemize" (many item))
+ , ("description", definitionList <$> listenv "description" (many descItem))
+ , ("enumerate", ordered_list)
+ , ("code", failUnlessLHS *>
+ (codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>
+ verbEnv "code"))
+ , ("verbatim", codeBlock <$> (verbEnv "verbatim"))
+ , ("Verbatim", codeBlock <$> (verbEnv "Verbatim"))
+ , ("lstlisting", codeBlock <$> (verbEnv "listlisting"))
+ , ("displaymath", mathEnv Nothing "displaymath")
+ , ("equation", mathEnv Nothing "equation")
+ , ("equation*", mathEnv Nothing "equation*")
+ , ("gather", mathEnv (Just "gathered") "gather")
+ , ("gather*", mathEnv (Just "gathered") "gather*")
+ , ("multiline", mathEnv (Just "gathered") "multiline")
+ , ("multiline*", mathEnv (Just "gathered") "multiline*")
+ , ("eqnarray", mathEnv (Just "aligned*") "eqnarray")
+ , ("eqnarray*", mathEnv (Just "aligned*") "eqnarray*")
+ , ("align", mathEnv (Just "aligned*") "align")
+ , ("align*", mathEnv (Just "aligned*") "align*")
+ , ("alignat", mathEnv (Just "aligned*") "alignat")
+ , ("alignat*", mathEnv (Just "aligned*") "alignat*")
+ ]
+
+letter_contents :: LP Blocks
+letter_contents = do
+ bs <- blocks
+ st <- getState
+ -- add signature (author) and address (title)
+ let addr = case stateTitle st of
+ [] -> mempty
+ x -> para $ trimInlines $ fromList x
+ updateState $ \s -> s{ stateAuthors = [], stateTitle = [] }
+ return $ addr <> bs -- sig added by \closing
+
+closing :: LP Blocks
+closing = do
+ contents <- tok
+ st <- getState
+ let sigs = case stateAuthors st of
+ [] -> mempty
+ xs -> para $ trimInlines $ fromList
+ $ intercalate [LineBreak] xs
+ return $ para (trimInlines contents) <> sigs
+
+item :: LP Blocks
+item = blocks *> controlSeq "item" *> skipopts *> blocks
+
+loose_item :: LP Blocks
+loose_item = do
+ ctx <- stateParserContext `fmap` getState
+ if ctx == ListItemState
+ then mzero
+ else return mempty
+
+descItem :: LP (Inlines, [Blocks])
+descItem = do
+ blocks -- skip blocks before item
+ controlSeq "item"
+ optional sp
+ ils <- opt
+ bs <- blocks
+ return (ils, [bs])
+
+env :: String -> LP a -> LP a
+env name p = p <* (controlSeq "end" *> braced >>= guard . (== name))
+
+listenv :: String -> LP a -> LP a
+listenv name p = try $ do
+ oldCtx <- stateParserContext `fmap` getState
+ updateState $ \st -> st{ stateParserContext = ListItemState }
+ res <- env name p
+ updateState $ \st -> st{ stateParserContext = oldCtx }
+ return res
+
+mathEnv :: Maybe String -> String -> LP Blocks
+mathEnv innerEnv name = para <$> mathDisplay (inner <$> verbEnv name)
+ where inner x = case innerEnv of
+ Nothing -> x
+ Just y -> "\\begin{" ++ y ++ "}\n" ++ x ++
+ "\\end{" ++ y ++ "}"
+
+verbEnv :: String -> LP String
+verbEnv name = do
+ skipopts
+ optional blankline
+ let endEnv = try $ controlSeq "end" *> braced >>= guard . (== name)
+ res <- manyTill anyChar endEnv
+ return $ stripTrailingNewlines res
+
+ordered_list :: LP Blocks
+ordered_list = do
+ optional sp
+ (_, style, delim) <- option (1, DefaultStyle, DefaultDelim) $
+ try $ char '[' *> anyOrderedListMarker <* char ']'
spaces
- contents <- manyTill block (end (name ++ star))
+ optional $ try $ controlSeq "setlength" *> grouped (controlSeq "itemindent") *> braced
spaces
- return $ BlockQuote contents
-
---
--- parsing documents
---
+ start <- option 1 $ try $ do controlSeq "setcounter"
+ grouped (string "enum" *> many1 (oneOf "iv"))
+ optional sp
+ num <- grouped (many1 digit)
+ spaces
+ return $ (read num + 1 :: Int)
+ bs <- listenv "enumerate" (many item)
+ return $ orderedListWith (start, style, delim) bs
+
+paragraph :: LP Blocks
+paragraph = do
+ x <- mconcat <$> many1 inline
+ if x == mempty
+ then return mempty
+ else return $ para $ trimInlines x
+
+preamble :: LP Blocks
+preamble = mempty <$> manyTill preambleBlock beginDoc
+ where beginDoc = lookAhead $ controlSeq "begin" *> string "{document}"
+ preambleBlock = (mempty <$ comment)
+ <|> (mempty <$ sp)
+ <|> (mempty <$ blanklines)
+ <|> (mempty <$ macro)
+ <|> blockCommand
+ <|> (mempty <$ anyControlSeq)
+ <|> (mempty <$ braced)
+ <|> (mempty <$ anyChar)
+
+-------
+
+-- citations
--- | Process LaTeX preamble, extracting metadata.
-processLaTeXPreamble :: GenParser Char ParserState ()
-processLaTeXPreamble = do
- try $ string "\\documentclass"
- skipMany $ bibliographic <|> macro <|> commentBlock <|> skipChar
+addPrefix :: [Inline] -> [Citation] -> [Citation]
+addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
+addPrefix _ _ = []
--- | Parse LaTeX and return 'Pandoc'.
-parseLaTeX :: GenParser Char ParserState Pandoc
-parseLaTeX = do
- spaces
- skipMany $ comment >> spaces
- blocks <- try (processLaTeXPreamble >> environment "document")
- <|> (many block >>~ (spaces >> eof))
- state <- getState
- let blocks' = filter (/= Null) blocks
- let title' = stateTitle state
- let authors' = stateAuthors state
- let date' = stateDate state
- return $ Pandoc (Meta title' authors' date') blocks'
-
---
--- parsing blocks
---
-
-parseBlocks :: GenParser Char ParserState [Block]
-parseBlocks = spaces >> many block
-
-block :: GenParser Char ParserState Block
-block = choice [ hrule
- , codeBlock
- , header
- , list
- , blockQuote
- , simpleTable
- , commentBlock
- , macro
- , bibliographic
- , para
- , itemBlock
- , unknownEnvironment
- , ignore
- , unknownCommand
- ] <?> "block"
-
---
--- header blocks
---
-
-header :: GenParser Char ParserState Block
-header = section <|> chapter
-
-chapter :: GenParser Char ParserState Block
-chapter = try $ do
- string "\\chapter"
- result <- headerWithLevel 1
- updateState $ \s -> s{ stateHasChapters = True }
- return result
-
-section :: GenParser Char ParserState Block
-section = try $ do
- char '\\'
- subs <- many (try (string "sub"))
- base <- try (string "section" >> return 1) <|> (string "paragraph" >> return 4)
- st <- getState
- let lev = if stateHasChapters st
- then length subs + base + 1
- else length subs + base
- headerWithLevel lev
+addSuffix :: [Inline] -> [Citation] -> [Citation]
+addSuffix s ks@(_:_) =
+ let k = last ks
+ s' = case s of
+ (Str (c:_):_)
+ | not (isPunctuation c || isSpace c) -> Str "," : Space : s
+ _ -> s
+ in init ks ++ [k {citationSuffix = citationSuffix k ++ s'}]
+addSuffix _ _ = []
-headerWithLevel :: Int -> GenParser Char ParserState Block
-headerWithLevel lev = try $ do
- spaces
- optional (char '*')
- spaces
- optional $ bracketedText '[' ']' -- alt title
- spaces
+simpleCiteArgs :: LP [Citation]
+simpleCiteArgs = try $ do
+ first <- optionMaybe $ toList <$> opt
+ second <- optionMaybe $ toList <$> opt
char '{'
- title' <- manyTill inline (char '}')
- spaces
- return $ Header lev (normalizeSpaces title')
-
---
--- hrule block
---
+ keys <- manyTill citationLabel (char '}')
+ let (pre, suf) = case (first , second ) of
+ (Just s , Nothing) -> (mempty, s )
+ (Just s , Just t ) -> (s , t )
+ _ -> (mempty, mempty)
+ conv k = Citation { citationId = k
+ , citationPrefix = []
+ , citationSuffix = []
+ , citationMode = NormalCitation
+ , citationHash = 0
+ , citationNoteNum = 0
+ }
+ return $ addPrefix pre $ addSuffix suf $ map conv keys
-hrule :: GenParser Char st Block
-hrule = oneOfStrings [ "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n\n",
- "\\newpage" ] >> spaces >> return HorizontalRule
+citationLabel :: LP String
+citationLabel = trim <$>
+ (many1 (satisfy $ \c -> c /=',' && c /='}') <* optional (char ',') <* optional sp)
--- tables
+cites :: CitationMode -> Bool -> LP [Citation]
+cites mode multi = try $ do
+ cits <- if multi
+ then many1 simpleCiteArgs
+ else count 1 simpleCiteArgs
+ let (c:cs) = concat cits
+ return $ case mode of
+ AuthorInText -> c {citationMode = mode} : cs
+ _ -> map (\a -> a {citationMode = mode}) (c:cs)
-simpleTable :: GenParser Char ParserState Block
-simpleTable = try $ do
- string "\\begin"
- spaces
- string "{tabular}"
- spaces
- aligns <- parseAligns
- let cols = length aligns
- optional hline
- header' <- option [] $ parseTableHeader cols
- rows <- many (parseTableRow cols >>~ optional hline)
- spaces
- end "tabular"
- spaces
- let header'' = if null header'
- then replicate cols []
- else header'
- return $ Table [] aligns (replicate cols 0) header'' rows
+citation :: String -> CitationMode -> Bool -> LP Inlines
+citation name mode multi = do
+ (c,raw) <- withRaw $ cites mode multi
+ return $ cite c (rawInline "latex" $ "\\" ++ name ++ raw)
+
+complexNatbibCitation :: CitationMode -> LP Inlines
+complexNatbibCitation mode = try $ do
+ let ils = (toList . trimInlines . mconcat) <$>
+ many (notFollowedBy (oneOf "\\};") >> inline)
+ let parseOne = try $ do
+ skipSpaces
+ pref <- ils
+ cit' <- inline -- expect a citation
+ let citlist = toList cit'
+ cits' <- case citlist of
+ [Cite cs _] -> return cs
+ _ -> mzero
+ suff <- ils
+ skipSpaces
+ optional $ char ';'
+ return $ addPrefix pref $ addSuffix suff $ cits'
+ (c:cits, raw) <- withRaw $ grouped parseOne
+ return $ cite (c{ citationMode = mode }:cits)
+ (rawInline "latex" $ "\\citetext" ++ raw)
-hline :: GenParser Char st ()
-hline = try $ spaces >> string "\\hline" >> return ()
+-- tables
-parseAligns :: GenParser Char ParserState [Alignment]
+parseAligns :: LP [Alignment]
parseAligns = try $ do
char '{'
optional $ char '|'
let cAlign = char 'c' >> return AlignCenter
let lAlign = char 'l' >> return AlignLeft
let rAlign = char 'r' >> return AlignRight
- let alignChar = cAlign <|> lAlign <|> rAlign
+ let alignChar = optional sp *> (cAlign <|> lAlign <|> rAlign)
aligns' <- sepEndBy alignChar (optional $ char '|')
+ spaces
char '}'
spaces
return aligns'
-parseTableHeader :: Int -- ^ number of columns
- -> GenParser Char ParserState [TableCell]
-parseTableHeader cols = try $ do
- cells' <- parseTableRow cols
- hline
- return cells'
+hline :: LP ()
+hline = () <$ (try $ spaces >> controlSeq "hline")
parseTableRow :: Int -- ^ number of columns
- -> GenParser Char ParserState [TableCell]
+ -> LP [Blocks]
parseTableRow cols = try $ do
- let tableCellInline = notFollowedBy (char '&' <|>
- (try $ char '\\' >> char '\\')) >> inline
- cells' <- sepBy (spaces >> liftM ((:[]) . Plain . normalizeSpaces)
- (many tableCellInline)) (char '&')
+ let amp = try $ spaces *> string "&"
+ let tableCellInline = notFollowedBy (amp <|> controlSeq "\\") >> inline
+ cells' <- sepBy ((plain . trimInlines . mconcat) <$> many tableCellInline) amp
guard $ length cells' == cols
spaces
- (try $ string "\\\\" >> spaces) <|>
- (lookAhead (end "tabular") >> return ())
- return cells'
-
---
--- code blocks
---
-
-codeBlock :: GenParser Char ParserState Block
-codeBlock = codeBlockWith "verbatim" <|> codeBlockWith "Verbatim" <|> codeBlockWith "lstlisting" <|> lhsCodeBlock
--- Note: Verbatim is from fancyvrb.
-
-codeBlockWith :: String -> GenParser Char st Block
-codeBlockWith env = try $ do
- string "\\begin"
- spaces -- don't use begin function because it
- string $ "{" ++ env ++ "}" -- gobbles whitespace; we want to gobble
- optional blanklines -- blank lines, but not leading space
- contents <- manyTill anyChar (try (string $ "\\end{" ++ env ++ "}"))
- spaces
- let classes = if env == "code" then ["haskell"] else []
- return $ CodeBlock ("",classes,[]) (stripTrailingNewlines contents)
-
-lhsCodeBlock :: GenParser Char ParserState Block
-lhsCodeBlock = do
- failUnlessLHS
- (CodeBlock (_,_,_) cont) <- codeBlockWith "code"
- return $ CodeBlock ("", ["sourceCode","literate","haskell"], []) cont
-
---
--- block quotes
---
-
-blockQuote :: GenParser Char ParserState Block
-blockQuote = (environment "quote" <|> environment "quotation") >>~ spaces >>=
- return . BlockQuote
-
---
--- list blocks
---
-
-list :: GenParser Char ParserState Block
-list = bulletList <|> orderedList <|> definitionList <?> "list"
-
-listItem :: GenParser Char ParserState ([Inline], [Block])
-listItem = try $ do
- ("item", _, args) <- command
- spaces
- state <- getState
- let oldParserContext = stateParserContext state
- updateState (\s -> s {stateParserContext = ListItemState})
- blocks <- many block
- updateState (\s -> s {stateParserContext = oldParserContext})
- opt <- case args of
- ([x]) | "[" `isPrefixOf` x && "]" `isSuffixOf` x ->
- parseFromString (many inline) $ tail $ init x
- _ -> return []
- return (opt, blocks)
-
-orderedList :: GenParser Char ParserState Block
-orderedList = try $ do
- string "\\begin"
- spaces
- string "{enumerate}"
- spaces
- (_, style, delim) <- option (1, DefaultStyle, DefaultDelim) $
- try $ do failIfStrict
- char '['
- res <- anyOrderedListMarker
- char ']'
- return res
- spaces
- option "" $ try $ do string "\\setlength{\\itemindent}"
- char '{'
- manyTill anyChar (char '}')
- spaces
- start <- option 1 $ try $ do failIfStrict
- string "\\setcounter{enum"
- many1 (oneOf "iv")
- string "}{"
- num <- many1 digit
- char '}'
- spaces
- return $ (read num) + 1
- items <- many listItem
- end "enumerate"
- spaces
- return $ OrderedList (start, style, delim) $ map snd items
-
-bulletList :: GenParser Char ParserState Block
-bulletList = try $ do
- begin "itemize"
- items <- many listItem
- end "itemize"
- spaces
- return (BulletList $ map snd items)
-
-definitionList :: GenParser Char ParserState Block
-definitionList = try $ do
- begin "description"
- items <- many listItem
- end "description"
- spaces
- return $ DefinitionList $ map (\(t,d) -> (t,[d])) items
-
---
--- paragraph block
---
-
-para :: GenParser Char ParserState Block
-para = do
- res <- many1 inline
- spaces
- return $ if null (filter (`notElem` [Str "", Space]) res)
- then Null
- else Para $ normalizeSpaces res
-
---
--- title authors date
---
-
-bibliographic :: GenParser Char ParserState Block
-bibliographic = choice [ maketitle, title, subtitle, authors, date ]
-
-maketitle :: GenParser Char st Block
-maketitle = try (string "\\maketitle") >> spaces >> return Null
-
-title :: GenParser Char ParserState Block
-title = try $ do
- string "\\title{"
- tit <- manyTill inline (char '}')
- spaces
- updateState (\state -> state { stateTitle = tit })
- return Null
-
-subtitle :: GenParser Char ParserState Block
-subtitle = try $ do
- string "\\subtitle{"
- tit <- manyTill inline (char '}')
- spaces
- updateState (\state -> state { stateTitle = stateTitle state ++
- Str ":" : LineBreak : tit })
- return Null
-
-authors :: GenParser Char ParserState Block
-authors = try $ do
- string "\\author{"
- let andsep = try $ string "\\and" >> notFollowedBy letter >>
- spaces >> return '&'
- raw <- sepBy (many $ notFollowedBy (char '}' <|> andsep) >> inline) andsep
- let authors' = map normalizeSpaces raw
- char '}'
+ optional $ controlSeq "\\"
spaces
- updateState (\s -> s { stateAuthors = authors' })
- return Null
-
-date :: GenParser Char ParserState Block
-date = try $ do
- string "\\date{"
- date' <- manyTill inline (char '}')
- spaces
- updateState (\state -> state { stateDate = normalizeSpaces date' })
- return Null
-
---
--- item block
--- for use in unknown environments that aren't being parsed as raw latex
---
-
--- this forces items to be parsed in different blocks
-itemBlock :: GenParser Char ParserState Block
-itemBlock = try $ do
- ("item", _, args) <- command
- state <- getState
- if stateParserContext state == ListItemState
- then fail "item should be handled by list block"
- else if null args
- then return Null
- else return $ Plain [Str (stripFirstAndLast (head args))]
-
---
--- raw LaTeX
---
-
--- | Parse any LaTeX environment and return a Para block containing
--- the whole literal environment as raw TeX.
-rawLaTeXEnvironment :: GenParser Char st Block
-rawLaTeXEnvironment = do
- contents <- rawLaTeXEnvironment'
- spaces
- return $ RawBlock "latex" contents
+ return cells'
--- | Parse any LaTeX environment and return a string containing
--- the whole literal environment as raw TeX.
-rawLaTeXEnvironment' :: GenParser Char st String
-rawLaTeXEnvironment' = try $ do
- string "\\begin"
- spaces
- char '{'
- name <- many1 letter
- star <- option "" (string "*") -- for starred variants
- let name' = name ++ star
- char '}'
- args <- option [] commandArgs
- let argStr = concat args
- contents <- manyTill (choice [ (many1 (noneOf "\\")),
- rawLaTeXEnvironment',
- string "\\" ])
- (end name')
- return $ "\\begin{" ++ name' ++ "}" ++ argStr ++
- concat contents ++ "\\end{" ++ name' ++ "}"
-
-unknownEnvironment :: GenParser Char ParserState Block
-unknownEnvironment = try $ do
- state <- getState
- result <- if stateParseRaw state -- check whether we should include raw TeX
- then rawLaTeXEnvironment -- if so, get whole raw environment
- else anyEnvironment -- otherwise just the contents
- return result
-
--- \ignore{} is used conventionally in literate haskell for definitions
--- that are to be processed by the compiler but not printed.
-ignore :: GenParser Char ParserState Block
-ignore = try $ do
- ("ignore", _, _) <- command
- spaces
- return Null
-
-demacro :: (String, String, [String]) -> GenParser Char ParserState Inline
-demacro (n,st,args) = try $ do
- let raw = "\\" ++ n ++ st ++ concat args
- s' <- applyMacros' raw
- if raw == s'
- then return $ RawInline "latex" raw
- else do
- inp <- getInput
- setInput $ s' ++ inp
- return $ Str ""
-
-unknownCommand :: GenParser Char ParserState Block
-unknownCommand = try $ do
- spaces
- notFollowedBy' $ oneOfStrings ["\\begin","\\end","\\item"]
- state <- getState
- when (stateParserContext state == ListItemState) $
- notFollowedBy' (string "\\item")
- if stateParseRaw state
- then command >>= demacro >>= return . Plain . (:[])
- else do
- (name, _, args) <- command
- spaces
- unless (name `elem` commandsToIgnore) $ do
- -- put arguments back in input to be parsed
- inp <- getInput
- setInput $ intercalate " " args ++ inp
- return Null
-
-commandsToIgnore :: [String]
-commandsToIgnore = ["special","pdfannot","pdfstringdef", "index","bibliography"]
-
-skipChar :: GenParser Char ParserState Block
-skipChar = do
- satisfy (/='\\') <|>
- (notFollowedBy' (try $
- string "\\begin" >> spaces >> string "{document}") >>
- anyChar)
+simpTable :: LP Blocks
+simpTable = try $ do
spaces
- return Null
-
-commentBlock :: GenParser Char st Block
-commentBlock = many1 (comment >> spaces) >> return Null
-
---
--- inline
---
-
-inline :: GenParser Char ParserState Inline
-inline = choice [ str
- , endline
- , whitespace
- , quoted
- , apostrophe
- , strong
- , math
- , ellipses
- , emDash
- , enDash
- , hyphen
- , emph
- , strikeout
- , superscript
- , subscript
- , code
- , url
- , link
- , image
- , footnote
- , linebreak
- , accentedChar
- , nonbreakingSpace
- , cite
- , specialChar
- , ensureMath
- , rawLaTeXInline'
- , escapedChar
- , unescapedChar
- , comment
- ] <?> "inline"
-
-
--- latex comment
-comment :: GenParser Char st Inline
-comment = try $ char '%' >> manyTill anyChar newline >> spaces >> return (Str "")
-
-accentedChar :: GenParser Char st Inline
-accentedChar = normalAccentedChar <|> specialAccentedChar
-
-normalAccentedChar :: GenParser Char st Inline
-normalAccentedChar = try $ do
- char '\\'
- accent <- oneOf "'`^\"~"
- character <- (try $ char '{' >> letter >>~ char '}') <|> letter
- let table = fromMaybe [] $ lookup character accentTable
- let result = case lookup accent table of
- Just num -> chr num
- Nothing -> '?'
- return $ Str [result]
-
--- an association list of letters and association list of accents
--- and decimal character numbers.
-accentTable :: [(Char, [(Char, Int)])]
-accentTable =
- [ ('A', [('`', 192), ('\'', 193), ('^', 194), ('~', 195), ('"', 196)]),
- ('E', [('`', 200), ('\'', 201), ('^', 202), ('"', 203)]),
- ('I', [('`', 204), ('\'', 205), ('^', 206), ('"', 207)]),
- ('N', [('~', 209)]),
- ('O', [('`', 210), ('\'', 211), ('^', 212), ('~', 213), ('"', 214)]),
- ('U', [('`', 217), ('\'', 218), ('^', 219), ('"', 220)]),
- ('a', [('`', 224), ('\'', 225), ('^', 227), ('"', 228)]),
- ('e', [('`', 232), ('\'', 233), ('^', 234), ('"', 235)]),
- ('i', [('`', 236), ('\'', 237), ('^', 238), ('"', 239)]),
- ('n', [('~', 241)]),
- ('o', [('`', 242), ('\'', 243), ('^', 244), ('~', 245), ('"', 246)]),
- ('u', [('`', 249), ('\'', 250), ('^', 251), ('"', 252)]) ]
-
-specialAccentedChar :: GenParser Char st Inline
-specialAccentedChar = choice [ ccedil, aring, iuml, szlig, aelig, lslash,
- oslash, pound, euro, copyright, sect ]
-
-ccedil :: GenParser Char st Inline
-ccedil = try $ do
- char '\\'
- letter' <- oneOfStrings ["cc", "cC"]
- let num = if letter' == "cc" then 231 else 199
- return $ Str [chr num]
-
-aring :: GenParser Char st Inline
-aring = try $ do
- char '\\'
- letter' <- oneOfStrings ["aa", "AA"]
- let num = if letter' == "aa" then 229 else 197
- return $ Str [chr num]
-
-iuml :: GenParser Char st Inline
-iuml = try (string "\\\"") >> oneOfStrings ["\\i", "{\\i}"] >>
- return (Str [chr 239])
-
-szlig :: GenParser Char st Inline
-szlig = try (string "\\ss") >> return (Str [chr 223])
-
-oslash :: GenParser Char st Inline
-oslash = try $ do
- char '\\'
- letter' <- choice [char 'o', char 'O']
- let num = if letter' == 'o' then 248 else 216
- return $ Str [chr num]
-
-lslash :: GenParser Char st Inline
-lslash = try $ do
- cmd <- oneOfStrings ["{\\L}","{\\l}","\\L ","\\l "]
- return $ if 'l' `elem` cmd
- then Str "\x142"
- else Str "\x141"
-
-aelig :: GenParser Char st Inline
-aelig = try $ do
- char '\\'
- letter' <- oneOfStrings ["ae", "AE"]
- let num = if letter' == "ae" then 230 else 198
- return $ Str [chr num]
-
-pound :: GenParser Char st Inline
-pound = try (string "\\pounds") >> return (Str [chr 163])
-
-euro :: GenParser Char st Inline
-euro = try (string "\\euro") >> return (Str [chr 8364])
-
-copyright :: GenParser Char st Inline
-copyright = try (string "\\copyright") >> return (Str [chr 169])
-
-sect :: GenParser Char st Inline
-sect = try (string "\\S") >> return (Str [chr 167])
-
-escapedChar :: GenParser Char st Inline
-escapedChar = do
- result <- escaped (oneOf specialChars)
- return $ if result == Str "\n" then Str " " else result
-
--- nonescaped special characters
-unescapedChar :: GenParser Char st Inline
-unescapedChar = oneOf "`$^&_#{}[]|<>" >>= return . (\c -> Str [c])
-
-specialChar :: GenParser Char st Inline
-specialChar = choice [ spacer, interwordSpace,
- backslash, tilde, caret,
- bar, lt, gt, doubleQuote ]
-
-spacer :: GenParser Char st Inline
-spacer = try (string "\\,") >> return (Str "")
-
-interwordSpace :: GenParser Char st Inline
-interwordSpace = try (string "\\ ") >> return (Str "\160")
-
-backslash :: GenParser Char st Inline
-backslash = try (string "\\textbackslash") >> optional (try $ string "{}") >> return (Str "\\")
-
-tilde :: GenParser Char st Inline
-tilde = try (string "\\ensuremath{\\sim}") >> return (Str "~")
-
-caret :: GenParser Char st Inline
-caret = try (string "\\^{}") >> return (Str "^")
-
-bar :: GenParser Char st Inline
-bar = try (string "\\textbar") >> optional (try $ string "{}") >> return (Str "\\")
-
-lt :: GenParser Char st Inline
-lt = try (string "\\textless") >> optional (try $ string "{}") >> return (Str "<")
-
-gt :: GenParser Char st Inline
-gt = try (string "\\textgreater") >> optional (try $ string "{}") >> return (Str ">")
-
-doubleQuote :: GenParser Char st Inline
-doubleQuote = char '"' >> return (Str "\"")
-
-code :: GenParser Char ParserState Inline
-code = code1 <|> code2 <|> code3 <|> lhsInlineCode
-
-code1 :: GenParser Char st Inline
-code1 = try $ do
- string "\\verb"
- marker <- anyChar
- result <- manyTill anyChar (char marker)
- return $ Code nullAttr $ removeLeadingTrailingSpace result
-
-code2 :: GenParser Char st Inline
-code2 = try $ do
- string "\\texttt{"
- result <- manyTill (noneOf "\\\n~$%^&{}") (char '}')
- return $ Code nullAttr result
-
-code3 :: GenParser Char st Inline
-code3 = try $ do
- string "\\lstinline"
- marker <- anyChar
- result <- manyTill anyChar (char marker)
- return $ Code nullAttr $ removeLeadingTrailingSpace result
-
-lhsInlineCode :: GenParser Char ParserState Inline
-lhsInlineCode = try $ do
- failUnlessLHS
- char '|'
- result <- manyTill (noneOf "|\n") (char '|')
- return $ Code ("",["haskell"],[]) result
-
-emph :: GenParser Char ParserState Inline
-emph = try $ oneOfStrings [ "\\emph{", "\\textit{" ] >>
- manyTill inline (char '}') >>= return . Emph
-
-strikeout :: GenParser Char ParserState Inline
-strikeout = try $ string "\\sout{" >> manyTill inline (char '}') >>=
- return . Strikeout
-
-superscript :: GenParser Char ParserState Inline
-superscript = try $ string "\\textsuperscript{" >>
- manyTill inline (char '}') >>= return . Superscript
-
--- note: \textsubscript isn't a standard latex command, but we use
--- a defined version in pandoc.
-subscript :: GenParser Char ParserState Inline
-subscript = try $ string "\\textsubscript{" >> manyTill inline (char '}') >>=
- return . Subscript
-
-apostrophe :: GenParser Char ParserState Inline
-apostrophe = char '\'' >> return Apostrophe
-
-quoted :: GenParser Char ParserState Inline
-quoted = doubleQuoted <|> singleQuoted
-
-singleQuoted :: GenParser Char ParserState Inline
-singleQuoted = enclosed singleQuoteStart singleQuoteEnd inline >>=
- return . Quoted SingleQuote . normalizeSpaces
-
-doubleQuoted :: GenParser Char ParserState Inline
-doubleQuoted = enclosed doubleQuoteStart doubleQuoteEnd inline >>=
- return . Quoted DoubleQuote . normalizeSpaces
-
-singleQuoteStart :: GenParser Char st Char
-singleQuoteStart = char '`'
-
-singleQuoteEnd :: GenParser Char st ()
-singleQuoteEnd = try $ char '\'' >> notFollowedBy alphaNum
-
-doubleQuoteStart :: CharParser st String
-doubleQuoteStart = string "``"
-
-doubleQuoteEnd :: CharParser st String
-doubleQuoteEnd = try $ string "''"
-
-ellipses :: GenParser Char st Inline
-ellipses = try $ do
- char '\\'
- optional $ char 'l'
- string "dots"
- optional $ try $ string "{}"
- return Ellipses
-
-enDash :: GenParser Char st Inline
-enDash = try (string "--") >> return EnDash
-
-emDash :: GenParser Char st Inline
-emDash = try (string "---") >> return EmDash
-
-hyphen :: GenParser Char st Inline
-hyphen = char '-' >> return (Str "-")
-
-strong :: GenParser Char ParserState Inline
-strong = try (string "\\textbf{") >> manyTill inline (char '}') >>=
- return . Strong
-
-whitespace :: GenParser Char st Inline
-whitespace = many1 (oneOf " \t") >> return Space
-
-nonbreakingSpace :: GenParser Char st Inline
-nonbreakingSpace = char '~' >> return (Str "\160")
-
--- hard line break
-linebreak :: GenParser Char st Inline
-linebreak = try $ do
- string "\\\\"
- optional $ bracketedText '[' ']' -- e.g. \\[10pt]
+ aligns <- parseAligns
+ let cols = length aligns
+ optional hline
+ header' <- option [] $ try (parseTableRow cols <* hline)
+ rows <- many (parseTableRow cols <* optional hline)
spaces
- return LineBreak
-
-str :: GenParser Char st Inline
-str = many1 (noneOf specialChars) >>= return . Str
-
--- endline internal to paragraph
-endline :: GenParser Char st Inline
-endline = try $ newline >> notFollowedBy blankline >> return Space
-
--- math
-math :: GenParser Char ParserState Inline
-math = (math3 >>= applyMacros' >>= return . Math DisplayMath)
- <|> (math1 >>= applyMacros' >>= return . Math InlineMath)
- <|> (math2 >>= applyMacros' >>= return . Math InlineMath)
- <|> (math4 >>= applyMacros' >>= return . Math DisplayMath)
- <|> (math5 >>= applyMacros' >>= return . Math DisplayMath)
- <|> (math6 >>= applyMacros' >>= return . Math DisplayMath)
- <?> "math"
-
-math1 :: GenParser Char st String
-math1 = try $ char '$' >> manyTill anyChar (char '$')
-
-math2 :: GenParser Char st String
-math2 = try $ string "\\(" >> manyTill anyChar (try $ string "\\)")
-
-math3 :: GenParser Char st String
-math3 = try $ char '$' >> math1 >>~ char '$'
-
-math4 :: GenParser Char st String
-math4 = try $ do
- name <- begin "displaymath" <|> begin "equation" <|> begin "equation*" <|>
- begin "gather" <|> begin "gather*" <|> begin "gathered" <|>
- begin "multline" <|> begin "multline*"
- manyTill anyChar (end name)
-
-math5 :: GenParser Char st String
-math5 = try $ (string "\\[") >> spaces >> manyTill anyChar (try $ string "\\]")
-
-math6 :: GenParser Char st String
-math6 = try $ do
- name <- begin "eqnarray" <|> begin "eqnarray*" <|> begin "align" <|>
- begin "align*" <|> begin "alignat" <|> begin "alignat*" <|>
- begin "split" <|> begin "aligned" <|> begin "alignedat"
- res <- manyTill anyChar (end name)
- return $ filter (/= '&') res -- remove alignment codes
-
-ensureMath :: GenParser Char st Inline
-ensureMath = try $ do
- (n, _, args) <- command
- guard $ n == "ensuremath" && not (null args)
- return $ Math InlineMath $ tail $ init $ head args
-
---
--- links and images
---
-
-url :: GenParser Char ParserState Inline
-url = try $ do
- string "\\url"
- url' <- charsInBalanced '{' '}'
- return $ Link [Code ("",["url"],[]) url'] (escapeURI url', "")
-
-link :: GenParser Char ParserState Inline
-link = try $ do
- string "\\href{"
- url' <- manyTill anyChar (char '}')
- char '{'
- label' <- manyTill inline (char '}')
- return $ Link (normalizeSpaces label') (escapeURI url', "")
-
-image :: GenParser Char ParserState Inline
-image = try $ do
- ("includegraphics", _, args) <- command
- let args' = filter isArg args -- filter out options
- let (src,tit) = case args' of
- [] -> ("", "")
- (x:_) -> (stripFirstAndLast x, "")
- return $ Image [Str "image"] (escapeURI src, tit)
-
-footnote :: GenParser Char ParserState Inline
-footnote = try $ do
- (name, _, (contents:[])) <- command
- if ((name == "footnote") || (name == "thanks"))
- then string ""
- else fail "not a footnote or thanks command"
- let contents' = stripFirstAndLast contents
- -- parse the extracted block, which may contain various block elements:
- rest <- getInput
- setInput $ contents'
- blocks <- parseBlocks
- setInput rest
- return $ Note blocks
-
--- | citations
-cite :: GenParser Char ParserState Inline
-cite = simpleCite <|> complexNatbibCites
-
-simpleCiteArgs :: GenParser Char ParserState [Citation]
-simpleCiteArgs = try $ do
- first <- optionMaybe $ (char '[') >> manyTill inline (char ']')
- second <- optionMaybe $ (char '[') >> manyTill inline (char ']')
- char '{'
- keys <- many1Till citationLabel (char '}')
- let (pre, suf) = case (first , second ) of
- (Just s , Nothing) -> ([], s )
- (Just s , Just t ) -> (s , t )
- _ -> ([], [])
- conv k = Citation { citationId = k
- , citationPrefix = []
- , citationSuffix = []
- , citationMode = NormalCitation
- , citationHash = 0
- , citationNoteNum = 0
- }
- return $ addPrefix pre $ addSuffix suf $ map conv keys
-
-
-simpleCite :: GenParser Char ParserState Inline
-simpleCite = try $ do
- char '\\'
- let biblatex = [a ++ "cite" | a <- ["auto", "foot", "paren", "super", ""]]
- ++ ["footcitetext"]
- normal = ["cite" ++ a ++ b | a <- ["al", ""], b <- ["p", "p*", ""]]
- ++ biblatex
- supress = ["citeyearpar", "citeyear", "autocite*", "cite*", "parencite*"]
- intext = ["textcite"] ++ ["cite" ++ a ++ b | a <- ["al", ""], b <- ["t", "t*"]]
- mintext = ["textcites"]
- mnormal = map (++ "s") biblatex
- cmdend = notFollowedBy (letter <|> char '*')
- capit [] = []
- capit (x:xs) = toUpper x : xs
- addUpper xs = xs ++ map capit xs
- toparser l t = try $ oneOfStrings (addUpper l) >> cmdend >> return t
- (mode, multi) <- toparser normal (NormalCitation, False)
- <|> toparser supress (SuppressAuthor, False)
- <|> toparser intext (AuthorInText , False)
- <|> toparser mnormal (NormalCitation, True )
- <|> toparser mintext (AuthorInText , True )
- cits <- if multi then
- many1 simpleCiteArgs
- else
- simpleCiteArgs >>= \c -> return [c]
- let (c:cs) = concat cits
- cits' = case mode of
- AuthorInText -> c {citationMode = mode} : cs
- _ -> map (\a -> a {citationMode = mode}) (c:cs)
- return $ Cite cits' []
-
-complexNatbibCites :: GenParser Char ParserState Inline
-complexNatbibCites = complexNatbibTextual <|> complexNatbibParenthetical
-
-complexNatbibTextual :: GenParser Char ParserState Inline
-complexNatbibTextual = try $ do
- string "\\citeauthor{"
- manyTill (noneOf "}") (char '}')
- skipSpaces
- Cite (c:cs) _ <- complexNatbibParenthetical
- return $ Cite (c {citationMode = AuthorInText} : cs) []
-
-
-complexNatbibParenthetical :: GenParser Char ParserState Inline
-complexNatbibParenthetical = try $ do
- string "\\citetext{"
- cits <- many1Till parseOne (char '}')
- return $ Cite (concat cits) []
- where
- parseOne = do
- skipSpaces
- pref <- many (notFollowedBy (oneOf "\\}") >> inline)
- (Cite cites _) <- simpleCite
- suff <- many (notFollowedBy (oneOf "\\};") >> inline)
- skipSpaces
- optional $ char ';'
- return $ addPrefix pref $ addSuffix suff $ cites
-
-addPrefix :: [Inline] -> [Citation] -> [Citation]
-addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
-addPrefix _ _ = []
-
-addSuffix :: [Inline] -> [Citation] -> [Citation]
-addSuffix s ks@(_:_) = let k = last ks
- in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
-addSuffix _ _ = []
-
-citationLabel :: GenParser Char ParserState String
-citationLabel = do
- res <- many1 $ noneOf ",}"
- optional $ char ','
- return $ removeLeadingTrailingSpace res
-
--- | Parse any LaTeX inline command and return it in a raw TeX inline element.
-rawLaTeXInline' :: GenParser Char ParserState Inline
-rawLaTeXInline' = do
- notFollowedBy' $ oneOfStrings ["\\begin", "\\end", "\\item", "\\ignore",
- "\\section"]
- rawLaTeXInline
+ let header'' = if null header'
+ then replicate cols mempty
+ else header'
+ lookAhead $ controlSeq "end" -- make sure we're at end
+ return $ table mempty (zip aligns (repeat 0)) header'' rows
--- | Parse any LaTeX command and return it in a raw TeX inline element.
-rawLaTeXInline :: GenParser Char ParserState Inline
-rawLaTeXInline = try $ do
- state <- getState
- if stateParseRaw state
- then command >>= demacro
- else do
- (name,st,args) <- command
- x <- demacro (name,st,args)
- unless (x == Str "" || name `elem` commandsToIgnore) $ do
- inp <- getInput
- setInput $ intercalate " " args ++ inp
- return $ Str ""
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
index 53531dc1a..666265935 100644
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -39,12 +39,12 @@ import Text.Pandoc.Definition
import Text.Pandoc.Generic
import Text.Pandoc.Shared
import Text.Pandoc.Parsing
-import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment' )
+import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockTag,
isTextTag, isCommentTag )
-import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
+import Text.Pandoc.XML ( fromEntities )
import Text.ParserCombinators.Parsec
-import Control.Monad (when, liftM, guard)
+import Control.Monad (when, liftM, guard, mzero)
import Text.HTML.TagSoup
import Text.HTML.TagSoup.Match (tagOpen)
@@ -108,6 +108,11 @@ atMostSpaces :: Int -> GenParser Char ParserState ()
atMostSpaces 0 = notFollowedBy (char ' ')
atMostSpaces n = (char ' ' >> atMostSpaces (n-1)) <|> return ()
+litChar :: GenParser Char ParserState Char
+litChar = escapedChar'
+ <|> noneOf "\n"
+ <|> (newline >> notFollowedBy blankline >> return ' ')
+
-- | Fail unless we're at beginning of a line.
failUnlessBeginningOfLine :: GenParser tok st ()
failUnlessBeginningOfLine = do
@@ -212,16 +217,15 @@ referenceKey = try $ do
lab <- reference
char ':'
skipSpaces >> optional newline >> skipSpaces >> notFollowedBy (char '[')
- let nl = char '\n' >> notFollowedBy blankline >> return ' '
let sourceURL = liftM unwords $ many $ try $ do
notFollowedBy' referenceTitle
skipMany spaceChar
- optional nl
+ optional $ newline >> notFollowedBy blankline
skipMany spaceChar
notFollowedBy' reference
- many1 (satisfy $ not . isBlank)
+ many1 $ escapedChar' <|> satisfy (not . isBlank)
let betweenAngles = try $ char '<' >>
- manyTill (noneOf ">\n" <|> nl) (char '>')
+ manyTill (escapedChar' <|> litChar) (char '>')
src <- try betweenAngles <|> sourceURL
tit <- option "" referenceTitle
blanklines
@@ -233,14 +237,14 @@ referenceKey = try $ do
-- return blanks so line count isn't affected
return $ replicate (sourceLine endPos - sourceLine startPos) '\n'
-referenceTitle :: GenParser Char st String
-referenceTitle = try $ do
+referenceTitle :: GenParser Char ParserState String
+referenceTitle = try $ do
skipSpaces >> optional newline >> skipSpaces
- tit <- (charsInBalanced '(' ')' >>= return . unwords . words)
+ tit <- (charsInBalanced '(' ')' litChar >>= return . unwords . words)
<|> do delim <- char '\'' <|> char '"'
- manyTill anyChar (try (char delim >> skipSpaces >>
+ manyTill litChar (try (char delim >> skipSpaces >>
notFollowedBy (noneOf ")\n")))
- return $ decodeCharacterReferences tit
+ return $ fromEntities tit
noteMarker :: GenParser Char ParserState [Char]
noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')
@@ -367,32 +371,37 @@ hrule = try $ do
indentedLine :: GenParser Char ParserState [Char]
indentedLine = indentSpaces >> manyTill anyChar newline >>= return . (++ "\n")
-codeBlockDelimiter :: Maybe Int
- -> GenParser Char st (Int, ([Char], [[Char]], [([Char], [Char])]))
-codeBlockDelimiter len = try $ do
+blockDelimiter :: (Char -> Bool)
+ -> Maybe Int
+ -> GenParser Char st (Int, (String, [String], [(String, String)]), Char)
+blockDelimiter f len = try $ do
+ c <- lookAhead (satisfy f)
size <- case len of
- Just l -> count l (char '~') >> many (char '~') >> return l
- Nothing -> count 3 (char '~') >> many (char '~') >>=
- return . (+ 3) . length
+ Just l -> count l (char c) >> many (char c) >> return l
+ Nothing -> count 3 (char c) >> many (char c) >>=
+ return . (+ 3) . length
many spaceChar
- attr <- option ([],[],[]) attributes
+ attr <- option ([],[],[])
+ $ attributes -- ~~~ {.ruby}
+ <|> (many1 alphaNum >>= \x -> return ([],[x],[])) -- github variant ```ruby
blankline
- return (size, attr)
+ return (size, attr, c)
attributes :: GenParser Char st ([Char], [[Char]], [([Char], [Char])])
attributes = try $ do
char '{'
- many spaceChar
- attrs <- many (attribute >>~ many spaceChar)
+ spnl
+ attrs <- many (attribute >>~ spnl)
char '}'
let (ids, classes, keyvals) = unzip3 attrs
- let id' = if null ids then "" else head ids
- return (id', concat classes, concat keyvals)
+ let firstNonNull [] = ""
+ firstNonNull (x:xs) | not (null x) = x
+ | otherwise = firstNonNull xs
+ return (firstNonNull $ reverse ids, concat classes, concat keyvals)
attribute :: GenParser Char st ([Char], [[Char]], [([Char], [Char])])
attribute = identifierAttr <|> classAttr <|> keyValAttr
-
identifier :: GenParser Char st [Char]
identifier = do
first <- letter
@@ -415,14 +424,15 @@ keyValAttr :: GenParser Char st ([Char], [a], [([Char], [Char])])
keyValAttr = try $ do
key <- identifier
char '='
- char '"'
- val <- manyTill (satisfy (/='\n')) (char '"')
+ val <- enclosed (char '"') (char '"') anyChar
+ <|> enclosed (char '\'') (char '\'') anyChar
+ <|> many nonspaceChar
return ("",[],[(key,val)])
codeBlockDelimited :: GenParser Char st Block
codeBlockDelimited = try $ do
- (size, attr) <- codeBlockDelimiter Nothing
- contents <- manyTill anyLine (codeBlockDelimiter (Just size))
+ (size, attr, c) <- blockDelimiter (\c -> c == '~' || c == '`') Nothing
+ contents <- manyTill anyLine (blockDelimiter (== c) (Just size))
blanklines
return $ CodeBlock attr $ intercalate "\n" contents
@@ -552,9 +562,9 @@ listLine = try $ do
return $ concat chunks ++ "\n"
-- parse raw text for one list item, excluding start marker and continuations
-rawListItem :: GenParser Char ParserState [Char]
-rawListItem = try $ do
- listStart
+rawListItem :: GenParser Char ParserState a -> GenParser Char ParserState [Char]
+rawListItem start = try $ do
+ start
result <- many1 listLine
blanks <- many blankline
return $ concat result ++ blanks
@@ -577,9 +587,9 @@ listContinuationLine = try $ do
result <- manyTill anyChar newline
return $ result ++ "\n"
-listItem :: GenParser Char ParserState [Block]
-listItem = try $ do
- first <- rawListItem
+listItem :: GenParser Char ParserState a -> GenParser Char ParserState [Block]
+listItem start = try $ do
+ first <- rawListItem start
continuations <- many listContinuation
-- parsing with ListItemState forces markers at beginning of lines to
-- count as list item markers, even if not separated by blank space.
@@ -596,13 +606,15 @@ listItem = try $ do
orderedList :: GenParser Char ParserState Block
orderedList = try $ do
(start, style, delim) <- lookAhead anyOrderedListStart
- items <- many1 listItem
+ items <- many1 $ listItem $ try $
+ do optional newline -- if preceded by a Plain block in a list context
+ skipNonindentSpaces
+ orderedListMarker style delim
return $ OrderedList (start, style, delim) $ compactify items
bulletList :: GenParser Char ParserState Block
-bulletList = try $ do
- lookAhead bulletListStart
- many1 listItem >>= return . BulletList . compactify
+bulletList =
+ many1 (listItem bulletListStart) >>= return . BulletList . compactify
-- definition lists
@@ -718,8 +730,8 @@ rawVerbatimBlock = try $ do
rawTeXBlock :: GenParser Char ParserState Block
rawTeXBlock = do
failIfStrict
- result <- liftM (RawBlock "latex") rawLaTeXEnvironment'
- <|> liftM (RawBlock "context") rawConTeXtEnvironment'
+ result <- liftM (RawBlock "latex") rawLaTeXBlock
+ <|> liftM (RawBlock "context") rawConTeXtEnvironment
spaces
return result
@@ -767,7 +779,7 @@ simpleTableHeader headless = try $ do
let (lengths, lines') = unzip dashes
let indices = scanl (+) (length initSp) lines'
-- If no header, calculate alignment on basis of first row of text
- rawHeads <- liftM (tail . splitByIndices (init indices)) $
+ rawHeads <- liftM (tail . splitStringByIndices (init indices)) $
if headless
then lookAhead anyLine
else return rawContent
@@ -794,7 +806,7 @@ rawTableLine indices = do
notFollowedBy' (blanklines <|> tableFooter)
line <- many1Till anyChar newline
return $ map removeLeadingTrailingSpace $ tail $
- splitByIndices (init indices) line
+ splitStringByIndices (init indices) line
-- Parse a table line and return a list of lists of blocks (columns).
tableLine :: [Int]
@@ -844,7 +856,7 @@ multilineTableHeader :: Bool -- ^ Headerless table
multilineTableHeader headless = try $ do
if headless
then return '\n'
- else tableSep
+ else tableSep >>~ notFollowedBy blankline
rawContent <- if headless
then return $ repeat ""
else many1
@@ -856,9 +868,9 @@ multilineTableHeader headless = try $ do
let indices = scanl (+) (length initSp) lines'
rawHeadsList <- if headless
then liftM (map (:[]) . tail .
- splitByIndices (init indices)) $ lookAhead anyLine
+ splitStringByIndices (init indices)) $ lookAhead anyLine
else return $ transpose $ map
- (\ln -> tail $ splitByIndices (init indices) ln)
+ (\ln -> tail $ splitStringByIndices (init indices) ln)
rawContent
let aligns = zipWith alignType rawHeadsList lengths
let rawHeads = if headless
@@ -922,30 +934,25 @@ inlineParsers = [ whitespace
, inlineNote -- after superscript because of ^[link](/foo)^
, autoLink
, rawHtmlInline
- , rawLaTeXInline'
, escapedChar
+ , rawLaTeXInline'
, exampleRef
, smartPunctuation inline
, charRef
, symbol
, ltSign ]
-inlineNonLink :: GenParser Char ParserState Inline
-inlineNonLink = (choice $
- map (\parser -> try (parser >>= failIfLink)) inlineParsers)
- <?> "inline (non-link)"
-
-failIfLink :: Inline -> GenParser tok st Inline
-failIfLink (Link _ _) = pzero
-failIfLink elt = return elt
-
-escapedChar :: GenParser Char ParserState Inline
-escapedChar = try $ do
+escapedChar' :: GenParser Char ParserState Char
+escapedChar' = try $ do
char '\\'
state <- getState
- result <- if stateStrict state
- then oneOf "\\`*_{}[]()>#+-.!~"
- else satisfy (not . isAlphaNum)
+ if stateStrict state
+ then oneOf "\\`*_{}[]()>#+-.!~"
+ else satisfy (not . isAlphaNum)
+
+escapedChar :: GenParser Char ParserState Inline
+escapedChar = do
+ result <- escapedChar'
return $ case result of
' ' -> Str "\160" -- "\ " is a nonbreaking space
'\n' -> LineBreak -- "\[newline]" is a linebreak
@@ -971,8 +978,7 @@ symbol :: GenParser Char ParserState Inline
symbol = do
result <- noneOf "<\\\n\t "
<|> try (do lookAhead $ char '\\'
- notFollowedBy' $ rawLaTeXEnvironment'
- <|> rawConTeXtEnvironment'
+ notFollowedBy' rawTeXBlock
char '\\')
return $ Str [result]
@@ -1036,8 +1042,20 @@ inlinesBetween start end =
where inner = innerSpace <|> (notFollowedBy' whitespace >> inline)
innerSpace = try $ whitespace >>~ notFollowedBy' end
+-- This is used to prevent exponential blowups for things like:
+-- a**a*a**a*a**a*a**a*a**a*a**a*a**
+nested :: GenParser Char ParserState a
+ -> GenParser Char ParserState a
+nested p = do
+ nestlevel <- stateMaxNestingLevel `fmap` getState
+ guard $ nestlevel > 0
+ updateState $ \st -> st{ stateMaxNestingLevel = stateMaxNestingLevel st - 1 }
+ res <- p
+ updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }
+ return res
+
emph :: GenParser Char ParserState Inline
-emph = Emph `liftM`
+emph = Emph `fmap` nested
(inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
where starStart = char '*' >> lookAhead nonspaceChar
starEnd = notFollowedBy' strong >> char '*'
@@ -1045,7 +1063,7 @@ emph = Emph `liftM`
ulEnd = notFollowedBy' strong >> char '_'
strong :: GenParser Char ParserState Inline
-strong = Strong `liftM`
+strong = Strong `liftM` nested
(inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
where starStart = string "**" >> lookAhead nonspaceChar
starEnd = try $ string "**"
@@ -1079,12 +1097,20 @@ nonEndline = satisfy (/='\n')
str :: GenParser Char ParserState Inline
str = do
+ smart <- stateSmart `fmap` getState
a <- alphaNum
- as <- many $ alphaNum <|> (try $ char '_' >>~ lookAhead alphaNum)
+ as <- many $ alphaNum
+ <|> (try $ char '_' >>~ lookAhead alphaNum)
+ <|> if smart
+ then (try $ satisfy (\c -> c == '\'' || c == '\x2019') >>
+ lookAhead alphaNum >> return '\x2019')
+ -- for things like l'aide
+ else mzero
+ pos <- getPosition
+ updateState $ \s -> s{ stateLastStrPos = Just pos }
let result = a:as
- state <- getState
let spacesToNbr = map (\c -> if c == ' ' then '\160' else c)
- if stateSmart state
+ if smart
then case likelyAbbrev result of
[] -> return $ Str result
xs -> choice (map (\x ->
@@ -1128,19 +1154,18 @@ endline = try $ do
-- a reference label for a link
reference :: GenParser Char ParserState [Inline]
reference = do notFollowedBy' (string "[^") -- footnote reference
- result <- inlinesInBalancedBrackets inlineNonLink
+ result <- inlinesInBalancedBrackets inline
return $ normalizeSpaces result
-- source for a link, with optional title
-source :: GenParser Char st (String, [Char])
+source :: GenParser Char ParserState (String, [Char])
source =
- (try $ charsInBalanced '(' ')' >>= parseFromString source') <|>
+ (try $ charsInBalanced '(' ')' litChar >>= parseFromString source') <|>
-- the following is needed for cases like: [ref](/url(a).
- (enclosed (char '(') (char ')') anyChar >>=
- parseFromString source')
+ (enclosed (char '(') (char ')') litChar >>= parseFromString source')
-- auxiliary function for source
-source' :: GenParser Char st (String, [Char])
+source' :: GenParser Char ParserState (String, [Char])
source' = do
skipSpaces
let nl = char '\n' >>~ notFollowedBy blankline
@@ -1149,29 +1174,33 @@ source' = do
skipMany spaceChar
optional nl
skipMany spaceChar
- many1 (satisfy $ not . isBlank)
- let betweenAngles = try $ char '<' >>
- manyTill (noneOf ">\n" <|> nl) (char '>')
+ many1 $ escapedChar' <|> satisfy (not . isBlank)
+ let betweenAngles = try $
+ char '<' >> manyTill (escapedChar' <|> noneOf ">\n" <|> nl) (char '>')
src <- try betweenAngles <|> sourceURL
tit <- option "" linkTitle
skipSpaces
eof
return (escapeURI $ removeTrailingSpace src, tit)
-linkTitle :: GenParser Char st String
-linkTitle = try $ do
+linkTitle :: GenParser Char ParserState String
+linkTitle = try $ do
(many1 spaceChar >> option '\n' newline) <|> newline
skipSpaces
delim <- oneOf "'\""
- tit <- manyTill (optional (char '\\') >> anyChar)
- (try (char delim >> skipSpaces >> eof))
- return $ decodeCharacterReferences tit
+ tit <- manyTill litChar (try (char delim >> skipSpaces >> eof))
+ return $ fromEntities tit
link :: GenParser Char ParserState Inline
link = try $ do
lab <- reference
(src, tit) <- source <|> referenceLink lab
- return $ Link lab (src, tit)
+ return $ Link (delinkify lab) (src, tit)
+
+delinkify :: [Inline] -> [Inline]
+delinkify = bottomUp $ concatMap go
+ where go (Link lab _) = lab
+ go x = [x]
-- a link like [this][ref] or [this][] or [this]
referenceLink :: [Inline]
@@ -1198,8 +1227,9 @@ autoLink = try $ do
image :: GenParser Char ParserState Inline
image = try $ do
char '!'
- (Link lab src) <- link
- return $ Image lab src
+ lab <- reference
+ (src, tit) <- source <|> referenceLink lab
+ return $ Image lab (src,tit)
note :: GenParser Char ParserState Inline
note = try $ do
@@ -1228,18 +1258,16 @@ inlineNote = try $ do
rawLaTeXInline' :: GenParser Char ParserState Inline
rawLaTeXInline' = try $ do
failIfStrict
- lookAhead $ char '\\'
- notFollowedBy' $ rawLaTeXEnvironment'
- <|> rawConTeXtEnvironment'
+ lookAhead $ char '\\' >> notFollowedBy' (string "start") -- context env
RawInline _ s <- rawLaTeXInline
return $ RawInline "tex" s -- "tex" because it might be context or latex
-rawConTeXtEnvironment' :: GenParser Char st String
-rawConTeXtEnvironment' = try $ do
+rawConTeXtEnvironment :: GenParser Char st String
+rawConTeXtEnvironment = try $ do
string "\\start"
completion <- inBrackets (letter <|> digit <|> spaceChar)
<|> (many1 letter)
- contents <- manyTill (rawConTeXtEnvironment' <|> (count 1 anyChar))
+ contents <- manyTill (rawConTeXtEnvironment <|> (count 1 anyChar))
(try $ string "\\stop" >> string completion)
return $ "\\start" ++ completion ++ concat contents ++ "\\stop" ++ completion
@@ -1312,7 +1340,8 @@ citeKey = try $ do
suppress_author <- option False (char '-' >> return True)
char '@'
first <- letter
- rest <- many $ (noneOf ",;!?[]()@ \t\n")
+ let internal p = try $ p >>~ lookAhead (letter <|> digit)
+ rest <- many $ letter <|> digit <|> internal (oneOf ":.#$%&-_?<>~")
let key = first:rest
st <- getState
guard $ key `elem` stateCitations st
@@ -1320,8 +1349,12 @@ citeKey = try $ do
suffix :: GenParser Char ParserState [Inline]
suffix = try $ do
+ hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
spnl
- liftM normalizeSpaces $ many $ notFollowedBy (oneOf ";]") >> inline
+ rest <- liftM normalizeSpaces $ many $ notFollowedBy (oneOf ";]") >> inline
+ return $ if hasSpace
+ then Space : rest
+ else rest
prefix :: GenParser Char ParserState [Inline]
prefix = liftM normalizeSpaces $
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 7fda0da19..456b23ce8 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -128,6 +128,7 @@ block = choice [ codeBlock
, fieldList
, imageBlock
, customCodeBlock
+ , mathBlock
, unknownDirective
, header
, hrule
@@ -360,6 +361,33 @@ customCodeBlock = try $ do
result <- indentedBlock
return $ CodeBlock ("", ["sourceCode", language], []) $ stripTrailingNewlines result
+-- | The 'math' directive (from Sphinx) for display math.
+mathBlock :: GenParser Char st Block
+mathBlock = try $ do
+ string ".. math::"
+ mathBlockMultiline <|> mathBlockOneLine
+
+mathBlockOneLine :: GenParser Char st Block
+mathBlockOneLine = try $ do
+ result <- manyTill anyChar newline
+ blanklines
+ return $ Para [Math DisplayMath $ removeLeadingTrailingSpace result]
+
+mathBlockMultiline :: GenParser Char st Block
+mathBlockMultiline = try $ do
+ blanklines
+ result <- indentedBlock
+ -- a single block can contain multiple equations, which need to go
+ -- in separate Pandoc math elements
+ let lns = map removeLeadingTrailingSpace $ lines result
+ -- drop :label, :nowrap, etc.
+ let startsWithColon (':':_) = True
+ startsWithColon _ = False
+ let lns' = dropWhile startsWithColon lns
+ let eqs = map (removeLeadingTrailingSpace . unlines)
+ $ filter (not . null) $ splitBy null lns'
+ return $ Para $ map (Math DisplayMath) eqs
+
lhsCodeBlock :: GenParser Char ParserState Block
lhsCodeBlock = try $ do
failUnlessLHS
@@ -526,8 +554,8 @@ noteBlock = try $ do
string ".."
spaceChar >> skipMany spaceChar
ref <- noteMarker
- spaceChar >> skipMany spaceChar
- first <- anyLine
+ first <- (spaceChar >> skipMany spaceChar >> anyLine)
+ <|> (newline >> return "")
blanks <- option "" blanklines
rest <- option "" indentedBlock
endPos <- getPosition
@@ -736,6 +764,7 @@ inline = choice [ whitespace
, image
, superscript
, subscript
+ , math
, note
, smartPunctuation inline
, hyphens
@@ -750,7 +779,8 @@ hyphens = do
return $ Str result
escapedChar :: GenParser Char st Inline
-escapedChar = escaped anyChar
+escapedChar = do c <- escaped anyChar
+ return $ Str [c]
symbol :: GenParser Char ParserState Inline
symbol = do
@@ -773,24 +803,31 @@ strong :: GenParser Char ParserState Inline
strong = enclosed (string "**") (try $ string "**") inline >>=
return . Strong . normalizeSpaces
-interpreted :: [Char] -> GenParser Char st [Inline]
+interpreted :: [Char] -> GenParser Char st [Char]
interpreted role = try $ do
optional $ try $ string "\\ "
result <- enclosed (string $ ":" ++ role ++ ":`") (char '`') anyChar
try (string "\\ ") <|> lookAhead (count 1 $ oneOf " \t\n") <|> (eof >> return "")
- return [Str result]
+ return result
superscript :: GenParser Char ParserState Inline
-superscript = interpreted "sup" >>= (return . Superscript)
+superscript = interpreted "sup" >>= \x -> return (Superscript [Str x])
subscript :: GenParser Char ParserState Inline
-subscript = interpreted "sub" >>= (return . Subscript)
+subscript = interpreted "sub" >>= \x -> return (Subscript [Str x])
+
+math :: GenParser Char ParserState Inline
+math = interpreted "math" >>= \x -> return (Math InlineMath x)
whitespace :: GenParser Char ParserState Inline
whitespace = many1 spaceChar >> return Space <?> "whitespace"
str :: GenParser Char ParserState Inline
-str = many1 (noneOf (specialChars ++ "\t\n ")) >>= return . Str
+str = do
+ result <- many1 (noneOf (specialChars ++ "\t\n "))
+ pos <- getPosition
+ updateState $ \s -> s{ stateLastStrPos = Just pos }
+ return $ Str result
-- an endline character that can be treated as a space, not a structural break
endline :: GenParser Char ParserState Inline
diff --git a/src/Text/Pandoc/Readers/TeXMath.hs b/src/Text/Pandoc/Readers/TeXMath.hs
index b9a46e8ff..67dfe6753 100644
--- a/src/Text/Pandoc/Readers/TeXMath.hs
+++ b/src/Text/Pandoc/Readers/TeXMath.hs
@@ -69,8 +69,17 @@ expToInlines (ESymbol t s) = Just $ addSpace t (Str s)
medspace = Str "\x2005"
widespace = Str "\x2004"
expToInlines (EStretchy x) = expToInlines x
+expToInlines (EDelimited start end xs) = do
+ xs' <- mapM expToInlines xs
+ return $ [Str start] ++ concat xs' ++ [Str end]
expToInlines (EGrouped xs) = expsToInlines xs
-expToInlines (ESpace _) = Just [Str " "] -- variable widths not supported
+expToInlines (ESpace "0.167em") = Just [Str "\x2009"]
+expToInlines (ESpace "0.222em") = Just [Str "\x2005"]
+expToInlines (ESpace "0.278em") = Just [Str "\x2004"]
+expToInlines (ESpace "0.333em") = Just [Str "\x2004"]
+expToInlines (ESpace "1em") = Just [Str "\x2001"]
+expToInlines (ESpace "2em") = Just [Str "\x2001\x2001"]
+expToInlines (ESpace _) = Just [Str " "]
expToInlines (EBinary _ _ _) = Nothing
expToInlines (ESub x y) = do
x' <- expToInlines x
@@ -88,10 +97,10 @@ expToInlines (ESubsup x y z) = do
expToInlines (EDown x y) = expToInlines (ESub x y)
expToInlines (EUp x y) = expToInlines (ESuper x y)
expToInlines (EDownup x y z) = expToInlines (ESubsup x y z)
-expToInlines (EText "normal" x) = Just [Str x]
-expToInlines (EText "bold" x) = Just [Strong [Str x]]
-expToInlines (EText "monospace" x) = Just [Code nullAttr x]
-expToInlines (EText "italic" x) = Just [Emph [Str x]]
+expToInlines (EText TextNormal x) = Just [Str x]
+expToInlines (EText TextBold x) = Just [Strong [Str x]]
+expToInlines (EText TextMonospace x) = Just [Code nullAttr x]
+expToInlines (EText TextItalic x) = Just [Emph [Str x]]
expToInlines (EText _ x) = Just [Str x]
expToInlines (EOver (EGrouped [EIdentifier [c]]) (ESymbol Accent [accent])) =
case accent of
diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs
index 12d299aa4..3b5954368 100644
--- a/src/Text/Pandoc/Readers/Textile.hs
+++ b/src/Text/Pandoc/Readers/Textile.hs
@@ -68,7 +68,8 @@ import Control.Monad ( guard, liftM )
readTextile :: ParserState -- ^ Parser state, including options for parser
-> String -- ^ String to parse (assuming @'\n'@ line endings)
-> Pandoc
-readTextile state s = (readWith parseTextile) state (s ++ "\n\n")
+readTextile state s =
+ (readWith parseTextile) state{ stateOldDashes = True } (s ++ "\n\n")
--
@@ -436,6 +437,8 @@ str = do
next <- lookAhead letter
guard $ isLetter (last xs) || isLetter next
return $ xs ++ "-"
+ pos <- getPosition
+ updateState $ \s -> s{ stateLastStrPos = Just pos }
return $ Str result
-- | Textile allows HTML span infos, we discard them
diff --git a/src/Text/Pandoc/S5.hs b/src/Text/Pandoc/S5.hs
deleted file mode 100644
index b17b052c5..000000000
--- a/src/Text/Pandoc/S5.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-{-
-Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-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.S5
- Copyright : Copyright (C) 2006-2010 John MacFarlane
- License : GNU GPL, version 2 or above
-
- Maintainer : John MacFarlane <jgm@berkeley.edu>
- Stability : alpha
- Portability : portable
-
-Definitions for creation of S5 powerpoint-like HTML.
-(See <http://meyerweb.com/eric/tools/s5/>.)
--}
-module Text.Pandoc.S5 ( s5HeaderIncludes) where
-import Text.Pandoc.Shared ( readDataFile )
-import System.FilePath ( (</>) )
-import Data.ByteString.UTF8 ( toString, fromString )
-import Data.ByteString.Base64 ( encode )
-
-s5HeaderIncludes :: Maybe FilePath -> IO String
-s5HeaderIncludes datadir = do
- c <- s5CSS datadir
- j <- s5Javascript datadir
- return $ c ++ j
-
-s5Javascript :: Maybe FilePath -> IO String
-s5Javascript datadir = do
- js <- readDataFile datadir $ "s5" </> "default" </> "slides.min.js"
- return $ "<script type=\"text/javascript\">\n" ++ inCDATA js ++ "</script>\n"
-
-inCDATA :: String -> String
-inCDATA s = "/*<![CDATA[*/\n" ++ s ++ "\n/*]]>*/\n"
-
-base64 :: String -> String
-base64 = toString . encode . fromString
-
-s5CSS :: Maybe FilePath -> IO String
-s5CSS datadir = do
- s5CoreCSS <- readDataFile datadir $ "s5" </> "default" </> "s5-core.css"
- s5FramingCSS <- readDataFile datadir $ "s5" </> "default" </> "framing.css"
- s5PrettyCSS <- readDataFile datadir $ "s5" </> "default" </> "pretty.css"
- s5OperaCSS <- readDataFile datadir $ "s5" </> "default" </> "opera.css"
- s5OutlineCSS <- readDataFile datadir $ "s5" </> "default" </> "outline.css"
- s5PrintCSS <- readDataFile datadir $ "s5" </> "default" </> "print.css"
- return $ "<link rel=\"stylesheet\" type=\"text/css\" media=\"projection\" id=\"slideProj\" href=\"data:text/css;charset=utf-8;base64," ++
- base64 (s5CoreCSS ++ "\n" ++ s5FramingCSS ++ "\n" ++ s5PrettyCSS) ++ "\" />\n" ++
- "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" id=\"outlineStyle\" href=\"data:text/css;charset=utf-8;base64," ++
- base64 s5OutlineCSS ++ "\" />\n" ++
- "<link rel=\"stylesheet\" type=\"text/css\" media=\"print\" id=\"slidePrint\" href=\"data:text/css;charset=utf-8;base64," ++
- base64 s5PrintCSS ++ "\" />\n" ++
- "<link rel=\"stylesheet\" type=\"text/css\" media=\"projection\" id=\"operaFix\" href=\"data:text/css;charset=utf-8;base64," ++
- base64 s5OperaCSS ++ "\" />\n"
diff --git a/src/Text/Pandoc/SelfContained.hs b/src/Text/Pandoc/SelfContained.hs
new file mode 100644
index 000000000..9c609b8fe
--- /dev/null
+++ b/src/Text/Pandoc/SelfContained.hs
@@ -0,0 +1,162 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-
+Copyright (C) 2011 John MacFarlane <jgm@berkeley.edu>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+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.SelfContained
+ Copyright : Copyright (C) 2011 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm@berkeley.edu>
+ Stability : alpha
+ Portability : portable
+
+Functions for converting an HTML file into one that can be viewed
+offline, by incorporating linked images, CSS, and scripts into
+the HTML using data URIs.
+-}
+module Text.Pandoc.SelfContained ( makeSelfContained ) where
+import Text.HTML.TagSoup
+import Network.URI (isAbsoluteURI, parseURI, escapeURIString)
+import Network.HTTP
+import Data.ByteString.Base64
+import qualified Data.ByteString.Char8 as B
+import Data.ByteString (ByteString)
+import Data.ByteString.UTF8 (toString, fromString)
+import System.FilePath (takeExtension, dropExtension, takeDirectory, (</>))
+import Data.Char (toLower, isAscii, isAlphaNum)
+import Codec.Compression.GZip as Gzip
+import qualified Data.ByteString.Lazy as L
+import Text.Pandoc.Shared (findDataFile)
+import Text.Pandoc.MIME (getMimeType)
+import System.Directory (doesFileExist)
+
+getItem :: Maybe FilePath -> String -> IO (ByteString, Maybe String)
+getItem userdata f =
+ if isAbsoluteURI f
+ then openURL f
+ else do
+ let mime = case takeExtension f of
+ ".gz" -> getMimeType $ dropExtension f
+ x -> getMimeType x
+ exists <- doesFileExist f
+ if exists
+ then do
+ cont <- B.readFile f
+ return (cont, mime)
+ else do
+ res <- findDataFile userdata f
+ exists' <- doesFileExist res
+ if exists'
+ then do
+ cont <- B.readFile res
+ return (cont, mime)
+ else error $ "Could not find `" ++ f ++ "'"
+
+-- TODO - have this return mime type too - then it can work for google
+-- chart API, e.g.
+openURL :: String -> IO (ByteString, Maybe String)
+openURL u = getBodyAndMimeType =<< simpleHTTP (getReq u)
+ where getReq v = case parseURI v of
+ Nothing -> error $ "Could not parse URI: " ++ v
+ Just u' -> mkRequest GET u'
+ getBodyAndMimeType (Left err) = fail (show err)
+ getBodyAndMimeType (Right r) = return (rspBody r, findHeader HdrContentType r)
+
+isOk :: Char -> Bool
+isOk c = isAscii c && isAlphaNum c
+
+convertTag :: Maybe FilePath -> Tag String -> IO (Tag String)
+convertTag userdata t@(TagOpen "img" as) =
+ case fromAttrib "src" t of
+ [] -> return t
+ src -> do
+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
+ let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)
+ return $ TagOpen "img" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
+convertTag userdata t@(TagOpen "video" as) =
+ case fromAttrib "src" t of
+ [] -> return t
+ src -> do
+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
+ let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)
+ return $ TagOpen "video" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
+convertTag userdata t@(TagOpen "script" as) =
+ case fromAttrib "src" t of
+ [] -> return t
+ src -> do
+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
+ let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
+ return $ TagOpen "script" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
+convertTag userdata t@(TagOpen "link" as) =
+ case fromAttrib "href" t of
+ [] -> return t
+ src -> do
+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
+ let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
+ return $ TagOpen "link" (("href",enc) : [(x,y) | (x,y) <- as, x /= "href"])
+convertTag _ t = return t
+
+cssURLs :: Maybe FilePath -> FilePath -> ByteString -> IO ByteString
+cssURLs userdata d orig =
+ case B.breakSubstring "url(" orig of
+ (x,y) | B.null y -> return orig
+ | otherwise -> do
+ let (u,v) = B.breakSubstring ")" $ B.drop 4 y
+ let url = toString
+ $ case B.take 1 u of
+ "\"" -> B.takeWhile (/='"') $ B.drop 1 u
+ _ -> u
+ (raw, mime) <- getRaw userdata "" (d </> url)
+ rest <- cssURLs userdata d v
+ let enc = "data:" `B.append` fromString mime `B.append`
+ ";base64," `B.append` (encode raw)
+ return $ x `B.append` "url(" `B.append` enc `B.append` rest
+
+getRaw :: Maybe FilePath -> String -> String -> IO (ByteString, String)
+getRaw userdata mimetype src = do
+ let ext = map toLower $ takeExtension src
+ (raw, respMime) <- getItem userdata src
+ let raw' = if ext == ".gz"
+ then B.concat $ L.toChunks $ Gzip.decompress $ L.fromChunks
+ $ [raw]
+ else raw
+ let mime = case (mimetype, respMime) of
+ ("",Nothing) -> error
+ $ "Could not determine mime type for `" ++ src ++ "'"
+ (x, Nothing) -> x
+ (_, Just x ) -> x
+ result <- if mime == "text/css"
+ then cssURLs userdata (takeDirectory src) raw'
+ else return raw'
+ return (result, mime)
+
+-- | Convert HTML into self-contained HTML, incorporating images,
+-- scripts, and CSS using data: URIs. Items specified using absolute
+-- URLs will be downloaded; those specified using relative URLs will
+-- be sought first relative to the working directory, then relative
+-- to the user data directory (if the first parameter is 'Just'
+-- a directory), and finally relative to pandoc's default data
+-- directory.
+makeSelfContained :: Maybe FilePath -> String -> IO String
+makeSelfContained userdata inp = do
+ let tags = parseTags inp
+ out' <- mapM (convertTag userdata) tags
+ return $ renderTagsOptions renderOptions{ optMinimize = (\t -> t == "br"
+ || t == "img" || t == "meta" || t == "link" ) } out'
+
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs
index 9717e1bc8..cd5b19164 100644
--- a/src/Text/Pandoc/Shared.hs
+++ b/src/Text/Pandoc/Shared.hs
@@ -32,6 +32,7 @@ module Text.Pandoc.Shared (
-- * List processing
splitBy,
splitByIndices,
+ splitStringByIndices,
substitute,
-- * Text processing
backslashEscapes,
@@ -44,8 +45,9 @@ module Text.Pandoc.Shared (
camelCaseToHyphenated,
toRomanNumeral,
escapeURI,
- unescapeURI,
tabFilter,
+ -- * Date/time
+ normalizeDate,
-- * Pandoc block and inline list processing
orderedListMarkers,
normalizeSpaces,
@@ -68,21 +70,31 @@ module Text.Pandoc.Shared (
inDirectory,
findDataFile,
readDataFile,
+ -- * Error handling
+ err,
+ warn,
) where
import Text.Pandoc.Definition
import Text.Pandoc.Generic
-import qualified Text.Pandoc.UTF8 as UTF8 (readFile)
-import Data.Char ( toLower, isLower, isUpper, isAlpha, isAscii,
- isLetter, isDigit )
+import qualified Text.Pandoc.UTF8 as UTF8
+import System.Environment (getProgName)
+import System.Exit (exitWith, ExitCode(..))
+import Data.Char ( toLower, isLower, isUpper, isAlpha,
+ isLetter, isDigit, isSpace )
import Data.List ( find, isPrefixOf, intercalate )
-import Network.URI ( isAllowedInURI, escapeURIString, unEscapeString )
-import Codec.Binary.UTF8.String ( encodeString, decodeString )
+import Network.URI ( escapeURIString )
import System.Directory
import System.FilePath ( (</>) )
import Data.Generics (Typeable, Data)
import qualified Control.Monad.State as S
+import Control.Monad (msum)
import Paths_pandoc (getDataFileName)
+import Text.Pandoc.Highlighting (Style, pygments)
+import Text.Pandoc.Pretty (charWidth)
+import System.Locale (defaultTimeLocale)
+import Data.Time
+import System.IO (stderr)
--
-- List processing
@@ -96,12 +108,23 @@ splitBy isSep lst =
rest' = dropWhile isSep rest
in first:(splitBy isSep rest')
--- | Split list into chunks divided at specified indices.
splitByIndices :: [Int] -> [a] -> [[a]]
splitByIndices [] lst = [lst]
-splitByIndices (x:xs) lst =
- let (first, rest) = splitAt x lst in
- first:(splitByIndices (map (\y -> y - x) xs) rest)
+splitByIndices (x:xs) lst = first:(splitByIndices (map (\y -> y - x) xs) rest)
+ where (first, rest) = splitAt x lst
+
+-- | Split string into chunks divided at specified indices.
+splitStringByIndices :: [Int] -> [Char] -> [[Char]]
+splitStringByIndices [] lst = [lst]
+splitStringByIndices (x:xs) lst =
+ let (first, rest) = splitAt' x lst in
+ first : (splitStringByIndices (map (\y -> y - x) xs) rest)
+
+splitAt' :: Int -> [Char] -> ([Char],[Char])
+splitAt' _ [] = ([],[])
+splitAt' n xs | n <= 0 = ([],xs)
+splitAt' n (x:xs) = (x:ys,zs)
+ where (ys,zs) = splitAt' (n - charWidth x) xs
-- | Replace each occurrence of one sublist in a list with another.
substitute :: (Eq a) => [a] -> [a] -> [a] -> [a]
@@ -181,16 +204,9 @@ toRomanNumeral x =
_ | x >= 1 -> "I" ++ toRomanNumeral (x - 1)
_ -> ""
--- | Escape unicode characters in a URI. Characters that are
--- already valid in a URI, including % and ?, are left alone.
+-- | Escape whitespace in URI.
escapeURI :: String -> String
-escapeURI = escapeURIString isAllowedInURI . encodeString
-
--- | Unescape unicode and some special characters in a URI, but
--- without introducing spaces.
-unescapeURI :: String -> String
-unescapeURI = escapeURIString (\c -> isAllowedInURI c || not (isAscii c)) .
- decodeString . unEscapeString
+escapeURI = escapeURIString (not . isSpace)
-- | Convert tabs to spaces and filter out DOS line endings.
-- Tabs will be preserved if tab stop is set to 0.
@@ -213,6 +229,18 @@ tabFilter tabStop =
in go tabStop
--
+-- Date/time
+--
+
+-- | Parse a date and convert (if possible) to "YYYY-MM-DD" format.
+normalizeDate :: String -> Maybe String
+normalizeDate s = fmap (formatTime defaultTimeLocale "%F")
+ (msum $ map (\fs -> parsetimeWith fs s) formats :: Maybe Day)
+ where parsetimeWith = parseTime defaultTimeLocale
+ formats = ["%x","%m/%d/%Y", "%D","%F", "%d %b %Y",
+ "%d %B %Y", "%b. %d, %Y", "%B %d, %Y"]
+
+--
-- Pandoc block and inline list processing
--
@@ -304,9 +332,9 @@ consolidateInlines (Str x : ys) =
fromStr (Str z) = z
fromStr _ = error "consolidateInlines - fromStr - not a Str"
consolidateInlines (Space : ys) = Space : rest
- where isSpace Space = True
- isSpace _ = False
- rest = consolidateInlines $ dropWhile isSpace ys
+ where isSp Space = True
+ isSp _ = False
+ rest = consolidateInlines $ dropWhile isSp ys
consolidateInlines (Emph xs : Emph ys : zs) = consolidateInlines $
Emph (xs ++ ys) : zs
consolidateInlines (Strong xs : Strong ys : zs) = consolidateInlines $
@@ -334,10 +362,6 @@ stringify = queryWith go
go (Str x) = x
go (Code _ x) = x
go (Math _ x) = x
- go EmDash = "--"
- go EnDash = "-"
- go Apostrophe = "'"
- go Ellipses = "..."
go LineBreak = " "
go _ = ""
@@ -458,6 +482,7 @@ data ObfuscationMethod = NoObfuscation
-- | Varieties of HTML slide shows.
data HTMLSlideVariant = S5Slides
| SlidySlides
+ | DZSlides
| NoSlides
deriving (Show, Read, Eq)
@@ -488,9 +513,13 @@ data WriterOptions = WriterOptions
, writerCiteMethod :: CiteMethod -- ^ How to print cites
, writerBiblioFiles :: [FilePath] -- ^ Biblio files to use for citations
, writerHtml5 :: Bool -- ^ Produce HTML5
+ , writerBeamer :: Bool -- ^ Produce beamer LaTeX slide show
+ , writerSlideLevel :: Maybe Int -- ^ Force header level of slides
, writerChapters :: Bool -- ^ Use "chapter" for top-level sects
, writerListings :: Bool -- ^ Use listings package for code
- , writerAscii :: Bool -- ^ Avoid non-ascii characters
+ , writerHighlight :: Bool -- ^ Highlight source code
+ , writerHighlightStyle :: Style -- ^ Style to use for highlighting
+ , writerSetextHeaders :: Bool -- ^ Use setext headers for levels 1-2 in markdown
} deriving Show
{-# DEPRECATED writerXeTeX "writerXeTeX no longer does anything" #-}
@@ -522,9 +551,13 @@ defaultWriterOptions =
, writerCiteMethod = Citeproc
, writerBiblioFiles = []
, writerHtml5 = False
+ , writerBeamer = False
+ , writerSlideLevel = Nothing
, writerChapters = False
, writerListings = False
- , writerAscii = False
+ , writerHighlight = False
+ , writerHighlightStyle = pygments
+ , writerSetextHeaders = True
}
--
@@ -554,3 +587,19 @@ findDataFile (Just u) f = do
-- Cabal data directory.
readDataFile :: Maybe FilePath -> FilePath -> IO String
readDataFile userDir fname = findDataFile userDir fname >>= UTF8.readFile
+
+--
+-- Error reporting
+--
+
+err :: Int -> String -> IO a
+err exitCode msg = do
+ name <- getProgName
+ UTF8.hPutStrLn stderr $ name ++ ": " ++ msg
+ exitWith $ ExitFailure exitCode
+ return undefined
+
+warn :: String -> IO ()
+warn msg = do
+ name <- getProgName
+ UTF8.hPutStrLn stderr $ name ++ ": " ++ msg
diff --git a/src/Text/Pandoc/Slides.hs b/src/Text/Pandoc/Slides.hs
new file mode 100644
index 000000000..1df556d38
--- /dev/null
+++ b/src/Text/Pandoc/Slides.hs
@@ -0,0 +1,57 @@
+{-
+Copyright (C) 2012 John MacFarlane <jgm@berkeley.edu>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+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.Slides
+ Copyright : Copyright (C) 2012 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm@berkeley.edu>
+ Stability : alpha
+ Portability : portable
+
+Utility functions for splitting documents into slides for slide
+show formats (dzslides, s5, slidy, beamer).
+-}
+module Text.Pandoc.Slides ( getSlideLevel, prepSlides ) where
+import Text.Pandoc.Definition
+
+-- | Find level of header that starts slides (defined as the least header
+-- level that occurs before a non-header/non-hrule in the blocks).
+getSlideLevel :: [Block] -> Int
+getSlideLevel = go 6
+ where go least (Header n _ : x : xs)
+ | n < least && nonHOrHR x = go n xs
+ | otherwise = go least (x:xs)
+ go least (_ : xs) = go least xs
+ go least [] = least
+ nonHOrHR (Header _ _) = False
+ nonHOrHR (HorizontalRule) = False
+ nonHOrHR _ = True
+
+-- | Prepare a block list to be passed to hierarchicalize.
+prepSlides :: Int -> [Block] -> [Block]
+prepSlides slideLevel = ensureStartWithH . splitHrule
+ where splitHrule (HorizontalRule : Header n xs : ys)
+ | n == slideLevel = Header slideLevel xs : splitHrule ys
+ splitHrule (HorizontalRule : xs) = Header slideLevel [] : splitHrule xs
+ splitHrule (x : xs) = x : splitHrule xs
+ splitHrule [] = []
+ ensureStartWithH bs@(Header n _:_)
+ | n <= slideLevel = bs
+ ensureStartWithH bs = Header slideLevel [] : bs
diff --git a/src/Text/Pandoc/Templates.hs b/src/Text/Pandoc/Templates.hs
index 19c9a808a..336efe453 100644
--- a/src/Text/Pandoc/Templates.hs
+++ b/src/Text/Pandoc/Templates.hs
@@ -72,7 +72,7 @@ import Text.ParserCombinators.Parsec
import Control.Monad (liftM, when, forM)
import System.FilePath
import Data.List (intercalate, intersperse)
-import Text.XHtml (primHtml, Html)
+import Text.Blaze (preEscapedString, Html)
import Data.ByteString.Lazy.UTF8 (ByteString, fromString)
import Text.Pandoc.Shared (readDataFile)
import qualified Control.Exception.Extensible as E (try, IOException)
@@ -82,6 +82,8 @@ getDefaultTemplate :: (Maybe FilePath) -- ^ User data directory to search first
-> String -- ^ Name of writer
-> IO (Either E.IOException String)
getDefaultTemplate _ "native" = return $ Right ""
+getDefaultTemplate _ "json" = return $ Right ""
+getDefaultTemplate _ "docx" = return $ Right ""
getDefaultTemplate user "odt" = getDefaultTemplate user "opendocument"
getDefaultTemplate user "epub" = getDefaultTemplate user "html"
getDefaultTemplate user writer = do
@@ -110,7 +112,7 @@ instance TemplateTarget ByteString where
toTarget = fromString
instance TemplateTarget Html where
- toTarget = primHtml
+ toTarget = preEscapedString
-- | Renders a template
renderTemplate :: TemplateTarget a
diff --git a/src/Text/Pandoc/Writers/AsciiDoc.hs b/src/Text/Pandoc/Writers/AsciiDoc.hs
new file mode 100644
index 000000000..1913eb92b
--- /dev/null
+++ b/src/Text/Pandoc/Writers/AsciiDoc.hs
@@ -0,0 +1,367 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-
+Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+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.Writers.AsciiDoc
+ Copyright : Copyright (C) 2006-2010 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm@berkeley.edu>
+ Stability : alpha
+ Portability : portable
+
+Conversion of 'Pandoc' documents to asciidoc.
+
+Note that some information may be lost in conversion, due to
+expressive limitations of asciidoc. Footnotes and table cells with
+paragraphs (or other block items) are not possible in asciidoc.
+If pandoc encounters one of these, it will insert a message indicating
+that it has omitted the construct.
+
+AsciiDoc: <http://www.methods.co.nz/asciidoc/>
+-}
+module Text.Pandoc.Writers.AsciiDoc (writeAsciiDoc) where
+import Text.Pandoc.Definition
+import Text.Pandoc.Templates (renderTemplate)
+import Text.Pandoc.Shared
+import Text.Pandoc.Parsing hiding (blankline)
+import Text.ParserCombinators.Parsec ( runParser, GenParser )
+import Data.List ( isPrefixOf, intersperse, intercalate )
+import Text.Pandoc.Pretty
+import Control.Monad.State
+
+data WriterState = WriterState { defListMarker :: String
+ , orderedListLevel :: Int
+ , bulletListLevel :: Int
+ }
+
+-- | Convert Pandoc to AsciiDoc.
+writeAsciiDoc :: WriterOptions -> Pandoc -> String
+writeAsciiDoc opts document =
+ evalState (pandocToAsciiDoc opts document) WriterState{
+ defListMarker = "::"
+ , orderedListLevel = 1
+ , bulletListLevel = 1
+ }
+
+-- | Return asciidoc representation of document.
+pandocToAsciiDoc :: WriterOptions -> Pandoc -> State WriterState String
+pandocToAsciiDoc opts (Pandoc (Meta title authors date) blocks) = do
+ title' <- inlineListToAsciiDoc opts title
+ let title'' = title' $$ text (replicate (offset title') '=')
+ authors' <- mapM (inlineListToAsciiDoc opts) authors
+ -- asciidoc only allows a singel author
+ date' <- inlineListToAsciiDoc opts date
+ let titleblock = not $ null title && null authors && null date
+ body <- blockListToAsciiDoc opts blocks
+ let colwidth = if writerWrapText opts
+ then Just $ writerColumns opts
+ else Nothing
+ let main = render colwidth body
+ let context = writerVariables opts ++
+ [ ("body", main)
+ , ("title", render colwidth title'')
+ , ("date", render colwidth date')
+ ] ++
+ [ ("toc", "yes") | writerTableOfContents opts &&
+ writerStandalone opts ] ++
+ [ ("titleblock", "yes") | titleblock ] ++
+ [ ("author", render colwidth a) | a <- authors' ]
+ if writerStandalone opts
+ then return $ renderTemplate context $ writerTemplate opts
+ else return main
+
+-- | Escape special characters for AsciiDoc.
+escapeString :: String -> String
+escapeString = escapeStringUsing escs
+ where escs = backslashEscapes "{"
+
+-- | Ordered list start parser for use in Para below.
+olMarker :: GenParser Char ParserState Char
+olMarker = do (start, style', delim) <- anyOrderedListMarker
+ if delim == Period &&
+ (style' == UpperAlpha || (style' == UpperRoman &&
+ start `elem` [1, 5, 10, 50, 100, 500, 1000]))
+ then spaceChar >> spaceChar
+ else spaceChar
+
+-- | True if string begins with an ordered list marker
+beginsWithOrderedListMarker :: String -> Bool
+beginsWithOrderedListMarker str =
+ case runParser olMarker defaultParserState "para start" (take 10 str) of
+ Left _ -> False
+ Right _ -> True
+
+-- | Convert Pandoc block element to asciidoc.
+blockToAsciiDoc :: WriterOptions -- ^ Options
+ -> Block -- ^ Block element
+ -> State WriterState Doc
+blockToAsciiDoc _ Null = return empty
+blockToAsciiDoc opts (Plain inlines) = do
+ contents <- inlineListToAsciiDoc opts inlines
+ return $ contents <> cr
+blockToAsciiDoc opts (Para inlines) = do
+ contents <- inlineListToAsciiDoc opts inlines
+ -- escape if para starts with ordered list marker
+ let esc = if beginsWithOrderedListMarker (render Nothing contents)
+ then text "\\"
+ else empty
+ return $ esc <> contents <> blankline
+blockToAsciiDoc _ (RawBlock _ _) = return empty
+blockToAsciiDoc _ HorizontalRule =
+ return $ blankline <> text "'''''" <> blankline
+blockToAsciiDoc opts (Header level inlines) = do
+ contents <- inlineListToAsciiDoc opts inlines
+ let len = offset contents
+ return $ contents <> cr <>
+ (case level of
+ 1 -> text $ replicate len '-'
+ 2 -> text $ replicate len '~'
+ 3 -> text $ replicate len '^'
+ 4 -> text $ replicate len '+'
+ _ -> empty) <> blankline
+blockToAsciiDoc _ (CodeBlock (_,classes,_) str) = return $
+ flush (attrs <> dashes <> space <> attrs <> cr <> text str <>
+ cr <> dashes) <> blankline
+ where dashes = text $ replicate (maximum $ map length $ lines str) '-'
+ attrs = if null classes
+ then empty
+ else text $ intercalate "," $ "code" : classes
+blockToAsciiDoc opts (BlockQuote blocks) = do
+ contents <- blockListToAsciiDoc opts blocks
+ let isBlock (BlockQuote _) = True
+ isBlock _ = False
+ -- if there are nested block quotes, put in an open block
+ let contents' = if any isBlock blocks
+ then "--" $$ contents $$ "--"
+ else contents
+ let cols = offset contents'
+ let bar = text $ replicate cols '_'
+ return $ bar $$ chomp contents' $$ bar <> blankline
+blockToAsciiDoc opts (Table caption aligns widths headers rows) = do
+ caption' <- inlineListToAsciiDoc opts caption
+ let caption'' = if null caption
+ then empty
+ else "." <> caption' <> cr
+ let isSimple = all (== 0) widths
+ let relativePercentWidths = if isSimple
+ then widths
+ else map (/ (sum widths)) widths
+ let widths'' :: [Integer]
+ widths'' = map (floor . (* 100)) relativePercentWidths
+ -- ensure that the widths sum to 100
+ let widths' = case widths'' of
+ _ | isSimple -> widths''
+ (w:ws) | sum (w:ws) < 100
+ -> (100 - sum ws) : ws
+ ws -> ws
+ let totalwidth :: Integer
+ totalwidth = floor $ sum widths * 100
+ let colspec al wi = (case al of
+ AlignLeft -> "<"
+ AlignCenter -> "^"
+ AlignRight -> ">"
+ AlignDefault -> "") ++
+ if wi == 0 then "" else (show wi ++ "%")
+ let headerspec = if all null headers
+ then empty
+ else text "options=\"header\","
+ let widthspec = if totalwidth == 0
+ then empty
+ else text "width="
+ <> doubleQuotes (text $ show totalwidth ++ "%")
+ <> text ","
+ let tablespec = text "["
+ <> widthspec
+ <> text "cols="
+ <> doubleQuotes (text $ intercalate ","
+ $ zipWith colspec aligns widths')
+ <> text ","
+ <> headerspec <> text "]"
+ let makeCell [Plain x] = do d <- blockListToAsciiDoc opts [Plain x]
+ return $ text "|" <> chomp d
+ makeCell [Para x] = makeCell [Plain x]
+ makeCell _ = return $ text "|" <> "[multiblock cell omitted]"
+ let makeRow cells = hsep `fmap` mapM makeCell cells
+ rows' <- mapM makeRow rows
+ head' <- makeRow headers
+ let head'' = if all null headers then empty else head'
+ let colwidth = if writerWrapText opts
+ then writerColumns opts
+ else 100000
+ let maxwidth = maximum $ map offset (head':rows')
+ let body = if maxwidth > colwidth then vsep rows' else vcat rows'
+ let border = text $ "|" ++ replicate ((min maxwidth colwidth) - 1) '='
+ return $
+ caption'' $$ tablespec $$ border $$ head'' $$ body $$ border $$ blankline
+blockToAsciiDoc opts (BulletList items) = do
+ contents <- mapM (bulletListItemToAsciiDoc opts) items
+ return $ cat contents <> blankline
+blockToAsciiDoc opts (OrderedList (_start, sty, _delim) items) = do
+ let sty' = case sty of
+ UpperRoman -> UpperAlpha
+ LowerRoman -> LowerAlpha
+ x -> x
+ let markers = orderedListMarkers (1, sty', Period) -- start num not used
+ let markers' = map (\m -> if length m < 3
+ then m ++ replicate (3 - length m) ' '
+ else m) markers
+ contents <- mapM (\(item, num) -> orderedListItemToAsciiDoc opts item num) $
+ zip markers' items
+ return $ cat contents <> blankline
+blockToAsciiDoc opts (DefinitionList items) = do
+ contents <- mapM (definitionListItemToAsciiDoc opts) items
+ return $ cat contents <> blankline
+
+-- | Convert bullet list item (list of blocks) to asciidoc.
+bulletListItemToAsciiDoc :: WriterOptions -> [Block] -> State WriterState Doc
+bulletListItemToAsciiDoc opts blocks = do
+ let addBlock :: Doc -> Block -> State WriterState Doc
+ addBlock d b | isEmpty d = chomp `fmap` blockToAsciiDoc opts b
+ addBlock d b@(BulletList _) = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> chomp x
+ addBlock d b@(OrderedList _ _) = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> chomp x
+ addBlock d b = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> text "+" <> cr <> chomp x
+ lev <- bulletListLevel `fmap` get
+ modify $ \s -> s{ bulletListLevel = lev + 1 }
+ contents <- foldM addBlock empty blocks
+ modify $ \s -> s{ bulletListLevel = lev }
+ let marker = text (replicate lev '*')
+ return $ marker <> space <> contents <> cr
+
+-- | Convert ordered list item (a list of blocks) to asciidoc.
+orderedListItemToAsciiDoc :: WriterOptions -- ^ options
+ -> String -- ^ list item marker
+ -> [Block] -- ^ list item (list of blocks)
+ -> State WriterState Doc
+orderedListItemToAsciiDoc opts marker blocks = do
+ let addBlock :: Doc -> Block -> State WriterState Doc
+ addBlock d b | isEmpty d = chomp `fmap` blockToAsciiDoc opts b
+ addBlock d b@(BulletList _) = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> chomp x
+ addBlock d b@(OrderedList _ _) = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> chomp x
+ addBlock d b = do x <- blockToAsciiDoc opts b
+ return $ d <> cr <> text "+" <> cr <> chomp x
+ lev <- orderedListLevel `fmap` get
+ modify $ \s -> s{ orderedListLevel = lev + 1 }
+ contents <- foldM addBlock empty blocks
+ modify $ \s -> s{ orderedListLevel = lev }
+ return $ text marker <> space <> contents <> cr
+
+-- | Convert definition list item (label, list of blocks) to asciidoc.
+definitionListItemToAsciiDoc :: WriterOptions
+ -> ([Inline],[[Block]])
+ -> State WriterState Doc
+definitionListItemToAsciiDoc opts (label, defs) = do
+ labelText <- inlineListToAsciiDoc opts label
+ marker <- defListMarker `fmap` get
+ if marker == "::"
+ then modify (\st -> st{ defListMarker = ";;"})
+ else modify (\st -> st{ defListMarker = "::"})
+ let divider = cr <> text "+" <> cr
+ let defsToAsciiDoc :: [Block] -> State WriterState Doc
+ defsToAsciiDoc ds = (vcat . intersperse divider . map chomp)
+ `fmap` mapM (blockToAsciiDoc opts) ds
+ defs' <- mapM defsToAsciiDoc defs
+ modify (\st -> st{ defListMarker = marker })
+ let contents = nest 2 $ vcat $ intersperse divider $ map chomp defs'
+ return $ labelText <> text marker <> cr <> contents <> cr
+
+-- | Convert list of Pandoc block elements to asciidoc.
+blockListToAsciiDoc :: WriterOptions -- ^ Options
+ -> [Block] -- ^ List of block elements
+ -> State WriterState Doc
+blockListToAsciiDoc opts blocks = cat `fmap` mapM (blockToAsciiDoc opts) blocks
+
+-- | Convert list of Pandoc inline elements to asciidoc.
+inlineListToAsciiDoc :: WriterOptions -> [Inline] -> State WriterState Doc
+inlineListToAsciiDoc opts lst =
+ mapM (inlineToAsciiDoc opts) lst >>= return . cat
+
+-- | Convert Pandoc inline element to asciidoc.
+inlineToAsciiDoc :: WriterOptions -> Inline -> State WriterState Doc
+inlineToAsciiDoc opts (Emph lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "_" <> contents <> "_"
+inlineToAsciiDoc opts (Strong lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "*" <> contents <> "*"
+inlineToAsciiDoc opts (Strikeout lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "[line-through]*" <> contents <> "*"
+inlineToAsciiDoc opts (Superscript lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "^" <> contents <> "^"
+inlineToAsciiDoc opts (Subscript lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "~" <> contents <> "~"
+inlineToAsciiDoc opts (SmallCaps lst) = inlineListToAsciiDoc opts lst
+inlineToAsciiDoc opts (Quoted SingleQuote lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "`" <> contents <> "'"
+inlineToAsciiDoc opts (Quoted DoubleQuote lst) = do
+ contents <- inlineListToAsciiDoc opts lst
+ return $ "``" <> contents <> "''"
+inlineToAsciiDoc _ (Code _ str) = return $
+ text "`" <> text (escapeStringUsing (backslashEscapes "`") str) <> "`"
+inlineToAsciiDoc _ (Str str) = return $ text $ escapeString str
+inlineToAsciiDoc _ (Math InlineMath str) =
+ return $ "latexmath:[$" <> text str <> "$]"
+inlineToAsciiDoc _ (Math DisplayMath str) =
+ return $ "latexmath:[\\[" <> text str <> "\\]]"
+inlineToAsciiDoc _ (RawInline _ _) = return empty
+inlineToAsciiDoc _ (LineBreak) = return $ " +" <> cr
+inlineToAsciiDoc _ Space = return space
+inlineToAsciiDoc opts (Cite _ lst) = inlineListToAsciiDoc opts lst
+inlineToAsciiDoc opts (Link txt (src, _tit)) = do
+-- relative: link:downloads/foo.zip[download foo.zip]
+-- abs: http://google.cod[Google]
+-- or my@email.com[email john]
+ linktext <- inlineListToAsciiDoc opts txt
+ let isRelative = ':' `notElem` src
+ let prefix = if isRelative
+ then text "link:"
+ else empty
+ let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
+ let useAuto = case txt of
+ [Code _ s] | s == srcSuffix -> True
+ _ -> False
+ return $ if useAuto
+ then text srcSuffix
+ else prefix <> text src <> "[" <> linktext <> "]"
+inlineToAsciiDoc opts (Image alternate (src, tit)) = do
+-- image:images/logo.png[Company logo, title="blah"]
+ let txt = if (null alternate) || (alternate == [Str ""])
+ then [Str "image"]
+ else alternate
+ linktext <- inlineListToAsciiDoc opts txt
+ let linktitle = if null tit
+ then empty
+ else text $ ",title=\"" ++ tit ++ "\""
+ return $ "image:" <> text src <> "[" <> linktext <> linktitle <> "]"
+inlineToAsciiDoc opts (Note [Para inlines]) =
+ inlineToAsciiDoc opts (Note [Plain inlines])
+inlineToAsciiDoc opts (Note [Plain inlines]) = do
+ contents <- inlineListToAsciiDoc opts inlines
+ return $ text "footnote:[" <> contents <> "]"
+-- asciidoc can't handle blank lines in notes
+inlineToAsciiDoc _ (Note _) = return "[multiblock footnote omitted]"
diff --git a/src/Text/Pandoc/Writers/ConTeXt.hs b/src/Text/Pandoc/Writers/ConTeXt.hs
index 763f77d7c..dfdf7a140 100644
--- a/src/Text/Pandoc/Writers/ConTeXt.hs
+++ b/src/Text/Pandoc/Writers/ConTeXt.hs
@@ -31,12 +31,13 @@ Conversion of 'Pandoc' format into ConTeXt.
module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where
import Text.Pandoc.Definition
import Text.Pandoc.Shared
+import Text.Pandoc.Generic (queryWith)
import Text.Printf ( printf )
import Data.List ( intercalate )
import Control.Monad.State
import Text.Pandoc.Pretty
import Text.Pandoc.Templates ( renderTemplate )
-import Network.URI ( isAbsoluteURI, unEscapeString )
+import Network.URI ( isURI, unEscapeString )
data WriterState =
WriterState { stNextRef :: Int -- number of next URL reference
@@ -68,13 +69,14 @@ pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do
datetext <- if null date
then return ""
else liftM (render colwidth) $ inlineListToConTeXt date
- body <- blockListToConTeXt blocks
- let main = render colwidth $ body
+ body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
+ let main = (render colwidth . vcat) body
let context = writerVariables options ++
[ ("toc", if writerTableOfContents options then "yes" else "")
, ("body", main)
, ("title", titletext)
, ("date", datetext) ] ++
+ [ ("number-sections", "yes") | writerNumberSections options ] ++
[ ("author", a) | a <- authorstext ]
return $ if writerStandalone options
then renderTemplate context $ writerTemplate options
@@ -101,12 +103,24 @@ escapeCharForConTeXt ch =
']' -> "{]}"
'_' -> "\\letterunderscore{}"
'\160' -> "~"
+ '\x2014' -> "---"
+ '\x2013' -> "--"
+ '\x2019' -> "'"
+ '\x2026' -> "\\ldots{}"
x -> [x]
-- | Escape string for ConTeXt
stringToConTeXt :: String -> String
stringToConTeXt = concatMap escapeCharForConTeXt
+-- | Convert Elements to ConTeXt
+elementToConTeXt :: WriterOptions -> Element -> State WriterState Doc
+elementToConTeXt _ (Blk block) = blockToConTeXt block
+elementToConTeXt opts (Sec level _ id' title' elements) = do
+ header' <- sectionHeader id' level title'
+ innerContents <- mapM (elementToConTeXt opts) elements
+ return $ vcat (header' : innerContents)
+
-- | Convert Pandoc block element to ConTeXt.
blockToConTeXt :: Block
-> State WriterState Doc
@@ -166,18 +180,8 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
blockToConTeXt (DefinitionList lst) =
liftM vcat $ mapM defListItemToConTeXt lst
blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
-blockToConTeXt (Header level lst) = do
- contents <- inlineListToConTeXt lst
- st <- get
- let opts = stOptions st
- let base = if writerNumberSections opts then "section" else "subject"
- let level' = if writerChapters opts then level - 1 else level
- return $ if level' >= 1 && level' <= 5
- then char '\\' <> text (concat (replicate (level' - 1) "sub")) <>
- text base <> char '{' <> contents <> char '}' <> blankline
- else if level' == 0
- then "\\chapter{" <> contents <> "}"
- else contents <> blankline
+-- If this is ever executed, provide a default for the reference identifier.
+blockToConTeXt (Header level lst) = sectionHeader "" level lst
blockToConTeXt (Table caption aligns widths heads rows) = do
let colDescriptor colWidth alignment = (case alignment of
AlignLeft -> 'l'
@@ -213,8 +217,8 @@ defListItemToConTeXt :: ([Inline], [[Block]]) -> State WriterState Doc
defListItemToConTeXt (term, defs) = do
term' <- inlineListToConTeXt term
def' <- liftM vsep $ mapM blockListToConTeXt defs
- return $ "\\startdescr" <> braces term' $$ nest 2 def' $$
- "\\stopdescr" <> blankline
+ return $ "\\startdescription" <> braces term' $$ nest 2 def' $$
+ "\\stopdescription" <> blankline
-- | Convert list of block elements to ConTeXt.
blockListToConTeXt :: [Block] -> State WriterState Doc
@@ -257,10 +261,6 @@ inlineToConTeXt (Quoted DoubleQuote lst) = do
contents <- inlineListToConTeXt lst
return $ "\\quotation" <> braces contents
inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst
-inlineToConTeXt Apostrophe = return $ char '\''
-inlineToConTeXt EmDash = return "---"
-inlineToConTeXt EnDash = return "--"
-inlineToConTeXt Ellipses = return "\\ldots{}"
inlineToConTeXt (Str str) = return $ text $ stringToConTeXt str
inlineToConTeXt (Math InlineMath str) =
return $ char '$' <> text str <> char '$'
@@ -271,23 +271,69 @@ inlineToConTeXt (RawInline "tex" str) = return $ text str
inlineToConTeXt (RawInline _ _) = return empty
inlineToConTeXt (LineBreak) = return $ text "\\crlf" <> cr
inlineToConTeXt Space = return space
-inlineToConTeXt (Link [Code _ str] (src, tit)) = -- since ConTeXt has its own
- inlineToConTeXt (Link [Str str] (src, tit)) -- way of printing links...
-inlineToConTeXt (Link txt (src, _)) = do
+-- autolink
+inlineToConTeXt (Link [Code _ str] (src, tit)) = inlineToConTeXt (Link
+ [RawInline "context" "\\hyphenatedurl{", Str str, RawInline "context" "}"]
+ (src, tit))
+-- Handle HTML-like internal document references to sections
+inlineToConTeXt (Link txt (('#' : ref), _)) = do
+ opts <- gets stOptions
+ label <- inlineListToConTeXt txt
+ return $ text "\\in"
+ <> braces (if writerNumberSections opts
+ then label <+> text "(\\S"
+ else label) -- prefix
+ <> braces (if writerNumberSections opts
+ then text ")"
+ else empty) -- suffix
+ <> brackets (text ref)
+
+inlineToConTeXt (Link txt (src, _)) = do
st <- get
let next = stNextRef st
put $ st {stNextRef = next + 1}
- let ref = show next
- label <- inlineListToConTeXt txt
- return $ "\\useURL" <> brackets (text ref) <> brackets (text src) <>
- brackets empty <> brackets label <>
- "\\from" <> brackets (text ref)
+ let ref = "url" ++ show next
+ label <- inlineListToConTeXt txt
+ return $ "\\useURL"
+ <> brackets (text ref)
+ <> brackets (text $ escapeStringUsing [('#',"\\#")] src)
+ <> brackets empty
+ <> brackets label
+ <> "\\from"
+ <> brackets (text ref)
inlineToConTeXt (Image _ (src, _)) = do
- let src' = if isAbsoluteURI src
+ let src' = if isURI src
then src
else unEscapeString src
return $ braces $ "\\externalfigure" <> brackets (text src')
inlineToConTeXt (Note contents) = do
contents' <- blockListToConTeXt contents
- return $ text "\\footnote{" <>
- nest 2 contents' <> char '}'
+ let codeBlock x@(CodeBlock _ _) = [x]
+ codeBlock _ = []
+ let codeBlocks = queryWith codeBlock contents
+ return $ if null codeBlocks
+ then text "\\footnote{" <> nest 2 contents' <> char '}'
+ else text "\\startbuffer " <> nest 2 contents' <>
+ text "\\stopbuffer\\footnote{\\getbuffer}"
+
+-- | Craft the section header, inserting the secton reference, if supplied.
+sectionHeader :: [Char]
+ -> Int
+ -> [Inline]
+ -> State WriterState Doc
+sectionHeader ident hdrLevel lst = do
+ contents <- inlineListToConTeXt lst
+ st <- get
+ let opts = stOptions st
+ let level' = if writerChapters opts then hdrLevel - 1 else hdrLevel
+ return $ if level' >= 1 && level' <= 5
+ then char '\\'
+ <> text (concat (replicate (level' - 1) "sub"))
+ <> text "section"
+ <> (if (not . null) ident then brackets (text ident) else empty)
+ <> braces contents
+ <> blankline
+ else if level' == 0
+ then "\\chapter{" <> contents <> "}"
+ else contents <> blankline
+
diff --git a/src/Text/Pandoc/Writers/Docbook.hs b/src/Text/Pandoc/Writers/Docbook.hs
index 29c042cf9..1bcf99dcf 100644
--- a/src/Text/Pandoc/Writers/Docbook.hs
+++ b/src/Text/Pandoc/Writers/Docbook.hs
@@ -35,8 +35,11 @@ import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Readers.TeXMath
import Data.List ( isPrefixOf, intercalate, isSuffixOf )
import Data.Char ( toLower )
-import Text.Pandoc.Highlighting (languages, languagesByExtension)
+import Text.Pandoc.Highlighting ( languages, languagesByExtension )
import Text.Pandoc.Pretty
+import Text.TeXMath
+import qualified Text.XML.Light as Xml
+import Data.Generics (everywhere, mkT)
-- | Convert list of authors to a docbook <author> section
authorToDocbook :: WriterOptions -> [Inline] -> Doc
@@ -69,34 +72,39 @@ writeDocbook opts (Pandoc (Meta tit auths dat) blocks) =
then Just $ writerColumns opts
else Nothing
render' = render colwidth
- opts' = if "</book>" `isSuffixOf`
+ opts' = if "/book>" `isSuffixOf`
(removeTrailingSpace $ writerTemplate opts)
then opts{ writerChapters = True }
else opts
- main = render' $ vcat (map (elementToDocbook opts') elements)
+ startLvl = if writerChapters opts' then 0 else 1
+ main = render' $ vcat (map (elementToDocbook opts' startLvl) elements)
context = writerVariables opts ++
[ ("body", main)
, ("title", render' title)
, ("date", render' date) ] ++
- [ ("author", render' a) | a <- authors ]
+ [ ("author", render' a) | a <- authors ] ++
+ [ ("mathml", "yes") | case writerHTMLMathMethod opts of
+ MathML _ -> True
+ _ -> False ]
in if writerStandalone opts
then renderTemplate context $ writerTemplate opts
else main
-- | Convert an Element to Docbook.
-elementToDocbook :: WriterOptions -> Element -> Doc
-elementToDocbook opts (Blk block) = blockToDocbook opts block
-elementToDocbook opts (Sec _ _num id' title elements) =
+elementToDocbook :: WriterOptions -> Int -> Element -> Doc
+elementToDocbook opts _ (Blk block) = blockToDocbook opts block
+elementToDocbook opts lvl (Sec _ _num id' title elements) =
-- Docbook doesn't allow sections with no content, so insert some if needed
let elements' = if null elements
then [Blk (Para [])]
else elements
- tag = if writerChapters opts
- then "chapter"
- else "section"
+ tag = case lvl of
+ n | n == 0 -> "chapter"
+ | n >= 1 && n <= 5 -> "sect" ++ show n
+ | otherwise -> "simplesect"
in inTags True tag [("id",id')] $
inTagsSimple "title" (inlinesToDocbook opts title) $$
- vcat (map (elementToDocbook opts{ writerChapters = False }) elements')
+ vcat (map (elementToDocbook opts (lvl + 1)) elements')
-- | Convert a list of Pandoc blocks to Docbook.
blocksToDocbook :: WriterOptions -> [Block] -> Doc
@@ -248,14 +256,27 @@ inlineToDocbook opts (Quoted _ lst) =
inTagsSimple "quote" $ inlinesToDocbook opts lst
inlineToDocbook opts (Cite _ lst) =
inlinesToDocbook opts lst
-inlineToDocbook _ Apostrophe = char '\''
-inlineToDocbook _ Ellipses = text "…"
-inlineToDocbook _ EmDash = text "—"
-inlineToDocbook _ EnDash = text "–"
inlineToDocbook _ (Code _ str) =
inTagsSimple "literal" $ text (escapeStringForXML str)
-inlineToDocbook opts (Math _ str) = inlinesToDocbook opts $ readTeXMath str
-inlineToDocbook _ (RawInline _ _) = empty
+inlineToDocbook opts (Math t str)
+ | isMathML (writerHTMLMathMethod opts) =
+ case texMathToMathML dt str of
+ Right r -> inTagsSimple tagtype
+ $ text $ Xml.ppcElement conf
+ $ fixNS
+ $ removeAttr r
+ Left _ -> inlinesToDocbook opts
+ $ readTeXMath str
+ | otherwise = inlinesToDocbook opts $ readTeXMath str
+ where (dt, tagtype) = case t of
+ InlineMath -> (DisplayInline,"inlineequation")
+ DisplayMath -> (DisplayBlock,"informalequation")
+ conf = Xml.useShortEmptyTags (const False) Xml.defaultConfigPP
+ removeAttr e = e{ Xml.elAttribs = [] }
+ fixNS' qname = qname{ Xml.qPrefix = Just "mml" }
+ fixNS = everywhere (mkT fixNS')
+inlineToDocbook _ (RawInline f x) | f == "html" || f == "docbook" = text x
+ | otherwise = empty
inlineToDocbook _ LineBreak = inTagsSimple "literallayout" empty
inlineToDocbook _ Space = space
inlineToDocbook opts (Link txt (src, _)) =
@@ -280,3 +301,7 @@ inlineToDocbook _ (Image _ (src, tit)) =
titleDoc $$ selfClosingTag "imagedata" [("fileref", src)]
inlineToDocbook opts (Note contents) =
inTagsIndented "footnote" $ blocksToDocbook opts contents
+
+isMathML :: HTMLMathMethod -> Bool
+isMathML (MathML _) = True
+isMathML _ = False
diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
new file mode 100644
index 000000000..22278be7e
--- /dev/null
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -0,0 +1,666 @@
+{-
+Copyright (C) 2012 John MacFarlane <jgm@berkeley.edu>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+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.Writers.Docx
+ Copyright : Copyright (C) 2012 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm@berkeley.edu>
+ Stability : alpha
+ Portability : portable
+
+Conversion of 'Pandoc' documents to docx.
+-}
+module Text.Pandoc.Writers.Docx ( writeDocx ) where
+import Data.List ( intercalate )
+import System.FilePath ( (</>) )
+import qualified Data.ByteString.Lazy as B
+import qualified Data.Map as M
+import Data.ByteString.Lazy.UTF8 ( fromString, toString )
+import Text.Pandoc.UTF8 as UTF8
+import System.IO ( stderr )
+import Codec.Archive.Zip
+import Data.Time.Clock.POSIX
+import Paths_pandoc ( getDataFileName )
+import Text.Pandoc.Definition
+import Text.Pandoc.Generic
+import System.Directory
+import Text.Pandoc.ImageSize
+import Text.Pandoc.Shared hiding (Element)
+import Text.Pandoc.Readers.TeXMath
+import Text.Pandoc.Highlighting ( highlight )
+import Text.Highlighting.Kate.Types ()
+import Text.XML.Light
+import Text.TeXMath
+import Control.Monad.State
+import Text.Highlighting.Kate
+
+data WriterState = WriterState{
+ stTextProperties :: [Element]
+ , stParaProperties :: [Element]
+ , stFootnotes :: [Element]
+ , stSectionIds :: [String]
+ , stExternalLinks :: M.Map String String
+ , stImages :: M.Map FilePath (String, B.ByteString)
+ , stListLevel :: Int
+ , stListMarker :: ListMarker
+ , stNumStyles :: M.Map ListMarker Int
+ , stLists :: [ListMarker]
+ }
+
+data ListMarker = NoMarker
+ | BulletMarker
+ | NumberMarker ListNumberStyle ListNumberDelim Int
+ deriving (Show, Read, Eq, Ord)
+
+defaultWriterState :: WriterState
+defaultWriterState = WriterState{
+ stTextProperties = []
+ , stParaProperties = []
+ , stFootnotes = []
+ , stSectionIds = []
+ , stExternalLinks = M.empty
+ , stImages = M.empty
+ , stListLevel = -1
+ , stListMarker = NoMarker
+ , stNumStyles = M.fromList [(NoMarker, 0)]
+ , stLists = [NoMarker]
+ }
+
+type WS a = StateT WriterState IO a
+
+showTopElement' :: Element -> String
+showTopElement' x = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++ showElement x
+
+mknode :: Node t => String -> [(String,String)] -> t -> Element
+mknode s attrs =
+ add_attrs (map (\(k,v) -> Attr (unqual k) v) attrs) . node (unqual s)
+
+-- | Produce an Docx file from a Pandoc document.
+writeDocx :: Maybe FilePath -- ^ Path specified by --reference-docx
+ -> WriterOptions -- ^ Writer options
+ -> Pandoc -- ^ Document to convert
+ -> IO B.ByteString
+writeDocx mbRefDocx opts doc@(Pandoc (Meta tit auths date) _) = do
+ let datadir = writerUserDataDir opts
+ refArchive <- liftM toArchive $
+ case mbRefDocx of
+ Just f -> B.readFile f
+ Nothing -> do
+ let defaultDocx = getDataFileName "reference.docx" >>= B.readFile
+ case datadir of
+ Nothing -> defaultDocx
+ Just d -> do
+ exists <- doesFileExist (d </> "reference.docx")
+ if exists
+ then B.readFile (d </> "reference.docx")
+ else defaultDocx
+
+ (newContents, st) <- runStateT (writeOpenXML opts{writerWrapText = False} doc)
+ defaultWriterState
+ epochtime <- floor `fmap` getPOSIXTime
+ let imgs = M.elems $ stImages st
+ let imgPath ident img = "media/" ++ ident ++
+ case imageType img of
+ Just Png -> ".png"
+ Just Jpeg -> ".jpeg"
+ Just Gif -> ".gif"
+ Nothing -> ""
+ let toImgRel (ident,img) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",ident),("Target",imgPath ident img)] ()
+ let newrels = map toImgRel imgs
+ let relpath = "word/_rels/document.xml.rels"
+ let reldoc = case findEntryByPath relpath refArchive >>=
+ parseXMLDoc . toString . fromEntry of
+ Just d -> d
+ Nothing -> error $ relpath ++ "missing in reference docx"
+ let reldoc' = reldoc{ elContent = elContent reldoc ++ map Elem newrels }
+ -- create entries for images
+ let toImageEntry (ident,img) = toEntry ("word/" ++ imgPath ident img)
+ epochtime img
+ let imageEntries = map toImageEntry imgs
+ -- NOW get list of external links and images from this, and do what's needed
+ let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()
+ let newrels' = map toLinkRel $ M.toList $ stExternalLinks st
+ let reldoc'' = reldoc' { elContent = elContent reldoc' ++ map Elem newrels' }
+ let relEntry = toEntry relpath epochtime $ fromString $ showTopElement' reldoc''
+ let contentEntry = toEntry "word/document.xml" epochtime $ fromString $ showTopElement' newContents
+ -- styles
+ let newstyles = styleToOpenXml $ writerHighlightStyle opts
+ let stylepath = "word/styles.xml"
+ let styledoc = case findEntryByPath stylepath refArchive >>=
+ parseXMLDoc . toString . fromEntry of
+ Just d -> d
+ Nothing -> error $ stylepath ++ "missing in reference docx"
+ let styledoc' = styledoc{ elContent = elContent styledoc ++ map Elem newstyles }
+ let styleEntry = toEntry stylepath epochtime $ fromString $ showTopElement' styledoc'
+ -- construct word/numbering.xml
+ let numpath = "word/numbering.xml"
+ let numEntry = toEntry numpath epochtime $ fromString $ showTopElement'
+ $ mkNumbering (stNumStyles st) (stLists st)
+ let docPropsPath = "docProps/core.xml"
+ let docProps = mknode "cp:coreProperties"
+ [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")
+ ,("xmlns:dc","http://purl.org/dc/elements/1.1/")
+ ,("xmlns:dcterms","http://purl.org/dc/terms/")
+ ,("xmlns:dcmitype","http://purl.org/dc/dcmitype/")
+ ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]
+ $ mknode "dc:title" [] (stringify tit)
+ : mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")]
+ (maybe "" id $ normalizeDate $ stringify date)
+ : mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] () -- put current time here
+ : map (mknode "dc:creator" [] . stringify) auths
+ let docPropsEntry = toEntry docPropsPath epochtime $ fromString $ showTopElement' docProps
+ let relsPath = "_rels/.rels"
+ rels <- case findEntryByPath relsPath refArchive of
+ Just e -> return $ toString $ fromEntry e
+ Nothing -> err 57 "could not find .rels/_rels in reference docx"
+ -- fix .rels/_rels, which can get screwed up when reference.docx is edited by Word
+ let rels' = substitute "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"
+ "http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties"
+ rels
+ let relsEntry = toEntry relsPath epochtime $ fromString rels'
+ let archive = foldr addEntryToArchive refArchive $
+ relsEntry : contentEntry : relEntry : numEntry : styleEntry : docPropsEntry : imageEntries
+ return $ fromArchive archive
+
+styleToOpenXml :: Style -> [Element]
+styleToOpenXml style = parStyle : map toStyle alltoktypes
+ where alltoktypes = enumFromTo KeywordTok NormalTok
+ toStyle toktype = mknode "w:style" [("w:type","character"),
+ ("w:customStyle","1"),("w:styleId",show toktype)]
+ [ mknode "w:name" [("w:val",show toktype)] ()
+ , mknode "w:basedOn" [("w:val","VerbatimChar")] ()
+ , mknode "w:rPr" [] $
+ [ mknode "w:color" [("w:val",tokCol toktype)] ()
+ | tokCol toktype /= "auto" ] ++
+ [ mknode "w:shd" [("w:val","clear"),("w:fill",tokBg toktype)] ()
+ | tokBg toktype /= "auto" ] ++
+ [ mknode "w:b" [] () | tokFeature tokenBold toktype ] ++
+ [ mknode "w:i" [] () | tokFeature tokenItalic toktype ] ++
+ [ mknode "w:u" [] () | tokFeature tokenUnderline toktype ]
+ ]
+ tokStyles = tokenStyles style
+ tokFeature f toktype = maybe False f $ lookup toktype tokStyles
+ tokCol toktype = maybe "auto" (drop 1 . fromColor)
+ $ (tokenColor =<< lookup toktype tokStyles)
+ `mplus` defaultColor style
+ tokBg toktype = maybe "auto" (drop 1 . fromColor)
+ $ (tokenBackground =<< lookup toktype tokStyles)
+ `mplus` backgroundColor style
+ parStyle = mknode "w:style" [("w:type","paragraph"),
+ ("w:customStyle","1"),("w:styleId","SourceCode")]
+ [ mknode "w:name" [("w:val","Source Code")] ()
+ , mknode "w:basedOn" [("w:val","Normal")] ()
+ , mknode "w:link" [("w:val","VerbatimChar")] ()
+ , mknode "w:pPr" []
+ $ mknode "w:wordWrap" [("w:val","off")] ()
+ : ( maybe [] (\col -> [mknode "w:shd" [("w:val","clear"),("w:fill",drop 1 $ fromColor col)] ()])
+ $ backgroundColor style )
+ ]
+
+mkNumbering :: M.Map ListMarker Int -> [ListMarker] -> Element
+mkNumbering markers lists =
+ mknode "w:numbering" [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
+ $ map mkAbstractNum (M.toList markers)
+ ++ zipWith (mkNum markers) lists [1..(length lists)]
+
+mkNum :: M.Map ListMarker Int -> ListMarker -> Int -> Element
+mkNum markers marker numid =
+ mknode "w:num" [("w:numId",show numid)]
+ $ mknode "w:abstractNumId" [("w:val",show absnumid)] ()
+ : case marker of
+ NoMarker -> []
+ BulletMarker -> []
+ NumberMarker _ _ start ->
+ map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]
+ $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]
+ where absnumid = maybe 0 id $ M.lookup marker markers
+
+mkAbstractNum :: (ListMarker,Int) -> Element
+mkAbstractNum (marker,numid) =
+ mknode "w:abstractNum" [("w:abstractNumId",show numid)]
+ $ mknode "w:multiLevelType" [("w:val","multilevel")] ()
+ : map (mkLvl marker) [0..6]
+
+mkLvl :: ListMarker -> Int -> Element
+mkLvl marker lvl =
+ mknode "w:lvl" [("w:ilvl",show lvl)] $
+ [ mknode "w:start" [("w:val",start)] ()
+ | marker /= NoMarker && marker /= BulletMarker ] ++
+ [ mknode "w:numFmt" [("w:val",fmt)] ()
+ , mknode "w:lvlText" [("w:val",lvltxt)] ()
+ , mknode "w:lvlJc" [("w:val","left")] ()
+ , mknode "w:pPr" []
+ [ mknode "w:tabs" []
+ $ mknode "w:tab" [("w:val","num"),("w:pos",show $ lvl * step)] ()
+ , mknode "w:ind" [("w:left",show $ lvl * step + hang),("w:hanging",show hang)] ()
+ ]
+ ]
+ where (fmt, lvltxt, start) =
+ case marker of
+ NoMarker -> ("bullet"," ","1")
+ BulletMarker -> ("bullet",bulletFor lvl,"1")
+ NumberMarker st de n -> (styleFor st lvl
+ ,patternFor de ("%" ++ show (lvl + 1))
+ ,show n)
+ step = 720
+ hang = 480
+ bulletFor 0 = "\8226"
+ bulletFor 1 = "\9702"
+ bulletFor 2 = "\8227"
+ bulletFor 3 = "\8259"
+ bulletFor 4 = "\8226"
+ bulletFor 5 = "\9702"
+ bulletFor _ = "\8227"
+ styleFor UpperAlpha _ = "upperLetter"
+ styleFor LowerAlpha _ = "lowerLetter"
+ styleFor UpperRoman _ = "upperRoman"
+ styleFor LowerRoman _ = "lowerRoman"
+ styleFor Decimal _ = "decimal"
+ styleFor DefaultStyle 1 = "decimal"
+ styleFor DefaultStyle 2 = "lowerLetter"
+ styleFor DefaultStyle 3 = "lowerRoman"
+ styleFor DefaultStyle 4 = "decimal"
+ styleFor DefaultStyle 5 = "lowerLetter"
+ styleFor DefaultStyle 6 = "lowerRoman"
+ styleFor _ _ = "decimal"
+ patternFor OneParen s = s ++ ")"
+ patternFor TwoParens s = "(" ++ s ++ ")"
+ patternFor _ s = s ++ "."
+
+-- | Convert Pandoc document to string in OpenXML format.
+writeOpenXML :: WriterOptions -> Pandoc -> WS Element
+writeOpenXML opts (Pandoc (Meta tit auths dat) blocks) = do
+ title <- withParaProp (pStyle "Title") $ blocksToOpenXML opts [Para tit | not (null tit)]
+ authors <- withParaProp (pStyle "Authors") $ blocksToOpenXML opts
+ [Para (intercalate [LineBreak] auths) | not (null auths)]
+ date <- withParaProp (pStyle "Date") $ blocksToOpenXML opts [Para dat | not (null dat)]
+ let convertSpace (Str x : Space : Str y : xs) = Str (x ++ " " ++ y) : xs
+ convertSpace (Str x : Str y : xs) = Str (x ++ y) : xs
+ convertSpace xs = xs
+ let blocks' = bottomUp convertSpace $ blocks
+ doc <- blocksToOpenXML opts blocks'
+ notes' <- reverse `fmap` gets stFootnotes
+ let notes = case notes' of
+ [] -> []
+ ns -> [mknode "w:footnotes" [] ns]
+ let meta = title ++ authors ++ date
+ return $ mknode "w:document"
+ [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")
+ ,("xmlns:m","http://schemas.openxmlformats.org/officeDocument/2006/math")
+ ,("xmlns:r","http://schemas.openxmlformats.org/officeDocument/2006/relationships")
+ ,("xmlns:o","urn:schemas-microsoft-com:office:office")
+ ,("xmlns:v","urn:schemas-microsoft-com:vml")
+ ,("xmlns:w10","urn:schemas-microsoft-com:office:word")
+ ,("xmlns:a","http://schemas.openxmlformats.org/drawingml/2006/main")
+ ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")
+ ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]
+ $ mknode "w:body" [] (meta ++ doc ++ notes)
+
+-- | Convert a list of Pandoc blocks to OpenXML.
+blocksToOpenXML :: WriterOptions -> [Block] -> WS [Element]
+blocksToOpenXML opts bls = concat `fmap` mapM (blockToOpenXML opts) bls
+
+pStyle :: String -> Element
+pStyle sty = mknode "w:pStyle" [("w:val",sty)] ()
+
+rStyle :: String -> Element
+rStyle sty = mknode "w:rStyle" [("w:val",sty)] ()
+
+-- | Convert a Pandoc block element to OpenXML.
+blockToOpenXML :: WriterOptions -> Block -> WS [Element]
+blockToOpenXML _ Null = return []
+blockToOpenXML opts (Header lev lst) = do
+ contents <- withParaProp (pStyle $ "Heading" ++ show lev) $
+ blockToOpenXML opts (Para lst)
+ usedIdents <- gets stSectionIds
+ let ident = uniqueIdent lst usedIdents
+ modify $ \s -> s{ stSectionIds = ident : stSectionIds s }
+ let bookmarkStart = mknode "w:bookmarkStart" [("w:id",ident)
+ ,("w:name",ident)] ()
+ let bookmarkEnd = mknode "w:bookmarkEnd" [("w:id",ident)] ()
+ return $ [bookmarkStart] ++ contents ++ [bookmarkEnd]
+blockToOpenXML opts (Plain lst) = blockToOpenXML opts (Para lst)
+blockToOpenXML opts (Para x@[Image alt _]) = do
+ paraProps <- getParaProps
+ contents <- inlinesToOpenXML opts x
+ captionNode <- withParaProp (pStyle "ImageCaption")
+ $ blockToOpenXML opts (Para alt)
+ return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
+blockToOpenXML opts (Para lst) = do
+ paraProps <- getParaProps
+ contents <- inlinesToOpenXML opts lst
+ return [mknode "w:p" [] (paraProps ++ contents)]
+blockToOpenXML _ (RawBlock format str)
+ | format == "openxml" = return [ x | Elem x <- parseXML str ]
+ | otherwise = return []
+blockToOpenXML opts (BlockQuote blocks) =
+ withParaProp (pStyle "BlockQuote") $ blocksToOpenXML opts blocks
+blockToOpenXML opts (CodeBlock attrs str) =
+ withParaProp (pStyle "SourceCode") $ blockToOpenXML opts $ Para [Code attrs str]
+blockToOpenXML _ HorizontalRule = return [
+ mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" []
+ $ mknode "v:rect" [("style","width:0;height:1.5pt"),
+ ("o:hralign","center"),
+ ("o:hrstd","t"),("o:hr","t")] () ]
+blockToOpenXML opts (Table caption aligns widths headers rows) = do
+ let captionStr = stringify caption
+ caption' <- if null caption
+ then return []
+ else withParaProp (pStyle "TableCaption")
+ $ blockToOpenXML opts (Para caption)
+ let alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()
+ let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)
+ $ blocksToOpenXML opts cell
+ headers' <- mapM cellToOpenXML $ zip aligns headers
+ rows' <- mapM (\cells -> mapM cellToOpenXML $ zip aligns cells)
+ $ rows
+ let borderProps = mknode "w:tcPr" []
+ [ mknode "w:tcBorders" []
+ $ mknode "w:bottom" [("w:val","single")] ()
+ , mknode "w:vAlign" [("w:val","bottom")] () ]
+ let mkcell border contents = mknode "w:tc" []
+ $ [ borderProps | border ] ++
+ if null contents
+ then [mknode "w:p" [] ()]
+ else contents
+ let mkrow border cells = mknode "w:tr" [] $ map (mkcell border) cells
+ let textwidth = 7920 -- 5.5 in in twips, 1/20 pt
+ let mkgridcol w = mknode "w:gridCol"
+ [("w:w", show $ (floor (textwidth * w) :: Integer))] ()
+ return $
+ [ mknode "w:tbl" []
+ ( mknode "w:tblPr" []
+ [ mknode "w:tblCaption" [("w:val", captionStr)] ()
+ | not (null caption) ]
+ : mknode "w:tblGrid" []
+ (if all (==0) widths
+ then []
+ else map mkgridcol widths)
+ : [ mkrow True headers' | not (all null headers) ] ++
+ map (mkrow False) rows'
+ )
+ ] ++ caption'
+blockToOpenXML opts (BulletList lst) = do
+ let marker = BulletMarker
+ addList marker
+ asList $ concat `fmap` mapM (listItemToOpenXML opts marker) lst
+blockToOpenXML opts (OrderedList (start, numstyle, numdelim) lst) = do
+ let marker = NumberMarker numstyle numdelim start
+ addList marker
+ asList $ concat `fmap` mapM (listItemToOpenXML opts marker) lst
+blockToOpenXML opts (DefinitionList items) =
+ concat `fmap` mapM (definitionListItemToOpenXML opts) items
+
+definitionListItemToOpenXML :: WriterOptions -> ([Inline],[[Block]]) -> WS [Element]
+definitionListItemToOpenXML opts (term,defs) = do
+ term' <- withParaProp (pStyle "DefinitionTerm")
+ $ blockToOpenXML opts (Para term)
+ defs' <- withParaProp (pStyle "Definition")
+ $ concat `fmap` mapM (blocksToOpenXML opts) defs
+ return $ term' ++ defs'
+
+getNumId :: WS Int
+getNumId = length `fmap` gets stLists
+
+addList :: ListMarker -> WS ()
+addList marker = do
+ lists <- gets stLists
+ modify $ \st -> st{ stLists = lists ++ [marker] }
+ numStyles <- gets stNumStyles
+ case M.lookup marker numStyles of
+ Just _ -> return ()
+ Nothing -> modify $ \st ->
+ st{ stNumStyles = M.insert marker (M.size numStyles + 1) numStyles }
+
+listItemToOpenXML :: WriterOptions -> ListMarker -> [Block] -> WS [Element]
+listItemToOpenXML _ _ [] = return []
+listItemToOpenXML opts marker (first:rest) = do
+ first' <- withMarker marker $ blockToOpenXML opts first
+ rest' <- withMarker NoMarker $ blocksToOpenXML opts rest
+ return $ first' ++ rest'
+
+alignmentToString :: Alignment -> [Char]
+alignmentToString alignment = case alignment of
+ AlignLeft -> "left"
+ AlignRight -> "right"
+ AlignCenter -> "center"
+ AlignDefault -> "left"
+
+-- | Convert a list of inline elements to OpenXML.
+inlinesToOpenXML :: WriterOptions -> [Inline] -> WS [Element]
+inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst
+
+withMarker :: ListMarker -> WS a -> WS a
+withMarker m p = do
+ origMarker <- gets stListMarker
+ modify $ \st -> st{ stListMarker = m }
+ result <- p
+ modify $ \st -> st{ stListMarker = origMarker }
+ return result
+
+asList :: WS a -> WS a
+asList p = do
+ origListLevel <- gets stListLevel
+ modify $ \st -> st{ stListLevel = stListLevel st + 1 }
+ result <- p
+ modify $ \st -> st{ stListLevel = origListLevel }
+ return result
+
+getTextProps :: WS [Element]
+getTextProps = do
+ props <- gets stTextProperties
+ return $ if null props
+ then []
+ else [mknode "w:rPr" [] $ props]
+
+pushTextProp :: Element -> WS ()
+pushTextProp d = modify $ \s -> s{ stTextProperties = d : stTextProperties s }
+
+popTextProp :: WS ()
+popTextProp = modify $ \s -> s{ stTextProperties = drop 1 $ stTextProperties s }
+
+withTextProp :: Element -> WS a -> WS a
+withTextProp d p = do
+ pushTextProp d
+ res <- p
+ popTextProp
+ return res
+
+getParaProps :: WS [Element]
+getParaProps = do
+ props <- gets stParaProperties
+ listLevel <- gets stListLevel
+ numid <- getNumId
+ let listPr = if listLevel >= 0
+ then [ mknode "w:numPr" []
+ [ mknode "w:numId" [("w:val",show numid)] ()
+ , mknode "w:ilvl" [("w:val",show listLevel)] () ]
+ ]
+ else []
+ return $ case props ++ listPr of
+ [] -> []
+ ps -> [mknode "w:pPr" [] ps]
+
+pushParaProp :: Element -> WS ()
+pushParaProp d = modify $ \s -> s{ stParaProperties = d : stParaProperties s }
+
+popParaProp :: WS ()
+popParaProp = modify $ \s -> s{ stParaProperties = drop 1 $ stParaProperties s }
+
+withParaProp :: Element -> WS a -> WS a
+withParaProp d p = do
+ pushParaProp d
+ res <- p
+ popParaProp
+ return res
+
+formattedString :: String -> WS [Element]
+formattedString str = do
+ props <- getTextProps
+ return [ mknode "w:r" [] $
+ props ++
+ [ mknode "w:t" [("xml:space","preserve")] str ] ]
+
+-- | Convert an inline element to OpenXML.
+inlineToOpenXML :: WriterOptions -> Inline -> WS [Element]
+inlineToOpenXML _ (Str str) = formattedString str
+inlineToOpenXML opts Space = inlineToOpenXML opts (Str " ")
+inlineToOpenXML opts (Strong lst) =
+ withTextProp (mknode "w:b" [] ()) $ inlinesToOpenXML opts lst
+inlineToOpenXML opts (Emph lst) =
+ withTextProp (mknode "w:i" [] ()) $ inlinesToOpenXML opts lst
+inlineToOpenXML opts (Subscript lst) =
+ withTextProp (mknode "w:vertAlign" [("w:val","subscript")] ())
+ $ inlinesToOpenXML opts lst
+inlineToOpenXML opts (Superscript lst) =
+ withTextProp (mknode "w:vertAlign" [("w:val","superscript")] ())
+ $ inlinesToOpenXML opts lst
+inlineToOpenXML opts (SmallCaps lst) =
+ withTextProp (mknode "w:smallCaps" [] ())
+ $ inlinesToOpenXML opts lst
+inlineToOpenXML opts (Strikeout lst) =
+ withTextProp (mknode "w:strike" [] ())
+ $ inlinesToOpenXML opts lst
+inlineToOpenXML _ LineBreak = return [ mknode "w:br" [] () ]
+inlineToOpenXML _ (RawInline f str)
+ | f == "openxml" = return [ x | Elem x <- parseXML str ]
+ | otherwise = return []
+inlineToOpenXML opts (Quoted quoteType lst) =
+ inlinesToOpenXML opts $ [Str open] ++ lst ++ [Str close]
+ where (open, close) = case quoteType of
+ SingleQuote -> ("\x2018", "\x2019")
+ DoubleQuote -> ("\x201C", "\x201D")
+inlineToOpenXML opts (Math InlineMath str) =
+ case texMathToOMML DisplayInline str of
+ Right r -> return [r]
+ Left _ -> inlinesToOpenXML opts (readTeXMath str)
+inlineToOpenXML opts (Math DisplayMath str) =
+ case texMathToOMML DisplayBlock str of
+ Right r -> return [br, r, br]
+ Left _ -> do
+ fallback <- inlinesToOpenXML opts (readTeXMath str)
+ return $ [br] ++ fallback ++ [br]
+ where br = mknode "w:br" [] ()
+inlineToOpenXML opts (Cite _ lst) = inlinesToOpenXML opts lst
+inlineToOpenXML _ (Code attrs str) =
+ withTextProp (rStyle "VerbatimChar")
+ $ case highlight formatOpenXML attrs str of
+ Nothing -> intercalate [mknode "w:br" [] ()]
+ `fmap` (mapM formattedString $ lines str)
+ Just h -> return h
+ where formatOpenXML _fmtOpts = intercalate [mknode "w:br" [] ()] .
+ map (map toHlTok)
+ toHlTok (toktype,tok) = mknode "w:r" []
+ [ mknode "w:rPr" []
+ [ rStyle $ show toktype ]
+ , mknode "w:t" [("xml:space","preserve")] tok ]
+inlineToOpenXML opts (Note bs) = do
+ notes <- gets stFootnotes
+ let notenum = length notes + 1
+ let notemarker = mknode "w:r" []
+ [ mknode "w:rPr" [] (rStyle "FootnoteReference")
+ , mknode "w:footnoteRef" [] () ]
+ let notemarkerXml = RawInline "openxml" $ ppElement notemarker
+ let insertNoteRef (Plain ils : xs) = Plain (notemarkerXml : ils) : xs
+ insertNoteRef (Para ils : xs) = Para (notemarkerXml : ils) : xs
+ insertNoteRef xs = Para [notemarkerXml] : xs
+ oldListLevel <- gets stListLevel
+ oldParaProperties <- gets stParaProperties
+ oldTextProperties <- gets stTextProperties
+ modify $ \st -> st{ stListLevel = -1, stParaProperties = [], stTextProperties = [] }
+ contents <- withParaProp (pStyle "FootnoteText") $ blocksToOpenXML opts
+ $ insertNoteRef bs
+ modify $ \st -> st{ stListLevel = oldListLevel, stParaProperties = oldParaProperties,
+ stTextProperties = oldTextProperties }
+ let newnote = mknode "w:footnote" [("w:id",show notenum)] $ contents
+ modify $ \s -> s{ stFootnotes = newnote : notes }
+ return [ mknode "w:r" []
+ [ mknode "w:rPr" [] (rStyle "FootnoteReference")
+ , mknode "w:footnoteReference" [("w:id", show notenum)] () ] ]
+-- internal link:
+inlineToOpenXML opts (Link txt ('#':xs,_)) = do
+ contents <- withTextProp (rStyle "Hyperlink") $ inlinesToOpenXML opts txt
+ return [ mknode "w:hyperlink" [("w:anchor",xs)] contents ]
+-- external link:
+inlineToOpenXML opts (Link txt (src,_)) = do
+ contents <- withTextProp (rStyle "Hyperlink") $ inlinesToOpenXML opts txt
+ extlinks <- gets stExternalLinks
+ ind <- case M.lookup src extlinks of
+ Just i -> return i
+ Nothing -> do
+ let i = "link" ++ show (M.size extlinks)
+ modify $ \st -> st{ stExternalLinks =
+ M.insert src i extlinks }
+ return i
+ return [ mknode "w:hyperlink" [("r:id",ind)] contents ]
+inlineToOpenXML opts (Image alt (src, tit)) = do
+ exists <- liftIO $ doesFileExist src
+ if exists
+ then do
+ imgs <- gets stImages
+ (ident,size) <- case M.lookup src imgs of
+ Just (i,img) -> return (i, imageSize img)
+ Nothing -> do
+ img <- liftIO $ B.readFile src
+ let ident' = "image" ++ show (M.size imgs + 1)
+ let size' = imageSize img
+ modify $ \st -> st{
+ stImages = M.insert src (ident',img) $ stImages st }
+ return (ident',size')
+ let (xpt,ypt) = maybe (120,120) sizeInPoints size
+ -- 12700 emu = 1 pt
+ let (xemu,yemu) = (xpt * 12700, ypt * 12700)
+ let cNvPicPr = mknode "pic:cNvPicPr" [] $
+ mknode "a:picLocks" [("noChangeArrowheads","1"),("noChangeAspect","1")] ()
+ let nvPicPr = mknode "pic:nvPicPr" []
+ [ mknode "pic:cNvPr"
+ [("descr",src),("id","0"),("name","Picture")] ()
+ , cNvPicPr ]
+ let blipFill = mknode "pic:blipFill" []
+ [ mknode "a:blip" [("r:embed",ident)] ()
+ , mknode "a:stretch" [] $ mknode "a:fillRect" [] () ]
+ let xfrm = mknode "a:xfrm" []
+ [ mknode "a:off" [("x","0"),("y","0")] ()
+ , mknode "a:ext" [("cx",show xemu),("cy",show yemu)] () ]
+ let prstGeom = mknode "a:prstGeom" [("prst","rect")] $
+ mknode "a:avLst" [] ()
+ let ln = mknode "a:ln" [("w","9525")]
+ [ mknode "a:noFill" [] ()
+ , mknode "a:headEnd" [] ()
+ , mknode "a:tailEnd" [] () ]
+ let spPr = mknode "pic:spPr" [("bwMode","auto")]
+ [xfrm, prstGeom, mknode "a:noFill" [] (), ln]
+ let graphic = mknode "a:graphic" [] $
+ mknode "a:graphicData" [("uri","http://schemas.openxmlformats.org/drawingml/2006/picture")]
+ [ mknode "pic:pic" []
+ [ nvPicPr
+ , blipFill
+ , spPr ] ]
+ return [ mknode "w:r" [] $
+ mknode "w:drawing" [] $
+ 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",tit),("id","1"),("name","Picture")] ()
+ , graphic ] ]
+ else do
+ liftIO $ UTF8.hPutStrLn stderr $
+ "Could not find image `" ++ src ++ "', skipping..."
+ inlinesToOpenXML opts alt
diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs
index 9fc393fed..67048348e 100644
--- a/src/Text/Pandoc/Writers/EPUB.hs
+++ b/src/Text/Pandoc/Writers/EPUB.hs
@@ -32,30 +32,31 @@ import Data.IORef
import Data.Maybe ( fromMaybe, isNothing )
import Data.List ( findIndices, isPrefixOf )
import System.Environment ( getEnv )
-import System.FilePath ( (</>), takeBaseName, takeExtension )
+import System.FilePath ( (</>), (<.>), takeBaseName, takeExtension, takeFileName )
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.UTF8 ( fromString )
import Codec.Archive.Zip
-import System.Time
+import Data.Time.Clock.POSIX
import Text.Pandoc.Shared hiding ( Element )
import Text.Pandoc.Definition
import Text.Pandoc.Generic
-import Control.Monad (liftM)
+import Control.Monad.State
import Text.XML.Light hiding (ppTopElement)
import Text.Pandoc.UUID
import Text.Pandoc.Writers.HTML
import Text.Pandoc.Writers.Markdown ( writePlain )
import Data.Char ( toLower )
-import System.Directory ( copyFile )
import Network.URI ( unEscapeString )
+import Text.Pandoc.MIME (getMimeType)
-- | Produce an EPUB file from a Pandoc document.
writeEPUB :: Maybe String -- ^ EPUB stylesheet specified at command line
+ -> [FilePath] -- ^ Paths to fonts to embed
-> WriterOptions -- ^ Writer options
-> Pandoc -- ^ Document to convert
-> IO B.ByteString
-writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
- (TOD epochtime _) <- getClockTime
+writeEPUB mbStylesheet fonts opts doc@(Pandoc meta _) = do
+ epochtime <- floor `fmap` getPOSIXTime
let mkEntry path content = toEntry path epochtime content
let opts' = opts{ writerEmailObfuscation = NoObfuscation
, writerStandalone = True
@@ -64,17 +65,24 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
let vars = writerVariables opts'
let mbCoverImage = lookup "epub-cover-image" vars
+ titlePageTemplate <- readDataFile (writerUserDataDir opts)
+ $ "templates" </> "epub-titlepage" <.> "html"
+
+ coverImageTemplate <- readDataFile (writerUserDataDir opts)
+ $ "templates" </> "epub-coverimage" <.> "html"
+
+ pageTemplate <- readDataFile (writerUserDataDir opts)
+ $ "templates" </> "epub-page" <.> "html"
+
-- cover page
(cpgEntry, cpicEntry) <-
case mbCoverImage of
Nothing -> return ([],[])
Just img -> do
let coverImage = "cover-image" ++ takeExtension img
- copyFile img coverImage
let cpContent = fromString $ writeHtmlString
- opts'{writerTemplate = pageTemplate
- ,writerVariables =
- ("coverimage",coverImage):vars}
+ opts'{writerTemplate = coverImageTemplate,
+ writerVariables = ("coverimage",coverImage):vars}
(Pandoc meta [])
imgContent <- B.readFile img
return ( [mkEntry "cover.xhtml" cpContent]
@@ -82,37 +90,47 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
-- title page
let tpContent = fromString $ writeHtmlString
- opts'{writerTemplate = pageTemplate
- ,writerVariables = ("titlepage","yes"):vars}
+ opts'{writerTemplate = titlePageTemplate}
(Pandoc meta [])
let tpEntry = mkEntry "title_page.xhtml" tpContent
-- handle pictures
picsRef <- newIORef []
- Pandoc _ blocks <- liftM (bottomUp transformBlock) $ bottomUpM
+ Pandoc _ blocks <- bottomUpM
(transformInlines (writerHTMLMathMethod opts) sourceDir picsRef) doc
pics <- readIORef picsRef
let readPicEntry (oldsrc, newsrc) = readEntry [] oldsrc >>= \e ->
return e{ eRelativePath = newsrc }
picEntries <- mapM readPicEntry pics
+ -- handle fonts
+ let mkFontEntry f = mkEntry (takeFileName f) `fmap` B.readFile f
+ fontEntries <- mapM mkFontEntry fonts
+
-- body pages
let isH1 (Header 1 _) = True
isH1 _ = False
- let h1Indices = dropWhile (== 0) $ findIndices isH1 blocks
- let chunks = splitByIndices h1Indices blocks
+ -- internal reference IDs change when we chunk the file,
+ -- so the next two lines fix that:
+ let reftable = correlateRefs blocks
+ let blocks' = replaceRefs reftable blocks
+ let h1Indices = dropWhile (== 0) $ findIndices isH1 blocks'
+ let chunks = splitByIndices h1Indices blocks'
let titleize (Header 1 xs : ys) = Pandoc meta{docTitle = xs} ys
titleize xs = Pandoc meta xs
- let chapToHtml = writeHtmlString opts'{ writerTemplate = pageTemplate }
let chapters = map titleize chunks
+ let chapToHtml = writeHtmlString opts'{ writerTemplate = pageTemplate }
let chapterToEntry :: Int -> Pandoc -> Entry
chapterToEntry num chap = mkEntry ("ch" ++ show num ++ ".xhtml") $
fromString $ chapToHtml chap
let chapterEntries = zipWith chapterToEntry [1..] chapters
-- contents.opf
- lang <- catch (liftM (takeWhile (/='.')) $ getEnv "lang")
- (\_ -> return "en-US")
+ localeLang <- catch (liftM (takeWhile (/='.')) $ getEnv "LANG")
+ (\_ -> return "en-US")
+ let lang = case lookup "lang" (writerVariables opts') of
+ Just x -> x
+ Nothing -> localeLang
uuid <- getRandomUUID
let chapterNode ent = unode "item" !
[("id", takeBaseName $ eRelativePath ent),
@@ -125,17 +143,22 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
("href", eRelativePath ent),
("media-type", fromMaybe "application/octet-stream"
$ imageTypeOf $ eRelativePath ent)] $ ()
+ let fontNode ent = unode "item" !
+ [("id", takeBaseName $ eRelativePath ent),
+ ("href", eRelativePath ent),
+ ("media-type", maybe "" id $ getMimeType $ eRelativePath ent)] $ ()
let plainify t = removeTrailingSpace $
writePlain opts'{ writerStandalone = False } $
Pandoc meta [Plain t]
let plainTitle = plainify $ docTitle meta
let plainAuthors = map plainify $ docAuthors meta
+ let plainDate = maybe "" id $ normalizeDate $ stringify $ docDate meta
let contentsData = fromString $ ppTopElement $
unode "package" ! [("version","2.0")
,("xmlns","http://www.idpf.org/2007/opf")
,("unique-identifier","BookId")] $
[ metadataElement (writerEPUBMetadata opts')
- uuid lang plainTitle plainAuthors mbCoverImage
+ uuid lang plainTitle plainAuthors plainDate mbCoverImage
, unode "manifest" $
[ unode "item" ! [("id","ncx"), ("href","toc.ncx")
,("media-type","application/x-dtbncx+xml")] $ ()
@@ -143,7 +166,8 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
,("media-type","text/css")] $ ()
] ++
map chapterNode (cpgEntry ++ (tpEntry : chapterEntries)) ++
- map pictureNode (cpicEntry ++ picEntries)
+ map pictureNode (cpicEntry ++ picEntries) ++
+ map fontNode fontEntries
, unode "spine" ! [("toc","ncx")] $
case mbCoverImage of
Nothing -> []
@@ -197,6 +221,13 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
,("media-type","application/oebps-package+xml")] $ ()
let containerEntry = mkEntry "META-INF/container.xml" containerData
+ -- com.apple.ibooks.display-options.xml
+ let apple = fromString $ ppTopElement $
+ unode "display_options" $
+ unode "platform" ! [("name","*")] $
+ unode "option" ! [("name","specified-fonts")] $ "true"
+ let appleEntry = mkEntry "META-INF/com.apple.ibooks.display-options.xml" apple
+
-- stylesheet
stylesheet <- case mbStylesheet of
Just s -> return s
@@ -205,13 +236,13 @@ writeEPUB mbStylesheet opts doc@(Pandoc meta _) = do
-- construct archive
let archive = foldr addEntryToArchive emptyArchive
- (mimetypeEntry : containerEntry : stylesheetEntry : tpEntry :
+ (mimetypeEntry : containerEntry : appleEntry : stylesheetEntry : tpEntry :
contentsEntry : tocEntry :
- (picEntries ++ cpicEntry ++ cpgEntry ++ chapterEntries) )
+ (picEntries ++ cpicEntry ++ cpgEntry ++ chapterEntries ++ fontEntries) )
return $ fromArchive archive
-metadataElement :: String -> UUID -> String -> String -> [String] -> Maybe a -> Element
-metadataElement metadataXML uuid lang title authors mbCoverImage =
+metadataElement :: String -> UUID -> String -> String -> [String] -> String -> Maybe a -> Element
+metadataElement metadataXML uuid lang title authors date mbCoverImage =
let userNodes = parseXML metadataXML
elt = unode "metadata" ! [("xmlns:dc","http://purl.org/dc/elements/1.1/")
,("xmlns:opf","http://www.idpf.org/2007/opf")] $
@@ -227,6 +258,7 @@ metadataElement metadataXML uuid lang title authors mbCoverImage =
[ unode "dc:identifier" ! [("id","BookId")] $ show uuid |
not (elt `contains` "identifier") ] ++
[ unode "dc:creator" ! [("opf:role","aut")] $ a | a <- authors ] ++
+ [ unode "dc:date" date | not (elt `contains` "date") ] ++
[ unode "meta" ! [("name","cover"), ("content","cover-image")] $ () |
not (isNothing mbCoverImage) ]
in elt{ elContent = elContent elt ++ map Elem newNodes }
@@ -263,20 +295,24 @@ transformInlines (MathML _) _ _ (x@(Math _ _) : xs) = do
"</ops:switch>"
result = if "<math" `isPrefixOf` mathml then inOps else mathml
return $ RawInline "html" result : xs
-transformInlines _ _ _ (RawInline _ _ : xs) = return $ Str "" : xs
-transformInlines _ _ _ (Link lab (_,_) : xs) = return $ lab ++ xs
transformInlines _ _ _ xs = return xs
-transformBlock :: Block -> Block
-transformBlock (RawBlock _ _) = Null
-transformBlock x = x
-
(!) :: Node t => (t -> Element) -> [(String, String)] -> t -> Element
(!) f attrs n = add_attrs (map (\(k,v) -> Attr (unqual k) v) attrs) (f n)
-- | Version of 'ppTopElement' that specifies UTF-8 encoding.
ppTopElement :: Element -> String
-ppTopElement = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++) . ppElement
+ppTopElement = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ++) . unEntity . ppElement
+ -- unEntity removes numeric entities introduced by ppElement
+ -- (kindlegen seems to choke on these).
+ where unEntity [] = ""
+ unEntity ('&':'#':xs) =
+ let (ds,ys) = break (==';') xs
+ rest = drop 1 ys
+ in case reads ('\'':'\\':ds ++ "'") of
+ ((x,_):_) -> x : unEntity rest
+ _ -> '&':'#':unEntity xs
+ unEntity (x:xs) = x : unEntity xs
imageTypeOf :: FilePath -> Maybe String
imageTypeOf x = case drop 1 (map toLower (takeExtension x)) of
@@ -288,38 +324,49 @@ imageTypeOf x = case drop 1 (map toLower (takeExtension x)) of
"svg" -> Just "image/svg+xml"
_ -> Nothing
-pageTemplate :: String
-pageTemplate = unlines
- [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- , "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"
- , "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
- , "<head>"
- , "<title>$title$</title>"
- , "$if(coverimage)$"
- , "<style type=\"text/css\">img{ max-width: 100%; }</style>"
- , "$endif$"
- , "<link href=\"stylesheet.css\" type=\"text/css\" rel=\"stylesheet\" />"
- , "</head>"
- , "<body>"
- , "$if(coverimage)$"
- , "<div id=\"cover-image\">"
- , "<img src=\"$coverimage$\" alt=\"$title$\" />"
- , "</div>"
- , "$else$"
- , "$if(titlepage)$"
- , "<h1 class=\"title\">$title$</h1>"
- , "$for(author)$"
- , "<h2 class=\"author\">$author$</h2>"
- , "$endfor$"
- , "$else$"
- , "<h1>$title$</h1>"
- , "$if(toc)$"
- , "$toc$"
- , "$endif$"
- , "$endif$"
- , "$body$"
- , "$endif$"
- , "</body>"
- , "</html>"
- ]
+data IdentState = IdentState{
+ chapterNumber :: Int,
+ runningIdents :: [String],
+ chapterIdents :: [String],
+ identTable :: [(String,String)]
+ } deriving (Read, Show)
+
+-- Go through a block list and construct a table
+-- correlating the automatically constructed references
+-- that would be used in a normal pandoc document with
+-- new URLs to be used in the EPUB. For example, what
+-- was "header-1" might turn into "ch6.xhtml#header".
+correlateRefs :: [Block] -> [(String,String)]
+correlateRefs bs = identTable $ execState (mapM_ go bs)
+ IdentState{ chapterNumber = 0
+ , runningIdents = []
+ , chapterIdents = []
+ , identTable = [] }
+ where go :: Block -> State IdentState ()
+ go (Header n ils) = do
+ when (n == 1) $
+ modify $ \s -> s{ chapterNumber = chapterNumber s + 1
+ , chapterIdents = [] }
+ st <- get
+ let runningid = uniqueIdent ils (runningIdents st)
+ let chapid = if n == 1
+ then Nothing
+ else Just $ uniqueIdent ils (chapterIdents st)
+ modify $ \s -> s{ runningIdents = runningid : runningIdents st
+ , chapterIdents = maybe (chapterIdents st)
+ (: chapterIdents st) chapid
+ , identTable = (runningid, "ch" ++ show (chapterNumber st) ++
+ ".xhtml" ++ maybe "" ('#':) chapid) : identTable st
+ }
+ go _ = return ()
+
+-- Replace internal link references using the table produced
+-- by correlateRefs.
+replaceRefs :: [(String,String)] -> [Block] -> [Block]
+replaceRefs refTable = bottomUp replaceOneRef
+ where replaceOneRef x@(Link lab ('#':xs,tit)) =
+ case lookup xs refTable of
+ Just url -> Link lab (url,tit)
+ Nothing -> x
+ replaceOneRef x = x
diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs
index 573adbf4a..f35b29370 100644
--- a/src/Text/Pandoc/Writers/HTML.hs
+++ b/src/Text/Pandoc/Writers/HTML.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-deprecations #-}
{-
Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
@@ -30,168 +31,186 @@ Conversion of 'Pandoc' documents to HTML.
-}
module Text.Pandoc.Writers.HTML ( writeHtml , writeHtmlString ) where
import Text.Pandoc.Definition
-import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
import Text.Pandoc.Shared
import Text.Pandoc.Templates
+import Text.Pandoc.Generic
import Text.Pandoc.Readers.TeXMath
-import Text.Pandoc.Highlighting ( highlightHtml, defaultHighlightingCss )
-import Text.Pandoc.XML (stripTags, escapeStringForXML)
+import Text.Pandoc.Slides
+import Text.Pandoc.Highlighting ( highlight, styleToCss,
+ formatHtmlInline, formatHtmlBlock )
+import Text.Pandoc.XML (stripTags, escapeStringForXML, fromEntities)
import Network.HTTP ( urlEncode )
import Numeric ( showHex )
import Data.Char ( ord, toLower )
import Data.List ( isPrefixOf, intersperse )
+import Data.String ( fromString )
import Data.Maybe ( catMaybes )
import Control.Monad.State
-import Text.XHtml.Transitional hiding ( stringToHtml, unordList, ordList )
-import qualified Text.XHtml.Transitional as XHtml
+import Text.Blaze
+import qualified Text.Blaze.Html5 as H5
+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.TeXMath
import Text.XML.Light.Output
import System.FilePath (takeExtension)
+import Data.Monoid (mempty, mconcat)
data WriterState = WriterState
{ stNotes :: [Html] -- ^ List of notes
, stMath :: Bool -- ^ Math is used in document
, stHighlighting :: Bool -- ^ Syntax highlighting is used
, stSecNum :: [Int] -- ^ Number of current section
- } deriving Show
+ }
defaultWriterState :: WriterState
defaultWriterState = WriterState {stNotes= [], stMath = False, stHighlighting = False, stSecNum = []}
-- Helpers to render HTML with the appropriate function.
--- | Modified version of Text.XHtml's stringToHtml.
--- Use unicode characters wherever possible.
-stringToHtml :: WriterOptions -> String -> Html
-stringToHtml opts = if writerAscii opts
- then XHtml.stringToHtml
- else primHtml . escapeStringForXML
+strToHtml :: String -> Html
+strToHtml = preEscapedString . escapeStringForXML
+-- strToHtml = toHtml
-- | Hard linebreak.
nl :: WriterOptions -> Html
nl opts = if writerWrapText opts
- then primHtml "\n"
- else noHtml
+ then preEscapedString "\n"
+ else mempty
-- | Convert Pandoc document to Html string.
writeHtmlString :: WriterOptions -> Pandoc -> String
writeHtmlString opts d =
- let (tit, auths, date, toc, body', newvars) = evalState (pandocToHtml opts d)
- defaultWriterState
+ let (tit, auths, authsMeta, date, toc, body', newvars) = evalState (pandocToHtml opts d)
+ defaultWriterState
in if writerStandalone opts
- then inTemplate opts tit auths date toc body' newvars
- else dropWhile (=='\n') $ showHtmlFragment body'
+ then inTemplate opts tit auths authsMeta date toc body' newvars
+ else renderHtml body'
-- | Convert Pandoc document to Html structure.
writeHtml :: WriterOptions -> Pandoc -> Html
writeHtml opts d =
- let (tit, auths, date, toc, body', newvars) = evalState (pandocToHtml opts d)
- defaultWriterState
+ let (tit, auths, authsMeta, date, toc, body', newvars) = evalState (pandocToHtml opts d)
+ defaultWriterState
in if writerStandalone opts
- then inTemplate opts tit auths date toc body' newvars
+ then inTemplate opts tit auths authsMeta date toc body' newvars
else body'
-- result is (title, authors, date, toc, body, new variables)
pandocToHtml :: WriterOptions
-> Pandoc
- -> State WriterState (Html, [Html], Html, Maybe Html, Html, [(String,String)])
+ -> State WriterState (Html, [Html], [Html], Html, Maybe Html, Html, [(String,String)])
pandocToHtml opts (Pandoc (Meta title' authors' date') blocks) = do
let standalone = writerStandalone opts
tit <- if standalone
then inlineListToHtml opts title'
- else return noHtml
+ else return mempty
auths <- if standalone
then mapM (inlineListToHtml opts) authors'
else return []
+ authsMeta <- if standalone
+ then mapM (inlineListToHtml opts . prepForMeta) authors'
+ else return []
date <- if standalone
then inlineListToHtml opts date'
- else return noHtml
+ else return mempty
+ let slideLevel = maybe (getSlideLevel blocks) id $ writerSlideLevel opts
let sects = hierarchicalize $
if writerSlideVariant opts == NoSlides
then blocks
- else case blocks of
- (Header 1 _ : _) -> blocks
- _ ->
- let isL1 (Header 1 _) = True
- isL1 _ = False
- (preBlocks, rest) = break isL1 blocks
- in (RawBlock "html" "<div class=\"slide\">" :
- preBlocks) ++ (RawBlock "html" "</div>" :
- rest)
+ else prepSlides slideLevel blocks
toc <- if writerTableOfContents opts
then tableOfContents opts sects
else return Nothing
- blocks' <- liftM (toHtmlFromList . intersperse (nl opts)) $
- mapM (elementToHtml opts) sects
+ blocks' <- liftM (mconcat . intersperse (nl opts)) $
+ mapM (elementToHtml slideLevel opts) sects
st <- get
let notes = reverse (stNotes st)
- let thebody = blocks' +++ footnoteSection opts notes
+ let thebody = blocks' >> footnoteSection opts notes
let math = if stMath st
then case writerHTMLMathMethod opts of
LaTeXMathML (Just url) ->
- script !
- [src url, thetype "text/javascript"] $ noHtml
+ H.script ! A.src (toValue url)
+ ! A.type_ "text/javascript"
+ $ mempty
MathML (Just url) ->
- script !
- [src url, thetype "text/javascript"] $ noHtml
+ H.script ! A.src (toValue url)
+ ! A.type_ "text/javascript"
+ $ mempty
MathJax url ->
- script ! [src url, thetype "text/javascript"] $ noHtml
+ H.script ! A.src (toValue url)
+ ! A.type_ "text/javascript"
+ $ mempty
JsMath (Just url) ->
- script !
- [src url, thetype "text/javascript"] $ noHtml
+ H.script ! A.src (toValue url)
+ ! A.type_ "text/javascript"
+ $ mempty
_ -> case lookup "mathml-script" (writerVariables opts) of
- Just s ->
- script ! [thetype "text/javascript"] <<
- primHtml ("/*<![CDATA[*/\n" ++ s ++
- "/*]]>*/\n")
- Nothing -> noHtml
- else noHtml
- let newvars = [("highlighting-css", defaultHighlightingCss) |
+ Just s | not (writerHtml5 opts) ->
+ H.script ! A.type_ "text/javascript"
+ $ preEscapedString
+ ("/*<![CDATA[*/\n" ++ s ++ "/*]]>*/\n")
+ | otherwise -> mempty
+ Nothing -> mempty
+ else mempty
+ let newvars = [("highlighting-css",
+ styleToCss $ writerHighlightStyle opts) |
stHighlighting st] ++
- [("math", showHtmlFragment math) | stMath st]
- return (tit, auths, date, toc, thebody, newvars)
+ [("math", renderHtml math) | stMath st]
+ return (tit, auths, authsMeta, date, toc, thebody, newvars)
+
+-- | Prepare author for meta tag, converting notes into
+-- bracketed text and removing links.
+prepForMeta :: [Inline] -> [Inline]
+prepForMeta = bottomUp (concatMap fixInline)
+ where fixInline (Note [Para xs]) = [Str " ["] ++ xs ++ [Str "]"]
+ fixInline (Note [Plain xs]) = [Str " ["] ++ xs ++ [Str "]"]
+ fixInline (Link lab _) = lab
+ fixInline (Image lab _) = lab
+ fixInline x = [x]
inTemplate :: TemplateTarget a
=> WriterOptions
-> Html
-> [Html]
+ -> [Html]
-> Html
-> Maybe Html
-> Html
-> [(String,String)]
-> a
-inTemplate opts tit auths date toc body' newvars =
- let renderedTit = showHtmlFragment tit
- topTitle' = stripTags renderedTit
- authors = map (stripTags . showHtmlFragment) auths
- date' = stripTags $ showHtmlFragment date
+inTemplate opts tit auths authsMeta date toc body' newvars =
+ let title' = renderHtml tit
+ date' = renderHtml date
+ dateMeta = maybe [] (\x -> [("date-meta",x)]) $ normalizeDate date'
variables = writerVariables opts ++ newvars
- context = variables ++
- [ ("body", dropWhile (=='\n') $ showHtmlFragment body')
- , ("pagetitle", topTitle')
- , ("title", dropWhile (=='\n') $ showHtmlFragment tit)
+ context = variables ++ dateMeta ++
+ [ ("body", dropWhile (=='\n') $ renderHtml body')
+ , ("pagetitle", stripTags title')
+ , ("title", title')
, ("date", date')
, ("idprefix", writerIdentifierPrefix opts)
, ("slidy-url", "http://www.w3.org/Talks/Tools/Slidy2")
- , ("s5-url", "ui/default") ] ++
+ , ("s5-url", "s5/default") ] ++
[ ("html5","true") | writerHtml5 opts ] ++
(case toc of
- Just t -> [ ("toc", showHtmlFragment t)]
+ Just t -> [ ("toc", renderHtml t)]
Nothing -> []) ++
- [ ("author", a) | a <- authors ]
+ [ ("author", renderHtml a) | a <- auths ] ++
+ [ ("author-meta", stripTags $ renderHtml a) | a <- authsMeta ]
in renderTemplate context $ writerTemplate opts
-- | Like Text.XHtml's identifier, but adds the writerIdentifierPrefix
-prefixedId :: WriterOptions -> String -> HtmlAttr
-prefixedId opts s = identifier $ writerIdentifierPrefix opts ++ s
+prefixedId :: WriterOptions -> String -> Attribute
+prefixedId opts s = A.id $ toValue $ writerIdentifierPrefix opts ++ s
-- | Replacement for Text.XHtml's unordList.
unordList :: WriterOptions -> ([Html] -> Html)
-unordList opts items = ulist << toListItems opts items
+unordList opts items = H.ul $ mconcat $ toListItems opts items
-- | Replacement for Text.XHtml's ordList.
ordList :: WriterOptions -> ([Html] -> Html)
-ordList opts items = olist << toListItems opts items
+ordList opts items = H.ol $ mconcat $ toListItems opts items
-- | Construct table of contents from list of elements.
tableOfContents :: WriterOptions -> [Element] -> State WriterState (Maybe Html)
@@ -214,52 +233,66 @@ elementToListItem :: WriterOptions -> Element -> State WriterState (Maybe Html)
elementToListItem _ (Blk _) = return Nothing
elementToListItem opts (Sec _ num id' headerText subsecs) = do
let sectnum = if writerNumberSections opts
- then (thespan ! [theclass "toc-section-number"] << showSecNum num) +++
- stringToHtml opts" "
- else noHtml
- txt <- liftM (sectnum +++) $ inlineListToHtml opts headerText
+ then (H.span ! A.class_ "toc-section-number" $ toHtml $ showSecNum num) >>
+ preEscapedString " "
+ else mempty
+ txt <- liftM (sectnum >>) $ inlineListToHtml opts headerText
subHeads <- mapM (elementToListItem opts) subsecs >>= return . catMaybes
let subList = if null subHeads
- then noHtml
+ then mempty
else unordList opts subHeads
- return $ Just $ (anchor ! [href ("#" ++ writerIdentifierPrefix opts ++ id')] $ txt) +++ subList
+ return $ Just $ (H.a ! A.href (toValue $ "#" ++ writerIdentifierPrefix opts ++ id')
+ $ toHtml txt) >> subList
-- | Convert an Element to Html.
-elementToHtml :: WriterOptions -> Element -> State WriterState Html
-elementToHtml opts (Blk HorizontalRule) | writerSlideVariant opts /= NoSlides =
- return $ primHtml "</div>" +++ nl opts +++ primHtml "<div class=\"slide\">"
-elementToHtml opts (Blk block) = blockToHtml opts block
-elementToHtml opts (Sec level num id' title' elements) = do
+elementToHtml :: Int -> WriterOptions -> Element -> State WriterState Html
+elementToHtml _slideLevel opts (Blk block) = blockToHtml opts block
+elementToHtml slideLevel opts (Sec level num id' title' elements) = do
+ let slide = writerSlideVariant opts /= NoSlides && level <= slideLevel
modify $ \st -> st{stSecNum = num} -- update section number
- header' <- blockToHtml opts (Header level title')
- innerContents <- mapM (elementToHtml opts) elements
- let header'' = header' ! [prefixedId opts id' |
- not (writerStrictMarkdown opts ||
- writerSectionDivs opts ||
- writerSlideVariant opts == S5Slides)]
- let stuff = header'' : innerContents
- let slide = writerSlideVariant opts /= NoSlides && level == 1
- let stuff' = if slide
- then [thediv ! [theclass "slide"] <<
- (nl opts : intersperse (nl opts) stuff ++ [nl opts])]
- else intersperse (nl opts) stuff
- let inNl x = nl opts : x ++ [nl opts]
- return $ if writerSectionDivs opts
- then if writerHtml5 opts
- then tag "section" ! [prefixedId opts id'] << inNl stuff'
- else thediv ! [prefixedId opts id'] << inNl stuff'
- else toHtmlFromList stuff'
+ -- always use level 1 for slide titles
+ let level' = if slide then 1 else level
+ let titleSlide = slide && level < slideLevel
+ header' <- blockToHtml opts (Header level' title')
+ let isSec (Sec _ _ _ _ _) = True
+ isSec (Blk _) = False
+ innerContents <- mapM (elementToHtml slideLevel opts)
+ $ if titleSlide
+ -- title slides have no content of their own
+ then filter isSec elements
+ else elements
+ let header'' = if (writerStrictMarkdown opts ||
+ writerSectionDivs opts ||
+ writerSlideVariant opts == S5Slides)
+ then header'
+ else header' ! prefixedId opts id'
+ let inNl x = mconcat $ nl opts : intersperse (nl opts) x ++ [nl opts]
+ let classes = ["titleslide" | titleSlide] ++ ["slide" | slide] ++
+ ["level" ++ show level]
+ let secttag = if writerHtml5 opts
+ then H5.section ! A.class_ (toValue $ unwords classes)
+ else H.div ! A.class_ (toValue $ unwords ("section":classes))
+ return $ if titleSlide
+ then mconcat $ (secttag ! prefixedId opts id' $ header'') : innerContents
+ else if writerSectionDivs opts || slide
+ then secttag ! prefixedId opts id' $ inNl $ header'' : innerContents
+ else mconcat $ intersperse (nl opts) $ header'' : innerContents
-- | Convert list of Note blocks to a footnote <div>.
-- Assumes notes are sorted.
footnoteSection :: WriterOptions -> [Html] -> Html
footnoteSection opts notes =
if null notes
- then noHtml
- else nl opts +++ (thediv ! [theclass "footnotes"]
- $ nl opts +++ hr +++ nl opts +++
- (olist << (notes ++ [nl opts])) +++ nl opts)
-
+ then mempty
+ else nl opts >> (container
+ $ nl opts >> hrtag >> nl opts >>
+ H.ol (mconcat notes >> nl opts) >> nl opts)
+ where container x = if writerHtml5 opts
+ then H5.section ! A.class_ "footnotes" $ x
+ else if writerSlideVariant opts /= NoSlides
+ then H.div ! A.class_ "footnotes slide" $ x
+ else H.div ! A.class_ "footnotes" $ x
+ hrtag = if writerHtml5 opts then H5.hr else H.hr
-- | Parse a mailto link; return Just (name, domain) or Nothing.
parseMailto :: String -> Maybe (String, String)
@@ -272,7 +305,7 @@ parseMailto _ = Nothing
-- | Obfuscate a "mailto:" link.
obfuscateLink :: WriterOptions -> String -> String -> Html
obfuscateLink opts txt s | writerEmailObfuscation opts == NoObfuscation =
- anchor ! [href s] << txt
+ H.a ! A.href (toValue s) $ toHtml txt
obfuscateLink opts txt s =
let meth = writerEmailObfuscation opts
s' = map toLower s
@@ -287,19 +320,19 @@ obfuscateLink opts txt s =
domain' ++ ")")
in case meth of
ReferenceObfuscation ->
- -- need to use primHtml or &'s are escaped to &amp; in URL
- primHtml $ "<a href=\"" ++ (obfuscateString s')
+ -- need to use preEscapedString or &'s are escaped to &amp; in URL
+ preEscapedString $ "<a href=\"" ++ (obfuscateString s')
++ "\">" ++ (obfuscateString txt) ++ "</a>"
JavascriptObfuscation ->
- (script ! [thetype "text/javascript"] $
- primHtml ("\n<!--\nh='" ++
+ (H.script ! A.type_ "text/javascript" $
+ preEscapedString ("\n<!--\nh='" ++
obfuscateString domain ++ "';a='" ++ at' ++ "';n='" ++
obfuscateString name' ++ "';e=n+a+h;\n" ++
"document.write('<a h'+'ref'+'=\"ma'+'ilto'+':'+e+'\">'+" ++
- linkText ++ "+'<\\/'+'a'+'>');\n// -->\n")) +++
- noscript (primHtml $ obfuscateString altText)
+ linkText ++ "+'<\\/'+'a'+'>');\n// -->\n")) >>
+ H.noscript (preEscapedString $ obfuscateString altText)
_ -> error $ "Unknown obfuscation method: " ++ show meth
- _ -> anchor ! [href s] $ stringToHtml opts txt -- malformed email
+ _ -> H.a ! A.href (toValue s) $ toHtml txt -- malformed email
-- | Obfuscate character as entity.
obfuscateChar :: Char -> String
@@ -310,13 +343,13 @@ obfuscateChar char =
-- | Obfuscate string using entities.
obfuscateString :: String -> String
-obfuscateString = concatMap obfuscateChar . decodeCharacterReferences
+obfuscateString = concatMap obfuscateChar . fromEntities
-attrsToHtml :: WriterOptions -> Attr -> [HtmlAttr]
+attrsToHtml :: WriterOptions -> Attr -> [Attribute]
attrsToHtml opts (id',classes',keyvals) =
- [theclass (unwords classes') | not (null classes')] ++
+ [A.class_ (toValue $ unwords classes') | not (null classes')] ++
[prefixedId opts id' | not (null id')] ++
- map (\(x,y) -> strAttr x y) keyvals
+ map (\(x,y) -> customAttribute (fromString x) (toValue y)) keyvals
imageExts :: [String]
imageExts = [ "art", "bmp", "cdr", "cdt", "cpt", "cr2", "crw", "djvu", "erf",
@@ -331,40 +364,41 @@ treatAsImage fp =
-- | Convert Pandoc block element to HTML.
blockToHtml :: WriterOptions -> Block -> State WriterState Html
-blockToHtml _ Null = return noHtml
+blockToHtml _ Null = return mempty
blockToHtml opts (Plain lst) = inlineListToHtml opts lst
blockToHtml opts (Para [Image txt (s,tit)]) = do
img <- inlineToHtml opts (Image txt (s,tit))
capt <- inlineListToHtml opts txt
return $ if writerHtml5 opts
- then tag "figure" <<
- [nl opts, img, tag "figcaption" << capt, nl opts]
- else thediv ! [theclass "figure"] <<
- [nl opts, img, paragraph ! [theclass "caption"] << capt,
+ then H5.figure $ mconcat
+ [nl opts, img, H5.figcaption capt, nl opts]
+ else H.div ! A.class_ "figure" $ mconcat
+ [nl opts, img, H.p ! A.class_ "caption" $ capt,
nl opts]
blockToHtml opts (Para lst) = do
contents <- inlineListToHtml opts lst
- return $ paragraph contents
-blockToHtml _ (RawBlock "html" str) = return $ primHtml str
-blockToHtml _ (RawBlock _ _) = return noHtml
-blockToHtml _ (HorizontalRule) = return hr
+ return $ H.p contents
+blockToHtml _ (RawBlock "html" str) = return $ preEscapedString str
+blockToHtml _ (RawBlock _ _) = return mempty
+blockToHtml opts (HorizontalRule) = return $ if writerHtml5 opts then H5.hr else H.hr
blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
- let classes' = if writerLiterateHaskell opts
- then classes
+ let tolhs = writerLiterateHaskell opts &&
+ any (\c -> map toLower c == "haskell") classes &&
+ any (\c -> map toLower c == "literate") classes
+ classes' = if tolhs
+ then map (\c -> if map toLower c == "haskell"
+ then "literatehaskell"
+ else c) classes
else filter (/= "literate") classes
- case highlightHtml False (id',classes',keyvals) rawCode of
- Left _ -> -- change leading newlines into <br /> tags, because some
- -- browsers ignore leading newlines in pre blocks
- let (leadingBreaks, rawCode') = span (=='\n') rawCode
- attrs = attrsToHtml opts (id', classes', keyvals)
- addBird = if "literate" `elem` classes'
- then unlines . map ("> " ++) . lines
- else unlines . lines
- in return $ pre ! attrs $ thecode <<
- (replicate (length leadingBreaks) br +++
- [stringToHtml opts $ addBird rawCode'])
- Right h -> modify (\st -> st{ stHighlighting = True }) >>
- return h
+ adjCode = if tolhs
+ then unlines . map ("> " ++) . lines $ rawCode
+ else rawCode
+ case highlight formatHtmlBlock (id',classes,keyvals) adjCode of
+ Nothing -> let attrs = attrsToHtml opts (id', classes', keyvals)
+ in return $ foldl (!) H.pre attrs $ H.code
+ $ toHtml adjCode
+ Just h -> modify (\st -> st{ stHighlighting = True }) >>
+ return (foldl (!) h (attrsToHtml opts (id',[],keyvals)))
blockToHtml opts (BlockQuote blocks) =
-- in S5, treat list in blockquote specially
-- if default is incremental, make it nonincremental;
@@ -378,47 +412,48 @@ blockToHtml opts (BlockQuote blocks) =
blockToHtml (opts {writerIncremental = inc})
(OrderedList attribs lst)
_ -> do contents <- blockListToHtml opts blocks
- return $ blockquote (nl opts +++
- contents +++ nl opts)
+ return $ H.blockquote
+ $ nl opts >> contents >> nl opts
else do
contents <- blockListToHtml opts blocks
- return $ blockquote (nl opts +++ contents +++ nl opts)
+ return $ H.blockquote $ nl opts >> contents >> nl opts
blockToHtml opts (Header level lst) = do
contents <- inlineListToHtml opts lst
secnum <- liftM stSecNum get
let contents' = if writerNumberSections opts
- then (thespan ! [theclass "header-section-number"] << showSecNum secnum) +++
- stringToHtml opts " " +++ contents
+ then (H.span ! A.class_ "header-section-number" $ toHtml $ showSecNum secnum) >>
+ strToHtml " " >> contents
else contents
let contents'' = if writerTableOfContents opts
- then anchor ! [href $ "#" ++ writerIdentifierPrefix opts ++ "TOC"] $ contents'
+ then H.a ! A.href (toValue $ "#" ++ writerIdentifierPrefix opts ++ "TOC") $ contents'
else contents'
return $ (case level of
- 1 -> h1 contents''
- 2 -> h2 contents''
- 3 -> h3 contents''
- 4 -> h4 contents''
- 5 -> h5 contents''
- 6 -> h6 contents''
- _ -> paragraph contents'')
+ 1 -> H.h1 contents''
+ 2 -> H.h2 contents''
+ 3 -> H.h3 contents''
+ 4 -> H.h4 contents''
+ 5 -> H.h5 contents''
+ 6 -> H.h6 contents''
+ _ -> H.p contents'')
blockToHtml opts (BulletList lst) = do
contents <- mapM (blockListToHtml opts) lst
- let attribs = if writerIncremental opts
- then [theclass "incremental"]
- else []
- return $ (unordList opts contents) ! attribs
+ let lst' = unordList opts contents
+ let lst'' = if writerIncremental opts
+ then lst' ! A.class_ "incremental"
+ else lst'
+ return lst''
blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do
contents <- mapM (blockListToHtml opts) lst
let numstyle' = camelCaseToHyphenated $ show numstyle
let attribs = (if writerIncremental opts
- then [theclass "incremental"]
+ then [A.class_ "incremental"]
else []) ++
(if startnum /= 1
- then [start startnum]
+ then [A.start $ toValue startnum]
else []) ++
(if numstyle /= DefaultStyle
then if writerHtml5 opts
- then [strAttr "type" $
+ then [A.type_ $
case numstyle of
Decimal -> "1"
LowerAlpha -> "a"
@@ -426,44 +461,44 @@ blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do
LowerRoman -> "i"
UpperRoman -> "I"
_ -> "1"]
- else [thestyle $ "list-style-type: " ++
+ else [A.style $ toValue $ "list-style-type: " ++
numstyle']
else [])
- return $ (ordList opts contents) ! attribs
+ return $ foldl (!) (ordList opts contents) attribs
blockToHtml opts (DefinitionList lst) = do
contents <- mapM (\(term, defs) ->
- do term' <- liftM (dterm <<) $ inlineListToHtml opts term
- defs' <- mapM ((liftM (\x -> ddef << (x +++ nl opts))) .
+ do term' <- liftM (H.dt) $ inlineListToHtml opts term
+ defs' <- mapM ((liftM (\x -> H.dd $ (x >> nl opts))) .
blockListToHtml opts) defs
- return $ nl opts : term' : nl opts : defs') lst
- let attribs = if writerIncremental opts
- then [theclass "incremental"]
- else []
- return $ dlist ! attribs << (concat contents +++ nl opts)
+ return $ mconcat $ nl opts : term' : nl opts : defs') lst
+ let lst' = H.dl $ mconcat contents >> nl opts
+ let lst'' = if writerIncremental opts
+ then lst' ! A.class_ "incremental"
+ else lst'
+ return lst''
blockToHtml opts (Table capt aligns widths headers rows') = do
captionDoc <- if null capt
- then return noHtml
+ then return mempty
else do
cs <- inlineListToHtml opts capt
- return $ caption cs +++ nl opts
+ return $ H.caption cs >> nl opts
let percent w = show (truncate (100*w) :: Integer) ++ "%"
- let widthAttrs w = if writerHtml5 opts
- then [thestyle $ "width: " ++ percent w]
- else [width $ percent w]
let coltags = if all (== 0.0) widths
- then noHtml
- else concatHtml $ map
- (\w -> (col ! (widthAttrs w)) noHtml +++ nl opts)
- widths
+ then mempty
+ else mconcat $ map (\w ->
+ if writerHtml5 opts
+ then H.col ! A.style (toValue $ "width: " ++ percent w)
+ else H.col ! A.width (toValue $ percent w) >> nl opts)
+ widths
head' <- if all null headers
- then return noHtml
+ then return mempty
else do
contents <- tableRowToHtml opts aligns 0 headers
- return $ thead << (nl opts +++ contents) +++ nl opts
- body' <- liftM (\x -> tbody << (nl opts +++ x)) $
+ return $ H.thead (nl opts >> contents) >> nl opts
+ body' <- liftM (\x -> H.tbody (nl opts >> mconcat x)) $
zipWithM (tableRowToHtml opts aligns) [1..] rows'
- return $ table $ nl opts +++ captionDoc +++ coltags +++ head' +++
- body' +++ nl opts
+ return $ H.table $ nl opts >> captionDoc >> coltags >> head' >>
+ body' >> nl opts
tableRowToHtml :: WriterOptions
-> [Alignment]
@@ -471,7 +506,7 @@ tableRowToHtml :: WriterOptions
-> [[Block]]
-> State WriterState Html
tableRowToHtml opts aligns rownum cols' = do
- let mkcell = if rownum == 0 then th else td
+ let mkcell = if rownum == 0 then H.th else H.td
let rowclass = case rownum of
0 -> "header"
x | x `rem` 2 == 1 -> "odd"
@@ -479,8 +514,8 @@ tableRowToHtml opts aligns rownum cols' = do
cols'' <- sequence $ zipWith
(\alignment item -> tableItemToHtml opts mkcell alignment item)
aligns cols'
- return $ (tr ! [theclass rowclass] $ nl opts +++ toHtmlFromList cols'')
- +++ nl opts
+ return $ (H.tr ! A.class_ rowclass $ nl opts >> mconcat cols'')
+ >> nl opts
alignmentToString :: Alignment -> [Char]
alignmentToString alignment = case alignment of
@@ -496,84 +531,87 @@ tableItemToHtml :: WriterOptions
-> State WriterState Html
tableItemToHtml opts tag' align' item = do
contents <- blockListToHtml opts item
- let alignAttrs = if writerHtml5 opts
- then [thestyle $ "align: " ++ alignmentToString align']
- else [align $ alignmentToString align']
- return $ (tag' ! alignAttrs) contents +++ nl opts
+ let alignStr = alignmentToString align'
+ let attribs = if writerHtml5 opts
+ then A.style (toValue $ "text-align: " ++ alignStr ++ ";")
+ else A.align (toValue alignStr)
+ return $ (tag' ! attribs $ contents) >> nl opts
toListItems :: WriterOptions -> [Html] -> [Html]
toListItems opts items = map (toListItem opts) items ++ [nl opts]
toListItem :: WriterOptions -> Html -> Html
-toListItem opts item = nl opts +++ li item
+toListItem opts item = nl opts >> H.li item
blockListToHtml :: WriterOptions -> [Block] -> State WriterState Html
blockListToHtml opts lst =
mapM (blockToHtml opts) lst >>=
- return . toHtmlFromList . intersperse (nl opts)
+ return . mconcat . intersperse (nl opts)
-- | Convert list of Pandoc inline elements to HTML.
inlineListToHtml :: WriterOptions -> [Inline] -> State WriterState Html
inlineListToHtml opts lst =
- mapM (inlineToHtml opts) lst >>= return . toHtmlFromList
+ mapM (inlineToHtml opts) lst >>= return . mconcat
-- | Convert Pandoc inline element to HTML.
inlineToHtml :: WriterOptions -> Inline -> State WriterState Html
inlineToHtml opts inline =
case inline of
- (Str str) -> return $ stringToHtml opts str
- (Space) -> return $ stringToHtml opts " "
- (LineBreak) -> return br
- (EmDash) -> return $ stringToHtml opts "—"
- (EnDash) -> return $ stringToHtml opts "–"
- (Ellipses) -> return $ stringToHtml opts "…"
- (Apostrophe) -> return $ stringToHtml opts "’"
- (Emph lst) -> inlineListToHtml opts lst >>= return . emphasize
- (Strong lst) -> inlineListToHtml opts lst >>= return . strong
- (Code attr str) -> case highlightHtml True attr str of
- Left _ -> return
- $ thecode ! (attrsToHtml opts attr)
- $ stringToHtml opts str
- Right h -> return h
+ (Str str) -> return $ strToHtml str
+ (Space) -> return $ strToHtml " "
+ (LineBreak) -> return $ if writerHtml5 opts then H5.br else H.br
+ (Emph lst) -> inlineListToHtml opts lst >>= return . H.em
+ (Strong lst) -> inlineListToHtml opts lst >>= return . H.strong
+ (Code attr str) -> case highlight formatHtmlInline attr str of
+ Nothing -> return
+ $ foldl (!) H.code (attrsToHtml opts attr)
+ $ strToHtml str
+ Just h -> return $ foldl (!) h $
+ attrsToHtml opts (id',[],keyvals)
+ where (id',_,keyvals) = attr
(Strikeout lst) -> inlineListToHtml opts lst >>=
- return . (thespan ! [thestyle "text-decoration: line-through;"])
+ return . H.del
(SmallCaps lst) -> inlineListToHtml opts lst >>=
- return . (thespan ! [thestyle "font-variant: small-caps;"])
- (Superscript lst) -> inlineListToHtml opts lst >>= return . sup
- (Subscript lst) -> inlineListToHtml opts lst >>= return . sub
+ return . (H.span ! A.style "font-variant: small-caps;")
+ (Superscript lst) -> inlineListToHtml opts lst >>= return . H.sup
+ (Subscript lst) -> inlineListToHtml opts lst >>= return . H.sub
(Quoted quoteType lst) ->
let (leftQuote, rightQuote) = case quoteType of
- SingleQuote -> (stringToHtml opts "‘",
- stringToHtml opts "’")
- DoubleQuote -> (stringToHtml opts "“",
- stringToHtml opts "”")
+ SingleQuote -> (strToHtml "‘",
+ strToHtml "’")
+ DoubleQuote -> (strToHtml "“",
+ strToHtml "”")
in do contents <- inlineListToHtml opts lst
- return $ leftQuote +++ contents +++ rightQuote
+ return $ leftQuote >> contents >> rightQuote
(Math t str) -> modify (\st -> st {stMath = True}) >>
(case writerHTMLMathMethod opts of
LaTeXMathML _ ->
-- putting LaTeXMathML in container with class "LaTeX" prevents
-- non-math elements on the page from being treated as math by
-- the javascript
- return $ thespan ! [theclass "LaTeX"] $
+ return $ H.span ! A.class_ "LaTeX" $
case t of
- InlineMath -> primHtml ("$" ++ str ++ "$")
- DisplayMath -> primHtml ("$$" ++ str ++ "$$")
+ InlineMath -> toHtml ("$" ++ str ++ "$")
+ DisplayMath -> toHtml ("$$" ++ str ++ "$$")
JsMath _ -> do
- let m = primHtml str
+ let m = preEscapedString str
return $ case t of
- InlineMath -> thespan ! [theclass "math"] $ m
- DisplayMath -> thediv ! [theclass "math"] $ m
+ InlineMath -> H.span ! A.class_ "math" $ m
+ DisplayMath -> H.div ! A.class_ "math" $ m
WebTeX url -> do
- let m = image ! [src (url ++ urlEncode str),
- alt str, title str]
+ let imtag = if writerHtml5 opts then H5.img else H.img
+ let m = imtag ! A.style "vertical-align:middle"
+ ! A.src (toValue $ url ++ urlEncode str)
+ ! A.alt (toValue str)
+ ! A.title (toValue str)
+ let brtag = if writerHtml5 opts then H5.br else H.br
return $ case t of
InlineMath -> m
- DisplayMath -> br +++ m +++ br
+ DisplayMath -> brtag >> m >> brtag
GladTeX ->
return $ case t of
- InlineMath -> primHtml $ "<EQ ENV=\"math\">" ++ str ++ "</EQ>"
- DisplayMath -> primHtml $ "<EQ ENV=\"displaymath\">" ++ str ++ "</EQ>"
+ InlineMath -> preEscapedString "<EQ ENV=\"math\">" >> toHtml str >> preEscapedString "</EQ>"
+ DisplayMath -> preEscapedString "<EQ ENV=\"displaymath\">" >> toHtml str >> preEscapedString "</EQ>"
MathML _ -> do
let dt = if t == InlineMath
then DisplayInline
@@ -581,54 +619,57 @@ inlineToHtml opts inline =
let conf = useShortEmptyTags (const False)
defaultConfigPP
case texMathToMathML dt str of
- Right r -> return $ primHtml $
+ Right r -> return $ preEscapedString $
ppcElement conf r
Left _ -> inlineListToHtml opts
(readTeXMath str) >>= return .
- (thespan ! [theclass "math"])
- MathJax _ -> return $ primHtml $
+ (H.span ! A.class_ "math")
+ MathJax _ -> return $ toHtml $
case t of
InlineMath -> "\\(" ++ str ++ "\\)"
DisplayMath -> "\\[" ++ str ++ "\\]"
PlainMath -> do
x <- inlineListToHtml opts (readTeXMath str)
- let m = thespan ! [theclass "math"] $ x
+ let m = H.span ! A.class_ "math" $ x
+ let brtag = if writerHtml5 opts then H5.br else H.br
return $ case t of
InlineMath -> m
- DisplayMath -> br +++ m +++ br )
+ DisplayMath -> brtag >> m >> brtag )
(RawInline "latex" str) -> case writerHTMLMathMethod opts of
LaTeXMathML _ -> do modify (\st -> st {stMath = True})
- return $ primHtml str
- _ -> return noHtml
- (RawInline "html" str) -> return $ primHtml str
- (RawInline _ _) -> return noHtml
+ return $ toHtml str
+ _ -> return mempty
+ (RawInline "html" str) -> return $ preEscapedString str
+ (RawInline _ _) -> return mempty
(Link [Code _ str] (s,_)) | "mailto:" `isPrefixOf` s ->
return $ obfuscateLink opts str s
(Link txt (s,_)) | "mailto:" `isPrefixOf` s -> do
linkText <- inlineListToHtml opts txt
- return $ obfuscateLink opts (show linkText) s
+ return $ obfuscateLink opts (renderHtml linkText) s
(Link txt (s,tit)) -> do
linkText <- inlineListToHtml opts txt
- return $ anchor ! ([href s] ++
- if null tit then [] else [title tit]) $
- linkText
+ let link = H.a ! A.href (toValue s) $ linkText
+ return $ if null tit
+ then link
+ else link ! A.title (toValue tit)
(Image txt (s,tit)) | treatAsImage s -> do
let alternate' = stringify txt
- let attributes = [src s] ++
+ let attributes = [A.src $ toValue s] ++
(if null tit
then []
- else [title tit]) ++
+ else [A.title $ toValue tit]) ++
if null txt
then []
- else [alt alternate']
- return $ image ! attributes
+ else [A.alt $ toValue alternate']
+ let tag = if writerHtml5 opts then H5.img else H.img
+ return $ foldl (!) tag attributes
-- note: null title included, as in Markdown.pl
(Image _ (s,tit)) -> do
- let attributes = [src s] ++
+ let attributes = [A.src $ toValue s] ++
(if null tit
then []
- else [title tit])
- return $ itag "embed" ! attributes
+ else [A.title $ toValue tit])
+ return $ foldl (!) H5.embed attributes
-- note: null title included, as in Markdown.pl
(Note contents) -> do
st <- get
@@ -638,19 +679,19 @@ inlineToHtml opts inline =
htmlContents <- blockListToNote opts ref contents
-- push contents onto front of notes
put $ st {stNotes = (htmlContents:notes)}
- return $ sup <<
- anchor ! [href ("#" ++ writerIdentifierPrefix opts ++ "fn" ++ ref),
- theclass "footnoteRef",
- prefixedId opts ("fnref" ++ ref)] << ref
- (Cite _ il) -> inlineListToHtml opts il
+ return $ H.sup $
+ H.a ! A.href (toValue $ "#" ++ writerIdentifierPrefix opts ++ "fn" ++ ref)
+ ! A.class_ "footnoteRef"
+ ! prefixedId opts ("fnref" ++ ref)
+ $ toHtml ref
+ (Cite _ il) -> do contents <- inlineListToHtml opts il
+ return $ H.span ! A.class_ "citation" $ contents
blockListToNote :: WriterOptions -> String -> [Block] -> State WriterState Html
blockListToNote opts ref blocks =
-- If last block is Para or Plain, include the backlink at the end of
-- that block. Otherwise, insert a new Plain block with the backlink.
- let backlink = [RawInline "html" $ " <a href=\"#" ++ writerIdentifierPrefix opts ++ "fnref" ++ ref ++
- "\" class=\"footnoteBackLink\">" ++
- (if writerAscii opts then "&#8617;" else "↩") ++ "</a>"]
+ let backlink = [Link [Str "↩"] ("#" ++ writerIdentifierPrefix opts ++ "fnref" ++ ref,[])]
blocks' = if null blocks
then []
else let lastBlock = last blocks
@@ -663,4 +704,4 @@ blockListToNote opts ref blocks =
_ -> otherBlocks ++ [lastBlock,
Plain backlink]
in do contents <- blockListToHtml opts blocks'
- return $ nl opts +++ (li ! [prefixedId opts ("fn" ++ ref)]) contents
+ return $ nl opts >> (H.li ! (prefixedId opts ("fn" ++ ref)) $ contents)
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
index d925b2897..e99b20c60 100644
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -20,10 +20,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Text.Pandoc.Writers.LaTeX
Copyright : Copyright (C) 2006-2010 John MacFarlane
- License : GNU GPL, version 2 or above
+ License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
- Stability : alpha
+ Stability : alpha
Portability : portable
Conversion of 'Pandoc' format into LaTeX.
@@ -41,53 +41,68 @@ import Data.Char ( toLower, isPunctuation )
import Control.Monad.State
import Text.Pandoc.Pretty
import System.FilePath (dropExtension)
+import Text.Pandoc.Slides
+import Text.Pandoc.Highlighting (highlight, styleToLaTeX,
+ formatLaTeXInline, formatLaTeXBlock)
-data WriterState =
- WriterState { stInNote :: Bool -- @True@ if we're in a note
- , stInTable :: Bool -- @True@ if we're in a table
- , stTableNotes :: [(Char, Doc)] -- List of markers, notes
- -- in current table
- , stOLLevel :: Int -- level of ordered list nesting
- , stOptions :: WriterOptions -- writer options, so they don't have to be parameter
- , stVerbInNote :: Bool -- true if document has verbatim text in note
- , stEnumerate :: Bool -- true if document needs fancy enumerated lists
- , stTable :: Bool -- true if document has a table
- , stStrikeout :: Bool -- true if document has strikeout
- , stSubscript :: Bool -- true if document has subscript
- , stUrl :: Bool -- true if document has visible URL link
- , stGraphics :: Bool -- true if document contains images
- , stLHS :: Bool -- true if document has literate haskell code
- , stBook :: Bool -- true if document uses book or memoir class
- , stCsquotes :: Bool -- true if document uses csquotes
+data WriterState =
+ WriterState { stInNote :: Bool -- true if we're in a note
+ , stInTable :: Bool -- true if we're in a table
+ , stTableNotes :: [(Char, Doc)] -- List of markers, notes
+ -- in current table
+ , stOLLevel :: Int -- level of ordered list nesting
+ , stOptions :: WriterOptions -- writer options, so they don't have to be parameter
+ , stVerbInNote :: Bool -- true if document has verbatim text in note
+ , stEnumerate :: Bool -- true if document needs fancy enumerated lists
+ , stTable :: Bool -- true if document has a table
+ , stStrikeout :: Bool -- true if document has strikeout
+ , stSubscript :: Bool -- true if document has subscript
+ , stUrl :: Bool -- true if document has visible URL link
+ , stGraphics :: Bool -- true if document contains images
+ , stLHS :: Bool -- true if document has literate haskell code
+ , stBook :: Bool -- true if document uses book or memoir class
+ , stCsquotes :: Bool -- true if document uses csquotes
+ , stHighlighting :: Bool -- true if document has highlighted code
+ , stIncremental :: Bool -- true if beamer lists should be displayed bit by bit
+ , stInternalLinks :: [String] -- list of internal link targets
}
-- | Convert Pandoc to LaTeX.
writeLaTeX :: WriterOptions -> Pandoc -> String
-writeLaTeX options document =
- evalState (pandocToLaTeX options document) $
+writeLaTeX options document =
+ evalState (pandocToLaTeX options document) $
WriterState { stInNote = False, stInTable = False,
stTableNotes = [], stOLLevel = 1, stOptions = options,
stVerbInNote = False, stEnumerate = False,
stTable = False, stStrikeout = False, stSubscript = False,
stUrl = False, stGraphics = False,
stLHS = False, stBook = writerChapters options,
- stCsquotes = False }
+ stCsquotes = False, stHighlighting = False,
+ stIncremental = writerIncremental options,
+ stInternalLinks = [] }
pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String
pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
+ -- see if there are internal links
+ let isInternalLink (Link _ ('#':xs,_)) = [xs]
+ isInternalLink _ = []
+ modify $ \s -> s{ stInternalLinks = queryWith isInternalLink blocks }
let template = writerTemplate options
- let usesBookClass x = "\\documentclass" `isPrefixOf` x &&
- ("{memoir}" `isSuffixOf` x || "{book}" `isSuffixOf` x ||
- "{report}" `isSuffixOf` x)
- when (any usesBookClass (lines template)) $
- modify $ \s -> s{stBook = True}
+ -- set stBook depending on documentclass
+ let bookClasses = ["memoir","book","report","scrreprt","scrbook"]
+ case lookup "documentclass" (writerVariables options) of
+ Just x | x `elem` bookClasses -> modify $ \s -> s{stBook = True}
+ | otherwise -> return ()
+ Nothing | any (\x -> "\\documentclass" `isPrefixOf` x &&
+ (any (`isSuffixOf` x) bookClasses))
+ (lines template) -> modify $ \s -> s{stBook = True}
+ | otherwise -> return ()
-- check for \usepackage...{csquotes}; if present, we'll use
-- \enquote{...} for smart quotes:
when ("{csquotes}" `isInfixOf` template) $
modify $ \s -> s{stCsquotes = True}
- opts <- liftM stOptions get
- let colwidth = if writerWrapText opts
- then Just $ writerColumns opts
+ let colwidth = if writerWrapText options
+ then Just $ writerColumns options
else Nothing
titletext <- liftM (render colwidth) $ inlineListToLaTeX title
authorsText <- mapM (liftM (render colwidth) . inlineListToLaTeX) authors
@@ -97,9 +112,12 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
else case last blocks of
Header 1 il -> (init blocks, il)
_ -> (blocks, [])
- body <- blockListToLaTeX blocks'
+ blocks'' <- if writerBeamer options
+ then toSlides blocks'
+ else return blocks'
+ body <- mapM (elementToLaTeX options) $ hierarchicalize blocks''
biblioTitle <- liftM (render colwidth) $ inlineListToLaTeX lastHeader
- let main = render colwidth body
+ let main = render colwidth $ vcat body
st <- get
let biblioFiles = intercalate "," $ map dropExtension $ writerBiblioFiles options
citecontext = case writerCiteMethod options of
@@ -116,7 +134,12 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
[ ("toc", if writerTableOfContents options then "yes" else "")
, ("body", main)
, ("title", titletext)
- , ("date", dateText) ] ++
+ , ("date", dateText)
+ , ("documentclass", if writerBeamer options
+ then "beamer"
+ else if writerChapters options
+ then "book"
+ else "article") ] ++
[ ("author", a) | a <- authorsText ] ++
[ ("verbatim-in-note", "yes") | stVerbInNote st ] ++
[ ("fancy-enums", "yes") | stEnumerate st ] ++
@@ -128,36 +151,102 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
[ ("lhs", "yes") | stLHS st ] ++
[ ("graphics", "yes") | stGraphics st ] ++
[ ("book-class", "yes") | stBook st] ++
- [ ("listings", "yes") | writerListings options ] ++
+ [ ("listings", "yes") | writerListings options || stLHS st ] ++
+ [ ("beamer", "yes") | writerBeamer options ] ++
+ [ ("highlighting-macros", styleToLaTeX
+ $ writerHighlightStyle options ) | stHighlighting st ] ++
citecontext
return $ if writerStandalone options
then renderTemplate context template
else main
--- escape things as needed for LaTeX
+-- | Convert Elements to LaTeX
+elementToLaTeX :: WriterOptions -> Element -> State WriterState Doc
+elementToLaTeX _ (Blk block) = blockToLaTeX block
+elementToLaTeX opts (Sec level _ id' title' elements) = do
+ header' <- sectionHeader id' level title'
+ innerContents <- mapM (elementToLaTeX opts) elements
+ return $ vcat (header' : innerContents)
-stringToLaTeX :: String -> String
-stringToLaTeX = escapeStringUsing latexEscapes
- where latexEscapes = backslashEscapes "{}$%&_#" ++
- [ ('^', "\\^{}")
- , ('\\', "\\textbackslash{}")
- , ('~', "\\ensuremath{\\sim}")
- , ('|', "\\textbar{}")
- , ('<', "\\textless{}")
- , ('>', "\\textgreater{}")
- , ('[', "{[}") -- to avoid interpretation as
- , (']', "{]}") -- optional arguments
- , ('\160', "~")
- , ('\x2018', "`")
- , ('\x2019', "'")
- , ('\x201C', "``")
- , ('\x201D', "''")
- ]
+-- escape things as needed for LaTeX
+stringToLaTeX :: Bool -> String -> String
+stringToLaTeX _ [] = ""
+stringToLaTeX isUrl (x:xs) =
+ case x of
+ '{' -> "\\{" ++ rest
+ '}' -> "\\}" ++ rest
+ '$' -> "\\$" ++ rest
+ '%' -> "\\%" ++ rest
+ '&' -> "\\&" ++ rest
+ '_' -> "\\_" ++ rest
+ '#' -> "\\#" ++ rest
+ '-' -> case xs of -- prevent adjacent hyphens from forming ligatures
+ ('-':_) -> "-{}" ++ rest
+ _ -> '-' : rest
+ '~' | not isUrl -> "\\ensuremath{\\sim}"
+ '^' -> "\\^{}" ++ rest
+ '\\' -> "\\textbackslash{}" ++ rest
+ '€' -> "\\euro{}" ++ rest
+ '|' -> "\\textbar{}" ++ rest
+ '<' -> "\\textless{}" ++ rest
+ '>' -> "\\textgreater{}" ++ rest
+ '[' -> "{[}" ++ rest -- to avoid interpretation as
+ ']' -> "{]}" ++ rest -- optional arguments
+ '\160' -> "~" ++ rest
+ '\x2018' -> "`" ++ rest
+ '\x2019' -> "'" ++ rest
+ '\x201C' -> "``" ++ rest
+ '\x201D' -> "''" ++ rest
+ '\x2026' -> "\\ldots{}" ++ rest
+ '\x2014' -> "---" ++ rest
+ '\x2013' -> "--" ++ rest
+ _ -> x : rest
+ where rest = stringToLaTeX isUrl xs
-- | Puts contents into LaTeX command.
inCmd :: String -> Doc -> Doc
inCmd cmd contents = char '\\' <> text cmd <> braces contents
+toSlides :: [Block] -> State WriterState [Block]
+toSlides bs = do
+ opts <- gets stOptions
+ let slideLevel = maybe (getSlideLevel bs) id $ writerSlideLevel opts
+ let bs' = prepSlides slideLevel bs
+ concat `fmap` (mapM (elementToBeamer slideLevel) $ hierarchicalize bs')
+
+elementToBeamer :: Int -> Element -> State WriterState [Block]
+elementToBeamer _slideLevel (Blk b) = return [b]
+elementToBeamer slideLevel (Sec lvl _num _ident tit elts)
+ | lvl > slideLevel = do
+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
+ return $ Para ( RawInline "latex" "\\begin{block}{"
+ : tit ++ [RawInline "latex" "}"] )
+ : bs ++ [RawBlock "latex" "\\end{block}"]
+ | lvl < slideLevel = do
+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
+ return $ (Header lvl tit) : bs
+ | otherwise = do -- lvl == slideLevel
+ -- note: [fragile] is required or verbatim breaks
+ let hasCodeBlock (CodeBlock _ _) = [True]
+ hasCodeBlock _ = []
+ let hasCode (Code _ _) = [True]
+ hasCode _ = []
+ let fragile = if not $ null $ queryWith hasCodeBlock elts ++ queryWith hasCode elts
+ then "[fragile]"
+ else ""
+ let slideStart = Para $ RawInline "latex" ("\\begin{frame}" ++ fragile ++
+ "\\frametitle{") : tit ++ [RawInline "latex" "}"]
+ let slideEnd = RawBlock "latex" "\\end{frame}"
+ -- now carve up slide into blocks if there are sections inside
+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
+ return $ slideStart : bs ++ [slideEnd]
+
+isListBlock :: Block -> Bool
+isListBlock (BulletList _) = True
+isListBlock (OrderedList _ _) = True
+isListBlock (DefinitionList _) = True
+isListBlock _ = False
+
-- | Convert Pandoc block element to LaTeX.
blockToLaTeX :: Block -- ^ Block to convert
-> State WriterState Doc
@@ -172,58 +261,80 @@ blockToLaTeX (Para lst) = do
result <- inlineListToLaTeX lst
return $ result <> blankline
blockToLaTeX (BlockQuote lst) = do
- contents <- blockListToLaTeX lst
- return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"
+ beamer <- writerBeamer `fmap` gets stOptions
+ case lst of
+ [b] | beamer && isListBlock b -> do
+ oldIncremental <- gets stIncremental
+ modify $ \s -> s{ stIncremental = True }
+ result <- blockToLaTeX b
+ modify $ \s -> s{ stIncremental = oldIncremental }
+ return result
+ _ -> do
+ contents <- blockListToLaTeX lst
+ return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"
blockToLaTeX (CodeBlock (_,classes,keyvalAttr) str) = do
- st <- get
- env <- if writerLiterateHaskell (stOptions st) && "haskell" `elem` classes &&
- "literate" `elem` classes
- then do
- modify $ \s -> s{ stLHS = True }
- return "code"
- else if writerListings (stOptions st)
- then return "lstlisting"
- else if stInNote st
- then do
- modify $ \s -> s{ stVerbInNote = True }
- return "Verbatim"
- else return "verbatim"
- let params = if writerListings (stOptions st)
- then take 1
- [ "language=" ++ lang | lang <- classes
- , lang `elem` ["ABAP","IDL","Plasm","ACSL","inform"
- ,"POV","Ada","Java","Prolog","Algol"
- ,"JVMIS","Promela","Ant","ksh","Python"
- ,"Assembler","Lisp","R","Awk","Logo"
- ,"Reduce","bash","make","Rexx","Basic"
- ,"Mathematica","RSL","C","Matlab","Ruby"
- ,"C++","Mercury","S","Caml","MetaPost"
- ,"SAS","Clean","Miranda","Scilab","Cobol"
- ,"Mizar","sh","Comal","ML","SHELXL","csh"
- ,"Modula-2","Simula","Delphi","MuPAD"
- ,"SQL","Eiffel","NASTRAN","tcl","Elan"
- ,"Oberon-2","TeX","erlang","OCL"
- ,"VBScript","Euphoria","Octave","Verilog"
- ,"Fortran","Oz","VHDL","GCL","Pascal"
- ,"VRML","Gnuplot","Perl","XML","Haskell"
- ,"PHP","XSLT","HTML","PL/I"]
- ] ++
- [ key ++ "=" ++ attr | (key,attr) <- keyvalAttr ]
- else []
- printParams
- | null params = empty
- | otherwise = "[" <> hsep (intersperse "," (map text params)) <>
- "]"
- return $ flush ("\\begin{" <> text env <> "}" <> printParams $$ text str $$
- "\\end{" <> text env <> "}") $$ cr
- -- final cr needed because of footnotes
+ opts <- gets stOptions
+ case () of
+ _ | writerLiterateHaskell opts && "haskell" `elem` classes &&
+ "literate" `elem` classes -> lhsCodeBlock
+ | writerListings opts -> listingsCodeBlock
+ | writerHighlight opts && not (null classes) -> highlightedCodeBlock
+ | otherwise -> rawCodeBlock
+ where lhsCodeBlock = do
+ modify $ \s -> s{ stLHS = True }
+ return $ flush ("\\begin{code}" $$ text str $$ "\\end{code}") $$ cr
+ rawCodeBlock = do
+ st <- get
+ env <- if stInNote st
+ then modify (\s -> s{ stVerbInNote = True }) >>
+ return "Verbatim"
+ else return "verbatim"
+ return $ flush (text ("\\begin{" ++ env ++ "}") $$ text str $$
+ text ("\\end{" ++ env ++ "}")) $$ cr -- final cr because of notes
+ listingsCodeBlock = do
+ st <- get
+ let params = if writerListings (stOptions st)
+ then take 1
+ [ "language=" ++ lang | lang <- classes
+ , lang `elem` ["ABAP","IDL","Plasm","ACSL","inform"
+ ,"POV","Ada","Java","Prolog","Algol"
+ ,"JVMIS","Promela","Ant","ksh","Python"
+ ,"Assembler","Lisp","R","Awk","Logo"
+ ,"Reduce","bash","make","Rexx","Basic"
+ ,"Mathematica","RSL","C","Matlab","Ruby"
+ ,"C++","Mercury","S","Caml","MetaPost"
+ ,"SAS","Clean","Miranda","Scilab","Cobol"
+ ,"Mizar","sh","Comal","ML","SHELXL","csh"
+ ,"Modula-2","Simula","Delphi","MuPAD"
+ ,"SQL","Eiffel","NASTRAN","tcl","Elan"
+ ,"Oberon-2","TeX","erlang","OCL"
+ ,"VBScript","Euphoria","Octave","Verilog"
+ ,"Fortran","Oz","VHDL","GCL","Pascal"
+ ,"VRML","Gnuplot","Perl","XML","Haskell"
+ ,"PHP","XSLT","HTML","PL/I"]
+ ] ++
+ [ key ++ "=" ++ attr | (key,attr) <- keyvalAttr ]
+ else []
+ printParams
+ | null params = empty
+ | otherwise = brackets $ hsep (intersperse "," (map text params))
+ return $ flush ("\\begin{lstlisting}" <> printParams $$ text str $$
+ "\\end{lstlisting}") $$ cr
+ highlightedCodeBlock =
+ case highlight formatLaTeXBlock ("",classes,keyvalAttr) str of
+ Nothing -> rawCodeBlock
+ Just h -> modify (\st -> st{ stHighlighting = True }) >>
+ return (flush $ text h)
blockToLaTeX (RawBlock "latex" x) = return $ text x <> blankline
blockToLaTeX (RawBlock _ _) = return empty
blockToLaTeX (BulletList lst) = do
+ incremental <- gets stIncremental
+ let inc = if incremental then "[<+->]" else ""
items <- mapM listItemToLaTeX lst
- return $ "\\begin{itemize}" $$ vcat items $$ "\\end{itemize}"
+ return $ text ("\\begin{itemize}" ++ inc) $$ vcat items $$ "\\end{itemize}"
blockToLaTeX (OrderedList (start, numstyle, numdelim) lst) = do
st <- get
+ let inc = if stIncremental st then "[<+->]" else ""
let oldlevel = stOLLevel st
put $ st {stOLLevel = oldlevel + 1}
items <- mapM listItemToLaTeX lst
@@ -231,46 +342,25 @@ blockToLaTeX (OrderedList (start, numstyle, numdelim) lst) = do
exemplar <- if numstyle /= DefaultStyle || numdelim /= DefaultDelim
then do
modify $ \s -> s{ stEnumerate = True }
- return $ char '[' <>
+ return $ char '[' <>
text (head (orderedListMarkers (1, numstyle,
numdelim))) <> char ']'
else return empty
let resetcounter = if start /= 1 && oldlevel <= 4
- then text $ "\\setcounter{enum" ++
+ then text $ "\\setcounter{enum" ++
map toLower (toRomanNumeral oldlevel) ++
"}{" ++ show (start - 1) ++ "}"
- else empty
- return $ "\\begin{enumerate}" <> exemplar $$ resetcounter $$
+ else empty
+ return $ text ("\\begin{enumerate}" ++ inc) <> exemplar $$ resetcounter $$
vcat items $$ "\\end{enumerate}"
blockToLaTeX (DefinitionList lst) = do
+ incremental <- gets stIncremental
+ let inc = if incremental then "[<+->]" else ""
items <- mapM defListItemToLaTeX lst
- return $ "\\begin{description}" $$ vcat items $$ "\\end{description}"
+ return $ text ("\\begin{description}" ++ inc) $$ vcat items $$ "\\end{description}"
blockToLaTeX HorizontalRule = return $
"\\begin{center}\\rule{3in}{0.4pt}\\end{center}" $$ blankline
-blockToLaTeX (Header level lst) = do
- txt <- inlineListToLaTeX lst
- let noNote (Note _) = Str ""
- noNote x = x
- let lstNoNotes = bottomUp noNote lst
- -- footnotes in sections don't work unless you specify an optional
- -- argument: \section[mysec]{mysec\footnote{blah}}
- optional <- if lstNoNotes == lst
- then return empty
- else do
- res <- inlineListToLaTeX lstNoNotes
- return $ char '[' <> res <> char ']'
- let stuffing = optional <> char '{' <> txt <> char '}'
- book <- liftM stBook get
- let level' = if book then level - 1 else level
- let headerWith x y = text x <> y $$ blankline
- return $ case level' of
- 0 -> headerWith "\\chapter" stuffing
- 1 -> headerWith "\\section" stuffing
- 2 -> headerWith "\\subsection" stuffing
- 3 -> headerWith "\\subsubsection" stuffing
- 4 -> headerWith "\\paragraph" stuffing
- 5 -> headerWith "\\subparagraph" stuffing
- _ -> txt $$ blankline
+blockToLaTeX (Header level lst) = sectionHeader "" level lst
blockToLaTeX (Table caption aligns widths heads rows) = do
modify $ \s -> s{ stInTable = True, stTableNotes = [] }
headers <- if all null heads
@@ -338,6 +428,49 @@ defListItemToLaTeX (term, defs) = do
def' <- liftM vsep $ mapM blockListToLaTeX defs
return $ "\\item" <> brackets term' $$ def'
+-- | Craft the section header, inserting the secton reference, if supplied.
+sectionHeader :: [Char]
+ -> Int
+ -> [Inline]
+ -> State WriterState Doc
+sectionHeader ref level lst = do
+ txt <- inlineListToLaTeX lst
+ let noNote (Note _) = Str ""
+ noNote x = x
+ let lstNoNotes = bottomUp noNote lst
+ -- footnotes in sections don't work unless you specify an optional
+ -- argument: \section[mysec]{mysec\footnote{blah}}
+ optional <- if lstNoNotes == lst
+ then return empty
+ else do
+ res <- inlineListToLaTeX lstNoNotes
+ return $ char '[' <> res <> char ']'
+ let stuffing = optional <> char '{' <> txt <> char '}'
+ book <- gets stBook
+ opts <- gets stOptions
+ let level' = if book || writerChapters opts then level - 1 else level
+ internalLinks <- gets stInternalLinks
+ let refLabel lab = (if ref `elem` internalLinks
+ then text "\\hyperdef"
+ <> braces empty
+ <> braces (text ref)
+ <> braces (lab <> text "\\label"
+ <> braces (text ref))
+ else lab)
+ $$ blankline
+ let headerWith x y = refLabel $ text x <> y
+ return $ case level' of
+ 0 -> if writerBeamer opts
+ then headerWith "\\part" stuffing
+ else headerWith "\\chapter" stuffing
+ 1 -> headerWith "\\section" stuffing
+ 2 -> headerWith "\\subsection" stuffing
+ 3 -> headerWith "\\subsubsection" stuffing
+ 4 -> headerWith "\\paragraph" stuffing
+ 5 -> headerWith "\\subparagraph" stuffing
+ _ -> txt $$ blankline
+
+
-- | Convert list of inline elements to LaTeX.
inlineListToLaTeX :: [Inline] -- ^ Inlines to convert
-> State WriterState Doc
@@ -345,7 +478,6 @@ inlineListToLaTeX lst = mapM inlineToLaTeX lst >>= return . hcat
isQuoted :: Inline -> Bool
isQuoted (Quoted _ _) = True
-isQuoted Apostrophe = True
isQuoted _ = False
-- | Convert inline element to LaTeX
@@ -353,8 +485,8 @@ inlineToLaTeX :: Inline -- ^ Inline to convert
-> State WriterState Doc
inlineToLaTeX (Emph lst) =
inlineListToLaTeX lst >>= return . inCmd "emph"
-inlineToLaTeX (Strong lst) =
- inlineListToLaTeX lst >>= return . inCmd "textbf"
+inlineToLaTeX (Strong lst) =
+ inlineListToLaTeX lst >>= return . inCmd "textbf"
inlineToLaTeX (Strikeout lst) = do
contents <- inlineListToLaTeX lst
modify $ \s -> s{ stStrikeout = True }
@@ -377,14 +509,24 @@ inlineToLaTeX (Cite cits lst) = do
Biblatex -> citationsToBiblatex cits
_ -> inlineListToLaTeX lst
-inlineToLaTeX (Code _ str) = do
- st <- get
- if writerListings (stOptions st)
- then do
- when (stInNote st) $ modify $ \s -> s{ stVerbInNote = True }
- let chr = ((enumFromTo '!' '~') \\ str) !! 0
- return $ text $ "\\lstinline" ++ [chr] ++ str ++ [chr]
- else return $ text $ "\\texttt{" ++ stringToLaTeX str ++ "}"
+inlineToLaTeX (Code (_,classes,_) str) = do
+ opts <- gets stOptions
+ case () of
+ _ | writerListings opts -> listingsCode
+ | writerHighlight opts && not (null classes) -> highlightCode
+ | otherwise -> rawCode
+ where listingsCode = do
+ inNote <- gets stInNote
+ when inNote $ modify $ \s -> s{ stVerbInNote = True }
+ let chr = ((enumFromTo '!' '~') \\ str) !! 0
+ return $ text $ "\\lstinline" ++ [chr] ++ str ++ [chr]
+ highlightCode = do
+ case highlight formatLaTeXInline ("",classes,[]) str of
+ Nothing -> rawCode
+ Just h -> modify (\st -> st{ stHighlighting = True }) >>
+ return (text h)
+ rawCode = return
+ $ text $ "\\texttt{" ++ stringToLaTeX False str ++ "}"
inlineToLaTeX (Quoted SingleQuote lst) = do
contents <- inlineListToLaTeX lst
csquotes <- liftM stCsquotes get
@@ -411,11 +553,7 @@ inlineToLaTeX (Quoted DoubleQuote lst) = do
then "\\,"
else empty
return $ "``" <> s1 <> contents <> s2 <> "''"
-inlineToLaTeX Apostrophe = return $ char '\''
-inlineToLaTeX EmDash = return "---"
-inlineToLaTeX EnDash = return "--"
-inlineToLaTeX Ellipses = return "\\ldots{}"
-inlineToLaTeX (Str str) = return $ text $ stringToLaTeX str
+inlineToLaTeX (Str str) = return $ text $ stringToLaTeX False str
inlineToLaTeX (Math InlineMath str) = return $ char '$' <> text str <> char '$'
inlineToLaTeX (Math DisplayMath str) = return $ "\\[" <> text str <> "\\]"
inlineToLaTeX (RawInline "latex" str) = return $ text str
@@ -429,7 +567,7 @@ inlineToLaTeX (Link txt (src, _)) =
do modify $ \s -> s{ stUrl = True }
return $ text $ "\\url{" ++ x ++ "}"
_ -> do contents <- inlineListToLaTeX txt
- return $ text ("\\href{" ++ stringToLaTeX src ++ "}{") <>
+ return $ text ("\\href{" ++ stringToLaTeX True src ++ "}{") <>
contents <> char '}'
inlineToLaTeX (Image _ (source, _)) = do
modify $ \s -> s{ stGraphics = True }
diff --git a/src/Text/Pandoc/Writers/Man.hs b/src/Text/Pandoc/Writers/Man.hs
index 78b9274d6..d3735efa7 100644
--- a/src/Text/Pandoc/Writers/Man.hs
+++ b/src/Text/Pandoc/Writers/Man.hs
@@ -98,7 +98,13 @@ noteToMan opts num note = do
-- | Association list of characters to escape.
manEscapes :: [(Char, String)]
-manEscapes = [('\160', "\\ "), ('\'', "\\[aq]")] ++ backslashEscapes "@\\"
+manEscapes = [ ('\160', "\\ ")
+ , ('\'', "\\[aq]")
+ , ('’', "'")
+ , ('\x2014', "\\[em]")
+ , ('\x2013', "\\[en]")
+ , ('\x2026', "\\&...")
+ ] ++ backslashEscapes "@\\"
-- | Escape special characters for Man.
escapeString :: String -> String
@@ -303,10 +309,6 @@ inlineToMan opts (Quoted DoubleQuote lst) = do
return $ text "\\[lq]" <> contents <> text "\\[rq]"
inlineToMan opts (Cite _ lst) =
inlineListToMan opts lst
-inlineToMan _ EmDash = return $ text "\\[em]"
-inlineToMan _ EnDash = return $ text "\\[en]"
-inlineToMan _ Apostrophe = return $ char '\''
-inlineToMan _ Ellipses = return $ text "\\&..."
inlineToMan _ (Code _ str) =
return $ text $ "\\f[C]" ++ escapeCode str ++ "\\f[]"
inlineToMan _ (Str str) = return $ text $ escapeString str
diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs
index 48e9578b4..7ce939395 100644
--- a/src/Text/Pandoc/Writers/Markdown.hs
+++ b/src/Text/Pandoc/Writers/Markdown.hs
@@ -233,17 +233,19 @@ blockToMarkdown _ HorizontalRule =
blockToMarkdown opts (Header level inlines) = do
contents <- inlineListToMarkdown opts inlines
st <- get
- -- use setext style headers if in literate haskell mode.
- -- ghc interprets '#' characters in column 1 as line number specifiers.
- if writerLiterateHaskell opts || stPlain st
- then let len = offset contents
- in return $ contents <> cr <>
- (case level of
- 1 -> text $ replicate len '='
- 2 -> text $ replicate len '-'
- _ -> empty) <> blankline
- else return $
- text ((replicate level '#') ++ " ") <> contents <> blankline
+ let setext = writerSetextHeaders opts
+ return $ nowrap
+ $ case level of
+ 1 | setext ->
+ contents <> cr <> text (replicate (offset contents) '=') <>
+ blankline
+ 2 | setext ->
+ contents <> cr <> text (replicate (offset contents) '-') <>
+ blankline
+ -- ghc interprets '#' characters in column 1 as linenum specifiers.
+ _ | stPlain st || writerLiterateHaskell opts ->
+ contents <> blankline
+ _ -> text (replicate level '#') <> space <> contents <> blankline
blockToMarkdown opts (CodeBlock (_,classes,_) str)
| "haskell" `elem` classes && "literate" `elem` classes &&
writerLiterateHaskell opts =
@@ -434,10 +436,6 @@ inlineToMarkdown opts (Quoted SingleQuote lst) = do
inlineToMarkdown opts (Quoted DoubleQuote lst) = do
contents <- inlineListToMarkdown opts lst
return $ "“" <> contents <> "”"
-inlineToMarkdown _ EmDash = return "\8212"
-inlineToMarkdown _ EnDash = return "\8211"
-inlineToMarkdown _ Apostrophe = return "\8217"
-inlineToMarkdown _ Ellipses = return "\8230"
inlineToMarkdown opts (Code attr str) =
let tickGroups = filter (\s -> '`' `elem` s) $ group str
longest = if null tickGroups
@@ -495,17 +493,16 @@ inlineToMarkdown opts (Cite (c:cs) lst)
modekey SuppressAuthor = "-"
modekey _ = ""
inlineToMarkdown _ (Cite _ _) = return $ text ""
-inlineToMarkdown opts (Link txt (src', tit)) = do
+inlineToMarkdown opts (Link txt (src, tit)) = do
linktext <- inlineListToMarkdown opts txt
let linktitle = if null tit
then empty
else text $ " \"" ++ tit ++ "\""
- let src = unescapeURI src'
let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
- let useRefLinks = writerReferenceLinks opts
let useAuto = case (tit,txt) of
("", [Code _ s]) | s == srcSuffix -> True
_ -> False
+ let useRefLinks = writerReferenceLinks opts && not useAuto
ref <- if useRefLinks then getReference txt (src, tit) else return []
reftext <- inlineListToMarkdown opts ref
return $ if useAuto
diff --git a/src/Text/Pandoc/Writers/MediaWiki.hs b/src/Text/Pandoc/Writers/MediaWiki.hs
index a7c7fc482..f31a2c2d1 100644
--- a/src/Text/Pandoc/Writers/MediaWiki.hs
+++ b/src/Text/Pandoc/Writers/MediaWiki.hs
@@ -346,22 +346,14 @@ inlineToMediaWiki opts (SmallCaps lst) = inlineListToMediaWiki opts lst
inlineToMediaWiki opts (Quoted SingleQuote lst) = do
contents <- inlineListToMediaWiki opts lst
- return $ "&lsquo;" ++ contents ++ "&rsquo;"
+ return $ "\8216" ++ contents ++ "\8217"
inlineToMediaWiki opts (Quoted DoubleQuote lst) = do
contents <- inlineListToMediaWiki opts lst
- return $ "&ldquo;" ++ contents ++ "&rdquo;"
+ return $ "\8220" ++ contents ++ "\8221"
inlineToMediaWiki opts (Cite _ lst) = inlineListToMediaWiki opts lst
-inlineToMediaWiki _ EmDash = return "&mdash;"
-
-inlineToMediaWiki _ EnDash = return "&ndash;"
-
-inlineToMediaWiki _ Apostrophe = return "&rsquo;"
-
-inlineToMediaWiki _ Ellipses = return "&hellip;"
-
inlineToMediaWiki _ (Code _ str) =
return $ "<tt>" ++ (escapeString str) ++ "</tt>"
diff --git a/src/Text/Pandoc/Writers/ODT.hs b/src/Text/Pandoc/Writers/ODT.hs
index f8030965c..f8f22494f 100644
--- a/src/Text/Pandoc/Writers/ODT.hs
+++ b/src/Text/Pandoc/Writers/ODT.hs
@@ -34,9 +34,10 @@ import System.FilePath ( (</>), takeExtension )
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.UTF8 ( fromString )
import Codec.Archive.Zip
-import System.Time
+import Data.Time.Clock.POSIX
import Paths_pandoc ( getDataFileName )
import Text.Pandoc.Shared ( WriterOptions(..) )
+import Text.Pandoc.ImageSize ( readImageSize, sizeInPoints )
import Text.Pandoc.MIME ( getMimeType )
import Text.Pandoc.Definition
import Text.Pandoc.Generic
@@ -71,7 +72,7 @@ writeODT mbRefOdt opts doc = do
let sourceDir = writerSourceDirectory opts
doc' <- bottomUpM (transformPic sourceDir picEntriesRef) doc
let newContents = writeOpenDocument opts{writerWrapText = False} doc'
- (TOD epochtime _) <- getClockTime
+ epochtime <- floor `fmap` getPOSIXTime
let contentEntry = toEntry "content.xml" epochtime $ fromString newContents
picEntries <- readIORef picEntriesRef
let archive = foldr addEntryToArchive refArchive $ contentEntry : picEntries
@@ -102,11 +103,16 @@ writeODT mbRefOdt opts doc = do
transformPic :: FilePath -> IORef [Entry] -> Inline -> IO Inline
transformPic sourceDir entriesRef (Image lab (src,tit)) = do
let src' = unEscapeString src
+ mbSize <- readImageSize src'
+ let tit' = case mbSize of
+ Just s -> let (w,h) = sizeInPoints s
+ in show w ++ "x" ++ show h
+ Nothing -> tit
entries <- readIORef entriesRef
let newsrc = "Pictures/" ++ show (length entries) ++ takeExtension src'
catch (readEntry [] (sourceDir </> src') >>= \entry ->
modifyIORef entriesRef (entry{ eRelativePath = newsrc } :) >>
- return (Image lab (newsrc, tit)))
+ return (Image lab (newsrc, tit')))
(\_ -> return (Emph lab))
transformPic _ _ x = return x
diff --git a/src/Text/Pandoc/Writers/OpenDocument.hs b/src/Text/Pandoc/Writers/OpenDocument.hs
index e675f4e65..a0317511a 100644
--- a/src/Text/Pandoc/Writers/OpenDocument.hs
+++ b/src/Text/Pandoc/Writers/OpenDocument.hs
@@ -40,7 +40,7 @@ import Text.Printf ( printf )
import Control.Applicative ( (<$>) )
import Control.Arrow ( (***), (>>>) )
import Control.Monad.State hiding ( when )
-import Data.Char (chr)
+import Data.Char (chr, isDigit)
import qualified Data.Map as Map
-- | Auxiliary function to convert Plain block to Para.
@@ -154,8 +154,8 @@ inHeaderTags i d =
, ("text:outline-level", show i)] d
inQuotes :: QuoteType -> Doc -> Doc
-inQuotes SingleQuote s = text "&#8216;" <> s <> text "&#8217;"
-inQuotes DoubleQuote s = text "&#8220;" <> s <> text "&#8221;"
+inQuotes SingleQuote s = char '\8216' <> s <> char '\8217'
+inQuotes DoubleQuote s = char '\8220' <> s <> char '\8221'
handleSpaces :: String -> Doc
handleSpaces s
@@ -361,10 +361,6 @@ inlinesToOpenDocument o l = hcat <$> mapM (inlineToOpenDocument o) l
-- | Convert an inline element to OpenDocument.
inlineToOpenDocument :: WriterOptions -> Inline -> State WriterState Doc
inlineToOpenDocument o ils
- | Ellipses <- ils = inTextStyle $ text "&#8230;"
- | EmDash <- ils = inTextStyle $ text "&#8212;"
- | EnDash <- ils = inTextStyle $ text "&#8211;"
- | Apostrophe <- ils = inTextStyle $ text "&#8217;"
| Space <- ils = inTextStyle space
| LineBreak <- ils = return $ selfClosingTag "text:line-break" []
| Str s <- ils = inTextStyle $ handleSpaces $ escapeStringForXML s
@@ -382,7 +378,7 @@ inlineToOpenDocument o ils
| RawInline "html" s <- ils = preformatted s -- for backwards compat.
| RawInline _ _ <- ils = return empty
| Link l (s,t) <- ils = mkLink s t <$> inlinesToOpenDocument o l
- | Image _ (s,_) <- ils = return $ mkImg s
+ | Image _ (s,t) <- ils = return $ mkImg s t
| Note l <- ils = mkNote l
| otherwise = return empty
where
@@ -391,7 +387,7 @@ inlineToOpenDocument o ils
, ("xlink:href" , s )
, ("office:name", t )
] . inSpanTags "Definition"
- mkImg s = inTags False "draw:frame" [] $
+ mkImg s t = inTags False "draw:frame" (attrsFromTitle t) $
selfClosingTag "draw:image" [ ("xlink:href" , s )
, ("xlink:type" , "simple")
, ("xlink:show" , "embed" )
@@ -407,6 +403,17 @@ inlineToOpenDocument o ils
addNote nn
return nn
+-- a title of the form "120x140" will be interpreted as image
+-- size in points.
+attrsFromTitle :: String -> [(String,String)]
+attrsFromTitle s = if null xs || null ys
+ then []
+ else [("svg:width",xs ++ "pt"),("svg:height",ys ++ "pt")]
+ where (xs,rest) = span isDigit s
+ ys = case rest of
+ ('x':zs) | all isDigit zs -> zs
+ _ -> ""
+
bulletListStyle :: Int -> State WriterState (Int,(Int,[Doc]))
bulletListStyle l =
let doStyles i = inTags True "text:list-level-style-bullet"
diff --git a/src/Text/Pandoc/Writers/Org.hs b/src/Text/Pandoc/Writers/Org.hs
index f7f314428..4c77ba7c6 100644
--- a/src/Text/Pandoc/Writers/Org.hs
+++ b/src/Text/Pandoc/Writers/Org.hs
@@ -95,7 +95,12 @@ noteToOrg num note = do
-- | Escape special characters for Org.
escapeString :: String -> String
-escapeString = escapeStringUsing (backslashEscapes "^_")
+escapeString = escapeStringUsing $
+ [ ('\x2014',"---")
+ , ('\x2013',"--")
+ , ('\x2019',"'")
+ , ('\x2026',"...")
+ ] ++ backslashEscapes "^_"
titleToOrg :: [Inline] -> State WriterState Doc
titleToOrg [] = return empty
@@ -249,10 +254,6 @@ inlineToOrg (Quoted DoubleQuote lst) = do
contents <- inlineListToOrg lst
return $ "\"" <> contents <> "\""
inlineToOrg (Cite _ lst) = inlineListToOrg lst
-inlineToOrg EmDash = return "---"
-inlineToOrg EnDash = return "--"
-inlineToOrg Apostrophe = return "'"
-inlineToOrg Ellipses = return "..."
inlineToOrg (Code _ str) = return $ "=" <> text str <> "="
inlineToOrg (Str str) = return $ text $ escapeString str
inlineToOrg (Math t str) = do
@@ -272,8 +273,7 @@ inlineToOrg (Link txt (src, _)) = do
_ -> do contents <- inlineListToOrg txt
modify $ \s -> s{ stLinks = True }
return $ "[[" <> text src <> "][" <> contents <> "]]"
-inlineToOrg (Image _ (source', _)) = do
- let source = unescapeURI source'
+inlineToOrg (Image _ (source, _)) = do
modify $ \s -> s{ stImages = True }
return $ "[[" <> text source <> "]]"
inlineToOrg (Note contents) = do
diff --git a/src/Text/Pandoc/Writers/RST.hs b/src/Text/Pandoc/Writers/RST.hs
index d4adaa929..d6e5b5c9e 100644
--- a/src/Text/Pandoc/Writers/RST.hs
+++ b/src/Text/Pandoc/Writers/RST.hs
@@ -157,7 +157,7 @@ blockToRST (Header level inlines) = do
contents <- inlineListToRST inlines
let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
let border = text $ replicate (offset contents) headerChar
- return $ contents $$ border $$ blankline
+ return $ nowrap $ contents $$ border $$ blankline
blockToRST (CodeBlock (_,classes,_) str) = do
opts <- stOptions <$> get
let tabstop = writerTabStop opts
@@ -176,7 +176,7 @@ blockToRST (Table caption _ widths headers rows) = do
else blankline <> text "Table: " <> caption'
headers' <- mapM blockListToRST headers
rawRows <- mapM (mapM blockListToRST) rows
- let isSimple = all (==0) widths && all (all (\bs -> length bs == 1)) rows
+ let isSimple = all (==0) widths && all (all (\bs -> length bs <= 1)) rows
let numChars = maximum . map offset
opts <- get >>= return . stOptions
let widthsInChars =
@@ -281,26 +281,24 @@ inlineToRST (Quoted DoubleQuote lst) = do
return $ "“" <> contents <> "”"
inlineToRST (Cite _ lst) =
inlineListToRST lst
-inlineToRST EmDash = return $ char '\8212'
-inlineToRST EnDash = return $ char '\8211'
-inlineToRST Apostrophe = return $ char '\8217'
-inlineToRST Ellipses = return $ char '\8230'
inlineToRST (Code _ str) = return $ "``" <> text str <> "``"
inlineToRST (Str str) = return $ text $ escapeString str
inlineToRST (Math t str) = do
modify $ \st -> st{ stHasMath = True }
return $ if t == InlineMath
- then ":math:`$" <> text str <> "$`"
- else ":math:`$$" <> text str <> "$$`"
+ then ":math:`" <> text str <> "`" <> beforeNonBlank "\\ "
+ else if '\n' `elem` str
+ then blankline $$ ".. math::" $$
+ blankline $$ nest 3 (text str) $$ blankline
+ else blankline $$ (".. math:: " <> text str) $$ blankline
inlineToRST (RawInline _ _) = return empty
inlineToRST (LineBreak) = return cr -- there's no line break in RST
inlineToRST Space = return space
inlineToRST (Link [Code _ str] (src, _)) | src == str ||
src == "mailto:" ++ str = do
let srcSuffix = if isPrefixOf "mailto:" src then drop 7 src else src
- return $ text $ unescapeURI srcSuffix
-inlineToRST (Link txt (src', tit)) = do
- let src = unescapeURI src'
+ return $ text srcSuffix
+inlineToRST (Link txt (src, tit)) = do
useReferenceLinks <- get >>= return . writerReferenceLinks . stOptions
linktext <- inlineListToRST $ normalizeSpaces txt
if useReferenceLinks
@@ -311,8 +309,7 @@ inlineToRST (Link txt (src', tit)) = do
modify $ \st -> st { stLinks = refs' }
return $ "`" <> linktext <> "`_"
else return $ "`" <> linktext <> " <" <> text src <> ">`_"
-inlineToRST (Image alternate (source', tit)) = do
- let source = unescapeURI source'
+inlineToRST (Image alternate (source, tit)) = do
pics <- get >>= return . stImages
let labelsUsed = map fst pics
let txt = if null alternate || alternate == [Str ""] ||
diff --git a/src/Text/Pandoc/Writers/RTF.hs b/src/Text/Pandoc/Writers/RTF.hs
index eb36c1ca6..4e7c2a7cd 100644
--- a/src/Text/Pandoc/Writers/RTF.hs
+++ b/src/Text/Pandoc/Writers/RTF.hs
@@ -106,7 +106,15 @@ handleUnicode (c:cs) =
-- | Escape special characters.
escapeSpecial :: String -> String
-escapeSpecial = escapeStringUsing (('\t',"\\tab "):(backslashEscapes "{\\}"))
+escapeSpecial = escapeStringUsing $
+ [ ('\t',"\\tab ")
+ , ('\8216',"\\u8216'")
+ , ('\8217',"\\u8217'")
+ , ('\8220',"\\u8220\"")
+ , ('\8221',"\\u8221\"")
+ , ('\8211',"\\u8211-")
+ , ('\8212',"\\u8212-")
+ ] ++ backslashEscapes "{\\}"
-- | Escape strings as needed for rich text format.
stringToRTF :: String -> String
@@ -287,10 +295,6 @@ inlineToRTF (Quoted SingleQuote lst) =
"\\u8216'" ++ (inlineListToRTF lst) ++ "\\u8217'"
inlineToRTF (Quoted DoubleQuote lst) =
"\\u8220\"" ++ (inlineListToRTF lst) ++ "\\u8221\""
-inlineToRTF Apostrophe = "\\u8217'"
-inlineToRTF Ellipses = "\\u8230?"
-inlineToRTF EmDash = "\\u8212-"
-inlineToRTF EnDash = "\\u8211-"
inlineToRTF (Code _ str) = "{\\f1 " ++ (codeStringToRTF str) ++ "}"
inlineToRTF (Str str) = stringToRTF str
inlineToRTF (Math _ str) = inlineListToRTF $ readTeXMath str
diff --git a/src/Text/Pandoc/Writers/Texinfo.hs b/src/Text/Pandoc/Writers/Texinfo.hs
index 4f6645cd5..563ad7044 100644
--- a/src/Text/Pandoc/Writers/Texinfo.hs
+++ b/src/Text/Pandoc/Writers/Texinfo.hs
@@ -96,6 +96,10 @@ stringToTexinfo = escapeStringUsing texinfoEscapes
, ('@', "@@")
, (',', "@comma{}") -- only needed in argument lists
, ('\160', "@ ")
+ , ('\x2014', "---")
+ , ('\x2013', "--")
+ , ('\x2026', "@dots{}")
+ , ('\x2019', "'")
]
-- | Puts contents into Texinfo command.
@@ -387,10 +391,6 @@ inlineToTexinfo (Quoted DoubleQuote lst) = do
inlineToTexinfo (Cite _ lst) =
inlineListToTexinfo lst
-inlineToTexinfo Apostrophe = return $ char '\''
-inlineToTexinfo EmDash = return $ text "---"
-inlineToTexinfo EnDash = return $ text "--"
-inlineToTexinfo Ellipses = return $ text "@dots{}"
inlineToTexinfo (Str str) = return $ text (stringToTexinfo str)
inlineToTexinfo (Math _ str) = return $ inCmd "math" $ text str
inlineToTexinfo (RawInline f str) | f == "latex" || f == "tex" =
diff --git a/src/Text/Pandoc/Writers/Textile.hs b/src/Text/Pandoc/Writers/Textile.hs
index 6614ec28e..26d5ec6d7 100644
--- a/src/Text/Pandoc/Writers/Textile.hs
+++ b/src/Text/Pandoc/Writers/Textile.hs
@@ -72,15 +72,19 @@ withUseTags action = do
-- | Escape one character as needed for Textile.
escapeCharForTextile :: Char -> String
escapeCharForTextile x = case x of
- '&' -> "&amp;"
- '<' -> "&lt;"
- '>' -> "&gt;"
- '"' -> "&quot;"
- '*' -> "&#42;"
- '_' -> "&#95;"
- '@' -> "&#64;"
- '|' -> "&#124;"
- c -> [c]
+ '&' -> "&amp;"
+ '<' -> "&lt;"
+ '>' -> "&gt;"
+ '"' -> "&quot;"
+ '*' -> "&#42;"
+ '_' -> "&#95;"
+ '@' -> "&#64;"
+ '|' -> "&#124;"
+ '\x2014' -> " -- "
+ '\x2013' -> " - "
+ '\x2019' -> "'"
+ '\x2026' -> "..."
+ c -> [c]
-- | Escape string as needed for Textile.
escapeStringForTextile :: String -> String
@@ -370,14 +374,6 @@ inlineToTextile opts (Quoted DoubleQuote lst) = do
inlineToTextile opts (Cite _ lst) = inlineListToTextile opts lst
-inlineToTextile _ EmDash = return " -- "
-
-inlineToTextile _ EnDash = return " - "
-
-inlineToTextile _ Apostrophe = return "'"
-
-inlineToTextile _ Ellipses = return "..."
-
inlineToTextile _ (Code _ str) =
return $ if '@' `elem` str
then "<tt>" ++ escapeStringForXML str ++ "</tt>"
diff --git a/src/Text/Pandoc/XML.hs b/src/Text/Pandoc/XML.hs
index e21525018..7a1c8bdd8 100644
--- a/src/Text/Pandoc/XML.hs
+++ b/src/Text/Pandoc/XML.hs
@@ -33,9 +33,13 @@ module Text.Pandoc.XML ( stripTags,
inTags,
selfClosingTag,
inTagsSimple,
- inTagsIndented ) where
+ inTagsIndented,
+ toEntities,
+ fromEntities ) where
import Text.Pandoc.Pretty
+import Data.Char (ord, isAscii)
+import Text.HTML.TagSoup.Entity (lookupEntity)
-- | Remove everything between <...>
stripTags :: String -> String
@@ -89,3 +93,22 @@ inTagsSimple tagType = inTags False tagType []
-- | Put the supplied contents in indented block btw start and end tags.
inTagsIndented :: String -> Doc -> Doc
inTagsIndented tagType = inTags True tagType []
+
+-- | Escape all non-ascii characters using numerical entities.
+toEntities :: String -> String
+toEntities [] = ""
+toEntities (c:cs)
+ | isAscii c = c : toEntities cs
+ | otherwise = "&#" ++ show (ord c) ++ ";" ++ toEntities cs
+
+-- Unescapes XML entities
+fromEntities :: String -> String
+fromEntities ('&':xs) =
+ case lookupEntity ent of
+ Just c -> c : fromEntities rest
+ Nothing -> '&' : fromEntities rest
+ where (ent, rest) = case break (==';') xs of
+ (zs,';':ys) -> (zs,ys)
+ _ -> ("",xs)
+fromEntities (x:xs) = x : fromEntities xs
+fromEntities [] = []
diff --git a/src/markdown2pdf.hs b/src/markdown2pdf.hs
deleted file mode 100644
index d6ee39dab..000000000
--- a/src/markdown2pdf.hs
+++ /dev/null
@@ -1,256 +0,0 @@
-module Main where
-
-import Data.List (isInfixOf, intercalate, isPrefixOf)
-import Data.Maybe (isNothing)
-import qualified Data.ByteString as BS
-import Codec.Binary.UTF8.String (decodeString, encodeString)
-import Data.ByteString.UTF8 (toString)
-import Control.Monad (unless, guard, liftM, when)
-import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO)
-import Control.Exception (tryJust, bracket, evaluate)
-
-import System.IO
-import System.IO.Error (isDoesNotExistError)
-import System.Environment ( getArgs, getProgName )
-import qualified Text.Pandoc.UTF8 as UTF8
-import System.Exit (ExitCode (..), exitWith)
-import System.FilePath
-import System.Directory
-import System.Process
-
--- A variant of 'readProcessWithExitCode' that does not
--- cause an error if the output is not UTF-8. (Copied
--- with slight variants from 'System.Process'.)
-readProcessWithExitCode'
- :: FilePath -- ^ command to run
- -> [String] -- ^ any arguments
- -> String -- ^ standard input
- -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr
-readProcessWithExitCode' cmd args input = do
- (Just inh, Just outh, Just errh, pid) <-
- createProcess (proc cmd args){ std_in = CreatePipe,
- std_out = CreatePipe,
- std_err = CreatePipe }
-
- outMVar <- newEmptyMVar
-
- -- fork off a thread to start consuming stdout
- out <- liftM toString $ BS.hGetContents outh
- _ <- forkIO $ evaluate (length out) >> putMVar outMVar ()
-
- -- fork off a thread to start consuming stderr
- err <- liftM toString $ BS.hGetContents errh
- _ <- forkIO $ evaluate (length err) >> putMVar outMVar ()
-
- -- now write and flush any input
- when (not (null input)) $ do hPutStr inh input; hFlush inh
- hClose inh -- done with stdin
-
- -- wait on the output
- takeMVar outMVar
- takeMVar outMVar
- hClose outh
-
- -- wait on the process
- ex <- waitForProcess pid
-
- return (ex, out, err)
-
-run :: FilePath -> [String] -> IO (Either String String)
-run file opts = do
- (code, out, err) <- readProcessWithExitCode' (encodeString file)
- (map encodeString opts) ""
- let msg = out ++ err
- case code of
- ExitFailure _ -> return $ Left $! msg
- ExitSuccess -> return $ Right $! msg
-
-parsePandocArgs :: [String] -> IO (Maybe ([String], String))
-parsePandocArgs args = do
- result <- run "pandoc" $ ["--dump-args"] ++ args
- return $ either error (parse . map trim . lines) result
- where parse [] = Nothing
- parse ("-":[]) = Just ([], "stdin") -- no output or input
- parse ("-":x:xs) = Just (x:xs, dropExtension x) -- no output
- parse ( x :xs) = Just (xs, dropExtension x) -- at least output
- --trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
- trim = takeWhile (/='\r') . dropWhile (=='\r')
-
-runPandoc :: [String] -> FilePath -> IO (Either String FilePath)
-runPandoc inputsAndArgs output = do
- let texFile = addExtension output "tex"
- result <- run "pandoc" $
- ["-s", "--no-wrap", "-r", "markdown", "-w", "latex"]
- ++ inputsAndArgs ++ ["-o", texFile]
- return $ either Left (const $ Right texFile) result
-
-runLatexRaw :: String -> FilePath -> IO (Either (Either String String) FilePath)
-runLatexRaw latexProgram file = do
- -- we ignore the ExitCode because pdflatex always fails the first time
- run latexProgram ["-halt-on-error", "-interaction", "nonstopmode",
- "-output-directory", takeDirectory file, dropExtension file] >> return ()
- let pdfFile = replaceExtension file "pdf"
- let logFile = replaceExtension file "log"
- txt <- tryJust (guard . isDoesNotExistError)
- (liftM toString $ BS.readFile logFile)
- let checks = checkLatex $ either (const "") id txt
- case checks of
- -- err , bib , ref , msg
- (True , _ , _ , msg) -> return $ Left $ Left msg -- failure
- (False, True , _ , msg) -> runBibtex file >>
- (return $ Left $ Right msg) -- citations
- (False, _ , True, msg) -> return $ Left $ Right msg -- references
- (False, False, False, _ ) -> return $ Right pdfFile -- success
-
-runLatex :: String -> FilePath -> IO (Either String FilePath)
-runLatex latexProgram file = step 3
- where
- step n = do
- result <- runLatexRaw latexProgram file
- case result of
- Left (Left err) -> return $ Left err
- Left (Right _) | n > 1 -> step (n-1 :: Int)
- Right _ | n > 2 -> step (n-1 :: Int)
- Left (Right msg) -> return $ Left msg
- Right pdfFile -> return $ Right pdfFile
-
-checkLatex :: String -> (Bool, Bool, Bool, String)
-checkLatex "" = (True, False, False, "Could not read log file")
-checkLatex txt = (err , bib, ref, unlines $! msgs ++ tips)
- where
- xs `oneOf` x = any (flip isInfixOf x) xs
- msgs = dropWhile (not . errorline) $ lines txt
- errorline ('!':_) = True
- errorline _ = False
- tips = checkPackages msgs
- err = any (oneOf ["!", "LaTeX Error:", "Latex Error:"]) msgs
- bib = any (oneOf ["Warning: Citation"
- ,"Warning: There were undefined citations"]) msgs
- ref = any (oneOf ["Warning: Reference"
- ,"Warning: Label"
- ,"Warning: There were undefined references"
- ]) msgs
-
-checkPackages :: [String] -> [String]
-checkPackages = concatMap chks
- where -- for each message, search 'pks' for matches and give a hint
- chks x = concatMap (chk x) pks
- chk x (k,v) = if sub k `isInfixOf` x then tip k v else []
- sub k = "`" ++ k ++ ".sty' not found"
- tip k v = ["Please install the '" ++ k ++
- "' package from CTAN:", " " ++ v]
- pks = [("ucs"
- ,"http://www.ctan.org/tex-archive/macros/latex/contrib/unicode/")
- ,("ulem"
- ,"http://www.ctan.org/tex-archive/macros/latex/contrib/misc/")
- ,("graphicx"
- ,"http://www.ctan.org/tex-archive/macros/latex/required/graphics/")
- ,("fancyhdr"
- ,"http://www.ctan.org/tex-archive/macros/latex/contrib/fancyhdr/")
- ,("array"
- ,"http://www.ctan.org/tex-archive/macros/latex/required/tools/")]
-
-runBibtex :: FilePath -> IO (Either String FilePath)
-runBibtex file = do
- let auxFile = replaceExtension file "aux"
- result <- run "bibtex" [auxFile]
- return $ either Left (const $ Right auxFile) result
-
-exit :: String -> IO a
-exit x = do
- progName <- getProgName
- UTF8.hPutStrLn stderr $ progName ++ ": " ++ x
- exitWith $ ExitFailure 1
-
-saveStdin :: FilePath -> IO (Either String FilePath)
-saveStdin file = do
- text <- liftM toString $ BS.getContents
- UTF8.writeFile file text
- fileExist <- doesFileExist (encodeString file)
- case fileExist of
- False -> return $ Left $! "Could not create " ++ file
- True -> return $ Right file
-
-saveOutput :: FilePath -> FilePath -> IO ()
-saveOutput input output = do
- copyFile (encodeString input) (encodeString output)
- UTF8.hPutStrLn stderr $! "Created " ++ output
-
-main :: IO ()
-main = bracket
- -- acquire resource
- (do dir <- getTemporaryDirectory
- let tmp = dir </> "pandoc"
- createDirectoryIfMissing True tmp
- return tmp)
-
- -- release resource
- ( \tmp -> removeDirectoryRecursive tmp)
-
- -- run computation
- $ \tmp -> do
- args <- liftM (map decodeString) getArgs
- -- check for invalid arguments and print help message if needed
- let goodopts = ["-f","-r","-N", "-p","-R","-H","-B","-A", "-C","-o","-V"]
- let goodoptslong = ["--from","--read","--strict",
- "--preserve-tabs","--tab-stop","--parse-raw",
- "--toc","--table-of-contents", "--xetex", "--luatex",
- "--number-sections","--include-in-header",
- "--include-before-body","--include-after-body",
- "--custom-header","--output",
- "--template", "--variable",
- "--csl", "--bibliography", "--data-dir", "--listings"]
- let isOpt ('-':_) = True
- isOpt _ = False
- let opts = filter isOpt args
- -- note that a long option can come in this form: --opt=val
- let isGoodopt x = x `elem` (goodopts ++ goodoptslong) ||
- any (\o -> (o ++ "=") `isPrefixOf` x) goodoptslong
- let markdown2pdfOpts = ["--xetex","--luatex"]
- unless (all isGoodopt opts) $ do
- (code, out, _err) <- readProcessWithExitCode "pandoc" ["--help"] ""
- UTF8.putStrLn "markdown2pdf [OPTIONS] [FILES]\nOptions:"
- UTF8.putStr $ unlines $
- filter (\l -> any (`isInfixOf` l) goodoptslong) (lines out)
- ++ map (replicate 24 ' ' ++) markdown2pdfOpts
- exitWith code
-
- let args' = filter (`notElem` markdown2pdfOpts) args
-
- -- check for executable files
- let latexProgram = if "--xetex" `elem` opts
- then "xelatex"
- else if "--luatex" `elem` opts
- then "lualatex"
- else "pdflatex"
- let execs = ["pandoc", latexProgram, "bibtex"]
- paths <- mapM findExecutable execs
- let miss = map snd $ filter (isNothing . fst) $ zip paths execs
- unless (null miss) $ exit $! "Could not find " ++ intercalate ", " miss
-
- -- parse arguments
- -- if no input given, use 'stdin'
- pandocArgs <- parsePandocArgs args'
- (input, output) <- case pandocArgs of
- Nothing -> exit "Could not parse arguments"
- Just ([],out) -> do
- stdinFile <- saveStdin (replaceDirectory (takeBaseName out) tmp)
- case stdinFile of
- Left err -> exit err
- Right f -> return ([f], out)
- -- no need because we'll pass all arguments to pandoc
- Just (_ ,out) -> return ([], out)
- -- run pandoc
- pandocRes <- runPandoc (input ++ args') $ replaceDirectory output tmp
- case pandocRes of
- Left err -> exit err
- Right texFile -> do
- -- run pdflatex
- latexRes <- runLatex latexProgram texFile
- case latexRes of
- Left err -> exit err
- Right pdfFile -> do
- -- save the output creating a backup if necessary
- saveOutput pdfFile $
- replaceDirectory pdfFile (takeDirectory output)
-
diff --git a/src/pandoc.hs b/src/pandoc.hs
index 27bc2c25c..3853d360a 100644
--- a/src/pandoc.hs
+++ b/src/pandoc.hs
@@ -1,5 +1,5 @@
{-
-Copyright (C) 2006-2011 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2006-2012 John MacFarlane <jgm@berkeley.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Main
- Copyright : Copyright (C) 2006-2011 John MacFarlane
+ Copyright : Copyright (C) 2006-2012 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley@edu>
@@ -30,24 +30,26 @@ writers.
-}
module Main where
import Text.Pandoc
-import Text.Pandoc.S5 (s5HeaderIncludes)
+import Text.Pandoc.PDF (tex2pdf)
+import Text.Pandoc.Readers.LaTeX (handleIncludes)
import Text.Pandoc.Shared ( tabFilter, ObfuscationMethod (..), readDataFile,
- headerShift, findDataFile, normalize )
-#ifdef _HIGHLIGHTING
-import Text.Pandoc.Highlighting ( languages )
-#endif
+ headerShift, findDataFile, normalize, err, warn )
+import Text.Pandoc.XML ( toEntities, fromEntities )
+import Text.Pandoc.SelfContained ( makeSelfContained )
+import Text.Pandoc.Highlighting ( languages, Style, tango, pygments,
+ espresso, kate, haddock, monochrome )
import System.Environment ( getArgs, getProgName )
import System.Exit ( exitWith, ExitCode (..) )
import System.FilePath
import System.Console.GetOpt
import Data.Char ( toLower )
import Data.List ( intercalate, isSuffixOf, isPrefixOf )
-import System.Directory ( getAppUserDataDirectory, doesFileExist )
-import System.IO ( stdout, stderr )
+import System.Directory ( getAppUserDataDirectory, doesFileExist, findExecutable )
+import System.IO ( stdout )
import System.IO.Error ( isDoesNotExistError )
import Control.Exception.Extensible ( throwIO )
import qualified Text.Pandoc.UTF8 as UTF8
-import Text.CSL
+import qualified Text.CSL as CSL
import Text.Pandoc.Biblio
import Control.Monad (when, unless, liftM)
import Network.HTTP (simpleHTTP, mkRequest, getResponseBody, RequestMethod(..))
@@ -55,35 +57,34 @@ import Network.URI (parseURI, isURI, URI(..))
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.UTF8 (toString )
import Codec.Binary.UTF8.String (decodeString, encodeString)
+import Text.CSL.Reference (Reference(..))
copyrightMessage :: String
-copyrightMessage = "\nCopyright (C) 2006-2011 John MacFarlane\n" ++
+copyrightMessage = "\nCopyright (C) 2006-2012 John MacFarlane\n" ++
"Web: http://johnmacfarlane.net/pandoc\n" ++
"This is free software; see the source for copying conditions. There is no\n" ++
"warranty, not even for merchantability or fitness for a particular purpose."
compileInfo :: String
compileInfo =
- "\nCompiled with citeproc support." ++
-#ifdef _HIGHLIGHTING
- "\nCompiled with syntax highlighting support for:\n" ++
- wrapWords 78 languages ++
-#endif
- ""
+ "\nCompiled with citeproc-hs " ++ VERSION_citeproc_hs ++ ", texmath " ++
+ VERSION_texmath ++ ", highlighting-kate " ++ VERSION_highlighting_kate ++
+ ".\nSyntax highlighting is supported for the following languages:\n " ++
+ wrapWords 4 78 languages
-- | Converts a list of strings into a single string with the items printed as
-- comma separated words in lines with a maximum line length.
-wrapWords :: Int -> [String] -> String
-wrapWords c = wrap' c c where
- wrap' _ _ [] = ""
+wrapWords :: Int -> Int -> [String] -> String
+wrapWords indent c = wrap' (c - indent) (c - indent)
+ where wrap' _ _ [] = ""
wrap' cols remaining (x:xs) = if remaining == cols
then x ++ wrap' cols (remaining - length x) xs
else if (length x + 1) > remaining
- then ",\n" ++ x ++ wrap' cols (cols - length x) xs
+ then ",\n" ++ replicate indent ' ' ++ x ++ wrap' cols (cols - length x) xs
else ", " ++ x ++ wrap' cols (remaining - (length x + 2)) xs
-isNonTextOutput :: String -> Bool
-isNonTextOutput = (`elem` ["odt","epub"])
+nonTextFormats :: [String]
+nonTextFormats = ["odt","docx","epub"]
-- | Data structure for command line options.
data Opt = Opt
@@ -101,15 +102,19 @@ data Opt = Opt
, optNumberSections :: Bool -- ^ Number sections in LaTeX
, optSectionDivs :: Bool -- ^ Put sections in div tags in HTML
, optIncremental :: Bool -- ^ Use incremental lists in Slidy/S5
- , optOffline :: Bool -- ^ Make slideshow accessible offline
- , optXeTeX :: Bool -- ^ Format latex for xetex
+ , optSelfContained :: Bool -- ^ Make HTML accessible offline
, optSmart :: Bool -- ^ Use smart typography
+ , optOldDashes :: Bool -- ^ Parse dashes like pandoc <=1.8.2.1
, optHtml5 :: Bool -- ^ Produce HTML5 in HTML
+ , optHighlight :: Bool -- ^ Highlight source code
+ , optHighlightStyle :: Style -- ^ Style to use for highlighted code
, optChapters :: Bool -- ^ Use chapter for top-level sects
, optHTMLMathMethod :: HTMLMathMethod -- ^ Method to print HTML math
, optReferenceODT :: Maybe FilePath -- ^ Path of reference.odt
+ , optReferenceDocx :: Maybe FilePath -- ^ Path of reference.docx
, optEPUBStylesheet :: Maybe String -- ^ EPUB stylesheet
, optEPUBMetadata :: String -- ^ EPUB metadata
+ , optEPUBFonts :: [FilePath] -- ^ EPUB fonts to embed
, optDumpArgs :: Bool -- ^ Output command-line arguments
, optIgnoreArgs :: Bool -- ^ Ignore command-line arguments
, optStrict :: Bool -- ^ Use strict markdown syntax
@@ -124,8 +129,12 @@ data Opt = Opt
, optCiteMethod :: CiteMethod -- ^ Method to output cites
, optBibliography :: [String]
, optCslFile :: FilePath
+ , optAbbrevsFile :: Maybe FilePath
, optListings :: Bool -- ^ Use listings package for code blocks
- , optAscii :: Bool -- ^ Avoid using nonascii characters
+ , optLaTeXEngine :: String -- ^ Program to use for latex -> pdf
+ , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
+ , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
+ , optAscii :: Bool -- ^ Use ascii characters only in html
}
-- | Defaults for command-line options.
@@ -145,15 +154,19 @@ defaultOpts = Opt
, optNumberSections = False
, optSectionDivs = False
, optIncremental = False
- , optOffline = False
- , optXeTeX = False
+ , optSelfContained = False
, optSmart = False
+ , optOldDashes = False
, optHtml5 = False
+ , optHighlight = True
+ , optHighlightStyle = pygments
, optChapters = False
, optHTMLMathMethod = PlainMath
, optReferenceODT = Nothing
+ , optReferenceDocx = Nothing
, optEPUBStylesheet = Nothing
, optEPUBMetadata = ""
+ , optEPUBFonts = []
, optDumpArgs = False
, optIgnoreArgs = False
, optStrict = False
@@ -168,7 +181,11 @@ defaultOpts = Opt
, optCiteMethod = Citeproc
, optBibliography = []
, optCslFile = ""
+ , optAbbrevsFile = Nothing
, optListings = False
+ , optLaTeXEngine = "pdflatex"
+ , optSlideLevel = Nothing
+ , optSetextHeaders = True
, optAscii = False
}
@@ -188,50 +205,23 @@ options =
"FORMAT")
""
- , Option "s" ["standalone"]
- (NoArg
- (\opt -> return opt { optStandalone = True }))
- "" -- "Include needed header and footer on output"
-
, Option "o" ["output"]
(ReqArg
(\arg opt -> return opt { optOutputFile = arg })
"FILENAME")
"" -- "Name of output file"
- , Option "p" ["preserve-tabs"]
- (NoArg
- (\opt -> return opt { optPreserveTabs = True }))
- "" -- "Preserve tabs instead of converting to spaces"
-
- , Option "" ["tab-stop"]
+ , Option "" ["data-dir"]
(ReqArg
- (\arg opt ->
- case reads arg of
- [(t,"")] | t > 0 -> return opt { optTabStop = t }
- _ -> do
- UTF8.hPutStrLn stderr $
- "tab-stop must be a number greater than 0"
- exitWith $ ExitFailure 31)
- "NUMBER")
- "" -- "Tab stop (default 4)"
+ (\arg opt -> return opt { optDataDir = Just arg })
+ "DIRECTORY") -- "Directory containing pandoc data files."
+ ""
, Option "" ["strict"]
(NoArg
(\opt -> return opt { optStrict = True } ))
"" -- "Disable markdown syntax extensions"
- , Option "" ["normalize"]
- (NoArg
- (\opt -> return opt { optTransforms =
- normalize : optTransforms opt } ))
- "" -- "Normalize the Pandoc AST"
-
- , Option "" ["reference-links"]
- (NoArg
- (\opt -> return opt { optReferenceLinks = True } ))
- "" -- "Use reference links in parsing HTML"
-
, Option "R" ["parse-raw"]
(NoArg
(\opt -> return opt { optParseRaw = True }))
@@ -242,145 +232,25 @@ options =
(\opt -> return opt { optSmart = True }))
"" -- "Use smart quotes, dashes, and ellipses"
- , Option "5" ["html5"]
- (NoArg
- (\opt -> return opt { optHtml5 = True }))
- "" -- "Produce HTML5 in HTML output"
-
- , Option "m" ["latexmathml", "asciimathml"]
- (OptArg
- (\arg opt ->
- return opt { optHTMLMathMethod = LaTeXMathML arg })
- "URL")
- "" -- "Use LaTeXMathML script in html output"
-
- , Option "" ["mathml"]
- (OptArg
- (\arg opt ->
- return opt { optHTMLMathMethod = MathML arg })
- "URL")
- "" -- "Use mathml for HTML math"
-
- , Option "" ["mimetex"]
- (OptArg
- (\arg opt -> do
- let url' = case arg of
- Just u -> u ++ "?"
- Nothing -> "/cgi-bin/mimetex.cgi?"
- return opt { optHTMLMathMethod = WebTeX url' })
- "URL")
- "" -- "Use mimetex for HTML math"
-
- , Option "" ["webtex"]
- (OptArg
- (\arg opt -> do
- let url' = case arg of
- Just u -> u
- Nothing -> "http://chart.apis.google.com/chart?cht=tx&chl="
- return opt { optHTMLMathMethod = WebTeX url' })
- "URL")
- "" -- "Use web service for HTML math"
-
- , Option "" ["jsmath"]
- (OptArg
- (\arg opt -> return opt { optHTMLMathMethod = JsMath arg})
- "URL")
- "" -- "Use jsMath for HTML math"
-
- , Option "" ["mathjax"]
- (OptArg
- (\arg opt -> do
- let url' = case arg of
- Just u -> u
- Nothing -> "https://d3eoax9i5htok0.cloudfront.net/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
- return opt { optHTMLMathMethod = MathJax url'})
- "URL")
- "" -- "Use MathJax for HTML math"
-
- , Option "" ["gladtex"]
- (NoArg
- (\opt -> return opt { optHTMLMathMethod = GladTeX }))
- "" -- "Use gladtex for HTML math"
-
- , Option "i" ["incremental"]
- (NoArg
- (\opt -> return opt { optIncremental = True }))
- "" -- "Make list items display incrementally in Slidy/S5"
-
- , Option "" ["offline"]
- (NoArg
- (\opt -> return opt { optOffline = True,
- optStandalone = True }))
- "" -- "Make slide shows include all the needed js and css"
-
- , Option "" ["xetex"]
+ , Option "" ["old-dashes"]
(NoArg
- (\opt -> do
- UTF8.hPutStrLn stderr $ "pandoc: --xetex is deprecated. "
- ++ "It is no longer needed for use with XeTeX."
- return opt { optXeTeX = True }))
- "" -- "Format latex for processing by XeTeX"
-
- , Option "" ["chapters"]
- (NoArg
- (\opt -> return opt { optChapters = True }))
- "" -- "Use chapter for top-level sections in LaTeX, DocBook"
-
- , Option "N" ["number-sections"]
- (NoArg
- (\opt -> return opt { optNumberSections = True }))
- "" -- "Number sections in LaTeX"
-
- , Option "" ["listings"]
- (NoArg
- (\opt -> return opt { optListings = True }))
- "" -- "Use listings package for LaTeX code blocks"
-
- , Option "" ["section-divs"]
- (NoArg
- (\opt -> return opt { optSectionDivs = True }))
- "" -- "Put sections in div tags in HTML"
-
- , Option "" ["no-wrap"]
- (NoArg
- (\opt -> return opt { optWrapText = False }))
- "" -- "Do not wrap text in output"
+ (\opt -> return opt { optSmart = True
+ , optOldDashes = True }))
+ "" -- "Use smart quotes, dashes, and ellipses"
- , Option "" ["columns"]
+ , Option "" ["base-header-level"]
(ReqArg
(\arg opt ->
case reads arg of
- [(t,"")] | t > 0 -> return opt { optColumns = t }
- _ -> do
- UTF8.hPutStrLn stderr $
- "columns must be a number greater than 0"
- exitWith $ ExitFailure 33)
- "NUMBER")
- "" -- "Length of line in characters"
-
- , Option "" ["ascii"]
- (NoArg
- (\opt -> return opt { optAscii = True }))
- "" -- "Avoid using non-ascii characters in output"
-
- , Option "" ["email-obfuscation"]
- (ReqArg
- (\arg opt -> do
- method <- case arg of
- "references" -> return ReferenceObfuscation
- "javascript" -> return JavascriptObfuscation
- "none" -> return NoObfuscation
- _ -> UTF8.hPutStrLn stderr ("Error: Unknown obfuscation method: " ++ arg) >>
- exitWith (ExitFailure 6)
- return opt { optEmailObfuscation = method })
- "none|javascript|references")
- "" -- "Method for obfuscating email in HTML"
-
- , Option "" ["id-prefix"]
- (ReqArg
- (\arg opt -> return opt { optIdentifierPrefix = arg })
- "STRING")
- "" -- "Prefix to add to automatically generated HTML identifiers"
+ [(t,"")] | t > 0 -> do
+ let oldTransforms = optTransforms opt
+ let shift = t - 1
+ return opt{ optTransforms =
+ headerShift shift : oldTransforms }
+ _ -> err 19
+ "base-header-level must be a number > 0")
+ "NUMBER")
+ "" -- "Headers base level"
, Option "" ["indented-code-classes"]
(ReqArg
@@ -389,26 +259,31 @@ options =
"STRING")
"" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks"
- , Option "" ["toc", "table-of-contents"]
- (NoArg
- (\opt -> return opt { optTableOfContents = True }))
- "" -- "Include table of contents"
+ , Option "" ["normalize"]
+ (NoArg
+ (\opt -> return opt { optTransforms =
+ normalize : optTransforms opt } ))
+ "" -- "Normalize the Pandoc AST"
- , Option "" ["base-header-level"]
+ , Option "p" ["preserve-tabs"]
+ (NoArg
+ (\opt -> return opt { optPreserveTabs = True }))
+ "" -- "Preserve tabs instead of converting to spaces"
+
+ , Option "" ["tab-stop"]
(ReqArg
(\arg opt ->
case reads arg of
- [(t,"")] | t > 0 -> do
- let oldTransforms = optTransforms opt
- let shift = t - 1
- return opt{ optTransforms =
- headerShift shift : oldTransforms }
- _ -> do
- UTF8.hPutStrLn stderr $
- "base-header-level must be a number > 0"
- exitWith $ ExitFailure 19)
+ [(t,"")] | t > 0 -> return opt { optTabStop = t }
+ _ -> err 31
+ "tab-stop must be a number greater than 0")
"NUMBER")
- "" -- "Headers base level"
+ "" -- "Tab stop (default 4)"
+
+ , Option "s" ["standalone"]
+ (NoArg
+ (\opt -> return opt { optStandalone = True }))
+ "" -- "Include needed header and footer on output"
, Option "" ["template"]
(ReqArg
@@ -425,21 +300,62 @@ options =
(k,_:v) -> do
let newvars = optVariables opt ++ [(k,v)]
return opt{ optVariables = newvars }
- _ -> do
- UTF8.hPutStrLn stderr $ "Could not parse `" ++ arg ++ "' as a key/value pair (k=v or k:v)"
- exitWith $ ExitFailure 17)
+ _ -> err 17 $
+ "Could not parse `" ++ arg ++ "' as a key/value pair (k=v or k:v)")
"KEY:VALUE")
"" -- "Use custom template"
- , Option "c" ["css"]
+ , Option "D" ["print-default-template"]
(ReqArg
- (\arg opt -> do
- -- add new link to end, so it is included in proper order
- let newvars = optVariables opt ++ [("css",arg)]
- return opt { optVariables = newvars,
- optStandalone = True })
- "URL")
- "" -- "Link to CSS style sheet"
+ (\arg _ -> do
+ templ <- getDefaultTemplate Nothing arg
+ case templ of
+ Right t -> UTF8.hPutStr stdout t
+ Left e -> error $ show e
+ exitWith ExitSuccess)
+ "FORMAT")
+ "" -- "Print default template for FORMAT"
+
+ , Option "" ["no-wrap"]
+ (NoArg
+ (\opt -> return opt { optWrapText = False }))
+ "" -- "Do not wrap text in output"
+
+ , Option "" ["columns"]
+ (ReqArg
+ (\arg opt ->
+ case reads arg of
+ [(t,"")] | t > 0 -> return opt { optColumns = t }
+ _ -> err 33 $
+ "columns must be a number greater than 0")
+ "NUMBER")
+ "" -- "Length of line in characters"
+
+ , Option "" ["toc", "table-of-contents"]
+ (NoArg
+ (\opt -> return opt { optTableOfContents = True }))
+ "" -- "Include table of contents"
+
+ , Option "" ["no-highlight"]
+ (NoArg
+ (\opt -> return opt { optHighlight = False }))
+ "" -- "Don't highlight source code"
+
+ , Option "" ["highlight-style"]
+ (ReqArg
+ (\arg opt -> do
+ newStyle <- case map toLower arg of
+ "pygments" -> return pygments
+ "tango" -> return tango
+ "espresso" -> return espresso
+ "kate" -> return kate
+ "monochrome" -> return monochrome
+ "haddock" -> return haddock
+ _ -> err 39 $
+ "Unknown style :" ++ arg
+ return opt{ optHighlightStyle = newStyle })
+ "STYLE")
+ "" -- "Style for highlighted code"
, Option "H" ["include-in-header"]
(ReqArg
@@ -474,6 +390,100 @@ options =
"FILENAME")
"" -- "File to include after document body"
+ , Option "" ["self-contained"]
+ (NoArg
+ (\opt -> return opt { optSelfContained = True,
+ optVariables = ("slidy-url","slidy") :
+ optVariables opt,
+ optStandalone = True }))
+ "" -- "Make slide shows include all the needed js and css"
+
+ , Option "" ["offline"]
+ (NoArg
+ (\opt -> do warn $ "--offline is deprecated. Use --self-contained instead."
+ return opt { optSelfContained = True,
+ optStandalone = True }))
+ "" -- "Make slide shows include all the needed js and css"
+ -- deprecated synonym for --self-contained
+
+ , Option "5" ["html5"]
+ (NoArg
+ (\opt -> do
+ warn $ "--html5 is deprecated. "
+ ++ "Use the html5 output format instead."
+ return opt { optHtml5 = True }))
+ "" -- "Produce HTML5 in HTML output"
+
+ , Option "" ["ascii"]
+ (NoArg
+ (\opt -> return opt { optAscii = True }))
+ "" -- "Use ascii characters only in HTML output"
+
+ , Option "" ["reference-links"]
+ (NoArg
+ (\opt -> return opt { optReferenceLinks = True } ))
+ "" -- "Use reference links in parsing HTML"
+
+ , Option "" ["atx-headers"]
+ (NoArg
+ (\opt -> return opt { optSetextHeaders = False } ))
+ "" -- "Use atx-style headers for markdown"
+
+ , Option "" ["chapters"]
+ (NoArg
+ (\opt -> return opt { optChapters = True }))
+ "" -- "Use chapter for top-level sections in LaTeX, DocBook"
+
+ , Option "N" ["number-sections"]
+ (NoArg
+ (\opt -> return opt { optNumberSections = True }))
+ "" -- "Number sections in LaTeX"
+
+ , Option "" ["listings"]
+ (NoArg
+ (\opt -> return opt { optListings = True }))
+ "" -- "Use listings package for LaTeX code blocks"
+
+ , Option "i" ["incremental"]
+ (NoArg
+ (\opt -> return opt { optIncremental = True }))
+ "" -- "Make list items display incrementally in Slidy/S5"
+
+ , Option "" ["slide-level"]
+ (ReqArg
+ (\arg opt -> do
+ case reads arg of
+ [(t,"")] | t >= 1 && t <= 6 ->
+ return opt { optSlideLevel = Just t }
+ _ -> err 39 $
+ "slide level must be a number between 1 and 6")
+ "NUMBER")
+ "" -- "Force header level for slides"
+
+ , Option "" ["section-divs"]
+ (NoArg
+ (\opt -> return opt { optSectionDivs = True }))
+ "" -- "Put sections in div tags in HTML"
+
+ , Option "" ["email-obfuscation"]
+ (ReqArg
+ (\arg opt -> do
+ method <- case arg of
+ "references" -> return ReferenceObfuscation
+ "javascript" -> return JavascriptObfuscation
+ "none" -> return NoObfuscation
+ _ -> err 6
+ ("Unknown obfuscation method: " ++ arg)
+ return opt { optEmailObfuscation = method })
+ "none|javascript|references")
+ "" -- "Method for obfuscating email in HTML"
+
+ , Option "" ["id-prefix"]
+ (ReqArg
+ (\arg opt -> return opt { optIdentifierPrefix = arg })
+ "STRING")
+ "" -- "Prefix to add to automatically generated HTML identifiers"
+
, Option "T" ["title-prefix"]
(ReqArg
(\arg opt -> do
@@ -483,6 +493,16 @@ options =
"STRING")
"" -- "String to prefix to HTML window title"
+ , Option "c" ["css"]
+ (ReqArg
+ (\arg opt -> do
+ -- add new link to end, so it is included in proper order
+ let newvars = optVariables opt ++ [("css",arg)]
+ return opt { optVariables = newvars,
+ optStandalone = True })
+ "URL")
+ "" -- "Link to CSS style sheet"
+
, Option "" ["reference-odt"]
(ReqArg
(\arg opt -> do
@@ -490,6 +510,13 @@ options =
"FILENAME")
"" -- "Path of custom reference.odt"
+ , Option "" ["reference-docx"]
+ (ReqArg
+ (\arg opt -> do
+ return opt { optReferenceDocx = Just arg })
+ "FILENAME")
+ "" -- "Path of custom reference.docx"
+
, Option "" ["epub-stylesheet"]
(ReqArg
(\arg opt -> do
@@ -514,16 +541,22 @@ options =
"FILENAME")
"" -- "Path of epub metadata file"
- , Option "D" ["print-default-template"]
+ , Option "" ["epub-embed-font"]
(ReqArg
- (\arg _ -> do
- templ <- getDefaultTemplate Nothing arg
- case templ of
- Right t -> UTF8.hPutStr stdout t
- Left e -> error $ show e
- exitWith ExitSuccess)
- "FORMAT")
- "" -- "Print default template for FORMAT"
+ (\arg opt -> do
+ return opt{ optEPUBFonts = arg : optEPUBFonts opt })
+ "FILE")
+ "" -- "Directory of fonts to embed"
+
+ , Option "" ["latex-engine"]
+ (ReqArg
+ (\arg opt -> do
+ let b = takeBaseName arg
+ if (b == "pdflatex" || b == "lualatex" || b == "xelatex")
+ then return opt { optLaTeXEngine = arg }
+ else err 45 "latex-engine must be pdflatex, lualatex, or xelatex.")
+ "PROGRAM")
+ "" -- "Name of latex program to use in generating PDF"
, Option "" ["bibliography"]
(ReqArg
@@ -537,6 +570,12 @@ options =
"FILENAME")
""
+ , Option "" ["citation-abbreviations"]
+ (ReqArg
+ (\arg opt -> return opt { optAbbrevsFile = Just arg })
+ "FILENAME")
+ ""
+
, Option "" ["natbib"]
(NoArg
(\opt -> return opt { optCiteMethod = Natbib }))
@@ -547,11 +586,60 @@ options =
(\opt -> return opt { optCiteMethod = Biblatex }))
"" -- "Use biblatex cite commands in LaTeX output"
- , Option "" ["data-dir"]
- (ReqArg
- (\arg opt -> return opt { optDataDir = Just arg })
- "DIRECTORY") -- "Directory containing pandoc data files."
- ""
+ , Option "m" ["latexmathml", "asciimathml"]
+ (OptArg
+ (\arg opt ->
+ return opt { optHTMLMathMethod = LaTeXMathML arg })
+ "URL")
+ "" -- "Use LaTeXMathML script in html output"
+
+ , Option "" ["mathml"]
+ (OptArg
+ (\arg opt ->
+ return opt { optHTMLMathMethod = MathML arg })
+ "URL")
+ "" -- "Use mathml for HTML math"
+
+ , Option "" ["mimetex"]
+ (OptArg
+ (\arg opt -> do
+ let url' = case arg of
+ Just u -> u ++ "?"
+ Nothing -> "/cgi-bin/mimetex.cgi?"
+ return opt { optHTMLMathMethod = WebTeX url' })
+ "URL")
+ "" -- "Use mimetex for HTML math"
+
+ , Option "" ["webtex"]
+ (OptArg
+ (\arg opt -> do
+ let url' = case arg of
+ Just u -> u
+ Nothing -> "http://chart.apis.google.com/chart?cht=tx&chl="
+ return opt { optHTMLMathMethod = WebTeX url' })
+ "URL")
+ "" -- "Use web service for HTML math"
+
+ , Option "" ["jsmath"]
+ (OptArg
+ (\arg opt -> return opt { optHTMLMathMethod = JsMath arg})
+ "URL")
+ "" -- "Use jsMath for HTML math"
+
+ , Option "" ["mathjax"]
+ (OptArg
+ (\arg opt -> do
+ let url' = case arg of
+ Just u -> u
+ Nothing -> "https://d3eoax9i5htok0.cloudfront.net/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
+ return opt { optHTMLMathMethod = MathJax url'})
+ "URL")
+ "" -- "Use MathJax for HTML math"
+
+ , Option "" ["gladtex"]
+ (NoArg
+ (\opt -> return opt { optHTMLMathMethod = GladTeX }))
+ "" -- "Use gladtex for HTML math"
, Option "" ["dump-args"]
(NoArg
@@ -579,14 +667,15 @@ options =
UTF8.hPutStr stdout (usageMessage prg options)
exitWith ExitSuccess ))
"" -- "Show help"
+
]
-- Returns usage message
usageMessage :: String -> [OptDescr (Opt -> IO Opt)] -> String
usageMessage programName = usageInfo
(programName ++ " [OPTIONS] [FILES]" ++ "\nInput formats: " ++
- (intercalate ", " $ map fst readers) ++ "\nOutput formats: " ++
- (intercalate ", " $ map fst writers ++ ["odt","epub"]) ++ "\nOptions:")
+ (wrapWords 16 78 $ map fst readers) ++ "\nOutput formats: " ++
+ (wrapWords 16 78 $ map fst writers ++ nonTextFormats) ++ "\nOptions:")
-- Determine default reader based on source file extensions
defaultReaderName :: String -> [FilePath] -> String
@@ -637,8 +726,11 @@ defaultWriterName x =
".texinfo" -> "texinfo"
".db" -> "docbook"
".odt" -> "odt"
+ ".docx" -> "docx"
".epub" -> "epub"
".org" -> "org"
+ ".asciidoc" -> "asciidoc"
+ ".pdf" -> "latex"
['.',y] | y `elem` ['1'..'9'] -> "man"
_ -> "html"
@@ -654,10 +746,8 @@ main = do
else getOpt Permute options rawArgs
unless (null errors) $
- do name <- getProgName
- mapM_ (\e -> UTF8.hPutStr stderr (name ++ ": ") >> UTF8.hPutStr stderr e) errors
- UTF8.hPutStrLn stderr $ "Try " ++ name ++ " --help for more information."
- exitWith $ ExitFailure 2
+ err 2 $ concat $ errors ++
+ ["Try " ++ prg ++ " --help for more information."]
let defaultOpts' = if compatMode
then defaultOpts { optReader = "markdown"
@@ -682,14 +772,19 @@ main = do
, optNumberSections = numberSections
, optSectionDivs = sectionDivs
, optIncremental = incremental
- , optOffline = offline
+ , optSelfContained = selfContained
, optSmart = smart
+ , optOldDashes = oldDashes
, optHtml5 = html5
+ , optHighlight = highlight
+ , optHighlightStyle = highlightStyle
, optChapters = chapters
, optHTMLMathMethod = mathMethod
, optReferenceODT = referenceODT
+ , optReferenceDocx = referenceDocx
, optEPUBStylesheet = epubStylesheet
, optEPUBMetadata = epubMetadata
+ , optEPUBFonts = epubFonts
, optDumpArgs = dumpArgs
, optIgnoreArgs = ignoreArgs
, optStrict = strict
@@ -702,8 +797,12 @@ main = do
, optDataDir = mbDataDir
, optBibliography = reffiles
, optCslFile = cslfile
+ , optAbbrevsFile = cslabbrevs
, optCiteMethod = citeMethod
, optListings = listings
+ , optLaTeXEngine = latexEngine
+ , optSlideLevel = slideLevel
+ , optSetextHeaders = setextHeaders
, optAscii = ascii
} = opts
@@ -726,17 +825,35 @@ main = do
then "html"
else "markdown"
in defaultReaderName fallback sources
- else readerName
+ else readerName
let writerName' = if null writerName
then defaultWriterName outputFile
else writerName
+ let pdfOutput = map toLower (takeExtension outputFile) == ".pdf"
+
+ when pdfOutput $ do
+ -- make sure writer is latex or beamer
+ unless (writerName' == "latex" || writerName' == "beamer" ||
+ writerName' == "latex+lhs") $
+ err 47 $ "cannot produce pdf output with " ++ writerName' ++ " writer"
+ -- check for latex program
+ mbLatex <- findExecutable latexEngine
+ case mbLatex of
+ Nothing -> err 41 $
+ latexEngine ++ " not found. " ++
+ latexEngine ++ " is needed for pdf output."
+ Just _ -> return ()
+
reader <- case (lookup readerName' readers) of
Just r -> return r
- Nothing -> error ("Unknown reader: " ++ readerName')
+ Nothing -> err 7 ("Unknown reader: " ++ readerName')
+
+ let standalone' = standalone || writerName' `elem` nonTextFormats || pdfOutput
templ <- case templatePath of
+ _ | not standalone' -> return ""
Nothing -> do
deftemp <- getDefaultTemplate datadir writerName'
case deftemp of
@@ -756,57 +873,57 @@ main = do
(\_ -> throwIO e)
else throwIO e)
- let standalone' = standalone || isNonTextOutput writerName'
-
- variables' <- case (writerName', standalone', offline) of
- ("s5", True, True) -> do
- inc <- s5HeaderIncludes datadir
- return $ ("s5includes", inc) : variables
- ("slidy", True, True) -> do
- slidyJs <- readDataFile datadir $
- "slidy" </> "slidy.min.js"
- slidyCss <- readDataFile datadir $
- "slidy" </> "slidy.css"
- return $ ("slidy-js", slidyJs) :
- ("slidy-css", slidyCss) : variables
- _ -> return variables
+ let slideVariant = case writerName' of
+ "s5" -> S5Slides
+ "slidy" -> SlidySlides
+ "dzslides" -> DZSlides
+ _ -> NoSlides
- variables'' <- case mathMethod of
+ variables' <- case mathMethod of
LaTeXMathML Nothing -> do
s <- readDataFile datadir $ "data" </> "LaTeXMathML.js"
- return $ ("mathml-script", s) : variables'
+ return $ ("mathml-script", s) : variables
MathML Nothing -> do
s <- readDataFile datadir $ "data"</>"MathMLinHTML.js"
- return $ ("mathml-script", s) : variables'
- _ -> return variables'
+ return $ ("mathml-script", s) : variables
+ _ -> return variables
+
+ variables'' <- case slideVariant of
+ DZSlides -> do
+ dztempl <- readDataFile datadir $ "dzslides" </> "template.html"
+ let dzcore = unlines $ dropWhile (not . isPrefixOf "<!-- {{{{ dzslides core")
+ $ lines dztempl
+ return $ ("dzslides-core", dzcore) : variables'
+ _ -> return variables'
- refs <- mapM (\f -> catch (readBiblioFile f) $ \e -> do
- UTF8.hPutStrLn stderr $ "Error reading bibliography `" ++ f ++ "'"
- UTF8.hPutStrLn stderr $ show e
- exitWith (ExitFailure 23)) reffiles >>= \rs -> return $ concat rs
+ -- unescape reference ids, which may contain XML entities, so
+ -- that we can do lookups with regular string equality
+ let unescapeRefId ref = ref{ refId = fromEntities (refId ref) }
+
+ refs <- mapM (\f -> catch (CSL.readBiblioFile f) $ \e ->
+ err 23 $ "Error reading bibliography `" ++ f ++ "'" ++ "\n" ++ show e)
+ reffiles >>=
+ return . map unescapeRefId . concat
let sourceDir = if null sources
then "."
else takeDirectory (head sources)
- let slideVariant = case writerName' of
- "s5" -> S5Slides
- "slidy" -> SlidySlides
- _ -> NoSlides
-
let startParserState =
defaultParserState { stateParseRaw = parseRaw,
stateTabStop = tabStop,
stateLiterateHaskell = "+lhs" `isSuffixOf` readerName' ||
lhsExtension sources,
stateStandalone = standalone',
- stateCitations = map refId refs,
+ stateCitations = map CSL.refId refs,
stateSmart = smart || writerName' `elem`
- ["latex", "context", "latex+lhs", "man"],
+ ["latex", "context", "latex+lhs", "beamer"],
+ stateOldDashes = oldDashes,
stateColumns = columns,
stateStrict = strict,
stateIndentedCodeClasses = codeBlockClasses,
- stateApplyMacros = writerName' `notElem` ["latex", "latex+lhs"] }
+ stateApplyMacros = writerName' `notElem`
+ ["latex", "latex+lhs", "beamer"] }
let writerOptions = defaultWriterOptions
{ writerStandalone = standalone',
@@ -836,16 +953,20 @@ main = do
writerIdentifierPrefix = idPrefix,
writerSourceDirectory = sourceDir,
writerUserDataDir = datadir,
- writerHtml5 = html5 &&
- "html" `isPrefixOf` writerName',
- writerChapters = chapters,
+ writerHtml5 = html5 ||
+ slideVariant == DZSlides,
+ writerChapters = chapters,
writerListings = listings,
- writerAscii = ascii }
+ writerBeamer = writerName' == "beamer",
+ writerSlideLevel = slideLevel,
+ writerHighlight = highlight,
+ writerHighlightStyle = highlightStyle,
+ writerSetextHeaders = setextHeaders
+ }
- when (isNonTextOutput writerName' && outputFile == "-") $
- do UTF8.hPutStrLn stderr ("Error: Cannot write " ++ writerName ++ " output to stdout.\n" ++
- "Specify an output file using the -o option.")
- exitWith $ ExitFailure 5
+ when (writerName' `elem` nonTextFormats&& outputFile == "-") $
+ err 5 $ "Cannot write " ++ writerName' ++ " output to stdout.\n" ++
+ "Specify an output file using the -o option."
let readSources [] = mapM readSource ["-"]
readSources srcs = mapM readSource srcs
@@ -859,7 +980,14 @@ main = do
let convertTabs = tabFilter (if preserveTabs then 0 else tabStop)
- doc <- fmap (reader startParserState . convertTabs . intercalate "\n") (readSources sources)
+ let handleIncludes' = if readerName' == "latex" || readerName' == "beamer" ||
+ readerName' == "latex+lhs" ||
+ readerName' == "context"
+ then handleIncludes
+ else return
+
+ doc <- (reader startParserState) `fmap` (readSources sources >>=
+ handleIncludes' . convertTabs . intercalate "\n")
let doc0 = foldr ($) doc transforms
@@ -881,19 +1009,41 @@ main = do
replaceDirectory
(replaceExtension cslfile "csl")
csldir
- processBiblio cslfile' refs doc1
+ processBiblio cslfile' cslabbrevs refs doc1
else return doc1
+ let writeBinary :: B.ByteString -> IO ()
+ writeBinary = B.writeFile (encodeString outputFile)
+
+ let writerFn :: FilePath -> String -> IO ()
+ writerFn "-" = UTF8.putStr
+ writerFn f = UTF8.writeFile f
+
case lookup writerName' writers of
- Nothing | writerName' == "epub" ->
- writeEPUB epubStylesheet writerOptions doc2
- >>= B.writeFile (encodeString outputFile)
- Nothing | writerName' == "odt" ->
- writeODT referenceODT writerOptions doc2
- >>= B.writeFile (encodeString outputFile)
- Just r -> writerFn outputFile result
- where writerFn "-" = UTF8.putStr
- writerFn f = UTF8.writeFile f
- result = r writerOptions doc2 ++
- ['\n' | not standalone']
- Nothing -> error $ "Unknown writer: " ++ writerName'
+ Nothing
+ | writerName' == "epub" ->
+ writeEPUB epubStylesheet epubFonts writerOptions doc2
+ >>= writeBinary
+ | writerName' == "odt" ->
+ writeODT referenceODT writerOptions doc2 >>= writeBinary
+ | writerName' == "docx" ->
+ writeDocx referenceDocx writerOptions doc2 >>= writeBinary
+ | otherwise -> err 9 ("Unknown writer: " ++ writerName')
+ Just _
+ | pdfOutput -> do
+ res <- tex2pdf latexEngine $ writeLaTeX writerOptions doc2
+ case res of
+ Right pdf -> writeBinary pdf
+ Left err' -> err 43 $ toString err'
+ Just r
+ | htmlFormat && ascii ->
+ writerFn outputFile =<< selfcontain (toEntities result)
+ | otherwise ->
+ writerFn outputFile =<< selfcontain result
+ where result = r writerOptions doc2 ++ ['\n' | not standalone']
+ htmlFormat = writerName' `elem`
+ ["html","html+lhs","html5","html5+lhs",
+ "s5","slidy","dzslides"]
+ selfcontain = if selfContained && htmlFormat
+ then makeSelfContained datadir
+ else return
diff --git a/templates/default.asciidoc b/templates/default.asciidoc
new file mode 100644
index 000000000..3e30ceef8
--- /dev/null
+++ b/templates/default.asciidoc
@@ -0,0 +1,26 @@
+$if(titleblock)$
+$title$
+$for(author)$
+:author: $author$
+$endfor$
+$if(date)$
+:date: $date$
+$endif$
+$if(toc)$
+:toc:
+$endif$
+
+$endif$
+$for(header-includes)$
+$header-includes$
+
+$endfor$
+$for(include-before)$
+$include-before$
+
+$endfor$
+$body$
+$for(include-after)$
+
+$include-after$
+$endfor$
diff --git a/templates/default.beamer b/templates/default.beamer
new file mode 100644
index 000000000..db9210ef1
--- /dev/null
+++ b/templates/default.beamer
@@ -0,0 +1,141 @@
+\documentclass[$if(fontsize)$$fontsize$,$endif$$if(handout)$handout,$endif$$if(beamer)$ignorenonframetext,$endif$]{$documentclass$}
+$if(theme)$
+\usetheme{$theme$}
+$endif$
+$if(colortheme)$
+\usecolortheme{$colortheme$}
+$endif$
+\usepackage{amssymb,amsmath}
+\usepackage{ifxetex,ifluatex}
+\ifxetex
+ \usepackage{fontspec,xltxtra,xunicode}
+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
+\else
+ \ifluatex
+ \usepackage{fontspec}
+ \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
+ \else
+ \usepackage[utf8]{inputenc}
+ \fi
+\fi
+$if(natbib)$
+\usepackage{natbib}
+\bibliographystyle{plainnat}
+$endif$
+$if(biblatex)$
+\usepackage{biblatex}
+$if(biblio-files)$
+\bibliography{$biblio-files$}
+$endif$
+$endif$
+$if(listings)$
+\usepackage{listings}
+$endif$
+$if(lhs)$
+\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
+$endif$
+$if(highlighting-macros)$
+$highlighting-macros$
+$endif$
+$if(verbatim-in-note)$
+\usepackage{fancyvrb}
+$endif$
+$if(fancy-enums)$
+% Redefine labelwidth for lists; otherwise, the enumerate package will cause
+% markers to extend beyond the left margin.
+\makeatletter\AtBeginDocument{%
+ \renewcommand{\@listi}
+ {\setlength{\labelwidth}{4em}}
+}\makeatother
+\usepackage{enumerate}
+$endif$
+$if(tables)$
+\usepackage{ctable}
+\usepackage{float} % provides the H option for float placement
+$endif$
+$if(url)$
+\usepackage{url}
+$endif$
+$if(graphics)$
+\usepackage{graphicx}
+$endif$
+% Comment these out if you don't want a slide with just the
+% part/section/subsection/subsubsection title:
+\AtBeginPart{\frame{\partpage}}
+\AtBeginSection{\frame{\sectionpage}}
+\AtBeginSubsection{\frame{\subsectionpage}}
+\AtBeginSubsubsection{\frame{\subsubsectionpage}}
+$if(strikeout)$
+\usepackage[normalem]{ulem}
+% avoid problems with \sout in headers with hyperref:
+\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
+$endif$
+$if(subscript)$
+\newcommand{\textsubscr}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}}
+$endif$
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{6pt plus 2pt minus 1pt}
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+$if(numbersections)$
+$else$
+\setcounter{secnumdepth}{0}
+$endif$
+$if(verbatim-in-note)$
+\VerbatimFootnotes % allows verbatim text in footnotes
+$endif$
+$if(lang)$
+\usepackage[$lang$]{babel}
+$endif$
+$for(header-includes)$
+$header-includes$
+$endfor$
+
+$if(title)$
+\title{$title$}
+$endif$
+$if(author)$
+\author{$for(author)$$author$$sep$ \and $endfor$}
+$endif$
+$if(date)$
+\date{$date$}
+$endif$
+
+\begin{document}
+$if(title)$
+\frame{\titlepage}
+$endif$
+
+$for(include-before)$
+$include-before$
+
+$endfor$
+$if(toc)$
+\begin{frame}
+\tableofcontents[hideallsubsections]
+\end{frame}
+
+$endif$
+$body$
+
+$if(natbib)$
+$if(biblio-files)$
+$if(biblio-title)$
+$if(book-class)$
+\renewcommand\bibname{$biblio-title$}
+$else$
+\renewcommand\refname{$biblio-title$}
+$endif$
+$endif$
+\bibliography{$biblio-files$}
+
+$endif$
+$endif$
+$if(biblatex)$
+\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
+
+$endif$
+$for(include-after)$
+$include-after$
+
+$endfor$
+\end{document}
diff --git a/templates/default.context b/templates/default.context
index 4269d06a1..f2710a8e9 100644
--- a/templates/default.context
+++ b/templates/default.context
@@ -1,54 +1,41 @@
-\enableregime[utf] % use UTF-8
+\startmode[*mkii]
+ \enableregime[utf-8]
+ \setupcolors[state=start]
+\stopmode
-\setupcolors[state=start]
-\setupinteraction[state=start, color=middleblue] % needed for hyperlinks
+% Enable hyperlinks
+\setupinteraction[state=start, color=middleblue]
-\setuppapersize[letter][letter] % use letter paper
-\setuplayout[width=middle, backspace=1.5in, cutspace=1.5in,
- height=middle, header=0.75in, footer=0.75in] % page layout
-\setuppagenumbering[location={footer,center}] % number pages
-\setupbodyfont[11pt] % 11pt font
-\setupwhitespace[medium] % inter-paragraph spacing
+\setuppapersize [letter][letter]
+\setuplayout [width=middle, backspace=1.5in, cutspace=1.5in,
+ height=middle, topspace=0.75in, bottomspace=0.75in]
-\setuphead[section][style=\tfc]
-\setuphead[subsection][style=\tfb]
-\setuphead[subsubsection][style=\bf]
+\setuppagenumbering[location={footer,center}]
-% define descr (for definition lists)
-\definedescription[descr][
- headstyle=bold,style=normal,align=left,location=hanging,
- width=broad,margin=1cm]
+\setupbodyfont[11pt]
-% prevent orphaned list intros
-\setupitemize[autointro]
+\setupwhitespace[medium]
-% define defaults for bulleted lists
-\setupitemize[1][symbol=1][indentnext=no]
-\setupitemize[2][symbol=2][indentnext=no]
-\setupitemize[3][symbol=3][indentnext=no]
-\setupitemize[4][symbol=4][indentnext=no]
+\setuphead[section] [style=\tfc$if(number-sections)$$else$,number=no$endif$]
+\setuphead[subsection] [style=\tfb$if(number-sections)$$else$,number=no$endif$]
+\setuphead[subsubsection][style=\bf$if(number-sections)$$else$,number=no$endif$]
-\setupthinrules[width=15em] % width of horizontal rules
+\definedescription
+ [description]
+ [headstyle=bold, style=normal, location=hanging, width=broad, margin=1cm]
-% for block quotations
-\unprotect
+\setupitemize[autointro] % prevent orphan list intro
+\setupitemize[indentnext=no]
-\startvariables all
-blockquote: blockquote
-\stopvariables
-
-\definedelimitedtext
-[\v!blockquote][\v!quotation]
+\setupthinrules[width=15em] % width of horizontal rules
\setupdelimitedtext
-[\v!blockquote]
-[\c!left=,
-\c!right=,
-before={\blank[medium]},
-after={\blank[medium]},
-]
+ [blockquote]
+ [before={\blank[medium]},
+ after={\blank[medium]},
+ indentnext=no,
+ ]
-\protect
$for(header-includes)$
$header-includes$
$endfor$
diff --git a/templates/default.docbook b/templates/default.docbook
index 66dfbef8d..e1c8e0134 100644
--- a/templates/default.docbook
+++ b/templates/default.docbook
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
+$if(mathml)$
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook EBNF Module V1.1CR1//EN"
+ "http://www.oasis-open.org/docbook/xml/mathml/1.1CR1/dbmathml.dtd">
+$else$
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+$endif$
<article>
<articleinfo>
<title>$title$</title>
diff --git a/templates/default.dzslides b/templates/default.dzslides
new file mode 100644
index 000000000..33e1ee098
--- /dev/null
+++ b/templates/default.dzslides
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+$for(author-meta)$
+ <meta name="author" content="$author-meta$" />
+$endfor$
+$if(date-meta)$
+ <meta name="dcterms.date" content="$date-meta$" />
+$endif$
+ <title>$if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$</title>
+$if(highlighting-css)$
+ <style type="text/css">
+$highlighting-css$
+ </style>
+$endif$
+$if(css)$
+$for(css)$
+ <link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>
+$endfor$
+$else$
+<style>
+ html { background-color: black; }
+ body { background-color: white; }
+ /* A section is a slide. It's size is 800x600, and this will never change */
+ section {
+ font-family: Arial, serif;
+ font-size: 20pt;
+ }
+ address, blockquote, dl, fieldset, form, h1, h2, h3, h4, h5, h6, hr, ol, p, pre, table, ul, dl { padding: 10px 20px 10px 20px; }
+ h1, h2, h3 {
+ text-align: center;
+ margin: 10pt 10pt 20pt 10pt;
+ }
+ ul, ol {
+ margin: 10px 10px 10px 50px;
+ }
+ section.titleslide h1 { margin-top: 200px; }
+ h1.title { margin-top: 150px; }
+ h1 { font-size: 180%; }
+ h2 { font-size: 120%; }
+ h3 { font-size: 100%; }
+ blockquote { font-style: italic }
+ q {
+ display: inline-block;
+ width: 700px;
+ height: 600px;
+ background-color: black;
+ color: white;
+ font-size: 60px;
+ padding: 50px;
+ }
+ footer {
+ position: absolute;
+ bottom: 10px;
+ right: 20px;
+ }
+
+ /* Transition effect */
+ /* Feel free to change the transition effect for original
+ animations. See here:
+ https://developer.mozilla.org/en/CSS/CSS_transitions
+ How to use CSS3 Transitions: */
+ section {
+ -moz-transition: left 400ms linear 0s;
+ -webkit-transition: left 400ms linear 0s;
+ -ms-transition: left 400ms linear 0s;
+ transition: left 400ms linear 0s;
+ }
+
+ /* Before */
+ section { left: -150%; }
+ /* Now */
+ section[aria-selected] { left: 0; }
+ /* After */
+ section[aria-selected] ~ section { left: +150%; }
+
+ /* Incremental elements */
+
+ /* By default, visible */
+ .incremental > * { opacity: 1; }
+
+ /* The current item */
+ .incremental > *[aria-selected] { color: red; opacity: 1; }
+
+ /* The items to-be-selected */
+ .incremental > *[aria-selected] ~ * { opacity: 0.2; }
+</style>
+$endif$
+$if(math)$
+ $math$
+$endif$
+$for(header-includes)$
+ $header-includes$
+$endfor$
+</head>
+<body>
+$if(title)$
+<section>
+ <h1 class="title">$title$</h1>
+$for(author)$
+ <h2 class="author">$author$</h2>
+$endfor$
+ <h3 class="date">$date$</h3>
+</section>
+$endif$
+$for(include-before)$
+$include-before$
+$endfor$
+$body$
+$for(include-after)$
+$include-after$
+$endfor$
+$dzslides-core$
+</body>
+</html>
diff --git a/templates/default.html b/templates/default.html
index d107f4809..c231b8fa5 100644
--- a/templates/default.html
+++ b/templates/default.html
@@ -1,45 +1,27 @@
-$if(html5)$
-<!DOCTYPE html>
-<html$if(lang)$ lang="$lang$"$endif$>
-$else$
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>
-$endif$
<head>
-$if(html5)$
- <meta charset="utf-8" />
-$else$
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-$endif$
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
-$for(author)$
- <meta name="author" content="$author$" />
+$for(author-meta)$
+ <meta name="author" content="$author-meta$" />
$endfor$
-$if(date)$
- <meta name="date" content="$date$" />
+$if(date-meta)$
+ <meta name="date" content="$date-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$</title>
-$if(html5)$
- <!--[if lt IE 9]>
- <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
-$endif$
$if(highlighting-css)$
<style type="text/css">
-/*<![CDATA[*/
$highlighting-css$
-/*]]>*/
</style>
$endif$
$for(css)$
<link rel="stylesheet" href="$css$" $if(html5)$$else$type="text/css" $endif$/>
$endfor$
$if(math)$
-$if(html5)$
-$else$
$math$
$endif$
-$endif$
$for(header-includes)$
$header-includes$
$endfor$
@@ -49,35 +31,21 @@ $for(include-before)$
$include-before$
$endfor$
$if(title)$
-$if(html5)$
-<header>
-$else$
<div id="$idprefix$header">
-$endif$
<h1 class="title">$title$</h1>
$for(author)$
-<h3 class="author">$author$</h3>
+<h2 class="author">$author$</h2>
$endfor$
$if(date)$
-<h4 class="date">$date$</h4>
+<h3 class="date">$date$</h3>
$endif$
-$if(html5)$
-</header>
-$else$
</div>
$endif$
-$endif$
$if(toc)$
-$if(html5)$
-<nav id="$idprefix$TOC">
-$toc$
-</nav>
-$else$
<div id="$idprefix$TOC">
$toc$
</div>
$endif$
-$endif$
$body$
$for(include-after)$
$include-after$
diff --git a/templates/default.html5 b/templates/default.html5
new file mode 100644
index 000000000..47a3fc934
--- /dev/null
+++ b/templates/default.html5
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html$if(lang)$ lang="$lang$"$endif$>
+<head>
+ <meta charset="utf-8">
+ <meta name="generator" content="pandoc">
+$for(author-meta)$
+ <meta name="author" content="$author-meta$">
+$endfor$
+$if(date-meta)$
+ <meta name="dcterms.date" content="$date-meta$">
+$endif$
+ <title>$if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$</title>
+ <!--[if lt IE 9]>
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+$if(highlighting-css)$
+ <style type="text/css">
+$highlighting-css$
+ </style>
+$endif$
+$for(css)$
+ <link rel="stylesheet" href="$css$">
+$endfor$
+$if(math)$
+ $math$
+$endif$
+$for(header-includes)$
+ $header-includes$
+$endfor$
+</head>
+<body>
+$for(include-before)$
+$include-before$
+$endfor$
+$if(title)$
+<header>
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+$if(date)$
+<h3 class="date">$date$</h3>
+$endif$
+</header>
+$endif$
+$if(toc)$
+<nav id="$idprefix$TOC">
+$toc$
+</nav>
+$endif$
+$body$
+$for(include-after)$
+$include-after$
+$endfor$
+</body>
+</html>
diff --git a/templates/default.latex b/templates/default.latex
index e56583392..d244ef7b9 100644
--- a/templates/default.latex
+++ b/templates/default.latex
@@ -1,4 +1,4 @@
-\documentclass$if(fontsize)$[$fontsize$]$endif${article}
+\documentclass[$if(fontsize)$$fontsize$,$endif$]{$documentclass$}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\ifxetex
@@ -22,10 +22,15 @@ $if(biblio-files)$
\bibliography{$biblio-files$}
$endif$
$endif$
-$if(lhs)$
+$if(listings)$
\usepackage{listings}
+$endif$
+$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
+$if(highlighting-macros)$
+$highlighting-macros$
+$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
$endif$
@@ -60,9 +65,13 @@ $endif$
\ifxetex
\usepackage[setpagesize=false, % page size defined by xetex
unicode=false, % unicode breaks when used with xetex
- xetex]{hyperref}
+ xetex,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\else
- \usepackage[unicode=true]{hyperref}
+ \usepackage[unicode=true,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\fi
\hypersetup{breaklinks=true, pdfborder={0 0 0}}
$if(strikeout)$
@@ -76,9 +85,6 @@ $endif$
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
\setlength{\emergencystretch}{3em} % prevent overfull lines
-$if(listings)$
-\usepackage{listings}
-$endif$
$if(numbersections)$
$else$
\setcounter{secnumdepth}{0}
@@ -86,6 +92,9 @@ $endif$
$if(verbatim-in-note)$
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
+$if(lang)$
+\usepackage[$lang$]{babel}
+$endif$
$for(header-includes)$
$header-includes$
$endfor$
diff --git a/templates/default.opendocument b/templates/default.opendocument
index ca49782f0..4135cdea7 100644
--- a/templates/default.opendocument
+++ b/templates/default.opendocument
@@ -7,7 +7,7 @@ $endfor$
<office:body>
<office:text>
$if(title)$
-<text:h text:style-name="Heading_20_1" text:outline-level="1">$title$</text:h>
+<text:h text:style-name="Title">$title$</text:h>
$endif$
$for(author)$
<text:p text:style-name="Author">$author$</text:p>
diff --git a/templates/default.rst b/templates/default.rst
index f09bdd8b9..3b28cbf51 100644
--- a/templates/default.rst
+++ b/templates/default.rst
@@ -18,6 +18,7 @@ $endif$
$if(math)$
.. role:: math(raw)
:format: html latex
+..
$endif$
$for(include-before)$
@@ -26,6 +27,7 @@ $include-before$
$endfor$
$if(toc)$
.. contents::
+..
$endif$
$for(header-includes)$
diff --git a/templates/default.s5 b/templates/default.s5
index 6f862ce7b..03008df88 100644
--- a/templates/default.s5
+++ b/templates/default.s5
@@ -2,12 +2,13 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
-$for(author)$
- <meta name="author" content="$author$" />
+$for(author-meta)$
+ <meta name="author" content="$author-meta$" />
$endfor$
-$if(date)$
- <meta name="date" content="$date$" />
+$if(date-meta)$
+ <meta name="date" content="$date-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$</title>
<!-- configuration parameters -->
@@ -21,9 +22,6 @@ $endif$
$for(css)$
<link rel="stylesheet" href="$css$" type="text/css" />
$endfor$
-$if(s5includes)$
-$s5includes$
-$else$
<!-- style sheet links -->
<link rel="stylesheet" href="$s5-url$/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="$s5-url$/outline.css" type="text/css" media="screen" id="outlineStyle" />
@@ -31,7 +29,6 @@ $else$
<link rel="stylesheet" href="$s5-url$/opera.css" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
<script src="$s5-url$/slides.js" type="text/javascript"></script>
-$endif$
$if(math)$
$math$
$endif$
@@ -54,10 +51,10 @@ $endfor$
</div>
<div class="presentation">
$if(title)$
-<div class="slide">
+<div class="titleslide slide">
<h1>$title$</h1>
- <h3>$for(author)$$author$$sep$<br/>$endfor$</h3>
- <h4>$date$</h4>
+ <h2>$for(author)$$author$$sep$<br/>$endfor$</h2>
+ <h3>$date$</h3>
</div>
$endif$
$body$
diff --git a/templates/default.slidy b/templates/default.slidy
index 75d2ebedd..86ccfd28d 100644
--- a/templates/default.slidy
+++ b/templates/default.slidy
@@ -4,31 +4,22 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
-$for(author)$
- <meta name="author" content="$author$" />
+$for(author-meta)$
+ <meta name="author" content="$author-meta$" />
$endfor$
-$if(date)$
- <meta name="date" content="$date$" />
+$if(date-meta)$
+ <meta name="date" content="$date-meta$" />
$endif$
-$if(highlighting-css)$
<title>$if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$</title>
+$if(highlighting-css)$
<style type="text/css">
-/*<![CDATA[*/
$highlighting-css$
-/*]]>*/
</style>
$endif$
-$if(slidy-css)$
- <style type="text/css">
-/*<![CDATA[*/
-$slidy-css$
-/*]]>*/
- </style>
-$else$
<link rel="stylesheet" type="text/css" media="screen, projection, print"
href="$slidy-url$/styles/slidy.css" />
-$endif$
$for(css)$
<link rel="stylesheet" type="text/css" media="screen, projection, print"
href="$css$" />
@@ -39,16 +30,8 @@ $endif$
$for(header-includes)$
$header-includes$
$endfor$
-$if(slidy-js)$
-<script type="text/javascript" charset="utf-8">
-/*<![CDATA[*/
-$slidy-js$
-/*]]>*/
-</script>
-$else$
<script src="$slidy-url$/scripts/slidy.js.gz"
charset="utf-8" type="text/javascript"></script>
-$endif$
$if(duration)$
<meta name="duration" content="$duration$" />
$endif$
diff --git a/templates/epub-coverimage.html b/templates/epub-coverimage.html
new file mode 100644
index 000000000..cd778a145
--- /dev/null
+++ b/templates/epub-coverimage.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>$title$</title>
+<style type="text/css">img{ max-width: 100%; }</style>
+<link href="stylesheet.css" type="text/css" rel="stylesheet" />
+</head>
+<body>
+<div id="cover-image">
+<img src="$coverimage$" alt="$title$" />
+</div>
+</body>
+</html>
diff --git a/templates/epub-page.html b/templates/epub-page.html
new file mode 100644
index 000000000..aa56170a0
--- /dev/null
+++ b/templates/epub-page.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>$title$</title>
+<link href="stylesheet.css" type="text/css" rel="stylesheet" />
+</head>
+<body>
+<h1>$title$</h1>
+$if(toc)$
+<div id="$idprefix$TOC">
+$toc$
+</div>
+$endif$
+$body$
+</body>
+</html>
+
diff --git a/templates/epub-titlepage.html b/templates/epub-titlepage.html
new file mode 100644
index 000000000..790431bb7
--- /dev/null
+++ b/templates/epub-titlepage.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>$title$</title>
+<link href="stylesheet.css" type="text/css" rel="stylesheet" />
+</head>
+<body>
+<h1 class="title">$title$</h1>
+$for(author)$
+<h2 class="author">$author$</h2>
+$endfor$
+$if(date)$
+<h3 class="date">$date$</h3>
+$endif$
+$if(toc)$
+<div id="$idprefix$TOC">
+$toc$
+</div>
+$endif$
+</body>
+</html>
diff --git a/tests/biblio.bib b/tests/biblio.bib
index 755d535a8..4eb2ba0d0 100644
--- a/tests/biblio.bib
+++ b/tests/biblio.bib
@@ -15,7 +15,7 @@ volume="6",
pages="33-34"
}
-@InCollection{item3,
+@InCollection{пункт3,
author="John Doe and Jenny Roe",
title="Why Water Is Wet",
booktitle="Third Book",
diff --git a/tests/chicago-author-date.csl b/tests/chicago-author-date.csl
index f16f82305..dea707114 100644
--- a/tests/chicago-author-date.csl
+++ b/tests/chicago-author-date.csl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" page-range-format="chicago">
+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
<info>
<title>Chicago Manual of Style (Author-Date format)</title>
<id>http://www.zotero.org/styles/chicago-author-date</id>
@@ -8,362 +8,415 @@
<name>Julian Onions</name>
<email>julian.onions@gmail.com</email>
</author>
+ <contributor>
+ <name>Sebastian Karcher</name>
+ </contributor>
<category citation-format="author-date"/>
<category field="generic-base"/>
- <updated>2009-12-04T20:22:16+00:00</updated>
+ <updated>2011-11-17T22:01:05+00:00</updated>
<summary>The author-date variant of the Chicago style</summary>
<link href="http://www.chicagomanualofstyle.org/tools_citationguide.html" rel="documentation"/>
+ <rights>This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
</info>
- <macro name="secondary-contributors">
- <choose>
- <if match="none" type="chapter">
- <group delimiter=". ">
- <choose>
- <if variable="author">
- <names variable="editor">
- <label form="verb-short" prefix=" " suffix=". " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </if>
- </choose>
- <choose>
- <if match="any" variable="author editor">
- <names variable="translator">
- <label form="verb-short" prefix=" " suffix=". " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </if>
- </choose>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="container-contributors">
- <choose>
- <if type="chapter">
- <group delimiter=", " prefix=",">
- <choose>
- <if variable="author">
- <names variable="editor">
- <label form="verb-short" prefix=" " suffix=". " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
+ <macro name="secondary-contributors">
+ <choose>
+ <if type="chapter paper-conference" match="none">
+ <group delimiter=". ">
+ <choose>
+ <if variable="author">
+ <names variable="editor">
+ <label form="verb-short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ <choose>
+ <if variable="author editor" match="any">
+ <names variable="translator">
+ <label form="verb-short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-contributors">
+ <choose>
+ <if type="chapter paper-conference" match="any">
+ <group prefix="," delimiter=", ">
+ <choose>
+ <if variable="author">
+ <names variable="editor">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ <choose>
+ <if variable="container-author">
+ <group>
+ <names variable="container-author">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=" " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </group>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ <choose>
+ <if variable="author editor" match="any">
+ <names variable="translator">
+ <label form="verb-short" prefix=" " text-case="lowercase" suffix=". " strip-periods="true"/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </if>
+ </choose>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="anon">
+ <text term="anonymous" form="short" text-case="capitalize-first" suffix="." strip-periods="true"/>
+ </macro>
+ <macro name="editor">
+ <names variable="editor">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", " suffix="." strip-periods="true"/>
+ </names>
+ </macro>
+ <macro name="translator">
+ <names variable="translator">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="verb-short" prefix=", " suffix="." strip-periods="true"/>
+ </names>
+ </macro>
+ <macro name="recipient">
+ <choose>
+ <if type="personal_communication">
+ <choose>
+ <if variable="genre">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ <else>
+ <text term="letter" text-case="capitalize-first"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ <names variable="recipient" delimiter=", ">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="contributors">
+ <names variable="author">
+ <name and="text" name-as-sort-order="first" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="verb-short" prefix=", " suffix="." text-case="lowercase" strip-periods="true"/>
+ <substitute>
+ <text macro="editor"/>
+ <text macro="translator"/>
+ <text macro="anon"/>
+ </substitute>
+ </names>
+ <text macro="recipient"/>
+ </macro>
+ <macro name="contributors-short">
+ <names variable="author">
+ <name form="short" and="text" delimiter=", " initialize-with=". "/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <text macro="anon"/>
+ </substitute>
+ </names>
+ </macro>
+ <macro name="interviewer">
+ <names variable="interviewer" delimiter=", ">
+ <label form="verb" prefix=" " text-case="capitalize-first" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="archive">
+ <group delimiter=". ">
+ <text variable="archive_location" text-case="capitalize-first"/>
+ <text variable="archive"/>
+ <text variable="archive-place"/>
+ </group>
+ </macro>
+ <macro name="access">
+ <group delimiter=". ">
+ <choose>
+ <if type="graphic report" match="any">
+ <text macro="archive"/>
</if>
- </choose>
- <choose>
- <if match="any" variable="author editor">
- <names variable="translator">
- <label form="verb-short" prefix=" " suffix=". " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
+ <else-if type="bill book graphic legal_case motion_picture report song article-magazine article-newspaper thesis chapter paper-conference" match="none">
+ <text macro="archive"/>
+ </else-if>
+ </choose>
+ <text variable="DOI" prefix="doi:"/>
+ <choose>
+ <if type="legal_case" match="none">
+ <text variable="URL"/>
</if>
- </choose>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="anon">
- <choose>
- <if match="none" variable="author editor translator">
- <text form="short" term="anonymous" text-case="capitalize-first" />
- </if>
- </choose>
- </macro>
- <macro name="editor">
- <names variable="editor">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="short" prefix=", " suffix="." />
- </names>
- </macro>
- <macro name="translator">
- <names variable="translator">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="verb-short" prefix=", " suffix="." />
- </names>
- </macro>
- <macro name="recipient">
- <choose>
- <if type="personal_communication">
- <choose>
- <if variable="genre">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- <else>
- <text term="letter" text-case="capitalize-first" />
- </else>
- </choose>
- </if>
- </choose>
- <names delimiter=", " variable="recipient">
- <label form="verb" prefix=" " suffix=" " text-case="lowercase" />
- <name and="text" delimiter=", " />
- </names>
- </macro>
- <macro name="contributors">
- <names variable="author">
- <name and="text" delimiter=", " delimiter-precedes-last="always" name-as-sort-order="first" sort-separator=", " />
- <label form="verb-short" prefix=", " suffix="." text-case="lowercase" />
- <substitute>
- <text macro="editor" />
- <text macro="translator" />
- </substitute>
- </names>
- <text macro="anon" />
- <text macro="recipient" />
- </macro>
- <macro name="contributors-short">
- <names variable="author">
- <name and="text" delimiter=", " form="short" />
- <substitute>
- <names variable="editor" />
- <names variable="translator" />
- </substitute>
- </names>
- <text macro="anon" />
- </macro>
- <macro name="interviewer">
- <names delimiter=", " variable="interviewer">
- <label form="verb" prefix=" " suffix=" " text-case="capitalize-first" />
- <name and="text" delimiter=", " />
- </names>
- </macro>
- <macro name="archive">
- <group delimiter=". ">
- <text text-case="capitalize-first" variable="archive_location" />
- <text variable="archive" />
- <text variable="archive-place" />
- </group>
- </macro>
- <macro name="access">
- <group delimiter=". ">
+ </choose>
+ </group>
+ </macro>
+ <macro name="title">
<choose>
- <if match="any" type="graphic report">
- <text macro="archive" />
- </if>
- <else-if match="none" type="book thesis chapter article-journal article-newspaper article-magazine">
- <text macro="archive" />
- </else-if>
+ <if variable="title" match="none">
+ <choose>
+ <if type="personal_communication" match="none">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <text variable="title" font-style="italic"/>
+ </else-if>
+ <else>
+ <text variable="title" quotes="true"/>
+ </else>
</choose>
- <text prefix="doi:" variable="DOI" />
- <text variable="URL" />
- </group>
- </macro>
- <macro name="title">
- <choose>
- <if match="none" variable="title">
- <choose>
- <if match="none" type="personal_communication">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- </choose>
- </if>
- <else-if type="book">
- <text font-style="italic" variable="title" />
- </else-if>
- <else>
- <text variable="title" />
- </else>
- </choose>
- </macro>
- <macro name="edition">
- <choose>
- <if match="any" type="book chapter">
- <choose>
- <if is-numeric="edition">
- <group delimiter=" ">
- <number form="ordinal" variable="edition" />
- <text form="short" suffix="." term="edition" />
+ </macro>
+ <macro name="edition">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short" suffix="." strip-periods="true"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition" suffix="."/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="locators">
+ <choose>
+ <if type="article-journal">
+ <text variable="volume" prefix=" "/>
+ <text variable="issue" prefix=" (" suffix=")"/>
+ </if>
+ <else-if type="legal_case">
+ <text variable="volume" prefix=", "/>
+ <text variable="container-title" prefix=" "/>
+ <text variable="page" prefix=" "/>
+ </else-if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <group prefix=". " delimiter=". ">
+ <group>
+ <text term="volume" form="short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ <group>
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" prefix=" " suffix="." plural="true" strip-periods="true"/>
+ </group>
</group>
- </if>
- <else>
- <text suffix="." variable="edition" />
- </else>
- </choose>
- </if>
- </choose>
- </macro>
- <macro name="locators">
- <choose>
- <if type="article-journal">
- <text prefix=" " variable="volume" />
- <text prefix=", no. " variable="issue" />
- </if>
- <else-if type="book">
- <group delimiter=". " prefix=". ">
- <group>
- <text form="short" suffix=". " term="volume" text-case="capitalize-first" />
- <number form="numeric" variable="volume" />
- </group>
- <group>
- <number form="numeric" variable="number-of-volumes" />
- <text form="short" plural="true" prefix=" " suffix="." term="volume" />
- </group>
- </group>
- </else-if>
- </choose>
- </macro>
- <macro name="locators-chapter">
- <choose>
- <if type="chapter">
- <group prefix=", ">
- <text suffix=":" variable="volume" />
- <text variable="page" />
- </group>
- </if>
- </choose>
- </macro>
- <macro name="locators-article">
- <choose>
- <if type="article-newspaper">
- <group delimiter=", " prefix=", ">
- <group>
- <text suffix=" " variable="edition" />
- <text prefix=" " term="edition" />
- </group>
- <group>
- <text form="short" suffix=". " term="section" />
- <text variable="section" />
- </group>
- </group>
- </if>
- <else-if type="article-journal">
- <text prefix=": " variable="page" />
- </else-if>
- </choose>
- </macro>
- <macro name="point-locators">
- <group>
+ </else-if>
+ <else-if type="chapter paper-conference" match="any">
+ <choose>
+ <if variable="page" match="none">
+ <group prefix=". ">
+ <text term="volume" form="short" text-case="capitalize-first" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ </if>
+ </choose>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="locators-chapter">
<choose>
- <if locator="page" match="none">
- <label form="short" suffix=" " variable="locator" />
- </if>
+ <if type="chapter paper-conference" match="any">
+ <choose>
+ <if variable="page">
+ <group prefix=", ">
+ <text variable="volume" suffix=":"/>
+ <text variable="page"/>
+ </group>
+ </if>
+ </choose>
+ </if>
</choose>
- <text variable="locator" />
- </group>
- </macro>
- <macro name="container-prefix">
- <text term="in" text-case="capitalize-first" />
- </macro>
- <macro name="container-title">
- <choose>
- <if type="chapter">
- <text macro="container-prefix" suffix=" " />
- </if>
- </choose>
- <text font-style="italic" variable="container-title" />
- </macro>
- <macro name="publisher">
- <group delimiter=": ">
- <text variable="publisher-place" />
- <text variable="publisher" />
- </group>
- </macro>
- <macro name="date">
- <date variable="issued">
- <date-part name="year" />
- </date>
- </macro>
- <macro name="day-month">
- <date variable="issued">
- <date-part name="month" />
- <date-part name="day" prefix=" " />
- </date>
- </macro>
- <macro name="collection-title">
- <text variable="collection-title" />
- <text prefix=" " variable="collection-number" />
- </macro>
- <macro name="event">
- <group>
- <text suffix=" " term="presented at" />
- <text variable="event" />
- </group>
- </macro>
- <macro name="description">
- <group delimiter=". ">
- <text macro="interviewer" />
- <text text-case="capitalize-first" variable="medium" />
- </group>
- <choose>
- <if match="none" variable="title"> </if>
- <else-if type="thesis"> </else-if>
- <else>
- <text prefix=". " text-case="capitalize-first" variable="genre" />
- </else>
- </choose>
- </macro>
- <macro name="issue">
- <choose>
- <if type="article-journal">
- <text macro="day-month" prefix=" (" suffix=")" />
- </if>
- <else-if type="speech">
- <group delimiter=", " prefix=" ">
- <text macro="event" />
- <text macro="day-month" />
- <text variable="event-place" />
- </group>
- </else-if>
- <else-if match="any" type="article-newspaper article-magazine">
- <text macro="day-month" prefix=", " />
- </else-if>
- <else>
- <group delimiter=", " prefix=". ">
- <choose>
- <if type="thesis">
- <text text-case="capitalize-first" variable="genre" />
- </if>
- </choose>
- <text macro="publisher" />
- <text macro="day-month" />
- </group>
- </else>
- </choose>
- </macro>
- <citation
- disambiguate-add-givenname="true"
- disambiguate-add-names="true"
- disambiguate-add-year-suffix="true"
- et-al-min="4"
- et-al-subsequent-min="4"
- et-al-subsequent-use-first="1"
- et-al-use-first="1">
- <layout delimiter="; " prefix="(" suffix=")">
- <group delimiter=", ">
- <group delimiter=" ">
- <text macro="contributors-short" />
- <text macro="date" />
- </group>
- <text macro="point-locators" />
+ </macro>
+ <macro name="locators-article">
+ <choose>
+ <if type="article-newspaper">
+ <group prefix=", " delimiter=", ">
+ <group>
+ <text variable="edition" suffix=" "/>
+ <text term="edition" prefix=" "/>
+ </group>
+ <group>
+ <text term="section" form="short" suffix=". " strip-periods="true"/>
+ <text variable="section"/>
+ </group>
+ </group>
+ </if>
+ <else-if type="article-journal">
+ <text variable="page" prefix=": "/>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="point-locators">
+ <choose>
+ <if variable="locator">
+ <choose>
+ <if locator="page" match="none">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song" match="any">
+ <choose>
+ <if variable="volume">
+ <group>
+ <text term="volume" form="short" text-case="lowercase" suffix=". " strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ <label variable="locator" form="short" prefix=", " suffix=" "/>
+ </group>
+ </if>
+ <else>
+ <label variable="locator" form="short" suffix=" "/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <number variable="volume" form="numeric" suffix=":"/>
+ </else-if>
+ </choose>
+ <text variable="locator"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-prefix">
+ <text term="in" text-case="capitalize-first"/>
+ </macro>
+ <macro name="container-title">
+ <choose>
+ <if type="chapter paper-conference" match="any">
+ <text macro="container-prefix" suffix=" "/>
+ </if>
+ </choose>
+ <choose>
+ <if type="legal_case" match="none">
+ <text variable="container-title" font-style="italic"/>
+ </if>
+ </choose>
+ </macro>
+ <macro name="publisher">
+ <group delimiter=": ">
+ <text variable="publisher-place"/>
+ <text variable="publisher"/>
</group>
- </layout>
- </citation>
- <bibliography
- entry-spacing="0"
- et-al-min="11"
- et-al-use-first="7"
- hanging-indent="true"
- subsequent-author-substitute="---">
- <sort>
- <key macro="contributors" />
- <key variable="issued" />
- <key variable="title" />
- </sort>
- <layout suffix=".">
- <text macro="contributors" suffix=". " />
- <text macro="date" suffix=". " />
- <text macro="title" />
- <text macro="description" />
- <text macro="secondary-contributors" prefix=". " />
- <text macro="container-title" prefix=". " />
- <text macro="container-contributors" />
- <text macro="locators-chapter" />
- <text macro="edition" prefix=". " />
- <text macro="locators" />
- <text macro="collection-title" prefix=". " />
- <text macro="issue" />
- <text macro="locators-article" />
- <text macro="access" prefix=". " />
- </layout>
- </bibliography>
-</style>
+ </macro>
+ <macro name="date">
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </macro>
+ <macro name="day-month">
+ <date variable="issued">
+ <date-part name="month"/>
+ <date-part name="day" prefix=" "/>
+ </date>
+ </macro>
+ <macro name="collection-title">
+ <text variable="collection-title"/>
+ <text variable="collection-number" prefix=" "/>
+ </macro>
+ <macro name="event">
+ <group>
+ <text term="presented at" suffix=" "/>
+ <text variable="event"/>
+ </group>
+ </macro>
+ <macro name="description">
+ <choose>
+ <if type="interview">
+ <group delimiter=". ">
+ <text macro="interviewer"/>
+ <text variable="medium" text-case="capitalize-first"/>
+ </group>
+ </if>
+ <else>
+ <text variable="medium" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ <choose>
+ <if variable="title" match="none"/>
+ <else-if type="thesis"/>
+ <else>
+ <text variable="genre" text-case="capitalize-first" prefix=". "/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="issue">
+ <choose>
+ <if type="article-journal">
+ <text macro="day-month" prefix=" (" suffix=")"/>
+ </if>
+ <else-if type="legal_case">
+ <text variable="authority" prefix=". "/>
+ </else-if>
+ <else-if type="speech">
+ <group prefix=" " delimiter=", ">
+ <text macro="event"/>
+ <text macro="day-month"/>
+ <text variable="event-place"/>
+ </group>
+ </else-if>
+ <else-if type="article-newspaper article-magazine" match="any">
+ <text macro="day-month" prefix=", "/>
+ </else-if>
+ <else>
+ <group prefix=". " delimiter=", ">
+ <choose>
+ <if type="thesis">
+ <text variable="genre" text-case="capitalize-first"/>
+ </if>
+ </choose>
+ <text macro="publisher"/>
+ </group>
+ </else>
+ </choose>
+ </macro>
+ <citation et-al-min="4" et-al-use-first="1" disambiguate-add-year-suffix="true" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="primary-name">
+ <layout prefix="(" suffix=")" delimiter="; ">
+ <group delimiter=", ">
+ <group delimiter=" ">
+ <text macro="contributors-short"/>
+ <text macro="date"/>
+ </group>
+ <text macro="point-locators"/>
+ </group>
+ </layout>
+ </citation>
+ <bibliography hanging-indent="true" et-al-min="11" et-al-use-first="7" subsequent-author-substitute="———" entry-spacing="0">
+ <sort>
+ <key macro="contributors"/>
+ <key variable="issued"/>
+ </sort>
+ <layout suffix=".">
+ <text macro="contributors" suffix=". "/>
+ <text macro="date" suffix=". "/>
+ <text macro="title"/>
+ <text macro="description"/>
+ <text macro="secondary-contributors" prefix=". "/>
+ <text macro="container-title" prefix=". "/>
+ <text macro="container-contributors"/>
+ <text macro="locators-chapter"/>
+ <text macro="edition" prefix=". "/>
+ <text macro="locators"/>
+ <text macro="collection-title" prefix=". "/>
+ <text macro="issue"/>
+ <text macro="locators-article"/>
+ <text macro="access" prefix=". "/>
+ </layout>
+ </bibliography>
+</style> \ No newline at end of file
diff --git a/tests/html-reader.html b/tests/html-reader.html
index ea10a306c..69bb9ba8a 100644
--- a/tests/html-reader.html
+++ b/tests/html-reader.html
@@ -1,6 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<style type="text/css">
div.pandocNote { border-left: 1px solid grey; padding-left: 1em; }
diff --git a/tests/ieee.csl b/tests/ieee.csl
index af57495c8..cd7ba4943 100644
--- a/tests/ieee.csl
+++ b/tests/ieee.csl
@@ -1,129 +1,302 @@
<?xml version="1.0" encoding="utf-8"?>
-<style xmlns="http://purl.org/net/xbiblio/csl" class="numeric" version="1.0">
- <info>
- <title>IEEE</title>
- <id>http://www.zotero.org/styles/ieee</id>
- <link href="http://www.zotero.org/styles/ieee" rel="self"/>
- <author>
- <name>Michael Berkowitz</name>
- <email>mberkowi@gmu.edu</email>
- </author>
- <contributor>
- <name>Julian Onions</name>
- <email>julian.onions@gmail.com</email>
- </contributor>
- <contributor>
- <name>Rintze Zelle</name>
- <uri>http://forums.zotero.org/account/831/</uri>
- </contributor>
- <category field="engineering"/>
- <category field="generic-base"/>
- <category citation-format="numeric"/>
- <updated>2010-02-06T06:35:40+00:00</updated>
- <link href="http://www.ieee.org/portal/cms_docs_iportals/iportals/publications/authors/transjnl/stylemanual.pdf" rel="documentation"/>
- </info>
- <macro name="author">
- <names variable="author">
- <name initialize-with="." delimiter=", " and="text"/>
- <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- </substitute>
- </names>
- </macro>
- <macro name="editor">
- <names variable="editor">
- <name initialize-with="." delimiter=", " and="text" name-as-sort-order="all"/>
- <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
- </names>
- </macro>
- <macro name="title">
+<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
+ <info>
+ <title>IEEE</title>
+ <id>http://www.zotero.org/styles/ieee</id>
+ <link href="http://www.zotero.org/styles/ieee" rel="self"/>
+ <author>
+ <name>Michael Berkowitz</name>
+ <email>mberkowi@gmu.edu</email>
+ </author>
+ <contributor>
+ <name>Julian Onions</name>
+ <email>julian.onions@gmail.com</email>
+ </contributor>
+ <contributor>
+ <name>Rintze Zelle</name>
+ <uri>http://twitter.com/rintzezelle</uri>
+ </contributor>
+ <contributor>
+ <name>Stephen Frank</name>
+ <uri>http://www.zotero.org/sfrank</uri>
+ </contributor>
+ <contributor>
+ <name>Sebastian Karcher</name>
+ </contributor>
+ <category field="engineering"/>
+ <category field="generic-base"/>
+ <category citation-format="numeric"/>
+ <updated>2011-09-15T07:01:02+00:00</updated>
+ <rights>
+ This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License:
+ http://creativecommons.org/licenses/by-sa/3.0/
+ </rights>
+ <link href="http://www.ieee.org/portal/cms_docs_iportals/iportals/publications/authors/transjnl/stylemanual.pdf" rel="documentation"/>
+ <link href="http://www.ieee.org/documents/auinfo07.pdf" rel="documentation"/>
+ </info>
+ <!-- Macros -->
+ <macro name="edition">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short" suffix="." strip-periods="true"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition" text-case="capitalize-first" suffix="."/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="issued">
+ <choose>
+ <if type="article-journal report" match="any">
+ <date variable="issued">
+ <date-part name="month" form="short" suffix=" "/>
+ <date-part name="year" form="long"/>
+ </date>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture song thesis chapter paper-conference" match="any">
+ <date variable="issued">
+ <date-part name="year" form="long"/>
+ </date>
+ </else-if>
+ <else>
+ <date variable="issued">
+ <date-part name="day" form="numeric-leading-zeros" suffix="-"/>
+ <date-part name="month" form="short" suffix="-" strip-periods="true"/>
+ <date-part name="year" form="long"/>
+ </date>
+ </else>
+ </choose>
+ </macro>
+ <macro name="author">
+ <names variable="author">
+ <name initialize-with=". " delimiter=", " and="text"/>
+ <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ </substitute>
+ </names>
+ </macro>
+ <macro name="editor">
+ <names variable="editor">
+ <name initialize-with=". " delimiter=", " and="text"/>
+ <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
+ </names>
+ </macro>
+ <macro name="locators">
+ <group delimiter=", ">
+ <text macro="edition"/>
+ <group delimiter=" ">
+ <text term="volume" form="short" suffix="." strip-periods="true"/>
+ <number variable="volume" form="numeric"/>
+ </group>
+ <group delimiter=" ">
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" suffix="." plural="true" strip-periods="true"/>
+ </group>
+ <group delimiter=" ">
+ <text term="issue" form="short" suffix="." strip-periods="true"/>
+ <number variable="issue" form="numeric"/>
+ </group>
+ </group>
+ </macro>
+ <macro name="title">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture song" match="any">
+ <text variable="title" font-style="italic"/>
+ </if>
+ <else>
+ <text variable="title" quotes="true"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="publisher">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture song chapter paper-conference" match="any">
+ <text variable="publisher-place" suffix=": "/>
+ <text variable="publisher"/>
+ </if>
+ <else>
+ <group delimiter=", ">
+ <text variable="publisher"/>
+ <text variable="publisher-place"/>
+ </group>
+ </else>
+ </choose>
+ </macro>
+ <macro name="event">
+ <choose>
+ <if type="paper-conference">
+ <choose>
+ <!-- Published Conference Paper -->
+ <if variable="container-title">
+ <group delimiter=", ">
+ <text variable="container-title" prefix="in " font-style="italic"/>
+ <text variable="event-place"/>
+ </group>
+ </if>
+ <!-- Unpublished Conference Paper -->
+ <else>
+ <group delimiter=", ">
+ <text variable="event" prefix="presented at the "/>
+ <text variable="event-place"/>
+ </group>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="access">
+ <choose>
+ <if type="webpage">
+ <choose>
+ <if variable="URL">
+ <group delimiter=". ">
+ <text value="[Online]"/>
+ <text variable="URL" prefix="Available: "/>
+ <group prefix="[" suffix="]">
+ <date variable="accessed" prefix="Accessed: ">
+ <date-part name="day" form="numeric-leading-zeros" suffix="-"/>
+ <date-part name="month" form="short" suffix="-" strip-periods="true"/>
+ <date-part name="year" form="long"/>
+ </date>
+ </group>
+ </group>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="page">
+ <group>
+ <label variable="page" form="short" suffix=". " strip-periods="true"/>
+ <text variable="page"/>
+ </group>
+ </macro>
+ <!-- Citation -->
+ <citation collapse="citation-number">
+ <sort>
+ <key variable="citation-number"/>
+ </sort>
+ <layout prefix="[" suffix="]" delimiter="], [">
+ <text variable="citation-number"/>
+ </layout>
+ </citation>
+ <!-- Bibliography -->
+ <bibliography entry-spacing="0" second-field-align="flush">
+ <layout suffix=".">
+ <!-- Citation Number -->
+ <text variable="citation-number" prefix="[" suffix="]"/>
+ <!-- Author(s) -->
+ <text macro="author" prefix=" " suffix=", "/>
+ <!-- Rest of Citation -->
<choose>
- <if type="bill book graphic legal_case motion_picture report song" match="any">
- <text variable="title" font-style="italic"/>
- </if>
- <else>
- <text variable="title" quotes="true"/>
- </else>
+ <!-- Specific Formats -->
+ <if type="article-journal">
+ <group delimiter=", ">
+ <text macro="title"/>
+ <text variable="container-title" font-style="italic" form="short"/>
+ <text macro="locators"/>
+ <text macro="page"/>
+ <text macro="issued"/>
+ </group>
+ </if>
+ <else-if type="paper-conference">
+ <group delimiter=", ">
+ <text macro="title"/>
+ <text macro="event"/>
+ <text macro="issued"/>
+ <text macro="locators"/>
+ <text macro="page"/>
+ </group>
+ </else-if>
+ <else-if type="report">
+ <group delimiter=", ">
+ <text macro="title"/>
+ <text macro="publisher"/>
+ <group delimiter=" ">
+ <text variable="genre"/>
+ <text variable="number"/>
+ </group>
+ <text macro="issued"/>
+ </group>
+ </else-if>
+ <else-if type="thesis">
+ <group delimiter=", ">
+ <text macro="title"/>
+ <text variable="genre"/>
+ <text macro="publisher"/>
+ <text macro="issued"/>
+ </group>
+ </else-if>
+ <else-if type="webpage">
+ <group delimiter=", " suffix=". ">
+ <text macro="title"/>
+ <text variable="container-title" font-style="italic"/>
+ <text macro="issued"/>
+ </group>
+ <text macro="access"/>
+ </else-if>
+ <else-if type="patent">
+ <text macro="title" suffix=", "/>
+ <text variable="number" prefix="U.S. Patent "/>
+ <text macro="issued"/>
+ </else-if>
+ <!-- Generic/Fallback Formats -->
+ <else-if type="bill book graphic legal_case motion_picture report song" match="any">
+ <group delimiter=", " suffix=". ">
+ <text macro="title"/>
+ <text macro="locators"/>
+ </group>
+ <group delimiter=", ">
+ <text macro="publisher"/>
+ <text macro="issued"/>
+ <text macro="page"/>
+ </group>
+ </else-if>
+ <else-if type="article-magazine article-newspaper broadcast interview manuscript map patent personal_communication song speech thesis webpage" match="any">
+ <group delimiter=", ">
+ <text macro="title"/>
+ <text variable="container-title" font-style="italic"/>
+ <text macro="locators"/>
+ <text macro="publisher"/>
+ <text macro="page"/>
+ <text macro="issued"/>
+ </group>
+ </else-if>
+ <else-if type="chapter paper-conference" match="any">
+ <group delimiter=", " suffix=", ">
+ <text macro="title"/>
+ <text variable="container-title" prefix="in " font-style="italic"/>
+ <text macro="locators"/>
+ </group>
+ <text macro="editor" suffix=" "/>
+ <group delimiter=", ">
+ <text macro="publisher"/>
+ <text macro="issued"/>
+ <text macro="page"/>
+ </group>
+ </else-if>
+ <else>
+ <group delimiter=", " suffix=". ">
+ <text macro="title"/>
+ <text variable="container-title" font-style="italic"/>
+ <text macro="locators"/>
+ </group>
+ <group delimiter=", ">
+ <text macro="publisher"/>
+ <text macro="page"/>
+ <text macro="issued"/>
+ </group>
+ </else>
</choose>
- </macro>
- <macro name="publisher">
- <text variable="publisher-place" suffix=": "/>
- <text variable="publisher" suffix=", "/>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </macro>
- <macro name="access">
- <text variable="URL"/>
- </macro>
- <macro name="page">
- <group>
- <label variable="page" form="short" suffix=". " strip-periods="true"/>
- <text variable="page"/>
- </group>
- </macro>
- <citation et-al-min="3" et-al-use-first="1" collapse="citation-number">
- <sort>
- <key variable="citation-number"/>
- </sort>
- <layout delimiter=",">
- <text variable="citation-number" prefix="[" suffix="]"/>
- </layout>
- </citation>
- <bibliography entry-spacing="0" second-field-align="flush">
- <layout suffix=".">
- <text variable="citation-number" prefix="[" suffix="]"/>
- <text macro="author" prefix=" " suffix=", "/>
- <choose>
- <if type="bill book graphic legal_case motion_picture report song" match="any">
- <group delimiter=", ">
- <text macro="title"/>
- <text macro="publisher"/>
- </group>
- </if>
- <else-if type="chapter paper-conference" match="any">
- <group delimiter=", ">
- <text macro="title"/>
- <text variable="container-title" font-style="italic"/>
- <text macro="editor"/>
- <text macro="publisher"/>
- <text macro="page"/>
- </group>
- </else-if>
- <else-if type="patent">
- <text macro="title" suffix=", "/>
- <text variable="number" prefix="U.S. Patent "/>
- <date variable="issued" prefix=", ">
- <date-part name="month" suffix=" "/>
- <date-part name="day" suffix=", "/>
- <date-part name="year"/>
- </date>
- </else-if>
- <else-if type="thesis">
- <group delimiter=", ">
- <text macro="title"/>
- <text variable="genre"/>
- <text variable="publisher"/>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </group>
- </else-if>
- <else>
- <group delimiter=", ">
- <text macro="title"/>
- <text variable="container-title" font-style="italic"/>
- <text variable="volume" prefix="vol. "/>
- <date variable="issued">
- <date-part name="month" form="short" suffix=". " strip-periods="true"/>
- <date-part name="year"/>
- </date>
- <text macro="page"/>
- </group>
- </else>
- </choose>
- </layout>
- </bibliography>
+ </layout>
+ </bibliography>
</style> \ No newline at end of file
diff --git a/tests/latex-reader.native b/tests/latex-reader.native
index a5e14dd8f..c6f6ce500 100644
--- a/tests/latex-reader.native
+++ b/tests/latex-reader.native
@@ -1,5 +1,6 @@
Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docAuthors = [[Str "John",Space,Str "MacFarlane"],[Str "Anonymous"]], docDate = [Str "July",Space,Str "17,",Space,Str "2006"]})
-[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
+[RawBlock "latex" "\\maketitle"
+,Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
,HorizontalRule
,Header 1 [Str "Headers"]
,Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]
@@ -14,13 +15,13 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
,HorizontalRule
,Header 1 [Str "Paragraphs"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]
-,Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]
+,Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard-wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]
+,Para [Str "Here\8217s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]
,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here."]
,HorizontalRule
,Header 1 [Str "Block",Space,Str "Quotes"]
-,Para [Str "E",Str "-",Str "mail",Space,Str "style:"]
+,Para [Str "E-mail",Space,Str "style:"]
,BlockQuote
[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."]]
,BlockQuote
@@ -36,7 +37,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,BlockQuote
[Para [Str "nested"]]]
,Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]
-,Para [Str "Box",Str "-",Str "style:"]
+,Para [Str "Box-style:"]
,BlockQuote
[Para [Str "Example:"]
,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"]
@@ -44,11 +45,11 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
[OrderedList (1,Decimal,Period)
[[Para [Str "do",Space,Str "laundry"]]
,[Para [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"]]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "nested",Space,Str "one:"]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "nested",Space,Str "one:"]
,BlockQuote
[Para [Str "Joe",Space,Str "said:"]
,BlockQuote
- [Para [Str "Don",Apostrophe,Str "t",Space,Str "quote",Space,Str "me."]]]
+ [Para [Str "Don\8217t",Space,Str "quote",Space,Str "me."]]]
,Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]
,HorizontalRule
,Header 1 [Str "Code",Space,Str "Blocks"]
@@ -113,7 +114,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Multiple",Space,Str "paragraphs:"]
,OrderedList (1,Decimal,Period)
[[Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]
- ,Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back."]]
+ ,Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog\8217s",Space,Str "back."]]
,[Para [Str "Item",Space,Str "2."]]
,[Para [Str "Item",Space,Str "3."]]]
,Header 2 [Str "Nested"]
@@ -123,7 +124,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
[[Para [Str "Tab"]
,BulletList
[[Para [Str "Tab"]]]]]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "another:"]
+,Para [Str "Here\8217s",Space,Str "another:"]
,OrderedList (1,Decimal,Period)
[[Para [Str "First"]]
,[Para [Str "Second:"]
@@ -217,7 +218,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]
,Para [Str "foo",Space,Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]
,Para [Str "foo",Space,Str "bar",Space,Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]
-,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Space,Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"],Space,Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block:"]
+,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Space,Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"],Space,Str "Here\8217s",Space,Str "a",Space,Str "simple",Space,Str "block:"]
,Para [Str "foo",Space,Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]
,CodeBlock ("",[],[]) "<div>\n foo\n</div>"
,Para [Str "As",Space,Str "should",Space,Str "this:"]
@@ -230,7 +231,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]
,Para [Str "Code:"]
,CodeBlock ("",[],[]) "<hr />"
-,Para [Str "Hr",Apostrophe,Str "s:"]
+,Para [Str "Hr\8217s:"]
,HorizontalRule
,Header 1 [Str "Inline",Space,Str "Markup"]
,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]
@@ -244,35 +245,35 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]
,Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello",Space,Str "there"],Str "."]
,Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many",Space,Str "of",Space,Str "them"],Str "O."]
-,Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a",Str "^",Str "b",Space,Str "c",Str "^",Str "d,",Space,Str "a",Str "~",Str "b",Space,Str "c",Str "~",Str "d."]
+,Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a^b",Space,Str "c^d,",Space,Str "a",Math InlineMath "\\sim",Str "b",Space,Str "c",Math InlineMath "\\sim",Str "d."]
,HorizontalRule
,Header 1 [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]
,Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name."]]
,Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters."]
,Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine."]]
-,Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s?"]
+,Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70\8217s?"]
,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code ("",[],[]) "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]
-,Para [Str "Some",Space,Str "dashes:",Space,Str "one",EmDash,Str "two",EmDash,Str "three",EmDash,Str "four",EmDash,Str "five."]
-,Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5",EnDash,Str "7,",Space,Str "255",EnDash,Str "66,",Space,Str "1987",EnDash,Str "1999."]
-,Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]
+,Para [Str "Some",Space,Str "dashes:",Space,Str "one\8212two\8212three\8212four\8212five."]
+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5\8211\&7,",Space,Str "255\8211\&66,",Space,Str "1987\8211\&1999."]
+,Para [Str "Ellipses\8230and\8230and\8230."]
,HorizontalRule
,Header 1 [Str "LaTeX"]
,BulletList
- [[Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str "22",Str "-",Str "23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] []]]
+ [[Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str ",",Space,Str "22-23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline "latex" "\\cite[22-23]{smith.1899}"]]]
,[Para [RawInline "latex" "\\doublespacing"]]
,[Para [Math InlineMath "2+2=4"]]
,[Para [Math InlineMath "x \\in y"]]
,[Para [Math InlineMath "\\alpha \\wedge \\omega"]]
,[Para [Math InlineMath "223"]]
- ,[Para [Math InlineMath "p",Str "-",Str "Tree"]]
+ ,[Para [Math InlineMath "p",Str "-Tree"]]
,[Para [Math InlineMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]
- ,[Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
-,Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math:"]
+ ,[Para [Str "Here\8217s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
+,Para [Str "These",Space,Str "shouldn\8217t",Space,Str "be",Space,Str "math:"]
,BulletList
[[Para [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code ("",[],[]) "$e = mc^2$",Str "."]]
- ,[Para [Str "$",Str "22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$",Str "34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized.)"]]
- ,[Para [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
+ ,[Para [Str "$22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized.)"]]
+ ,[Para [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."]]]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
,Table [] [AlignLeft,AlignLeft] [0.0,0.0]
[[Plain [Str "Animal"]]
,[Plain [Str "Number"]]]
@@ -289,8 +290,8 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,[Para [Str "section:",Space,Str "\167"]]
,[Para [Str "set",Space,Str "membership:",Space,Str "\8712"]]
,[Para [Str "copyright:",Space,Str "\169"]]]
-,Para [Str "AT",Str "&",Str "T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]
-,Para [Str "AT",Str "&",Str "T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]
+,Para [Str "AT&T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]
+,Para [Str "AT&T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]
,Para [Str "This",Space,Str "&",Space,Str "that."]
,Para [Str "4",Space,Str "<",Space,Str "5."]
,Para [Str "6",Space,Str ">",Space,Str "5."]
@@ -304,7 +305,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Right",Space,Str "bracket:",Space,Str "]"]
,Para [Str "Left",Space,Str "paren:",Space,Str "("]
,Para [Str "Right",Space,Str "paren:",Space,Str ")"]
-,Para [Str "Greater",Str "-",Str "than:",Space,Str ">"]
+,Para [Str "Greater-than:",Space,Str ">"]
,Para [Str "Hash:",Space,Str "#"]
,Para [Str "Period:",Space,Str "."]
,Para [Str "Bang:",Space,Str "!"]
@@ -319,37 +320,37 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/",""),Str "."]
,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","")]
,Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","")]
-,Para [Link [Str "with",Str "_",Str "underscore"] ("/url/with_underscore","")]
+,Para [Link [Str "with_underscore"] ("/url/with_underscore","")]
,Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]
,Para [Link [Str "Empty"] ("",""),Str "."]
,Header 2 [Str "Reference"]
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
-,Para [Str "With",Space,Link [Str "embedded",Space,Str "[",Str "brackets",Str "]"] ("/url/",""),Str "."]
+,Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]
,Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]
,Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]
,Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]
,Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]
-,Para [Str "This",Space,Str "should",Space,Str "[",Str "not",Str "]",Str "[",Str "]",Space,Str "be",Space,Str "a",Space,Str "link."]
+,Para [Str "This",Space,Str "should",Space,Str "[not][]",Space,Str "be",Space,Str "a",Space,Str "link."]
,CodeBlock ("",[],[]) "[not]: /url"
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
,Para [Str "Foo",Space,Link [Str "biz"] ("/url/",""),Str "."]
,Header 2 [Str "With",Space,Str "ampersands"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT&T"] ("http://att.com/",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
,Header 2 [Str "Autolinks"]
,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Code ("",["url"],[]) "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
,BulletList
[[Para [Str "In",Space,Str "a",Space,Str "list?"]]
,[Para [Link [Code ("",["url"],[]) "http://example.com/"] ("http://example.com/","")]]
,[Para [Str "It",Space,Str "should."]]]
-,Para [Str "An",Space,Str "e",Str "-",Str "mail",Space,Str "address:",Space,Link [Code ("",[],[]) "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link [Code ("",[],[]) "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
,BlockQuote
[Para [Str "Blockquoted:",Space,Link [Code ("",["url"],[]) "http://example.com/"] ("http://example.com/","")]]
-,Para [Str "Auto",Str "-",Str "links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]
+,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]
,CodeBlock ("",[],[]) "or here: <http://example.com/>"
,HorizontalRule
,Header 1 [Str "Images"]
@@ -358,7 +359,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "image"] ("movie.jpg",""),Space,Str "icon."]
,HorizontalRule
,Header 1 [Str "Footnotes"]
-,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here\8217s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.[^my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]]
,BlockQuote
[Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes.",Note [Para [Str "In",Space,Str "quote."]]]]
,OrderedList (1,Decimal,Period)
diff --git a/tests/lhs-test.html b/tests/lhs-test.html
index 75ad7b41f..955adcdd7 100644
--- a/tests/lhs-test.html
+++ b/tests/lhs-test.html
@@ -2,37 +2,37 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">
-/*<![CDATA[*/
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
- { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
-td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+ margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
-code.sourceCode span.kw { color: #007020; font-weight: bold; }
-code.sourceCode span.dt { color: #902000; }
-code.sourceCode span.dv { color: #40a070; }
-code.sourceCode span.bn { color: #40a070; }
-code.sourceCode span.fl { color: #40a070; }
-code.sourceCode span.ch { color: #4070a0; }
-code.sourceCode span.st { color: #4070a0; }
-code.sourceCode span.co { color: #60a0b0; font-style: italic; }
-code.sourceCode span.ot { color: #007020; }
-code.sourceCode span.al { color: red; font-weight: bold; }
-code.sourceCode span.fu { color: #06287e; }
-code.sourceCode span.re { }
-code.sourceCode span.er { color: red; font-weight: bold; }
-/*]]>*/
+code > span.kw { color: #007020; font-weight: bold; }
+code > span.dt { color: #902000; }
+code > span.dv { color: #40a070; }
+code > span.bn { color: #40a070; }
+code > span.fl { color: #40a070; }
+code > span.ch { color: #4070a0; }
+code > span.st { color: #4070a0; }
+code > span.co { color: #60a0b0; font-style: italic; }
+code > span.ot { color: #007020; }
+code > span.al { color: #ff0000; font-weight: bold; }
+code > span.fu { color: #06287e; }
+code > span.er { color: #ff0000; font-weight: bold; }
</style>
</head>
<body>
<h1 id="lhs-test">lhs test</h1>
<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>
-<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">unsplit </span><span class="ot">::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d<br />unsplit <span class="fu">=</span> arr <span class="fu">.</span> <span class="fu">uncurry</span> <br /> <span class="co">-- arr (\op (x,y) -&gt; x `op` y) </span></code></pre>
+<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d
+unsplit <span class="fu">=</span> arr <span class="fu">.</span> <span class="fu">uncurry</span>
+ <span class="co">-- arr (\op (x,y) -&gt; x `op` y) </span></code></pre>
<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
-<pre><code>f *** g = first f &gt;&gt;&gt; second g
-</code></pre>
+<pre><code>f *** g = first f &gt;&gt;&gt; second g</code></pre>
<p>Block quote:</p>
<blockquote>
<p>foo bar</p>
diff --git a/tests/lhs-test.html+lhs b/tests/lhs-test.html+lhs
index 16112299d..ea6fa3d48 100644
--- a/tests/lhs-test.html+lhs
+++ b/tests/lhs-test.html+lhs
@@ -2,37 +2,37 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">
-/*<![CDATA[*/
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
- { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
-td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+ margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
-code.sourceCode span.kw { color: #007020; font-weight: bold; }
-code.sourceCode span.dt { color: #902000; }
-code.sourceCode span.dv { color: #40a070; }
-code.sourceCode span.bn { color: #40a070; }
-code.sourceCode span.fl { color: #40a070; }
-code.sourceCode span.ch { color: #4070a0; }
-code.sourceCode span.st { color: #4070a0; }
-code.sourceCode span.co { color: #60a0b0; font-style: italic; }
-code.sourceCode span.ot { color: #007020; }
-code.sourceCode span.al { color: red; font-weight: bold; }
-code.sourceCode span.fu { color: #06287e; }
-code.sourceCode span.re { }
-code.sourceCode span.er { color: red; font-weight: bold; }
-/*]]>*/
+code > span.kw { color: #007020; font-weight: bold; }
+code > span.dt { color: #902000; }
+code > span.dv { color: #40a070; }
+code > span.bn { color: #40a070; }
+code > span.fl { color: #40a070; }
+code > span.ch { color: #4070a0; }
+code > span.st { color: #4070a0; }
+code > span.co { color: #60a0b0; font-style: italic; }
+code > span.ot { color: #007020; }
+code > span.al { color: #ff0000; font-weight: bold; }
+code > span.fu { color: #06287e; }
+code > span.er { color: #ff0000; font-weight: bold; }
</style>
</head>
<body>
<h1 id="lhs-test">lhs test</h1>
<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>
-<pre class="sourceCode"><code class="sourceCode haskell">&gt; <span class="ot">unsplit </span><span class="ot">::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d<br />&gt; unsplit <span class="fu">=</span> arr <span class="fu">.</span> <span class="fu">uncurry</span> <br />&gt; <span class="co">-- arr (\op (x,y) -&gt; x `op` y) </span></code></pre>
+<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="fu">&gt;</span><span class="ot"> unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d
+<span class="fu">&gt;</span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> <span class="fu">uncurry</span>
+<span class="fu">&gt;</span> <span class="co">-- arr (\op (x,y) -&gt; x `op` y) </span></code></pre>
<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
-<pre><code>f *** g = first f &gt;&gt;&gt; second g
-</code></pre>
+<pre><code>f *** g = first f &gt;&gt;&gt; second g</code></pre>
<p>Block quote:</p>
<blockquote>
<p>foo bar</p>
diff --git a/tests/lhs-test.latex b/tests/lhs-test.latex
index 307fd948f..4bb2ab1a6 100644
--- a/tests/lhs-test.latex
+++ b/tests/lhs-test.latex
@@ -1,4 +1,4 @@
-\documentclass{article}
+\documentclass[]{article}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\ifxetex
@@ -12,12 +12,36 @@
\usepackage[utf8]{inputenc}
\fi
\fi
+\usepackage{color}
+\usepackage{fancyvrb}
+\DefineShortVerb[commandchars=\\\{\}]{\|}
+\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
+% Add ',fontsize=\small' for more characters per line
+\newenvironment{Shaded}{}{}
+\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
+\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
+\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
+\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
+\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
+\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
+\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
+\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
+\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
+\newcommand{\RegionMarkerTok}[1]{{#1}}
+\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
+\newcommand{\NormalTok}[1]{{#1}}
\ifxetex
\usepackage[setpagesize=false, % page size defined by xetex
unicode=false, % unicode breaks when used with xetex
- xetex]{hyperref}
+ xetex,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\else
- \usepackage[unicode=true]{hyperref}
+ \usepackage[unicode=true,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\fi
\hypersetup{breaklinks=true, pdfborder={0 0 0}}
\setlength{\parindent}{0pt}
@@ -33,11 +57,13 @@
\texttt{unsplit} is an arrow that takes a pair of values and combines them to
return a single value:
-\begin{verbatim}
-unsplit :: (Arrow a) => (b -> c -> d) -> a (b, c) d
-unsplit = arr . uncurry
- -- arr (\op (x,y) -> x `op` y)
-\end{verbatim}
+\begin{Shaded}
+\begin{Highlighting}[]
+\OtherTok{unsplit ::} \NormalTok{(}\DataTypeTok{Arrow} \NormalTok{a) }\OtherTok{=>} \NormalTok{(b }\OtherTok{->} \NormalTok{c }\OtherTok{->} \NormalTok{d) }\OtherTok{->} \NormalTok{a (b, c) d}
+\NormalTok{unsplit }\FunctionTok{=} \NormalTok{arr }\FunctionTok{.} \FunctionTok{uncurry}
+ \CommentTok{-- arr (\textbackslash{}op (x,y) -> x `op` y) }
+\end{Highlighting}
+\end{Shaded}
\texttt{(***)} combines two arrows into a new arrow by running the two arrows
on a pair of values (one arrow on the first item of the pair and one arrow on
the second item of the pair).
diff --git a/tests/lhs-test.latex+lhs b/tests/lhs-test.latex+lhs
index 4d36dc532..d80d02a38 100644
--- a/tests/lhs-test.latex+lhs
+++ b/tests/lhs-test.latex+lhs
@@ -1,4 +1,4 @@
-\documentclass{article}
+\documentclass[]{article}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\ifxetex
@@ -17,9 +17,13 @@
\ifxetex
\usepackage[setpagesize=false, % page size defined by xetex
unicode=false, % unicode breaks when used with xetex
- xetex]{hyperref}
+ xetex,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\else
- \usepackage[unicode=true]{hyperref}
+ \usepackage[unicode=true,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\fi
\hypersetup{breaklinks=true, pdfborder={0 0 0}}
\setlength{\parindent}{0pt}
diff --git a/tests/lhs-test.markdown b/tests/lhs-test.markdown
index 1d6cfcfb7..261021bb7 100644
--- a/tests/lhs-test.markdown
+++ b/tests/lhs-test.markdown
@@ -1,4 +1,5 @@
-# lhs test
+lhs test
+========
`unsplit` is an arrow that takes a pair of values and combines them to return
a single value:
diff --git a/tests/lhs-test.nohl.html b/tests/lhs-test.nohl.html
deleted file mode 100644
index cd5c0ac05..000000000
--- a/tests/lhs-test.nohl.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="generator" content="pandoc" />
- <title></title>
-</head>
-<body>
-<h1 id="lhs-test">lhs test</h1>
-<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>
-<pre class="sourceCode haskell"><code>unsplit :: (Arrow a) =&gt; (b -&gt; c -&gt; d) -&gt; a (b, c) d
-unsplit = arr . uncurry
- -- arr (\op (x,y) -&gt; x `op` y)
-</code></pre>
-<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
-<pre><code>f *** g = first f &gt;&gt;&gt; second g
-</code></pre>
-<p>Block quote:</p>
-<blockquote>
-<p>foo bar</p>
-</blockquote>
-</body>
-</html>
diff --git a/tests/lhs-test.nohl.html+lhs b/tests/lhs-test.nohl.html+lhs
deleted file mode 100644
index 15c21f3be..000000000
--- a/tests/lhs-test.nohl.html+lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="generator" content="pandoc" />
- <title></title>
-</head>
-<body>
-<h1 id="lhs-test">lhs test</h1>
-<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>
-<pre class="sourceCode literate haskell"><code>&gt; unsplit :: (Arrow a) =&gt; (b -&gt; c -&gt; d) -&gt; a (b, c) d
-&gt; unsplit = arr . uncurry
-&gt; -- arr (\op (x,y) -&gt; x `op` y)
-</code></pre>
-<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a pair of values (one arrow on the first item of the pair and one arrow on the second item of the pair).</p>
-<pre><code>f *** g = first f &gt;&gt;&gt; second g
-</code></pre>
-<p>Block quote:</p>
-<blockquote>
-<p>foo bar</p>
-</blockquote>
-</body>
-</html>
diff --git a/tests/markdown-citations.chicago-author-date.txt b/tests/markdown-citations.chicago-author-date.txt
index 11d84dadc..8e207e956 100644
--- a/tests/markdown-citations.chicago-author-date.txt
+++ b/tests/markdown-citations.chicago-author-date.txt
@@ -1,4 +1,5 @@
-# Pandoc with citeproc-hs
+Pandoc with citeproc-hs
+=======================
- [@nonexistent]
@@ -14,7 +15,7 @@
- In a note.[^1]
-- A citation group (see Doe 2005, 34–35; also Doe and Roe 2007, chap. 3).
+- A citation group (see Doe 2005, chap. 3; also Doe and Roe 2007, 34–35).
- Another one (see Doe 2005, 34–35).
@@ -22,22 +23,23 @@
- Citation with a suffix and locator (Doe 2005, 33, 35–37, and nowhere else).
-- Citation with suffix only (Doe 2005, and nowhere else).
+- Citation with suffix only (Doe 2005 and nowhere else).
- Now some modifiers.[^3]
- With some markup (*see* Doe 2005, 32).
-# References
+References
+==========
Doe, John. 2005. *First Book*. Cambridge: Cambridge University Press.
----. 2006. Article. *Journal of Generic Studies* 6: 33–34.
+———. 2006. “Article.” *Journal of Generic Studies* 6: 33–34.
-Doe, John, and Jenny Roe. 2007. Why Water Is Wet. In *Third Book*, ed. Sam Smith. Oxford: Oxford University Press.
+Doe, John, and Jenny Roe. 2007. “Why Water Is Wet.” In *Third Book*, ed. Sam Smith. Oxford: Oxford University Press.
[^1]: A citation without locators (Doe and Roe 2007).
-[^2]: Some citations (see Doe 2006, chap. 3; Doe and Roe 2007; Doe 2005).
+[^2]: Some citations (see Doe 2005, chap. 3; Doe and Roe 2007; Doe 2006).
[^3]: Like a citation without author: (2005), and now Doe with a locator (2006, 44).
diff --git a/tests/markdown-citations.ieee.txt b/tests/markdown-citations.ieee.txt
index 0fd9335ad..011bbf3de 100644
--- a/tests/markdown-citations.ieee.txt
+++ b/tests/markdown-citations.ieee.txt
@@ -1,20 +1,21 @@
-# Pandoc with citeproc-hs
+Pandoc with citeproc-hs
+=======================
- [@nonexistent]
- @nonexistent
-- Reference [1] says blah.
+- Reference 1 says blah.
-- Reference [1] says blah.
+- Reference 1 says blah.
-- Reference [1] says blah.
+- Reference 1 says blah.
-- Reference [1] says blah.
+- Reference 1 [3] says blah.
- In a note.[^1]
-- A citation group [1],[3].
+- A citation group [1], [3].
- Another one [1].
@@ -28,16 +29,17 @@
- With some markup [1].
-# References
+References
+==========
-[1] J. Doe, *First Book*, Cambridge: Cambridge University Press, 2005.
+[1] J. Doe, *First Book*. Cambridge: Cambridge University Press, 2005.
-[2] J. Doe, “Article,” *Journal of Generic Studies*, vol. 6, 2006, pp. 33-34.
+[2] J. Doe, “Article,” *Journal of Generic Studies*, vol. 6, pp. 33–34, 2006.
-[3] J. Doe and J. Roe, “Why Water Is Wet,” *Third Book*, Smith, S., Ed., Oxford: Oxford University Press, 2007.
+[3] J. Doe and J. Roe, “Why Water Is Wet,” in *Third Book*, S. Smith, Ed. Oxford: Oxford University Press, 2007.
[^1]: A citation without locators [3].
-[^2]: Some citations [1]-[3].
+[^2]: Some citations [1–3].
[^3]: Like a citation without author: [1], and now Doe with a locator [2].
diff --git a/tests/markdown-citations.mhra.txt b/tests/markdown-citations.mhra.txt
index 56eb147a3..17b8f1a40 100644
--- a/tests/markdown-citations.mhra.txt
+++ b/tests/markdown-citations.mhra.txt
@@ -1,4 +1,5 @@
-# Pandoc with citeproc-hs
+Pandoc with citeproc-hs
+=======================
- [@nonexistent]
@@ -28,34 +29,35 @@
- With some markup.[^12]
-# References
+References
+==========
-Doe, John, ‘Article’, *Journal of Generic Studies*, 6 (2006), 33-34.
+Doe, John, ‘Article’, *Journal of Generic Studies*, 6 (2006), 33–34.
---, *First Book* (Cambridge: Cambridge University Press, 2005).
-Doe, John, and Jenny Roe, ‘Why Water Is Wet’, in *Third Book*, ed by Sam Smith (Oxford: Oxford University Press, 2007).
+Doe, John, and Jenny Roe, ‘Why Water Is Wet’, in *Third Book*, ed. by Sam Smith (Oxford: Oxford University Press, 2007).
[^1]: *First Book* (Cambridge: Cambridge University Press, 2005).
-[^2]: First Book, p. 30.
+[^2]: *First Book*, p. 30.
-[^3]: First Book, p. 30, with suffix.
+[^3]: *First Book*, p. 30, with suffix.
-[^4]: First Book; ‘Article’, *Journal of Generic Studies*, 6 (2006), 33-34 (p. 30); see also John Doe and Jenny Roe, ‘Why Water Is Wet’, in *Third Book*, ed by Sam Smith (Oxford: Oxford University Press, 2007).
+[^4]: *First Book*; ‘Article’, *Journal of Generic Studies*, 6 (2006), 33–34 (p. 30); see also John Doe and Jenny Roe, ‘Why Water Is Wet’, in *Third Book*, ed. by Sam Smith (Oxford: Oxford University Press, 2007).
[^5]: A citation without locators Doe and Roe.
-[^6]: See Doe, First Book, pp. 34-35; also Doe and Roe, chap. 3.
+[^6]: See Doe, *First Book*, chap. 3; also Doe and Roe, pp. 34–35.
-[^7]: See Doe, First Book, pp. 34-35.
+[^7]: See Doe, *First Book*, pp. 34–35.
-[^8]: Some citations see Doe, Article, 33-34 (chap. 3); Doe and Roe; Doe, First Book.
+[^8]: Some citations see Doe, *First Book*, chap. 3; Doe and Roe; Doe, ‘Article’, 33–34.
-[^9]: Doe, First Book, pp. 33, 35-37, and nowhere else.
+[^9]: Doe, *First Book*, pp. 33, 35–37, and nowhere else.
-[^10]: Doe, First Book, and nowhere else.
+[^10]: Doe, *First Book* and nowhere else.
-[^11]: Like a citation without author: First Book, and now Doe with a locator Article, 33-34 (p. 44).
+[^11]: Like a citation without author: *First Book*, and now Doe with a locator ‘Article’, 33–34 (p. 44).
-[^12]: *See* Doe, First Book, p. 32.
+[^12]: *See* Doe, *First Book*, p. 32.
diff --git a/tests/markdown-citations.txt b/tests/markdown-citations.txt
index e2864d365..1207c0133 100644
--- a/tests/markdown-citations.txt
+++ b/tests/markdown-citations.txt
@@ -1,4 +1,5 @@
-# Pandoc with citeproc-hs
+Pandoc with citeproc-hs
+=======================
- [@nonexistent]
@@ -10,11 +11,11 @@
- @item1 [p. 30, with suffix] says blah.
-- @item1 [-@item2 p. 30; see also @item3] says blah.
+- @item1 [-@item2 p. 30; see also @пункт3] says blah.
- In a note.[^1]
-- A citation group [see @item1 p. 34-35; also @item3 chap. 3].
+- A citation group [see @item1 chap. 3; also @пункт3 p. 34-35].
- Another one [see @item1 p. 34-35].
@@ -28,10 +29,11 @@
- With some markup [*see* @item1 p. **32**].
-# References
+References
+==========
-[^1]: A citation without locators [@item3].
+[^1]: A citation without locators [@пункт3].
-[^2]: Some citations [see @item2 chap. 3; @item3; @item1].
+[^2]: Some citations [see @item1 chap. 3; @пункт3; @item2].
[^3]: Like a citation without author: [-@item1], and now Doe with a locator [-@item2 p. 44].
diff --git a/tests/markdown-reader-more.native b/tests/markdown-reader-more.native
index e5e079e9f..a24e48e86 100644
--- a/tests/markdown-reader-more.native
+++ b/tests/markdown-reader-more.native
@@ -2,7 +2,7 @@
,Header 2 [Str "Blank",Space,Str "line",Space,Str "before",Space,Str "URL",Space,Str "in",Space,Str "link",Space,Str "reference"]
,Para [Link [Str "foo"] ("/url",""),Space,Str "and",Space,Link [Str "bar"] ("/url","title")]
,Header 2 [Str "Raw",Space,Str "ConTeXt",Space,Str "environments"]
-,Plain [RawInline "tex" "\\placeformula"]
+,Plain [RawInline "tex" "\\placeformula "]
,RawBlock "context" "\\startformula\n L_{1} = L_{2}\n \\stopformula"
,RawBlock "context" "\\start[a2]\n\\start[a2]\n\\stop[a2]\n\\stop[a2]"
,Header 2 [Str "URLs",Space,Str "with",Space,Str "spaces"]
@@ -29,9 +29,9 @@
,Para [Str "`",Str "hi"]
,Para [Str "there",Str "`"]
,Header 2 [Str "Multilingual",Space,Str "URLs"]
-,Para [Link [Code ("",["url"],[]) "http://\27979.com?\27979=\27979"] ("http://%E6%B5%8B.com?%E6%B5%8B=%E6%B5%8B","")]
-,Para [Link [Str "foo"] ("/bar/%E6%B5%8B?x=%E6%B5%8B","title")]
-,Para [Link [Code ("",["url"],[]) "\27979@foo.\27979.baz"] ("mailto:%E6%B5%8B@foo.%E6%B5%8B.baz","")]
+,Plain [RawInline "html" "<http://\27979.com?\27979=\27979>"]
+,Para [Link [Str "foo"] ("/bar/\27979?x=\27979","title")]
+,Para [Link [Code ("",["url"],[]) "\27979@foo.\27979.baz"] ("mailto:\27979@foo.\27979.baz","")]
,Header 2 [Str "Numbered",Space,Str "examples"]
,OrderedList (1,Example,TwoParens)
[[Plain [Str "First",Space,Str "example",Str "."]]
@@ -47,4 +47,14 @@
,Para [Link [Str "bat"] ("/bat","")]
,Header 2 [Str "Curly",Space,Str "smart",Space,Str "quotes"]
,Para [Quoted DoubleQuote [Str "Hi"]]
-,Para [Quoted SingleQuote [Str "Hi"]]]
+,Para [Quoted SingleQuote [Str "Hi"]]
+,Header 2 [Str "Consecutive",Space,Str "lists"]
+,BulletList
+ [[Plain [Str "one"]]
+ ,[Plain [Str "two"]]]
+,OrderedList (1,Decimal,Period)
+ [[Plain [Str "one"]]
+ ,[Plain [Str "two"]]]
+,OrderedList (1,LowerAlpha,Period)
+ [[Plain [Str "one"]]
+ ,[Plain [Str "two"]]]]
diff --git a/tests/markdown-reader-more.txt b/tests/markdown-reader-more.txt
index 258002b8a..b99bb3121 100644
--- a/tests/markdown-reader-more.txt
+++ b/tests/markdown-reader-more.txt
@@ -123,3 +123,13 @@ $\tuple{x,y}$
“Hi”
‘Hi’
+
+## Consecutive lists
+
+- one
+- two
+1. one
+2. two
+
+ a. one
+ b. two
diff --git a/tests/mhra.csl b/tests/mhra.csl
index 4749cdcd7..fe34c8f84 100644
--- a/tests/mhra.csl
+++ b/tests/mhra.csl
@@ -1,390 +1,399 @@
<?xml version="1.0" encoding="utf-8"?>
-<style xmlns="http://purl.org/net/xbiblio/csl" class="note" version="1.0">
- <info>
- <title>Modern Humanities Research Association (Note with Bibliography)</title>
- <id>http://www.zotero.org/styles/mhra</id>
- <link href="http://www.zotero.org/styles/mhra" rel="self"/>
- <link href="http://www.mhra.org.uk/Publications/Books/StyleGuide/download.shtml" rel="documentation"/>
- <author>
- <name>Rintze Zelle</name>
- <uri>http://forums.zotero.org/account/831/</uri>
- </author>
- <contributor>
- <name>Sebastian Karcher</name>
- </contributor>
- <summary>MHRA format with full notes and bibliography</summary>
- <category field="generic-base"/>
- <category citation-format="note"/>
- <updated>2009-12-15T12:42:52+00:00</updated>
- </info>
- <locale xml:lang="en">
- <terms>
- <term name="et-al">and others</term>
- <term name="editor" form="verb-short">ed. by</term>
- <term name="edition" form="short">edn</term>
- <term name="translator" form="verb-short">trans. by</term>
- </terms>
- </locale>
- <macro name="author">
- <names variable="author">
- <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
- <label form="short" prefix=", " suffix="." strip-periods="true"/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- <text macro="title-note"/>
- </substitute>
+<style xmlns="http://purl.org/net/xbiblio/csl" class="note" version="1.0" demote-non-dropping-particle="sort-only">
+ <info>
+ <title>Modern Humanities Research Association (Note with Bibliography)</title>
+ <id>http://www.zotero.org/styles/mhra</id>
+ <link href="http://www.zotero.org/styles/mhra" rel="self"/>
+ <link href="http://www.mhra.org.uk/Publications/Books/StyleGuide/download.shtml" rel="documentation"/>
+ <author>
+ <name>Rintze Zelle</name>
+ <uri>http://twitter.com/rintzezelle</uri>
+ </author>
+ <contributor>
+ <name>Sebastian Karcher</name>
+ </contributor>
+ <summary>MHRA format with full notes and bibliography</summary>
+ <category field="generic-base"/>
+ <category citation-format="note"/>
+ <updated>2011-08-18T16:08:33+00:00</updated>
+ <rights>This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
+ </info>
+ <locale xml:lang="en">
+ <terms>
+ <term name="et-al">and others</term>
+ <term name="editor" form="verb-short">ed. by</term>
+ <term name="edition" form="short">edn</term>
+ <term name="translator" form="verb-short">trans. by</term>
+ </terms>
+ </locale>
+ <macro name="author">
+ <names variable="author">
+ <name name-as-sort-order="first" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="always"/>
+ <label form="short" prefix=", " suffix="."/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ <text macro="title-note"/>
+ </substitute>
+ </names>
+ </macro>
+ <macro name="contributors-note">
+ <names variable="author">
+ <name and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="never"/>
+ </names>
+ <text macro="recipient-note"/>
+ </macro>
+ <macro name="title-note">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song" match="any">
+ <text variable="title" font-style="italic" text-case="title"/>
+ </if>
+ <else>
+ <text variable="title" prefix="‘" suffix="’" text-case="title"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="title-short">
+ <choose>
+ <if disambiguate="true">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song" match="any">
+ <text variable="title" font-style="italic" text-case="title" form="short"/>
+ </if>
+ <else>
+ <text variable="title" prefix="‘" suffix="’" text-case="title" form="short"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="editor-translator">
+ <group delimiter=", ">
+ <names variable="editor" delimiter=", ">
+ <label form="verb-short" text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", " delimiter-precedes-last="never"/>
</names>
- </macro>
- <macro name="contributors-note">
- <names variable="author">
- <name and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="never"/>
- </names>
- <text macro="recipient-note"/>
- </macro>
- <macro name="title-note">
- <choose>
- <if type="bill book graphic legal_case motion_picture report song" match="any">
- <text variable="title" font-style="italic"/>
- </if>
- <else>
- <text variable="title" prefix="‘" suffix="’"/>
- </else>
- </choose>
- </macro>
- <macro name="editor-translator">
- <group delimiter=", ">
- <names variable="editor" delimiter=", ">
- <label form="verb-short" text-case="lowercase" suffix=" " strip-periods="true"/>
- <name and="text" delimiter=", " delimiter-precedes-last="never"/>
- </names>
- <choose>
- <if variable="author editor" match="any">
- <names variable="translator" delimiter=", ">
- <label form="verb-short" text-case="lowercase" suffix=" " strip-periods="true"/>
- <name and="text" delimiter=", " delimiter-precedes-last="never"/>
- </names>
- </if>
- </choose>
- </group>
- </macro>
- <macro name="collection-title">
- <text variable="collection-title"/>
- <text variable="collection-number" prefix=", "/>
- </macro>
- <macro name="locators-note">
- <choose>
- <if type="article-journal">
- <text variable="volume"/>
- </if>
- <else-if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
- <group delimiter=", ">
- <text macro="edition-note"/>
- <group>
- <number variable="number-of-volumes" form="numeric"/>
- <text term="volume" form="short" prefix=" " plural="true" strip-periods="true"/>
- </group>
- </group>
- </else-if>
- </choose>
- </macro>
- <macro name="volume">
- <choose>
- <if type="article-journal">
- <text variable="volume"/>
- </if>
- <else-if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
- <group delimiter=", ">
- <text macro="edition-note"/>
- <group>
- <number variable="number-of-volumes" form="numeric"/>
- <text term="volume" form="short" prefix=" " plural="true" strip-periods="true"/>
- </group>
- </group>
- </else-if>
- </choose>
- </macro>
- <macro name="issue-note">
<choose>
- <if type="article-journal">
- <choose>
- <if variable="volume">
- <text macro="issued" prefix=" (" suffix=")"/>
- </if>
- <else>
- <text macro="issued" prefix=", "/>
- </else>
- </choose>
- </if>
- <else-if variable="publisher-place publisher" match="any">
- <group prefix=" (" suffix=")" delimiter=", ">
- <group delimiter=" ">
- <choose>
- <if variable="title" match="none"/>
- <else-if type="thesis speech" match="any">
- <text variable="genre" prefix="unpublished "/>
- </else-if>
- </choose>
- <text macro="event"/>
- </group>
- <text macro="publisher"/>
- <text macro="issued"/>
- </group>
- </else-if>
- <else>
- <text macro="issued" prefix=", "/>
- </else>
+ <if variable="author editor" match="any">
+ <names variable="translator" delimiter=", ">
+ <label form="verb-short" text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", " delimiter-precedes-last="never"/>
+ </names>
+ </if>
</choose>
- </macro>
- <macro name="locators-specific-note">
+ </group>
+ </macro>
+ <macro name="collection-title">
+ <text variable="collection-title" text-case="title"/>
+ <text variable="collection-number" prefix=", "/>
+ </macro>
+ <macro name="locators-note">
+ <choose>
+ <if type="article-journal">
+ <text variable="volume"/>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <group delimiter=", ">
+ <text macro="edition-note"/>
+ <group>
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" prefix=" " plural="true"/>
+ </group>
+ </group>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="volume">
+ <choose>
+ <if type="article-journal">
+ <text variable="volume"/>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <group delimiter=", ">
+ <text macro="edition-note"/>
+ <group>
+ <number variable="number-of-volumes" form="numeric"/>
+ <text term="volume" form="short" prefix=" " plural="true"/>
+ </group>
+ </group>
+ </else-if>
+ </choose>
+ </macro>
+ <macro name="issue-note">
+ <choose>
+ <if type="article-journal">
+ <choose>
+ <if variable="volume">
+ <text macro="issued" prefix=" (" suffix=")"/>
+ </if>
+ <else>
+ <text macro="issued" prefix=", "/>
+ </else>
+ </choose>
+ </if>
+ <else-if variable="publisher-place publisher" match="any">
+ <group prefix=" (" suffix=")" delimiter=", ">
+ <group delimiter=" ">
+ <choose>
+ <if variable="title" match="none"/>
+ <else-if type="thesis speech" match="any">
+ <text variable="genre" prefix="unpublished "/>
+ </else-if>
+ </choose>
+ <text macro="event"/>
+ </group>
+ <text macro="publisher"/>
+ <text macro="issued"/>
+ </group>
+ </else-if>
+ <else>
+ <text macro="issued" prefix=", "/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="locators-specific-note">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <choose>
+ <if is-numeric="volume">
+ <number variable="volume" form="roman" font-variant="small-caps"/>
+ </if>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="container-title-note">
+ <choose>
+ <if type="chapter paper-conference" match="any">
+ <text term="in" text-case="lowercase" suffix=" "/>
+ </if>
+ </choose>
+ <text variable="container-title" font-style="italic" text-case="title"/>
+ </macro>
+ <macro name="edition-note">
+ <choose>
+ <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
+ <choose>
+ <if is-numeric="edition">
+ <group delimiter=" ">
+ <number variable="edition" form="ordinal"/>
+ <text term="edition" form="short"/>
+ </group>
+ </if>
+ <else>
+ <text variable="edition"/>
+ </else>
+ </choose>
+ </if>
+ </choose>
+ </macro>
+ <macro name="editor-note">
+ <names variable="editor">
+ <name and="text" sort-separator=", " delimiter=", "/>
+ <label form="short" prefix=", " suffix="."/>
+ </names>
+ </macro>
+ <macro name="translator-note">
+ <names variable="translator">
+ <name and="text" sort-separator=", " delimiter=", "/>
+ <label form="verb-short" prefix=", " suffix="."/>
+ </names>
+ </macro>
+ <macro name="recipient-note">
+ <names variable="recipient" delimiter=", ">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="recipient-short">
+ <names variable="recipient">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name form="short" and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="contributors-short">
+ <names variable="author">
+ <name form="short" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="never"/>
+ <substitute>
+ <names variable="editor"/>
+ <names variable="translator"/>
+ </substitute>
+ </names>
+ <text macro="recipient-short"/>
+ </macro>
+ <macro name="interviewer-note">
+ <names variable="interviewer" delimiter=", ">
+ <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
+ <name and="text" delimiter=", "/>
+ </names>
+ </macro>
+ <macro name="locators-newspaper">
+ <choose>
+ <if type="article-newspaper">
+ <group delimiter=", ">
+ <group>
+ <text variable="edition" suffix=" "/>
+ <text term="edition" prefix=" "/>
+ </group>
+ <group>
+ <text term="section" suffix=" "/>
+ <text variable="section"/>
+ </group>
+ </group>
+ </if>
+ </choose>
+ </macro>
+ <macro name="event">
+ <group>
+ <text term="presented at" suffix=" "/>
+ <text variable="event"/>
+ </group>
+ </macro>
+ <macro name="publisher">
+ <group delimiter=": ">
+ <text variable="publisher-place"/>
+ <text variable="publisher"/>
+ </group>
+ </macro>
+ <macro name="issued">
+ <choose>
+ <if type="graphic report article-newspaper" match="any">
+ <date variable="issued">
+ <date-part name="day" suffix=" "/>
+ <date-part name="month" suffix=" "/>
+ <date-part name="year"/>
+ </date>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song thesis chapter paper-conference" match="any">
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </else-if>
+ <else>
+ <date variable="issued">
+ <date-part name="year"/>
+ </date>
+ </else>
+ </choose>
+ </macro>
+ <macro name="pages">
+ <choose>
+ <if type="article-journal">
+ <text variable="page" prefix=", "/>
+ </if>
+ <else>
+ <choose>
+ <if variable="volume">
+ <text variable="page" prefix=", "/>
+ </if>
+ <else>
+ <label variable="page" form="short" prefix=", " suffix=" "/>
+ <text variable="page"/>
+ </else>
+ </choose>
+ </else>
+ </choose>
+ </macro>
+ <macro name="point-locators">
+ <text macro="pages"/>
+ <choose>
+ <if variable="page">
+ <group prefix=" (" suffix=")">
+ <label variable="locator" form="short" suffix=" "/>
+ <text variable="locator"/>
+ </group>
+ </if>
+ <else>
+ <label variable="locator" form="short" prefix=", " suffix=" "/>
+ <text variable="locator"/>
+ </else>
+ </choose>
+ </macro>
+ <macro name="archive-note">
+ <group delimiter=", ">
+ <text variable="archive_location"/>
+ <text variable="archive"/>
+ <text variable="archive-place"/>
+ </group>
+ </macro>
+ <macro name="access-note">
+ <group delimiter=", ">
<choose>
- <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
- <choose>
- <if is-numeric="volume">
- <number variable="volume" form="roman" font-variant="small-caps"/>
- </if>
- </choose>
- </if>
+ <if type="graphic report" match="any">
+ <text macro="archive-note" prefix=", "/>
+ </if>
+ <else-if type="bill book graphic legal_case motion_picture report song article-journal article-magazine article-newspaper thesis chapter paper-conference" match="none">
+ <text macro="archive-note" prefix=", "/>
+ </else-if>
</choose>
- </macro>
- <macro name="container-title-note">
+ </group>
+ <choose>
+ <if variable="DOI">
+ <text variable="DOI" prefix=" &lt;doi:" suffix="&gt;"/>
+ </if>
+ <else>
+ <choose>
+ <if variable="URL">
+ <text variable="URL" prefix=" &lt;" suffix="&gt;"/>
+ <group prefix=" [" suffix="]">
+ <text term="accessed" text-case="lowercase"/>
+ <date variable="accessed">
+ <date-part name="day" prefix=" "/>
+ <date-part name="month" prefix=" "/>
+ <date-part name="year" prefix=" "/>
+ </date>
+ </group>
+ </if>
+ </choose>
+ </else>
+ </choose>
+ </macro>
+ <citation et-al-min="4" et-al-use-first="1" et-al-subsequent-min="4" et-al-subsequent-use-first="1" disambiguate-add-names="true" disambiguate-add-givenname="true">
+ <layout prefix="" suffix="." delimiter="; ">
<choose>
- <if type="chapter paper-conference" match="any">
- <text term="in" text-case="lowercase" suffix=" "/>
- </if>
+ <if position="subsequent">
+ <text macro="contributors-short"/>
+ <text macro="title-short" prefix=", "/>
+ <text macro="locators-specific-note" prefix=", "/>
+ <text macro="point-locators"/>
+ </if>
+ <else>
+ <group delimiter=", ">
+ <text macro="contributors-note"/>
+ <text macro="title-note"/>
+ <text macro="container-title-note"/>
+ <text macro="editor-translator"/>
+ <text macro="collection-title"/>
+ <text macro="locators-note"/>
+ </group>
+ <text macro="issue-note"/>
+ <text macro="locators-specific-note" prefix=", "/>
+ <text macro="locators-newspaper" prefix=", "/>
+ <text macro="point-locators"/>
+ <text macro="access-note"/>
+ </else>
</choose>
- <text variable="container-title" font-style="italic"/>
- </macro>
- <macro name="edition-note">
- <choose>
- <if type="bill book graphic legal_case motion_picture report song chapter paper-conference" match="any">
- <choose>
- <if is-numeric="edition">
- <group delimiter=" ">
- <number variable="edition" form="ordinal"/>
- <text term="edition" form="short" strip-periods="true"/>
- </group>
- </if>
- <else>
- <text variable="edition"/>
- </else>
- </choose>
- </if>
- </choose>
- </macro>
- <macro name="editor-note">
- <names variable="editor">
- <name and="text" sort-separator=", " delimiter=", "/>
- <label form="short" prefix=", " suffix="." strip-periods="true"/>
- </names>
- </macro>
- <macro name="translator-note">
- <names variable="translator">
- <name and="text" sort-separator=", " delimiter=", "/>
- <label form="verb-short" prefix=", " suffix="." strip-periods="true"/>
- </names>
- </macro>
- <macro name="recipient-note">
- <names variable="recipient" delimiter=", ">
- <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
- <name and="text" delimiter=", "/>
- </names>
- </macro>
- <macro name="recipient-short">
- <names variable="recipient">
- <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
- <name form="short" and="text" delimiter=", "/>
- </names>
- </macro>
- <macro name="contributors-short">
- <names variable="author">
- <name form="short" and="text" sort-separator=", " delimiter=", " delimiter-precedes-last="never"/>
- <substitute>
- <names variable="editor"/>
- <names variable="translator"/>
- </substitute>
- </names>
- <text macro="recipient-short"/>
- </macro>
- <macro name="interviewer-note">
- <names variable="interviewer" delimiter=", ">
- <label form="verb" prefix=" " text-case="lowercase" suffix=" "/>
- <name and="text" delimiter=", "/>
- </names>
- </macro>
- <macro name="locators-newspaper">
- <choose>
- <if type="article-newspaper">
- <group delimiter=", ">
- <group>
- <text variable="edition" suffix=" "/>
- <text term="edition" prefix=" "/>
- </group>
- <group>
- <text term="section" suffix=" "/>
- <text variable="section"/>
- </group>
- </group>
- </if>
- </choose>
- </macro>
- <macro name="event">
- <group>
- <text term="presented at" suffix=" "/>
- <text variable="event"/>
- </group>
- </macro>
- <macro name="publisher">
- <group delimiter=": ">
- <text variable="publisher-place"/>
- <text variable="publisher"/>
- </group>
- </macro>
- <macro name="issued">
- <choose>
- <if type="graphic report article-newspaper" match="any">
- <date variable="issued">
- <date-part name="day" suffix=" "/>
- <date-part name="month" suffix=" "/>
- <date-part name="year"/>
- </date>
- </if>
- <else-if type="bill book graphic legal_case motion_picture report song thesis chapter paper-conference" match="any">
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else-if>
- <else>
- <date variable="issued">
- <date-part name="year"/>
- </date>
- </else>
- </choose>
- </macro>
- <macro name="pages">
- <choose>
- <if type="article-journal">
- <text variable="page" prefix=", "/>
- </if>
- <else>
- <choose>
- <if variable="volume">
- <text variable="page" prefix=", "/>
- </if>
- <else>
- <label variable="page" form="short" prefix=", " suffix=" "/>
- <text variable="page"/>
- </else>
- </choose>
- </else>
- </choose>
- </macro>
- <macro name="point-locators">
- <text macro="pages"/>
- <choose>
- <if variable="page">
- <group prefix=" (" suffix=")">
- <label variable="locator" form="short" suffix=" "/>
- <text variable="locator"/>
- </group>
- </if>
- <else>
- <label variable="locator" form="short" prefix=", " suffix=" "/>
- <text variable="locator"/>
- </else>
- </choose>
- </macro>
- <macro name="archive-note">
- <group delimiter=", ">
- <text variable="archive_location"/>
- <text variable="archive"/>
- <text variable="archive-place"/>
- </group>
- </macro>
- <macro name="access-note">
+ </layout>
+ </citation>
+ <bibliography hanging-indent="true" et-al-min="6" et-al-use-first="6" subsequent-author-substitute="---">
+ <sort>
+ <key macro="author"/>
+ <key variable="title"/>
+ </sort>
+ <layout suffix=".">
<group delimiter=", ">
- <choose>
- <if type="graphic report" match="any">
- <text macro="archive-note" prefix=", "/>
- </if>
- <else-if type="bill book graphic legal_case motion_picture report song article-journal article-magazine article-newspaper thesis chapter paper-conference" match="none">
- <text macro="archive-note" prefix=", "/>
- </else-if>
- </choose>
+ <text macro="author"/>
+ <text macro="title-note"/>
+ <text macro="container-title-note"/>
+ <text macro="editor-translator"/>
+ <text macro="collection-title"/>
+ <text macro="volume"/>
</group>
- <choose>
- <if variable="DOI">
- <text variable="DOI" prefix=" &lt;doi:" suffix="&gt;"/>
- </if>
- <else>
- <text variable="URL" prefix=" &lt;" suffix="&gt;"/>
- <choose>
- <if variable="accessed">
- <group prefix=" [" suffix="]">
- <text term="accessed" text-case="lowercase"/>
- <date variable="accessed">
- <date-part name="day" prefix=" "/>
- <date-part name="month" prefix=" "/>
- <date-part name="year" prefix=" "/>
- </date>
- </group>
- </if>
- </choose>
- </else>
- </choose>
- </macro>
- <citation et-al-min="4" et-al-use-first="1" et-al-subsequent-min="4" et-al-subsequent-use-first="1" disambiguate-add-names="true" disambiguate-add-givenname="true" givenname-disambiguation-rule="by-cite">
- <layout prefix="" suffix="." delimiter="; ">
- <choose>
- <if position="subsequent">
- <group delimiter=", ">
- <text macro="contributors-short"/>
- <choose>
- <if disambiguate="true">
- <text variable="title" form="short"/>
- </if>
- </choose>
- </group>
- <text macro="locators-specific-note" prefix=", "/>
- <text macro="point-locators"/>
- </if>
- <else>
- <group delimiter=", ">
- <text macro="contributors-note"/>
- <text macro="title-note"/>
- <text macro="container-title-note"/>
- <text macro="editor-translator"/>
- <text macro="collection-title"/>
- <text macro="locators-note"/>
- </group>
- <text macro="issue-note"/>
- <text macro="locators-specific-note" prefix=", "/>
- <text macro="locators-newspaper" prefix=", "/>
- <text macro="point-locators"/>
- <text macro="access-note"/>
- </else>
- </choose>
- </layout>
- </citation>
- <bibliography hanging-indent="true" et-al-min="6" et-al-use-first="6" subsequent-author-substitute="---">
- <sort>
- <key macro="author"/>
- <key variable="title"/>
- </sort>
- <layout suffix=".">
- <group delimiter=", ">
- <text macro="author"/>
- <text macro="title-note"/>
- <text macro="container-title-note"/>
- <text macro="editor-translator"/>
- <text macro="collection-title"/>
- <text macro="volume"/>
- </group>
- <text macro="issue-note"/>
- <text macro="locators-specific-note" prefix=", "/>
- <text macro="locators-newspaper" prefix=", "/>
- <text macro="pages"/>
- <text macro="access-note"/>
- </layout>
- </bibliography>
+ <text macro="issue-note"/>
+ <text macro="locators-specific-note" prefix=", "/>
+ <text macro="locators-newspaper" prefix=", "/>
+ <text macro="pages"/>
+ <text macro="access-note"/>
+ </layout>
+ </bibliography>
</style> \ No newline at end of file
diff --git a/tests/rst-reader.native b/tests/rst-reader.native
index 3e521cb7c..e0eb4d438 100644
--- a/tests/rst-reader.native
+++ b/tests/rst-reader.native
@@ -3,26 +3,26 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
[([Str "Revision"],
[[Para [Str "3"]]])]
,Header 1 [Str "Level",Space,Str "one",Space,Str "header"]
-,Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
+,Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Str "\8217",Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
,Header 2 [Str "Level",Space,Str "two",Space,Str "header"]
,Header 3 [Str "Level",Space,Str "three"]
,Header 4 [Str "Level",Space,Str "four",Space,Str "with",Space,Emph [Str "emphasis"]]
,Header 5 [Str "Level",Space,Str "five"]
,Header 1 [Str "Paragraphs"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
,Para [Str "In",Space,Str "Markdown",Space,Str "1",Str ".",Str "0",Str ".",Str "0",Space,Str "and",Space,Str "earlier",Str ".",Space,Str "Version",Space,Str "8",Str ".",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item",Str ".",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item",Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
,Para [Str "Horizontal",Space,Str "rule",Str ":"]
,HorizontalRule
,Para [Str "Another",Str ":"]
,HorizontalRule
,Header 1 [Str "Block",Space,Str "Quotes"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]
,BlockQuote
[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote",Str ".",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short",Str "."]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "another,",Space,Str "differently",Space,Str "indented",Str ":"]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "another,",Space,Str "differently",Space,Str "indented",Str ":"]
,BlockQuote
- [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote",Str ".",Space,Str "It",Apostrophe,Str "s",Space,Str "indented",Space,Str "with",Space,Str "a",Space,Str "tab",Str "."]
+ [Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote",Str ".",Space,Str "It",Str "\8217",Str "s",Space,Str "indented",Space,Str "with",Space,Str "a",Space,Str "tab",Str "."]
,Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]
,CodeBlock ("",[],[]) "sub status {\n print \"working\";\n}"
,Para [Str "List",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote",Str ":"]
@@ -98,7 +98,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
,Para [Str "Multiple",Space,Str "paragraphs",Str ":"]
,OrderedList (1,Decimal,Period)
[[Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one",Str "."]
- ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back",Str "."]]
+ ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Str "\8217",Str "s",Space,Str "back",Str "."]]
,[Para [Str "Item",Space,Str "2",Str "."]]
,[Para [Str "Item",Space,Str "3",Str "."]]]
,Para [Str "Nested",Str ":"]
@@ -108,7 +108,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
[[Para [Str "Tab"]
,BulletList
[[Plain [Str "Tab"]]]]]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "another",Str ":"]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "another",Str ":"]
,OrderedList (1,Decimal,Period)
[[Para [Str "First"]]
,[Para [Str "Second",Str ":"]
@@ -165,14 +165,14 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
,([Str "city"],
[[Para [Emph [Str "Nowhere"],Str ",",Space,Str "MA,",Space,Str "USA"]]])
,([Str "phone"],
- [[Para [Str "123",EnDash,Str "4567"]]])]]
+ [[Para [Str "123",Str "-",Str "4567"]]])]]
,DefinitionList
[([Str "address"],
[[Para [Str "61",Space,Str "Main",Space,Str "St",Str "."]]])
,([Str "city"],
[[Para [Emph [Str "Nowhere"],Str ",",Space,Str "MA,",Space,Str "USA"]]])
,([Str "phone"],
- [[Para [Str "123",EnDash,Str "4567"]]])]
+ [[Para [Str "123",Str "-",Str "4567"]]])]
,Header 1 [Str "HTML",Space,Str "Blocks"]
,Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line",Str ":"]
,RawBlock "html" "<div>foo</div>\n"
@@ -216,8 +216,8 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
,Para [Str "Explicit",Str ":",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]
,Para [Str "Two",Space,Str "anonymous",Space,Str "links",Str ":",Space,Link [Str "the",Space,Str "first"] ("/url1/",""),Space,Str "and",Space,Link [Str "the",Space,Str "second"] ("/url2/","")]
,Para [Str "Reference",Space,Str "links",Str ":",Space,Link [Str "link1"] ("/url1/",""),Space,Str "and",Space,Link [Str "link2"] ("/url2/",""),Space,Str "and",Space,Link [Str "link1"] ("/url1/",""),Space,Str "again",Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT&T"] ("/url/",""),Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT&T"] ("/url/",""),Str "."]
,Para [Str "Autolinks",Str ":",Space,Link [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2",""),Space,Str "and",Space,Link [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net",""),Str "."]
,Para [Str "But",Space,Str "not",Space,Str "here",Str ":"]
,CodeBlock ("",[],[]) "http://example.com/"
@@ -305,4 +305,11 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
,Para [Note [Para [Str "Note",Space,Str "with",Space,Str "continuation",Space,Str "line",Str "."]]]
,Para [Note [Para [Str "Note",Space,Str "with"],Para [Str "continuation",Space,Str "block",Str "."]]]
,Para [Note [Para [Str "Note",Space,Str "with",Space,Str "continuation",Space,Str "line"],Para [Str "and",Space,Str "a",Space,Str "second",Space,Str "para",Str "."]]]
-,Para [Str "Not",Space,Str "in",Space,Str "note",Str "."]]
+,Para [Str "Not",Space,Str "in",Space,Str "note",Str "."]
+,Header 1 [Str "Math"]
+,Para [Str "Some",Space,Str "inline",Space,Str "math",Space,Math InlineMath "E=mc^2",Str ".",Space,Str "Now",Space,Str "some",Space,Str "display",Space,Str "math",Str ":"]
+,Para [Math DisplayMath "E=mc^2"]
+,Para [Math DisplayMath "E = mc^2"]
+,Para [Math DisplayMath "E = mc^2",Math DisplayMath "\\alpha = \\beta"]
+,Para [Math DisplayMath "E &= mc^2\\\\\nF &= \\pi E",Math DisplayMath "F &= \\gamma \\alpha^2"]
+,Para [Str "All",Space,Str "done",Str "."]]
diff --git a/tests/rst-reader.rst b/tests/rst-reader.rst
index 519f0080c..cfebd2054 100644
--- a/tests/rst-reader.rst
+++ b/tests/rst-reader.rst
@@ -536,3 +536,32 @@ Footnotes
Not in note.
+Math
+====
+
+Some inline math :math:`E=mc^2`\ . Now some
+display math:
+
+.. math:: E=mc^2
+
+.. math::
+
+ E = mc^2
+
+.. math::
+
+ E = mc^2
+
+ \alpha = \beta
+
+.. math::
+ :label hithere
+ :nowrap
+
+ E &= mc^2\\
+ F &= \pi E
+
+ F &= \gamma \alpha^2
+
+All done.
+
diff --git a/tests/s5.basic.html b/tests/s5.basic.html
index 0658dcf4b..6194c27a9 100644
--- a/tests/s5.basic.html
+++ b/tests/s5.basic.html
@@ -2,21 +2,22 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="author" content="Sam Smith" />
<meta name="author" content="Jen Jones" />
- <meta name="date" content="July 15, 2006" />
+ <meta name="date" content="2006-07-15" />
<title>My S5 Document</title>
<!-- configuration parameters -->
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="hidden" />
<!-- style sheet links -->
- <link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
- <link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
- <link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
- <link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
+ <link rel="stylesheet" href="s5/default/slides.css" type="text/css" media="projection" id="slideProj" />
+ <link rel="stylesheet" href="s5/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
+ <link rel="stylesheet" href="s5/default/print.css" type="text/css" media="print" id="slidePrint" />
+ <link rel="stylesheet" href="s5/default/opera.css" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
- <script src="ui/default/slides.js" type="text/javascript"></script>
+ <script src="s5/default/slides.js" type="text/javascript"></script>
</head>
<body>
<div class="layout">
@@ -29,19 +30,19 @@
</div>
</div>
<div class="presentation">
-<div class="slide">
+<div class="titleslide slide">
<h1>My S5 Document</h1>
- <h3>Sam Smith<br/>Jen Jones</h3>
- <h4>July 15, 2006</h4>
+ <h2>Sam Smith<br/>Jen Jones</h2>
+ <h3>July 15, 2006</h3>
</div>
-<div class="slide">
+<div class="section slide level1" id="first-slide">
<h1>First slide</h1>
<ul>
<li>first bullet</li>
<li>second bullet</li>
</ul>
</div>
-<div class="slide">
+<div class="section slide level1" id="math">
<h1>Math</h1>
<ul>
<li><span class="math">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>
diff --git a/tests/s5.fancy.html b/tests/s5.fancy.html
index 39188bb1e..119306143 100644
--- a/tests/s5.fancy.html
+++ b/tests/s5.fancy.html
@@ -2,21 +2,22 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="author" content="Sam Smith" />
<meta name="author" content="Jen Jones" />
- <meta name="date" content="July 15, 2006" />
+ <meta name="date" content="2006-07-15" />
<title>My S5 Document</title>
<!-- configuration parameters -->
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="hidden" />
<!-- style sheet links -->
- <link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
- <link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
- <link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
- <link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
+ <link rel="stylesheet" href="s5/default/slides.css" type="text/css" media="projection" id="slideProj" />
+ <link rel="stylesheet" href="s5/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
+ <link rel="stylesheet" href="s5/default/print.css" type="text/css" media="print" id="slidePrint" />
+ <link rel="stylesheet" href="s5/default/opera.css" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
- <script src="ui/default/slides.js" type="text/javascript"></script>
+ <script src="s5/default/slides.js" type="text/javascript"></script>
<script type="text/javascript">/*<![CDATA[*/
/*
LaTeXMathML.js from http://math.etsu.edu/LaTeXMathML/
@@ -230,19 +231,19 @@
</div>
</div>
<div class="presentation">
-<div class="slide">
+<div class="titleslide slide">
<h1>My S5 Document</h1>
- <h3>Sam Smith<br/>Jen Jones</h3>
- <h4>July 15, 2006</h4>
+ <h2>Sam Smith<br/>Jen Jones</h2>
+ <h3>July 15, 2006</h3>
</div>
-<div class="slide">
+<div class="section slide level1" id="first-slide">
<h1>First slide</h1>
<ul class="incremental">
<li>first bullet</li>
<li>second bullet</li>
</ul>
</div>
-<div class="slide">
+<div class="section slide level1" id="math">
<h1>Math</h1>
<ul class="incremental">
<li><span class="LaTeX">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span></li>
diff --git a/tests/s5.inserts.html b/tests/s5.inserts.html
index 67832ea3d..524c5b0ce 100644
--- a/tests/s5.inserts.html
+++ b/tests/s5.inserts.html
@@ -2,10 +2,11 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="author" content="Sam Smith" />
<meta name="author" content="Jen Jones" />
- <meta name="date" content="July 15, 2006" />
+ <meta name="date" content="2006-07-15" />
<title>My S5 Document</title>
<link rel="stylesheet" href="main.css" type="text/css" />
STUFF INSERTED
@@ -14,9 +15,9 @@
STUFF INSERTED
<div id="header">
<h1 class="title">My S5 Document</h1>
-<h3 class="author">Sam Smith</h3>
-<h3 class="author">Jen Jones</h3>
-<h4 class="date">July 15, 2006</h4>
+<h2 class="author">Sam Smith</h2>
+<h2 class="author">Jen Jones</h2>
+<h3 class="date">July 15, 2006</h3>
</div>
<h1 id="first-slide">First slide</h1>
<ul>
diff --git a/tests/tables.asciidoc b/tests/tables.asciidoc
new file mode 100644
index 000000000..38daca192
--- /dev/null
+++ b/tests/tables.asciidoc
@@ -0,0 +1,71 @@
+Simple table with caption:
+
+.Demonstration of simple table syntax.
+[cols=">,<,^,",options="header",]
+|============================
+|Right |Left |Center |Default
+|12 |12 |12 |12
+|123 |123 |123 |123
+|1 |1 |1 |1
+|============================
+
+Simple table without caption:
+
+[cols=">,<,^,",options="header",]
+|============================
+|Right |Left |Center |Default
+|12 |12 |12 |12
+|123 |123 |123 |123
+|1 |1 |1 |1
+|============================
+
+Simple table indented two spaces:
+
+.Demonstration of simple table syntax.
+[cols=">,<,^,",options="header",]
+|============================
+|Right |Left |Center |Default
+|12 |12 |12 |12
+|123 |123 |123 |123
+|1 |1 |1 |1
+|============================
+
+Multiline table with caption:
+
+.Here's the caption. It may span multiple lines.
+[width="78%",cols="^21%,<17%,>20%,<42%",options="header",]
+|=======================================================================
+|Centered Header |Left Aligned |Right Aligned |Default aligned
+|First |row |12.0 |Example of a row that spans multiple lines.
+|Second |row |5.0 |Here's another one. Note the blank line between rows.
+|=======================================================================
+
+Multiline table without caption:
+
+[width="78%",cols="^21%,<17%,>20%,<42%",options="header",]
+|=======================================================================
+|Centered Header |Left Aligned |Right Aligned |Default aligned
+|First |row |12.0 |Example of a row that spans multiple lines.
+|Second |row |5.0 |Here's another one. Note the blank line between rows.
+|=======================================================================
+
+Table without column headers:
+
+[cols=">,<,^,>",]
+|=============================================================================
+|12 |12 |12 |12
+
+|123 |123 |123 |123
+
+|1 |1 |1 |1
+|=============================================================================
+
+Multiline table without column headers:
+
+[width="78%",cols="^21%,<17%,>20%,42%",]
+|=============================================================================
+|First |row |12.0 |Example of a row that spans multiple lines.
+
+|Second |row |5.0 |Here's another one. Note the blank line between rows.
+|=============================================================================
+
diff --git a/tests/testsuite.native b/tests/testsuite.native
index 879cb24fc..691c4959a 100644
--- a/tests/testsuite.native
+++ b/tests/testsuite.native
@@ -1,5 +1,5 @@
Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docAuthors = [[Str "John",Space,Str "MacFarlane"],[Str "Anonymous"]], docDate = [Str "July",Space,Str "17",Str ",",Space,Str "2006"]})
-[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
,HorizontalRule
,Header 1 [Str "Headers"]
,Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]
@@ -14,9 +14,9 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
,HorizontalRule
,Header 1 [Str "Paragraphs"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
,Para [Str "In",Space,Str "Markdown",Space,Str "1",Str ".",Str "0",Str ".",Str "0",Space,Str "and",Space,Str "earlier",Str ".",Space,Str "Version",Space,Str "8",Str ".",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item",Str ".",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item",Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
+,Para [Str "Here\8217s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here",Str "."]
,HorizontalRule
,Header 1 [Str "Block",Space,Str "Quotes"]
@@ -100,7 +100,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Multiple",Space,Str "paragraphs",Str ":"]
,OrderedList (1,Decimal,Period)
[[Para [Str "Item",Space,Str "1",Str ",",Space,Str "graf",Space,Str "one",Str "."]
- ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back",Str "."]]
+ ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog\8217s",Space,Str "back",Str "."]]
,[Para [Str "Item",Space,Str "2",Str "."]]
,[Para [Str "Item",Space,Str "3",Str "."]]]
,Header 2 [Str "Nested"]
@@ -110,7 +110,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
[[Plain [Str "Tab"]
,BulletList
[[Plain [Str "Tab"]]]]]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "another",Str ":"]
+,Para [Str "Here\8217s",Space,Str "another",Str ":"]
,OrderedList (1,Decimal,Period)
[[Plain [Str "First"]]
,[Plain [Str "Second",Str ":"]
@@ -243,7 +243,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,RawBlock "html" "</td>\n<td>"
,Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]
,RawBlock "html" "</td>\n</tr>\n</table>\n\n<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>\n"
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block",Str ":"]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "simple",Space,Str "block",Str ":"]
,RawBlock "html" "<div>\n "
,Plain [Str "foo"]
,RawBlock "html" "</div>\n"
@@ -265,7 +265,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,RawBlock "html" "<!-- foo --> \n"
,Para [Str "Code",Str ":"]
,CodeBlock ("",[],[]) "<hr />"
-,Para [Str "Hr",Apostrophe,Str "s",Str ":"]
+,Para [Str "Hr\8217s",Str ":"]
,RawBlock "html" "<hr>\n\n<hr />\n\n<hr />\n\n<hr> \n\n<hr /> \n\n<hr /> \n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\">\n"
,HorizontalRule
,Header 1 [Str "Inline",Space,Str "Markup"]
@@ -286,11 +286,11 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Quoted DoubleQuote [Str "Hello",Str ","],Space,Str "said",Space,Str "the",Space,Str "spider",Str ".",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name",Str "."]]
,Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters",Str "."]
,Para [Quoted SingleQuote [Str "Oak",Str ","],Space,Quoted SingleQuote [Str "elm",Str ","],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees",Str ".",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine",Str "."]]
-,Para [Quoted SingleQuote [Str "He",Space,Str "said",Str ",",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s",Str "?"]
+,Para [Quoted SingleQuote [Str "He",Space,Str "said",Str ",",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70\8217s",Str "?"]
,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code ("",[],[]) "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]
-,Para [Str "Some",Space,Str "dashes",Str ":",Space,Str "one",EmDash,Str "two",Space,EmDash,Space,Str "three",EmDash,Str "four",Space,EmDash,Space,Str "five",Str "."]
-,Para [Str "Dashes",Space,Str "between",Space,Str "numbers",Str ":",Space,Str "5",EnDash,Str "7",Str ",",Space,Str "255",EnDash,Str "66",Str ",",Space,Str "1987",EnDash,Str "1999",Str "."]
-,Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]
+,Para [Str "Some",Space,Str "dashes",Str ":",Space,Str "one",Str "\8212",Str "two",Space,Str "\8212",Space,Str "three",Str "\8212",Str "four",Space,Str "\8212",Space,Str "five",Str "."]
+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers",Str ":",Space,Str "5",Str "\8211",Str "7",Str ",",Space,Str "255",Str "\8211",Str "66",Str ",",Space,Str "1987",Str "\8211",Str "1999",Str "."]
+,Para [Str "Ellipses",Str "\8230",Str "and",Str "\8230",Str "and",Str "\8230",Str "."]
,HorizontalRule
,Header 1 [Str "LaTeX"]
,BulletList
@@ -300,15 +300,15 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,[Plain [Math InlineMath "\\alpha \\wedge \\omega"]]
,[Plain [Math InlineMath "223"]]
,[Plain [Math InlineMath "p",Str "-",Str "Tree"]]
- ,[Plain [Str "Here",Apostrophe,Str "s",Space,Str "some",Space,Str "display",Space,Str "math",Str ":",Space,Math DisplayMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]
- ,[Plain [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it",Str ":",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
-,Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math",Str ":"]
+ ,[Plain [Str "Here\8217s",Space,Str "some",Space,Str "display",Space,Str "math",Str ":",Space,Math DisplayMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]
+ ,[Plain [Str "Here\8217s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it",Str ":",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
+,Para [Str "These",Space,Str "shouldn\8217t",Space,Str "be",Space,Str "math",Str ":"]
,BulletList
[[Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation",Str ",",Space,Str "write",Space,Code ("",[],[]) "$e = mc^2$",Str "."]]
,[Plain [Str "$",Str "22",Str ",",Str "000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money",Str ".",Space,Str "So",Space,Str "is",Space,Str "$",Str "34",Str ",",Str "000",Str ".",Space,Str "(",Str "It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized",Str ".",Str ")"]]
,[Plain [Str "Shoes",Space,Str "(",Str "$",Str "20",Str ")",Space,Str "and",Space,Str "socks",Space,Str "(",Str "$",Str "5",Str ")",Str "."]]
,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table",Str ":"]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table",Str ":"]
,RawBlock "latex" "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
,HorizontalRule
,Header 1 [Str "Special",Space,Str "Characters"]
@@ -366,10 +366,10 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]
,Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]
,Header 2 [Str "With",Space,Str "ampersands"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
,Header 2 [Str "Autolinks"]
,Para [Str "With",Space,Str "an",Space,Str "ampersand",Str ":",Space,Link [Code ("",["url"],[]) "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
,BulletList
@@ -388,7 +388,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon",Str "."]
,HorizontalRule
,Header 1 [Str "Footnotes"]
-,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(",Str "as",Space,Str "with",Space,Str "list",Space,Str "items",Str ")",Str "."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want",Str ",",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line",Str ",",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters",Str ",",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here\8217s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(",Str "as",Space,Str "with",Space,Str "list",Space,Str "items",Str ")",Str "."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want",Str ",",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line",Str ",",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters",Str ",",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
,BlockQuote
[Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes",Str ".",Note [Para [Str "In",Space,Str "quote",Str "."]]]]
,OrderedList (1,Decimal,Period)
diff --git a/tests/testsuite.txt b/tests/testsuite.txt
index ccee0764a..3bb5d8cb5 100644
--- a/tests/testsuite.txt
+++ b/tests/testsuite.txt
@@ -492,9 +492,9 @@ So is 'pine.'
Here is some quoted '`code`' and a "[quoted link][1]".
-Some dashes: one---two --- three--four -- five.
+Some dashes: one---two --- three---four --- five.
-Dashes between numbers: 5-7, 255-66, 1987-1999.
+Dashes between numbers: 5--7, 255--66, 1987--1999.
Ellipses...and...and....
diff --git a/tests/textile-reader.native b/tests/textile-reader.native
index 5dd6301f1..8e149c33d 100644
--- a/tests/textile-reader.native
+++ b/tests/textile-reader.native
@@ -1,5 +1,5 @@
Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
-[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Space,Str "Textile",Space,Str "Reader",Str ".",Space,Str "Part",Space,Str "of",Space,Str "it",Space,Str "comes",LineBreak,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Space,Str "Textile",Space,Str "Reader",Str ".",Space,Str "Part",Space,Str "of",Space,Str "it",Space,Str "comes",LineBreak,Str "from",Space,Str "John",Space,Str "Gruber",Str "\8217",Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
,HorizontalRule
,Header 1 [Str "Headers"]
,Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embeded",Space,Str "link"] ("http://www.example.com","")]
@@ -8,9 +8,9 @@ Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
,Header 5 [Str "Level",Space,Str "5"]
,Header 6 [Str "Level",Space,Str "6"]
,Header 1 [Str "Paragraphs"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
,Para [Str "Line",Space,Str "breaks",Space,Str "are",Space,Str "preserved",Space,Str "in",Space,Str "textile",Str ",",Space,Str "so",Space,Str "you",Space,Str "can",Space,Str "not",Space,Str "wrap",Space,Str "your",Space,Str "very",LineBreak,Str "long",Space,Str "paragraph",Space,Str "with",Space,Str "your",Space,Str "favourite",Space,Str "text",Space,Str "editor",Space,Str "and",Space,Str "have",Space,Str "it",Space,Str "rendered",LineBreak,Str "with",Space,Str "no",Space,Str "break",Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str "."]
+,Para [Str "Here",Str "\8217",Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str "."]
,BulletList
[[Plain [Str "criminey",Str "."]]]
,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "paragraph",Space,Str "break",Space,Str "between",Space,Str "here"]
@@ -70,9 +70,9 @@ Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str ".",LineBreak,Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str ".",LineBreak,Str "A",Space,Link [Strong [Str "strong",Space,Str "link"]] ("http://www.foobar.com",""),Str "."]
,Para [Emph [Strong [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em",Str "."]],LineBreak,Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word",Space,Str "and",Space,Emph [Strong [Str "that",Space,Str "one"]],Str ".",LineBreak,Strikeout [Str "This",Space,Str "is",Space,Str "strikeout",Space,Str "and",Space,Strong [Str "strong"]]]
,Para [Str "Superscripts",Str ":",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Strong [Str "hello"]],Space,Str "a",Superscript [Str "hello",Space,Str "there"],Str ".",LineBreak,Str "Subscripts",Str ":",Space,Str "H",Subscript [Str "2"],Str "O",Str ",",Space,Str "H",Subscript [Str "23"],Str "O",Str ",",Space,Str "H",Subscript [Str "many",Space,Str "of",Space,Str "them"],Str "O",Str "."]
-,Para [Str "Dashes",Space,Str ":",Space,Str "How",Space,Str "cool",Space,EmDash,Space,Str "automatic",Space,Str "dashes",Str "."]
-,Para [Str "Elipses",Space,Str ":",Space,Str "He",Space,Str "thought",Space,Str "and",Space,Str "thought",Space,Ellipses,Space,Str "and",Space,Str "then",Space,Str "thought",Space,Str "some",Space,Str "more",Str "."]
-,Para [Str "Quotes",Space,Str "and",Space,Str "apostrophes",Space,Str ":",Space,Quoted DoubleQuote [Str "I",Apostrophe,Str "d",Space,Str "like",Space,Str "to",Space,Str "thank",Space,Str "you"],Space,Str "for",Space,Str "example",Str "."]
+,Para [Str "Dashes",Space,Str ":",Space,Str "How",Space,Str "cool",Space,Str "\8212",Space,Str "automatic",Space,Str "dashes",Str "."]
+,Para [Str "Elipses",Space,Str ":",Space,Str "He",Space,Str "thought",Space,Str "and",Space,Str "thought",Space,Str "\8230",Space,Str "and",Space,Str "then",Space,Str "thought",Space,Str "some",Space,Str "more",Str "."]
+,Para [Str "Quotes",Space,Str "and",Space,Str "apostrophes",Space,Str ":",Space,Quoted DoubleQuote [Str "I",Str "\8217",Str "d",Space,Str "like",Space,Str "to",Space,Str "thank",Space,Str "you"],Space,Str "for",Space,Str "example",Str "."]
,Header 1 [Str "Links"]
,Header 2 [Str "Explicit"]
,Para [Str "Just",Space,Str "a",Space,Link [Str "url"] ("http://www.url.com","")]
@@ -96,7 +96,7 @@ Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
,[[Plain [Str "bella"]]
,[Plain [Str "45"]]
,[Plain [Str "f"]]]]
-,Para [Str "and",Space,Str "some",Space,Str "text",Space,Str "following",Space,Ellipses]
+,Para [Str "and",Space,Str "some",Space,Str "text",Space,Str "following",Space,Str "\8230"]
,Header 2 [Str "With",Space,Str "headers"]
,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0]
[[Plain [Str "name"]]
@@ -136,7 +136,7 @@ Pandoc (Meta {docTitle = [], docAuthors = [], docDate = []})
,RawBlock "html" "</div>"
,Para [Str "as",Space,Str "well",Str "."]
,BulletList
- [[Plain [Str "this",Space,Str "<",Str "div",Str ">",Space,Str "won",Apostrophe,Str "t",Space,Str "produce",Space,Str "raw",Space,Str "html",Space,Str "blocks",Space,Str "<",Str "/div",Str ">"]]
+ [[Plain [Str "this",Space,Str "<",Str "div",Str ">",Space,Str "won",Str "\8217",Str "t",Space,Str "produce",Space,Str "raw",Space,Str "html",Space,Str "blocks",Space,Str "<",Str "/div",Str ">"]]
,[Plain [Str "but",Space,Str "this",Space,RawInline "html" "<strong>",Space,Str "will",Space,Str "produce",Space,Str "inline",Space,Str "html",Space,RawInline "html" "</strong>"]]]
,Para [Str "Can",Space,Str "you",Space,Str "prove",Space,Str "that",Space,Str "2",Space,Str "<",Space,Str "3",Space,Str "?"]
,Header 1 [Str "Acronyms",Space,Str "and",Space,Str "marks"]
diff --git a/tests/writer.asciidoc b/tests/writer.asciidoc
new file mode 100644
index 000000000..440127379
--- /dev/null
+++ b/tests/writer.asciidoc
@@ -0,0 +1,656 @@
+Pandoc Test Suite
+=================
+:author: John MacFarlane
+:author: Anonymous
+:date: July 17, 2006
+
+This is a set of tests for pandoc. Most of them are adapted from John Gruber’s
+markdown test suite.
+
+'''''
+
+Headers
+-------
+
+Level 2 with an link:/url[embedded link]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Level 3 with _emphasis_
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Level 4
++++++++
+
+Level 5
+
+Level 1
+-------
+
+Level 2 with _emphasis_
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Level 3
+^^^^^^^
+
+with no blank line
+
+Level 2
+~~~~~~~
+
+with no blank line
+
+'''''
+
+Paragraphs
+----------
+
+Here’s a regular paragraph.
+
+In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item.
+Because a hard-wrapped line in the middle of a paragraph looked like a list
+item.
+
+Here’s one with a bullet. * criminey.
+
+There should be a hard line break +
+here.
+
+'''''
+
+Block Quotes
+------------
+
+E-mail style:
+
+__________________________________________
+This is a block quote. It is pretty short.
+__________________________________________
+
+______________________
+--
+Code in a block quote:
+
+--------------------
+sub status {
+ print "working";
+}
+--------------------
+
+A list:
+
+1. item one
+2. item two
+
+Nested block quotes:
+
+______
+nested
+______
+
+______
+nested
+______
+
+--
+______________________
+
+This should not be a block quote: 2 > 1.
+
+And a following paragraph.
+
+'''''
+
+Code Blocks
+-----------
+
+Code:
+
+--------------------------------------
+---- (should be four hyphens)
+
+sub status {
+ print "working";
+}
+
+this code block is indented by one tab
+--------------------------------------
+
+And:
+
+--------------------------------------------
+ this code block is indented by two tabs
+
+These should not be escaped: \$ \\ \> \[ \{
+--------------------------------------------
+
+'''''
+
+Lists
+-----
+
+Unordered
+~~~~~~~~~
+
+Asterisks tight:
+
+* asterisk 1
+* asterisk 2
+* asterisk 3
+
+Asterisks loose:
+
+* asterisk 1
+* asterisk 2
+* asterisk 3
+
+Pluses tight:
+
+* Plus 1
+* Plus 2
+* Plus 3
+
+Pluses loose:
+
+* Plus 1
+* Plus 2
+* Plus 3
+
+Minuses tight:
+
+* Minus 1
+* Minus 2
+* Minus 3
+
+Minuses loose:
+
+* Minus 1
+* Minus 2
+* Minus 3
+
+Ordered
+~~~~~~~
+
+Tight:
+
+1. First
+2. Second
+3. Third
+
+and:
+
+1. One
+2. Two
+3. Three
+
+Loose using tabs:
+
+1. First
+2. Second
+3. Third
+
+and using spaces:
+
+1. One
+2. Two
+3. Three
+
+Multiple paragraphs:
+
+1. Item 1, graf one.
++
+Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.
+2. Item 2.
+3. Item 3.
+
+Nested
+~~~~~~
+
+* Tab
+** Tab
+*** Tab
+
+Here’s another:
+
+1. First
+2. Second:
+* Fee
+* Fie
+* Foe
+3. Third
+
+Same thing but with paragraphs:
+
+1. First
+2. Second:
+* Fee
+* Fie
+* Foe
+3. Third
+
+Tabs and spaces
+~~~~~~~~~~~~~~~
+
+* this is a list item indented with tabs
+* this is a list item indented with spaces
+** this is an example list item indented with tabs
+** this is an example list item indented with spaces
+
+Fancy list markers
+~~~~~~~~~~~~~~~~~~
+
+1. begins with 2
+2. and now 3
++
+with a continuation
+a. sublist with roman numerals, starting with 4
+b. more items
+A. a subsublist
+B. a subsublist
+
+Nesting:
+
+A. Upper Alpha
+A. Upper Roman.
+1. Decimal start with 6
+a. Lower alpha with paren
+
+Autonumbering:
+
+1. Autonumber.
+2. More.
+1. Nested.
+
+Should not be a list item:
+
+M.A. 2007
+
+B. Williams
+
+'''''
+
+Definition Lists
+----------------
+
+Tight using spaces:
+
+apple::
+ red fruit
+orange::
+ orange fruit
+banana::
+ yellow fruit
+
+Tight using tabs:
+
+apple::
+ red fruit
+orange::
+ orange fruit
+banana::
+ yellow fruit
+
+Loose:
+
+apple::
+ red fruit
+orange::
+ orange fruit
+banana::
+ yellow fruit
+
+Multiple blocks with italics:
+
+_apple_::
+ red fruit
+ +
+ contains seeds, crisp, pleasant to taste
+_orange_::
+ orange fruit
+ +
+---------------------
+{ orange code block }
+---------------------
+ +
+ __________________
+ orange block quote
+ __________________
+
+Multiple definitions, tight:
+
+apple::
+ red fruit
+ +
+ computer
+orange::
+ orange fruit
+ +
+ bank
+
+Multiple definitions, loose:
+
+apple::
+ red fruit
+ +
+ computer
+orange::
+ orange fruit
+ +
+ bank
+
+Blank line after term, indented marker, alternate markers:
+
+apple::
+ red fruit
+ +
+ computer
+orange::
+ orange fruit
+ +
+ 1. sublist
+ 2. sublist
+
+HTML Blocks
+-----------
+
+Simple block on one line:
+
+foo
+And nested without indentation:
+
+foo
+bar
+Interpreted markdown in a table:
+
+This is _emphasized_
+And this is *strong*
+Here’s a simple block:
+
+foo
+This should be a code block, though:
+
+-------
+<div>
+ foo
+</div>
+-------
+
+As should this:
+
+--------------
+<div>foo</div>
+--------------
+
+Now, nested:
+
+foo
+This should just be an HTML comment:
+
+Multiline:
+
+Code block:
+
+----------------
+<!-- Comment -->
+----------------
+
+Just plain comment, with trailing spaces on the line:
+
+Code:
+
+------
+<hr />
+------
+
+Hr’s:
+
+'''''
+
+Inline Markup
+-------------
+
+This is _emphasized_, and so _is this_.
+
+This is *strong*, and so *is this*.
+
+An _link:/url[emphasized link]_.
+
+*_This is strong and em._*
+
+So is *_this_* word.
+
+*_This is strong and em._*
+
+So is *_this_* word.
+
+This is code: `>`, `$`, `\`, `\$`, `<html>`.
+
+[line-through]*This is _strikeout_.*
+
+Superscripts: a^bc^d a^_hello_^ a^hello there^.
+
+Subscripts: H~2~O, H~23~O, H~many of them~O.
+
+These should not be superscripts or subscripts, because of the unescaped
+spaces: a^b c^d, a~b c~d.
+
+'''''
+
+Smart quotes, ellipses, dashes
+------------------------------
+
+``Hello,'' said the spider. ```Shelob' is my name.''
+
+`A', `B', and `C' are letters.
+
+`Oak,' `elm,' and `beech' are names of trees. So is `pine.'
+
+`He said, ``I want to go.''' Were you alive in the 70’s?
+
+Here is some quoted ``code`' and a ``http://example.com/?foo=1&bar=2[quoted
+link]''.
+
+Some dashes: one—two — three—four — five.
+
+Dashes between numbers: 5–7, 255–66, 1987–1999.
+
+Ellipses…and…and….
+
+'''''
+
+LaTeX
+-----
+
+*
+* latexmath:[$2+2=4$]
+* latexmath:[$x \in y$]
+* latexmath:[$\alpha \wedge \omega$]
+* latexmath:[$223$]
+* latexmath:[$p$]-Tree
+* Here’s some display math:
+latexmath:[\[\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}\]]
+* Here’s one that has a line break in it:
+latexmath:[$\alpha + \omega \times x^2$].
+
+These shouldn’t be math:
+
+* To get the famous equation, write `$e = mc^2$`.
+* $22,000 is a _lot_ of money. So is $34,000. (It worked if ``lot'' is
+emphasized.)
+* Shoes ($20) and socks ($5).
+* Escaped `$`: $73 _this should be emphasized_ 23$.
+
+Here’s a LaTeX table:
+
+'''''
+
+Special Characters
+------------------
+
+Here is some unicode:
+
+* I hat: Î
+* o umlaut: ö
+* section: §
+* set membership: ∈
+* copyright: ©
+
+AT&T has an ampersand in their name.
+
+AT&T is another way to write it.
+
+This & that.
+
+4 < 5.
+
+6 > 5.
+
+Backslash: \
+
+Backtick: `
+
+Asterisk: *
+
+Underscore: _
+
+Left brace: \{
+
+Right brace: }
+
+Left bracket: [
+
+Right bracket: ]
+
+Left paren: (
+
+Right paren: )
+
+Greater-than: >
+
+Hash: #
+
+Period: .
+
+Bang: !
+
+Plus: +
+
+Minus: -
+
+'''''
+
+Links
+-----
+
+Explicit
+~~~~~~~~
+
+Just a link:/url/[URL].
+
+link:/url/[URL and title].
+
+link:/url/[URL and title].
+
+link:/url/[URL and title].
+
+link:/url/[URL and title]
+
+link:/url/[URL and title]
+
+link:/url/with_underscore[with_underscore]
+
+mailto:nobody@nowhere.net[Email link]
+
+link:[Empty].
+
+Reference
+~~~~~~~~~
+
+Foo link:/url/[bar].
+
+Foo link:/url/[bar].
+
+Foo link:/url/[bar].
+
+With link:/url/[embedded [brackets]].
+
+link:/url/[b] by itself should be a link.
+
+Indented link:/url[once].
+
+Indented link:/url[twice].
+
+Indented link:/url[thrice].
+
+This should [not][] be a link.
+
+-----------
+[not]: /url
+-----------
+
+Foo link:/url/[bar].
+
+Foo link:/url/[biz].
+
+With ampersands
+~~~~~~~~~~~~~~~
+
+Here’s a http://example.com/?foo=1&bar=2[link with an ampersand in the URL].
+
+Here’s a link with an amersand in the link text: http://att.com/[AT&T].
+
+Here’s an link:/script?foo=1&bar=2[inline link].
+
+Here’s an link:/script?foo=1&bar=2[inline link in pointy braces].
+
+Autolinks
+~~~~~~~~~
+
+With an ampersand: http://example.com/?foo=1&bar=2
+
+* In a list?
+* http://example.com/
+* It should.
+
+An e-mail address: nobody@nowhere.net
+
+________________________________
+Blockquoted: http://example.com/
+________________________________
+
+Auto-links should not occur here: `<http://example.com/>`
+
+------------------------------
+or here: <http://example.com/>
+------------------------------
+
+'''''
+
+Images
+------
+
+From ``Voyage dans la Lune'' by Georges Melies (1902):
+
+image:lalune.jpg[lalune,title="Voyage dans la Lune"]
+
+Here is a movie image:movie.jpg[movie] icon.
+
+'''''
+
+Footnotes
+---------
+
+Here is a footnote reference,footnote:[Here is the footnote. It can go
+anywhere after the footnote reference. It need not be placed at the end of the
+document.] and another.[multiblock footnote omitted] This should _not_ be a
+footnote reference, because it contains a space.[^my note] Here is an inline
+note.footnote:[This is _easier_ to type. Inline notes may contain
+http://google.com[links] and `]` verbatim characters, as well as [bracketed
+text].]
+
+___________________________________________
+Notes can go in quotes.footnote:[In quote.]
+___________________________________________
+
+1. And in list items.footnote:[In list.]
+
+This paragraph should not be part of the note, as it is not indented.
diff --git a/tests/writer.context b/tests/writer.context
index 9c3221c31..3aaf8c14b 100644
--- a/tests/writer.context
+++ b/tests/writer.context
@@ -1,54 +1,41 @@
-\enableregime[utf] % use UTF-8
+\startmode[*mkii]
+ \enableregime[utf-8]
+ \setupcolors[state=start]
+\stopmode
-\setupcolors[state=start]
-\setupinteraction[state=start, color=middleblue] % needed for hyperlinks
+% Enable hyperlinks
+\setupinteraction[state=start, color=middleblue]
-\setuppapersize[letter][letter] % use letter paper
-\setuplayout[width=middle, backspace=1.5in, cutspace=1.5in,
- height=middle, header=0.75in, footer=0.75in] % page layout
-\setuppagenumbering[location={footer,center}] % number pages
-\setupbodyfont[11pt] % 11pt font
-\setupwhitespace[medium] % inter-paragraph spacing
+\setuppapersize [letter][letter]
+\setuplayout [width=middle, backspace=1.5in, cutspace=1.5in,
+ height=middle, topspace=0.75in, bottomspace=0.75in]
-\setuphead[section][style=\tfc]
-\setuphead[subsection][style=\tfb]
-\setuphead[subsubsection][style=\bf]
+\setuppagenumbering[location={footer,center}]
-% define descr (for definition lists)
-\definedescription[descr][
- headstyle=bold,style=normal,align=left,location=hanging,
- width=broad,margin=1cm]
+\setupbodyfont[11pt]
-% prevent orphaned list intros
-\setupitemize[autointro]
+\setupwhitespace[medium]
-% define defaults for bulleted lists
-\setupitemize[1][symbol=1][indentnext=no]
-\setupitemize[2][symbol=2][indentnext=no]
-\setupitemize[3][symbol=3][indentnext=no]
-\setupitemize[4][symbol=4][indentnext=no]
+\setuphead[section] [style=\tfc,number=no]
+\setuphead[subsection] [style=\tfb,number=no]
+\setuphead[subsubsection][style=\bf,number=no]
-\setupthinrules[width=15em] % width of horizontal rules
+\definedescription
+ [description]
+ [headstyle=bold, style=normal, location=hanging, width=broad, margin=1cm]
-% for block quotations
-\unprotect
+\setupitemize[autointro] % prevent orphan list intro
+\setupitemize[indentnext=no]
-\startvariables all
-blockquote: blockquote
-\stopvariables
-
-\definedelimitedtext
-[\v!blockquote][\v!quotation]
+\setupthinrules[width=15em] % width of horizontal rules
\setupdelimitedtext
-[\v!blockquote]
-[\c!left=,
-\c!right=,
-before={\blank[medium]},
-after={\blank[medium]},
-]
+ [blockquote]
+ [before={\blank[medium]},
+ after={\blank[medium]},
+ indentnext=no,
+ ]
-\protect
\starttext
\startalignment[center]
@@ -66,31 +53,32 @@ markdown test suite.
\thinrule
-\subject{Headers}
+\section[headers]{Headers}
-\subsubject{Level 2 with an \useURL[1][/url][][embedded link]\from[1]}
+\subsection[level-2-with-an-embedded-link]{Level 2 with an
+\useURL[url1][/url][][embedded link]\from[url1]}
-\subsubsubject{Level 3 with {\em emphasis}}
+\subsubsection[level-3-with-emphasis]{Level 3 with {\em emphasis}}
-\subsubsubsubject{Level 4}
+\subsubsubsection[level-4]{Level 4}
-\subsubsubsubsubject{Level 5}
+\subsubsubsubsection[level-5]{Level 5}
-\subject{Level 1}
+\section[level-1]{Level 1}
-\subsubject{Level 2 with {\em emphasis}}
+\subsection[level-2-with-emphasis]{Level 2 with {\em emphasis}}
-\subsubsubject{Level 3}
+\subsubsection[level-3]{Level 3}
with no blank line
-\subsubject{Level 2}
+\subsection[level-2]{Level 2}
with no blank line
\thinrule
-\subject{Paragraphs}
+\section[paragraphs]{Paragraphs}
Here's a regular paragraph.
@@ -105,7 +93,7 @@ here.
\thinrule
-\subject{Block Quotes}
+\section[block-quotes]{Block Quotes}
E-mail style:
@@ -148,7 +136,7 @@ And a following paragraph.
\thinrule
-\subject{Code Blocks}
+\section[code-blocks]{Code Blocks}
Code:
@@ -172,9 +160,9 @@ These should not be escaped: \$ \\ \> \[ \{
\thinrule
-\subject{Lists}
+\section[lists]{Lists}
-\subsubject{Unordered}
+\subsection[unordered]{Unordered}
Asterisks tight:
@@ -242,7 +230,7 @@ Minuses loose:
Minus 3
\stopitemize
-\subsubject{Ordered}
+\subsection[ordered]{Ordered}
Tight:
@@ -301,7 +289,7 @@ Multiple paragraphs:
Item 3.
\stopitemize
-\subsubject{Nested}
+\subsection[nested]{Nested}
\startitemize
\item
@@ -355,7 +343,7 @@ Same thing but with paragraphs:
Third
\stopitemize
-\subsubject{Tabs and spaces}
+\subsection[tabs-and-spaces]{Tabs and spaces}
\startitemize
\item
@@ -371,7 +359,7 @@ Same thing but with paragraphs:
\stopitemize
\stopitemize
-\subsubject{Fancy list markers}
+\subsection[fancy-list-markers]{Fancy list markers}
\startitemize[n][start=2,left=(,stopper=),width=2.0em]
\item
@@ -435,59 +423,59 @@ B. Williams
\thinrule
-\subject{Definition Lists}
+\section[definition-lists]{Definition Lists}
Tight using spaces:
-\startdescr{apple}
+\startdescription{apple}
red fruit
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
-\stopdescr
+\stopdescription
-\startdescr{banana}
+\startdescription{banana}
yellow fruit
-\stopdescr
+\stopdescription
Tight using tabs:
-\startdescr{apple}
+\startdescription{apple}
red fruit
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
-\stopdescr
+\stopdescription
-\startdescr{banana}
+\startdescription{banana}
yellow fruit
-\stopdescr
+\stopdescription
Loose:
-\startdescr{apple}
+\startdescription{apple}
red fruit
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
-\stopdescr
+\stopdescription
-\startdescr{banana}
+\startdescription{banana}
yellow fruit
-\stopdescr
+\stopdescription
Multiple blocks with italics:
-\startdescr{{\em apple}}
+\startdescription{{\em apple}}
red fruit
contains seeds, crisp, pleasant to taste
-\stopdescr
+\stopdescription
-\startdescr{{\em orange}}
+\startdescription{{\em orange}}
orange fruit
\starttyping
@@ -497,45 +485,45 @@ Multiple blocks with italics:
\startblockquote
orange block quote
\stopblockquote
-\stopdescr
+\stopdescription
Multiple definitions, tight:
-\startdescr{apple}
+\startdescription{apple}
red fruit
computer
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
bank
-\stopdescr
+\stopdescription
Multiple definitions, loose:
-\startdescr{apple}
+\startdescription{apple}
red fruit
computer
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
bank
-\stopdescr
+\stopdescription
Blank line after term, indented marker, alternate markers:
-\startdescr{apple}
+\startdescription{apple}
red fruit
computer
-\stopdescr
+\stopdescription
-\startdescr{orange}
+\startdescription{orange}
orange fruit
\startitemize[n][stopper=.]
@@ -544,9 +532,9 @@ Blank line after term, indented marker, alternate markers:
\item
sublist
\stopitemize
-\stopdescr
+\stopdescription
-\subject{HTML Blocks}
+\section[html-blocks]{HTML Blocks}
Simple block on one line:
@@ -601,13 +589,13 @@ Hr's:
\thinrule
-\subject{Inline Markup}
+\section[inline-markup]{Inline Markup}
This is {\em emphasized}, and so {\em is this}.
This is {\bf strong}, and so {\bf is this}.
-An {\em \useURL[2][/url][][emphasized link]\from[2]}.
+An {\em \useURL[url2][/url][][emphasized link]\from[url2]}.
{\bf {\em This is strong and em.}}
@@ -630,7 +618,7 @@ spaces: a\letterhat{}b c\letterhat{}d, a\lettertilde{}b c\lettertilde{}d.
\thinrule
-\subject{Smart quotes, ellipses, dashes}
+\section[smart-quotes-ellipses-dashes]{Smart quotes, ellipses, dashes}
\quotation{Hello,} said the spider. \quotation{\quote{Shelob} is my name.}
@@ -642,8 +630,8 @@ spaces: a\letterhat{}b c\letterhat{}d, a\lettertilde{}b c\lettertilde{}d.
\quote{He said, \quotation{I want to go.}} Were you alive in the 70's?
Here is some quoted \quote{\type{code}} and a
-\quotation{\useURL[3][http://example.com/?foo=1&bar=2][][quoted
-link]\from[3]}.
+\quotation{\useURL[url3][http://example.com/?foo=1&bar=2][][quoted
+link]\from[url3]}.
Some dashes: one---two --- three---four --- five.
@@ -653,7 +641,7 @@ Ellipses\ldots{}and\ldots{}and\ldots{}.
\thinrule
-\subject{LaTeX}
+\section[latex]{LaTeX}
\startitemize
\item
@@ -693,7 +681,7 @@ Here's a LaTeX table:
\thinrule
-\subject{Special Characters}
+\section[special-characters]{Special Characters}
Here is some unicode:
@@ -754,45 +742,45 @@ Minus: -
\thinrule
-\subject{Links}
+\section[links]{Links}
-\subsubject{Explicit}
+\subsection[explicit]{Explicit}
-Just a \useURL[4][/url/][][URL]\from[4].
+Just a \useURL[url4][/url/][][URL]\from[url4].
-\useURL[5][/url/][][URL and title]\from[5].
+\useURL[url5][/url/][][URL and title]\from[url5].
-\useURL[6][/url/][][URL and title]\from[6].
+\useURL[url6][/url/][][URL and title]\from[url6].
-\useURL[7][/url/][][URL and title]\from[7].
+\useURL[url7][/url/][][URL and title]\from[url7].
-\useURL[8][/url/][][URL and title]\from[8]
+\useURL[url8][/url/][][URL and title]\from[url8]
-\useURL[9][/url/][][URL and title]\from[9]
+\useURL[url9][/url/][][URL and title]\from[url9]
-\useURL[10][/url/with_underscore][][with\letterunderscore{}underscore]\from[10]
+\useURL[url10][/url/with_underscore][][with\letterunderscore{}underscore]\from[url10]
-\useURL[11][mailto:nobody@nowhere.net][][Email link]\from[11]
+\useURL[url11][mailto:nobody@nowhere.net][][Email link]\from[url11]
-\useURL[12][][][Empty]\from[12].
+\useURL[url12][][][Empty]\from[url12].
-\subsubject{Reference}
+\subsection[reference]{Reference}
-Foo \useURL[13][/url/][][bar]\from[13].
+Foo \useURL[url13][/url/][][bar]\from[url13].
-Foo \useURL[14][/url/][][bar]\from[14].
+Foo \useURL[url14][/url/][][bar]\from[url14].
-Foo \useURL[15][/url/][][bar]\from[15].
+Foo \useURL[url15][/url/][][bar]\from[url15].
-With \useURL[16][/url/][][embedded {[}brackets{]}]\from[16].
+With \useURL[url16][/url/][][embedded {[}brackets{]}]\from[url16].
-\useURL[17][/url/][][b]\from[17] by itself should be a link.
+\useURL[url17][/url/][][b]\from[url17] by itself should be a link.
-Indented \useURL[18][/url][][once]\from[18].
+Indented \useURL[url18][/url][][once]\from[url18].
-Indented \useURL[19][/url][][twice]\from[19].
+Indented \useURL[url19][/url][][twice]\from[url19].
-Indented \useURL[20][/url][][thrice]\from[20].
+Indented \useURL[url20][/url][][thrice]\from[url20].
This should {[}not{]}{[}{]} be a link.
@@ -800,42 +788,43 @@ This should {[}not{]}{[}{]} be a link.
[not]: /url
\stoptyping
-Foo \useURL[21][/url/][][bar]\from[21].
+Foo \useURL[url21][/url/][][bar]\from[url21].
-Foo \useURL[22][/url/][][biz]\from[22].
+Foo \useURL[url22][/url/][][biz]\from[url22].
-\subsubject{With ampersands}
+\subsection[with-ampersands]{With ampersands}
-Here's a \useURL[23][http://example.com/?foo=1&bar=2][][link with an ampersand
-in the URL]\from[23].
+Here's a \useURL[url23][http://example.com/?foo=1&bar=2][][link with an
+ampersand in the URL]\from[url23].
Here's a link with an amersand in the link text:
-\useURL[24][http://att.com/][][AT\&T]\from[24].
+\useURL[url24][http://att.com/][][AT\&T]\from[url24].
-Here's an \useURL[25][/script?foo=1&bar=2][][inline link]\from[25].
+Here's an \useURL[url25][/script?foo=1&bar=2][][inline link]\from[url25].
-Here's an \useURL[26][/script?foo=1&bar=2][][inline link in pointy
-braces]\from[26].
+Here's an \useURL[url26][/script?foo=1&bar=2][][inline link in pointy
+braces]\from[url26].
-\subsubject{Autolinks}
+\subsection[autolinks]{Autolinks}
With an ampersand:
-\useURL[27][http://example.com/?foo=1&bar=2][][http://example.com/?foo=1\&bar=2]\from[27]
+\useURL[url27][http://example.com/?foo=1&bar=2][][\hyphenatedurl{http://example.com/?foo=1\&bar=2}]\from[url27]
\startitemize
\item
In a list?
\item
- \useURL[28][http://example.com/][][http://example.com/]\from[28]
+ \useURL[url28][http://example.com/][][\hyphenatedurl{http://example.com/}]\from[url28]
\item
It should.
\stopitemize
An e-mail address:
-\useURL[29][mailto:nobody@nowhere.net][][nobody@nowhere.net]\from[29]
+\useURL[url29][mailto:nobody@nowhere.net][][\hyphenatedurl{nobody@nowhere.net}]\from[url29]
\startblockquote
-Blockquoted: \useURL[30][http://example.com/][][http://example.com/]\from[30]
+Blockquoted:
+\useURL[url30][http://example.com/][][\hyphenatedurl{http://example.com/}]\from[url30]
\stopblockquote
Auto-links should not occur here: \type{<http://example.com/>}
@@ -846,7 +835,7 @@ or here: <http://example.com/>
\thinrule
-\subject{Images}
+\section[images]{Images}
From \quotation{Voyage dans la Lune} by Georges Melies (1902):
@@ -856,12 +845,12 @@ Here is a movie {\externalfigure[movie.jpg]} icon.
\thinrule
-\subject{Footnotes}
+\section[footnotes]{Footnotes}
Here is a footnote reference,\footnote{Here is the footnote. It can go
anywhere after the footnote reference. It need not be placed at the end of
- the document.} and another.\footnote{Here's the long note. This one contains
- multiple blocks.
+ the document.} and another.\startbuffer Here's the long note. This one
+ contains multiple blocks.
Subsequent blocks are indented to show that they belong to the footnote (as
with list items).
@@ -871,10 +860,11 @@ Here is a footnote reference,\footnote{Here is the footnote. It can go
\stoptyping
If you want, you can indent every line, but you can also be lazy and just
- indent the first line of each block.} This should {\em not} be a footnote
-reference, because it contains a space.{[}\letterhat{}my note{]} Here is an
-inline note.\footnote{This is {\em easier} to type. Inline notes may contain
- \useURL[31][http://google.com][][links]\from[31] and \type{]} verbatim
+ indent the first line of each block.\stopbuffer\footnote{\getbuffer} This
+should {\em not} be a footnote reference, because it contains a
+space.{[}\letterhat{}my note{]} Here is an inline note.\footnote{This is
+ {\em easier} to type. Inline notes may contain
+ \useURL[url31][http://google.com][][links]\from[url31] and \type{]} verbatim
characters, as well as {[}bracketed text{]}.}
\startblockquote
diff --git a/tests/writer.docbook b/tests/writer.docbook
index 780775d0f..0eeaebbfd 100644
--- a/tests/writer.docbook
+++ b/tests/writer.docbook
@@ -16,47 +16,47 @@
</articleinfo>
<para>
This is a set of tests for pandoc. Most of them are adapted from John
- Gruber's markdown test suite.
+ Gruber’s markdown test suite.
</para>
-<section id="headers">
+<sect1 id="headers">
<title>Headers</title>
- <section id="level-2-with-an-embedded-link">
+ <sect2 id="level-2-with-an-embedded-link">
<title>Level 2 with an <ulink url="/url">embedded link</ulink></title>
- <section id="level-3-with-emphasis">
+ <sect3 id="level-3-with-emphasis">
<title>Level 3 with <emphasis>emphasis</emphasis></title>
- <section id="level-4">
+ <sect4 id="level-4">
<title>Level 4</title>
- <section id="level-5">
+ <sect5 id="level-5">
<title>Level 5</title>
<para>
</para>
- </section>
- </section>
- </section>
- </section>
-</section>
-<section id="level-1">
+ </sect5>
+ </sect4>
+ </sect3>
+ </sect2>
+</sect1>
+<sect1 id="level-1">
<title>Level 1</title>
- <section id="level-2-with-emphasis">
+ <sect2 id="level-2-with-emphasis">
<title>Level 2 with <emphasis>emphasis</emphasis></title>
- <section id="level-3">
+ <sect3 id="level-3">
<title>Level 3</title>
<para>
with no blank line
</para>
- </section>
- </section>
- <section id="level-2">
+ </sect3>
+ </sect2>
+ <sect2 id="level-2">
<title>Level 2</title>
<para>
with no blank line
</para>
- </section>
-</section>
-<section id="paragraphs">
+ </sect2>
+</sect1>
+<sect1 id="paragraphs">
<title>Paragraphs</title>
<para>
- Here's a regular paragraph.
+ Here’s a regular paragraph.
</para>
<para>
In Markdown 1.0.0 and earlier. Version 8. This line turns into a list
@@ -64,13 +64,13 @@
a list item.
</para>
<para>
- Here's one with a bullet. * criminey.
+ Here’s one with a bullet. * criminey.
</para>
<para>
There should be a hard line break<literallayout></literallayout>here.
</para>
-</section>
-<section id="block-quotes">
+</sect1>
+<sect1 id="block-quotes">
<title>Block Quotes</title>
<para>
E-mail style:
@@ -124,8 +124,8 @@ sub status {
<para>
And a following paragraph.
</para>
-</section>
-<section id="code-blocks">
+</sect1>
+<sect1 id="code-blocks">
<title>Code Blocks</title>
<para>
Code:
@@ -147,10 +147,10 @@ this code block is indented by one tab
These should not be escaped: \$ \\ \&gt; \[ \{
</programlisting>
-</section>
-<section id="lists">
+</sect1>
+<sect1 id="lists">
<title>Lists</title>
- <section id="unordered">
+ <sect2 id="unordered">
<title>Unordered</title>
<para>
Asterisks tight:
@@ -272,8 +272,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</para>
</listitem>
</itemizedlist>
- </section>
- <section id="ordered">
+ </sect2>
+ <sect2 id="ordered">
<title>Ordered</title>
<para>
Tight:
@@ -364,7 +364,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
Item 1, graf one.
</para>
<para>
- Item 1. graf two. The quick brown fox jumped over the lazy dog's
+ Item 1. graf two. The quick brown fox jumped over the lazy dog’s
back.
</para>
</listitem>
@@ -379,8 +379,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</para>
</listitem>
</orderedlist>
- </section>
- <section id="nested">
+ </sect2>
+ <sect2 id="nested">
<title>Nested</title>
<itemizedlist>
<listitem>
@@ -404,7 +404,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</listitem>
</itemizedlist>
<para>
- Here's another:
+ Here’s another:
</para>
<orderedlist numeration="arabic">
<listitem>
@@ -477,8 +477,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</para>
</listitem>
</orderedlist>
- </section>
- <section id="tabs-and-spaces">
+ </sect2>
+ <sect2 id="tabs-and-spaces">
<title>Tabs and spaces</title>
<itemizedlist>
<listitem>
@@ -504,8 +504,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</itemizedlist>
</listitem>
</itemizedlist>
- </section>
- <section id="fancy-list-markers">
+ </sect2>
+ <sect2 id="fancy-list-markers">
<title>Fancy list markers</title>
<orderedlist numeration="arabic">
<listitem override="2">
@@ -608,9 +608,9 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<para>
B. Williams
</para>
- </section>
-</section>
-<section id="definition-lists">
+ </sect2>
+</sect1>
+<sect1 id="definition-lists">
<title>Definition Lists</title>
<para>
Tight using spaces:
@@ -855,8 +855,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</listitem>
</varlistentry>
</variablelist>
-</section>
-<section id="html-blocks">
+</sect1>
+<sect1 id="html-blocks">
<title>HTML Blocks</title>
<para>
Simple block on one line:
@@ -893,7 +893,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>
<para>
- Here's a simple block:
+ Here’s a simple block:
</para>
<div>
@@ -956,7 +956,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
&lt;hr /&gt;
</programlisting>
<para>
- Hr's:
+ Hr’s:
</para>
<hr>
@@ -975,8 +975,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<hr class="foo" id="bar" />
<hr class="foo" id="bar">
-</section>
-<section id="inline-markup">
+</sect1>
+<sect1 id="inline-markup">
<title>Inline Markup</title>
<para>
This is <emphasis>emphasized</emphasis>, and so <emphasis>is
@@ -1025,8 +1025,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
These should not be superscripts or subscripts, because of the unescaped
spaces: a^b c^d, a~b c~d.
</para>
-</section>
-<section id="smart-quotes-ellipses-dashes">
+</sect1>
+<sect1 id="smart-quotes-ellipses-dashes">
<title>Smart quotes, ellipses, dashes</title>
<para>
<quote>Hello,</quote> said the spider. <quote><quote>Shelob</quote> is my
@@ -1041,7 +1041,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</para>
<para>
<quote>He said, <quote>I want to go.</quote></quote> Were you alive in the
- 70's?
+ 70’s?
</para>
<para>
Here is some quoted <quote><literal>code</literal></quote> and a
@@ -1057,8 +1057,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<para>
Ellipses…and…and….
</para>
-</section>
-<section id="latex">
+</sect1>
+<sect1 id="latex">
<title>LaTeX</title>
<itemizedlist>
<listitem>
@@ -1077,7 +1077,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</listitem>
<listitem>
<para>
- α ∧ ω
+ <emphasis>α</emphasis> ∧ <emphasis>ω</emphasis>
</para>
</listitem>
<listitem>
@@ -1092,19 +1092,19 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</listitem>
<listitem>
<para>
- Here's some display math:
+ Here’s some display math:
$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$
</para>
</listitem>
<listitem>
<para>
- Here's one that has a line break in it:
- α + ω × <emphasis>x</emphasis><superscript>2</superscript>.
+ Here’s one that has a line break in it:
+ <emphasis>α</emphasis> + <emphasis>ω</emphasis> × <emphasis>x</emphasis><superscript>2</superscript>.
</para>
</listitem>
</itemizedlist>
<para>
- These shouldn't be math:
+ These shouldn’t be math:
</para>
<itemizedlist>
<listitem>
@@ -1131,10 +1131,10 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</listitem>
</itemizedlist>
<para>
- Here's a LaTeX table:
+ Here’s a LaTeX table:
</para>
-</section>
-<section id="special-characters">
+</sect1>
+<sect1 id="special-characters">
<title>Special Characters</title>
<para>
Here is some unicode:
@@ -1229,10 +1229,10 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<para>
Minus: -
</para>
-</section>
-<section id="links">
+</sect1>
+<sect1 id="links">
<title>Links</title>
- <section id="explicit">
+ <sect2 id="explicit">
<title>Explicit</title>
<para>
Just a <ulink url="/url/">URL</ulink>.
@@ -1261,8 +1261,8 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<para>
<ulink url="">Empty</ulink>.
</para>
- </section>
- <section id="reference">
+ </sect2>
+ <sect2 id="reference">
<title>Reference</title>
<para>
Foo <ulink url="/url/">bar</ulink>.
@@ -1300,26 +1300,26 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<para>
Foo <ulink url="/url/">biz</ulink>.
</para>
- </section>
- <section id="with-ampersands">
+ </sect2>
+ <sect2 id="with-ampersands">
<title>With ampersands</title>
<para>
- Here's a <ulink url="http://example.com/?foo=1&amp;bar=2">link with an
+ Here’s a <ulink url="http://example.com/?foo=1&amp;bar=2">link with an
ampersand in the URL</ulink>.
</para>
<para>
- Here's a link with an amersand in the link text:
+ Here’s a link with an amersand in the link text:
<ulink url="http://att.com/">AT&amp;T</ulink>.
</para>
<para>
- Here's an <ulink url="/script?foo=1&amp;bar=2">inline link</ulink>.
+ Here’s an <ulink url="/script?foo=1&amp;bar=2">inline link</ulink>.
</para>
<para>
- Here's an <ulink url="/script?foo=1&amp;bar=2">inline link in pointy
+ Here’s an <ulink url="/script?foo=1&amp;bar=2">inline link in pointy
braces</ulink>.
</para>
- </section>
- <section id="autolinks">
+ </sect2>
+ <sect2 id="autolinks">
<title>Autolinks</title>
<para>
With an ampersand:
@@ -1358,9 +1358,9 @@ These should not be escaped: \$ \\ \&gt; \[ \{
<programlisting>
or here: &lt;http://example.com/&gt;
</programlisting>
- </section>
-</section>
-<section id="images">
+ </sect2>
+</sect1>
+<sect1 id="images">
<title>Images</title>
<para>
From <quote>Voyage dans la Lune</quote> by Georges Melies (1902):
@@ -1381,8 +1381,8 @@ or here: &lt;http://example.com/&gt;
</imageobject>
</inlinemediaobject> icon.
</para>
-</section>
-<section id="footnotes">
+</sect1>
+<sect1 id="footnotes">
<title>Footnotes</title>
<para>
Here is a footnote reference,<footnote>
@@ -1392,7 +1392,7 @@ or here: &lt;http://example.com/&gt;
</para>
</footnote> and another.<footnote>
<para>
- Here's the long note. This one contains multiple blocks.
+ Here’s the long note. This one contains multiple blocks.
</para>
<para>
Subsequent blocks are indented to show that they belong to the
@@ -1437,5 +1437,5 @@ or here: &lt;http://example.com/&gt;
<para>
This paragraph should not be part of the note, as it is not indented.
</para>
-</section>
+</sect1>
</article>
diff --git a/tests/writer.html b/tests/writer.html
index 279c33019..c9ef6f1f1 100644
--- a/tests/writer.html
+++ b/tests/writer.html
@@ -2,18 +2,19 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="author" content="John MacFarlane" />
<meta name="author" content="Anonymous" />
- <meta name="date" content="July 17, 2006" />
+ <meta name="date" content="2006-07-17" />
<title>Pandoc Test Suite</title>
</head>
<body>
<div id="header">
<h1 class="title">Pandoc Test Suite</h1>
-<h3 class="author">John MacFarlane</h3>
-<h3 class="author">Anonymous</h3>
-<h4 class="date">July 17, 2006</h4>
+<h2 class="author">John MacFarlane</h2>
+<h2 class="author">Anonymous</h2>
+<h3 class="date">July 17, 2006</h3>
</div>
<p>This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.</p>
<hr />
@@ -44,8 +45,7 @@
<p>Code in a block quote:</p>
<pre><code>sub status {
print &quot;working&quot;;
-}
-</code></pre>
+}</code></pre>
<p>A list:</p>
<ol style="list-style-type: decimal">
<li>item one</li>
@@ -70,13 +70,11 @@ sub status {
print &quot;working&quot;;
}
-this code block is indented by one tab
-</code></pre>
+this code block is indented by one tab</code></pre>
<p>And:</p>
<pre><code> this code block is indented by two tabs
-These should not be escaped: \$ \\ \&gt; \[ \{
-</code></pre>
+These should not be escaped: \$ \\ \&gt; \[ \{</code></pre>
<hr />
<h1 id="lists">Lists</h1>
<h2 id="unordered">Unordered</h2>
@@ -273,8 +271,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
</dd>
<dt><em>orange</em></dt>
<dd><p>orange fruit</p>
-<pre><code>{ orange code block }
-</code></pre>
+<pre><code>{ orange code block }</code></pre>
<blockquote>
<p>orange block quote</p>
</blockquote>
@@ -357,11 +354,9 @@ foo
<p>This should be a code block, though:</p>
<pre><code>&lt;div&gt;
foo
-&lt;/div&gt;
-</code></pre>
+&lt;/div&gt;</code></pre>
<p>As should this:</p>
-<pre><code>&lt;div&gt;foo&lt;/div&gt;
-</code></pre>
+<pre><code>&lt;div&gt;foo&lt;/div&gt;</code></pre>
<p>Now, nested:</p>
<div>
<div>
@@ -386,14 +381,12 @@ Blah
-->
<p>Code block:</p>
-<pre><code>&lt;!-- Comment --&gt;
-</code></pre>
+<pre><code>&lt;!-- Comment --&gt;</code></pre>
<p>Just plain comment, with trailing spaces on the line:</p>
<!-- foo -->
<p>Code:</p>
-<pre><code>&lt;hr /&gt;
-</code></pre>
+<pre><code>&lt;hr /&gt;</code></pre>
<p>Hr’s:</p>
<hr>
@@ -423,7 +416,7 @@ Blah
<p><strong><em>This is strong and em.</em></strong></p>
<p>So is <strong><em>this</em></strong> word.</p>
<p>This is code: <code>&gt;</code>, <code>$</code>, <code>\</code>, <code>\$</code>, <code>&lt;html&gt;</code>.</p>
-<p><span style="text-decoration: line-through;">This is <em>strikeout</em>.</span></p>
+<p><del>This is <em>strikeout</em>.</del></p>
<p>Superscripts: a<sup>bc</sup>d a<sup><em>hello</em></sup> a<sup>hello there</sup>.</p>
<p>Subscripts: H<sub>2</sub>O, H<sub>23</sub>O, H<sub>many of them</sub>O.</p>
<p>These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</p>
@@ -443,11 +436,11 @@ Blah
<li></li>
<li><span class="math">2 + 2 = 4</span></li>
<li><span class="math"><em>x</em> ∈ <em>y</em></span></li>
-<li><span class="math">α ∧ ω</span></li>
+<li><span class="math"><em>α</em> ∧ <em>ω</em></span></li>
<li><span class="math">223</span></li>
<li><span class="math"><em>p</em></span>-Tree</li>
<li>Here’s some display math: <br /><span class="math">$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</span><br /></li>
-<li>Here’s one that has a line break in it: <span class="math">α + ω × <em>x</em><sup>2</sup></span>.</li>
+<li>Here’s one that has a line break in it: <span class="math"><em>α</em> + <em>ω</em> × <em>x</em><sup>2</sup></span>.</li>
</ul>
<p>These shouldn’t be math:</p>
<ul>
@@ -516,8 +509,7 @@ document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'Email link'+'<\/'+'a'+'>')
<p>Indented <a href="/url">twice</a>.</p>
<p>Indented <a href="/url">thrice</a>.</p>
<p>This should [not][] be a link.</p>
-<pre><code>[not]: /url
-</code></pre>
+<pre><code>[not]: /url</code></pre>
<p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
<p>Foo <a href="/url/" title="Title with &quot;quote&quot; inside">biz</a>.</p>
<h2 id="with-ampersands">With ampersands</h2>
@@ -542,8 +534,7 @@ document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'<code>'+e+'</code>'+'<\/'+
<p>Blockquoted: <a href="http://example.com/"><code class="url">http://example.com/</code></a></p>
</blockquote>
<p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
-<pre><code>or here: &lt;http://example.com/&gt;
-</code></pre>
+<pre><code>or here: &lt;http://example.com/&gt;</code></pre>
<hr />
<h1 id="images">Images</h1>
<p>From “Voyage dans la Lune” by Georges Melies (1902):</p>
@@ -564,15 +555,14 @@ document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+'<code>'+e+'</code>'+'<\/'+
<div class="footnotes">
<hr />
<ol>
-<li id="fn1"><p>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document. <a href="#fnref1" class="footnoteBackLink">↩</a></p></li>
+<li id="fn1"><p>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>Here’s the long note. This one contains multiple blocks.</p>
<p>Subsequent blocks are indented to show that they belong to the footnote (as with list items).</p>
-<pre><code> { &lt;code&gt; }
-</code></pre>
-<p>If you want, you can indent every line, but you can also be lazy and just indent the first line of each block. <a href="#fnref2" class="footnoteBackLink">↩</a></p></li>
-<li id="fn3"><p>This is <em>easier</em> to type. Inline notes may contain <a href="http://google.com">links</a> and <code>]</code> verbatim characters, as well as [bracketed text]. <a href="#fnref3" class="footnoteBackLink">↩</a></p></li>
-<li id="fn4"><p>In quote. <a href="#fnref4" class="footnoteBackLink">↩</a></p></li>
-<li id="fn5"><p>In list. <a href="#fnref5" class="footnoteBackLink">↩</a></p></li>
+<pre><code> { &lt;code&gt; }</code></pre>
+<p>If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.<a href="#fnref2">↩</a></p></li>
+<li id="fn3"><p>This is <em>easier</em> to type. Inline notes may contain <a href="http://google.com">links</a> and <code>]</code> verbatim characters, as well as [bracketed text].<a href="#fnref3">↩</a></p></li>
+<li id="fn4"><p>In quote.<a href="#fnref4">↩</a></p></li>
+<li id="fn5"><p>In list.<a href="#fnref5">↩</a></p></li>
</ol>
</div>
</body>
diff --git a/tests/writer.latex b/tests/writer.latex
index 5c2594ec7..4ce579516 100644
--- a/tests/writer.latex
+++ b/tests/writer.latex
@@ -1,4 +1,4 @@
-\documentclass{article}
+\documentclass[]{article}
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\ifxetex
@@ -34,9 +34,13 @@
\ifxetex
\usepackage[setpagesize=false, % page size defined by xetex
unicode=false, % unicode breaks when used with xetex
- xetex]{hyperref}
+ xetex,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\else
- \usepackage[unicode=true]{hyperref}
+ \usepackage[unicode=true,
+ colorlinks=true,
+ linkcolor=blue]{hyperref}
\fi
\hypersetup{breaklinks=true, pdfborder={0 0 0}}
\usepackage[normalem]{ulem}
diff --git a/tests/writer.man b/tests/writer.man
index bdbb91604..28bc0feb5 100644
--- a/tests/writer.man
+++ b/tests/writer.man
@@ -564,7 +564,7 @@ Ellipses\&...and\&...and\&....
.IP \[bu] 2
\f[I]x\f[] ∈ \f[I]y\f[]
.IP \[bu] 2
-α ∧ ω
+\f[I]α\f[] ∧ \f[I]ω\f[]
.IP \[bu] 2
223
.IP \[bu] 2
@@ -575,7 +575,8 @@ Here's some display math:
$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$
.RE
.IP \[bu] 2
-Here's one that has a line break in it: α + ω × \f[I]x\f[]^2^.
+Here's one that has a line break in it:
+\f[I]α\f[] + \f[I]ω\f[] × \f[I]x\f[]^2^.
.PP
These shouldn't be math:
.IP \[bu] 2
diff --git a/tests/writer.markdown b/tests/writer.markdown
index cc56b8b3a..364954e00 100644
--- a/tests/writer.markdown
+++ b/tests/writer.markdown
@@ -7,9 +7,11 @@ markdown test suite.
* * * * *
-# Headers
+Headers
+=======
-## Level 2 with an [embedded link](/url)
+Level 2 with an [embedded link](/url)
+-------------------------------------
### Level 3 with *emphasis*
@@ -17,21 +19,25 @@ markdown test suite.
##### Level 5
-# Level 1
+Level 1
+=======
-## Level 2 with *emphasis*
+Level 2 with *emphasis*
+-----------------------
### Level 3
with no blank line
-## Level 2
+Level 2
+-------
with no blank line
* * * * *
-# Paragraphs
+Paragraphs
+==========
Here’s a regular paragraph.
@@ -46,7 +52,8 @@ here.
* * * * *
-# Block Quotes
+Block Quotes
+============
E-mail style:
@@ -75,7 +82,8 @@ And a following paragraph.
* * * * *
-# Code Blocks
+Code Blocks
+===========
Code:
@@ -95,9 +103,11 @@ And:
* * * * *
-# Lists
+Lists
+=====
-## Unordered
+Unordered
+---------
Asterisks tight:
@@ -141,7 +151,8 @@ Minuses loose:
- Minus 3
-## Ordered
+Ordered
+-------
Tight:
@@ -181,7 +192,8 @@ Multiple paragraphs:
3. Item 3.
-## Nested
+Nested
+------
- Tab
- Tab
@@ -209,7 +221,8 @@ Same thing but with paragraphs:
3. Third
-## Tabs and spaces
+Tabs and spaces
+---------------
- this is a list item indented with tabs
@@ -219,7 +232,8 @@ Same thing but with paragraphs:
- this is an example list item indented with spaces
-## Fancy list markers
+Fancy list markers
+------------------
(2) begins with 2
(3) and now 3
@@ -252,7 +266,8 @@ B. Williams
* * * * *
-# Definition Lists
+Definition Lists
+================
Tight using spaces:
@@ -331,7 +346,8 @@ orange
1. sublist
2. sublist
-# HTML Blocks
+HTML Blocks
+===========
Simple block on one line:
@@ -444,7 +460,8 @@ Hr’s:
* * * * *
-# Inline Markup
+Inline Markup
+=============
This is *emphasized*, and so *is this*.
@@ -473,7 +490,8 @@ spaces: a\^b c\^d, a\~b c\~d.
* * * * *
-# Smart quotes, ellipses, dashes
+Smart quotes, ellipses, dashes
+==============================
“Hello,” said the spider. “‘Shelob’ is my name.”
@@ -494,7 +512,8 @@ Ellipses…and…and….
* * * * *
-# LaTeX
+LaTeX
+=====
- \cite[22-23]{smith.1899}
- $2+2=4$
@@ -524,7 +543,8 @@ Cat & 1 \\ \hline
* * * * *
-# Special Characters
+Special Characters
+==================
Here is some unicode:
@@ -578,9 +598,11 @@ Minus: -
* * * * *
-# Links
+Links
+=====
-## Explicit
+Explicit
+--------
Just a [URL](/url/).
@@ -600,7 +622,8 @@ Just a [URL](/url/).
[Empty]().
-## Reference
+Reference
+---------
Foo [bar](/url/).
@@ -626,7 +649,8 @@ Foo [bar](/url/ "Title with "quotes" inside").
Foo [biz](/url/ "Title with "quote" inside").
-## With ampersands
+With ampersands
+---------------
Here’s a [link with an ampersand in the URL](http://example.com/?foo=1&bar=2).
@@ -637,7 +661,8 @@ Here’s an [inline link](/script?foo=1&bar=2).
Here’s an [inline link in pointy braces](/script?foo=1&bar=2).
-## Autolinks
+Autolinks
+---------
With an ampersand: <http://example.com/?foo=1&bar=2>
@@ -655,7 +680,8 @@ Auto-links should not occur here: `<http://example.com/>`
* * * * *
-# Images
+Images
+======
From “Voyage dans la Lune” by Georges Melies (1902):
@@ -665,7 +691,8 @@ Here is a movie ![movie](movie.jpg) icon.
* * * * *
-# Footnotes
+Footnotes
+=========
Here is a footnote reference,[^1] and another.[^2] This should *not* be a
footnote reference, because it contains a space.[\^my note] Here is an inline
diff --git a/tests/writer.mediawiki b/tests/writer.mediawiki
index af4f7050c..314e7ab2f 100644
--- a/tests/writer.mediawiki
+++ b/tests/writer.mediawiki
@@ -1,4 +1,4 @@
-This is a set of tests for pandoc. Most of them are adapted from John Gruber&rsquo;s markdown test suite.
+This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.
-----
@@ -30,11 +30,11 @@ with no blank line
= Paragraphs =
-Here&rsquo;s a regular paragraph.
+Here’s a regular paragraph.
In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.
-Here&rsquo;s one with a bullet. * criminey.
+Here’s one with a bullet. * criminey.
There should be a hard line break<br />
here.
@@ -160,7 +160,7 @@ Multiple paragraphs:
<ol style="list-style-type: decimal;">
<li><p>Item 1, graf one.</p>
-<p>Item 1. graf two. The quick brown fox jumped over the lazy dog&rsquo;s back.</p></li>
+<p>Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.</p></li>
<li><p>Item 2.</p></li>
<li><p>Item 3.</p></li></ol>
@@ -172,7 +172,7 @@ Multiple paragraphs:
-Here&rsquo;s another:
+Here’s another:
# First
# Second:
@@ -350,7 +350,7 @@ And this is '''strong'''
<script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script>
-Here&rsquo;s a simple block:
+Here’s a simple block:
<div>
@@ -401,7 +401,7 @@ Just plain comment, with trailing spaces on the line:
Code:
<pre>&lt;hr /&gt;</pre>
-Hr&rsquo;s:
+Hr’s:
<hr>
@@ -455,21 +455,21 @@ These should not be superscripts or subscripts, because of the unescaped spaces:
= Smart quotes, ellipses, dashes =
-&ldquo;Hello,&rdquo; said the spider. &ldquo;&lsquo;Shelob&rsquo; is my name.&rdquo;
+“Hello,” said the spider. “‘Shelob’ is my name.”
-&lsquo;A&rsquo;, &lsquo;B&rsquo;, and &lsquo;C&rsquo; are letters.
+‘A’, ‘B’, and ‘C’ are letters.
-&lsquo;Oak,&rsquo; &lsquo;elm,&rsquo; and &lsquo;beech&rsquo; are names of trees. So is &lsquo;pine.&rsquo;
+‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’
-&lsquo;He said, &ldquo;I want to go.&rdquo;&rsquo; Were you alive in the 70&rsquo;s?
+‘He said, “I want to go.”’ Were you alive in the 70’s?
-Here is some quoted &lsquo;<tt>code</tt>&rsquo; and a &ldquo;[http://example.com/?foo=1&bar=2 quoted link]&rdquo;.
+Here is some quoted ‘<tt>code</tt>’ and a “[http://example.com/?foo=1&bar=2 quoted link]”.
-Some dashes: one&mdash;two &mdash; three&mdash;four &mdash; five.
+Some dashes: one—two — three—four — five.
-Dashes between numbers: 5&ndash;7, 255&ndash;66, 1987&ndash;1999.
+Dashes between numbers: 5–7, 255–66, 1987–1999.
-Ellipses&hellip;and&hellip;and&hellip;.
+Ellipses…and…and….
-----
@@ -482,17 +482,17 @@ Ellipses&hellip;and&hellip;and&hellip;.
* <math>\alpha \wedge \omega</math>
* <math>223</math>
* <math>p</math>-Tree
-* Here&rsquo;s some display math: <math>\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}</math>
-* Here&rsquo;s one that has a line break in it: <math>\alpha + \omega \times x^2</math>.
+* Here’s some display math: <math>\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}</math>
+* Here’s one that has a line break in it: <math>\alpha + \omega \times x^2</math>.
-These shouldn&rsquo;t be math:
+These shouldn’t be math:
* To get the famous equation, write <tt>$e = mc^2$</tt>.
-* $22,000 is a ''lot'' of money. So is $34,000. (It worked if &ldquo;lot&rdquo; is emphasized.)
+* $22,000 is a ''lot'' of money. So is $34,000. (It worked if “lot” is emphasized.)
* Shoes ($20) and socks ($5).
* Escaped <tt>$</tt>: $73 ''this should be emphasized'' 23$.
-Here&rsquo;s a LaTeX table:
+Here’s a LaTeX table:
@@ -602,13 +602,13 @@ Foo [[url/|biz]].
== With ampersands ==
-Here&rsquo;s a [http://example.com/?foo=1&bar=2 link with an ampersand in the URL].
+Here’s a [http://example.com/?foo=1&bar=2 link with an ampersand in the URL].
-Here&rsquo;s a link with an amersand in the link text: [http://att.com/ AT&amp;T].
+Here’s a link with an amersand in the link text: [http://att.com/ AT&amp;T].
-Here&rsquo;s an [[script?foo=1&bar=2|inline link]].
+Here’s an [[script?foo=1&bar=2|inline link]].
-Here&rsquo;s an [[script?foo=1&bar=2|inline link in pointy braces]].
+Here’s an [[script?foo=1&bar=2|inline link in pointy braces]].
== Autolinks ==
@@ -630,7 +630,7 @@ Auto-links should not occur here: <tt>&lt;http://example.com/&gt;</tt>
= Images =
-From &ldquo;Voyage dans la Lune&rdquo; by Georges Melies (1902):
+From “Voyage dans la Lune” by Georges Melies (1902):
[[Image:lalune.jpg|frame|none|alt=Voyage dans la Lune|caption lalune]]
@@ -642,7 +642,7 @@ Here is a movie [[Image:movie.jpg|movie]] icon.
= Footnotes =
Here is a footnote reference,<ref>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.
-</ref> and another.<ref>Here&rsquo;s the long note. This one contains multiple blocks.
+</ref> and another.<ref>Here’s the long note. This one contains multiple blocks.
Subsequent blocks are indented to show that they belong to the footnote (as with list items).
diff --git a/tests/writer.native b/tests/writer.native
index 879cb24fc..691c4959a 100644
--- a/tests/writer.native
+++ b/tests/writer.native
@@ -1,5 +1,5 @@
Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docAuthors = [[Str "John",Space,Str "MacFarlane"],[Str "Anonymous"]], docDate = [Str "July",Space,Str "17",Str ",",Space,Str "2006"]})
-[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc",Str ".",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite",Str "."]
,HorizontalRule
,Header 1 [Str "Headers"]
,Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]
@@ -14,9 +14,9 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
,HorizontalRule
,Header 1 [Str "Paragraphs"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "regular",Space,Str "paragraph",Str "."]
,Para [Str "In",Space,Str "Markdown",Space,Str "1",Str ".",Str "0",Str ".",Str "0",Space,Str "and",Space,Str "earlier",Str ".",Space,Str "Version",Space,Str "8",Str ".",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item",Str ".",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item",Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
+,Para [Str "Here\8217s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet",Str ".",Space,Str "*",Space,Str "criminey",Str "."]
,Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here",Str "."]
,HorizontalRule
,Header 1 [Str "Block",Space,Str "Quotes"]
@@ -100,7 +100,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Multiple",Space,Str "paragraphs",Str ":"]
,OrderedList (1,Decimal,Period)
[[Para [Str "Item",Space,Str "1",Str ",",Space,Str "graf",Space,Str "one",Str "."]
- ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back",Str "."]]
+ ,Para [Str "Item",Space,Str "1",Str ".",Space,Str "graf",Space,Str "two",Str ".",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog\8217s",Space,Str "back",Str "."]]
,[Para [Str "Item",Space,Str "2",Str "."]]
,[Para [Str "Item",Space,Str "3",Str "."]]]
,Header 2 [Str "Nested"]
@@ -110,7 +110,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
[[Plain [Str "Tab"]
,BulletList
[[Plain [Str "Tab"]]]]]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "another",Str ":"]
+,Para [Str "Here\8217s",Space,Str "another",Str ":"]
,OrderedList (1,Decimal,Period)
[[Plain [Str "First"]]
,[Plain [Str "Second",Str ":"]
@@ -243,7 +243,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,RawBlock "html" "</td>\n<td>"
,Plain [Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"]]
,RawBlock "html" "</td>\n</tr>\n</table>\n\n<script type=\"text/javascript\">document.write('This *should not* be interpreted as markdown');</script>\n"
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block",Str ":"]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "simple",Space,Str "block",Str ":"]
,RawBlock "html" "<div>\n "
,Plain [Str "foo"]
,RawBlock "html" "</div>\n"
@@ -265,7 +265,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,RawBlock "html" "<!-- foo --> \n"
,Para [Str "Code",Str ":"]
,CodeBlock ("",[],[]) "<hr />"
-,Para [Str "Hr",Apostrophe,Str "s",Str ":"]
+,Para [Str "Hr\8217s",Str ":"]
,RawBlock "html" "<hr>\n\n<hr />\n\n<hr />\n\n<hr> \n\n<hr /> \n\n<hr /> \n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\" />\n\n<hr class=\"foo\" id=\"bar\">\n"
,HorizontalRule
,Header 1 [Str "Inline",Space,Str "Markup"]
@@ -286,11 +286,11 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Quoted DoubleQuote [Str "Hello",Str ","],Space,Str "said",Space,Str "the",Space,Str "spider",Str ".",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name",Str "."]]
,Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters",Str "."]
,Para [Quoted SingleQuote [Str "Oak",Str ","],Space,Quoted SingleQuote [Str "elm",Str ","],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees",Str ".",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine",Str "."]]
-,Para [Quoted SingleQuote [Str "He",Space,Str "said",Str ",",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s",Str "?"]
+,Para [Quoted SingleQuote [Str "He",Space,Str "said",Str ",",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go",Str "."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70\8217s",Str "?"]
,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code ("",[],[]) "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]
-,Para [Str "Some",Space,Str "dashes",Str ":",Space,Str "one",EmDash,Str "two",Space,EmDash,Space,Str "three",EmDash,Str "four",Space,EmDash,Space,Str "five",Str "."]
-,Para [Str "Dashes",Space,Str "between",Space,Str "numbers",Str ":",Space,Str "5",EnDash,Str "7",Str ",",Space,Str "255",EnDash,Str "66",Str ",",Space,Str "1987",EnDash,Str "1999",Str "."]
-,Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]
+,Para [Str "Some",Space,Str "dashes",Str ":",Space,Str "one",Str "\8212",Str "two",Space,Str "\8212",Space,Str "three",Str "\8212",Str "four",Space,Str "\8212",Space,Str "five",Str "."]
+,Para [Str "Dashes",Space,Str "between",Space,Str "numbers",Str ":",Space,Str "5",Str "\8211",Str "7",Str ",",Space,Str "255",Str "\8211",Str "66",Str ",",Space,Str "1987",Str "\8211",Str "1999",Str "."]
+,Para [Str "Ellipses",Str "\8230",Str "and",Str "\8230",Str "and",Str "\8230",Str "."]
,HorizontalRule
,Header 1 [Str "LaTeX"]
,BulletList
@@ -300,15 +300,15 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,[Plain [Math InlineMath "\\alpha \\wedge \\omega"]]
,[Plain [Math InlineMath "223"]]
,[Plain [Math InlineMath "p",Str "-",Str "Tree"]]
- ,[Plain [Str "Here",Apostrophe,Str "s",Space,Str "some",Space,Str "display",Space,Str "math",Str ":",Space,Math DisplayMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]
- ,[Plain [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it",Str ":",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
-,Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math",Str ":"]
+ ,[Plain [Str "Here\8217s",Space,Str "some",Space,Str "display",Space,Str "math",Str ":",Space,Math DisplayMath "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"]]
+ ,[Plain [Str "Here\8217s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it",Str ":",Space,Math InlineMath "\\alpha + \\omega \\times x^2",Str "."]]]
+,Para [Str "These",Space,Str "shouldn\8217t",Space,Str "be",Space,Str "math",Str ":"]
,BulletList
[[Plain [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation",Str ",",Space,Str "write",Space,Code ("",[],[]) "$e = mc^2$",Str "."]]
,[Plain [Str "$",Str "22",Str ",",Str "000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money",Str ".",Space,Str "So",Space,Str "is",Space,Str "$",Str "34",Str ",",Str "000",Str ".",Space,Str "(",Str "It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized",Str ".",Str ")"]]
,[Plain [Str "Shoes",Space,Str "(",Str "$",Str "20",Str ")",Space,Str "and",Space,Str "socks",Space,Str "(",Str "$",Str "5",Str ")",Str "."]]
,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."]]]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table",Str ":"]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table",Str ":"]
,RawBlock "latex" "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
,HorizontalRule
,Header 1 [Str "Special",Space,Str "Characters"]
@@ -366,10 +366,10 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Foo",Space,Link [Str "bar"] ("/url/","Title with \"quotes\" inside"),Str "."]
,Para [Str "Foo",Space,Link [Str "biz"] ("/url/","Title with \"quote\" inside"),Str "."]
,Header 2 [Str "With",Space,Str "ampersands"]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
-,Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text",Str ":",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/","AT&T"),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
+,Para [Str "Here\8217s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
,Header 2 [Str "Autolinks"]
,Para [Str "With",Space,Str "an",Space,Str "ampersand",Str ":",Space,Link [Code ("",["url"],[]) "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
,BulletList
@@ -388,7 +388,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "movie"] ("movie.jpg",""),Space,Str "icon",Str "."]
,HorizontalRule
,Header 1 [Str "Footnotes"]
-,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(",Str "as",Space,Str "with",Space,Str "list",Space,Str "items",Str ")",Str "."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want",Str ",",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line",Str ",",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters",Str ",",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
+,Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote",Str ".",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference",Str ".",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document",Str "."]],Space,Str "and",Space,Str "another",Str ".",Note [Para [Str "Here\8217s",Space,Str "the",Space,Str "long",Space,Str "note",Str ".",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks",Str "."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(",Str "as",Space,Str "with",Space,Str "list",Space,Str "items",Str ")",Str "."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want",Str ",",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line",Str ",",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block",Str "."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference",Str ",",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space",Str ".",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note",Str ".",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type",Str ".",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code ("",[],[]) "]",Space,Str "verbatim",Space,Str "characters",Str ",",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
,BlockQuote
[Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes",Str ".",Note [Para [Str "In",Space,Str "quote",Str "."]]]]
,OrderedList (1,Decimal,Period)
diff --git a/tests/writer.opendocument b/tests/writer.opendocument
index 70ef85b46..587c16502 100644
--- a/tests/writer.opendocument
+++ b/tests/writer.opendocument
@@ -689,17 +689,21 @@
<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 style:text-position="super 58%" /></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 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="T66" style:family="text"><style:text-properties style:text-position="super 58%" /></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 fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></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="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>
@@ -855,12 +859,12 @@
</office:automatic-styles>
<office:body>
<office:text>
-<text:h text:style-name="Heading_20_1" text:outline-level="1">Pandoc Test Suite</text:h>
+<text:h text:style-name="Title">Pandoc Test Suite</text:h>
<text:p text:style-name="Author">John MacFarlane</text:p>
<text:p text:style-name="Author">Anonymous</text:p>
<text:p text:style-name="Date">July 17, 2006</text:p>
<text:p text:style-name="Text_20_body">This is a set of tests for pandoc. Most
-of them are adapted from John Gruber&#8217;s markdown test suite.</text:p>
+of them are adapted from John Gruber’s markdown test suite.</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">Headers</text:h>
<text:h text:style-name="Heading_20_2" text:outline-level="2">Level 2 with an
@@ -879,12 +883,12 @@ link</text:span></text:a></text:h>
<text:p text:style-name="First_20_paragraph">with no blank line</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">Paragraphs</text:h>
-<text:p text:style-name="First_20_paragraph">Here&#8217;s a regular
+<text:p text:style-name="First_20_paragraph">Here’s a regular
paragraph.</text:p>
<text:p text:style-name="Text_20_body">In Markdown 1.0.0 and earlier. Version
8. This line turns into a list item. Because a hard-wrapped line in the middle
of a paragraph looked like a list item.</text:p>
-<text:p text:style-name="Text_20_body">Here&#8217;s one with a bullet. *
+<text:p text:style-name="Text_20_body">Here’s one with a bullet. *
criminey.</text:p>
<text:p text:style-name="Text_20_body">There should be a hard line
break<text:line-break />here.</text:p>
@@ -1057,7 +1061,7 @@ Blocks</text:h>
<text:list-item>
<text:p text:style-name="P29">Item 1, graf one.</text:p>
<text:p text:style-name="P29">Item 1. graf two. The quick brown fox jumped
- over the lazy dog&#8217;s back.</text:p>
+ over the lazy dog’s back.</text:p>
</text:list-item>
<text:list-item>
<text:p text:style-name="P29">Item 2.</text:p>
@@ -1080,7 +1084,7 @@ Blocks</text:h>
</text:list>
</text:list-item>
</text:list>
-<text:p text:style-name="First_20_paragraph">Here&#8217;s another:</text:p>
+<text:p text:style-name="First_20_paragraph">Here’s another:</text:p>
<text:list text:style-name="L16">
<text:list-item>
<text:p text:style-name="P33">First</text:p>
@@ -1299,7 +1303,7 @@ table:</text:p>
<text:span text:style-name="T5">emphasized</text:span></text:p>
<text:p text:style-name="Text_20_body">And this is
<text:span text:style-name="T6">strong</text:span></text:p>
-<text:p text:style-name="Text_20_body">Here&#8217;s a simple block:</text:p>
+<text:p text:style-name="Text_20_body">Here’s a simple block:</text:p>
<text:p text:style-name="Text_20_body">foo</text:p>
<text:p text:style-name="Text_20_body">This should be a code block,
though:</text:p>
@@ -1319,7 +1323,7 @@ comment:</text:p>
spaces on the line:</text:p>
<text:p text:style-name="Text_20_body">Code:</text:p>
<text:p text:style-name="P50">&lt;hr /&gt;</text:p>
-<text:p text:style-name="First_20_paragraph">Hr&#8217;s:</text:p>
+<text:p text:style-name="First_20_paragraph">Hr’s:</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">Inline
Markup</text:h>
@@ -1370,23 +1374,22 @@ subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">Smart quotes,
ellipses, dashes</text:h>
-<text:p text:style-name="First_20_paragraph">&#8220;Hello,&#8221; said the
-spider. &#8220;&#8216;Shelob&#8217; is my name.&#8221;</text:p>
-<text:p text:style-name="Text_20_body">&#8216;A&#8217;, &#8216;B&#8217;, and
-&#8216;C&#8217; are letters.</text:p>
-<text:p text:style-name="Text_20_body">&#8216;Oak,&#8217; &#8216;elm,&#8217;
-and &#8216;beech&#8217; are names of trees. So is &#8216;pine.&#8217;</text:p>
-<text:p text:style-name="Text_20_body">&#8216;He said, &#8220;I want to
-go.&#8221;&#8217; Were you alive in the 70&#8217;s?</text:p>
+<text:p text:style-name="First_20_paragraph">“Hello,” said the spider.
+“‘Shelob’ is my name.”</text:p>
+<text:p text:style-name="Text_20_body">‘A’, ‘B’, and ‘C’ are letters.</text:p>
+<text:p text:style-name="Text_20_body">‘Oak,’ ‘elm,’ and ‘beech’ are names of
+trees. So is ‘pine.’</text:p>
+<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
-&#8216;<text:span text:style-name="Teletype">code</text:span>&#8217; and a
-&#8220;<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>&#8221;.</text:p>
-<text:p text:style-name="Text_20_body">Some dashes: one&#8212;two &#8212;
-three&#8212;four &#8212; five.</text:p>
-<text:p text:style-name="Text_20_body">Dashes between numbers: 5&#8211;7,
-255&#8211;66, 1987&#8211;1999.</text:p>
-<text:p text:style-name="Text_20_body">Ellipses&#8230;and&#8230;and&#8230;.</text:p>
+‘<text:span text:style-name="Teletype">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 —
+five.</text:p>
+<text:p text:style-name="Text_20_body">Dashes between numbers: 5–7, 255–66,
+1987–1999.</text:p>
+<text:p text:style-name="Text_20_body">Ellipses…and…and….</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">LaTeX</text:h>
<text:list text:style-name="L26">
@@ -1400,26 +1403,24 @@ three&#8212;four &#8212; five.</text:p>
<text:p text:style-name="P51"><text:span text:style-name="T58">x</text:span> ∈ <text:span text:style-name="T59">y</text:span></text:p>
</text:list-item>
<text:list-item>
- <text:p text:style-name="P51">α ∧ ω</text:p>
+ <text:p text:style-name="P51"><text:span text:style-name="T60">α</text:span> ∧ <text:span text:style-name="T61">ω</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="T62">p</text:span>-Tree</text:p>
</text:list-item>
<text:list-item>
- <text:p text:style-name="P51">Here&#8217;s some display math:
+ <text:p text:style-name="P51">Here’s some display math:
$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</text:p>
</text:list-item>
<text:list-item>
- <text:p text:style-name="P51">Here&#8217;s one that has a line break in
- it:
- α + ω × <text:span text:style-name="T61">x</text:span><text:span text:style-name="T62">2</text:span>.</text:p>
+ <text:p text:style-name="P51">Here’s one that has a line break in it:
+ <text:span text:style-name="T63">α</text:span> + <text:span text:style-name="T64">ω</text:span> × <text:span text:style-name="T65">x</text:span><text:span text:style-name="T66">2</text:span>.</text:p>
</text:list-item>
</text:list>
-<text:p text:style-name="First_20_paragraph">These shouldn&#8217;t be
-math:</text:p>
+<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
@@ -1427,8 +1428,8 @@ math:</text:p>
</text:list-item>
<text:list-item>
<text:p text:style-name="P52">$22,000 is a
- <text:span text:style-name="T63">lot</text:span> of money. So is $34,000.
- (It worked if &#8220;lot&#8221; is emphasized.)</text:p>
+ <text:span text:style-name="T67">lot</text:span> of money. So is $34,000.
+ (It worked if “lot” is emphasized.)</text:p>
</text:list-item>
<text:list-item>
<text:p text:style-name="P52">Shoes ($20) and socks ($5).</text:p>
@@ -1436,15 +1437,14 @@ math:</text:p>
<text:list-item>
<text:p text:style-name="P52">Escaped
<text:span text:style-name="Teletype">$</text:span>: $73
- <text:span text:style-name="T64">this</text:span><text:span text:style-name="T65">
- </text:span><text:span text:style-name="T66">should</text:span><text:span text:style-name="T67">
- </text:span><text:span text:style-name="T68">be</text:span><text:span text:style-name="T69">
- </text:span><text:span text:style-name="T70">emphasized</text:span>
+ <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>
23$.</text:p>
</text:list-item>
</text:list>
-<text:p text:style-name="First_20_paragraph">Here&#8217;s a LaTeX
-table:</text:p>
+<text:p text:style-name="First_20_paragraph">Here’s a LaTeX table:</text:p>
<text:p text:style-name="Horizontal_20_Line" />
<text:h text:style-name="Heading_20_1" text:outline-level="1">Special
Characters</text:h>
@@ -1534,16 +1534,16 @@ by itself should be a link.</text:p>
<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with &quot;quote&quot; inside"><text:span text:style-name="Definition">biz</text:span></text:a>.</text:p>
<text:h text:style-name="Heading_20_2" text:outline-level="2">With
ampersands</text:h>
-<text:p text:style-name="First_20_paragraph">Here&#8217;s a
+<text:p text:style-name="First_20_paragraph">Here’s a
<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">link
with an ampersand in the URL</text:span></text:a>.</text:p>
-<text:p text:style-name="Text_20_body">Here&#8217;s a link with an amersand in
-the link text:
+<text:p text:style-name="Text_20_body">Here’s a link with an amersand in the
+link text:
<text:a xlink:type="simple" xlink:href="http://att.com/" office:name="AT&amp;T"><text:span text:style-name="Definition">AT&amp;T</text:span></text:a>.</text:p>
-<text:p text:style-name="Text_20_body">Here&#8217;s an
+<text:p text:style-name="Text_20_body">Here’s an
<text:a xlink:type="simple" xlink:href="/script?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">inline
link</text:span></text:a>.</text:p>
-<text:p text:style-name="Text_20_body">Here&#8217;s an
+<text:p text:style-name="Text_20_body">Here’s an
<text:a xlink:type="simple" xlink:href="/script?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">inline
link in pointy braces</text:span></text:a>.</text:p>
<text:h text:style-name="Heading_20_2" text:outline-level="2">Autolinks</text:h>
@@ -1569,8 +1569,8 @@ link in pointy braces</text:span></text:a>.</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>
-<text:p text:style-name="First_20_paragraph">From &#8220;Voyage dans la
-Lune&#8221; by Georges Melies (1902):</text:p>
+<text:p text:style-name="First_20_paragraph">From “Voyage dans la Lune” by
+Georges Melies (1902):</text:p>
<text:p text:style-name="Text_20_body"><draw:frame><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>
<text:p text:style-name="Text_20_body">Here is a movie
<draw:frame><draw:image xlink:href="movie.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame>
@@ -1582,17 +1582,17 @@ reference,<text:note text:id="ftn0" text:note-class="footnote"><text:note-citati
is the footnote. It can go anywhere after the footnote reference. It need not
be placed at the end of the document.</text:p></text:note-body></text:note>
and
-another.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>2</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here&#8217;s
+another.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>2</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here’s
the long note. This one contains multiple
blocks.</text:p><text:p text:style-name="Footnote">Subsequent blocks are
indented to show that they belong to the footnote (as with list
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="T71">not</text:span> be a footnote
+should <text:span text:style-name="T75">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="T72">easier</text:span> to type. Inline notes
+is <text:span text:style-name="T76">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="Teletype">]</text:span> verbatim characters,
diff --git a/tests/writer.rst b/tests/writer.rst
index 189886a87..09fd8dcb3 100644
--- a/tests/writer.rst
+++ b/tests/writer.rst
@@ -8,6 +8,7 @@ Pandoc Test Suite
.. role:: math(raw)
:format: html latex
+..
This is a set of tests for pandoc. Most of them are adapted from John Gruber’s
markdown test suite.
@@ -597,15 +598,16 @@ LaTeX
=====
-
-- :math:`$2+2=4$`
-- :math:`$x \in y$`
-- :math:`$\alpha \wedge \omega$`
-- :math:`$223$`
-- :math:`$p$`-Tree
+- :math:`2+2=4`
+- :math:`x \in y`
+- :math:`\alpha \wedge \omega`
+- :math:`223`
+- :math:`p`\ -Tree
- Here’s some display math:
- :math:`$$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$`
-- Here’s one that has a line break in it:
- :math:`$\alpha + \omega \times x^2$`.
+
+ .. math:: \frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}
+
+- Here’s one that has a line break in it: :math:`\alpha + \omega \times x^2`\ .
These shouldn’t be math:
diff --git a/tests/writer.rtf b/tests/writer.rtf
index 6bca9387f..648b4966d 100644
--- a/tests/writer.rtf
+++ b/tests/writer.rtf
@@ -266,11 +266,11 @@ quoted link
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab \par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab 2\u8197?+\u8197?2\u8196?=\u8196?4\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i x}\u8196?\u8712?\u8196?{\i y}\par}
-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab \u945?\u8197?\u8743?\u8197?\u969?\par}
+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i \u945?}\u8197?\u8743?\u8197?{\i \u969?}\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab 223\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i p}-Tree\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's some display math: $\\frac\{d\}\{dx\}f(x)=\\lim_\{h\\to 0\}\\frac\{f(x+h)-f(x)\}\{h\}$\par}
-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's one that has a line break in it: \u945?\u8197?+\u8197?\u969?\u8197?\u215?\u8197?{\i x}{\super 2}.\sa180\par}
+{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's one that has a line break in it: {\i \u945?}\u8197?+\u8197?{\i \u969?}\u8197?\u215?\u8197?{\i x}{\super 2}.\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 These shouldn\u8217't be math:\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab To get the famous equation, write {\f1 $e = mc^2$}.\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab $22,000 is a {\i lot} of money. So is $34,000. (It worked if \u8220"lot\u8221" is emphasized.)\par}