git.iko.soy/typeable/pandoc
on master help sign in
Merge branch 'master' into groff_reader
commit27467189ab184c5d098e244e01f7d1bfdb0d4d45 authorYan Pas <yanp.bugz@gmail.com> dateSun 7 Oct 2018, 18:10 (8 years ago) parent4f3dd3bbd8a663
225 files changed+8087−3836
.stylish-haskell.yaml+4−4 .travis.yml+30−23 AUTHORS.md+13 CONTRIBUTING.md+11−7 INSTALL.md+22−7 MANUAL.txt+189−88 Makefile+27−13 README.md+6−6 RELEASE-CHECKLIST+1−2 RELEASE-CHECKLIST.md−27 appveyor.yml+48−32 cabal.project+7 changelog+679−33 data/pandoc.lua+2−2 data/templates/default.epub3+1−1 data/templates/default.html5+1−1 data/templates/default.latex+43−38 data/templates/default.opendocument+1−3 data/templates/default.revealjs+5−1 data/templates/default.rst+6−2 data/templates/default.tei+16−4 data/templates/default.texinfo−22 data/translations/fr.yaml+10−10 data/translations/ru.yaml+9−9 default.nix+1−1 doc/lua-filter-types-and-objects.md+396 doc/lua-filters.md+43−7 doc/using-the-pandoc-api.md+2−2 linux/Dockerfile+7−40 man/pandoc.1+245−63 pandoc.cabal+36−34 src/Text/Pandoc/App.hs+42−37 src/Text/Pandoc/Class.hs+3−3 src/Text/Pandoc/Emoji.hs+6−1 src/Text/Pandoc/Extensions.hs+5−2 src/Text/Pandoc/Highlighting.hs+1 src/Text/Pandoc/ImageSize.hs+30−25 src/Text/Pandoc/Lua.hs+12−14 src/Text/Pandoc/Lua/Filter.hs+81−63 src/Text/Pandoc/Lua/Init.hs+10−5 src/Text/Pandoc/Lua/Module/MediaBag.hs+1−1 src/Text/Pandoc/Lua/Module/Pandoc.hs+18−17 src/Text/Pandoc/Lua/Module/Utils.hs+22−12 src/Text/Pandoc/Lua/Packages.hs+12−20 src/Text/Pandoc/Lua/StackInstances.hs+112−142 src/Text/Pandoc/Lua/Util.hs+85−101 src/Text/Pandoc/Options.hs+2 src/Text/Pandoc/PDF.hs+63−59 src/Text/Pandoc/Parsing.hs+10−13 src/Text/Pandoc/Readers/CommonMark.hs+36−28 src/Text/Pandoc/Readers/Creole.hs+1−1 src/Text/Pandoc/Readers/DocBook.hs+28−38 src/Text/Pandoc/Readers/Docx/Lists.hs+2−3 src/Text/Pandoc/Readers/Docx/Parse.hs+8−5 src/Text/Pandoc/Readers/EPUB.hs+1−1 src/Text/Pandoc/Readers/HTML.hs+45−8 src/Text/Pandoc/Readers/Haddock.hs+1−13 src/Text/Pandoc/Readers/JATS.hs+1−1 src/Text/Pandoc/Readers/LaTeX.hs+495−979 src/Text/Pandoc/Readers/LaTeX/Lang.hs+173 src/Text/Pandoc/Readers/LaTeX/Parsing.hs+668 src/Text/Pandoc/Readers/LaTeX/Types.hs+5−1 src/Text/Pandoc/Readers/Markdown.hs+98−94 src/Text/Pandoc/Readers/Muse.hs+260−254 src/Text/Pandoc/Readers/Odt/Arrows/Utils.hs+2−2 src/Text/Pandoc/Readers/Odt/Generic/Namespaces.hs+1−1 src/Text/Pandoc/Readers/Odt/Generic/Utils.hs+3−5 src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs+1−1 src/Text/Pandoc/Readers/Odt/StyleReader.hs+2−2 src/Text/Pandoc/Readers/Org/Blocks.hs+2−5 src/Text/Pandoc/Readers/Org/DocumentTree.hs+98−41 src/Text/Pandoc/Readers/Org/ExportSettings.hs+1−1 src/Text/Pandoc/Readers/Org/Inlines.hs+6−4 src/Text/Pandoc/Readers/Org/Meta.hs+14 src/Text/Pandoc/Readers/Org/ParserState.hs+10 src/Text/Pandoc/Readers/Org/Parsing.hs+11−4 src/Text/Pandoc/Readers/Org/Shared.hs+4 src/Text/Pandoc/Readers/RST.hs+45−23 src/Text/Pandoc/Readers/TWiki.hs+50−61 src/Text/Pandoc/Readers/Textile.hs+1−1 src/Text/Pandoc/Readers/TikiWiki.hs+5−4 src/Text/Pandoc/Readers/Txt2Tags.hs+5−3 src/Text/Pandoc/Readers/Vimwiki.hs+7−11 src/Text/Pandoc/Shared.hs+38−3 src/Text/Pandoc/Translations.hs+31−8 src/Text/Pandoc/UUID.hs+8−7 src/Text/Pandoc/Writers/AsciiDoc.hs+15−10 src/Text/Pandoc/Writers/CommonMark.hs+47−10 src/Text/Pandoc/Writers/ConTeXt.hs+13−12 src/Text/Pandoc/Writers/Custom.hs+80−75 src/Text/Pandoc/Writers/Docbook.hs+4−3 src/Text/Pandoc/Writers/Docx.hs+16−20 src/Text/Pandoc/Writers/EPUB.hs+29−10 src/Text/Pandoc/Writers/FB2.hs+9−3 src/Text/Pandoc/Writers/HTML.hs+166−33 src/Text/Pandoc/Writers/Haddock.hs+6−8 src/Text/Pandoc/Writers/ICML.hs+3−2 src/Text/Pandoc/Writers/JATS.hs+4−4 src/Text/Pandoc/Writers/LaTeX.hs+139−64 src/Text/Pandoc/Writers/Man.hs+4−29 src/Text/Pandoc/Writers/Markdown.hs+20−35 src/Text/Pandoc/Writers/Math.hs+1−1 src/Text/Pandoc/Writers/MediaWiki.hs+1 src/Text/Pandoc/Writers/Ms.hs+3−28 src/Text/Pandoc/Writers/Muse.hs+189−56 src/Text/Pandoc/Writers/ODT.hs+2−2 src/Text/Pandoc/Writers/OPML.hs+2−1 src/Text/Pandoc/Writers/OpenDocument.hs+109−47 src/Text/Pandoc/Writers/Org.hs+2−2 src/Text/Pandoc/Writers/Powerpoint/Presentation.hs+8−14 src/Text/Pandoc/Writers/RST.hs+69−18 src/Text/Pandoc/Writers/RTF.hs+4−2 src/Text/Pandoc/Writers/Shared.hs+111−10 src/Text/Pandoc/Writers/TEI.hs+1−14 src/Text/Pandoc/Writers/Texinfo.hs+10−20 src/Text/Pandoc/Writers/Textile.hs+7−7 stack.lts10.yaml+31 stack.lts11.yaml+27 stack.lts9.yaml+17−10 stack.yaml+16−12 test/Tests/Lua.hs+10−9 test/Tests/Readers/HTML.hs+25 test/Tests/Readers/Markdown.hs+8−4 test/Tests/Readers/Muse.hs+79−6 test/Tests/Readers/Org/Block/Header.hs+38 test/Tests/Readers/Org/Block/List.hs+11 test/Tests/Readers/Org/Directive.hs+23 test/Tests/Readers/Org/Inline.hs+8−1 test/Tests/Readers/RST.hs+15−1 test/Tests/Writers/HTML.hs+5 test/Tests/Writers/Muse.hs+77−17 test/Tests/Writers/RST.hs+8 test/command/1126.md+29 test/command/1710.md+3−4 test/command/2118.md+1−1 test/command/3407.md+2−2 test/command/3432.md+1−1 test/command/3534.md+22 test/command/3558.md+2−2 test/command/3716.md+1−1 test/command/3804.md+1−1 test/command/3947.md+1−1 test/command/4016.md+2−2 test/command/4056.md+1−1 test/command/4159.md+1−1 test/command/4284.md+40 test/command/4528.md+156 test/command/4545.md+20 test/command/4553.md+15 test/command/4624.md+30 test/command/4653.md+8 test/command/4667.md+20 test/command/4669.md+29 test/command/4677.md+8 test/command/4690.md+28 test/command/4722.md+34 test/command/4742.md+25 test/command/4743.md+25 test/command/4748.md+16 test/command/4768.md+7 test/command/4781.md+22 test/command/4794.md+18 test/command/4811.md+48 test/command/4817.md+10 test/command/4819.md+50 test/command/4832.md+21 test/command/4833.md+20 test/command/4842.md+6 test/command/4845.md+6 test/command/4848.md+59 test/command/4860.md+9 test/command/4877.md+13 test/command/4885.md+8 test/command/4908.md+16 test/command/4913.md+34 test/command/4919.md+14 test/command/4928.md+48 test/command/adjacent_latex_blocks.md+2−2 test/command/ascii.md+45 test/command/bar.tex+1 test/command/emoji.md+27 test/command/empty-inline-code.txt+6 test/command/gfm.md+1−1 test/command/hspace.md+3−3 test/command/macros.md+4−4 test/command/refs.md+45−2 test/command/write18.md+1−1 test/command/yaml-metadata-blocks.md+63 test/command/yaml-metadata.yaml+4 test/docbook-xref.native+1−1 test/fb2/meta.fb2+1−1 test/lhs-test.html+4−6 test/lhs-test.html+lhs+4−6 test/lua/test-pandoc-utils.lua+15 test/markdown-reader-more.native+9−8 test/pptx/lists.native+1−1 test/pptx/lists.pptx test/pptx/lists_templated.pptx test/rst-reader.native+1−1 test/tables-rstsubset.native+4−4 test/tables.opendocument+98−96 test/tables.rst+26−34 test/testsuite.native+5−5 test/textile-reader.native+1−1 test/textile-reader.textile+1−1 test/tikiwiki-reader.native+29−29 test/txt2tags.t2t+1−1 test/writer.context+6 test/writer.docbook4+3−3 test/writer.docbook5+3−3 test/writer.fb2+1−1 test/writer.haddock+7−7 test/writer.html4+1−1 test/writer.html5+2−2 test/writer.jats+6−7 test/writer.muse+37−40 test/writer.native+5−5 test/writer.opendocument+621−234 test/writer.org+4−4 test/writer.rst+14−68 test/writer.tei+2−2 test/writer.texinfo+2−22 test/writer.textile+1−1 tools/changelog-helper.sh+23 trypandoc/trypandoc.hs+1−1
.stylish-haskell.yaml+4−4
@@ -41,7 +41,7 @@ steps:
4141 # Default: global.
4242 align: none
4343
44− # Folowing options affect only import list alignment.
44+ # Following options affect only import list alignment.
4545 #
4646 # List align has following options:
4747 #
@@ -75,7 +75,7 @@ steps:
7575 # short enough to fit to single line. Otherwise it'll be multiline.
7676 #
7777 # - multiline: One line per import list entry.
78− # Type with contructor list acts like single import.
78+ # Type with constructor list acts like single import.
7979 #
8080 # > import qualified Data.Map as M
8181 # > ( empty
@@ -91,7 +91,7 @@ steps:
9191 # This option affects 'list_align' and 'long_list_align'.
9292 list_padding: 4
9393
94− # Separate lists option affects formating of import list for type
94+ # Separate lists option affects formatting of import list for type
9595 # or class. The only difference is single space between type and list
9696 # of constructors, selectors and class functions.
9797 #
@@ -124,7 +124,7 @@ steps:
124124
125125 # Align affects alignment of closing pragma brackets.
126126 #
127− # - true: Brackets are aligned in same collumn.
127+ # - true: Brackets are aligned in same column.
128128 #
129129 # - false: Brackets are not aligned together. There is only one space
130130 # between actual import and closing bracket.
.travis.yml+30−23
@@ -32,26 +32,26 @@ matrix:
3232 # We grab the appropriate GHC and cabal-install versions from hvr's PPA. See:
3333 # https://github.com/hvr/multi-ghc-travis
3434 # don't build benchmarks for ghc 7.10.3, because build takes too long...
35− - env: BUILD=cabal GHCVER=7.10.3 CABALVER=1.22 OPTS="-O0 -Wall -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS=""
35+ - env: BUILD=cabal GHCVER=7.10.3 CABALVER=2.0 OPTS="-O0 -Wall -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS="" TESTPATTERN="! /Round trip/"
3636 compiler: ": #GHC 7.10.3"
37− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5], sources: [hvr-ghc]}}
37+ addons: {apt: {packages: [cabal-install-2.0,ghc-7.10.3,happy-1.19.5], sources: [hvr-ghc]}}
3838
3939 # don't build benchmarks for ghc 8.0.2, because build takes too long...
40− - env: BUILD=cabal GHCVER=8.0.2 CABALVER=1.24 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast" CABALARGS=""
40+ - env: BUILD=cabal GHCVER=8.0.2 CABALVER=2.0 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast" CABALARGS="" TESTPATTERN="! /Round trip/"
4141 compiler: ": #GHC 8.0.2"
42− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,happy-1.19.5], sources: [hvr-ghc]}}
42+ addons: {apt: {packages: [cabal-install-2.0,ghc-8.0.2,happy-1.19.5], sources: [hvr-ghc]}}
4343
44− - env: BUILD=cabal GHCVER=8.2.2 CABALVER=1.24 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks"
45− compiler: ": #GHC 8.2.2"
46− addons: {apt: {packages: [cabal-install-1.24,ghc-8.2.2,happy-1.19.5], sources: [hvr-ghc]}}
47−
48− - env: BUILD=cabal GHCVER=8.2.2 CABALVER=2.0 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks"
44+ - env: BUILD=cabal GHCVER=8.2.2 CABALVER=2.0 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks" TESTPATTERN="! /Round trip/"
4945 compiler: ": #GHC 8.2.2"
5046 addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2,happy-1.19.5], sources: [hvr-ghc]}}
5147
52− - env: BUILD=cabal GHCVER=8.4.1 CABALVER=2.0 OPTS="-O0 -Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks"
53− compiler: ": #GHC 8.4.1"
54− addons: {apt: {packages: [cabal-install-2.0,ghc-8.4.1,happy-1.19.5], sources: [hvr-ghc]}}
48+ - env: BUILD=cabal GHCVER=8.4.3 CABALVER=2.2 OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks" TESTPATTERN="! /Round trip/"
49+ compiler: ": #GHC 8.4.3"
50+ addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.3,happy-1.19.5], sources: [hvr-ghc]}}
51+
52+ # - env: BUILD=cabal GHCVER=8.6.1 CABALVER=2.4 OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" FLAGS="fast embed_data_files" CABALARGS="--enable-benchmarks --allow-newer=haddock-library:base" TESTPATTERN="! /Round trip/"
53+ # compiler: ": #GHC 8.6.1"
54+ # addons: {apt: {packages: [cabal-install-2.4,ghc-8.6.1,happy-1.19.5], sources: [hvr-ghc]}}
5555
5656 # Build with the newest GHC and cabal-install. This is an accepted failure,
5757 # see below.
@@ -61,18 +61,18 @@ matrix:
6161
6262 # The Stack builds. We can pass in arbitrary Stack arguments via the ARGS
6363 # variable, such as using --stack-yaml to point to a different file.
64− # - env: BUILD=stack ARGS="--stack-yaml stack.lts9.yaml" OPTS="-Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror"
64+ # - env: BUILD=stack ARGS="--stack-yaml stack.lts9.yaml" OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" FLAGS="fast embed_data_files"
6565 # compiler: ": #stack 8.0.2"
6666 # addons: {apt: {packages: [ghc-8.0.2], sources: [hvr-ghc]}}
6767
68− - env: BUILD=stack ARGS="--resolver lts-10" OPTS="-Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror"
69− compiler: ": #stack 8.2.2"
70− addons: {apt: {packages: [ghc-8.2.2], sources: [hvr-ghc]}}
68+ - env: BUILD=stack ARGS="--resolver lts-12" OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" TESTPATTERN="! /Round trip/"
69+ compiler: ": #stack 8.4.3"
70+ addons: {apt: {packages: [ghc-8.4.3], sources: [hvr-ghc]}}
7171
7272 # Nightly builds are allowed to fail
73− - env: BUILD=stack ARGS="--resolver nightly" OPTS="-Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror"
73+ - env: BUILD=stack ARGS="--resolver nightly" OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" TESTPATTERN="."
7474 compiler: ": #stack nightly"
75− addons: {apt: {packages: [ghc-8.2.2], sources: [hvr-ghc]}}
75+ addons: {apt: {packages: [ghc-8.4.3], sources: [hvr-ghc]}}
7676
7777 # - env: BUILD=stack ARGS="--resolver lts-8"
7878 # compiler: ": #stack 8.0.2 osx"
@@ -84,14 +84,14 @@ matrix:
8484
8585 allow_failures:
8686 - env: BUILD=cabal GHCVER=head CABALVER=head
87− - env: BUILD=stack ARGS="--resolver nightly" OPTS="-Wall -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -fno-warn-unused-do-bind -Werror"
87+ - env: BUILD=stack ARGS="--resolver nightly" OPTS="-O0 -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -Werror" TESTPATTERN="."
8888
8989 fast_finish: true
9090
9191before_install:
9292# Using compiler above sets CC to an invalid value, so unset it
9393- unset CC
94−- export PATH=/opt/happy/1.19.5/bin/:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.local/bin:$HOME/.cabal/bin:$PATH
94+- export PATH=/opt/happy/1.19.5/bin/:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:/opt/cabal/bin:$HOME/.local/bin:$HOME/.cabal/bin:$PATH
9595# Download and unpack the stack executable
9696- |
9797 if [[ $BUILD == "stack" ]]; then
@@ -117,7 +117,14 @@ install:
117117 cabal)
118118 cabal --version
119119 travis_retry cabal update
120− cabal install --disable-optimization --only-dependencies --flags="$FLAGS" --enable-tests --force-reinstalls --reorder-goals --max-backjumps=-1 $CABALARGS
120+ case "$GHCVER" in
121+ 7.10.3)
122+ cabal install -v1 --disable-optimization --flags="$FLAGS" --enable-tests --force-reinstalls --reorder-goals --max-backjumps=-1 $CABALARGS
123+ ;;
124+ *)
125+ cabal install --disable-optimization --only-dependencies --flags="$FLAGS" --enable-tests --force-reinstalls --reorder-goals --max-backjumps=-1 $CABALARGS
126+ ;;
127+ esac
121128 ;;
122129 esac
123130
@@ -127,13 +134,13 @@ script:
127134 stack)
128135 ulimit -n 4096
129136 stack config set system-ghc --global true
130− stack --no-terminal $ARGS test --fast --flag 'aeson:fast' --flag pandoc:embed_data_files --haddock --no-haddock-deps --ghc-options="$OPTS" --test-arguments='--hide-successes'
137+ stack --no-terminal $ARGS test --fast --flag 'aeson:fast' --flag pandoc:embed_data_files --haddock --no-haddock-deps --ghc-options="$OPTS" --test-arguments="--hide-successes --pattern \"$TESTPATTERN\""
131138 ;;
132139 cabal)
133140 cabal sdist --output-directory=sourcedist && \
134141 cd sourcedist && \
135142 cabal configure --disable-optimization --enable-tests -v2 --flags="$FLAGS" --ghc-options="$OPTS" $CABALARGS && \
136143 cabal build -v2 -j2 && \
137− cabal test
144+ cabal test --test-options="--pattern=\"$TESTPATTERN\""
138145 ;;
139146 esac
AUTHORS.md+13
@@ -11,9 +11,11 @@
1111- Alexander Sulfrian
1212- Alexander V Vershilov
1313- Alfred Wechselberger
14+- Anders Waldenborg
1415- Andreas Lööw
1516- Andrew Dunning
1617- Antoine Latter
18+- Antonio Terceiro
1719- Arata Mizuki
1820- Arlo O'Keeffe
1921- Artyom Kazak
@@ -26,6 +28,7 @@
2628- Bjorn Buckwalter
2729- Bradley Kuhn
2830- Brent Yorgey
31+- Brian Leung
2932- Bryan O'Sullivan
3033- Caleb McDaniel
3134- Calvin Beck
@@ -71,8 +74,11 @@
7174- Henrik Tramberend
7275- Henry de Valence
7376- Hubert Plociniczak
77+- Igor Khorlo
7478- Ilya V. Portnov
79+- Ivan Trubach
7580- Ivo Clarysse
81+- J. B. Rainsberger
7682- J. Lewis Muir
7783- Jaime Marquínez Ferrándiz
7884- Jakob Voß
@@ -92,8 +98,10 @@
9298- John Muccigrosso
9399- John Luke Bentley
94100- Jonas Smedegaard
101+- Jonas Scholl
95102- Jonathan Daugherty
96103- Jose Luis Duran
104+- José de Mattos Neto
97105- Josef Svenningsson
98106- Julien Cretel
99107- Juliusz Gonera
@@ -133,6 +141,7 @@
133141- Nick Bart
134142- Nicolas Kaiser
135143- Nikolay Yakimov
144+- Nils Carlson
136145- Nokome Bentley
137146- Oliver Matthews
138147- Ophir Lifshitz
@@ -148,6 +157,7 @@
148157- Puneeth Chaganti
149158- Ralf Stephan
150159- Raniere Silva
160+- Raymond Ehlers
151161- Recai Oktaş
152162- Roland Hieber
153163- RyanGlScott
@@ -189,6 +199,8 @@
189199- d-dorazio
190200- iandol
191201- infinity0x
202+- kaizshang91
203+- lux-lth
192204- lwolfsonkin
193205- nkalvi
194206- oltolm
@@ -202,3 +214,4 @@
202214- takahashim
203215- tgkokk
204216- thsutton
217+- wiefling
CONTRIBUTING.md+11−7
@@ -144,13 +144,10 @@ Please follow these guidelines:
1441449. It is better not to introduce new dependencies. Dependencies on
145145 external C libraries should especially be avoided.
146146
147−10. We aim for compatibility with ghc versions from 7.8.3 to the
147+10. We aim for compatibility with ghc versions from 7.10.3 to the
148148 latest release. All pull requests and commits are tested
149149 automatically on <travis-ci.org>, using GHC versions in the
150− `Tested-With` stanza of `pandoc.cabal`. We currently relax
151− the "`-Wall` clean" requirement for GHC 7.10.x, because
152− there are so many warnings relating to the addition of type
153− classes to the Prelude.
150+ `Tested-With` stanza of `pandoc.cabal`.
154151
155152Tests
156153-----
@@ -192,7 +189,7 @@ Using the REPL
192189
193190With a recent version of cabal, you can do `cabal repl` and get
194191a ghci REPL for working with pandoc. With [stack], use
195−`cabal ghci`.
192+`stack ghci`.
196193
197194We recommend using the following `.ghci` file (which can be
198195placed in the source directory):
@@ -267,7 +264,7 @@ The library is structured as follows:
267264 - `Text.Pandoc.Definition` (in `pandoc-types`) defines the types
268265 used for representing a pandoc document.
269266 - `Text.Pandoc.Builder` (in `pandoc-types`) provides functions for
270− building pandoc documents programatically.
267+ building pandoc documents programmatically.
271268 - `Text.Pandoc.Generics` (in `pandoc-types`) provides functions allowing
272269 you to promote functions that operate on parts of pandoc documents
273270 to functions that operate on whole pandoc documents, walking the
@@ -306,6 +303,13 @@ The library is structured as follows:
306303 - `Text.Pandoc.UUID` contains functions for generating UUIDs.
307304 - `Text.Pandoc.XML` contains functions for formatting XML.
308305
306+Lua filters
307+-----------
308+
309+If you've written a useful pandoc [lua filter](lua-filters.html),
310+you may want to consider submitting a pull request to the
311+[lua-filters repository](https://github.com/pandoc/lua-filters).
312+
309313[open issues]: https://github.com/jgm/pandoc/issues
310314[closed issues]: https://github.com/jgm/pandoc/issues?q=is%3Aissue+is%3Aclosed
311315[latest released version]: https://github.com/jgm/pandoc/releases/latest
INSTALL.md+22−7
@@ -11,15 +11,15 @@
1111 a zip file that contains pandoc's binaries and
1212 documentation. Simply unzip this file and move the binaries
1313 to a directory of your choice.
14+
15+ - Alternatively, you can install pandoc using
16+ [chocolatey](https://chocolatey.org): `choco install pandoc`.
1417
1518 - For PDF output, you'll also need to install LaTeX.
1619 We recommend [MiKTeX](http://miktex.org/).
1720
1821## macOS
1922
20− - You can install pandoc using
21− [homebrew](http://brew.sh): `brew install pandoc`.
22−
2323 - There is a package installer at pandoc's [download page].
2424 If you later want to uninstall the package, you can do so
2525 by downloading [this script][uninstaller]
@@ -30,6 +30,12 @@
3030 unzip the file and move the binaries and man pages to
3131 whatever directory you like.
3232
33+ - Alternatively, you can install pandoc using
34+ [homebrew](http://brew.sh): `brew install pandoc`.
35+ Note: If you are using macOS < 10.10, this method installs
36+ pandoc from source, so it will take a long time and a lot of
37+ disk space for the ghc compiler and dependent Haskell libraries.
38+
3339 - For PDF output, you'll also need LaTeX. Because a full [MacTeX]
3440 installation takes more than a gigabyte of disk space, we recommend
3541 installing [BasicTeX](http://www.tug.org/mactex/morepackages.html)
@@ -137,13 +143,21 @@ The easiest way to build pandoc from source is to use [stack]:
137143
1381441. Install the [Haskell platform]. This will give you [GHC] and
139145 the [cabal-install] build tool. Note that pandoc requires
140− GHC >= 7.10.
146+ GHC >= 7.10 and cabal >= 2.0.
141147
1421482. Update your package database:
143149
144150 cabal update
145151
146−3. Use `cabal` to install pandoc and its dependencies:
152+3. Check your cabal version with
153+
154+ cabal --version
155+
156+ If you have a version less than 2.0, install the latest with:
157+
158+ cabal install cabal-install
159+
160+4. Use `cabal` to install pandoc and its dependencies:
147161
148162 cabal install pandoc
149163
@@ -156,7 +170,7 @@ The easiest way to build pandoc from source is to use [stack]:
156170
157171 cabal install
158172
159−4. Make sure the `$CABALDIR/bin` directory is in your path. You should
173+5. Make sure the `$CABALDIR/bin` directory is in your path. You should
160174 now be able to run `pandoc`:
161175
162176 pandoc --help
@@ -200,6 +214,7 @@ over the build and installation. Most users should use the
200214quick install, but this information may be of use to packagers.
201215For more details, see the [Cabal User's Guide]. These instructions
202216assume that the pandoc source directory is your working directory.
217+You will need cabal version 2.0 or higher.
203218
2042191. Install dependencies: in addition to the [Haskell platform],
205220 you will need a number of additional libraries. You can install
@@ -331,5 +346,5 @@ To run just the markdown benchmarks:
331346[openSUSE]: https://software.opensuse.org/package/pandoc
332347[source tarball]: http://hackage.haskell.org/package/pandoc
333348[stack]: http://docs.haskellstack.org/en/stable/install_and_upgrade.html
334−[cabal-install]: http://hackage.haskell.org/trac/hackage/wiki/CabalInstall
349+[cabal-install]: http://hackage.haskell.org/package/cabal-install
335350[uninstaller]: https://raw.githubusercontent.com/jgm/pandoc/master/macos/uninstall-pandoc.pl
MANUAL.txt+189−88
@@ -1,6 +1,6 @@
11% Pandoc User's Guide
22% John MacFarlane
3−% May 10, 2018
3+% September 27, 2018
44
55Synopsis
66========
@@ -155,9 +155,10 @@ the LaTeX engine requires [`fontspec`]. `xelatex` uses
155155`xelatex` will use [`mathspec`] instead of [`unicode-math`].
156156The [`upquote`] and [`microtype`] packages are used if
157157available, and [`csquotes`] will be used for [typography]
158−if added to the template or included in any header file. The
159−[`natbib`], [`biblatex`], [`bibtex`], and [`biber`] packages can
160−optionally be used for [citation rendering].
158+if `\usepackage{csquotes}` is present in the template or
159+included via `/H/--include-in-header`. The [`natbib`],
160+[`biblatex`], [`bibtex`], and [`biber`] packages can optionally
161+be used for [citation rendering].
161162
162163[`amsfonts`]: https://ctan.org/pkg/amsfonts
163164[`amsmath`]: https://ctan.org/pkg/amsmath
@@ -210,7 +211,7 @@ header when requesting a document from a URL:
210211Options
211212=======
212213
213−General options
214+General options {.options}
214215---------------
215216
216217`-f` *FORMAT*, `-r` *FORMAT*, `--from=`*FORMAT*, `--read=`*FORMAT*
@@ -225,9 +226,9 @@ General options
225226 - `epub` ([EPUB])
226227 - `fb2` ([FictionBook2] e-book)
227228 - `gfm` ([GitHub-Flavored Markdown]),
228− or `markdown_github`, which provides deprecated and less accurate
229− support for Github-Flavored Markdown; please use `gfm` instead,
230− unless you need to use extensions other than `smart`.
229+ or the deprecated and less accurate `markdown_github`;
230+ use [`markdown_github`](#markdown-variants) only
231+ if you need extensions not supported in [`gfm`](#markdown-variants).
231232 - `haddock` ([Haddock markup])
232233 - `html` ([HTML])
233234 - `jats` ([JATS] XML)
@@ -274,9 +275,9 @@ General options
274275 - `epub2` (EPUB v2)
275276 - `fb2` ([FictionBook2] e-book)
276277 - `gfm` ([GitHub-Flavored Markdown]),
277− or `markdown_github`, which provides deprecated and less accurate
278− support for Github-Flavored Markdown; please use `gfm` instead,
279− unless you use extensions that do not work with `gfm`.
278+ or the deprecated and less accurate `markdown_github`;
279+ use [`markdown_github`](#markdown-variants) only
280+ if you need extensions not supported in [`gfm`](#markdown-variants).
280281 - `haddock` ([Haddock markup])
281282 - `html` or `html5` ([HTML], i.e. [HTML5]/XHTML [polyglot markup])
282283 - `html4` ([XHTML] 1.0 Transitional)
@@ -458,7 +459,7 @@ General options
458459[PowerPoint]: https://en.wikipedia.org/wiki/Microsoft_PowerPoint
459460[Vimwiki]: https://vimwiki.github.io
460461
461−Reader options
462+Reader options {.options}
462463--------------
463464
464465`--base-header-level=`*NUMBER*
@@ -493,7 +494,7 @@ Reader options
493494 footnotes and links will not work across files. Reading binary
494495 files (docx, odt, epub) implies `--file-scope`.
495496
496−`--filter=`*PROGRAM*
497+`-F` *PROGRAM*, `--filter=`*PROGRAM*
497498
498499: Specify an executable to be used as a filter transforming the
499500 pandoc AST after the input is parsed and before the output is
@@ -577,6 +578,16 @@ Reader options
577578 printed in some output formats) and metadata values will be escaped
578579 when inserted into the template.
579580
581+`--metadata-file=`*FILE*
582+
583+: Read metadata from the supplied YAML (or JSON) file.
584+ This option can be used with every input format, but string
585+ scalars in the YAML file will always be parsed as Markdown.
586+ Generally, the input will be handled the same as in
587+ [YAML metadata blocks][Extension: `yaml_metadata_block`].
588+ Metadata values specified inside the document, or by using `-M`,
589+ overwrite values specified with this option.
590+
580591`-p`, `--preserve-tabs`
581592
582593: Preserve tabs instead of converting them to spaces (the default).
@@ -634,7 +645,7 @@ Reader options
634645[perl]: https://metacpan.org/pod/Pandoc::Filter
635646[JavaScript/node.js]: https://github.com/mvhenderson/pandoc-filter-node
636647
637−General writer options
648+General writer options {.options}
638649----------------------
639650
640651`-s`, `--standalone`
@@ -645,10 +656,10 @@ General writer options
645656 output. For `native` output, this option causes metadata to
646657 be included; otherwise, metadata is suppressed.
647658
648−`--template=`*FILE*
659+`--template=`*FILE*|*URL*
649660
650−: Use *FILE* as a custom template for the generated document. Implies
651− `--standalone`. See [Templates], below, for a description
661+: Use the specified file as a custom template for the generated document.
662+ Implies `--standalone`. See [Templates], below, for a description
652663 of template syntax. If no extension is specified, an extension
653664 corresponding to the writer will be added, so that `--template=special`
654665 looks for `special.html` for HTML output. If the template is not
@@ -713,8 +724,9 @@ General writer options
713724: Include an automatically generated table of contents (or, in
714725 the case of `latex`, `context`, `docx`, `odt`,
715726 `opendocument`, `rst`, or `ms`, an instruction to create
716− one) in the output document. This option has no effect on
717− `man`, `docbook4`, `docbook5`, or `jats` output.
727+ one) in the output document. This option has no effect
728+ unless `-s/--standalone` is used, and it has no effect
729+ on `man`, `docbook4`, `docbook5`, or `jats` output.
718730
719731`--toc-depth=`*NUMBER*
720732
@@ -803,14 +815,20 @@ General writer options
803815 `--resource-path=.:test` will search the working directory
804816 and the `test` subdirectory, in that order.
805817
818+ `--resource-path` only has an effect if (a) the output
819+ format embeds images (for example, `docx`, `pdf`, or `html`
820+ with `--self-contained`) or (b) it is used together with
821+ `--extract-media`.
822+
806823`--request-header=`*NAME*`:`*VAL*
807824
808825: Set the request header *NAME* to the value *VAL* when making
809826 HTTP requests (for example, when a URL is given on the
810827 command line, or when resources used in a document must be
811− downloaded).
828+ downloaded). If you're behind a proxy, you also need to set
829+ the environment variable `http_proxy` to `http://...`.
812830
813−Options affecting specific writers
831+Options affecting specific writers {.options}
814832----------------------------------
815833
816834`--self-contained`
@@ -842,8 +860,10 @@ Options affecting specific writers
842860
843861: Use only ASCII characters in output. Currently supported for
844862 XML and HTML formats (which use numerical entities instead of
845− UTF-8 when this option is selected) and for groff ms and man
846− (which use hexadecimal escapes).
863+ UTF-8 when this option is selected), groff ms and man
864+ (which use hexadecimal escapes), and to a limited degree
865+ for LaTeX (which uses standard commands for accented
866+ characters when possible).
847867
848868`--reference-links`
849869
@@ -898,7 +918,10 @@ Options affecting specific writers
898918
899919`--listings`
900920
901−: Use the [`listings`] package for LaTeX code blocks
921+: Use the [`listings`] package for LaTeX code blocks. The package
922+ does not support multi-byte encoding for source code. To handle UTF-8
923+ you would need to use a custom template. This issue is fully
924+ documented here: [Encoding issue with the listings package].
902925
903926`-i`, `--incremental`
904927
@@ -1126,8 +1149,10 @@ Options affecting specific writers
11261149
11271150[Dublin Core elements]: http://dublincore.org/documents/dces/
11281151[ISO 8601 format]: http://www.w3.org/TR/NOTE-datetime
1152+[Encoding issue with the listings package]:
1153+ https://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings#Encoding_issue
11291154
1130−Citation rendering
1155+Citation rendering {.options}
11311156------------------
11321157
11331158`--bibliography=`*FILE*
@@ -1167,7 +1192,7 @@ Citation rendering
11671192 with the `pandoc-citeproc` filter or with PDF output. It is intended for
11681193 use in producing a LaTeX file that can be processed with [`bibtex`] or [`biber`].
11691194
1170−Math rendering in HTML
1195+Math rendering in HTML {.options}
11711196----------------------
11721197
11731198The default is to render TeX math as far as possible using Unicode characters.
@@ -1208,14 +1233,9 @@ of the following options.
12081233`--katex`[`=`*URL*]
12091234
12101235: Use [KaTeX] to display embedded TeX math in HTML output.
1211− The *URL* is the base URL for the KaTeX library. If a *URL* is
1212− not provided, a link to the KaTeX CDN will be inserted.
1213−
1214−`--katex-stylesheet=`*URL*
1215−
1216−: The *URL* should point to the `katex.css` stylesheet. If this option is
1217− not specified, a link to the KaTeX CDN will be inserted. Note that this
1218− option does not imply `--katex`.
1236+ The *URL* is the base URL for the KaTeX library. That directory
1237+ should contain a `katex.min.js` and a `katex.min.css` file.
1238+ If a *URL* is not provided, a link to the KaTeX CDN will be inserted.
12191239
12201240`--gladtex`
12211241
@@ -1233,7 +1253,7 @@ of the following options.
12331253[KaTeX]: https://github.com/Khan/KaTeX
12341254[GladTeX]: http://humenda.github.io/GladTeX/
12351255
1236−Options for wrapper scripts
1256+Options for wrapper scripts {.options}
12371257---------------------------
12381258
12391259`--dump-args`
@@ -1349,7 +1369,7 @@ depending on the output format, but include the following:
13491369
13501370`toc-title`
13511371: title of table of contents (works only with EPUB,
1352− opendocument, odt, docx, pptx)
1372+ opendocument, odt, docx, pptx, beamer, LaTeX)
13531373
13541374`include-before`
13551375: contents specified by `-B/--include-before-body` (may have
@@ -1523,12 +1543,14 @@ LaTeX variables are used when [creating a PDF].
15231543: options to pass to the microtype package
15241544
15251545`colorlinks`
1526−: add color to link text; automatically enabled if any of `linkcolor`, `citecolor`,
1527− `urlcolor`, or `toccolor` are set
1546+: add color to link text; automatically enabled if any of
1547+ `linkcolor`, `filecolor`, `citecolor`, `urlcolor`, or `toccolor` are set
15281548
1529−`linkcolor`, `citecolor`, `urlcolor`, `toccolor`
1530−: color for internal links, citation links, external links, and links in table of contents:
1531− uses options allowed by [`xcolor`], including the `dvipsnames`, `svgnames`, and `x11names` lists
1549+`linkcolor`, `filecolor`, `citecolor`, `urlcolor`, `toccolor`
1550+: color for internal links, external links, citation links, linked
1551+ URLs, and links in table of contents, respectively: uses options
1552+ allowed by [`xcolor`], including the `dvipsnames`, `svgnames`, and
1553+ `x11names` lists
15321554
15331555`links-as-notes`
15341556: causes links to be printed as footnotes
@@ -1646,17 +1668,17 @@ Variables for ConTeXt
16461668 from [ConTeXt ICC Profiles]. See also [ConTeXt PDFA] for more
16471669 details.
16481670
1649−[ConTeXt Paper Setup]: http://wiki.contextgarden.net/PaperSetup
1650−[ConTeXt Layout]: http://wiki.contextgarden.net/Layout
1651−[ConTeXt Font Switching]: http://wiki.contextgarden.net/Font_Switching
1652−[ConTeXt Color]: http://wiki.contextgarden.net/Color
1653−[ConTeXt Headers and Footers]: http://wiki.contextgarden.net/Headers_and_Footers
1654−[ConTeXt Indentation]: http://wiki.contextgarden.net/Indentation
1655−[ConTeXt ICC Profiles]: http://wiki.contextgarden.net/PDFX#ICC_profiles
1656−[ConTeXt PDFA]: http://wiki.contextgarden.net/PDF/A
1657−[`setupwhitespace`]: http://wiki.contextgarden.net/Command/setupwhitespace
1658−[`setupinterlinespace`]: http://wiki.contextgarden.net/Command/setupinterlinespace
1659−[`setuppagenumbering`]: http://wiki.contextgarden.net/Command/setuppagenumbering
1671+[ConTeXt Paper Setup]: https://wiki.contextgarden.net/PaperSetup
1672+[ConTeXt Layout]: https://wiki.contextgarden.net/Layout
1673+[ConTeXt Font Switching]: https://wiki.contextgarden.net/Font_Switching
1674+[ConTeXt Color]: https://wiki.contextgarden.net/Color
1675+[ConTeXt Headers and Footers]: https://wiki.contextgarden.net/Headers_and_Footers
1676+[ConTeXt Indentation]: https://wiki.contextgarden.net/Indentation
1677+[ConTeXt ICC Profiles]: https://wiki.contextgarden.net/PDFX#ICC_profiles
1678+[ConTeXt PDFA]: https://wiki.contextgarden.net/PDF/A
1679+[`setupwhitespace`]: https://wiki.contextgarden.net/Command/setupwhitespace
1680+[`setupinterlinespace`]: https://wiki.contextgarden.net/Command/setupinterlinespace
1681+[`setuppagenumbering`]: https://wiki.contextgarden.net/Command/setuppagenumbering
16601682
16611683Variables for man pages
16621684-----------------------
@@ -1723,8 +1745,7 @@ of the following:
17231745- any object,
17241746- the boolean `true` (to specify the boolean `true`
17251747 value using YAML metadata or the `--metadata` flag,
1726− use `y`, `Y`, `yes`, `Yes`, `YES`, `true`, `True`,
1727− `TRUE`, `on`, `On`, or `ON`; with the `--variable`
1748+ use `true`, `True`, or `TRUE`; with the `--variable`
17281749 flag, simply omit a value for the variable, e.g.
17291750 `--variable draft`).
17301751
@@ -1913,10 +1934,11 @@ This extension can be enabled/disabled for the following formats
19131934(in addition to `markdown`):
19141935
19151936input formats
1916−: `latex`, `org`, `textile`
1937+: `latex`, `org`, `textile`, `html` (environments, `\ref`, and
1938+ `\eqref` only)
19171939
19181940output formats
1919−: `textile`
1941+: `textile`, `commonmark`
19201942
19211943#### [Extension: `native_divs`] {#native_divs}
19221944
@@ -3051,13 +3073,17 @@ and pass it to pandoc as an argument, along with your Markdown files:
30513073 pandoc chap1.md chap2.md chap3.md metadata.yaml -s -o book.html
30523074
30533075Just be sure that the YAML file begins with `---` and ends with `---` or
3054−`...`.)
3076+`...`.) Alternatively, you can use the `--metadata-file` option. Using
3077+that approach however, you cannot reference content (like footnotes)
3078+from the main markdown input document.
30553079
30563080Metadata will be taken from the fields of the YAML object and added to any
30573081existing document metadata. Metadata can contain lists and objects (nested
30583082arbitrarily), but all string scalars will be interpreted as Markdown. Fields
30593083with names ending in an underscore will be ignored by pandoc. (They may be
3060−given a role by external processors.)
3084+given a role by external processors.) Field names must not be
3085+interpretable as YAML numbers or boolean values (so, for
3086+example, `yes`, `True`, and `15` cannot be used as field names).
30613087
30623088A document may contain multiple metadata blocks. The metadata fields will
30633089be combined through a *left-biased union*: if two metadata blocks attempt
@@ -3079,7 +3105,7 @@ when the field contains blank lines or block-level formatting:
30793105 author:
30803106 - Author One
30813107 - Author Two
3082− tags: [nothing, nothingness]
3108+ keywords: [nothing, nothingness]
30833109 abstract: |
30843110 This is the abstract.
30853111
@@ -3290,8 +3316,13 @@ them and they won't be treated as math delimiters.
32903316TeX math will be printed in all output formats. How it is rendered
32913317depends on the output format:
32923318
3293−Markdown, LaTeX, Emacs Org mode, ConTeXt, ZimWiki
3294− ~ It will appear verbatim between `$` characters.
3319+LaTeX
3320+ ~ It will appear verbatim surrounded by `\(...\)` (for inline
3321+ math) or `\[...\]` (for display math).
3322+
3323+Markdown, Emacs Org mode, ConTeXt, ZimWiki
3324+ ~ It will appear verbatim surrounded by `$...$` (for inline
3325+ math) or `$$...$$` (for display math).
32953326
32963327reStructuredText
32973328 ~ It will be rendered using an [interpreted text role `:math:`].
@@ -3350,8 +3381,14 @@ Markdown allows it, but it has been made an extension so that it can
33503381be disabled if desired.)
33513382
33523383The raw HTML is passed through unchanged in HTML, S5, Slidy, Slideous,
3353−DZSlides, EPUB, Markdown, Emacs Org mode, and Textile output, and suppressed
3354−in other formats.
3384+DZSlides, EPUB, Markdown, CommonMark, Emacs Org mode, and Textile
3385+output, and suppressed in other formats.
3386+
3387+In the CommonMark format, if `raw_html` is enabled, superscripts,
3388+subscripts, strikeouts and small capitals will be represented as HTML.
3389+Otherwise, plain-text fallbacks will be used. Note that even if
3390+`raw_html` is disabled, tables will be rendered with HTML syntax if
3391+they cannot use pipe syntax.
33553392
33563393#### Extension: `markdown_in_html_blocks` ####
33573394
@@ -3964,11 +4001,12 @@ whether or not they appear in the document, by using a wildcard:
39644001 @*
39654002 ...
39664003
3967−For LaTeX or PDF output, you can also use [`natbib`] or [`biblatex`]
3968−to render bibliography. In order to do so, specify bibliography files as
3969−outlined above, and add `--natbib` or `--biblatex` argument to `pandoc`
3970−invocation. Bear in mind that bibliography files have to be in respective
3971−format (either BibTeX or BibLaTeX).
4004+For LaTeX output, you can also use [`natbib`] or [`biblatex`] to
4005+render the bibliography. In order to do so, specify bibliography
4006+files as outlined above, and add `--natbib` or `--biblatex`
4007+argument to `pandoc` invocation. Bear in mind that bibliography
4008+files have to be in respective format (either BibTeX or
4009+BibLaTeX).
39724010
39734011For more information, see the [pandoc-citeproc man page].
39744012
@@ -3976,7 +4014,7 @@ For more information, see the [pandoc-citeproc man page].
39764014[Chicago Manual of Style]: http://chicagomanualofstyle.org
39774015[Citation Style Language]: http://citationstyles.org
39784016[Zotero Style Repository]: https://www.zotero.org/styles
3979−[finding and editing styles]: http://citationstyles.org/styles/
4017+[finding and editing styles]: https://citationstyles.org/authors/
39804018[CSL locale files]: https://github.com/citation-style-language/locales
39814019[pandoc-citeproc man page]: https://github.com/jgm/pandoc-citeproc/blob/master/man/pandoc-citeproc.1.md
39824020
@@ -4178,7 +4216,7 @@ individually disabled.
41784216Also, `raw_tex` only affects `gfm` output, not input.
41794217
41804218`gfm` (GitHub-Flavored Markdown)
4181−: `pipe_tables`, `raw_html`, `fenced_code_blocks`, `auto_identifiers`,
4219+: `pipe_tables`, `raw_html`, `fenced_code_blocks`, `gfm_auto_identifiers`,
41824220 `ascii_identifiers`, `backtick_code_blocks`, `autolink_bare_uris`,
41834221 `intraword_underscores`, `strikeout`, `hard_line_breaks`, `emoji`,
41844222 `shortcut_reference_links`, `angle_brackets_escapable`.
@@ -4438,28 +4476,32 @@ introducing the slide:
44384476All of the other frame attributes described in Section 8.1 of
44394477the [Beamer User's Guide] may also be used: `allowdisplaybreaks`,
44404478`allowframebreaks`, `b`, `c`, `t`, `environment`, `label`, `plain`,
4441−`shrink`.
4479+`shrink`, `standout`, `noframenumbering`.
44424480
4443−Background in reveal.js
4444−-----------------------
4481+Background in reveal.js and beamer
4482+----------------------------------
4483+
4484+Background images can be added to self-contained reveal.js slideshows and
4485+to beamer slideshows.
44454486
4446−Background images can be added to self-contained reveal.js slideshows.
4487+For the same image on every slide, use the configuration
4488+option `background-image` either in the YAML metadata block
4489+or as a command-line variable. (There are no other options in
4490+beamer and the rest of this section concerns reveal.js slideshows.)
44474491
4448−For the same image on every slide, use the reveal.js configuration
4449−option `parallaxBackgroundImage` either in the YAML metadata block
4450−or as a command-line variable. You can also set
4451−`parallaxBackgroundHorizontal` and `parallaxBackgroundVertical` the same
4452−way and must also set `parallaxBackgroundSize` to have your values
4453−take effect.
4492+For reveal.js, you can instead use the reveal.js-native option
4493+`parallaxBackgroundImage`. You can also set `parallaxBackgroundHorizontal`
4494+and `parallaxBackgroundVertical` the same way and must also set
4495+`parallaxBackgroundSize` to have your values take effect.
44544496
4455−To set an image for a particular slide, add
4497+To set an image for a particular reveal.js slide, add
44564498`{data-background-image="/path/to/image"}`
44574499to the first slide-level header on the slide (which may even be empty).
44584500
44594501In reveal.js's overview mode, the parallaxBackgroundImage will show up
44604502only on the first slide.
44614503
4462−Other background settings also work on individual slides, including
4504+Other reveal.js background settings also work on individual slides, including
44634505`data-background-size`, `data-background-repeat`, `data-background-color`,
44644506`data-transition`, and `data-transition-speed`.
44654507
@@ -4467,7 +4509,7 @@ See the [reveal.js
44674509documentation](https://github.com/hakimel/reveal.js#slide-backgrounds)
44684510for more details.
44694511
4470−For example:
4512+For example in reveal.js:
44714513
44724514```
44734515---
@@ -4590,11 +4632,52 @@ The following fields are recognized:
45904632[MARC relators]: http://loc.gov/marc/relators/relaterm.html
45914633[`spine` element]: http://idpf.org/epub/301/spec/epub-publications.html#sec-spine-elem
45924634
4635+The `epub:type` attribute
4636+-------------------------
4637+
4638+For `epub3` output, you can mark up the header that corresponds to an EPUB
4639+chapter using the [`epub:type` attribute][epub-type]. For example, to set
4640+the attribute to the value `prologue`, use this markdown:
4641+
4642+ # My chapter {epub:type=prologue}
4643+
4644+Which will result in:
4645+
4646+ <body epub:type="frontmatter">
4647+ <section epub:type="prologue">
4648+ <h1>My chapter</h1>
4649+
4650+Pandoc will output `<body epub:type="bodymatter">`, unless
4651+you use one of the following values, in which case either
4652+`frontmatter` or `backmatter` will be output.
4653+
4654+`epub:type` of first section `epub:type` of body
4655+---------------------------- ------------------
4656+prologue frontmatter
4657+abstract frontmatter
4658+acknowledgments frontmatter
4659+copyright-page frontmatter
4660+dedication frontmatter
4661+foreword frontmatter
4662+halftitle, frontmatter
4663+introduction frontmatter
4664+preface frontmatter
4665+seriespage frontmatter
4666+titlepage frontmatter
4667+afterword backmatter
4668+appendix backmatter
4669+colophon backmatter
4670+conclusion backmatter
4671+epigraph backmatter
4672+
4673+[epub-type]: http://www.idpf.org/epub/31/spec/epub-contentdocs.html#sec-epub-type-attribute
4674+
45934675Linked media
45944676------------
45954677
4596−By default, pandoc will download linked media (including audio and
4597−video) and include it in the EPUB container, yielding a completely
4678+By default, pandoc will download media referenced from any `<img>`, `<audio>`,
4679+`<video>` or `<source>` element present in the generated EPUB,
4680+and include it in the EPUB container, yielding a completely
45984681self-contained EPUB. If you want to link to external media resources
45994682instead, use raw HTML in your source and add `data-external="1"` to the tag
46004683with the `src` attribute. For example:
@@ -4610,9 +4693,9 @@ Syntax highlighting
46104693
46114694Pandoc will automatically highlight syntax in [fenced code blocks] that
46124695are marked with a language name. The Haskell library [skylighting] is
4613−used for highlighting, which works in HTML, Docx, Ms, and LaTeX/PDF output.
4614−To see a list of language names that pandoc will recognize, type
4615−`pandoc --list-highlight-languages`.
4696+used for highlighting. Currently highlighting is supported only for
4697+HTML, EPUB, Docx, Ms, and LaTeX/PDF output. To see a list of language names
4698+that pandoc will recognize, type `pandoc --list-highlight-languages`.
46164699
46174700The color scheme can be selected using the `--highlight-style` option.
46184701The default color scheme is `pygments`, which imitates the default color
@@ -4620,6 +4703,24 @@ scheme used by the Python library pygments (though pygments is not actually
46204703used to do the highlighting). To see a list of highlight styles,
46214704type `pandoc --list-highlight-styles`.
46224705
4706+If you are not satisfied with the predefined styles, you can
4707+use `--print-highlight-style` to generate a JSON `.theme` file which
4708+can be modified and used as the argument to `--highlight-style`. To
4709+get a JSON version of the `pygments` style, for example:
4710+
4711+ pandoc --print-highlight-style pygments > my.theme
4712+
4713+Then edit `my.theme` and use it like this:
4714+
4715+ pandoc --highlight-style my.theme
4716+
4717+If you are not satisfied with the built-in highlighting, or you
4718+want highlight a language that isn't supported, you can use the
4719+`--syntax-definition` option to load a [KDE-style XML syntax definition
4720+file](https://docs.kde.org/stable5/en/applications/katepart/highlight.html).
4721+Before writing your own, have a look at KDE's [repository of syntax
4722+definitions](https://github.com/KDE/syntax-highlighting/tree/master/data/syntax).
4723+
46234724To disable highlighting, use the `--no-highlight` option.
46244725
46254726[skylighting]: https://github.com/jgm/skylighting
Makefile+27−13
@@ -2,13 +2,23 @@ version?=$(shell grep '^[Vv]ersion:' pandoc.cabal | awk '{print $$2;}')
22pandoc=$(shell find dist -name pandoc -type f -exec ls -t {} \; | head -1)
33SOURCEFILES?=$(shell find pandoc.hs src test -name '*.hs')
44BRANCH?=master
5−RESOLVER=lts-10
6−GHCOPTS=-fdiagnostics-color=always -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances
5+RESOLVER=lts-12
6+GHCOPTS=-fdiagnostics-color=always -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Werror=missing-home-modules -Widentities -Wcpp-undef -fhide-source-paths -j +RTS -A32M -RTS
7+# Later:
8+# -Wpartial-fields (currently used in Powerpoint writer)
9+# -Wmissing-export-lists (currently some Odt modules violate this)
10+# -Wredundant-constraints (problematic if we want to support older base)
711WEBSITE=../../web/pandoc.org
812
913quick:
1014 stack install --resolver=$(RESOLVER) --ghc-options='$(GHCOPTS)' --install-ghc --flag 'pandoc:embed_data_files' --fast --test --test-arguments='-j4 --hide-successes $(TESTARGS)'
1115
16+quick-cabal:
17+ cabal new-build . --ghc-options '$(GHCOPTS)' --flags '+embed_data_files' --enable-tests --only-dependencies
18+ cabal new-build . --ghc-options '$(GHCOPTS)' --flags '+embed_data_files' --enable-tests --disable-optimization
19+ cabal new-install --symlink-bindir=$$HOME/.local/bin
20+ cabal new-run test-pandoc --ghc-options '$(GHCOPTS)' --flags '+embed_data_files' --disable-optimization -- --hide-successes $(TESTARGS)
21+
1222full:
1323 stack install --resolver=$(RESOLVER) --flag 'pandoc:embed_data_files' --flag 'pandoc:weigh-pandoc' --flag 'pandoc:trypandoc' --bench --no-run-benchmarks --test --test-arguments='-j4 --hide-successes' --ghc-options '-Wall -Werror -fno-warn-unused-do-bind -O0 -j4 $(GHCOPTS)'
1424
@@ -57,25 +67,29 @@ macospkg: man/pandoc.1
5767winpkg: pandoc-$(version)-windows-i386.msi pandoc-$(version)-windows-i386.zip pandoc-$(version)-windows-x86_64.msi pandoc-$(version)-windows-x86_64.zip
5868
5969pandoc-$(version)-windows-%.zip: pandoc-$(version)-windows-%.msi
60− -rm -rf wintmp && \
61− msiextract -C wintmp $< && \
62− cd wintmp/"Program Files" && \
63− mv Pandoc pandoc-$(version) && \
64− zip -r $@ pandoc-$(version) && \
65− mv $@ ../../ && \
66− cd ../.. && \
67− rm -rf wintmp
70+ ORIGDIR=`pwd` && \
71+ CONTAINER=$(basename $<) && \
72+ TEMPDIR=`mktemp -d` && \
73+ msiextract -C $$TEMPDIR/msi $< && \
74+ pushd $$TEMPDIR && \
75+ mkdir $$CONTAINER && \
76+ find msi -type f -exec cp {} $$CONTAINER/ \; && \
77+ zip -r $$ORIGDIR/$@ $$CONTAINER && \
78+ popd & \
79+ rm -rf $$TEMPDIR
6880
6981pandoc-$(version)-windows-%.msi: pandoc-windows-%.msi
7082 osslsigncode sign -pkcs12 ~/Private/ComodoCodeSigning.exp2019.p12 -in $< -i http://johnmacfarlane.net/ -t http://timestamp.comodoca.com/ -out $@ -askpass
7183 rm $<
7284
85+.INTERMEDIATE: pandoc-windows-i386.msi pandoc-windows-x86_64.msi
86+
7387pandoc-windows-i386.msi:
74− JOBID=$(shell curl 'https://ci.appveyor.com/api/projects/jgm/pandoc' | jq -r '.build.jobs[0].jobId') && \
88+ JOBID=$(shell curl 'https://ci.appveyor.com/api/projects/jgm/pandoc' | jq -r '.build.jobs[1].jobId') && \
7589 wget "https://ci.appveyor.com/api/buildjobs/$$JOBID/artifacts/windows%2F$@" -O $@
7690
7791pandoc-windows-x86_64.msi:
78− JOBID=$(shell curl 'https://ci.appveyor.com/api/projects/jgm/pandoc' | jq -r '.build.jobs[1].jobId') && \
92+ JOBID=$(shell curl 'https://ci.appveyor.com/api/projects/jgm/pandoc' | jq -r '.build.jobs[0].jobId') && \
7993 wget "https://ci.appveyor.com/api/buildjobs/$$JOBID/artifacts/windows%2F$@" -O $@
8094
8195man/pandoc.1: MANUAL.txt man/pandoc.1.template
@@ -109,7 +123,7 @@ pandoc-templates:
109123 popd
110124
111125trypandoc:
112− ssh -t macfarlane 'cd src/pandoc && git pull && ~/.local/bin/stack install --flag pandoc:trypandoc --flag pandoc:embed_data_files && cd trypandoc && sudo make install'
126+ ssh -t macfarlane 'cd src/pandoc && git pull && stack install --flag pandoc:trypandoc --flag pandoc:embed_data_files && cd trypandoc && sudo make install'
113127
114128update-website:
115129 make -C $(WEBSITE) update
README.md+6−6
@@ -38,9 +38,9 @@ library. It can convert *from*
3838 e-book)
3939 - `gfm` ([GitHub-Flavored
4040 Markdown](https://help.github.com/articles/github-flavored-markdown/)),
41− or `markdown_github`, which provides deprecated and less accurate
42− support for Github-Flavored Markdown; please use `gfm` instead,
43− unless you need to use extensions other than `smart`.
41+ or the deprecated and less accurate `markdown_github`; use
42+ [`markdown_github`](#markdown-variants) only if you need extensions
43+ not supported in [`gfm`](#markdown-variants).
4444 - `haddock` ([Haddock
4545 markup](https://www.haskell.org/haddock/doc/html/ch03s08.html))
4646 - `html` ([HTML](http://www.w3.org/html/))
@@ -92,9 +92,9 @@ It can convert *to*
9292 e-book)
9393 - `gfm` ([GitHub-Flavored
9494 Markdown](https://help.github.com/articles/github-flavored-markdown/)),
95− or `markdown_github`, which provides deprecated and less accurate
96− support for Github-Flavored Markdown; please use `gfm` instead,
97− unless you use extensions that do not work with `gfm`.
95+ or the deprecated and less accurate `markdown_github`; use
96+ [`markdown_github`](#markdown-variants) only if you need extensions
97+ not supported in [`gfm`](#markdown-variants).
9898 - `haddock` ([Haddock
9999 markup](https://www.haskell.org/haddock/doc/html/ch03s08.html))
100100 - `html` or `html5` ([HTML](http://www.w3.org/html/), i.e.
RELEASE-CHECKLIST+1−2
@@ -1,8 +1,7 @@
11[ ] make README.md and commit if needed
22[ ] make man/pandoc.1 and commit if needed
33[ ] Finalize changelog
4− git log --pretty='format:%n%n* %s (%an)%n%b%n%h%n' \
5− --reverse --name-only LASTRELEASE..HEAD > LOG
4+ tools/changelog-helper.sh
65[ ] make packages
76[ ] make update-website
87[ ] make trypandoc
RELEASE-CHECKLIST.mddeleted−27
@@ -1,27 +0,0 @@
1−- [ ] Test, on Linux, Windows, macOS (inc. website demos)
2−
3−- [ ] Finalize changelog:
4− `git log --pretty='format:%n%n* %s (%an)%n%b%n%h%n' --reverse --name-only 1.17.0.3..HEAD > LOG`
5−
6−- [ ] `make man/pandoc.1` and commit if needed
7−
8−- [ ] Tag release in git
9−
10−- [ ] Tag templates
11−
12−- [ ] Generate Windows package (`make winpkg`)
13−
14−- [ ] Generate macOS package (`make macospkg`)
15−
16−- [ ] Generate Ubuntu/Debian deb package (`make debpkg`)
17−
18−- [ ] Add release on github (use `make changes_github` and upload files)
19−
20−- [ ] Upload to HackageDB
21−
22−- [ ] Update website (`make update`), including short description of changes (`make changes`)
23−
24−- [ ] on server, `cabal install --enable-tests -ftrypandoc`
25− and then `cd trypandoc; sudo make install`
26−
27−- [ ] Announce on pandoc-announce, pandoc-discuss
appveyor.yml+48−32
@@ -3,18 +3,31 @@ clone_folder: "c:\\pandoc"
33environment:
44 global:
55 WIXBIN: "c:\\Program Files (x86)\\WiX Toolset v3.11\\bin"
6− STACK_YAML: "c:\\pandoc\\stack.yaml"
7− STACK_BUILD_OPTS: "-j1 --no-terminal --test --local-bin-path=.\\windows"
6+ CABAL_STORE: "C:\\cs"
7+ CABAL_PACKAGE_DB: "%CABAL_STORE%\\ghc-%GHC_MINOR_VERSION%\\package.db"
8+ # Override the temp directory to avoid sed escaping issues
9+ # See https://github.com/haskell/cabal/issues/5386
10+ TMP: "c:\\tmp"
811 # see #4201, https://github.com/haskell-tools/haskell-tools/issues/277
912 matrix:
10− - STACK_VERSION: "windows-i386"
11− STACK_ROOT: "c:\\sr32"
12− STACK: "%STACK_ROOT%\\stack.exe"
13− STACK_FLAGS: "--flag=hslua:lua_32bits"
14− - STACK_VERSION: "windows-x86_64"
15− STACK_ROOT: "c:\\sr64"
16− STACK: "%STACK_ROOT%\\stack.exe"
17− STACK_FLAGS: ""
13+ - OSARCH: "windows-x86_64"
14+ GHC_VERSION: "8.6.1.1"
15+ GHC_MINOR_VERSION: "8.6.1"
16+ GHC: "C:\\ProgramData\\chocolatey\\lib\\ghc\\tools\\ghc-%GHC_MINOR_VERSION%\\bin\\ghc.exe"
17+ CABAL_VERSION: "2.4.0.0"
18+ CABAL_OPTS: "-fembed_data_files -fbibutils"
19+ GHC_OPTS: "-fhide-source-paths"
20+ ARCH: "x64"
21+ CHOCO_OPTS: ""
22+ - OSARCH: "windows-i386"
23+ GHC_VERSION: "8.6.1.1"
24+ GHC_MINOR_VERSION: "8.6.1"
25+ GHC: "C:\\ProgramData\\chocolatey\\lib\\ghc\\tools\\ghc-%GHC_MINOR_VERSION%\\bin\\ghc.exe"
26+ CABAL_VERSION: "2.4.0.0"
27+ CABAL_OPTS: "-flua_32bits -fembed_data_files -fbibutils"
28+ GHC_OPTS: "-fhide-source-paths"
29+ ARCH: "x86"
30+ CHOCO_OPTS: "--x86"
1831
1932skip_commits:
2033 files:
@@ -30,50 +43,53 @@ matrix:
3043 fast_finish: true
3144
3245cache:
33− - "%STACK_ROOT%"
34− - "%WIXBIN%"
35− # This is where stack install ghc by default, but we don't
36− # cache it because it's too large:
37− # - "c:\\Users\\appveyor\\AppData\\Local\\Programs\\stack"
46+ - '%CABAL_STORE%'
3847
3948# Note: to reset build cache, do the following in JavaScript
4049# console on appveyor:
4150# $.ajax({ url: 'https://ci.appveyor.com/api/projects/jgm/pandoc/buildcache', type: 'DELETE'})
42−# We don't do a normal C build, but build in test_script via stack
51+
52+# We don't do a normal C build, but build in test_script
4353build: off
4454
4555install:
46− - '"%WIXBIN%"\candle -? || choco install wixtoolset'
47− - |
48− %STACK% --version || curl -ostack.zip -L --insecure http://www.stackage.org/stack/%STACK_VERSION% && 7z e stack.zip -o"%STACK_ROOT%" stack.exe
56+ - choco install wixtoolset --version 3.11.1 %CHOCO_OPTS%
57+ - choco install ghc --version %GHC_VERSION% --ignore-dependencies %CHOCO_OPTS%
58+ - choco install cabal --version %CABAL_VERSION% --ignore-dependencies %CHOCO_OPTS%
4959
5060# before_test:
5161
5262test_script:
53− # The ugly echo "" hack is to avoid complaints about 0 being an invalid file
54− # descriptor
55− - |
56− %STACK% setup > nul
57− %STACK% path
58− echo "" | %STACK% clean
59− echo "" | %STACK% install %STACK_BUILD_OPTS% pandoc pandoc-citeproc %STACK_FLAGS%
63+ # Note: we manually create cabal store, because of a cabal bug:
64+ # see https://github.com/haskell/cabal/issues/5516
65+ - if not exist "%CABAL_PACKAGE_DB%" ( mkdir "%CABAL_PACKAGE_DB%" )
66+ - cabal --store-dir="%CABAL_STORE%" --version
67+ - cabal --store-dir="%CABAL_STORE%" new-update
68+ - cabal --store-dir="%CABAL_STORE%" new-configure -w %GHC% --enable-tests %CABAL_OPTS% --ghc-options="%GHC_OPTS%" . pandoc-citeproc
69+ - cabal --store-dir="%CABAL_STORE%" new-build . pandoc-citeproc
70+ - cabal --store-dir="%CABAL_STORE%" new-test . pandoc-citeproc
71+ - forfiles /P .\dist-newstyle /M pandoc*.exe /S /C "cmd /C copy @path C:\pandoc\windows"
6072
6173after_test:
62− # .\ in the stack commandline seems to be .\windows\ (where the stack-appveyor.yaml is)
74+ # create msi and zip artifacts
6375 - cd windows
6476 - .\pandoc.exe -s --toc ..\MANUAL.txt -o MANUAL.html
6577 - .\pandoc.exe -s ..\COPYING.md -o COPYING.rtf
6678 - copy ..\COPYRIGHT COPYRIGHT.txt
67− - 7z a "pandoc-%STACK_VERSION%.zip" pandoc.exe pandoc-citeproc.exe MANUAL.html COPYING.rtf
79+ - 7z a "pandoc-%OSARCH%.zip" pandoc.exe pandoc-citeproc.exe MANUAL.html COPYING.rtf
6880 - |
6981 set VERSION=
7082 for /f "tokens=1-2 delims= " %%a in ('.\pandoc.exe --version') do ( if not defined VERSION set "VERSION=%%b" )
7183 echo %VERSION%
72− "%WIXBIN%\\candle" -dVERSION=%VERSION% -dBINPATH=. *.wxs -out wixobj\
73− "%WIXBIN%\\light" -sw1076 -ext WixUIExtension -ext WixUtilExtension -cultures:en-us -loc Pandoc-en-us.wxl -out "pandoc-%STACK_VERSION%.msi" wixobj\*.wixobj
84+ "%WIXBIN%"\candle -arch %ARCH% -dVERSION=%VERSION% -dBINPATH=. *.wxs -out wixobj\
85+ "%WIXBIN%"\light -sw1076 -ext WixUIExtension -ext WixUtilExtension -cultures:en-us -loc Pandoc-en-us.wxl -out "pandoc-%OSARCH%.msi" wixobj\*.wixobj
86+
87+# for debugging
88+# on_finish:
89+# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
7490
7591artifacts:
76− - path: 'windows\pandoc-%STACK_VERSION%.zip'
92+ - path: 'windows\pandoc-%OSARCH%.zip'
7793 name: exe
78− - path: 'windows\pandoc-%STACK_VERSION%.msi'
94+ - path: 'windows\pandoc-%OSARCH%.msi'
7995 name: msi
cabal.projectnew file+7
@@ -0,0 +1,7 @@
1+packages: pandoc.cabal
2+
3+source-repository-package
4+ type: git
5+ location: https://github.com/jgm/pandoc-citeproc
6+
7+allow-newer: haddock-library:base
changelog+679−33
@@ -1,3 +1,644 @@
1+pandoc (2.3.1)
2+
3+ * RST reader:
4+
5+ + Parse RST inlines containing newlines (#4912, Francesco Occhipinti).
6+ This eliminates a regression introduced after pandoc 2.1.1, which
7+ caused inline constructions containing newlines not to be recognized.
8+ + Fix bug with internal link targets (#4919). They were gobbling up
9+ indented content underneath.
10+
11+ * Markdown reader: distinguish autolinks in the AST. With this change,
12+ autolinks are parsed as Links with the `uri` class. (The same is true
13+ for bare links, if the `autolink_bare_uris` extension is enabled.)
14+ Email autolinks are parsed as Links with the `email` class. This
15+ allows the distinction to be represented in the AST.
16+
17+ * Org reader:
18+
19+ + Force inline code blocks to honor export options (Brian Leung).
20+ + Parse empty argument array in inline src blocks (Brian Leung).
21+
22+ * Muse reader (Alexander Krotov):
23+
24+ + Added additional tests.
25+ + Do not allow code markup to be followed by digit.
26+ + Remove heading level limit.
27+ + Simplify `<literal>` tag parsers
28+ + Parse Text instead of String. Benchmark shows 7% improvement.
29+ + Get rid of HTML parser dependency.
30+ + Various code improvements.
31+
32+ * ConTeXt writer: change `\` to `/` in Windows image paths (#4918).
33+ We do this in the LaTeX writer, and it avoids problems.
34+ Note that `/` works as a LaTeX path separator on Windows.
35+
36+ * LaTeX writer:
37+
38+ + Add support for multiprenote and multipostnote arguments
39+ with `--biblatex` (Brian Leung, #4930). The multiprenotes occur before
40+ the first prefix of a multicite, and the multipostnotes follow the
41+ last suffix.
42+ + Fix a use of `last` that might take empty list. If you ran with
43+ `--biblatex` and have an empty document (metadata but no blocks),
44+ pandoc would previously raise an error because of the use of
45+ `last` on an empty list.
46+
47+ * RTF writer: Fix build failure with ghc-8.6.1 caused by missing
48+ MonadFail instance (Jonas Scholl).
49+
50+ * ODT Writer: Improve table header row style handling (Nils Carlson).
51+ This changes the way styles for cells in the header row
52+ and normal rows are handled in ODT tables.
53+ Previously a new (but identical) style was generated for
54+ every table, specifying the style of the cells within the table.
55+ After this change there are two style definitions for table cells,
56+ one for the cells in the header row, one for all other cells.
57+ This doesn't change the actual styles, but makes post-processing
58+ changes to the table styles much simpler as it is no longer
59+ necessary to introduce new styles for header rows and there are
60+ now only two styles where there was previously one per table.
61+
62+ * HTML writer:
63+
64+ + Don't add `uri` class to presumed autolinks. Formerly the `uri`
65+ class was added to autolinks by the HTML writer, but it had to
66+ guess what was an autolink and could not distinguish
67+ `[http://example.com](http://example.com)` from
68+ `<http://example.com>`. It also incorrectly recognized
69+ `[pandoc](pandoc)` as an autolink. Now the HTML writer
70+ simply passes through the `uri` attribute if it is present,
71+ but does not add anything.
72+ + Avoid adding extra section nestings for revealjs.
73+ Previously revealjs title slides at level (slidelevel - 1)
74+ were nested under an extra section element, even when
75+ the section contained no additional (vertical) content.
76+ That caused problems for some transition effects.
77+ + Omit unknown attributes in EPUB2 output. For example,
78+ `epub:type` attributes should not be passed through,
79+ or the epub produced will not validate.
80+
81+ * JATS writer: remove 'role' attribute on 'bold' and 'sc' elements (#4937).
82+ The JATS spec does not allow these.
83+
84+ * Textile writer: don't represent `uri` class explicitly
85+ for autolinks (#4913).
86+
87+ * Lua filters (Albert Krewinkel):
88+
89+ + Cleanup filter execution code.
90+ + Better error on test failure.
91+
92+ * HTML, Muse reader tests: reduce time taken by round-trip test.
93+
94+ * Added cabal.project.
95+
96+ * MANUAL: `epub:type` is only useful for epub3 (Maura Bieg).
97+
98+ * Use hslua v1.0.0 (Albert Krewinkel).
99+
100+ * Fix `translations/ru` to use modern Russian orthography
101+ (Ivan Trubach).
102+
103+ * Build Windows binary using ghc 8.6.1 and cabal new-build. This
104+ fixes issues with segfaults in the 32-bit Windows binaries (#4283).
105+
106+pandoc (2.3)
107+
108+ * Add `--metadata-file` option (Mauro Bieg, #1960), which allows
109+ users to specify metadata in a YAML file, regardless of the
110+ input format (#1960).
111+
112+ * Text.Pandoc.Writers.Shared: export `isDisplayMath` (API change).
113+
114+ * Text.Pandoc.Readers.Markdown: export `yamlToMeta` (API change,
115+ Mauro Bieg).
116+
117+ * Text.Pandoc.Readers.LaTeX.Types:
118+
119+ + New type `ArgSpec` (API change).
120+ + Second parameter of `Macro` constructor is now `[ArgSpec]` instead of
121+ `Int` (API change).
122+
123+ * Markdown reader:
124+
125+ + Use `tex` instead of `latex` for raw tex-ish content. We can't
126+ always tell if it's LaTeX, ConTeXt, or plain TeX. Better just to
127+ use `tex` always. Note that if `context` or `latex` specifically
128+ is desired, you can still force that in a markdown document by
129+ using the raw attribute. Note that this change may affect some
130+ filters, if they assume that raw tex parsed by the Markdown reader
131+ will be RawBlock (Format `latex`). In most cases it should be
132+ trivial to modify the filters to accept `tex` as well.
133+ + Refactor and reorganize YAML code (Mauro Bieg).
134+ + Make `example_lists` work for interrupted lists
135+ without `startnum` (#4908).
136+
137+ * HTML reader:
138+
139+ + Parse `<script type="math/tex` tags as math (#4877).
140+ These are used by MathJax in some configurations.
141+ + Extract spaces inside links instead of trimming them
142+ (Alexander Krotov, #4845).
143+ + Added round-trip tests (Alexander Krotov).
144+ + Make parsing sensitive to the `raw_tex` extension (#1126). This now
145+ allows raw LaTeX environments, `\ref`, and `\eqref` to be parsed
146+ (which is helpful for translation HTML documents using MathJaX).
147+
148+ * Org reader (Albert Krewinkel):
149+
150+ + Respect export option `p` for planning info. Inclusion of planning info
151+ (`*DEADLINE*`, `*SCHEDULED*`, and `*CLOSED*`) can be controlled via the
152+ `p` export option: setting the option to `t` will add all planning
153+ information in a *Plain* block below the respective headline.
154+ + Org reader internals: don't rely on RecordWildCards and ViewPatterns
155+ ghc extensions.
156+ + Strip planning info from output. Planning info is parsed, but not
157+ included in the output (as is the default with Emacs Org-mode, #4867).
158+
159+ * LaTeX reader:
160+
161+ + Split some general-purpose definitions into a separate, unexported
162+ module, Text.Pandoc.Readers.LaTeX.Parsing. This is to avoid
163+ out-of-memory errors compiling the LaTeX reader.
164+ + Handle parameter patterns for `\def` (#4768, #4771).
165+ For example: `\def\foo#1[#2]{#1 and #2}`.
166+ + Allow `%` characters in URLs. This affects `\href` and `\url` (#4832).
167+ + Fixed parsing of `\texorpdfstring`. We were returning the wrong
168+ argument as the content.
169+ + Support `blockcquote`, `foreignblockquote`, `foreigncblockquote`,
170+ `hyphenblockquote`, `hyphencblockquote`, `enquote*`, `foreignquote`,
171+ `hyphenquote` from `csquotes` (#4848). Note that `foreignquote`
172+ will be parsed as a regular Quoted inline (not using the quotes
173+ appropriate to the foreign language).
174+ + Support more text-mode accents (#4652). Add support for `\|`, `\b`, `\G`,
175+ `\h`, `\d`, `\f`, `\r`, `\t`, `\U`, `\i`, `\j`, `\newtie`,
176+ `\textcircled`. Also fall back to combining characters when composed
177+ characters are not available.
178+ + Resolve `\ref` for figure numbers.
179+ + Support `mintinline` (#4365, Marc Schreiber).
180+ + Fix siunitx unit commands so they are only recognized in
181+ siunitx contexts (#4842). For example, `\l` outside of an
182+ siunitx context should be l-slash, not l (for liter).
183+ + Fix double `unnumbered` class (#4838). The `unnumbered` class
184+ was being included twice for starred sections.
185+
186+ * RST reader: Don't skip link definitions after comments (#4860).
187+
188+ * Muse reader (Alexander Krotov):
189+
190+ + Close the `</quote>` in indented tag test.
191+ There is already a separate test for unclosed `</quote>`.
192+ + Autonumber sections in the correct order. Parsing now stops
193+ at each section header to ensure the header is registered before
194+ parsing of the next section starts.
195+ + Move duplicate code into `headingStart` function.
196+ + Allow newline after opening `*` or `**`.
197+ + Don't allow digits after closing marker in lightweight markup
198+ This change makes reader more compatible with Emacs Muse.
199+ + Parse `<verse>` tag in one pass instead of using
200+ `parseFromString`. This change makes it possible to have
201+ verbatim `</verse>` tag inside verse.
202+
203+ * ODT reader: deal gracefully with missing `<office:font-face-decls/>`
204+ (#4336). This allows pandoc to parse ODT document produced by KDE's
205+ Calligra.
206+
207+ * Muse writer (Alexander Krotov):
208+
209+ + Output headers without asterisks if not on the top level.
210+ + Never wrap definition list terms.
211+ + Set `envInsideBlock = True` when rendering notes.
212+ + Use `""` instead of `[]` for empty String.
213+ + Check for whitespace in the beginning and end of Str's.
214+ + Escape `-`, `;` and `>` in the beginning of strings.
215+ + Escape list markers in the beginning of notes.
216+ + Normalize inline list before testing if tags should be used.
217+ + Use tags instead of lightweight markup for empty strings.
218+ + Use lightweight markup when possible.
219+ + Escape empty strings. This guarantees that `conditionalEscapeString`
220+ never returns empty string.
221+ + Wrap conditionalEscapeString result into `Muse` type.
222+ This removes the need to pass `envInsideLinkDescription` to it.
223+ + Separate `shouldEscapeString` function.
224+ + Simplify inline list rendering.
225+ + Replace newlines in strings with spaces.
226+
227+ * Docx writer:
228+
229+ + Add MetaString case for abstract, subtitle (#4900, Mauro Bieg).
230+ + Properly handle display math in spans (#4826). This isn't a
231+ complete solution, since other nestings of display math may still
232+ cause problems, but it should work for what is by far the most
233+ common case.
234+
235+ * HTML writer:
236+
237+ + Always output `<dt>` element, even if it is empty (#4883,
238+ Alexander Krotov).
239+ + Don't prefix `epub:` attributes with `data-`.
240+
241+ * Org writer: Don't escape literal `_`, `^` (#4882). Org doesn't
242+ recognize these escapes.
243+
244+ * ODT writer: Fix percentage image scaling (#4881, Nils Carlson).
245+ Image scaling was broken when a width was set to a percentage.
246+
247+ * EPUB writer: set `epub:type` on body element in each chapter,
248+ depending on the `epub:type` of the first section (#4823). This
249+ only affects epub3. See
250+ http://www.idpf.org/epub/profiles/edu/structure/#h.l0bzsloklt10
251+
252+ * FB2 writer: put `coverpage` element between title and date rather than in
253+ `document-info` element (#4854).
254+
255+ * Markdown writer: Escape `~` if strikeout extension enabled (#4840).
256+
257+ * Haddock writer: Use proper format for latex math in haddock (#4571, Joe
258+ Hermaszewski). Inline math in `\(..\)`, display math in `\[..\]`,
259+ tex is now used. Previously we'd "fake it with unicode" and fall
260+ back to tex when that didn't work. But newer haddock versions
261+ support latex math.
262+
263+ * TEI writer:
264+
265+ + Ensure that title element is always present, even if empty (#4839).
266+ + Put author tags in the template, rather than adding them in
267+ the writer (#4839).
268+
269+ * LaTeX writer/template: be sensitive to `filecolor` variable (#4822).
270+ `linkcolor` only affects internal links, and `urlcolor` only
271+ affects linked URLs. For external links, the option to use is
272+ `filecolor`.
273+
274+ * ConTeXt writer: output raw `tex` blocks as well as `context` (#969).
275+
276+ * RST writer:
277+
278+ + Use `.. raw:: latex` for `tex` content.
279+ + Use `.. container` for generic Divs, instead of raw HTML.
280+ + Render Divs with admonition classes as admonitions (#4833).
281+ Also omit Div with class `admonition-title`. These are generated
282+ by the RST reader and should be omitted on round-trip.
283+
284+ * Text.Pandoc.PDF: fix message printed when rsvg-convert is not available
285+ (#4855, Antonio Terceiro).
286+
287+ * HTML5 template: add the `title-block-header` identifier to the
288+ `header` element, to make it easier to style precisely (#4767,
289+ J. B. Rainsberger).
290+
291+ * OpenDocument template: Remove unnecessary indenting of TOC title (#4798,
292+ José de Mattos Neto).
293+
294+ * latex template: Add support for $toc-title$ to LaTeX (and PDF)
295+ (#4853, Wandmalfarbe).
296+
297+ * TEI template: improve `publicationStmt`. Add support for
298+ `publisher`, `address`, `pubPlace`, and `date` variables.
299+
300+ * beamer template: Support "toc-title" (#4835, Cyril Roelandt).
301+
302+ * Text.Pandoc.Extensions: Fix haddock on `Ext_footnotes` (Chris Martin).
303+
304+ * Lua: cleanup Lua utils, remove unused functions (Albert Krewinkel).
305+
306+ * MANUAL.txt:
307+
308+ + Clarify that `--biblatex/--natbib` don't work directly for PDF
309+ (#4904).
310+ + Document `epub:type` attribute (Mauro Bieg, #4901)
311+ + Clarify when `--resource-path` has an effect.
312+ + More detail on customization in syntax highlighting section.
313+ + Document encoding issue with `--listings` (#4871, Damien Clochard).
314+ + Remove docs on removed `--katex-stylesheet` (Mauro Bieg, #4862).
315+ + Use https for context wiki links (#4910).
316+
317+ * CONTRIBUTING.md:
318+
319+ + Link to lua-filters repository (#4874).
320+ + Fix mistake in REPL instructions for stack. (#4849, Brian Leung).
321+
322+ * lua-filters.md: add links to filters, and to lua-filters repository
323+ (#4874).
324+
325+ * INSTALL.md:
326+
327+ + Indicate that cabal >= 2.0 is needed.
328+ + Added chocolatey installation method (#4844, Miodrag Milić).
329+
330+ * Travis: exclude round-trip tests, except for nightly test which can fail.
331+
332+ * Use latest texmath, pandoc-citeproc.
333+
334+ * Use a patched version of foundation until
335+ https://github.com/haskell-foundation/foundation/pull/503
336+ is fixed.
337+
338+ * Clean up appveyor build and Windows package creation.
339+ We now use 64-bit stack and ghc 8.4.3, lts-12 for the 64-bit build. The
340+ WiX-based msi is now 64-bit for 64-bit builds (fixing #4795).
341+
342+ * Remove obsolete RELEASE-CHECKLIST.md.
343+
344+ * Added additional compiler warnings in Makefile and CI builds.
345+
346+pandoc (2.2.3.2)
347+
348+ * Markdown reader: Properly handle boolean values in YAML metadata (#4819).
349+ This fixes a regression in 2.2.3, which cause boolean values to
350+ be parsed as MetaInlines instead of MetaBool.
351+
352+ We here record another undocumented (but desirable) change in 2.2.3:
353+ numerical metadata fields are now parsed as MetaInlines rather than
354+ MetaString.
355+
356+pandoc (2.2.3.1)
357+
358+ * Markdown reader: Fix parsing of embedded mappings in YAML metadata
359+ (#4817). This fixes a regression in 2.2.3 which caused embedded
360+ mappings (e.g. mappings in sequences) not to work in YAML metadata.
361+
362+pandoc (2.2.3)
363+
364+ * RST reader: improve parsing of inline interpreted text roles (#4811).
365+
366+ + Use a Span with class "title-reference" for the default
367+ title-reference role.
368+ + Use `B.text` to split up contents into `Space`s, `SoftBreak`s,
369+ and `Str`s for `title-reference`.
370+ + Use Code with class "interpreted-text" instead of Span and Str for
371+ unknown roles. (The RST writer has also been modified to round-trip
372+ this properly.)
373+ + Disallow blank lines in interpreted text.
374+ + Backslash-escape now works in interpreted text.
375+ + Backticks followed by alphanumerics no longer end interpreted text.
376+ + Remove support for nested inlines (Francesco Occhipinti).
377+ RST does not allow nested emphasis, links, or other inline
378+ constructs. This fixes several bugs (#4581, #4561, #4792).
379+
380+ * Org reader: fix parsers relying on `parseFromString` (#4784, Albert
381+ Krewinkel). Emphasis was not parsed when it followed directly after
382+ some block types (e.g., lists).
383+
384+ * Markdown reader: Allow unquoted numbers and booleans as YAML mapping
385+ keys. Previously in 2.2.2 you could not do
386+ ```
387+ ---
388+ 0: bar
389+ ...
390+ ```
391+ but only
392+ ```
393+ ---
394+ '0': bar
395+ ...
396+ ```
397+ With this change, both forms work.
398+
399+ * DocBook reader: metadata handling improvements.
400+ Now we properly parse title and subtitle elements that are direct
401+ children of book and article (as well as children of bookinfo,
402+ articleinfo, or info). We also now use the `subtitle` metadata
403+ field for subtitles, rather than tacking the subtitle on to the
404+ title.
405+
406+ * RST writer:
407+
408+ + Allow images to be directly nested within links (#4810, Francesco
409+ Occhipinti).
410+ + Use `titleblock` instead of `title` variable for title block (#4803,
411+ Francesco Occhipinti). `titleblock` contains a properly formatted
412+ title and subtitle (using top-level headers). `title` and
413+ `subtitle` variables are still available and just contain the
414+ title and subtitle text. Note that this change will require an
415+ update to custom rst templates.
416+ + Render Code with class "interpreted-text" as interpreted text role.
417+
418+ * MediaWiki writer: Avoid extra blank line in tables with empty cells
419+ (#4794). Note that the old output is semantically identical, but the
420+ new output looks better.
421+
422+ * Lua Utils module: add function `blocks_to_inlines` (#4799, Albert
423+ Krewinkel). Exposes a function converting which flattenes a list of
424+ blocks into a list of inlines. An example use case would be the
425+ conversion of Note elements into other inlines.
426+
427+ * RST template: use `titleblock` instead of `title`. Users of
428+ custom RST templates will want to update this.
429+
430+ * LaTeX template: Moved some beamer code in default.latex template.
431+ This change allows beamer themes to change the template and font (as
432+ Metropolis does) (#4450).
433+
434+ * Better error message on `-t pdf -o out.pdf` (#1155, Mauro Bieg).
435+
436+ * Added test case for #4669 to repository.
437+
438+ * INSTALL.md: Fix broken link for cabal-install (#4806, ChanHoHo).
439+
440+ * MANUAL.txt:
441+
442+ + Add beamer info for slide backgrounds (#4802, John Muccigrosso).
443+ + Clarify when `csquotes` is used in LaTeX writer (#4514).
444+ + Add `commonmark` to list of output formats where `raw_tex` has an
445+ effect (see #4527).
446+
447+
448+pandoc (2.2.2.1)
449+
450+ * Fix regression finding templates in user data directory (#4777).
451+ Under version 2.2.1 and prior pandoc found latex templates in the
452+ templates directory under the data directory, but this broke in 2.2.2.
453+
454+ * Fix for bug in parsing `\input` in `rawLaTeXBlock` and
455+ `rawLaTeXInline` (#4781). (This primarily affects the markdown
456+ reader, and other readers that accept raw tex.)
457+ Starting in 2.2.2, everything after an `\input` (or `\include`)
458+ in a markdown file would be parsed as raw LaTeX.
459+
460+ * MANUAL:
461+
462+ + Clarify `gfm` vs `markdown_github` (#4783, Mauro Bieg).
463+ * Use `keywords` instead of `tags` in YAML metadata example (#4779).
464+ Unlike `tags`, `keywords` is used in some of the writers
465+ and default templates.
466+
467+ * Add missing `rollingLinks` option to revealjs template (#4778,
468+ Igor Khorlo).
469+
470+pandoc (2.2.2)
471+
472+ * Use HsYAML instead of yaml for translations and YAML metadata (#4747).
473+ yaml wraps a C library; HsYAML is pure Haskell. Advances #4535.
474+
475+ Note: HsYAML implements YAML 1.2, in which the valid true
476+ values are `true`, `True`, `TRUE`. This means a change in
477+ the semantics of YAML metadata that could affect users:
478+ `y`, `yes`, and `on` no longer count as true values.
479+
480+ * Fix regression: make `--pdf-engine` work with full paths (#4681, Mauro
481+ Bieg).
482+
483+ * CommonMark reader: Handle `ascii_identifiers` extension (#4742,
484+ Anders Waldenborg). Non-ascii characters were not stripped from
485+ identifiers even if the `ascii_identifiers` extension was
486+ enabled (which is is by default for gfm).
487+
488+ * TikiWiki reader: Improve list parsing (#4722, Mauro Bieg).
489+ Remove trailing Space from list items. Parse lists that have no space
490+ after marker.
491+
492+ * LaTeX reader:
493+
494+ + Treat `lilypond` as a verbatim environment (#4725).
495+ + Parse figure label into Image id (#4700, Mauro Bieg).
496+ + Beamer: Allow "noframenumbering" option (#4696, Raymond Ehlers).
497+ + Allow spaces around `\graphicspath` arguments (#4698).
498+ + Handle includes without surrounding blanklines (#4553).
499+ In addition, `\input` can now be used in an inline context,
500+ e.g. to provide part of a paragraph, as it can in LaTeX.
501+ + In `rawLaTeXBlock`, handle macros that resolve to a
502+ `\begin` or `\end` (#4667).
503+ + In `rawLaTeXBlock`, don't expand macros in macro definitions (#4653).
504+ Note that this only affected LaTeX in markdown.
505+ + Tighten up reading of beamer overlay specifications (#4669).
506+ Ideally we'd turn these on only when reading beamer, but currently
507+ beamer is not distinguished from latex as an input format.
508+ This commit also activates parsing of overlay specifications
509+ after commands in general (e.g. `\item`), since they can occur
510+ in many contexts in beamer.
511+ + Parse more siunitx unit commands (#4296, #4773).
512+ + Be more forgiving in key/value option parsing (#4761).
513+
514+ * Markdown reader:
515+
516+ + Allow empty code spans, e.g. `` ` ` ``.
517+ + Emojis are now wrapped in Spans with class `emoji` and
518+ attribute `data-emoji` (Anders Waldenborg, #4743).
519+ This allows the writer to handle them in a special way
520+ (e.g. using a special font, or just rendering the
521+ emoji name).
522+
523+ * Muse reader (Alexander Krotov, except where indicated):
524+
525+ + Get rid of non-exhaustive pattern match warning (Mauro Bieg).
526+ + Add support for floating images.
527+ + Add support for images with specified width.
528+ + Parse image URLs without "guard" and "takeExtension".
529+ + Split link and image parsing into separate functions.
530+ + Parse links starting with "URL:" explicitly instead of trying to strip
531+ "URL:" prefix after parsing.
532+
533+ * Texinfo writer: Use `@sup` and `@sub` instead of custom macros (#4728,
534+ Alexander Krotov).
535+
536+ * Markdown writer: Preserve `implicit_figures` with attributes, even if
537+ `implicit_attributes` is not set, by rendering in raw HTML (#4677).
538+
539+ * Markdown and commonmark/github writers now respect the `emoji`
540+ extension. So, `-f markdown+emoji -t markdown+emoji` now leaves
541+ `:smile:` as `:smile:` rather than converting it to a smile
542+ character.
543+
544+ * Docx writer: Be sensitive to `toc` in YAML metadata (#4645).
545+
546+ * ODT/OpenDocument writer: Make internal links work (#4358).
547+ This adds proper bookmarks to the headers with non-null IDs.
548+
549+ * EPUB writer: Properly escape pagetitle. Previously we weren't
550+ escaping `&` and other XML characters in the pagetitle, so a title
551+ containing a `&` would be invalid.
552+
553+ * AsciiDoc Writer: Eescape square brackets at start of line (#4545,
554+ Mauro Bieg).
555+
556+ * RST writer:
557+
558+ + Don't treat 'example' as a syntax name (#4748).
559+ This fixes conversions from org with example blocks.
560+ + Support `--number-sections` via the `section-numbering`
561+ directive in standalone output.
562+
563+ * reveal.js writer and template: reuse mathjax URL
564+ provided by the argument to `--mathjax` or the normal pandoc default,
565+ rather than a hard-coded one in the template (#4701).
566+
567+ * LaTeX writer:
568+
569+ + Properly handle footnotes in table captions (#4683).
570+ Refactored code from figure captions to use in both places.
571+ + In beamer output, fix single digit column percentage (#4690, Mauro
572+ Bieg).
573+
574+ * FB2 writer (Alexander Krotov):
575+
576+ + Convert Plain to Para in annotation (#2424).
577+ + Fix order of items in title-info (#2424).
578+
579+ * Custom writer: fix error message on script failure (Albert Krewinkel).
580+ Error messages produced by Lua were not displayed by Pandoc.
581+
582+ * Text.Pandoc.Emoji now exports `emojiToInline`, which returns a Span
583+ inline containing the emoji character and some attributes with metadata
584+ (class `emoji`, attribute `data-emoji` with emoji name). (API change,
585+ Anders Waldenborg, #4743).
586+
587+ * Text.Pandoc.PDF:
588+
589+ + Revert fix for #4484 (only compress images on last run, #4755).
590+ This will mean some increase in the time it takes to
591+ produce an image-heavy PDF with xelatex, but it will
592+ make tables of contents correct, which is more important.
593+ + Fix logic error in `runTeXProgram`. We were running the tex program
594+ one more time than requested. This should speed up PDF production.
595+
596+ * Allow `--template` to take a URL as argument.
597+
598+ * Text.Pandoc.Highlighting: Add missing re-export of `breezeDark`
599+ highlighting style (#4687, Adrian Sieber, API change).
600+
601+ * Clarify macOS install in INSTALL.md (#4661). Make the binary package
602+ installer the recommended method, and note that on some older versions of
603+ macOS, homebrew installs from source and takes a lot of disk space
604+ (#4664, Ian).
605+
606+ * MANUAL:
607+
608+ + Clarify EPUB linked media (#4756, Mauro Bieg)
609+ + Update manual for "true" YAML values. Now that we're using HsYAML and
610+ YAML 1.2, the valid true values are `true`, `True`, `TRUE`. NOTE!
611+ `y`, `yes`, `on` no longer count as true values.
612+ + Document `-F` as alias for `--filter` (thanks to Gandalf Saxe).
613+ + Update manual on how math is rendered in LaTeX.
614+ + Add proxy description (#4131, Mauro Bieg).
615+ + Clarify that `--toc` requires `--standalone` (#4703).
616+ + Update citation styles link (#4699, wiefling).
617+
618+ * In API docs, clarify how `Ext_east_asian_line_breaks` extension works
619+ (kaizshang91). Note that it will not take effect when readers/writers
620+ are called as libraries (#4674).
621+
622+ * Improved translations/fr (#4766, lux-lth).
623+
624+ * Removed inadvertently added `.orig` files from repository (#4648).
625+
626+ * Remove `network-uri` flag and use 'Network.Socket'.
627+ This removes a compiler warning. There is no need for the old
628+ `network-uri` flag, since network 2.6 was released in 2014.
629+
630+ * Add stack.lts10.yaml, stack.lts11.yaml. use lts-12 in stack.yaml.
631+
632+ * Bump upper bounds for dependent packages.
633+
634+ * Exclude foundation 0.0.21 for ghc 7.10. Otherwise cabal gets
635+ confused because of the way ghc 7.10 is excluded in foundation's
636+ cabal file. This can be removed when haskell-foundation/foundation#500
637+ is fixed.
638+
639+ * Require cabal-version >= 2.0. This is needed for haddock-library.
640+
641+
1642pandoc (2.2.1)
2643
3644 * Restored and undeprecated gladtex for HTML math (#4607).
@@ -432,7 +1073,7 @@ pandoc (2.1.3)
4321073 * JATS writer: Remove extraneous, significant whitespace (#4335,
4331074 Nokome Bentley).
4341075
435− * html2pdf: inject base tag wih current working directory (#4413, Mauro
1076+ * html2pdf: inject base tag with current working directory (#4413, Mauro
4361077 Bieg). This helps ensure that linked resources are included.
4371078
4381079 * Add Semigroup instances for everything for which we defined a
@@ -580,7 +1221,7 @@ pandoc (2.1.2)
5801221 * Docx reader (Jesse Rosenthal, except where noted):
5811222
5821223 + Handle nested sdt tags (#4415).
583− + Don't look up dependant run styles if `+styles` is enabled.
1224+ + Don't look up dependent run styles if `+styles` is enabled.
5841225 + Move pandoc inline styling inside custom-style span.
5851226 + Read custom styles (#1843). This will read all paragraph and
5861227 character classes as divs and spans, respectively. Dependent styles
@@ -2283,7 +2924,7 @@ pandoc (2.0)
22832924
22842925 * Removed `hard_line_breaks` extension from `markdown_github` (#3594).
22852926 GitHub has two Markdown modes, one for long-form documents like READMEs
2286− and one for short things like issue coments. In issue comments, a line
2927+ and one for short things like issue comments. In issue comments, a line
22872928 break is treated as a hard line break. In README, wikis, etc., it is
22882929 treated as a space as in regular Markdown. Since pandoc is more likely to
22892930 be used to convert long-form documents from GitHub Markdown,
@@ -2416,6 +3057,11 @@ pandoc (2.0)
24163057 (since the two-space version of a line break doesn't work inside ATX
24173058 headers, and neither version works inside Setext headers).
24183059
3060+ + A space between the opening # and the header is now required for
3061+ pandoc and GitHub markdown (but not the other flavors). Disable
3062+ the `space_in_atx_header` extension (#3512) to restore the
3063+ original behavior.
3064+
24193065
24203066 * Org reader (Albert Krewinkel, unless noted):
24213067
@@ -2636,7 +3282,7 @@ pandoc (2.0)
26363282 top-level `Text.Pandoc` module.
26373283
26383284 + Changed `StringWriter` -> `TextWriter`.
2639− + `getWriter` now retuns a pair of a reader and
3285+ + `getWriter` now returns a pair of a reader and
26403286 `Extensions`, instead of building the extensions into the
26413287 reader (#3659). The calling code must explicitly set
26423288 `readerExtensions` using the `Extensions` returned. The
@@ -3049,7 +3695,7 @@ pandoc (2.0)
30493695 of item disappear or are misplaced. Use `\texttt` instead.
30503696 + Fix problem with escaping in `lstinline` (#1629). Previously the
30513697 LaTeX writer created invalid LaTeX when `--listings` was specified and
3052− a code span occured inside emphasis or another construction.
3698+ a code span occurred inside emphasis or another construction.
30533699 + Fix error with line breaks after empty content (#2874). LaTeX
30543700 requires something before a line break, so we insert a `~` if no
30553701 printable content has yet been emitted.
@@ -3156,7 +3802,7 @@ pandoc (2.0)
31563802
31573803 + Don't drop smartTag contents (#2242).
31583804 + Handle local namespace declarations (#3365). Previously we didn't
3159− recognize math, for example, when the xmlns declaration occured on
3805+ recognize math, for example, when the xmlns declaration occurred on
31603806 the element and not the root.
31613807 + More efficient trimSps (#1530). Replacing `trimLineBreaks`. This
31623808 does the work of `normalizeSpaces` as well, so we avoid the need for
@@ -3390,7 +4036,7 @@ pandoc (2.0)
33904036 + Allow `]` inside group in option brackets (#3857).
33914037 + lstinline with braces can be used (verb cannot be used with braces)
33924038 (Marc Schreiber, #3535).
3393− + Fix keyval funtion: pandoc did not parse options in braces correctly
4039+ + Fix keyval function: pandoc did not parse options in braces correctly
33944040 (Marc Schreiber, #3642).
33954041 + When parsing raw LaTeX commands, include trailing space (#1773).
33964042 Otherwise things like `\noindent foo` break and turn into
@@ -3482,7 +4128,7 @@ pandoc (2.0)
34824128 parse, the parser was applied too often, consuming too much of the
34834129 input. This only affects `many1Till p end` where `p` matches on a
34844130 prefix of `end`.
3485− + Provide `parseFromString` (#3690). This is a verison of
4131+ + Provide `parseFromString` (#3690). This is a version of
34864132 `parseFromString` specialied to ParserState, which resets
34874133 `stateLastStrPos` at the end. This is almost always what we want.
34884134 This fixes a bug where `_hi_` wasn't treated as emphasis in the
@@ -3588,7 +4234,7 @@ pandoc (2.0)
35884234 + Use `unicode-math` (Vaclav Haisman). Use `mathspec` with only
35894235 XeLaTeX on request.
35904236 + Don't load `fontspec` before `unicode-math` (over there).
3591− The `unicode-math` package loads `fontspec` so explict loading of
4237+ The `unicode-math` package loads `fontspec` so explicit loading of
35924238 `fontspec` before `unicode-math` is not necessary.
35934239 + Use `unicode-math` by default in default.latex template. mathspec will
35944240 be used in xelatex if the `mathspec` variable is set; otherwise
@@ -4241,7 +4887,7 @@ pandoc (1.18)
42414887 is now used in parsing RST and Markdown line blocks, DocBook
42424888 `linegroup`/`line` combinations, and Org-mode `VERSE` blocks.
42434889 Previously `Para` blocks with hard linebreaks were used. `LineBlock`s
4244− are handled specially in the following ouput formats: AsciiDoc
4890+ are handled specially in the following output formats: AsciiDoc
42454891 (as `[verse]` blocks), ConTeXt (`\startlines`/`\endlines`),
42464892 HTML (`div` with a style), Markdown (line blocks if `line_blocks`
42474893 is enabled), Org-mode (`VERSE` blocks), RST (line blocks). In
@@ -4388,7 +5034,7 @@ pandoc (1.18)
43885034 comma-separated list.
43895035 + Give precedence to later meta lines. The last meta-line of any given
43905036 type is the significant line. Previously the value of the first line
4391− was kept, even if more lines of the same type were encounterd.
5037+ was kept, even if more lines of the same type were encountered.
43925038 + Read LaTeX_header as header-includes. LaTeX-specific header commands
43935039 can be defined in `#+LaTeX_header` lines. They are parsed as
43945040 format-specific inlines to ensure that they will only show up in LaTeX
@@ -4436,7 +5082,7 @@ pandoc (1.18)
44365082 be able to figure out internal links to a header in a docx if the
44375083 anchor span was empty. We change that to read the inlines out of the
44385084 first anchor span in a header.
4439− + Let headers use exisiting id. Previously we always generated an id for
5085+ + Let headers use existing id. Previously we always generated an id for
44405086 headers (since they wouldn't bring one from Docx). Now we let it use an
44415087 existing one if possible. This should allow us to recurs through anchor
44425088 spans.
@@ -4543,7 +5189,7 @@ pandoc (1.18)
45435189 + Don't emit HTML for tables unless `raw_html` extension is set (#3154).
45445190 Emit `[TABLE]` if no suitable table formats are enabled and raw HTML
45455191 is disabled.
4546− + Check for the `raw_html` extension before emiting a raw HTML block.
5192+ + Check for the `raw_html` extension before emitting a raw HTML block.
45475193 + Abstract out note/ref function (Jesse Rosenthal).
45485194 + Add ReaderT monad for environment variables (Jesse Rosenthal).
45495195
@@ -5023,7 +5669,7 @@ pandoc (1.17.1)
50235669 character. Empty rows where parsed as alignment rows and dropped from
50245670 the output.
50255671 + Fix spacing after LaTeX-style symbols.
5026− The org-reader was droping space after unescaped LaTeX-style symbol
5672+ The org-reader was dropping space after unescaped LaTeX-style symbol
50275673 commands: `\ForAll \Auml` resulted in `∀Ä` but should give `∀ Ä`
50285674 instead. This seems to be because the LaTeX-reader treats the
50295675 command-terminating space as part of the command. Dropping the trailing
@@ -5117,7 +5763,7 @@ pandoc (1.17.1)
51175763 + Clarified documentation of `implicit_header_references` (#2904).
51185764 + Improved documentation of `--columns` option.
51195765
5120− * Added appveyor setup, with artefacts (Jan Schulz).
5766+ * Added appveyor setup, with artifacts (Jan Schulz).
51215767
51225768 * stack.yaml versions: Use proper flags used for texmath, pandoc-citeproc.
51235769
@@ -5356,7 +6002,7 @@ pandoc (1.16.0.1)
53566002
53576003 * Entity handling fixes: improved handling of entities like
53586004 `&lang;` that require a trailing semicolon. Allow uppercase
5359− `x` in numerical hexidecimal character references, working
6005+ `x` in numerical hexadecimal character references, working
53606006 around a tagsoup bug.
53616007
53626008 * `stack.yaml` - use lts-4.0, but with older aeson to avoid excessive
@@ -6852,7 +7498,7 @@ pandoc (1.14)
68527498 * `Text.Pandoc.Shared`:
68537499
68547500 + Make safeRead safe (#1801, Matthew Pickering).
6855− + Addded `mapLeft`, `hush` (Matthew Pickering).
7501+ + Added `mapLeft`, `hush` (Matthew Pickering).
68567502
68577503 * `Text.Pandoc.Pretty`:
68587504
@@ -6920,7 +7566,7 @@ pandoc (1.14)
69207566
69217567 + Use `text:p` instead of `text:h` for title.
69227568 Using `text:h` causes problems with numbering. Closes #2059.
6923− Thansk to @nkalvi for diagnosing this.
7569+ Thanks to @nkalvi for diagnosing this.
69247570
69257571 * reveal.js template:
69267572
@@ -7003,7 +7649,7 @@ pandoc (1.13.2.1)
70037649
70047650pandoc (1.13.2)
70057651
7006− * TWiki Reader: add new new twiki reader (API change, Alexander Sulfrian).
7652+ * TWiki Reader: add new twiki reader (API change, Alexander Sulfrian).
70077653
70087654 * Markdown reader:
70097655
@@ -7026,7 +7672,7 @@ pandoc (1.13.2)
70267672 + Parse RST class directives. The class directive accepts one or more
70277673 class names, and creates a Div value with those classes. If the
70287674 directive has an indented body, the body is parsed as the children of
7029− the Div. If not, the first block folowing the directive is made a
7675+ the Div. If not, the first block following the directive is made a
70307676 child of the Div. This differs from the behavior of rst2xml, which
70317677 does not create a Div element. Instead, the specified classes are
70327678 applied to each child of the directive. However, most Pandoc Block
@@ -7971,7 +8617,7 @@ pandoc (1.13)
79718617 different versions of the `directory` library.
79728618
79738619 + Added `Text.Pandoc.Compat.Except` to allow building against
7974− different verions of `mtl`.
8620+ different versions of `mtl`.
79758621
79768622 * Code cleanup in some writers, using Reader monad to avoid
79778623 passing options parameter around (Matej Kollar).
@@ -8631,7 +9277,7 @@ pandoc (1.12.2)
86319277 + Parse contents of curly quotes or matched `"` as quotes.
86329278 + Support `\textnormal` as span with class `nodecor`.
86339279 This is needed for pandoc-citeproc.
8634− + Improved citation parsing. This fixes a run-time error that occured
9280+ + Improved citation parsing. This fixes a run-time error that occurred
86359281 with `\citet{}` (empty list of keys). It also ensures that empty keys
86369282 don't get produced.
86379283
@@ -8914,7 +9560,7 @@ pandoc (1.12)
89149560 to make that the current directory before running pandoc. (#942)
89159561
89169562 * Better error reporting in some readers, due to changes in `readWith`:
8917− the line in which the error occured is printed, with a caret pointing
9563+ the line in which the error occurred is printed, with a caret pointing
89189564 to the column.
89199565
89209566 * All slide formats now support incremental slide view for definition lists.
@@ -9608,7 +10254,7 @@ pandoc (1.11)
960810254 + Include HTML TOC, even in epub2. The TOC is included in `<spine>`,
960910255 but `linear` is set to `no` unless the `--toc` option is specified.
961010256 Include `<guide>` element in OPF. This should allow the TOC to
9611− be useable in Kindles when converted with kindlegen. Closes #773.
10257+ be usable in Kindles when converted with kindlegen. Closes #773.
961210258
961310259 * `Text.Pandoc.Parsing`: Optimized `oneOfStringsCI`.
961410260 This dramatically reduces the speed penalty that comes from enabling the
@@ -9973,7 +10619,7 @@ pandoc (1.10)
997310619 [API changes]
997410620
997510621 * `Text.Pandoc.Definition`: Added `Attr` field to `Header`.
9976− Previously header identifers were autogenerated by the writers.
10622+ Previously header identifiers were autogenerated by the writers.
997710623 Now they are added in the readers (either automatically or explicitly).
997810624
997910625 * `Text.Pandoc.Builder`:
@@ -10210,7 +10856,7 @@ pandoc (1.10)
1021010856 incorrectly implented RST-style autolinks for URLs and email
1021110857 addresses. This has been fixed. Now an autolink is done this way:
1021210858 `"$":http://myurl.com`.
10213− + Fixed footnotes bug in textile. This affected notes occuring
10859+ + Fixed footnotes bug in textile. This affected notes occurring
1021410860 before punctuation, e.g. `foo[1].`. Closes #518.
1021510861
1021610862 * LaTeX reader:
@@ -11243,7 +11889,7 @@ pandoc (1.9)
1124311889 Items are no longer installed as root.
1124411890 Man pages are zipped and given proper permissions.
1124511891
11246− * Modified windows installer generater to use cabal-dev.
11892+ * Modified windows installer generator to use cabal-dev.
1124711893
1124811894 * Setup: Making man pages now works with cabal-dev (at least on OSX). In
1124911895 Setup.hs we now invoke 'runghc' in a way that points it to the correct
@@ -12286,7 +12932,7 @@ pandoc (1.5)
1228612932 better browsers) as text/html.
1228712933 + Removed Text.Pandoc.LaTeXMathML. The module was no longer
1228812934 necessary; it was replaced by two lines in pandoc.hs.
12289− + Replaced LaTeXMathML.js.commend and LaTeXMathML.js.packed with a
12935+ + Replaced LaTeXMathML.js.comment and LaTeXMathML.js.packed with a
1229012936 single combined file, LaTeXMathML.js.
1229112937
1229212938 * Added --data-dir option.
@@ -12520,7 +13166,7 @@ pandoc (1.4)
1252013166 * Replaced old headers with templates. Now users have much more
1252113167 control over the way documents appear in --standalone mode,
1252213168 and writer code is simplified. Resolves Issues #59, 147.
12523− Every effort has been made to retain backwards compatibilty.
13169+ Every effort has been made to retain backwards compatibility.
1252413170 So, the --custom-header option should still work as before.
1252513171
1252613172 + Added Text.Pandoc.Templates. This provides functions for
@@ -13488,7 +14134,7 @@ pandoc (0.46) unstable; urgency=low
1348814134
1348914135 + Don't interpret contents of style tags as markdown.
1349014136 (Resolves Issue #40.)
13491− - Added htmlStyle, analagous to htmlScript.
14137+ - Added htmlStyle, analogous to htmlScript.
1349214138 - Use htmlStyle in htmlBlockElement and rawHtmlInline.
1349314139 - Moved "script" from the list of tags that can be either block or
1349414140 inline to the list of block tags.
@@ -14267,7 +14913,7 @@ pandoc (0.4) unstable; urgency=low
1426714913 notes and add information to state. (Reference keys may be needed
1426814914 at this stage.) Finally, parse everything else.
1426914915 + Replaced named constants like 'emphStart' with literals.
14270− + Removed an extra occurance of escapedChar in definition of inline.
14916+ + Removed an extra occurrence of escapedChar in definition of inline.
1427114917
1427214918 * RST reader:
1427314919
@@ -14307,7 +14953,7 @@ pandoc (0.4) unstable; urgency=low
1430714953 + The Html header is now written programmatically, so it has been
1430814954 removed from the 'headers' directory. The S5 header is still
1430914955 needed, but the doctype and some of the meta declarations have
14310− been removed, since they are written programatically. This change
14956+ been removed, since they are written programmatically. This change
1431114957 introduces a new dependency on the xhtml package.
1431214958 + Fixed two bugs in email obfuscation involving improper escaping
1431314959 of '&' in the `<noscript>` section and in `--strict` mode. Resolves
@@ -14616,7 +15262,7 @@ pandoc (0.3) unstable; urgency=low
1461615262 + win-pkg target creates Windows binary package.
1461715263 + tarball target creates distribution source tarball.
1461815264 + website target generates pandoc's website automatically, including
14619− demos. New 'web' directory containts files needed for construction
15265+ demos. New 'web' directory contains files needed for construction
1462015266 of the website (which will be created as the 'pandoc' subdirectory
1462115267 of 'web').
1462215268 + Makefile checks to see if we're running Windows/Cygwin; if so,
data/pandoc.lua+2−2
@@ -124,7 +124,7 @@ Type.behavior = {
124124Type.behavior.__index = Type.behavior
125125
126126--- Set a new behavior for the type, inheriting that of the parent type if none
127−--- is specified explicitely
127+--- is specified explicitly
128128-- @param behavior the behavior object for this type.
129129-- @local
130130function Type:set_behavior (behavior)
@@ -487,7 +487,7 @@ M.Cite = M.Inline:create_constructor(
487487
488488--- Creates a Code inline element
489489-- @function Code
490−-- @tparam string text brief image description
490+-- @tparam string text code string
491491-- @tparam[opt] Attr attr additional attributes
492492-- @treturn Inline code element
493493M.Code = M.Inline:create_constructor(
data/templates/default.epub3+1−1
@@ -26,7 +26,7 @@ $for(header-includes)$
2626 $header-includes$
2727$endfor$
2828</head>
29−<body$if(coverpage)$ id="cover"$endif$>
29+<body$if(coverpage)$ id="cover"$endif$$if(body-type)$ epub:type="$body-type$"$endif$>
3030$if(titlepage)$
3131<section epub:type="titlepage">
3232$for(title)$
data/templates/default.html5+1−1
@@ -46,7 +46,7 @@ $for(include-before)$
4646$include-before$
4747$endfor$
4848$if(title)$
49−<header>
49+<header id="title-block-header">
5050<h1 class="title">$title$</h1>
5151$if(subtitle)$
5252<p class="subtitle">$subtitle$</p>
data/templates/default.latex+43−38
@@ -1,4 +1,4 @@
1−\PassOptionsToPackage{unicode=true}{hyperref} % options for packages loaded elsewhere
1+\PassOptionsToPackage{unicode=true$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} % options for packages loaded elsewhere
22\PassOptionsToPackage{hyphens}{url}
33$if(colorlinks)$
44\PassOptionsToPackage{dvipsnames,svgnames*,x11names*}{xcolor}
@@ -20,6 +20,41 @@ $endif$
2020$for(beameroption)$
2121\setbeameroption{$beameroption$}
2222$endfor$
23+% Prevent slide breaks in the middle of a paragraph:
24+\widowpenalties 1 10000
25+\raggedbottom
26+$if(section-titles)$
27+\setbeamertemplate{part page}{
28+\centering
29+\begin{beamercolorbox}[sep=16pt,center]{part title}
30+ \usebeamerfont{part title}\insertpart\par
31+\end{beamercolorbox}
32+}
33+\setbeamertemplate{section page}{
34+\centering
35+\begin{beamercolorbox}[sep=12pt,center]{part title}
36+ \usebeamerfont{section title}\insertsection\par
37+\end{beamercolorbox}
38+}
39+\setbeamertemplate{subsection page}{
40+\centering
41+\begin{beamercolorbox}[sep=8pt,center]{part title}
42+ \usebeamerfont{subsection title}\insertsubsection\par
43+\end{beamercolorbox}
44+}
45+\AtBeginPart{
46+ \frame{\partpage}
47+}
48+\AtBeginSection{
49+ \ifbibliography
50+ \else
51+ \frame{\sectionpage}
52+ \fi
53+}
54+\AtBeginSubsection{
55+ \frame{\subsectionpage}
56+}
57+$endif$
2358$endif$
2459$if(beamerarticle)$
2560\usepackage{beamerarticle} % needs to be loaded first
@@ -148,6 +183,7 @@ $endif$
148183$if(colorlinks)$
149184 colorlinks=true,
150185 linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
186+ filecolor=$if(filecolor)$$filecolor$$else$Maroon$endif$,
151187 citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
152188 urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
153189$else$
@@ -198,43 +234,6 @@ $if(graphics)$
198234% using explicit options in \includegraphics[width, height, ...]{}
199235\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
200236$endif$
201−$if(beamer)$
202−% Prevent slide breaks in the middle of a paragraph:
203−\widowpenalties 1 10000
204−\raggedbottom
205−$if(section-titles)$
206−\setbeamertemplate{part page}{
207−\centering
208−\begin{beamercolorbox}[sep=16pt,center]{part title}
209− \usebeamerfont{part title}\insertpart\par
210−\end{beamercolorbox}
211−}
212−\setbeamertemplate{section page}{
213−\centering
214−\begin{beamercolorbox}[sep=12pt,center]{part title}
215− \usebeamerfont{section title}\insertsection\par
216−\end{beamercolorbox}
217−}
218−\setbeamertemplate{subsection page}{
219−\centering
220−\begin{beamercolorbox}[sep=8pt,center]{part title}
221− \usebeamerfont{subsection title}\insertsubsection\par
222−\end{beamercolorbox}
223−}
224−\AtBeginPart{
225− \frame{\partpage}
226−}
227−\AtBeginSection{
228− \ifbibliography
229− \else
230− \frame{\sectionpage}
231− \fi
232−}
233−\AtBeginSubsection{
234− \frame{\subsectionpage}
235−}
236−$endif$
237−$endif$
238237$if(links-as-notes)$
239238% Make links footnotes instead of hotlinks:
240239\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}}
@@ -361,8 +360,14 @@ $include-before$
361360
362361$endfor$
363362$if(toc)$
363+$if(toc-title)$
364+\renewcommand*\contentsname{$toc-title$}
365+$endif$
364366$if(beamer)$
365367\begin{frame}
368+$if(toc-title)$
369+\frametitle{$toc-title$}
370+$endif$
366371\tableofcontents[hideallsubsections]
367372\end{frame}
368373$else$
data/templates/default.opendocument+1−3
@@ -26,9 +26,7 @@ $endfor$
2626$if(toc)$
2727<text:table-of-content>
2828 <text:table-of-content-source text:outline-level="10">
29− <text:index-title-template text:style-name="Contents_20_Heading">
30− $toc-title$
31− </text:index-title-template>
29+ <text:index-title-template text:style-name="Contents_20_Heading">$toc-title$</text:index-title-template>
3230 <text:table-of-content-entry-template text:outline-level="1"
3331 text:style-name="Contents_20_1">
3432 <text:index-entry-link-start text:style-name="Internet_20_link" />
data/templates/default.revealjs+5−1
@@ -170,6 +170,10 @@ $if(mouseWheel)$
170170 // Enable slide navigation via mouse wheel
171171 mouseWheel: $mouseWheel$,
172172$endif$
173+$if(rollingLinks)$
174+ // Apply a 3D roll to links on hover
175+ rollingLinks: $rollingLinks$,
176+$endif$
173177$if(hideAddressBar)$
174178 // Hides the address bar on mobile devices
175179 hideAddressBar: $hideAddressBar$,
@@ -237,7 +241,7 @@ $if(maxScale)$
237241$endif$
238242$if(mathjax)$
239243 math: {
240− mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
244+ mathjax: '$mathjaxurl$',
241245 config: 'TeX-AMS_HTML-full',
242246 tex2jax: {
243247 inlineMath: [['\\(','\\)']],
data/templates/default.rst+6−2
@@ -1,5 +1,5 @@
1−$if(title)$
2−$title$
1+$if(titleblock)$
2+$titleblock$
33
44$endif$
55$for(author)$
@@ -30,6 +30,10 @@ $if(toc)$
3030 :depth: $toc-depth$
3131..
3232
33+$endif$
34+$if(number-sections)$
35+.. section-numbering::
36+
3337$endif$
3438$for(header-includes)$
3539$header-includes$
data/templates/default.tei+16−4
@@ -3,17 +3,29 @@
33<teiHeader>
44 <fileDesc>
55 <titleStmt>
6−$if(title)$
76 <title>$title$</title>
8−$endif$
97$for(author)$
10− $author$
8+ <author>$author$</author>
119$endfor$
1210 </titleStmt>
1311 <publicationStmt>
12+$if(publicationStmt)$
1413 <p>$if(publicationStmt)$$publicationStmt$$endif$</p>
15− $if(license)$
14+$endif$
15+$if(license)$
1616 <availability><licence>$license$</licence></availability>
17+$endif$
18+$if(publisher)$
19+ <publisher>$publisher$</publisher>
20+$endif$
21+$if(pubPlace)$
22+ <pubPlace>$pubPlace$</pubPlace>
23+$endif$
24+$if(address)$
25+ <address>$address$</address>
26+$endif$
27+$if(date)$
28+ <date>$date$</date>
1729$endif$
1830 </publicationStmt>
1931 <sourceDesc>
data/templates/default.texinfo−22
@@ -9,28 +9,6 @@ $if(strikeout)$
99~~\text\~~
1010@end macro
1111
12−$endif$
13−$if(subscript)$
14−@macro textsubscript{text}
15−@iftex
16−@textsubscript{\text\}
17−@end iftex
18−@ifnottex
19−_@{\text\@}
20−@end ifnottex
21−@end macro
22−
23−$endif$
24−$if(superscript)$
25−@macro textsuperscript{text}
26−@iftex
27−@textsuperscript{\text\}
28−@end iftex
29−@ifnottex
30−^@{\text\@}
31−@end ifnottex
32−@end macro
33−
3412$endif$
3513@ifnottex
3614@paragraphindent 0
data/translations/fr.yaml+10−10
@@ -1,20 +1,20 @@
11Abstract: Résumé
22Appendix: Annexe
33Bibliography: Bibliographie
4−Cc: Copie à
5−Chapter: Chaptire
4+Cc: Cc
5+Chapter: Chapitre
66Contents: Table des matières
7−Figure: Fig.
8−Glossary:
7+Figure: Figure
8+Glossary: Glossaire
99Index: Index
1010ListOfFigures: Table des figures
1111ListOfTables: Liste des tableaux
12−Page: page
13−Part: partie
12+Page: Page
13+Part: Partie
1414Preface: Préface
1515Proof: Démonstration
1616References: Références
17−See: voir
18−SeeAlso: voir aussi
19−Table: Tab.
20−To:
17+See: Voir
18+SeeAlso: Voir aussi
19+Table: Tableau
20+To: À
data/translations/ru.yaml+9−9
@@ -1,20 +1,20 @@
1−Abstract: Аннотація
2−Appendix: Приложеніе
1+Abstract: Аннотация
2+Appendix: Приложение
33Author: Именной указатель
4−Bibliography: Библіографія
4+Bibliography: Литература
55Cc: исх.
66Chapter: Глава
7−Contents: Оглавленіе
7+Contents: Оглавление
88Encl: вкл.
99Figure: Рис.
10−Index: Предмѣтный указатель
11−ListOfFigures: Списокъ иллюстрацій
12−ListOfTables: Списокъ таблицъ
10+Index: Предметный указатель
11+ListOfFigures: Список иллюстраций
12+ListOfTables: Список таблиц
1313Page: с.
1414Part: Часть
15−Preface: Предисловіе
15+Preface: Предисловие
1616Proof: Доказательство
17−References: Примѣчанія
17+References: Список литературы
1818See: см.
1919SeeAlso: см. также
2020Table: Таблица
default.nix+1−1
@@ -2,7 +2,7 @@
22#
33# To build pandoc run:
44# nix-build
5−# To run a nix shell with everthing needed to build pandoc with cabal:
5+# To run a nix shell with everything needed to build pandoc with cabal:
66# nix-shell
77# To build pandoc for use on Linux and macOS systems without Nix:
88# nix-build -A patched
doc/lua-filter-types-and-objects.mdnew file+396
@@ -0,0 +1,396 @@
1+% Lua filter types and objects
2+% Albert Krewinkel
3+% Oct 6, 2018
4+
5+## Pandoc
6+
7+blocks
8+: document content ([list] of [blocks])
9+
10+meta
11+: document meta information ([Meta] object)
12+
13+
14+## Meta
15+
16+Meta information on a document; string-indexed collection of [meta
17+values](#metavalue). This is represented as a string-indexed table containing
18+[meta values](#MetaValue).
19+
20+
21+## MetaValue
22+
23+Document meta information items.
24+
25+### MetaBlocks
26+
27+blocks
28+: a list of blocks usable as meta value ([list] of [blocks])
29+
30+
31+## Block
32+
33+### BlockQuote
34+
35+A block quote element
36+
37+content:
38+: block content ([list] of [blocks])
39+
40+tag, t
41+: the literal `BlockQuote` (string)
42+
43+### BulletList
44+
45+A bullet list
46+
47+content
48+: list of items ([list] of [blocks])
49+
50+tag, t
51+: the literal `BlockQuote` (string)
52+
53+### CodeBlock
54+
55+Block of code.
56+
57+text
58+: code string (string)
59+
60+attr
61+: element attributes (Attr)
62+
63+identifier
64+: alias for `attr.identifier` (string)
65+
66+classes
67+: alias for `attr.classes` ([list] of strings)
68+
69+attributes
70+: alias for `attr.attributes` ([attributes])
71+
72+tag, t
73+: the literal `CodeBlock` (string)
74+
75+### DefinitionList
76+
77+Definition list, containing terms and their explanation.
78+
79+content
80+: list of items
81+
82+tag, t
83+: the literal `DefinitionList` (string)
84+
85+### Div
86+
87+Generic block container with attributes
88+
89+content
90+: block content ([list] of [blocks])
91+
92+attr
93+: element attributes (Attr)
94+
95+identifier
96+: alias for `attr.identifier` (string)
97+
98+classes
99+: alias for `attr.classes` ([list] of strings)
100+
101+attributes
102+: alias for `attr.attributes` ([attributes])
103+
104+tag, t
105+: the literal `Div` (string)
106+
107+### Header
108+
109+Creates a header element.
110+
111+level
112+: header level (integer)
113+
114+content
115+: inline content ([list] of [inlines])
116+
117+attr
118+: element attributes (Attr)
119+
120+identifier
121+: alias for `attr.identifier` (string)
122+
123+classes
124+: alias for `attr.classes` ([list] of strings)
125+
126+attributes
127+: alias for `attr.attributes` ([attributes])
128+
129+tag, t
130+: the literal `Header` (string)
131+
132+
133+### HorizontalRule
134+
135+A horizontal rule.
136+
137+tag, t
138+: the literal `HorizontalRule` (string)
139+
140+### LineBlock
141+
142+A line block, i.e. a list of lines, each separated from the next
143+by a newline.
144+
145+content
146+: inline content
147+
148+tag, t
149+: the literal `LineBlock` (string)
150+
151+### Null
152+
153+A null element; this element never produces any output in the
154+target format.
155+
156+tag, t
157+: the literal `Null` (string)
158+
159+### OrderedList
160+
161+An ordered list.
162+
163+Parameters:
164+
165+items
166+: list items ([list] of [blocks])
167+
168+listAttributes
169+: list parameters
170+
171+tag, t
172+: the literal `OrderedList` (string)
173+
174+### Para
175+
176+A paragraph
177+
178+content
179+: inline content
180+
181+tag, t
182+: the literal `Para` (string)
183+
184+### Plain
185+
186+Plain text, not a paragraph
187+
188+content
189+: inline content
190+
191+tag, t
192+: the literal `Plain` (string)
193+
194+### RawBlock
195+
196+Raw content of a specified format.
197+
198+format
199+: format of content (string)
200+
201+text
202+: raw content (string)
203+
204+tag, t
205+: the literal `RawBlock` (string)
206+
207+### Table
208+
209+A table.
210+
211+caption:
212+: table caption
213+
214+aligns:
215+: alignments
216+
217+widths:
218+: column widths
219+
220+headers
221+: header row
222+
223+rows:
224+: table rows
225+
226+tag, t
227+: the literal `Table` (string)
228+
229+## Inline
230+
231+### Cite
232+Citation
233+
234+content
235+: ([list] of [inlines])
236+
237+citations
238+: citation entries ([list] of [citations])
239+
240+tag, t
241+: the literal `Cite` (string)
242+
243+### Code
244+Inline code
245+
246+text
247+: code string (string)
248+
249+attr
250+: attributes ([Attr])
251+
252+identifier
253+: alias for `attr.identifier` (string)
254+
255+classes
256+: alias for `attr.classes` ([list] of strings)
257+
258+attributes
259+: alias for `attr.attributes` ([attributes])
260+
261+tag, t
262+: the literal `Code` (string)
263+
264+### Emph
265+Emphasized text
266+
267+content
268+: inline content ([list] of [inlines])
269+
270+tag, t
271+: the literal `Emph` (string)
272+
273+<!-- TODO -->
274+
275+### Image
276+Image: alt text (list of inlines), target
277+
278+tag, t
279+: the literal `Image` (string)
280+
281+### Link
282+Hyperlink: alt text (list of inlines), target
283+
284+tag, t
285+: the literal `Link` (string)
286+
287+### LineBreak
288+Hard line break
289+
290+tag, t
291+: the literal `LineBreak` (string)
292+
293+### Math
294+TeX math (literal)
295+
296+tag, t
297+: the literal `Math` (string)
298+
299+### Note
300+Footnote or endnote
301+
302+tag, t
303+: the literal `Note` (string)
304+
305+### Quoted
306+Quoted text (list of inlines)
307+
308+tag, t
309+: the literal `Quoted` (string)
310+
311+### RawInline
312+Raw inline
313+
314+tag, t
315+: the literal `RawInline` (string)
316+
317+### SmallCaps
318+Small caps text (list of inlines)
319+
320+tag, t
321+: the literal `SmallCaps` (string)
322+
323+### SoftBreak
324+Soft line break
325+
326+tag, t
327+: the literal `SoftBreak` (string)
328+
329+### Space
330+Inter-word space
331+
332+tag, t
333+: the literal `Space` (string)
334+
335+### Span
336+Generic inline container with attributes
337+
338+attr
339+: attributes ([Attr])
340+
341+identifier
342+: alias for `attr.identifier` (string)
343+
344+classes
345+: alias for `attr.classes` ([list] of strings)
346+
347+attributes
348+: alias for `attr.attributes` ([attributes])
349+
350+tag, t
351+: the literal `Span` (string)
352+
353+### Str
354+Text (string)
355+
356+tag, t
357+: the literal `Str` (string)
358+
359+### Strikeout
360+Strikeout text (list of inlines)
361+
362+tag, t
363+: the literal `Strikeout` (string)
364+
365+### Strong
366+Strongly emphasized text (list of inlines)
367+
368+tag, t
369+: the literal `Strong` (string)
370+
371+### Subscript
372+Subscripted text (list of inlines)
373+
374+tag, t
375+: the literal `Subscript` (string)
376+
377+### Superscript
378+Superscripted text (list of inlines)
379+
380+tag, t
381+: the literal `Superscript` (string)
382+
383+## Attributes
384+
385+List of key/value pairs. Values can be accessed by using keys as indices to the
386+list table.
387+
388+
389+[block]: #block
390+[blocks]: #block
391+[list]: #list
392+[meta value]: #metavalue
393+[inline]: #inline
394+[inlines]: #inline
395+[Attr]: #attr
396+[attributes]: #attributes
doc/lua-filters.md+43−7
@@ -10,11 +10,11 @@ title: Pandoc Lua Filters
1010
1111Pandoc has long supported filters, which allow the pandoc
1212abstract syntax tree (AST) to be manipulated between the parsing
13−and the writing phase. Traditional pandoc filters accept a JSON
14−representation of the pandoc AST and produce an altered JSON
15−representation of the AST. They may be written in any
16−programming language, and invoked from pandoc using the
17−`--filter` option.
13+and the writing phase. [Traditional pandoc
14+filters](filters.html) accept a JSON representation of the
15+pandoc AST and produce an altered JSON representation of the
16+AST. They may be written in any programming language, and
17+invoked from pandoc using the `--filter` option.
1818
1919Although traditional filters are very flexible, they have a
2020couple of disadvantages. First, there is some overhead in
@@ -114,7 +114,7 @@ The return of a filter function must one of the following:
114114- a pandoc object: this must be of the same type as the input
115115 and will replace the original object.
116116- a list of pandoc objects: these will replace the original
117− object; the list is merged with the neighbors of the orignal
117+ object; the list is merged with the neighbors of the original
118118 objects (spliced into the list the original object belongs
119119 to); returning an empty list deletes the object.
120120
@@ -240,6 +240,11 @@ colon syntax (`mystring:uc_upper()`).
240240
241241# Examples
242242
243+The following filters are presented as examples.
244+A repository of useful lua filters (which may also serve
245+as good examples) is available at
246+<https://github.com/pandoc/lua-filters>.
247+
243248## Macro substitution.
244249
245250The following filter converts the string `{{helloworld}}` into
@@ -948,7 +953,7 @@ Lua functions for pandoc scripts.
948953 Parameters:
949954
950955 `text`:
951− : brief image description
956+ : code string
952957
953958 `attr`:
954959 : additional attributes
@@ -1438,6 +1443,37 @@ Lua functions for pandoc scripts.
14381443This module exposes internal pandoc functions and utility
14391444functions.
14401445
1446+[`blocks_to_inlines (blocks[, sep])`]{#utils-blocks_to_inlines}
1447+
1448+: Squash a list of blocks into a list of inlines.
1449+
1450+ Parameters:
1451+
1452+ `blocks`:
1453+ : List of blocks to be flattened.
1454+
1455+ `sep`:
1456+ : List of inlines inserted as separator between two
1457+ consecutive blocks; defaults to `{ pandoc.Space(),
1458+ pandoc.Str'¶', pandoc.Space()}`.
1459+
1460+ Returns:
1461+
1462+ - ({[Inline][#Inline]}) List of inlines
1463+
1464+ Usage:
1465+
1466+ local blocks = {
1467+ pandoc.Para{ pandoc.Str 'Paragraph1' },
1468+ pandoc.Para{ pandoc.Emph 'Paragraph2' }
1469+ }
1470+ local inlines = pandoc.utils.blocks_to_inlines(blocks)
1471+ -- inlines = {
1472+ -- pandoc.Str 'Paragraph1',
1473+ -- pandoc.Space(), pandoc.Str'¶', pandoc.Space(),
1474+ -- pandoc.Emph{ pandoc.Str 'Paragraph2' }
1475+ -- }
1476+
14411477[`hierarchicalize (blocks)`]{#utils-hierarchicalize}
14421478
14431479: Convert list of blocks into an hierarchical list. An
doc/using-the-pandoc-api.md+2−2
@@ -42,7 +42,7 @@ limitation is mostly a help rather than a hindrance, since many
4242of the formats pandoc supports have similar limitations.
4343
4444The best way to explore the pandoc AST is to use `pandoc -t
45−native`, which will display the AST correspoding to some
45+native`, which will display the AST corresponding to some
4646Markdown input:
4747
4848```
@@ -187,7 +187,7 @@ Some particularly important options to know about:
187187# Builder
188188
189189Sometimes it's useful to construct a Pandoc document
190−programatically. To make this easier we provide the
190+programmatically. To make this easier we provide the
191191module [Text.Pandoc.Builder] `pandoc-types`.
192192
193193Because concatenating lists is slow, we use special
linux/Dockerfile+7−40
@@ -1,57 +1,24 @@
11# USE ALPINE LINUX
22FROM alpine
33RUN apk update
4−# INSTALL BASIC DEV TOOLS, GHC, GMP & ZLIB
5−RUN echo "https://s3-us-west-2.amazonaws.com/alpine-ghc/8.0" >> /etc/apk/repositories
6−ADD https://raw.githubusercontent.com/mitchty/alpine-ghc/master/mitch.tishmack%40gmail.com-55881c97.rsa.pub \
7− /etc/apk/keys/mitch.tishmack@gmail.com-55881c97.rsa.pub
8−RUN apk update
94RUN apk add alpine-sdk git ca-certificates ghc gmp-dev zlib-dev bash dpkg fakeroot
105# GRAB A RECENT BINARY OF STACK
11−RUN curl -L https://github.com/commercialhaskell/stack/releases/download/v1.6.5/stack-1.6.5-linux-x86_64-static.tar.gz | tar xz --wildcards --strip-components=1 -C /usr/local/bin '*/stack'
12−# COMPRESS WITH UPX
13−ADD https://github.com/lalyos/docker-upx/releases/download/v3.91/upx /usr/local/bin/upx
6+# Note that 1.6.5 is the last one with an official static binary...we need
7+# a more recent version, so we use this unofficial one.
8+RUN curl -L https://github.com/nh2/stack/releases/download/v1.6.5/stack-1.7.1-x86_64-unofficial-fully-static-musl > /usr/local/bin/stack
9+#RUN curl -L https://github.com/commercialhaskell/stack/releases/download/v1.6.5/stack-1.6.5-linux-x86_64-static.tar.gz | tar xz --wildcards --strip-components=1 -C /usr/local/bin '*/stack'
10+RUN chmod +x /usr/local/bin/stack
1411ENV PATH="/usr/local/bin:${PATH}"
15−RUN chmod 755 /usr/local/bin/upx
1612RUN ulimit -n 4096
1713RUN stack config set system-ghc --global true
18−RUN stack --resolver lts-9 setup --install-cabal 2.0.1.1
19−#RUN mkdir -p /etc/stack
20−#RUN echo "build: { split-objs: true }" > /etc/stack/config.yaml
14+RUN stack setup --resolver lts-12
2115RUN mkdir -p /usr/src/
2216WORKDIR /usr/src/
2317RUN git clone https://github.com/jgm/pandoc
2418WORKDIR /usr/src/pandoc
25−RUN stack install --stack-yaml stack.lts9.yaml \
26− --only-dependencies \
27− --flag 'pandoc:static' \
28− --flag 'pandoc:embed_data_files' \
29− --flag 'pandoc-citeproc:static' \
30− --flag 'pandoc-citeproc:embed_data_files' \
31− --flag 'hslua:-export-dynamic' \
32− --ghc-options '-O2 -optc-Os -optl=-pthread -optl=-static -fPIC' \
33− aeson
34−RUN stack install --stack-yaml stack.lts9.yaml \
35− --only-dependencies \
36− --flag 'pandoc:static' \
37− --flag 'pandoc:embed_data_files' \
38− --flag 'pandoc-citeproc:static' \
39− --flag 'pandoc-citeproc:embed_data_files' \
40− --flag 'hslua:-export-dynamic' \
41− --ghc-options '-O2 -optc-Os -optl=-pthread -optl=-static -fPIC' \
42− http-client-tls
43−RUN stack install --stack-yaml stack.lts9.yaml \
44− --only-dependencies \
45− --flag 'pandoc:static' \
46− --flag 'pandoc:embed_data_files' \
47− --flag 'pandoc-citeproc:static' \
48− --flag 'pandoc-citeproc:embed_data_files' \
49− --flag 'hslua:-export-dynamic' \
50− --ghc-options '-O2 -optc-Os -optl=-pthread -optl=-static -fPIC' \
51− pandoc pandoc-citeproc
5219CMD git pull && \
5320 git checkout -b work $TREE && \
54− stack install --stack-yaml stack.lts9.yaml \
21+ stack install \
5522 --flag 'pandoc:static' \
5623 --flag 'pandoc:embed_data_files' \
5724 --flag 'pandoc-citeproc:static' \
man/pandoc.1+245−63
@@ -1,5 +1,5 @@
11.\"t
2−.TH PANDOC 1 "May 10, 2018" "pandoc 2.2.1"
2+.TH PANDOC 1 "September 27, 2018" "pandoc 2.3.1"
33.SH NAME
44pandoc - general markup converter
55.SH SYNOPSIS
@@ -187,8 +187,9 @@ requires \f[C]fontspec\f[].
187187If the \f[C]mathspec\f[] variable is set, \f[C]xelatex\f[] will use
188188\f[C]mathspec\f[] instead of \f[C]unicode\-math\f[].
189189The \f[C]upquote\f[] and \f[C]microtype\f[] packages are used if
190−available, and \f[C]csquotes\f[] will be used for typography if added to
191−the template or included in any header file.
190+available, and \f[C]csquotes\f[] will be used for typography if
191+\f[C]\\usepackage{csquotes}\f[] is present in the template or included
192+via \f[C]/H/\-\-include\-in\-header\f[].
192193The \f[C]natbib\f[], \f[C]biblatex\f[], \f[C]bibtex\f[], and
193194\f[C]biber\f[] packages can optionally be used for citation rendering.
194195.SS Reading from the Web
@@ -231,10 +232,9 @@ Specify input format.
231232.IP \[bu] 2
232233\f[C]fb2\f[] (FictionBook2 e\-book)
233234.IP \[bu] 2
234−\f[C]gfm\f[] (GitHub\-Flavored Markdown), or \f[C]markdown_github\f[],
235−which provides deprecated and less accurate support for Github\-Flavored
236−Markdown; please use \f[C]gfm\f[] instead, unless you need to use
237−extensions other than \f[C]smart\f[].
235+\f[C]gfm\f[] (GitHub\-Flavored Markdown), or the deprecated and less
236+accurate \f[C]markdown_github\f[]; use \f[C]markdown_github\f[] only if
237+you need extensions not supported in \f[C]gfm\f[].
238238.IP \[bu] 2
239239\f[C]haddock\f[] (Haddock markup)
240240.IP \[bu] 2
@@ -312,10 +312,9 @@ Specify output format.
312312.IP \[bu] 2
313313\f[C]fb2\f[] (FictionBook2 e\-book)
314314.IP \[bu] 2
315−\f[C]gfm\f[] (GitHub\-Flavored Markdown), or \f[C]markdown_github\f[],
316−which provides deprecated and less accurate support for Github\-Flavored
317−Markdown; please use \f[C]gfm\f[] instead, unless you use extensions
318−that do not work with \f[C]gfm\f[].
315+\f[C]gfm\f[] (GitHub\-Flavored Markdown), or the deprecated and less
316+accurate \f[C]markdown_github\f[]; use \f[C]markdown_github\f[] only if
317+you need extensions not supported in \f[C]gfm\f[].
319318.IP \[bu] 2
320319\f[C]haddock\f[] (Haddock markup)
321320.IP \[bu] 2
@@ -556,7 +555,7 @@ Reading binary files (docx, odt, epub) implies \f[C]\-\-file\-scope\f[].
556555.RS
557556.RE
558557.TP
559−.B \f[C]\-\-filter=\f[]\f[I]PROGRAM\f[]
558+.B \f[C]\-F\f[] \f[I]PROGRAM\f[], \f[C]\-\-filter=\f[]\f[I]PROGRAM\f[]
560559Specify an executable to be used as a filter transforming the pandoc AST
561560after the input is parsed and before the output is written.
562561The executable should read JSON from stdin and write JSON to stdout.
@@ -659,6 +658,17 @@ escaped when inserted into the template.
659658.RS
660659.RE
661660.TP
661+.B \f[C]\-\-metadata\-file=\f[]\f[I]FILE\f[]
662+Read metadata from the supplied YAML (or JSON) file.
663+This option can be used with every input format, but string scalars in
664+the YAML file will always be parsed as Markdown.
665+Generally, the input will be handled the same as in YAML metadata
666+blocks.
667+Metadata values specified inside the document, or by using \f[C]\-M\f[],
668+overwrite values specified with this option.
669+.RS
670+.RE
671+.TP
662672.B \f[C]\-p\f[], \f[C]\-\-preserve\-tabs\f[]
663673Preserve tabs instead of converting them to spaces (the default).
664674Note that this will only affect tabs in literal code spans and code
@@ -731,8 +741,8 @@ otherwise, metadata is suppressed.
731741.RS
732742.RE
733743.TP
734−.B \f[C]\-\-template=\f[]\f[I]FILE\f[]
735−Use \f[I]FILE\f[] as a custom template for the generated document.
744+.B \f[C]\-\-template=\f[]\f[I]FILE\f[]|\f[I]URL\f[]
745+Use the specified file as a custom template for the generated document.
736746Implies \f[C]\-\-standalone\f[].
737747See Templates, below, for a description of template syntax.
738748If no extension is specified, an extension corresponding to the writer
@@ -815,7 +825,8 @@ Include an automatically generated table of contents (or, in the case of
815825\f[C]latex\f[], \f[C]context\f[], \f[C]docx\f[], \f[C]odt\f[],
816826\f[C]opendocument\f[], \f[C]rst\f[], or \f[C]ms\f[], an instruction to
817827create one) in the output document.
818−This option has no effect on \f[C]man\f[], \f[C]docbook4\f[],
828+This option has no effect unless \f[C]\-s/\-\-standalone\f[] is used,
829+and it has no effect on \f[C]man\f[], \f[C]docbook4\f[],
819830\f[C]docbook5\f[], or \f[C]jats\f[] output.
820831.RS
821832.RE
@@ -921,12 +932,19 @@ directory must be explicitly listed or it will not be searched.
921932For example: \f[C]\-\-resource\-path=.:test\f[] will search the working
922933directory and the \f[C]test\f[] subdirectory, in that order.
923934.RS
935+.PP
936+\f[C]\-\-resource\-path\f[] only has an effect if (a) the output format
937+embeds images (for example, \f[C]docx\f[], \f[C]pdf\f[], or
938+\f[C]html\f[] with \f[C]\-\-self\-contained\f[]) or (b) it is used
939+together with \f[C]\-\-extract\-media\f[].
924940.RE
925941.TP
926942.B \f[C]\-\-request\-header=\f[]\f[I]NAME\f[]\f[C]:\f[]\f[I]VAL\f[]
927943Set the request header \f[I]NAME\f[] to the value \f[I]VAL\f[] when
928944making HTTP requests (for example, when a URL is given on the command
929945line, or when resources used in a document must be downloaded).
946+If you\[aq]re behind a proxy, you also need to set the environment
947+variable \f[C]http_proxy\f[] to \f[C]http://...\f[].
930948.RS
931949.RE
932950.SS Options affecting specific writers
@@ -1037,7 +1055,11 @@ Implies \f[C]\-\-number\-sections\f[].
10371055.RE
10381056.TP
10391057.B \f[C]\-\-listings\f[]
1040−Use the \f[C]listings\f[] package for LaTeX code blocks
1058+Use the \f[C]listings\f[] package for LaTeX code blocks.
1059+The package does not support multi\-byte encoding for source code.
1060+To handle UTF\-8 you would need to use a custom template.
1061+This issue is fully documented here: Encoding issue with the listings
1062+package.
10411063.RS
10421064.RE
10431065.TP
@@ -1402,19 +1424,13 @@ without native math support.
14021424.B \f[C]\-\-katex\f[][\f[C]=\f[]\f[I]URL\f[]]
14031425Use KaTeX to display embedded TeX math in HTML output.
14041426The \f[I]URL\f[] is the base URL for the KaTeX library.
1427+That directory should contain a \f[C]katex.min.js\f[] and a
1428+\f[C]katex.min.css\f[] file.
14051429If a \f[I]URL\f[] is not provided, a link to the KaTeX CDN will be
14061430inserted.
14071431.RS
14081432.RE
14091433.TP
1410−.B \f[C]\-\-katex\-stylesheet=\f[]\f[I]URL\f[]
1411−The \f[I]URL\f[] should point to the \f[C]katex.css\f[] stylesheet.
1412−If this option is not specified, a link to the KaTeX CDN will be
1413−inserted.
1414−Note that this option does not imply \f[C]\-\-katex\f[].
1415−.RS
1416−.RE
1417−.TP
14181434.B \f[C]\-\-gladtex\f[]
14191435Enclose TeX math in \f[C]<eq>\f[] tags in HTML output.
14201436The resulting HTML can then be processed by GladTeX to produce images of
@@ -1594,7 +1610,7 @@ specified
15941610.TP
15951611.B \f[C]toc\-title\f[]
15961612title of table of contents (works only with EPUB, opendocument, odt,
1597−docx, pptx)
1613+docx, pptx, beamer, LaTeX)
15981614.RS
15991615.RE
16001616.TP
@@ -1825,15 +1841,16 @@ options to pass to the microtype package
18251841.TP
18261842.B \f[C]colorlinks\f[]
18271843add color to link text; automatically enabled if any of
1828−\f[C]linkcolor\f[], \f[C]citecolor\f[], \f[C]urlcolor\f[], or
1829−\f[C]toccolor\f[] are set
1844+\f[C]linkcolor\f[], \f[C]filecolor\f[], \f[C]citecolor\f[],
1845+\f[C]urlcolor\f[], or \f[C]toccolor\f[] are set
18301846.RS
18311847.RE
18321848.TP
1833−.B \f[C]linkcolor\f[], \f[C]citecolor\f[], \f[C]urlcolor\f[], \f[C]toccolor\f[]
1834−color for internal links, citation links, external links, and links in
1835−table of contents: uses options allowed by \f[C]xcolor\f[], including
1836−the \f[C]dvipsnames\f[], \f[C]svgnames\f[], and \f[C]x11names\f[] lists
1849+.B \f[C]linkcolor\f[], \f[C]filecolor\f[], \f[C]citecolor\f[], \f[C]urlcolor\f[], \f[C]toccolor\f[]
1850+color for internal links, external links, citation links, linked URLs,
1851+and links in table of contents, respectively: uses options allowed by
1852+\f[C]xcolor\f[], including the \f[C]dvipsnames\f[], \f[C]svgnames\f[],
1853+and \f[C]x11names\f[] lists
18371854.RS
18381855.RE
18391856.TP
@@ -2109,11 +2126,9 @@ any number (including zero),
21092126any object,
21102127.IP \[bu] 2
21112128the boolean \f[C]true\f[] (to specify the boolean \f[C]true\f[] value
2112−using YAML metadata or the \f[C]\-\-metadata\f[] flag, use \f[C]y\f[],
2113−\f[C]Y\f[], \f[C]yes\f[], \f[C]Yes\f[], \f[C]YES\f[], \f[C]true\f[],
2114−\f[C]True\f[], \f[C]TRUE\f[], \f[C]on\f[], \f[C]On\f[], or \f[C]ON\f[];
2115−with the \f[C]\-\-variable\f[] flag, simply omit a value for the
2116−variable, e.g.
2129+using YAML metadata or the \f[C]\-\-metadata\f[] flag, use
2130+\f[C]true\f[], \f[C]True\f[], or \f[C]TRUE\f[]; with the
2131+\f[C]\-\-variable\f[] flag, simply omit a value for the variable, e.g.
21172132\f[C]\-\-variable\ draft\f[]).
21182133.PP
21192134\f[C]X\f[] and \f[C]Y\f[] are placeholders for any valid template text,
@@ -2360,12 +2375,13 @@ This extension can be enabled/disabled for the following formats (in
23602375addition to \f[C]markdown\f[]):
23612376.TP
23622377.B input formats
2363−\f[C]latex\f[], \f[C]org\f[], \f[C]textile\f[]
2378+\f[C]latex\f[], \f[C]org\f[], \f[C]textile\f[], \f[C]html\f[]
2379+(environments, \f[C]\\ref\f[], and \f[C]\\eqref\f[] only)
23642380.RS
23652381.RE
23662382.TP
23672383.B output formats
2368−\f[C]textile\f[]
2384+\f[C]textile\f[], \f[C]commonmark\f[]
23692385.RS
23702386.RE
23712387.SS Extension: \f[C]native_divs\f[]
@@ -3772,14 +3788,20 @@ pandoc\ chap1.md\ chap2.md\ chap3.md\ metadata.yaml\ \-s\ \-o\ book.html
37723788.fi
37733789.PP
37743790Just be sure that the YAML file begins with \f[C]\-\-\-\f[] and ends
3775−with \f[C]\-\-\-\f[] or \f[C]\&...\f[].)
3791+with \f[C]\-\-\-\f[] or \f[C]\&...\f[].) Alternatively, you can use the
3792+\f[C]\-\-metadata\-file\f[] option.
3793+Using that approach however, you cannot reference content (like
3794+footnotes) from the main markdown input document.
37763795.PP
37773796Metadata will be taken from the fields of the YAML object and added to
37783797any existing document metadata.
37793798Metadata can contain lists and objects (nested arbitrarily), but all
37803799string scalars will be interpreted as Markdown.
37813800Fields with names ending in an underscore will be ignored by pandoc.
3782−(They may be given a role by external processors.)
3801+(They may be given a role by external processors.) Field names must not
3802+be interpretable as YAML numbers or boolean values (so, for example,
3803+\f[C]yes\f[], \f[C]True\f[], and \f[C]15\f[] cannot be used as field
3804+names).
37833805.PP
37843806A document may contain multiple metadata blocks.
37853807The metadata fields will be combined through a \f[I]left\-biased
@@ -3806,7 +3828,7 @@ title:\ \ \[aq]This\ is\ the\ title:\ it\ contains\ a\ colon\[aq]
38063828author:
38073829\-\ Author\ One
38083830\-\ Author\ Two
3809−tags:\ [nothing,\ nothingness]
3831+keywords:\ [nothing,\ nothingness]
38103832abstract:\ |
38113833\ \ This\ is\ the\ abstract.
38123834
@@ -4094,8 +4116,15 @@ delimiters.
40944116TeX math will be printed in all output formats.
40954117How it is rendered depends on the output format:
40964118.TP
4097−.B Markdown, LaTeX, Emacs Org mode, ConTeXt, ZimWiki
4098−It will appear verbatim between \f[C]$\f[] characters.
4119+.B LaTeX
4120+It will appear verbatim surrounded by \f[C]\\(...\\)\f[] (for inline
4121+math) or \f[C]\\[...\\]\f[] (for display math).
4122+.RS
4123+.RE
4124+.TP
4125+.B Markdown, Emacs Org mode, ConTeXt, ZimWiki
4126+It will appear verbatim surrounded by \f[C]$...$\f[] (for inline math)
4127+or \f[C]$$...$$\f[] (for display math).
40994128.RS
41004129.RE
41014130.TP
@@ -5017,8 +5046,8 @@ nocite:\ |
50175046\f[]
50185047.fi
50195048.PP
5020−For LaTeX or PDF output, you can also use \f[C]natbib\f[] or
5021−\f[C]biblatex\f[] to render bibliography.
5049+For LaTeX output, you can also use \f[C]natbib\f[] or \f[C]biblatex\f[]
5050+to render the bibliography.
50225051In order to do so, specify bibliography files as outlined above, and add
50235052\f[C]\-\-natbib\f[] or \f[C]\-\-biblatex\f[] argument to \f[C]pandoc\f[]
50245053invocation.
@@ -5230,7 +5259,7 @@ Also, \f[C]raw_tex\f[] only affects \f[C]gfm\f[] output, not input.
52305259.TP
52315260.B \f[C]gfm\f[] (GitHub\-Flavored Markdown)
52325261\f[C]pipe_tables\f[], \f[C]raw_html\f[], \f[C]fenced_code_blocks\f[],
5233−\f[C]auto_identifiers\f[], \f[C]ascii_identifiers\f[],
5262+\f[C]gfm_auto_identifiers\f[], \f[C]ascii_identifiers\f[],
52345263\f[C]backtick_code_blocks\f[], \f[C]autolink_bare_uris\f[],
52355264\f[C]intraword_underscores\f[], \f[C]strikeout\f[],
52365265\f[C]hard_line_breaks\f[], \f[C]emoji\f[],
@@ -5551,33 +5580,40 @@ introducing the slide:
55515580All of the other frame attributes described in Section 8.1 of the Beamer
55525581User\[aq]s Guide may also be used: \f[C]allowdisplaybreaks\f[],
55535582\f[C]allowframebreaks\f[], \f[C]b\f[], \f[C]c\f[], \f[C]t\f[],
5554−\f[C]environment\f[], \f[C]label\f[], \f[C]plain\f[], \f[C]shrink\f[].
5555−.SS Background in reveal.js
5583+\f[C]environment\f[], \f[C]label\f[], \f[C]plain\f[], \f[C]shrink\f[],
5584+\f[C]standout\f[], \f[C]noframenumbering\f[].
5585+.SS Background in reveal.js and beamer
55565586.PP
5557−Background images can be added to self\-contained reveal.js slideshows.
5587+Background images can be added to self\-contained reveal.js slideshows
5588+and to beamer slideshows.
55585589.PP
5559−For the same image on every slide, use the reveal.js configuration
5560−option \f[C]parallaxBackgroundImage\f[] either in the YAML metadata
5561−block or as a command\-line variable.
5590+For the same image on every slide, use the configuration option
5591+\f[C]background\-image\f[] either in the YAML metadata block or as a
5592+command\-line variable.
5593+(There are no other options in beamer and the rest of this section
5594+concerns reveal.js slideshows.)
5595+.PP
5596+For reveal.js, you can instead use the reveal.js\-native option
5597+\f[C]parallaxBackgroundImage\f[].
55625598You can also set \f[C]parallaxBackgroundHorizontal\f[] and
55635599\f[C]parallaxBackgroundVertical\f[] the same way and must also set
55645600\f[C]parallaxBackgroundSize\f[] to have your values take effect.
55655601.PP
5566−To set an image for a particular slide, add
5602+To set an image for a particular reveal.js slide, add
55675603\f[C]{data\-background\-image="/path/to/image"}\f[] to the first
55685604slide\-level header on the slide (which may even be empty).
55695605.PP
55705606In reveal.js\[aq]s overview mode, the parallaxBackgroundImage will show
55715607up only on the first slide.
55725608.PP
5573−Other background settings also work on individual slides, including
5574−\f[C]data\-background\-size\f[], \f[C]data\-background\-repeat\f[],
5575−\f[C]data\-background\-color\f[], \f[C]data\-transition\f[], and
5576−\f[C]data\-transition\-speed\f[].
5609+Other reveal.js background settings also work on individual slides,
5610+including \f[C]data\-background\-size\f[],
5611+\f[C]data\-background\-repeat\f[], \f[C]data\-background\-color\f[],
5612+\f[C]data\-transition\f[], and \f[C]data\-transition\-speed\f[].
55775613.PP
55785614See the reveal.js documentation for more details.
55795615.PP
5580−For example:
5616+For example in reveal.js:
55815617.IP
55825618.nf
55835619\f[C]
@@ -5748,11 +5784,129 @@ iBooks\-specific metadata, with the following fields:
57485784\f[C]scroll\-axis\f[]:
57495785\f[C]vertical\f[]|\f[C]horizontal\f[]|\f[C]default\f[]
57505786.RE
5787+.SS The \f[C]epub:type\f[] attribute
5788+.PP
5789+For \f[C]epub3\f[] output, you can mark up the header that corresponds
5790+to an EPUB chapter using the \f[C]epub:type\f[] attribute.
5791+For example, to set the attribute to the value \f[C]prologue\f[], use
5792+this markdown:
5793+.IP
5794+.nf
5795+\f[C]
5796+#\ My\ chapter\ {epub:type=prologue}
5797+\f[]
5798+.fi
5799+.PP
5800+Which will result in:
5801+.IP
5802+.nf
5803+\f[C]
5804+<body\ epub:type="frontmatter">
5805+\ \ <section\ epub:type="prologue">
5806+\ \ \ \ <h1>My\ chapter</h1>
5807+\f[]
5808+.fi
5809+.PP
5810+Pandoc will output \f[C]<body\ epub:type="bodymatter">\f[], unless you
5811+use one of the following values, in which case either
5812+\f[C]frontmatter\f[] or \f[C]backmatter\f[] will be output.
5813+.PP
5814+.TS
5815+tab(@);
5816+l l.
5817+T{
5818+\f[C]epub:type\f[] of first section
5819+T}@T{
5820+\f[C]epub:type\f[] of body
5821+T}
5822+_
5823+T{
5824+prologue
5825+T}@T{
5826+frontmatter
5827+T}
5828+T{
5829+abstract
5830+T}@T{
5831+frontmatter
5832+T}
5833+T{
5834+acknowledgments
5835+T}@T{
5836+frontmatter
5837+T}
5838+T{
5839+copyright\-page
5840+T}@T{
5841+frontmatter
5842+T}
5843+T{
5844+dedication
5845+T}@T{
5846+frontmatter
5847+T}
5848+T{
5849+foreword
5850+T}@T{
5851+frontmatter
5852+T}
5853+T{
5854+halftitle,
5855+T}@T{
5856+frontmatter
5857+T}
5858+T{
5859+introduction
5860+T}@T{
5861+frontmatter
5862+T}
5863+T{
5864+preface
5865+T}@T{
5866+frontmatter
5867+T}
5868+T{
5869+seriespage
5870+T}@T{
5871+frontmatter
5872+T}
5873+T{
5874+titlepage
5875+T}@T{
5876+frontmatter
5877+T}
5878+T{
5879+afterword
5880+T}@T{
5881+backmatter
5882+T}
5883+T{
5884+appendix
5885+T}@T{
5886+backmatter
5887+T}
5888+T{
5889+colophon
5890+T}@T{
5891+backmatter
5892+T}
5893+T{
5894+conclusion
5895+T}@T{
5896+backmatter
5897+T}
5898+T{
5899+epigraph
5900+T}@T{
5901+backmatter
5902+T}
5903+.TE
57515904.SS Linked media
57525905.PP
5753−By default, pandoc will download linked media (including audio and
5754−video) and include it in the EPUB container, yielding a completely
5755−self\-contained EPUB.
5906+By default, pandoc will download media referenced from any
5907+\f[C]<img>\f[], \f[C]<audio>\f[], \f[C]<video>\f[] or \f[C]<source>\f[]
5908+element present in the generated EPUB, and include it in the EPUB
5909+container, yielding a completely self\-contained EPUB.
57565910If you want to link to external media resources instead, use raw HTML in
57575911your source and add \f[C]data\-external="1"\f[] to the tag with the
57585912\f[C]src\f[] attribute.
@@ -5771,8 +5925,9 @@ For example:
57715925.PP
57725926Pandoc will automatically highlight syntax in fenced code blocks that
57735927are marked with a language name.
5774−The Haskell library skylighting is used for highlighting, which works in
5775−HTML, Docx, Ms, and LaTeX/PDF output.
5928+The Haskell library skylighting is used for highlighting.
5929+Currently highlighting is supported only for HTML, EPUB, Docx, Ms, and
5930+LaTeX/PDF output.
57765931To see a list of language names that pandoc will recognize, type
57775932\f[C]pandoc\ \-\-list\-highlight\-languages\f[].
57785933.PP
@@ -5784,6 +5939,33 @@ pygments is not actually used to do the highlighting).
57845939To see a list of highlight styles, type
57855940\f[C]pandoc\ \-\-list\-highlight\-styles\f[].
57865941.PP
5942+If you are not satisfied with the predefined styles, you can use
5943+\f[C]\-\-print\-highlight\-style\f[] to generate a JSON
5944+\f[C]\&.theme\f[] file which can be modified and used as the argument to
5945+\f[C]\-\-highlight\-style\f[].
5946+To get a JSON version of the \f[C]pygments\f[] style, for example:
5947+.IP
5948+.nf
5949+\f[C]
5950+pandoc\ \-\-print\-highlight\-style\ pygments\ >\ my.theme
5951+\f[]
5952+.fi
5953+.PP
5954+Then edit \f[C]my.theme\f[] and use it like this:
5955+.IP
5956+.nf
5957+\f[C]
5958+pandoc\ \-\-highlight\-style\ my.theme
5959+\f[]
5960+.fi
5961+.PP
5962+If you are not satisfied with the built\-in highlighting, or you want
5963+highlight a language that isn\[aq]t supported, you can use the
5964+\f[C]\-\-syntax\-definition\f[] option to load a KDE\-style XML syntax
5965+definition file.
5966+Before writing your own, have a look at KDE\[aq]s repository of syntax
5967+definitions.
5968+.PP
57875969To disable highlighting, use the \f[C]\-\-no\-highlight\f[] option.
57885970.SH CUSTOM STYLES IN DOCX
57895971.SS Input
pandoc.cabal+36−34
@@ -1,6 +1,6 @@
11name: pandoc
2−version: 2.2.1
3−cabal-version: >= 1.10
2+version: 2.4
3+cabal-version: 2.0
44build-type: Custom
55license: GPL-2
66license-file: COPYING.md
@@ -11,7 +11,7 @@ bug-reports: https://github.com/jgm/pandoc/issues
1111stability: alpha
1212homepage: https://pandoc.org
1313category: Text
14−tested-with: GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.1
14+tested-with: GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3
1515synopsis: Conversion between markup formats
1616description: Pandoc is a Haskell library for converting from one markup
1717 format to another, and a command-line tool that uses
@@ -192,6 +192,8 @@ extra-source-files:
192192 test/command/inkscape-cube.svg
193193 test/command/sub-file-chapter-1.tex
194194 test/command/sub-file-chapter-2.tex
195+ test/command/bar.tex
196+ test/command/yaml-metadata.yaml
195197 test/command/3510-subdoc.org
196198 test/command/3510-export.latex
197199 test/command/3510-src.hs
@@ -334,15 +336,11 @@ flag trypandoc
334336 Description: Build trypandoc cgi executable.
335337 Default: False
336338
337−flag network-uri
338− Description: Get Network.URI from the network-uri package
339− Default: True
340−
341339custom-setup
342− setup-depends: base, Cabal
340+ setup-depends: base, Cabal >= 2.0
343341
344342library
345− build-depends: base >= 4.7 && < 5,
343+ build-depends: base >= 4.8 && < 5,
346344 syb >= 0.1 && < 0.8,
347345 containers >= 0.4.2.1 && < 0.6,
348346 unordered-containers >= 0.2 && < 0.3,
@@ -358,40 +356,46 @@ library
358356 safe >= 0.3 && < 0.4,
359357 zip-archive >= 0.2.3.4 && < 0.4,
360358 HTTP >= 4000.0.5 && < 4000.4,
361− texmath >= 0.10 && < 0.12,
359+ texmath >= 0.11 && < 0.12,
362360 xml >= 1.3.12 && < 1.4,
363361 split >= 0.2 && < 0.3,
364362 random >= 1 && < 1.2,
365− pandoc-types >= 1.17.4.2 && < 1.18,
366− aeson >= 0.7 && < 1.4,
363+ pandoc-types >= 1.17.5 && < 1.18,
364+ aeson >= 0.7 && < 1.5,
367365 aeson-pretty >= 0.8.5 && < 0.9,
368366 tagsoup >= 0.14.6 && < 0.15,
369367 base64-bytestring >= 0.1 && < 1.1,
370368 zlib >= 0.5 && < 0.7,
371− skylighting >= 0.5.1 && < 0.8,
369+ skylighting >= 0.7.2 && < 0.8,
372370 data-default >= 0.4 && < 0.8,
373371 temporary >= 1.1 && < 1.4,
374372 blaze-html >= 0.9 && < 0.10,
375373 blaze-markup >= 0.8 && < 0.9,
376− yaml >= 0.8.8.2 && < 0.9,
377− scientific >= 0.2 && < 0.4,
378374 vector >= 0.10 && < 0.13,
379− hslua >= 0.9.5 && < 0.9.6,
380− hslua-module-text >= 0.1.2 && < 0.2,
375+ hslua >= 1.0.1 && < 1.1,
376+ hslua-module-text >= 0.2 && < 0.3,
381377 binary >= 0.5 && < 0.10,
382378 SHA >= 1.6 && < 1.7,
383− haddock-library >= 1.1 && < 1.6,
379+ haddock-library >= 1.6 && < 1.7,
384380 deepseq >= 1.3 && < 1.5,
385− JuicyPixels >= 3.1.6.1 && < 3.3,
381+ JuicyPixels >= 3.1.6.1 && < 3.4,
386382 Glob >= 0.7 && < 0.10,
387383 cmark-gfm >= 0.1.1 && < 0.2,
388384 doctemplates >= 0.2.1 && < 0.3,
385+ network-uri >= 2.6 && < 2.7,
386+ network >= 2.6,
389387 http-client >= 0.4.30 && < 0.6,
390388 http-client-tls >= 0.2.4 && < 0.4,
391389 http-types >= 0.8 && < 0.13,
392− case-insensitive >= 1.2 && < 1.3
390+ case-insensitive >= 1.2 && < 1.3,
391+ unicode-transforms >= 0.3 && < 0.4,
392+ HsYAML >= 0.1.1.1 && < 0.2
393393 if impl(ghc < 8.0)
394− build-depends: semigroups == 0.18.*
394+ build-depends: semigroups == 0.18.*,
395+ -- basement 0.0.8 and foundation 0.0.21, transitive
396+ -- dependencies, drop support for ghc 7.10:
397+ basement < 0.0.8,
398+ foundation < 0.0.21
395399 if impl(ghc < 8.4)
396400 hs-source-dirs: prelude
397401 other-modules: Prelude
@@ -400,10 +404,6 @@ library
400404 cpp-options: -D_WINDOWS
401405 else
402406 build-depends: unix >= 2.4 && < 2.8
403− if flag(network-uri)
404− build-depends: network-uri >= 2.6 && < 2.7, network >= 2.6
405− else
406− build-depends: network >= 2 && < 2.6
407407 if flag(embed_data_files)
408408 cpp-options: -DEMBED_DATA_FILES
409409 build-depends: file-embed >= 0.0 && < 0.1
@@ -510,6 +510,8 @@ library
510510 Text.Pandoc.Readers.Docx.Util,
511511 Text.Pandoc.Readers.Docx.StyleMap,
512512 Text.Pandoc.Readers.Docx.Fields,
513+ Text.Pandoc.Readers.LaTeX.Parsing,
514+ Text.Pandoc.Readers.LaTeX.Lang,
513515 Text.Pandoc.Readers.Odt.Base,
514516 Text.Pandoc.Readers.Odt.Namespaces,
515517 Text.Pandoc.Readers.Odt.StyleReader,
@@ -546,11 +548,11 @@ library
546548 Text.Pandoc.Translations,
547549 Text.Pandoc.Slides,
548550 Paths_pandoc
549−
551+ autogen-modules: Paths_pandoc
550552 buildable: True
551553
552554executable pandoc
553− build-depends: pandoc, base >= 4.7 && < 5
555+ build-depends: pandoc, base >= 4.8 && < 5
554556 if impl(ghc < 8.0)
555557 build-depends: semigroups == 0.18.*
556558 if impl(ghc < 8.4)
@@ -590,7 +592,7 @@ benchmark weigh-pandoc
590592 main-is: weigh-pandoc.hs
591593 hs-source-dirs: benchmark
592594 build-depends: pandoc,
593− base >= 4.2 && < 5,
595+ base >= 4.8 && < 5,
594596 text,
595597 weigh >= 0.0 && < 0.1,
596598 mtl >= 2.2 && < 2.3
@@ -608,20 +610,20 @@ test-suite test-pandoc
608610 type: exitcode-stdio-1.0
609611 main-is: test-pandoc.hs
610612 hs-source-dirs: test
611− build-depends: base >= 4.2 && < 5,
613+ build-depends: base >= 4.8 && < 5,
612614 pandoc,
613− pandoc-types >= 1.17.4.2 && < 1.18,
615+ pandoc-types >= 1.17.5 && < 1.18,
614616 bytestring >= 0.9 && < 0.11,
615617 base64-bytestring >= 0.1 && < 1.1,
616618 text >= 0.11 && < 1.3,
617619 time >= 1.5 && < 1.10,
618620 directory >= 1 && < 1.4,
619621 filepath >= 1.1 && < 1.5,
620− hslua >= 0.9.5 && < 0.9.6,
622+ hslua >= 1.0 && < 1.1,
621623 process >= 1.2.3 && < 1.7,
622624 temporary >= 1.1 && < 1.4,
623625 Diff >= 0.2 && < 0.4,
624− tasty >= 0.11 && < 1.1,
626+ tasty >= 0.11 && < 1.2,
625627 tasty-hunit >= 0.9 && < 0.11,
626628 tasty-quickcheck >= 0.8 && < 0.11,
627629 tasty-golden >= 2.3 && < 2.4,
@@ -696,9 +698,9 @@ benchmark benchmark-pandoc
696698 hs-source-dirs: benchmark
697699 build-depends: pandoc,
698700 time, bytestring, containers,
699− base >= 4.2 && < 5,
701+ base >= 4.8 && < 5,
700702 text >= 0.11 && < 1.3,
701− criterion >= 1.0 && < 1.5
703+ criterion >= 1.0 && < 1.6
702704 if impl(ghc < 8.0)
703705 build-depends: semigroups == 0.18.*
704706 if impl(ghc < 8.4)
src/Text/Pandoc/App.hs+42−37
@@ -52,7 +52,7 @@ import Data.Aeson (defaultOptions)
5252import Data.Aeson.TH (deriveJSON)
5353import qualified Data.ByteString as BS
5454import qualified Data.ByteString.Lazy as B
55−import Data.Char (toLower, toUpper, isAscii, ord)
55+import Data.Char (toLower, toUpper)
5656import Data.List (find, intercalate, isPrefixOf, isSuffixOf, sort)
5757import qualified Data.Map as M
5858import Data.Maybe (fromMaybe, isJust, isNothing)
@@ -62,8 +62,7 @@ import qualified Data.Text as T
6262import qualified Data.Text.Lazy as TL
6363import qualified Data.Text.Lazy.Encoding as TE
6464import qualified Data.Text.Encoding.Error as TE
65−import Data.Yaml (decode)
66−import qualified Data.Yaml as Yaml
65+import qualified Data.YAML as YAML
6766import GHC.Generics
6867import Network.URI (URI (..), parseURI)
6968#ifdef EMBED_DATA_FILES
@@ -84,19 +83,18 @@ import System.Exit (exitSuccess)
8483import System.FilePath
8584import System.IO (nativeNewline, stdout)
8685import qualified System.IO as IO (Newline (..))
87−import System.IO.Error (isDoesNotExistError)
8886import Text.Pandoc
8987import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
9088import Text.Pandoc.Builder (setMeta, deleteMeta)
9189import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
9290import Text.Pandoc.Highlighting (highlightingStyles)
9391import Text.Pandoc.PDF (makePDF)
92+import Text.Pandoc.Readers.Markdown (yamlToMeta)
9493import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
9594import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
9695 headerShift, isURI, ordNub, safeRead, tabFilter, uriPathToPath)
9796import qualified Text.Pandoc.UTF8 as UTF8
9897import Text.Pandoc.Writers.Math (defaultKaTeXURL, defaultMathJaxURL)
99−import Text.Pandoc.XML (toEntities)
10098import Text.Printf
10199#ifndef _WINDOWS
102100import System.Posix.IO (stdOutput)
@@ -144,6 +142,13 @@ engines = map ("html",) htmlEngines ++
144142pdfEngines :: [String]
145143pdfEngines = ordNub $ map snd engines
146144
145+pdfIsNoWriterErrorMsg :: String
146+pdfIsNoWriterErrorMsg =
147+ "To create a pdf using pandoc, use " ++
148+ "-t latex|beamer|context|ms|html5" ++
149+ "\nand specify an output file with " ++
150+ ".pdf extension (-o filename.pdf)."
151+
147152pdfWriterAndProg :: Maybe String -- ^ user-specified writer name
148153 -> Maybe String -- ^ user-specified pdf-engine
149154 -> IO (String, Maybe String) -- ^ IO (writerName, maybePdfEngineProg)
@@ -155,9 +160,9 @@ pdfWriterAndProg mWriter mEngine = do
155160 where
156161 go Nothing Nothing = Right ("latex", "pdflatex")
157162 go (Just writer) Nothing = (writer,) <$> engineForWriter writer
158− go Nothing (Just engine) = (,engine) <$> writerForEngine engine
163+ go Nothing (Just engine) = (,engine) <$> writerForEngine (takeBaseName engine)
159164 go (Just writer) (Just engine) =
160− case find (== (baseWriterName writer, engine)) engines of
165+ case find (== (baseWriterName writer, takeBaseName engine)) engines of
161166 Just _ -> Right (writer, engine)
162167 Nothing -> Left $ "pdf-engine " ++ engine ++
163168 " is not compatible with output format " ++ writer
@@ -167,6 +172,7 @@ pdfWriterAndProg mWriter mEngine = do
167172 [] -> Left $
168173 "pdf-engine " ++ eng ++ " not known"
169174
175+ engineForWriter "pdf" = Left pdfIsNoWriterErrorMsg
170176 engineForWriter w = case [e | (f,e) <- engines, f == baseWriterName w] of
171177 eng : _ -> Right eng
172178 [] -> Left $
@@ -235,11 +241,7 @@ convertWithOpts opts = do
235241 else case getWriter (map toLower writerName) of
236242 Left e -> E.throwIO $ PandocAppError $
237243 if format == "pdf"
238− then e ++
239− "\nTo create a pdf using pandoc, use " ++
240− "-t latex|beamer|context|ms|html5" ++
241− "\nand specify an output file with " ++
242− ".pdf extension (-o filename.pdf)."
244+ then e ++ "\n" ++ pdfIsNoWriterErrorMsg
243245 else e
244246 Right (w, es) -> return (w :: Writer PandocIO, es)
245247
@@ -381,11 +383,10 @@ convertWithOpts opts = do
381383 "" -> tp <.> format
382384 _ -> tp
383385 Just . UTF8.toString <$>
384− (readFileStrict tp' `catchError`
386+ ((fst <$> fetchItem tp') `catchError`
385387 (\e ->
386388 case e of
387− PandocIOError _ e' |
388− isDoesNotExistError e' ->
389+ PandocResourceNotFound _ ->
389390 readDataFile ("templates" </> tp')
390391 _ -> throwError e))
391392
@@ -398,6 +399,10 @@ convertWithOpts opts = do
398399 ("application/xml", jatsCSL)
399400 return $ ("csl", jatsEncoded) : optMetadata opts
400401 else return $ optMetadata opts
402+ metadataFromFile <-
403+ case optMetadataFile opts of
404+ Nothing -> return mempty
405+ Just file -> readFileLazy file >>= yamlToMeta
401406
402407 case lookup "lang" (optMetadata opts) of
403408 Just l -> case parseBCP47 l of
@@ -437,6 +442,7 @@ convertWithOpts opts = do
437442 , writerTOCDepth = optTOCDepth opts
438443 , writerReferenceDoc = optReferenceDoc opts
439444 , writerSyntaxMap = syntaxMap
445+ , writerPreferAscii = optAscii opts
440446 }
441447
442448 let readerOpts = def{
@@ -490,6 +496,7 @@ convertWithOpts opts = do
490496 ( (if isJust (optExtractMedia opts)
491497 then fillMediaBag
492498 else return)
499+ >=> return . addNonPresentMetadata metadataFromFile
493500 >=> return . addMetadata metadata
494501 >=> applyTransforms transforms
495502 >=> applyFilters readerOpts filters' [format]
@@ -512,19 +519,10 @@ convertWithOpts opts = do
512519 let htmlFormat = format `elem`
513520 ["html","html4","html5","s5","slidy",
514521 "slideous","dzslides","revealjs"]
515− escape
516− | optAscii opts
517− , htmlFormat || format == "docbook4" ||
518− format == "docbook5" || format == "docbook" ||
519− format == "jats" || format == "opml" ||
520− format == "icml" = toEntities
521− | optAscii opts
522− , format == "ms" || format == "man" = groffEscape
523− | otherwise = id
524522 addNl = if standalone
525523 then id
526524 else (<> T.singleton '\n')
527− output <- (addNl . escape) <$> f writerOptions doc
525+ output <- addNl <$> f writerOptions doc
528526 writerFn eol outputFile =<<
529527 if optSelfContained opts && htmlFormat
530528 -- TODO not maximally efficient; change type
@@ -532,12 +530,6 @@ convertWithOpts opts = do
532530 then T.pack <$> makeSelfContained (T.unpack output)
533531 else return output
534532
535−groffEscape :: Text -> Text
536−groffEscape = T.concatMap toUchar
537− where toUchar c
538− | isAscii c = T.singleton c
539− | otherwise = T.pack $ printf "\\[u%04X]" (ord c)
540−
541533type Transform = Pandoc -> Pandoc
542534
543535isTextFormat :: String -> Bool
@@ -555,6 +547,7 @@ data Opt = Opt
555547 , optTemplate :: Maybe FilePath -- ^ Custom template
556548 , optVariables :: [(String,String)] -- ^ Template variables to set
557549 , optMetadata :: [(String, String)] -- ^ Metadata fields to set
550+ , optMetadataFile :: Maybe FilePath -- ^ Name of YAML metadata file
558551 , optOutputFile :: Maybe FilePath -- ^ Name of output file
559552 , optInputFiles :: [FilePath] -- ^ Names of input files
560553 , optNumberSections :: Bool -- ^ Number sections in LaTeX
@@ -598,7 +591,7 @@ data Opt = Opt
598591 , optPdfEngineArgs :: [String] -- ^ Flags to pass to the engine
599592 , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
600593 , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
601− , optAscii :: Bool -- ^ Use ascii characters only in html
594+ , optAscii :: Bool -- ^ Prefer ascii output
602595 , optDefaultImageExtension :: String -- ^ Default image extension
603596 , optExtractMedia :: Maybe FilePath -- ^ Path to extract embedded media
604597 , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
@@ -627,6 +620,7 @@ defaultOpts = Opt
627620 , optTemplate = Nothing
628621 , optVariables = []
629622 , optMetadata = []
623+ , optMetadataFile = Nothing
630624 , optOutputFile = Nothing
631625 , optInputFiles = []
632626 , optNumberSections = False
@@ -686,6 +680,9 @@ defaultOpts = Opt
686680 , optStripComments = False
687681 }
688682
683+addNonPresentMetadata :: Text.Pandoc.Meta -> Pandoc -> Pandoc
684+addNonPresentMetadata newmeta (Pandoc meta bs) = Pandoc (meta <> newmeta) bs
685+
689686addMetadata :: [(String, String)] -> Pandoc -> Pandoc
690687addMetadata kvs pdc = foldr addMeta (removeMetaKeys kvs pdc) kvs
691688
@@ -702,10 +699,12 @@ removeMetaKeys :: [(String,String)] -> Pandoc -> Pandoc
702699removeMetaKeys kvs pdc = foldr (deleteMeta . fst) pdc kvs
703700
704701readMetaValue :: String -> MetaValue
705−readMetaValue s = case decode (UTF8.fromString s) of
706− Just (Yaml.String t) -> MetaString $ T.unpack t
707− Just (Yaml.Bool b) -> MetaBool b
708− _ -> MetaString s
702+readMetaValue s = case YAML.decodeStrict (UTF8.fromString s) of
703+ Right [YAML.Scalar (YAML.SStr t)]
704+ -> MetaString $ T.unpack t
705+ Right [YAML.Scalar (YAML.SBool b)]
706+ -> MetaBool b
707+ _ -> MetaString s
709708
710709-- Determine default reader based on source file extensions
711710defaultReaderName :: String -> [FilePath] -> String
@@ -960,6 +959,12 @@ options =
960959 "KEY[:VALUE]")
961960 ""
962961
962+ , Option "" ["metadata-file"]
963+ (ReqArg
964+ (\arg opt -> return opt{ optMetadataFile = Just arg })
965+ "FILE")
966+ ""
967+
963968 , Option "V" ["variable"]
964969 (ReqArg
965970 (\arg opt -> do
@@ -1153,7 +1158,7 @@ options =
11531158 , Option "" ["ascii"]
11541159 (NoArg
11551160 (\opt -> return opt { optAscii = True }))
1156− "" -- "Use ascii characters only in HTML output"
1161+ "" -- "Prefer ASCII output"
11571162
11581163 , Option "" ["reference-links"]
11591164 (NoArg
src/Text/Pandoc/Class.hs+3−3
@@ -132,7 +132,7 @@ import Network.HTTP.Client.Internal (addProxy)
132132import Network.HTTP.Client.TLS (tlsManagerSettings)
133133import System.Environment (getEnv)
134134import Network.HTTP.Types.Header ( hContentType )
135−import Network (withSocketsDo)
135+import Network.Socket (withSocketsDo)
136136import Data.ByteString.Lazy (toChunks)
137137import qualified Control.Exception as E
138138import qualified Data.Time.LocalTime as IO (getCurrentTimeZone)
@@ -882,10 +882,10 @@ adjustImagePath _ _ x = x
882882-- of things that would normally be obtained through IO.
883883data PureState = PureState { stStdGen :: StdGen
884884 , stWord8Store :: [Word8] -- should be
885− -- inifinite,
885+ -- infinite,
886886 -- i.e. [1..]
887887 , stUniqStore :: [Int] -- should be
888− -- inifinite and
888+ -- infinite and
889889 -- contain every
890890 -- element at most
891891 -- once, e.g. [1..]
src/Text/Pandoc/Emoji.hs+6−1
@@ -28,9 +28,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2828
2929Emoji symbol lookup from canonical string identifier.
3030-}
31−module Text.Pandoc.Emoji ( emojis ) where
31+module Text.Pandoc.Emoji ( emojis, emojiToInline ) where
3232import Prelude
3333import qualified Data.Map as M
34+import Text.Pandoc.Definition (Inline (Span, Str))
3435
3536emojis :: M.Map String String
3637emojis = M.fromList
@@ -905,3 +906,7 @@ emojis = M.fromList
905906 ,("zero","0\65039\8419")
906907 ,("zzz","\128164")
907908 ]
909+
910+emojiToInline :: String -> Maybe Inline
911+emojiToInline emojikey = makeSpan <$> M.lookup emojikey emojis
912+ where makeSpan = Span ("", ["emoji"], [("data-emoji", emojikey)]) . (:[]) . Str
src/Text/Pandoc/Extensions.hs+5−2
@@ -101,7 +101,10 @@ data Extension =
101101 -- and disallow laziness
102102 | Ext_definition_lists -- ^ Definition lists as in pandoc, mmd, php
103103 | Ext_east_asian_line_breaks -- ^ Newlines in paragraphs are ignored between
104− -- East Asian wide characters
104+ -- East Asian wide characters. Note: this extension
105+ -- does not affect readers/writers directly; it causes
106+ -- the eastAsianLineBreakFilter to be applied after
107+ -- parsing, in Text.Pandoc.App.convertWithOpts.
105108 | Ext_emoji -- ^ Support emoji like :smile:
106109 | Ext_empty_paragraphs -- ^ Allow empty paragraphs
107110 | Ext_epub_html_exts -- ^ Recognise the EPUB extended version of HTML
@@ -111,7 +114,7 @@ data Extension =
111114 | Ext_fenced_code_attributes -- ^ Allow attributes on fenced code blocks
112115 | Ext_fenced_code_blocks -- ^ Parse fenced code blocks
113116 | Ext_fenced_divs -- ^ Allow fenced div syntax :::
114− | Ext_footnotes -- ^ Pandoc/PHP/MMD style footnotes
117+ | Ext_footnotes -- ^ Pandoc\/PHP\/MMD style footnotes
115118 | Ext_four_space_rule -- ^ Require 4-space indent for list contents
116119 | Ext_gfm_auto_identifiers -- ^ Automatic identifiers for headers, using
117120 -- GitHub's method for generating identifiers
src/Text/Pandoc/Highlighting.hs+1
@@ -45,6 +45,7 @@ module Text.Pandoc.Highlighting ( highlightingStyles
4545 , tango
4646 , kate
4747 , monochrome
48+ , breezeDark
4849 , haddock
4950 , Style
5051 , fromListingsLanguage
src/Text/Pandoc/ImageSize.hs+30−25
@@ -319,20 +319,22 @@ pngSize img = do
319319 (shift w1 24 + shift w2 16 + shift w3 8 + w4,
320320 shift h1 24 + shift h2 16 + shift h3 8 + h4)
321321 _ -> Nothing -- "PNG parse error"
322− let (dpix, dpiy) = findpHYs rest''
322+ (dpix, dpiy) <- findpHYs rest''
323323 return ImageSize { pxX = x, pxY = y, dpiX = dpix, dpiY = dpiy }
324324
325−findpHYs :: ByteString -> (Integer, Integer)
325+findpHYs :: ByteString -> Maybe (Integer, Integer)
326326findpHYs x
327− | B.null x || "IDAT" `B.isPrefixOf` x = (72,72)
327+ | B.null x || "IDAT" `B.isPrefixOf` x = return (72,72)
328328 | "pHYs" `B.isPrefixOf` x =
329− let [x1,x2,x3,x4,y1,y2,y3,y4,u] =
330− map fromIntegral $ unpack $ B.take 9 $ B.drop 4 x
331− factor = if u == 1 -- dots per meter
332− then \z -> z * 254 `div` 10000
333− else const 72
334− in ( factor $ shift x1 24 + shift x2 16 + shift x3 8 + x4,
335− factor $ shift y1 24 + shift y2 16 + shift y3 8 + y4 )
329+ case map fromIntegral $ unpack $ B.take 9 $ B.drop 4 x of
330+ [x1,x2,x3,x4,y1,y2,y3,y4,u] -> do
331+ let factor = if u == 1 -- dots per meter
332+ then \z -> z * 254 `div` 10000
333+ else const 72
334+ return
335+ ( factor $ shift x1 24 + shift x2 16 + shift x3 8 + x4,
336+ factor $ shift y1 24 + shift y2 16 + shift y3 8 + y4 )
337+ _ -> mzero
336338 | otherwise = findpHYs $ B.drop 1 x -- read another byte
337339
338340gifSize :: ByteString -> Maybe ImageSize
@@ -408,20 +410,21 @@ jpegSize img =
408410
409411jfifSize :: ByteString -> Either String ImageSize
410412jfifSize rest =
411− let [dpiDensity,dpix1,dpix2,dpiy1,dpiy2] = map fromIntegral
412− $ unpack $ B.take 5 $B.drop 9 rest
413− factor = case dpiDensity of
414− 1 -> id
415− 2 -> \x -> x * 254 `div` 10
416− _ -> const 72
417− dpix = factor (shift dpix1 8 + dpix2)
418− dpiy = factor (shift dpiy1 8 + dpiy2)
419− in case findJfifSize rest of
420− Left msg -> Left msg
421− Right (w,h) ->Right ImageSize { pxX = w
413+ case map fromIntegral $ unpack $ B.take 5 $ B.drop 9 rest of
414+ [dpiDensity,dpix1,dpix2,dpiy1,dpiy2] ->
415+ let factor = case dpiDensity of
416+ 1 -> id
417+ 2 -> \x -> x * 254 `div` 10
418+ _ -> const 72
419+ dpix = factor (shift dpix1 8 + dpix2)
420+ dpiy = factor (shift dpiy1 8 + dpiy2)
421+ in case findJfifSize rest of
422+ Left msg -> Left msg
423+ Right (w,h) -> Right ImageSize { pxX = w
422424 , pxY = h
423425 , dpiX = dpix
424426 , dpiY = dpiy }
427+ _ -> Left "unable to determine JFIF size"
425428
426429findJfifSize :: ByteString -> Either String (Integer,Integer)
427430findJfifSize bs =
@@ -541,10 +544,12 @@ exifHeader hdr = do
541544 let resfactor = case lookup ResolutionUnit allentries of
542545 Just (UnsignedShort 1) -> 100 / 254
543546 _ -> 1
544− let xres = maybe 72 (\(UnsignedRational x) -> floor $ x * resfactor)
545− $ lookup XResolution allentries
546− let yres = maybe 72 (\(UnsignedRational x) -> floor $ x * resfactor)
547− $ lookup YResolution allentries
547+ let xres = case lookup XResolution allentries of
548+ Just (UnsignedRational x) -> floor (x * resfactor)
549+ _ -> 72
550+ let yres = case lookup YResolution allentries of
551+ Just (UnsignedRational y) -> floor (y * resfactor)
552+ _ -> 72
548553 return ImageSize{
549554 pxX = wdth
550555 , pxY = hght
src/Text/Pandoc/Lua.hs+12−14
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2017–2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -16,6 +15,7 @@ You should have received a copy of the GNU General Public License
1615along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
18+{-# LANGUAGE NoImplicitPrelude #-}
1919{- |
2020 Module : Text.Pandoc.Lua
2121 Copyright : Copyright © 2017–2018 Albert Krewinkel
@@ -34,14 +34,14 @@ module Text.Pandoc.Lua
3434
3535import Prelude
3636import Control.Monad ((>=>))
37−import Foreign.Lua (FromLuaStack (peek), Lua, LuaException (..),
38− Status (OK), ToLuaStack (push))
37+import Foreign.Lua (Lua)
3938import Text.Pandoc.Class (PandocIO)
4039import Text.Pandoc.Definition (Pandoc)
4140import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
42−import Text.Pandoc.Lua.Init (runPandocLua, registerScriptPath)
43−import Text.Pandoc.Lua.Util (popValue)
41+import Text.Pandoc.Lua.Init (LuaException (..), runPandocLua, registerScriptPath)
42+import Text.Pandoc.Lua.Util (dofileWithTraceback)
4443import Text.Pandoc.Options (ReaderOptions)
44+
4545import qualified Foreign.Lua as Lua
4646
4747-- | Run the Lua filter in @filterPath@ for a transformation to target
@@ -59,26 +59,24 @@ runLuaFilter' ropts filterPath format pd = do
5959 registerReaderOptions
6060 registerScriptPath filterPath
6161 top <- Lua.gettop
62− stat <- Lua.dofile filterPath
63− if stat /= OK
64− then do
65− luaErrMsg <- popValue
66− Lua.throwLuaError luaErrMsg
62+ stat <- dofileWithTraceback filterPath
63+ if stat /= Lua.OK
64+ then Lua.throwTopMessage
6765 else do
6866 newtop <- Lua.gettop
6967 -- Use the returned filters, or the implicitly defined global filter if
7068 -- nothing was returned.
7169 luaFilters <- if newtop - top >= 1
72− then peek (-1)
73− else Lua.getglobal "_G" *> fmap (:[]) popValue
70+ then Lua.peek Lua.stackTop
71+ else Lua.pushglobaltable *> fmap (:[]) Lua.popValue
7472 runAll luaFilters pd
7573 where
7674 registerFormat = do
77− push format
75+ Lua.push format
7876 Lua.setglobal "FORMAT"
7977
8078 registerReaderOptions = do
81− push ropts
79+ Lua.push ropts
8280 Lua.setglobal "PANDOC_READER_OPTIONS"
8381
8482runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
src/Text/Pandoc/Lua/Filter.hs+81−63
@@ -1,6 +1,33 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+{-
2+Copyright © 2012-2018 John MacFarlane <jgm@berkeley.edu>
3+ 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
4+
5+This program is free software; you can redistribute it and/or modify
6+it under the terms of the GNU General Public License as published by
7+the Free Software Foundation; either version 2 of the License, or
8+(at your option) any later version.
9+
10+This program is distributed in the hope that it will be useful,
11+but WITHOUT ANY WARRANTY; without even the implied warranty of
12+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+GNU General Public License for more details.
14+
15+You should have received a copy of the GNU General Public License
16+along with this program; if not, write to the Free Software
17+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18+-}
219{-# LANGUAGE FlexibleContexts #-}
3−
20+{-# LANGUAGE NoImplicitPrelude #-}
21+{- |
22+Module : Text.Pandoc.Lua.Filter
23+Copyright : © 2012–2018 John MacFarlane,
24+ © 2017-2018 Albert Krewinkel
25+License : GNU GPL, version 2 or above
26+Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
27+Stability : alpha
28+
29+Types and functions for running Lua filters.
30+-}
431module Text.Pandoc.Lua.Filter ( LuaFilterFunction
532 , LuaFilter
633 , tryFilter
@@ -12,62 +39,58 @@ module Text.Pandoc.Lua.Filter ( LuaFilterFunction
1239 , inlineElementNames
1340 ) where
1441import Prelude
15−import Control.Monad (mplus, unless, when, (>=>))
42+import Control.Monad (mplus, (>=>))
1643import Control.Monad.Catch (finally)
17−import Text.Pandoc.Definition
44+import Data.Data (Data, DataType, dataTypeConstrs, dataTypeName, dataTypeOf,
45+ showConstr, toConstr, tyconUQname)
1846import Data.Foldable (foldrM)
1947import Data.Map (Map)
20−import qualified Data.Map as Map
21−import qualified Foreign.Lua as Lua
22−import Foreign.Lua (FromLuaStack (peek), Lua, StackIndex,
23− Status (OK), ToLuaStack (push))
48+import Foreign.Lua (Lua, Peekable, Pushable)
49+import Text.Pandoc.Definition
50+import Text.Pandoc.Lua.StackInstances ()
2451import Text.Pandoc.Walk (walkM, Walkable)
25−import Data.Data (Data, DataType, dataTypeConstrs, dataTypeName, dataTypeOf,
26− showConstr, toConstr, tyconUQname)
27−import Text.Pandoc.Lua.StackInstances()
28−import Text.Pandoc.Lua.Util (typeCheck)
2952
30−type FunctionMap = Map String LuaFilterFunction
31−
32−newtype LuaFilterFunction = LuaFilterFunction { functionIndex :: Int }
33−
34−instance ToLuaStack LuaFilterFunction where
35− push = pushFilterFunction
36−
37−instance FromLuaStack LuaFilterFunction where
38− peek = registerFilterFunction
39−
40−newtype LuaFilter = LuaFilter FunctionMap
41−
42−instance FromLuaStack LuaFilter where
43− peek idx =
44− let constrs = metaFilterName : pandocFilterNames
45− ++ blockElementNames
46− ++ inlineElementNames
47− fn c acc = do
48− Lua.getfield idx c
49− filterFn <- Lua.tryLua (peek (-1))
50− Lua.pop 1
53+import qualified Data.Map.Strict as Map
54+import qualified Foreign.Lua as Lua
55+import qualified Text.Pandoc.Lua.Util as LuaUtil
56+
57+-- | Filter function stored in the registry
58+newtype LuaFilterFunction = LuaFilterFunction Lua.Reference
59+
60+-- | Collection of filter functions (at most one function per element
61+-- constructor)
62+newtype LuaFilter = LuaFilter (Map String LuaFilterFunction)
63+
64+instance Peekable LuaFilter where
65+ peek idx = do
66+ let constrs = metaFilterName
67+ : pandocFilterNames
68+ ++ blockElementNames
69+ ++ inlineElementNames
70+ let go constr acc = do
71+ Lua.getfield idx constr
72+ filterFn <- registerFilterFunction
5173 return $ case filterFn of
52− Left _ -> acc
53− Right f -> (c, f) : acc
54− in LuaFilter . Map.fromList <$> foldrM fn [] constrs
55−
56−-- | Push the filter function to the top of the stack.
74+ Nothing -> acc
75+ Just fn -> Map.insert constr fn acc
76+ LuaFilter <$> foldrM go Map.empty constrs
77+
78+-- | Register the function at the top of the stack as a filter function in the
79+-- registry.
80+registerFilterFunction :: Lua (Maybe LuaFilterFunction)
81+registerFilterFunction = do
82+ isFn <- Lua.isfunction Lua.stackTop
83+ if isFn
84+ then Just . LuaFilterFunction <$> Lua.ref Lua.registryindex
85+ else Nothing <$ Lua.pop 1
86+
87+-- | Retrieve filter function from registry and push it to the top of the stack.
5788pushFilterFunction :: LuaFilterFunction -> Lua ()
58−pushFilterFunction lf =
59− -- The function is stored in a lua registry table, retrieve it from there.
60− Lua.rawgeti Lua.registryindex (functionIndex lf)
61−
62−registerFilterFunction :: StackIndex -> Lua LuaFilterFunction
63−registerFilterFunction idx = do
64− isFn <- Lua.isfunction idx
65− unless isFn . Lua.throwLuaError $ "Not a function at index " ++ show idx
66− Lua.pushvalue idx
67− refIdx <- Lua.ref Lua.registryindex
68− return $ LuaFilterFunction refIdx
69−
70−elementOrList :: FromLuaStack a => a -> Lua [a]
89+pushFilterFunction (LuaFilterFunction fnRef) =
90+ Lua.getref Lua.registryindex fnRef
91+
92+
93+elementOrList :: Peekable a => a -> Lua [a]
7194elementOrList x = do
7295 let topOfStack = Lua.stackTop
7396 elementUnchanged <- Lua.isnil topOfStack
@@ -77,12 +100,10 @@ elementOrList x = do
77100 mbres <- Lua.peekEither topOfStack
78101 case mbres of
79102 Right res -> [res] <$ Lua.pop 1
80− Left _ -> do
81− typeCheck Lua.stackTop Lua.TypeTable
82− Lua.toList topOfStack `finally` Lua.pop 1
103+ Left _ -> Lua.peekList topOfStack `finally` Lua.pop 1
83104
84105-- | Try running a filter for the given element
85−tryFilter :: (Data a, FromLuaStack a, ToLuaStack a)
106+tryFilter :: (Data a, Peekable a, Pushable a)
86107 => LuaFilter -> a -> Lua [a]
87108tryFilter (LuaFilter fnMap) x =
88109 let filterFnName = showConstr (toConstr x)
@@ -96,14 +117,11 @@ tryFilter (LuaFilter fnMap) x =
96117-- called with given element as argument and is expected to return an element.
97118-- Alternatively, the function can return nothing or nil, in which case the
98119-- element is left unchanged.
99−runFilterFunction :: ToLuaStack a => LuaFilterFunction -> a -> Lua ()
120+runFilterFunction :: Pushable a => LuaFilterFunction -> a -> Lua ()
100121runFilterFunction lf x = do
101122 pushFilterFunction lf
102− push x
103− z <- Lua.pcall 1 1 Nothing
104− when (z /= OK) $ do
105− let addPrefix = ("Error while running filter function: " ++)
106− Lua.throwTopMessageAsError' addPrefix
123+ Lua.push x
124+ LuaUtil.callWithTraceback 1 1
107125
108126walkMWithLuaFilter :: LuaFilter -> Pandoc -> Lua Pandoc
109127walkMWithLuaFilter f =
@@ -156,7 +174,7 @@ metaFilterName = "Meta"
156174pandocFilterNames :: [String]
157175pandocFilterNames = ["Pandoc", "Doc"]
158176
159−singleElement :: FromLuaStack a => a -> Lua a
177+singleElement :: Peekable a => a -> Lua a
160178singleElement x = do
161179 elementUnchanged <- Lua.isnil (-1)
162180 if elementUnchanged
@@ -167,6 +185,6 @@ singleElement x = do
167185 Right res -> res <$ Lua.pop 1
168186 Left err -> do
169187 Lua.pop 1
170− Lua.throwLuaError $
188+ Lua.throwException $
171189 "Error while trying to get a filter's return " ++
172190 "value from lua stack.\n" ++ err
src/Text/Pandoc/Lua/Init.hs+10−5
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -16,6 +15,7 @@ You should have received a copy of the GNU General Public License
1615along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
18+{-# LANGUAGE NoImplicitPrelude #-}
1919{- |
2020 Module : Text.Pandoc.Lua
2121 Copyright : Copyright © 2017-2018 Albert Krewinkel
@@ -40,7 +40,7 @@ import Control.Monad.Trans (MonadIO (..))
4040import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
4141import Data.IORef (newIORef, readIORef)
4242import Data.Version (Version (versionBranch))
43−import Foreign.Lua (Lua, LuaException (..))
43+import Foreign.Lua (Lua)
4444import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
4545import Paths_pandoc (version)
4646import Text.Pandoc.Class (PandocIO, getCommonState, getUserDataDir, getMediaBag,
@@ -54,17 +54,22 @@ import qualified Foreign.Lua as Lua
5454import qualified Foreign.Lua.Module.Text as Lua
5555import qualified Text.Pandoc.Definition as Pandoc
5656
57+-- | Lua error message
58+newtype LuaException = LuaException String deriving (Show)
59+
5760-- | Run the lua interpreter, using pandoc's default way of environment
58−-- initalization.
61+-- initialization.
5962runPandocLua :: Lua a -> PandocIO (Either LuaException a)
6063runPandocLua luaOp = do
6164 luaPkgParams <- luaPackageParams
6265 enc <- liftIO $ getForeignEncoding <* setForeignEncoding utf8
63− res <- liftIO $ Lua.runLuaEither (initLuaState luaPkgParams *> luaOp)
66+ res <- liftIO $ Lua.runEither (initLuaState luaPkgParams *> luaOp)
6467 liftIO $ setForeignEncoding enc
6568 newMediaBag <- liftIO (readIORef (luaPkgMediaBag luaPkgParams))
6669 setMediaBag newMediaBag
67− return res
70+ return $ case res of
71+ Left (Lua.Exception msg) -> Left (LuaException msg)
72+ Right x -> Right x
6873
6974-- | Generate parameters required to setup pandoc's lua environment.
7075luaPackageParams :: PandocIO LuaPackageParams
src/Text/Pandoc/Lua/Module/MediaBag.hs+1−1
@@ -87,7 +87,7 @@ mediaDirectoryFn mbRef = do
8787 zipWithM_ addEntry [1..] dirContents
8888 return 1
8989 where
90− addEntry :: Int -> (FilePath, MimeType, Int) -> Lua ()
90+ addEntry :: Lua.Integer -> (FilePath, MimeType, Int) -> Lua ()
9191 addEntry idx (fp, mimeType, contentLength) = do
9292 Lua.newtable
9393 Lua.push "path" *> Lua.push fp *> Lua.rawset (-3)
src/Text/Pandoc/Lua/Module/Pandoc.hs+18−17
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -17,6 +16,7 @@ along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
1918{-# LANGUAGE FlexibleContexts #-}
19+{-# LANGUAGE NoImplicitPrelude #-}
2020{- |
2121 Module : Text.Pandoc.Lua.Module.Pandoc
2222 Copyright : Copyright © 2017-2018 Albert Krewinkel
@@ -36,13 +36,12 @@ import Control.Monad (when)
3636import Data.Default (Default (..))
3737import Data.Maybe (fromMaybe)
3838import Data.Text (pack)
39−import Foreign.Lua (ToLuaStack, FromLuaStack, Lua, NumResults, Optional, liftIO)
39+import Foreign.Lua (Lua, NumResults, Optional, Peekable, Pushable)
4040import System.Exit (ExitCode (..))
4141import Text.Pandoc.Class (runIO)
4242import Text.Pandoc.Definition (Block, Inline)
4343import Text.Pandoc.Lua.Filter (walkInlines, walkBlocks, LuaFilter)
4444import Text.Pandoc.Lua.StackInstances ()
45−import Text.Pandoc.Lua.Util (addFunction, addValue, loadScriptFromDataDir)
4645import Text.Pandoc.Walk (Walkable)
4746import Text.Pandoc.Options (ReaderOptions (readerExtensions))
4847import Text.Pandoc.Process (pipeProcess)
@@ -51,19 +50,20 @@ import Text.Pandoc.Readers (Reader (..), getReader)
5150import qualified Data.ByteString.Lazy as BL
5251import qualified Data.ByteString.Lazy.Char8 as BSL
5352import qualified Foreign.Lua as Lua
53+import qualified Text.Pandoc.Lua.Util as LuaUtil
5454
5555-- | Push the "pandoc" on the lua stack. Requires the `list` module to be
5656-- loaded.
5757pushModule :: Maybe FilePath -> Lua NumResults
5858pushModule datadir = do
59− loadScriptFromDataDir datadir "pandoc.lua"
60− addFunction "read" readDoc
61− addFunction "pipe" pipeFn
62− addFunction "walk_block" walkBlock
63− addFunction "walk_inline" walkInline
59+ LuaUtil.loadScriptFromDataDir datadir "pandoc.lua"
60+ LuaUtil.addFunction "read" readDoc
61+ LuaUtil.addFunction "pipe" pipeFn
62+ LuaUtil.addFunction "walk_block" walkBlock
63+ LuaUtil.addFunction "walk_inline" walkInline
6464 return 1
6565
66−walkElement :: (ToLuaStack a, Walkable [Inline] a, Walkable [Block] a)
66+walkElement :: (Pushable a, Walkable [Inline] a, Walkable [Block] a)
6767 => a -> LuaFilter -> Lua a
6868walkElement x f = walkInlines f x >>= walkBlocks f
6969
@@ -81,7 +81,8 @@ readDoc content formatSpecOrNil = do
8181 Right (reader, es) ->
8282 case reader of
8383 TextReader r -> do
84− res <- liftIO $ runIO $ r def{ readerExtensions = es } (pack content)
84+ res <- Lua.liftIO . runIO $
85+ r def{ readerExtensions = es } (pack content)
8586 case res of
8687 Right pd -> (1 :: NumResults) <$ Lua.push pd -- success, push Pandoc
8788 Left s -> Lua.raiseError (show s) -- error while reading
@@ -93,7 +94,7 @@ pipeFn :: String
9394 -> BL.ByteString
9495 -> Lua NumResults
9596pipeFn command args input = do
96− (ec, output) <- liftIO $ pipeProcess Nothing command args input
97+ (ec, output) <- Lua.liftIO $ pipeProcess Nothing command args input
9798 case ec of
9899 ExitSuccess -> 1 <$ Lua.push output
99100 ExitFailure n -> Lua.raiseError (PipeError command n output)
@@ -104,26 +105,26 @@ data PipeError = PipeError
104105 , pipeErrorOutput :: BL.ByteString
105106 }
106107
107−instance FromLuaStack PipeError where
108+instance Peekable PipeError where
108109 peek idx =
109110 PipeError
110111 <$> (Lua.getfield idx "command" *> Lua.peek (-1) <* Lua.pop 1)
111112 <*> (Lua.getfield idx "error_code" *> Lua.peek (-1) <* Lua.pop 1)
112113 <*> (Lua.getfield idx "output" *> Lua.peek (-1) <* Lua.pop 1)
113114
114−instance ToLuaStack PipeError where
115+instance Pushable PipeError where
115116 push pipeErr = do
116117 Lua.newtable
117− addValue "command" (pipeErrorCommand pipeErr)
118− addValue "error_code" (pipeErrorCode pipeErr)
119− addValue "output" (pipeErrorOutput pipeErr)
118+ LuaUtil.addField "command" (pipeErrorCommand pipeErr)
119+ LuaUtil.addField "error_code" (pipeErrorCode pipeErr)
120+ LuaUtil.addField "output" (pipeErrorOutput pipeErr)
120121 pushPipeErrorMetaTable
121122 Lua.setmetatable (-2)
122123 where
123124 pushPipeErrorMetaTable :: Lua ()
124125 pushPipeErrorMetaTable = do
125126 v <- Lua.newmetatable "pandoc pipe error"
126− when v $ addFunction "__tostring" pipeErrorMessage
127+ when v $ LuaUtil.addFunction "__tostring" pipeErrorMessage
127128
128129 pipeErrorMessage :: PipeError -> Lua BL.ByteString
129130 pipeErrorMessage (PipeError cmd errorCode output) = return $ mconcat
src/Text/Pandoc/Lua/Module/Utils.hs+22−12
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -16,6 +15,7 @@ You should have received a copy of the GNU General Public License
1615along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
18+{-# LANGUAGE NoImplicitPrelude #-}
1919{- |
2020 Module : Text.Pandoc.Lua.Module.Utils
2121 Copyright : Copyright © 2017-2018 Albert Krewinkel
@@ -33,15 +33,16 @@ module Text.Pandoc.Lua.Module.Utils
3333import Prelude
3434import Control.Applicative ((<|>))
3535import Data.Default (def)
36−import Foreign.Lua (FromLuaStack, Lua, LuaInteger, NumResults)
36+import Foreign.Lua (Peekable, Lua, NumResults)
3737import Text.Pandoc.Class (runIO, setUserDataDir)
3838import Text.Pandoc.Definition (Pandoc, Meta, MetaValue, Block, Inline)
3939import Text.Pandoc.Lua.StackInstances ()
40−import Text.Pandoc.Lua.Util (addFunction, popValue)
40+import Text.Pandoc.Lua.Util (addFunction)
4141
4242import qualified Data.Digest.Pure.SHA as SHA
4343import qualified Data.ByteString.Lazy as BSL
4444import qualified Foreign.Lua as Lua
45+import qualified Text.Pandoc.Builder as B
4546import qualified Text.Pandoc.Filter.JSON as JSONFilter
4647import qualified Text.Pandoc.Shared as Shared
4748
@@ -49,6 +50,7 @@ import qualified Text.Pandoc.Shared as Shared
4950pushModule :: Maybe FilePath -> Lua NumResults
5051pushModule mbDatadir = do
5152 Lua.newtable
53+ addFunction "blocks_to_inlines" blocksToInlines
5254 addFunction "hierarchicalize" hierarchicalize
5355 addFunction "normalize_date" normalizeDate
5456 addFunction "run_json_filter" (runJSONFilter mbDatadir)
@@ -57,6 +59,14 @@ pushModule mbDatadir = do
5759 addFunction "to_roman_numeral" toRomanNumeral
5860 return 1
5961
62+-- | Squashes a list of blocks into inlines.
63+blocksToInlines :: [Block] -> Lua.Optional [Inline] -> Lua [Inline]
64+blocksToInlines blks optSep = do
65+ let sep = case Lua.fromOptional optSep of
66+ Just x -> B.fromList x
67+ Nothing -> Shared.defaultBlocksSeparator
68+ return $ B.toList (Shared.blocksToInlinesWithSep sep blks)
69+
6070-- | Convert list of Pandoc blocks into (hierarchical) list of Elements.
6171hierarchicalize :: [Block] -> Lua [Shared.Element]
6272hierarchicalize = return . Shared.hierarchicalize
@@ -79,7 +89,7 @@ runJSONFilter mbDatadir doc filterFile optArgs = do
7989 Just x -> return x
8090 Nothing -> do
8191 Lua.getglobal "FORMAT"
82− (:[]) <$> popValue
92+ (:[]) <$> Lua.popValue
8393 filterRes <- Lua.liftIO . runIO $ do
8494 setUserDataDir mbDatadir
8595 JSONFilter.apply def args filterFile doc
@@ -111,18 +121,18 @@ data AstElement
111121 | MetaValueElement MetaValue
112122 deriving (Show)
113123
114−instance FromLuaStack AstElement where
124+instance Peekable AstElement where
115125 peek idx = do
116− res <- Lua.tryLua $ (PandocElement <$> Lua.peek idx)
117− <|> (InlineElement <$> Lua.peek idx)
118− <|> (BlockElement <$> Lua.peek idx)
119− <|> (MetaElement <$> Lua.peek idx)
120− <|> (MetaValueElement <$> Lua.peek idx)
126+ res <- Lua.try $ (PandocElement <$> Lua.peek idx)
127+ <|> (InlineElement <$> Lua.peek idx)
128+ <|> (BlockElement <$> Lua.peek idx)
129+ <|> (MetaElement <$> Lua.peek idx)
130+ <|> (MetaValueElement <$> Lua.peek idx)
121131 case res of
122132 Right x -> return x
123− Left _ -> Lua.throwLuaError
133+ Left _ -> Lua.throwException
124134 "Expected an AST element, but could not parse value as such."
125135
126136-- | Convert a number < 4000 to uppercase roman numeral.
127−toRomanNumeral :: LuaInteger -> Lua String
137+toRomanNumeral :: Lua.Integer -> Lua String
128138toRomanNumeral = return . Shared.toRomanNumeral . fromIntegral
src/Text/Pandoc/Lua/Packages.hs+12−20
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -16,8 +15,9 @@ You should have received a copy of the GNU General Public License
1615along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
19−{-# LANGUAGE ScopedTypeVariables #-}
2018{-# LANGUAGE FlexibleContexts #-}
19+{-# LANGUAGE NoImplicitPrelude #-}
20+{-# LANGUAGE ScopedTypeVariables #-}
2121{- |
2222 Module : Text.Pandoc.Lua.Packages
2323 Copyright : Copyright © 2017-2018 Albert Krewinkel
@@ -35,12 +35,11 @@ module Text.Pandoc.Lua.Packages
3535
3636import Prelude
3737import Control.Monad (forM_)
38−import Data.ByteString.Char8 (unpack)
38+import Data.ByteString (ByteString)
3939import Data.IORef (IORef)
4040import Foreign.Lua (Lua, NumResults, liftIO)
4141import Text.Pandoc.Class (CommonState, readDataFile, runIO, setUserDataDir)
4242import Text.Pandoc.MediaBag (MediaBag)
43−import Text.Pandoc.Lua.Util (dostring')
4443
4544import qualified Foreign.Lua as Lua
4645import Text.Pandoc.Lua.Module.Pandoc as Pandoc
@@ -57,14 +56,10 @@ data LuaPackageParams = LuaPackageParams
5756-- | Insert pandoc's package loader as the first loader, making it the default.
5857installPandocPackageSearcher :: LuaPackageParams -> Lua ()
5958installPandocPackageSearcher luaPkgParams = do
60− luaVersion <- Lua.getglobal "_VERSION" *> Lua.peek (-1)
61− if luaVersion == "Lua 5.1"
62− then Lua.getglobal' "package.loaders"
63− else Lua.getglobal' "package.searchers"
59+ Lua.getglobal' "package.searchers"
6460 shiftArray
6561 Lua.pushHaskellFunction (pandocPackageSearcher luaPkgParams)
66− Lua.wrapHaskellFunction
67− Lua.rawseti (-2) 1
62+ Lua.rawseti (Lua.nthFromTop 2) 1
6863 Lua.pop 1 -- remove 'package.searchers' from stack
6964 where
7065 shiftArray = forM_ [4, 3, 2, 1] $ \i -> do
@@ -86,7 +81,6 @@ pandocPackageSearcher luaPkgParams pkgName =
8681 where
8782 pushWrappedHsFun f = do
8883 Lua.pushHaskellFunction f
89− Lua.wrapHaskellFunction
9084 return 1
9185 searchPureLuaLoader = do
9286 let filename = pkgName ++ ".lua"
@@ -97,21 +91,19 @@ pandocPackageSearcher luaPkgParams pkgName =
9791 Lua.push ("no file '" ++ filename ++ "' in pandoc's datadir")
9892 return 1
9993
100−loadStringAsPackage :: String -> String -> Lua NumResults
94+loadStringAsPackage :: String -> ByteString -> Lua NumResults
10195loadStringAsPackage pkgName script = do
102− status <- dostring' script
96+ status <- Lua.dostring script
10397 if status == Lua.OK
10498 then return (1 :: NumResults)
10599 else do
106− msg <- Lua.peek (-1) <* Lua.pop 1
107− Lua.push ("Error while loading ``" ++ pkgName ++ "`.\n" ++ msg)
108− Lua.lerror
109− return (2 :: NumResults)
100+ msg <- Lua.popValue
101+ Lua.raiseError ("Error while loading `" <> pkgName <> "`.\n" <> msg)
110102
111−-- | Get the string representation of the pandoc module
112−dataDirScript :: Maybe FilePath -> FilePath -> IO (Maybe String)
103+-- | Get the ByteString representation of the pandoc module.
104+dataDirScript :: Maybe FilePath -> FilePath -> IO (Maybe ByteString)
113105dataDirScript datadir moduleFile = do
114106 res <- runIO $ setUserDataDir datadir >> readDataFile moduleFile
115107 return $ case res of
116108 Left _ -> Nothing
117− Right s -> Just (unpack s)
109+ Right s -> Just s
src/Text/Pandoc/Lua/StackInstances.hs+112−142
@@ -1,4 +1,8 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
4+{-# LANGUAGE LambdaCase #-}
5+{-# OPTIONS_GHC -fno-warn-orphans #-}
26{-
37Copyright © 2012-2018 John MacFarlane <jgm@berkeley.edu>
48 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -17,10 +21,6 @@ You should have received a copy of the GNU General Public License
1721along with this program; if not, write to the Free Software
1822Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1923-}
20−{-# LANGUAGE FlexibleInstances #-}
21−{-# LANGUAGE LambdaCase #-}
22−{-# LANGUAGE ScopedTypeVariables #-}
23−{-# OPTIONS_GHC -fno-warn-orphans #-}
2424{- |
2525 Module : Text.Pandoc.Lua.StackInstances
2626 Copyright : © 2012-2018 John MacFarlane
@@ -37,148 +37,125 @@ module Text.Pandoc.Lua.StackInstances () where
3737import Prelude
3838import Control.Applicative ((<|>))
3939import Control.Monad (when)
40−import Control.Monad.Catch (finally)
4140import Data.Data (showConstr, toConstr)
42−import Data.Foldable (forM_)
43−import Foreign.Lua (FromLuaStack (peek), Lua, LuaInteger, LuaNumber, StackIndex,
44− ToLuaStack (push), Type (..), throwLuaError, tryLua)
41+import Foreign.Lua (Lua, Peekable, Pushable, StackIndex)
4542import Text.Pandoc.Definition
4643import Text.Pandoc.Extensions (Extensions)
47−import Text.Pandoc.Lua.Util (getTable, getTag, pushViaConstructor, typeCheck)
44+import Text.Pandoc.Lua.Util (defineHowTo, pushViaConstructor)
4845import Text.Pandoc.Options (ReaderOptions (..), TrackChanges)
49−import Text.Pandoc.Shared (Element (Blk, Sec), safeRead)
46+import Text.Pandoc.Shared (Element (Blk, Sec))
5047
51−import qualified Foreign.Lua as Lua
5248import qualified Data.Set as Set
49+import qualified Foreign.Lua as Lua
5350import qualified Text.Pandoc.Lua.Util as LuaUtil
5451
55−defineHowTo :: String -> Lua a -> Lua a
56−defineHowTo ctx op = op `Lua.modifyLuaError` (("Could not " ++ ctx ++ ": ") ++)
57−
58−instance ToLuaStack Pandoc where
52+instance Pushable Pandoc where
5953 push (Pandoc meta blocks) =
6054 pushViaConstructor "Pandoc" blocks meta
6155
62−instance FromLuaStack Pandoc where
56+instance Peekable Pandoc where
6357 peek idx = defineHowTo "get Pandoc value" $ do
64− typeCheck idx Lua.TypeTable
65− blocks <- getTable idx "blocks"
66− meta <- Lua.getfield idx "meta" *> (Lua.peek Lua.stackTop `finally` Lua.pop 1)
58+ blocks <- LuaUtil.rawField idx "blocks"
59+ meta <- LuaUtil.rawField idx "meta"
6760 return $ Pandoc meta blocks
6861
69−instance ToLuaStack Meta where
62+instance Pushable Meta where
7063 push (Meta mmap) =
7164 pushViaConstructor "Meta" mmap
72−instance FromLuaStack Meta where
73− peek idx = defineHowTo "get Meta value" $ do
74− typeCheck idx Lua.TypeTable
75− Meta <$> peek idx
65+instance Peekable Meta where
66+ peek idx = defineHowTo "get Meta value" $
67+ Meta <$> Lua.peek idx
7668
77−instance ToLuaStack MetaValue where
69+instance Pushable MetaValue where
7870 push = pushMetaValue
79−instance FromLuaStack MetaValue where
71+instance Peekable MetaValue where
8072 peek = peekMetaValue
8173
82−instance ToLuaStack Block where
74+instance Pushable Block where
8375 push = pushBlock
8476
85−instance FromLuaStack Block where
77+instance Peekable Block where
8678 peek = peekBlock
8779
8880-- Inline
89−instance ToLuaStack Inline where
81+instance Pushable Inline where
9082 push = pushInline
9183
92−instance FromLuaStack Inline where
84+instance Peekable Inline where
9385 peek = peekInline
9486
9587-- Citation
96−instance ToLuaStack Citation where
88+instance Pushable Citation where
9789 push (Citation cid prefix suffix mode noteNum hash) =
9890 pushViaConstructor "Citation" cid mode prefix suffix noteNum hash
9991
100−instance FromLuaStack Citation where
92+instance Peekable Citation where
10193 peek idx = do
102− id' <- getTable idx "id"
103− prefix <- getTable idx "prefix"
104− suffix <- getTable idx "suffix"
105− mode <- getTable idx "mode"
106− num <- getTable idx "note_num"
107− hash <- getTable idx "hash"
94+ id' <- LuaUtil.rawField idx "id"
95+ prefix <- LuaUtil.rawField idx "prefix"
96+ suffix <- LuaUtil.rawField idx "suffix"
97+ mode <- LuaUtil.rawField idx "mode"
98+ num <- LuaUtil.rawField idx "note_num"
99+ hash <- LuaUtil.rawField idx "hash"
108100 return $ Citation id' prefix suffix mode num hash
109101
110−instance ToLuaStack Alignment where
111− push = push . show
112−instance FromLuaStack Alignment where
113− peek idx = safeRead' =<< peek idx
114−
115−instance ToLuaStack CitationMode where
116− push = push . show
117−instance FromLuaStack CitationMode where
118− peek idx = safeRead' =<< peek idx
119−
120−instance ToLuaStack Format where
121− push (Format f) = push f
122−instance FromLuaStack Format where
123− peek idx = Format <$> peek idx
124−
125−instance ToLuaStack ListNumberDelim where
126− push = push . show
127−instance FromLuaStack ListNumberDelim where
128− peek idx = safeRead' =<< peek idx
129−
130−instance ToLuaStack ListNumberStyle where
131− push = push . show
132−instance FromLuaStack ListNumberStyle where
133− peek idx = safeRead' =<< peek idx
134−
135−instance ToLuaStack MathType where
136− push = push . show
137−instance FromLuaStack MathType where
138− peek idx = safeRead' =<< peek idx
139−
140−instance ToLuaStack QuoteType where
141− push = push . show
142−instance FromLuaStack QuoteType where
143− peek idx = safeRead' =<< peek idx
144−
145−instance ToLuaStack Double where
146− push = push . (realToFrac :: Double -> LuaNumber)
147−instance FromLuaStack Double where
148− peek = fmap (realToFrac :: LuaNumber -> Double) . peek
149−
150−instance ToLuaStack Int where
151− push = push . (fromIntegral :: Int -> LuaInteger)
152−instance FromLuaStack Int where
153− peek = fmap (fromIntegral :: LuaInteger-> Int) . peek
154−
155−safeRead' :: Read a => String -> Lua a
156−safeRead' s = case safeRead s of
157− Nothing -> throwLuaError ("Could not read: " ++ s)
158− Just x -> return x
102+instance Pushable Alignment where
103+ push = Lua.push . show
104+instance Peekable Alignment where
105+ peek = Lua.peekRead
106+
107+instance Pushable CitationMode where
108+ push = Lua.push . show
109+instance Peekable CitationMode where
110+ peek = Lua.peekRead
111+
112+instance Pushable Format where
113+ push (Format f) = Lua.push f
114+instance Peekable Format where
115+ peek idx = Format <$> Lua.peek idx
116+
117+instance Pushable ListNumberDelim where
118+ push = Lua.push . show
119+instance Peekable ListNumberDelim where
120+ peek = Lua.peekRead
121+
122+instance Pushable ListNumberStyle where
123+ push = Lua.push . show
124+instance Peekable ListNumberStyle where
125+ peek = Lua.peekRead
126+
127+instance Pushable MathType where
128+ push = Lua.push . show
129+instance Peekable MathType where
130+ peek = Lua.peekRead
131+
132+instance Pushable QuoteType where
133+ push = Lua.push . show
134+instance Peekable QuoteType where
135+ peek = Lua.peekRead
159136
160137-- | Push an meta value element to the top of the lua stack.
161138pushMetaValue :: MetaValue -> Lua ()
162139pushMetaValue = \case
163140 MetaBlocks blcks -> pushViaConstructor "MetaBlocks" blcks
164− MetaBool bool -> push bool
141+ MetaBool bool -> Lua.push bool
165142 MetaInlines inlns -> pushViaConstructor "MetaInlines" inlns
166143 MetaList metalist -> pushViaConstructor "MetaList" metalist
167144 MetaMap metamap -> pushViaConstructor "MetaMap" metamap
168− MetaString str -> push str
145+ MetaString str -> Lua.push str
169146
170147-- | Interpret the value at the given stack index as meta value.
171148peekMetaValue :: StackIndex -> Lua MetaValue
172149peekMetaValue idx = defineHowTo "get MetaValue" $ do
173150 -- Get the contents of an AST element.
174− let elementContent :: FromLuaStack a => Lua a
175− elementContent = peek idx
151+ let elementContent :: Peekable a => Lua a
152+ elementContent = Lua.peek idx
176153 luatype <- Lua.ltype idx
177154 case luatype of
178− TypeBoolean -> MetaBool <$> peek idx
179− TypeString -> MetaString <$> peek idx
180− TypeTable -> do
181− tag <- tryLua $ getTag idx
155+ Lua.TypeBoolean -> MetaBool <$> Lua.peek idx
156+ Lua.TypeString -> MetaString <$> Lua.peek idx
157+ Lua.TypeTable -> do
158+ tag <- Lua.try $ LuaUtil.getTag idx
182159 case tag of
183160 Right "MetaBlocks" -> MetaBlocks <$> elementContent
184161 Right "MetaBool" -> MetaBool <$> elementContent
@@ -186,16 +163,16 @@ peekMetaValue idx = defineHowTo "get MetaValue" $ do
186163 Right "MetaInlines" -> MetaInlines <$> elementContent
187164 Right "MetaList" -> MetaList <$> elementContent
188165 Right "MetaString" -> MetaString <$> elementContent
189− Right t -> throwLuaError ("Unknown meta tag: " ++ t)
166+ Right t -> Lua.throwException ("Unknown meta tag: " <> t)
190167 Left _ -> do
191168 -- no meta value tag given, try to guess.
192169 len <- Lua.rawlen idx
193170 if len <= 0
194− then MetaMap <$> peek idx
195− else (MetaInlines <$> peek idx)
196− <|> (MetaBlocks <$> peek idx)
197− <|> (MetaList <$> peek idx)
198− _ -> throwLuaError "could not get meta value"
171+ then MetaMap <$> Lua.peek idx
172+ else (MetaInlines <$> Lua.peek idx)
173+ <|> (MetaBlocks <$> Lua.peek idx)
174+ <|> (MetaList <$> Lua.peek idx)
175+ _ -> Lua.throwException "could not get meta value"
199176
200177-- | Push an block element to the top of the lua stack.
201178pushBlock :: Block -> Lua ()
@@ -219,8 +196,7 @@ pushBlock = \case
219196-- | Return the value at the given index as block if possible.
220197peekBlock :: StackIndex -> Lua Block
221198peekBlock idx = defineHowTo "get Block value" $ do
222− typeCheck idx Lua.TypeTable
223− tag <- getTag idx
199+ tag <- LuaUtil.getTag idx
224200 case tag of
225201 "BlockQuote" -> BlockQuote <$> elementContent
226202 "BulletList" -> BulletList <$> elementContent
@@ -239,11 +215,11 @@ peekBlock idx = defineHowTo "get Block value" $ do
239215 "Table" -> (\(capt, aligns, widths, headers, body) ->
240216 Table capt aligns widths headers body)
241217 <$> elementContent
242− _ -> throwLuaError ("Unknown block type: " ++ tag)
218+ _ -> Lua.throwException ("Unknown block type: " <> tag)
243219 where
244220 -- Get the contents of an AST element.
245− elementContent :: FromLuaStack a => Lua a
246− elementContent = getTable idx "c"
221+ elementContent :: Peekable a => Lua a
222+ elementContent = LuaUtil.rawField idx "c"
247223
248224-- | Push an inline element to the top of the lua stack.
249225pushInline :: Inline -> Lua ()
@@ -271,8 +247,7 @@ pushInline = \case
271247-- | Return the value at the given index as inline if possible.
272248peekInline :: StackIndex -> Lua Inline
273249peekInline idx = defineHowTo "get Inline value" $ do
274− typeCheck idx Lua.TypeTable
275− tag <- getTag idx
250+ tag <- LuaUtil.getTag idx
276251 case tag of
277252 "Cite" -> uncurry Cite <$> elementContent
278253 "Code" -> withAttr Code <$> elementContent
@@ -295,11 +270,11 @@ peekInline idx = defineHowTo "get Inline value" $ do
295270 "Strong" -> Strong <$> elementContent
296271 "Subscript" -> Subscript <$> elementContent
297272 "Superscript"-> Superscript <$> elementContent
298− _ -> throwLuaError ("Unknown inline type: " ++ tag)
273+ _ -> Lua.throwException ("Unknown inline type: " <> tag)
299274 where
300275 -- Get the contents of an AST element.
301− elementContent :: FromLuaStack a => Lua a
302− elementContent = getTable idx "c"
276+ elementContent :: Peekable a => Lua a
277+ elementContent = LuaUtil.rawField idx "c"
303278
304279withAttr :: (Attr -> a -> b) -> (LuaAttr, a) -> b
305280withAttr f (attributes, x) = f (fromLuaAttr attributes) x
@@ -307,25 +282,25 @@ withAttr f (attributes, x) = f (fromLuaAttr attributes) x
307282-- | Wrapper for Attr
308283newtype LuaAttr = LuaAttr { fromLuaAttr :: Attr }
309284
310−instance ToLuaStack LuaAttr where
285+instance Pushable LuaAttr where
311286 push (LuaAttr (id', classes, kv)) =
312287 pushViaConstructor "Attr" id' classes kv
313288
314−instance FromLuaStack LuaAttr where
315− peek idx = defineHowTo "get Attr value" (LuaAttr <$> peek idx)
289+instance Peekable LuaAttr where
290+ peek idx = defineHowTo "get Attr value" (LuaAttr <$> Lua.peek idx)
316291
317292--
318293-- Hierarchical elements
319294--
320−instance ToLuaStack Element where
321− push (Blk blk) = push blk
295+instance Pushable Element where
296+ push (Blk blk) = Lua.push blk
322297 push (Sec lvl num attr label contents) = do
323298 Lua.newtable
324− LuaUtil.addValue "level" lvl
325− LuaUtil.addValue "numbering" num
326− LuaUtil.addValue "attr" (LuaAttr attr)
327− LuaUtil.addValue "label" label
328− LuaUtil.addValue "contents" contents
299+ LuaUtil.addField "level" lvl
300+ LuaUtil.addField "numbering" num
301+ LuaUtil.addField "attr" (LuaAttr attr)
302+ LuaUtil.addField "label" label
303+ LuaUtil.addField "contents" contents
329304 pushSecMetaTable
330305 Lua.setmetatable (-2)
331306 where
@@ -333,7 +308,7 @@ instance ToLuaStack Element where
333308 pushSecMetaTable = do
334309 inexistant <- Lua.newmetatable "PandocElementSec"
335310 when inexistant $ do
336− LuaUtil.addValue "t" "Sec"
311+ LuaUtil.addField "t" "Sec"
337312 Lua.push "__index"
338313 Lua.pushvalue (-2)
339314 Lua.rawset (-3)
@@ -342,18 +317,13 @@ instance ToLuaStack Element where
342317--
343318-- Reader Options
344319--
345−instance ToLuaStack Extensions where
346− push exts = push (show exts)
347−
348−instance ToLuaStack TrackChanges where
349− push = push . showConstr . toConstr
320+instance Pushable Extensions where
321+ push exts = Lua.push (show exts)
350322
351−instance ToLuaStack a => ToLuaStack (Set.Set a) where
352− push set = do
353− Lua.newtable
354− forM_ set (`LuaUtil.addValue` True)
323+instance Pushable TrackChanges where
324+ push = Lua.push . showConstr . toConstr
355325
356−instance ToLuaStack ReaderOptions where
326+instance Pushable ReaderOptions where
357327 push ro = do
358328 let ReaderOptions
359329 (extensions :: Extensions)
@@ -367,12 +337,12 @@ instance ToLuaStack ReaderOptions where
367337 (stripComments :: Bool)
368338 = ro
369339 Lua.newtable
370− LuaUtil.addValue "extensions" extensions
371− LuaUtil.addValue "standalone" standalone
372− LuaUtil.addValue "columns" columns
373− LuaUtil.addValue "tabStop" tabStop
374− LuaUtil.addValue "indentedCodeClasses" indentedCodeClasses
375− LuaUtil.addValue "abbreviations" abbreviations
376− LuaUtil.addValue "defaultImageExtension" defaultImageExtension
377− LuaUtil.addValue "trackChanges" trackChanges
378− LuaUtil.addValue "stripComments" stripComments
340+ LuaUtil.addField "extensions" extensions
341+ LuaUtil.addField "standalone" standalone
342+ LuaUtil.addField "columns" columns
343+ LuaUtil.addField "tabStop" tabStop
344+ LuaUtil.addField "indentedCodeClasses" indentedCodeClasses
345+ LuaUtil.addField "abbreviations" abbreviations
346+ LuaUtil.addField "defaultImageExtension" defaultImageExtension
347+ LuaUtil.addField "trackChanges" trackChanges
348+ LuaUtil.addField "stripComments" stripComments
src/Text/Pandoc/Lua/Util.hs+85−101
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright © 2012-2018 John MacFarlane <jgm@berkeley.edu>
43 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@@ -18,6 +17,8 @@ along with this program; if not, write to the Free Software
1817Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1918-}
2019{-# LANGUAGE FlexibleInstances #-}
20+{-# LANGUAGE LambdaCase #-}
21+{-# LANGUAGE NoImplicitPrelude #-}
2122{- |
2223 Module : Text.Pandoc.Lua.Util
2324 Copyright : © 2012–2018 John MacFarlane,
@@ -31,101 +32,53 @@ Lua utility functions.
3132-}
3233module Text.Pandoc.Lua.Util
3334 ( getTag
34− , getTable
35− , addValue
35+ , rawField
36+ , addField
3637 , addFunction
37− , getRawInt
38− , setRawInt
39− , addRawInt
40− , typeCheck
41− , raiseError
42− , popValue
43− , PushViaCall
44− , pushViaCall
38+ , addValue
4539 , pushViaConstructor
4640 , loadScriptFromDataDir
47− , dostring'
41+ , defineHowTo
42+ , throwTopMessageAsError'
43+ , callWithTraceback
44+ , dofileWithTraceback
4845 ) where
4946
5047import Prelude
51−import Control.Monad (when)
52−import Control.Monad.Catch (finally)
53−import Data.ByteString.Char8 (unpack)
54−import Foreign.Lua (FromLuaStack (..), NumResults, Lua, NumArgs, StackIndex,
55− ToLuaStack (..), ToHaskellFunction)
56−import Foreign.Lua.Api (Status, call, pop, rawget, rawgeti, rawset, rawseti)
48+import Control.Monad (unless, when)
49+import Foreign.Lua ( Lua, NumArgs, NumResults, Peekable, Pushable, StackIndex
50+ , Status, ToHaskellFunction )
5751import Text.Pandoc.Class (readDataFile, runIOorExplode, setUserDataDir)
5852
5953import qualified Foreign.Lua as Lua
60−
61−-- | Adjust the stack index, assuming that @n@ new elements have been pushed on
62−-- the stack.
63−adjustIndexBy :: StackIndex -> StackIndex -> StackIndex
64−adjustIndexBy idx n =
65− if idx < 0
66− then idx - n
67− else idx
54+import qualified Text.Pandoc.UTF8 as UTF8
6855
6956-- | Get value behind key from table at given index.
70−getTable :: (ToLuaStack a, FromLuaStack b) => StackIndex -> a -> Lua b
71−getTable idx key = do
72− push key
73− rawget (idx `adjustIndexBy` 1)
74− popValue
57+rawField :: Peekable a => StackIndex -> String -> Lua a
58+rawField idx key = do
59+ absidx <- Lua.absindex idx
60+ Lua.push key
61+ Lua.rawget absidx
62+ Lua.popValue
63+
64+-- | Add a value to the table at the top of the stack at a string-index.
65+addField :: Pushable a => String -> a -> Lua ()
66+addField = addValue
7567
7668-- | Add a key-value pair to the table at the top of the stack.
77−addValue :: (ToLuaStack a, ToLuaStack b) => a -> b -> Lua ()
69+addValue :: (Pushable a, Pushable b) => a -> b -> Lua ()
7870addValue key value = do
79− push key
80− push value
81− rawset (-3)
71+ Lua.push key
72+ Lua.push value
73+ Lua.rawset (Lua.nthFromTop 3)
8274
8375-- | Add a function to the table at the top of the stack, using the given name.
8476addFunction :: ToHaskellFunction a => String -> a -> Lua ()
8577addFunction name fn = do
8678 Lua.push name
8779 Lua.pushHaskellFunction fn
88− Lua.wrapHaskellFunction
8980 Lua.rawset (-3)
9081
91−-- | Get value behind key from table at given index.
92−getRawInt :: FromLuaStack a => StackIndex -> Int -> Lua a
93−getRawInt idx key = do
94− rawgeti idx key
95− popValue
96−
97−-- | Set numeric key/value in table at the given index
98−setRawInt :: ToLuaStack a => StackIndex -> Int -> a -> Lua ()
99−setRawInt idx key value = do
100− push value
101− rawseti (idx `adjustIndexBy` 1) key
102−
103−-- | Set numeric key/value in table at the top of the stack.
104−addRawInt :: ToLuaStack a => Int -> a -> Lua ()
105−addRawInt = setRawInt (-1)
106−
107−typeCheck :: StackIndex -> Lua.Type -> Lua ()
108−typeCheck idx expected = do
109− actual <- Lua.ltype idx
110− when (actual /= expected) $ do
111− expName <- Lua.typename expected
112− actName <- Lua.typename actual
113− Lua.throwLuaError $ "expected " ++ expName ++ " but got " ++ actName ++ "."
114−
115−raiseError :: ToLuaStack a => a -> Lua NumResults
116−raiseError e = do
117− Lua.push e
118− fromIntegral <$> Lua.lerror
119−
120−-- | Get, then pop the value at the top of the stack.
121−popValue :: FromLuaStack a => Lua a
122−popValue = do
123− resOrError <- Lua.peekEither (-1)
124− pop 1
125− case resOrError of
126− Left err -> Lua.throwLuaError err
127− Right x -> return x
128−
12982-- | Helper class for pushing a single value to the stack via a lua function.
13083-- See @pushViaCall@.
13184class PushViaCall a where
@@ -136,11 +89,11 @@ instance PushViaCall (Lua ()) where
13689 Lua.push fn
13790 Lua.rawget Lua.registryindex
13891 pushArgs
139− call num 1
92+ Lua.call num 1
14093
141−instance (ToLuaStack a, PushViaCall b) => PushViaCall (a -> b) where
94+instance (Pushable a, PushViaCall b) => PushViaCall (a -> b) where
14295 pushViaCall' fn pushArgs num x =
143− pushViaCall' fn (pushArgs *> push x) (num + 1)
96+ pushViaCall' fn (pushArgs *> Lua.push x) (num + 1)
14497
14598-- | Push an value to the stack via a lua function. The lua function is called
14699-- with all arguments that are passed to this function and is expected to return
@@ -155,26 +108,11 @@ pushViaConstructor pandocFn = pushViaCall ("pandoc." ++ pandocFn)
155108-- | Load a file from pandoc's data directory.
156109loadScriptFromDataDir :: Maybe FilePath -> FilePath -> Lua ()
157110loadScriptFromDataDir datadir scriptFile = do
158− script <- fmap unpack . Lua.liftIO . runIOorExplode $
111+ script <- Lua.liftIO . runIOorExplode $
159112 setUserDataDir datadir >> readDataFile scriptFile
160− status <- dostring' script
161− when (status /= Lua.OK) .
162− Lua.throwTopMessageAsError' $ \msg ->
163− "Couldn't load '" ++ scriptFile ++ "'.\n" ++ msg
164−
165−-- | Load a string and immediately perform a full garbage collection. This is
166−-- important to keep the program from hanging: If the program contained a call
167−-- to @require@, the a new loader function was created which then become
168−-- garbage. If that function is collected at an inopportune times, i.e. when the
169−-- Lua API is called via a function that doesn't allow calling back into Haskell
170−-- (getraw, setraw, …), then the function's finalizer, and the full program,
171−-- will hang.
172−dostring' :: String -> Lua Status
173−dostring' script = do
174− loadRes <- Lua.loadstring script
175− if loadRes == Lua.OK
176− then Lua.pcall 0 1 Nothing <* Lua.gc Lua.GCCOLLECT 0
177− else return loadRes
113+ status <- Lua.dostring script
114+ when (status /= Lua.OK) $
115+ throwTopMessageAsError' (("Couldn't load '" ++ scriptFile ++ "'.\n") ++)
178116
179117-- | Get the tag of a value. This is an optimized and specialized version of
180118-- @Lua.getfield idx "tag"@. It only checks for the field on the table at index
@@ -182,8 +120,54 @@ dostring' script = do
182120-- metatable.
183121getTag :: StackIndex -> Lua String
184122getTag idx = do
185− top <- Lua.gettop
186− hasMT <- Lua.getmetatable idx
187− push "tag"
188− if hasMT then Lua.rawget (-2) else Lua.rawget (idx `adjustIndexBy` 1)
189− peek Lua.stackTop `finally` Lua.settop top
123+ -- push metatable or just the table
124+ Lua.getmetatable idx >>= \hasMT -> unless hasMT (Lua.pushvalue idx)
125+ Lua.push "tag"
126+ Lua.rawget (Lua.nthFromTop 2)
127+ Lua.tostring Lua.stackTop <* Lua.pop 2 >>= \case
128+ Nothing -> Lua.throwException "untagged value"
129+ Just x -> return (UTF8.toString x)
130+
131+-- | Modify the message at the top of the stack before throwing it as an
132+-- Exception.
133+throwTopMessageAsError' :: (String -> String) -> Lua a
134+throwTopMessageAsError' modifier = do
135+ msg <- Lua.tostring' Lua.stackTop
136+ Lua.pop 2 -- remove error and error string pushed by tostring'
137+ Lua.throwException (modifier (UTF8.toString msg))
138+
139+-- | Mark the context of a Lua computation for better error reporting.
140+defineHowTo :: String -> Lua a -> Lua a
141+defineHowTo ctx = Lua.withExceptionMessage (("Could not " <> ctx <> ": ") <>)
142+
143+-- | Like @'Lua.pcall'@, but uses a predefined error handler which adds a
144+-- traceback on error.
145+pcallWithTraceback :: NumArgs -> NumResults -> Lua Status
146+pcallWithTraceback nargs nresults = do
147+ let traceback' :: Lua NumResults
148+ traceback' = do
149+ l <- Lua.state
150+ msg <- Lua.tostring' (Lua.nthFromBottom 1)
151+ Lua.traceback l (Just (UTF8.toString msg)) 2
152+ return 1
153+ tracebackIdx <- Lua.absindex (Lua.nthFromTop (Lua.fromNumArgs nargs + 1))
154+ Lua.pushHaskellFunction traceback'
155+ Lua.insert tracebackIdx
156+ result <- Lua.pcall nargs nresults (Just tracebackIdx)
157+ Lua.remove tracebackIdx
158+ return result
159+
160+-- | Like @'Lua.call'@, but adds a traceback to the error message (if any).
161+callWithTraceback :: NumArgs -> NumResults -> Lua ()
162+callWithTraceback nargs nresults = do
163+ result <- pcallWithTraceback nargs nresults
164+ when (result /= Lua.OK) Lua.throwTopMessage
165+
166+-- | Run the given string as a Lua program, while also adding a traceback to the
167+-- error message if an error occurs.
168+dofileWithTraceback :: FilePath -> Lua Status
169+dofileWithTraceback fp = do
170+ loadRes <- Lua.loadfile fp
171+ case loadRes of
172+ Lua.OK -> pcallWithTraceback 0 Lua.multret
173+ _ -> return loadRes
src/Text/Pandoc/Options.hs+2
@@ -194,6 +194,7 @@ data WriterOptions = WriterOptions
194194 , writerReferenceDoc :: Maybe FilePath -- ^ Path to reference document if specified
195195 , writerReferenceLocation :: ReferenceLocation -- ^ Location of footnotes and references for writing markdown
196196 , writerSyntaxMap :: SyntaxMap
197+ , writerPreferAscii :: Bool -- ^ Prefer ASCII representations of characters when possible
197198 } deriving (Show, Data, Typeable, Generic)
198199
199200instance Default WriterOptions where
@@ -228,6 +229,7 @@ instance Default WriterOptions where
228229 , writerReferenceDoc = Nothing
229230 , writerReferenceLocation = EndOfDocument
230231 , writerSyntaxMap = defaultSyntaxMap
232+ , writerPreferAscii = False
231233 }
232234
233235instance HasSyntaxExtensions WriterOptions where
src/Text/Pandoc/PDF.hs+63−59
@@ -79,13 +79,52 @@ changePathSeparators = intercalate "/" . splitDirectories
7979#endif
8080
8181makePDF :: String -- ^ pdf creator (pdflatex, lualatex, xelatex,
82− -- wkhtmltopdf, weasyprint, prince, context, pdfroff)
82+ -- wkhtmltopdf, weasyprint, prince, context, pdfroff,
83+ -- or path to executable)
8384 -> [String] -- ^ arguments to pass to pdf creator
8485 -> (WriterOptions -> Pandoc -> PandocIO Text) -- ^ writer
8586 -> WriterOptions -- ^ options
8687 -> Pandoc -- ^ document
8788 -> PandocIO (Either ByteString ByteString)
88−makePDF "wkhtmltopdf" pdfargs writer opts doc@(Pandoc meta _) = do
89+makePDF program pdfargs writer opts doc = do
90+ case takeBaseName program of
91+ "wkhtmltopdf" -> makeWithWkhtmltopdf program pdfargs writer opts doc
92+ prog | prog `elem` ["weasyprint", "prince"] -> do
93+ source <- writer opts doc
94+ verbosity <- getVerbosity
95+ liftIO $ html2pdf verbosity program pdfargs source
96+ "pdfroff" -> do
97+ source <- writer opts doc
98+ let args = ["-ms", "-mpdfmark", "-e", "-t", "-k", "-KUTF-8", "-i",
99+ "--no-toc-relocation"] ++ pdfargs
100+ verbosity <- getVerbosity
101+ liftIO $ ms2pdf verbosity program args source
102+ baseProg -> do
103+ -- With context and latex, we create a temp directory within
104+ -- the working directory, since pdflatex sometimes tries to
105+ -- use tools like epstopdf.pl, which are restricted if run
106+ -- on files outside the working directory.
107+ let withTemp = withTempDirectory "."
108+ commonState <- getCommonState
109+ verbosity <- getVerbosity
110+ liftIO $ withTemp "tex2pdf." $ \tmpdir -> do
111+ source <- runIOorExplode $ do
112+ putCommonState commonState
113+ doc' <- handleImages tmpdir doc
114+ writer opts doc'
115+ case baseProg of
116+ "context" -> context2pdf verbosity program tmpdir source
117+ prog | prog `elem` ["pdflatex", "lualatex", "xelatex"]
118+ -> tex2pdf verbosity program pdfargs tmpdir source
119+ _ -> return $ Left $ UTF8.fromStringLazy $ "Unknown program " ++ program
120+
121+makeWithWkhtmltopdf :: String -- ^ wkhtmltopdf or path
122+ -> [String] -- ^ arguments
123+ -> (WriterOptions -> Pandoc -> PandocIO Text) -- ^ writer
124+ -> WriterOptions -- ^ options
125+ -> Pandoc -- ^ document
126+ -> PandocIO (Either ByteString ByteString)
127+makeWithWkhtmltopdf program pdfargs writer opts doc@(Pandoc meta _) = do
89128 let mathArgs = case writerHTMLMathMethod opts of
90129 -- with MathJax, wait til all math is rendered:
91130 MathJax _ -> ["--run-script", "MathJax.Hub.Register.StartupHook('End Typeset', function() { window.status = 'mathjax_loaded' });",
@@ -111,39 +150,7 @@ makePDF "wkhtmltopdf" pdfargs writer opts doc@(Pandoc meta _) = do
111150 ]
112151 source <- writer opts doc
113152 verbosity <- getVerbosity
114− liftIO $ html2pdf verbosity "wkhtmltopdf" args source
115−makePDF "weasyprint" pdfargs writer opts doc = do
116− source <- writer opts doc
117− verbosity <- getVerbosity
118− liftIO $ html2pdf verbosity "weasyprint" pdfargs source
119−makePDF "prince" pdfargs writer opts doc = do
120− source <- writer opts doc
121− verbosity <- getVerbosity
122− liftIO $ html2pdf verbosity "prince" pdfargs source
123−makePDF "pdfroff" pdfargs writer opts doc = do
124− source <- writer opts doc
125− let args = ["-ms", "-mpdfmark", "-e", "-t", "-k", "-KUTF-8", "-i",
126− "--no-toc-relocation"] ++ pdfargs
127− verbosity <- getVerbosity
128− liftIO $ ms2pdf verbosity args source
129−makePDF program pdfargs writer opts doc = do
130− -- With context and latex, we create a temp directory within
131− -- the working directory, since pdflatex sometimes tries to
132− -- use tools like epstopdf.pl, which are restricted if run
133− -- on files outside the working directory.
134− let withTemp = withTempDirectory "."
135− commonState <- getCommonState
136− verbosity <- getVerbosity
137− liftIO $ withTemp "tex2pdf." $ \tmpdir -> do
138− source <- runIOorExplode $ do
139− putCommonState commonState
140− doc' <- handleImages tmpdir doc
141− writer opts doc'
142− case takeBaseName program of
143− "context" -> context2pdf verbosity tmpdir source
144− prog | prog `elem` ["pdflatex", "lualatex", "xelatex"]
145− -> tex2pdf' verbosity pdfargs tmpdir program source
146− _ -> return $ Left $ UTF8.fromStringLazy $ "Unknown program " ++ program
153+ liftIO $ html2pdf verbosity program args source
147154
148155handleImages :: FilePath -- ^ temp dir to store images
149156 -> Pandoc -- ^ document
@@ -181,7 +188,7 @@ convertImage tmpdir fname =
181188 then return $ Right pdfOut
182189 else return $ Left "conversion from SVG failed")
183190 (\(e :: E.SomeException) -> return $ Left $
184− "check that rsvg2pdf is in path.\n" ++
191+ "check that rsvg-convert is in path.\n" ++
185192 show e)
186193 _ -> JP.readImage fname >>= \res ->
187194 case res of
@@ -195,13 +202,13 @@ convertImage tmpdir fname =
195202 mime = getMimeType fname
196203 doNothing = return (Right fname)
197204
198−tex2pdf' :: Verbosity -- ^ Verbosity level
199− -> [String] -- ^ Arguments to the latex-engine
200− -> FilePath -- ^ temp directory for output
201− -> String -- ^ tex program
202− -> Text -- ^ tex source
203− -> IO (Either ByteString ByteString)
204−tex2pdf' verbosity args tmpDir program source = do
205+tex2pdf :: Verbosity -- ^ Verbosity level
206+ -> String -- ^ tex program
207+ -> [String] -- ^ Arguments to the latex-engine
208+ -> FilePath -- ^ temp directory for output
209+ -> Text -- ^ tex source
210+ -> IO (Either ByteString ByteString)
211+tex2pdf verbosity program args tmpDir source = do
205212 let numruns = if "\\tableofcontents" `T.isInfixOf` source
206213 then 3 -- to get page numbers
207214 else 2 -- 1 run won't give you PDF bookmarks
@@ -278,12 +285,7 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
278285 let file' = file
279286#endif
280287 let programArgs = ["-halt-on-error", "-interaction", "nonstopmode",
281− "-output-directory", tmpDir'] ++
282− -- see #4484, only compress images on last run:
283− if program == "xelatex" && runNumber < numRuns
284− then ["-output-driver", "xdvipdfmx -z0"]
285− else []
286− ++ args ++ [file']
288+ "-output-directory", tmpDir'] ++ args ++ [file']
287289 env' <- getEnvironment
288290 let sep = [searchPathSeparator]
289291 let texinputs = maybe (tmpDir' ++ sep) ((tmpDir' ++ sep) ++)
@@ -307,7 +309,7 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
307309 putStrLn $ "[makePDF] Run #" ++ show runNumber
308310 BL.hPutStr stdout out
309311 putStr "\n"
310− if runNumber <= numRuns
312+ if runNumber < numRuns
311313 then runTeXProgram verbosity program args (runNumber + 1) numRuns tmpDir source
312314 else do
313315 let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir
@@ -328,14 +330,15 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
328330 return (exit, log', pdf)
329331
330332ms2pdf :: Verbosity
333+ -> String
331334 -> [String]
332335 -> Text
333336 -> IO (Either ByteString ByteString)
334−ms2pdf verbosity args source = do
337+ms2pdf verbosity program args source = do
335338 env' <- getEnvironment
336339 when (verbosity >= INFO) $ do
337340 putStrLn "[makePDF] Command line:"
338− putStrLn $ "pdfroff " ++ " " ++ unwords (map show args)
341+ putStrLn $ program ++ " " ++ unwords (map show args)
339342 putStr "\n"
340343 putStrLn "[makePDF] Environment:"
341344 mapM_ print env'
@@ -344,11 +347,11 @@ ms2pdf verbosity args source = do
344347 putStr $ T.unpack source
345348 putStr "\n"
346349 (exit, out) <- E.catch
347− (pipeProcess (Just env') "pdfroff" args
350+ (pipeProcess (Just env') program args
348351 (BL.fromStrict $ UTF8.fromText source))
349352 (\(e :: IOError) -> if isDoesNotExistError e
350353 then E.throwIO $
351− PandocPDFProgramNotFoundError "pdfroff"
354+ PandocPDFProgramNotFoundError program
352355 else E.throwIO e)
353356 when (verbosity >= INFO) $ do
354357 BL.hPutStr stdout out
@@ -358,7 +361,7 @@ ms2pdf verbosity args source = do
358361 ExitSuccess -> Right out
359362
360363html2pdf :: Verbosity -- ^ Verbosity level
361− -> String -- ^ Program (wkhtmltopdf, weasyprint or prince)
364+ -> String -- ^ Program (wkhtmltopdf, weasyprint, prince, or path)
362365 -> [String] -- ^ Args to program
363366 -> Text -- ^ HTML5 source
364367 -> IO (Either ByteString ByteString)
@@ -369,7 +372,7 @@ html2pdf verbosity program args source = do
369372 file <- withTempFile "." "html2pdf.html" $ \fp _ -> return fp
370373 pdfFile <- withTempFile "." "html2pdf.pdf" $ \fp _ -> return fp
371374 BS.writeFile file $ UTF8.fromText source
372− let pdfFileArgName = ["-o" | program == "prince"]
375+ let pdfFileArgName = ["-o" | takeBaseName program == "prince"]
373376 let programArgs = args ++ [file] ++ pdfFileArgName ++ [pdfFile]
374377 env' <- getEnvironment
375378 when (verbosity >= INFO) $ do
@@ -408,10 +411,11 @@ html2pdf verbosity program args source = do
408411 (ExitSuccess, Just pdf) -> Right pdf
409412
410413context2pdf :: Verbosity -- ^ Verbosity level
414+ -> String -- ^ "context" or path to it
411415 -> FilePath -- ^ temp directory for output
412416 -> Text -- ^ ConTeXt source
413417 -> IO (Either ByteString ByteString)
414−context2pdf verbosity tmpDir source = inDirectory tmpDir $ do
418+context2pdf verbosity program tmpDir source = inDirectory tmpDir $ do
415419 let file = "input.tex"
416420 BS.writeFile file $ UTF8.fromText source
417421#ifdef _WINDOWS
@@ -426,7 +430,7 @@ context2pdf verbosity tmpDir source = inDirectory tmpDir $ do
426430 putStrLn "[makePDF] temp dir:"
427431 putStrLn tmpDir'
428432 putStrLn "[makePDF] Command line:"
429− putStrLn $ "context" ++ " " ++ unwords (map show programArgs)
433+ putStrLn $ program ++ " " ++ unwords (map show programArgs)
430434 putStr "\n"
431435 putStrLn "[makePDF] Environment:"
432436 mapM_ print env'
@@ -435,7 +439,7 @@ context2pdf verbosity tmpDir source = inDirectory tmpDir $ do
435439 BL.readFile file >>= BL.putStr
436440 putStr "\n"
437441 (exit, out) <- E.catch
438− (pipeProcess (Just env') "context" programArgs BL.empty)
442+ (pipeProcess (Just env') program programArgs BL.empty)
439443 (\(e :: IOError) -> if isDoesNotExistError e
440444 then E.throwIO $
441445 PandocPDFProgramNotFoundError "context"
src/Text/Pandoc/Parsing.hs+10−13
@@ -514,22 +514,19 @@ charsInBalanced open close parser = try $ do
514514
515515-- Auxiliary functions for romanNumeral:
516516
517−lowercaseRomanDigits :: [Char]
518−lowercaseRomanDigits = ['i','v','x','l','c','d','m']
519−
520−uppercaseRomanDigits :: [Char]
521−uppercaseRomanDigits = map toUpper lowercaseRomanDigits
522−
523517-- | Parses a roman numeral (uppercase or lowercase), returns number.
524518romanNumeral :: Stream s m Char => Bool -- ^ Uppercase if true
525519 -> ParserT s st m Int
526520romanNumeral upperCase = do
527− let romanDigits = if upperCase
528− then uppercaseRomanDigits
529− else lowercaseRomanDigits
530− lookAhead $ oneOf romanDigits
531− let [one, five, ten, fifty, hundred, fivehundred, thousand] =
532− map char romanDigits
521+ let rchar uc = char $ if upperCase then uc else toLower uc
522+ let one = rchar 'I'
523+ let five = rchar 'V'
524+ let ten = rchar 'X'
525+ let fifty = rchar 'L'
526+ let hundred = rchar 'C'
527+ let fivehundred = rchar 'D'
528+ let thousand = rchar 'M'
529+ lookAhead $ choice [one, five, ten, fifty, hundred, fivehundred, thousand]
533530 thousands <- ((1000 *) . length) <$> many thousand
534531 ninehundreds <- option 0 $ try $ hundred >> thousand >> return 900
535532 fivehundreds <- option 0 $ 500 <$ fivehundred
@@ -1289,7 +1286,7 @@ type SubstTable = M.Map Key Inlines
12891286-- unique identifier, and update the list of identifiers
12901287-- in state. Issue a warning if an explicit identifier
12911288-- is encountered that duplicates an earlier identifier
1292−-- (explict or automatically generated).
1289+-- (explicit or automatically generated).
12931290registerHeader :: (Stream s m a, HasReaderOptions st,
12941291 HasHeaderMap st, HasLogMessages st, HasIdentifierList st)
12951292 => Attr -> Inlines -> ParserT s st m Attr
src/Text/Pandoc/Readers/CommonMark.hs+36−28
@@ -39,10 +39,12 @@ import Control.Monad.State
3939import Data.Char (isAlphaNum, isLetter, isSpace, toLower)
4040import Data.List (groupBy)
4141import qualified Data.Map as Map
42+import Data.Maybe (mapMaybe)
4243import Data.Text (Text, unpack)
44+import Text.Pandoc.Asciify (toAsciiChar)
4345import Text.Pandoc.Class (PandocMonad)
4446import Text.Pandoc.Definition
45−import Text.Pandoc.Emoji (emojis)
47+import Text.Pandoc.Emoji (emojiToInline)
4648import Text.Pandoc.Options
4749import Text.Pandoc.Shared (stringify)
4850import Text.Pandoc.Walk (walkM)
@@ -51,7 +53,7 @@ import Text.Pandoc.Walk (walkM)
5153readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
5254readCommonMark opts s = return $
5355 (if isEnabled Ext_gfm_auto_identifiers opts
54− then addHeaderIdentifiers
56+ then addHeaderIdentifiers opts
5557 else id) $
5658 nodeToPandoc opts $ commonmarkToNode opts' exts s
5759 where opts' = [ optSmart | isEnabled Ext_smart opts ]
@@ -59,24 +61,27 @@ readCommonMark opts s = return $
5961 [ extTable | isEnabled Ext_pipe_tables opts ] ++
6062 [ extAutolink | isEnabled Ext_autolink_bare_uris opts ]
6163
62−convertEmojis :: String -> String
63−convertEmojis (':':xs) =
64+convertEmojis :: String -> [Inline]
65+convertEmojis s@(':':xs) =
6466 case break (==':') xs of
6567 (ys,':':zs) ->
66− case Map.lookup ys emojis of
67− Just s -> s ++ convertEmojis zs
68− Nothing -> ':' : ys ++ convertEmojis (':':zs)
69− _ -> ':':xs
70−convertEmojis (x:xs) = x : convertEmojis xs
71−convertEmojis [] = []
72−
73−addHeaderIdentifiers :: Pandoc -> Pandoc
74−addHeaderIdentifiers doc = evalState (walkM addHeaderId doc) mempty
75−
76−addHeaderId :: Block -> State (Map.Map String Int) Block
77−addHeaderId (Header lev (_,classes,kvs) ils) = do
68+ case emojiToInline ys of
69+ Just em -> em : convertEmojis zs
70+ Nothing -> Str (':' : ys) : convertEmojis (':':zs)
71+ _ -> [Str s]
72+convertEmojis s =
73+ case break (==':') s of
74+ ("","") -> []
75+ (_,"") -> [Str s]
76+ (xs,ys) -> Str xs:convertEmojis ys
77+
78+addHeaderIdentifiers :: ReaderOptions -> Pandoc -> Pandoc
79+addHeaderIdentifiers opts doc = evalState (walkM (addHeaderId opts) doc) mempty
80+
81+addHeaderId :: ReaderOptions -> Block -> State (Map.Map String Int) Block
82+addHeaderId opts (Header lev (_,classes,kvs) ils) = do
7883 idmap <- get
79− let ident = toIdent ils
84+ let ident = toIdent opts ils
8085 ident' <- case Map.lookup ident idmap of
8186 Nothing -> do
8287 put (Map.insert ident 1 idmap)
@@ -85,13 +90,16 @@ addHeaderId (Header lev (_,classes,kvs) ils) = do
8590 put (Map.adjust (+ 1) ident idmap)
8691 return (ident ++ "-" ++ show i)
8792 return $ Header lev (ident',classes,kvs) ils
88−addHeaderId x = return x
93+addHeaderId _ x = return x
8994
90−toIdent :: [Inline] -> String
91−toIdent = map (\c -> if isSpace c then '-' else c)
92− . filter (\c -> isLetter c || isAlphaNum c || isSpace c ||
93− c == '_' || c == '-')
94− . map toLower . stringify
95+toIdent :: ReaderOptions -> [Inline] -> String
96+toIdent opts = map (\c -> if isSpace c then '-' else c)
97+ . filterer
98+ . map toLower . stringify
99+ where filterer = if isEnabled Ext_ascii_identifiers opts
100+ then mapMaybe toAsciiChar
101+ else filter (\c -> isLetter c || isAlphaNum c || isSpace c ||
102+ c == '_' || c == '-')
95103
96104nodeToPandoc :: ReaderOptions -> Node -> Pandoc
97105nodeToPandoc opts (Node _ DOCUMENT nodes) =
@@ -200,17 +208,17 @@ addInlines :: ReaderOptions -> [Node] -> [Inline]
200208addInlines opts = foldr (addInline opts) []
201209
202210addInline :: ReaderOptions -> Node -> [Inline] -> [Inline]
203−addInline opts (Node _ (TEXT t) _) = (map toinl clumps ++)
211+addInline opts (Node _ (TEXT t) _) = (foldr ((++) . toinl) [] clumps ++)
204212 where raw = unpack t
205213 clumps = groupBy samekind raw
206214 samekind ' ' ' ' = True
207215 samekind ' ' _ = False
208216 samekind _ ' ' = False
209217 samekind _ _ = True
210− toinl (' ':_) = Space
211− toinl xs = Str $ if isEnabled Ext_emoji opts
212− then convertEmojis xs
213− else xs
218+ toinl (' ':_) = [Space]
219+ toinl xs = if isEnabled Ext_emoji opts
220+ then convertEmojis xs
221+ else [Str xs]
214222addInline _ (Node _ LINEBREAK _) = (LineBreak :)
215223addInline opts (Node _ SOFTBREAK _)
216224 | isEnabled Ext_hard_line_breaks opts = (LineBreak :)
src/Text/Pandoc/Readers/Creole.hs+1−1
@@ -2,7 +2,7 @@
22{-
33 Copyright (C) 2017 Sascha Wilde <wilde@sha-bang.de>
44
5− partly based on all the other readers, especialy the work by
5+ partly based on all the other readers, especially the work by
66 John MacFarlane <jgm@berkeley.edu> and
77 Alexander Sulfrian <alexander.sulfrian@fu-berlin.de>
88 all bugs are solely created by me.
src/Text/Pandoc/Readers/DocBook.hs+28−38
@@ -537,7 +537,6 @@ type DB m = StateT DBState m
537537data DBState = DBState{ dbSectionLevel :: Int
538538 , dbQuoteType :: QuoteType
539539 , dbMeta :: Meta
540− , dbAcceptsMeta :: Bool
541540 , dbBook :: Bool
542541 , dbFigureTitle :: Inlines
543542 , dbContent :: [Content]
@@ -547,7 +546,6 @@ instance Default DBState where
547546 def = DBState{ dbSectionLevel = 0
548547 , dbQuoteType = DoubleQuote
549548 , dbMeta = mempty
550− , dbAcceptsMeta = False
551549 , dbBook = False
552550 , dbFigureTitle = mempty
553551 , dbContent = [] }
@@ -609,18 +607,26 @@ named s e = qName (elName e) == s
609607
610608--
611609
612−acceptingMetadata :: PandocMonad m => DB m a -> DB m a
613−acceptingMetadata p = do
614− modify (\s -> s { dbAcceptsMeta = True } )
615− res <- p
616− modify (\s -> s { dbAcceptsMeta = False })
617− return res
618−
619−checkInMeta :: (PandocMonad m, Monoid a) => DB m () -> DB m a
620−checkInMeta p = do
621− accepts <- dbAcceptsMeta <$> get
622− when accepts p
623− return mempty
610+addMetadataFromElement :: PandocMonad m => Element -> DB m Blocks
611+addMetadataFromElement e = do
612+ case filterChild (named "title") e of
613+ Nothing -> return ()
614+ Just z -> do
615+ getInlines z >>= addMeta "title"
616+ addMetaField "subtitle" z
617+ case filterChild (named "authorgroup") e of
618+ Nothing -> return ()
619+ Just z -> addMetaField "author" z
620+ addMetaField "subtitle" e
621+ addMetaField "author" e
622+ addMetaField "date" e
623+ addMetaField "release" e
624+ return mempty
625+ where addMetaField fieldname elt =
626+ case filterChildren (named fieldname) elt of
627+ [] -> return ()
628+ [z] -> getInlines z >>= addMeta fieldname
629+ zs -> mapM getInlines zs >>= addMeta fieldname
624630
625631addMeta :: PandocMonad m => ToMetaValue a => String -> a -> DB m ()
626632addMeta field val = modify (setMeta field val)
@@ -718,11 +724,6 @@ parseBlock (Elem e) =
718724 "attribution" -> return mempty
719725 "titleabbrev" -> return mempty
720726 "authorinitials" -> return mempty
721− "title" -> checkInMeta getTitle
722− "author" -> checkInMeta getAuthor
723− "authorgroup" -> checkInMeta getAuthorGroup
724− "releaseinfo" -> checkInMeta (getInlines e >>= addMeta "release")
725− "date" -> checkInMeta getDate
726727 "bibliography" -> sect 0
727728 "bibliodiv" -> sect 1
728729 "biblioentry" -> parseMixed para (elContent e)
@@ -788,8 +789,8 @@ parseBlock (Elem e) =
788789 "figure" -> getFigure e
789790 "mediaobject" -> para <$> getMediaobject e
790791 "caption" -> return mempty
791− "info" -> metaBlock
792− "articleinfo" -> metaBlock
792+ "info" -> addMetadataFromElement e
793+ "articleinfo" -> addMetadataFromElement e
793794 "sectioninfo" -> return mempty -- keywords & other metadata
794795 "refsectioninfo" -> return mempty -- keywords & other metadata
795796 "refsect1info" -> return mempty -- keywords & other metadata
@@ -803,10 +804,11 @@ parseBlock (Elem e) =
803804 "chapterinfo" -> return mempty -- keywords & other metadata
804805 "glossaryinfo" -> return mempty -- keywords & other metadata
805806 "appendixinfo" -> return mempty -- keywords & other metadata
806− "bookinfo" -> metaBlock
807+ "bookinfo" -> addMetadataFromElement e
807808 "article" -> modify (\st -> st{ dbBook = False }) >>
808− getBlocks e
809− "book" -> modify (\st -> st{ dbBook = True }) >> getBlocks e
809+ addMetadataFromElement e >> getBlocks e
810+ "book" -> modify (\st -> st{ dbBook = True }) >>
811+ addMetadataFromElement e >> getBlocks e
810812 "table" -> parseTable
811813 "informaltable" -> parseTable
812814 "informalexample" -> divWith ("", ["informalexample"], []) <$>
@@ -816,6 +818,8 @@ parseBlock (Elem e) =
816818 "screen" -> codeBlockWithLang
817819 "programlisting" -> codeBlockWithLang
818820 "?xml" -> return mempty
821+ "title" -> return mempty -- handled in parent element
822+ "subtitle" -> return mempty -- handled in parent element
819823 _ -> getBlocks e
820824 where parseMixed container conts = do
821825 let (ils,rest) = break isBlockElement conts
@@ -857,19 +861,6 @@ parseBlock (Elem e) =
857861 terms' <- mapM getInlines terms
858862 items' <- mapM getBlocks items
859863 return (mconcat $ intersperse (str "; ") terms', items')
860− getTitle = do
861− tit <- getInlines e
862− subtit <- case filterChild (named "subtitle") e of
863− Just s -> (text ": " <>) <$>
864− getInlines s
865− Nothing -> return mempty
866− addMeta "title" (tit <> subtit)
867−
868− getAuthor = (:[]) <$> getInlines e >>= addMeta "author"
869− getAuthorGroup = do
870− let terms = filterChildren (named "author") e
871− mapM getInlines terms >>= addMeta "author"
872− getDate = getInlines e >>= addMeta "date"
873864 parseTable = do
874865 let isCaption x = named "title" x || named "caption" x
875866 caption <- case filterChild isCaption e of
@@ -935,7 +926,6 @@ parseBlock (Elem e) =
935926 modify $ \st -> st{ dbSectionLevel = n - 1 }
936927 return $ headerWith (ident,[],[]) n' headerText <> b
937928 lineItems = mapM getInlines $ filterChildren (named "line") e
938− metaBlock = acceptingMetadata (getBlocks e) >> return mempty
939929
940930getInlines :: PandocMonad m => Element -> DB m Inlines
941931getInlines e' = (trimInlines . mconcat) <$>
src/Text/Pandoc/Readers/Docx/Lists.hs+2−3
@@ -183,14 +183,13 @@ blocksToDefinitions' defAcc acc
183183 pair = if remainingAttr2 == ("", [], []) then (concatMap plainParaInlines blks1, [blks2]) else (concatMap plainParaInlines blks1, [[Div remainingAttr2 blks2]])
184184 in
185185 blocksToDefinitions' (pair : defAcc) acc blks
186−blocksToDefinitions' defAcc acc
186+blocksToDefinitions' ((defTerm, defItems):defs) acc
187187 (Div (ident2, classes2, kvs2) blks2 : blks)
188− | (not . null) defAcc && "Definition" `elem` classes2 =
188+ | "Definition" `elem` classes2 =
189189 let remainingAttr2 = (ident2, delete "Definition" classes2, kvs2)
190190 defItems2 = case remainingAttr2 == ("", [], []) of
191191 True -> blks2
192192 False -> [Div remainingAttr2 blks2]
193− ((defTerm, defItems):defs) = defAcc
194193 defAcc' = case null defItems of
195194 True -> (defTerm, [defItems2]) : defs
196195 False -> (defTerm, init defItems ++ [last defItems ++ defItems2]) : defs
src/Text/Pandoc/Readers/Docx/Parse.hs+8−5
@@ -785,7 +785,7 @@ So we do this in a number of steps. If we encounter the fldchar begin
785785tag, we start open a fldchar state variable (see state above). We add
786786the instrtext to it as FieldInfo. Then we close that and start adding
787787the runs when we get to separate. Then when we get to end, we produce
788−the Field type with approriate FieldInfo and Runs.
788+the Field type with appropriate FieldInfo and Runs.
789789-}
790790elemToParPart ns element
791791 | isElem ns "w" "r" element
@@ -1056,8 +1056,10 @@ elemToRunStyle ns element parentStyle
10561056 | Just rPr <- findChildByName ns "w" "rPr" element =
10571057 RunStyle
10581058 {
1059− isBold = checkOnOff ns rPr (elemName ns "w" "b")
1060− , isItalic = checkOnOff ns rPr (elemName ns "w" "i")
1059+ isBold = checkOnOff ns rPr (elemName ns "w" "b") `mplus`
1060+ checkOnOff ns rPr (elemName ns "w" "bCs")
1061+ , isItalic = checkOnOff ns rPr (elemName ns "w" "i") `mplus`
1062+ checkOnOff ns rPr (elemName ns "w" "iCs")
10611063 , isSmallCaps = checkOnOff ns rPr (elemName ns "w" "smallCaps")
10621064 , isStrike = checkOnOff ns rPr (elemName ns "w" "strike")
10631065 , rVertAlign =
@@ -1153,8 +1155,9 @@ getSymChar :: NameSpaces -> Element -> RunElem
11531155getSymChar ns element
11541156 | Just s <- lowerFromPrivate <$> getCodepoint
11551157 , Just font <- getFont =
1156− let [(char, _)] = readLitChar ("\\x" ++ s) in
1157− TextRun . maybe "" (:[]) $ getUnicode font char
1158+ case readLitChar ("\\x" ++ s) of
1159+ [(char, _)] -> TextRun . maybe "" (:[]) $ getUnicode font char
1160+ _ -> TextRun ""
11581161 where
11591162 getCodepoint = findAttrByName ns "w" "char" element
11601163 getFont = stringToFont =<< findAttrByName ns "w" "font" element
src/Text/Pandoc/Readers/EPUB.hs+1−1
@@ -73,7 +73,7 @@ readEPUB opts bytes = case toArchiveOrFail bytes of
7373-- runEPUB :: Except PandocError a -> Either PandocError a
7474-- runEPUB = runExcept
7575
76−-- Note that internal reference are aggresively normalised so that all ids
76+-- Note that internal reference are aggressively normalised so that all ids
7777-- are of the form "filename#id"
7878--
7979archiveToEPUB :: (PandocMonad m) => ReaderOptions -> Archive -> m Pandoc
src/Text/Pandoc/Readers/HTML.hs+45−8
@@ -68,11 +68,13 @@ import qualified Text.Pandoc.Builder as B
6868import Text.Pandoc.Class (PandocMonad (..))
6969import Text.Pandoc.CSS (foldOrElse, pickStyleAttrProps)
7070import Text.Pandoc.Definition
71+import Text.Pandoc.Readers.LaTeX (rawLaTeXInline)
72+import Text.Pandoc.Readers.LaTeX.Types (Macro)
7173import Text.Pandoc.Error
7274import Text.Pandoc.Logging
7375import Text.Pandoc.Options (
7476 Extension (Ext_epub_html_exts, Ext_empty_paragraphs, Ext_native_divs,
75− Ext_native_spans, Ext_raw_html, Ext_line_blocks),
77+ Ext_native_spans, Ext_raw_html, Ext_line_blocks, Ext_raw_tex),
7678 ReaderOptions (readerExtensions, readerStripComments),
7779 extensionEnabled)
7880import Text.Pandoc.Parsing hiding ((<|>))
@@ -102,7 +104,8 @@ readHtml opts inp = do
102104 (m:_) -> messageString m
103105 result <- flip runReaderT def $
104106 runParserT parseDoc
105− (HTMLState def{ stateOptions = opts } [] Nothing Set.empty M.empty [])
107+ (HTMLState def{ stateOptions = opts }
108+ [] Nothing Set.empty M.empty [] M.empty)
106109 "source" tags
107110 case result of
108111 Right doc -> return doc
@@ -124,7 +127,8 @@ data HTMLState =
124127 baseHref :: Maybe URI,
125128 identifiers :: Set.Set String,
126129 headerMap :: M.Map Inlines String,
127− logMessages :: [LogMessage]
130+ logMessages :: [LogMessage],
131+ macros :: M.Map Text Macro
128132 }
129133
130134data HTMLLocal = HTMLLocal { quoteContext :: QuoteContext
@@ -659,6 +663,7 @@ inline = choice
659663 , pCode
660664 , pSpan
661665 , pMath False
666+ , pScriptMath
662667 , pRawHtmlInline
663668 ]
664669
@@ -745,18 +750,18 @@ pLink = try $ do
745750 let uid = fromMaybe (T.unpack $ fromAttrib "name" tag) $
746751 maybeFromAttrib "id" tag
747752 let cls = words $ T.unpack $ fromAttrib "class" tag
748− lab <- trimInlines . mconcat <$> manyTill inline (pCloses "a")
753+ lab <- mconcat <$> manyTill inline (pCloses "a")
749754 -- check for href; if href, then a link, otherwise a span
750755 case maybeFromAttrib "href" tag of
751756 Nothing ->
752− return $ B.spanWith (uid, cls, []) lab
757+ return $ extractSpaces (B.spanWith (uid, cls, [])) lab
753758 Just url' -> do
754759 mbBaseHref <- baseHref <$> getState
755760 let url = case (parseURIReference url', mbBaseHref) of
756761 (Just rel, Just bs) ->
757762 show (rel `nonStrictRelativeTo` bs)
758763 _ -> url'
759− return $ B.linkWith (uid, cls, []) (escapeURI url) title lab
764+ return $ extractSpaces (B.linkWith (uid, cls, []) (escapeURI url) title) lab
760765
761766pImage :: PandocMonad m => TagParser m Inlines
762767pImage = do
@@ -818,6 +823,17 @@ toStringAttr :: [(Text, Text)] -> [(String, String)]
818823toStringAttr = map go
819824 where go (x,y) = (T.unpack x, T.unpack y)
820825
826+pScriptMath :: PandocMonad m => TagParser m Inlines
827+pScriptMath = try $ do
828+ TagOpen _ attr' <- pSatisfy $ tagOpen (=="script") (const True)
829+ isdisplay <- case lookup "type" attr' of
830+ Just x | "math/tex" `T.isPrefixOf` x
831+ -> return $ "display" `T.isSuffixOf` x
832+ _ -> mzero
833+ contents <- T.unpack . innerText <$>
834+ manyTill pAnyTag (pSatisfy (matchTagClose "script"))
835+ return $ (if isdisplay then B.displayMath else B.math) contents
836+
821837pMath :: PandocMonad m => Bool -> TagParser m Inlines
822838pMath inCase = try $ do
823839 open@(TagOpen _ attr') <- pSatisfy $ tagOpen (=="math") (const True)
@@ -852,7 +868,7 @@ pInTags' tagtype tagtest parser = try $ do
852868 pSatisfy (\t -> t ~== TagOpen tagtype [] && tagtest t)
853869 mconcat <$> manyTill parser (pCloses tagtype <|> eof)
854870
855−-- parses p, preceeded by an optional opening tag
871+-- parses p, preceded by an optional opening tag
856872-- and followed by an optional closing tags
857873pOptInTag :: PandocMonad m => Text -> TagParser m a -> TagParser m a
858874pOptInTag tagtype p = try $ do
@@ -907,9 +923,25 @@ pTagContents =
907923 <|> pStr
908924 <|> pSpace
909925 <|> smartPunctuation pTagContents
926+ <|> pRawTeX
910927 <|> pSymbol
911928 <|> pBad
912929
930+pRawTeX :: PandocMonad m => InlinesParser m Inlines
931+pRawTeX = do
932+ lookAhead $ try $ do
933+ char '\\'
934+ choice $ map (try . string) ["begin", "eqref", "ref"]
935+ guardEnabled Ext_raw_tex
936+ inp <- getInput
937+ st <- getState
938+ res <- lift $ runParserT (withRaw rawLaTeXInline) st "chunk" (T.unpack inp)
939+ case res of
940+ Left _ -> mzero
941+ Right (contents, raw) -> do
942+ _ <- count (length raw) anyChar
943+ return $ B.rawInline "tex" contents
944+
913945pStr :: PandocMonad m => InlinesParser m Inlines
914946pStr = do
915947 result <- many1 $ satisfy $ \c ->
@@ -923,6 +955,7 @@ isSpecial '\'' = True
923955isSpecial '.' = True
924956isSpecial '-' = True
925957isSpecial '$' = True
958+isSpecial '\\' = True
926959isSpecial '\8216' = True
927960isSpecial '\8217' = True
928961isSpecial '\8220' = True
@@ -1249,6 +1282,10 @@ isSpace _ = False
12491282
12501283-- Instances
12511284
1285+instance HasMacros HTMLState where
1286+ extractMacros = macros
1287+ updateMacros f st = st{ macros = f $ macros st }
1288+
12521289instance HasIdentifierList HTMLState where
12531290 extractIdentifierList = identifiers
12541291 updateIdentifierList f s = s{ identifiers = f (identifiers s) }
@@ -1281,7 +1318,7 @@ instance HasLastStrPosition HTMLState where
12811318 setLastStrPos s st = st {parserState = setLastStrPos s (parserState st)}
12821319 getLastStrPos = getLastStrPos . parserState
12831320
1284−-- For now we need a special verison here; the one in Shared has String type
1321+-- For now we need a special version here; the one in Shared has String type
12851322renderTags' :: [Tag Text] -> Text
12861323renderTags' = renderTagsOptions
12871324 renderOptions{ optMinimize = matchTags ["hr", "br", "img",
src/Text/Pandoc/Readers/Haddock.hs+1−13
@@ -44,11 +44,7 @@ readHaddockEither :: ReaderOptions -- ^ Reader options
4444 -> String -- ^ String to parse
4545 -> Either PandocError Pandoc
4646readHaddockEither _opts =
47−#if MIN_VERSION_haddock_library(1,2,0)
48− Right . B.doc . docHToBlocks . _doc . parseParas
49−#else
50− Right . B.doc . docHToBlocks . parseParas
51−#endif
47+ Right . B.doc . docHToBlocks . _doc . parseParas Nothing
5248
5349docHToBlocks :: DocH String Identifier -> Blocks
5450docHToBlocks d' =
@@ -68,10 +64,8 @@ docHToBlocks d' =
6864 DocEmphasis _ -> inlineFallback
6965 DocMonospaced _ -> inlineFallback
7066 DocBold _ -> inlineFallback
71−#if MIN_VERSION_haddock_library(1,4,0)
7267 DocMathInline _ -> inlineFallback
7368 DocMathDisplay _ -> inlineFallback
74−#endif
7569 DocHeader h -> B.header (headerLevel h)
7670 (docHToInlines False $ headerTitle h)
7771 DocUnorderedList items -> B.bulletList (map docHToBlocks items)
@@ -87,7 +81,6 @@ docHToBlocks d' =
8781 DocProperty s -> B.codeBlockWith ("",["property","haskell"],[]) (trim s)
8882 DocExamples es -> mconcat $ map (\e ->
8983 makeExample ">>>" (exampleExpression e) (exampleResult e)) es
90−#if MIN_VERSION_haddock_library(1,5,0)
9184 DocTable H.Table{ tableHeaderRows = headerRows
9285 , tableBodyRows = bodyRows
9386 }
@@ -100,7 +93,6 @@ docHToBlocks d' =
10093 colspecs = replicate (maximum (map length body))
10194 (AlignDefault, 0.0)
10295 in B.table mempty colspecs header body
103−#endif
10496
10597 where inlineFallback = B.plain $ docHToInlines False d'
10698 consolidatePlains = B.fromList . consolidatePlains' . B.toList
@@ -133,10 +125,8 @@ docHToInlines isCode d' =
133125 DocMonospaced (DocString s) -> B.code s
134126 DocMonospaced d -> docHToInlines True d
135127 DocBold d -> B.strong (docHToInlines isCode d)
136−#if MIN_VERSION_haddock_library(1,4,0)
137128 DocMathInline s -> B.math s
138129 DocMathDisplay s -> B.displayMath s
139−#endif
140130 DocHeader _ -> mempty
141131 DocUnorderedList _ -> mempty
142132 DocOrderedList _ -> mempty
@@ -149,9 +139,7 @@ docHToInlines isCode d' =
149139 DocAName s -> B.spanWith (s,["anchor"],[]) mempty
150140 DocProperty _ -> mempty
151141 DocExamples _ -> mempty
152−#if MIN_VERSION_haddock_library(1,5,0)
153142 DocTable _ -> mempty
154−#endif
155143
156144-- | Create an 'Example', stripping superfluous characters as appropriate
157145makeExample :: String -> String -> [String] -> Blocks
src/Text/Pandoc/Readers/JATS.hs+1−1
@@ -191,7 +191,7 @@ parseBlock (Elem e) =
191191 listType -> do
192192 let start = fromMaybe 1 $
193193 (strContent <$> (filterElement (named "list-item") e
194− >>= filterElement (named "lable")))
194+ >>= filterElement (named "label")))
195195 >>= safeRead
196196 orderedListWith (start, parseListStyleType listType, DefaultDelim)
197197 <$> listitems
src/Text/Pandoc/Readers/LaTeX.hs+495−979
@@ -47,8 +47,7 @@ import Prelude
4747import Control.Applicative (many, optional, (<|>))
4848import Control.Monad
4949import Control.Monad.Except (throwError)
50−import Control.Monad.Trans (lift)
51−import Data.Char (chr, isAlphaNum, isDigit, isLetter, ord, toLower, toUpper)
50+import Data.Char (isDigit, isLetter, toLower, toUpper)
5251import Data.Default
5352import Data.List (intercalate, isPrefixOf)
5453import qualified Data.Map as M
@@ -63,7 +62,7 @@ import Text.Pandoc.Builder
6362import Text.Pandoc.Class (PandocMonad, PandocPure, getResourcePath, lookupEnv,
6463 readFileFromDirs, report, setResourcePath,
6564 setTranslations, translateTerm, trace)
66−import Text.Pandoc.Error (PandocError (PandocMacroLoop, PandocParseError, PandocParsecError))
65+import Text.Pandoc.Error (PandocError ( PandocParseError, PandocParsecError))
6766import Text.Pandoc.Highlighting (fromListingsLanguage, languagesByExtension)
6867import Text.Pandoc.ImageSize (numUnit, showFl)
6968import Text.Pandoc.Logging
@@ -71,12 +70,15 @@ import Text.Pandoc.Options
7170import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
7271 optional, space, spaces, withRaw, (<|>))
7372import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
74− Tok (..), TokType (..))
73+ ArgSpec (..), Tok (..), TokType (..))
74+import Text.Pandoc.Readers.LaTeX.Parsing
75+import Text.Pandoc.Readers.LaTeX.Lang (polyglossiaLangToBCP47,
76+ babelLangToBCP47)
7577import Text.Pandoc.Shared
7678import qualified Text.Pandoc.Translations as Translations
7779import Text.Pandoc.Walk
78−import Text.Parsec.Pos
7980import qualified Text.Pandoc.Builder as B
81+import qualified Data.Text.Normalize as Normalize
8082
8183-- for debugging:
8284-- import Text.Pandoc.Extensions (getDefaultExtensions)
@@ -137,482 +139,49 @@ resolveRefs _ x = x
137139-- Left e -> error (show e)
138140-- Right r -> return r
139141
140−newtype HeaderNum = HeaderNum [Int]
141− deriving (Show)
142−
143−renderHeaderNum :: HeaderNum -> String
144−renderHeaderNum (HeaderNum xs) =
145− intercalate "." (map show xs)
146−
147−incrementHeaderNum :: Int -> HeaderNum -> HeaderNum
148−incrementHeaderNum level (HeaderNum ns) = HeaderNum $
149− case reverse (take level (ns ++ repeat 0)) of
150− (x:xs) -> reverse (x+1 : xs)
151− [] -> [] -- shouldn't happen
152−
153−data LaTeXState = LaTeXState{ sOptions :: ReaderOptions
154− , sMeta :: Meta
155− , sQuoteContext :: QuoteContext
156− , sMacros :: M.Map Text Macro
157− , sContainers :: [String]
158− , sHeaders :: M.Map Inlines String
159− , sLogMessages :: [LogMessage]
160− , sIdentifiers :: Set.Set String
161− , sVerbatimMode :: Bool
162− , sCaption :: Maybe Inlines
163− , sInListItem :: Bool
164− , sInTableCell :: Bool
165− , sLastHeaderNum :: HeaderNum
166− , sLabels :: M.Map String [Inline]
167− , sHasChapters :: Bool
168− , sToggles :: M.Map String Bool
169− }
170− deriving Show
171−
172−defaultLaTeXState :: LaTeXState
173−defaultLaTeXState = LaTeXState{ sOptions = def
174− , sMeta = nullMeta
175− , sQuoteContext = NoQuote
176− , sMacros = M.empty
177− , sContainers = []
178− , sHeaders = M.empty
179− , sLogMessages = []
180− , sIdentifiers = Set.empty
181− , sVerbatimMode = False
182− , sCaption = Nothing
183− , sInListItem = False
184− , sInTableCell = False
185− , sLastHeaderNum = HeaderNum []
186− , sLabels = M.empty
187− , sHasChapters = False
188− , sToggles = M.empty
189− }
190−
191−instance PandocMonad m => HasQuoteContext LaTeXState m where
192− getQuoteContext = sQuoteContext <$> getState
193− withQuoteContext context parser = do
194− oldState <- getState
195− let oldQuoteContext = sQuoteContext oldState
196− setState oldState { sQuoteContext = context }
197− result <- parser
198− newState <- getState
199− setState newState { sQuoteContext = oldQuoteContext }
200− return result
201−
202−instance HasLogMessages LaTeXState where
203− addLogMessage msg st = st{ sLogMessages = msg : sLogMessages st }
204− getLogMessages st = reverse $ sLogMessages st
205−
206−instance HasIdentifierList LaTeXState where
207− extractIdentifierList = sIdentifiers
208− updateIdentifierList f st = st{ sIdentifiers = f $ sIdentifiers st }
209−
210−instance HasIncludeFiles LaTeXState where
211− getIncludeFiles = sContainers
212− addIncludeFile f s = s{ sContainers = f : sContainers s }
213− dropLatestIncludeFile s = s { sContainers = drop 1 $ sContainers s }
214−
215−instance HasHeaderMap LaTeXState where
216− extractHeaderMap = sHeaders
217− updateHeaderMap f st = st{ sHeaders = f $ sHeaders st }
218−
219−instance HasMacros LaTeXState where
220− extractMacros st = sMacros st
221− updateMacros f st = st{ sMacros = f (sMacros st) }
222−
223−instance HasReaderOptions LaTeXState where
224− extractReaderOptions = sOptions
225−
226−instance HasMeta LaTeXState where
227− setMeta field val st =
228− st{ sMeta = setMeta field val $ sMeta st }
229− deleteMeta field st =
230− st{ sMeta = deleteMeta field $ sMeta st }
231−
232−instance Default LaTeXState where
233− def = defaultLaTeXState
234−
235−type LP m = ParserT [Tok] LaTeXState m
236−
237−withVerbatimMode :: PandocMonad m => LP m a -> LP m a
238−withVerbatimMode parser = do
239− updateState $ \st -> st{ sVerbatimMode = True }
240− result <- parser
241− updateState $ \st -> st{ sVerbatimMode = False }
242− return result
243−
244−rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s)
245− => LP m a -> LP m a -> ParserT String s m (a, String)
246−rawLaTeXParser parser valParser = do
247− inp <- getInput
248− let toks = tokenize "source" $ T.pack inp
249− pstate <- getState
250− let lstate = def{ sOptions = extractReaderOptions pstate }
251− let lstate' = lstate { sMacros = extractMacros pstate }
252− let rawparser = (,) <$> withRaw valParser <*> getState
253− res' <- lift $ runParserT (snd <$> withRaw parser) lstate "chunk" toks
254− case res' of
255− Left _ -> mzero
256− Right toks' -> do
257− res <- lift $ runParserT (do doMacros 0
258− -- retokenize, applying macros
259− ts <- many (satisfyTok (const True))
260− setInput ts
261− rawparser)
262− lstate' "chunk" toks'
263− case res of
264− Left _ -> mzero
265− Right ((val, raw), st) -> do
266− updateState (updateMacros (sMacros st <>))
267− _ <- takeP (T.length (untokenize toks'))
268− return (val, T.unpack (untokenize raw))
269−
270−applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
271− => String -> ParserT String s m String
272−applyMacros s = (guardDisabled Ext_latex_macros >> return s) <|>
273− do let retokenize = doMacros 0 *>
274− (toksToString <$> many (satisfyTok (const True)))
275− pstate <- getState
276− let lstate = def{ sOptions = extractReaderOptions pstate
277− , sMacros = extractMacros pstate }
278− res <- runParserT retokenize lstate "math" (tokenize "math" (T.pack s))
279− case res of
280− Left e -> fail (show e)
281− Right s' -> return s'
282142
283143rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
284144 => ParserT String s m String
285145rawLaTeXBlock = do
286146 lookAhead (try (char '\\' >> letter))
287− -- we don't want to apply newly defined latex macros to their own
288− -- definitions:
289− snd <$> rawLaTeXParser (environment <|> macroDef <|> blockCommand) blocks
147+ snd <$> (rawLaTeXParser False macroDef blocks
148+ <|> (rawLaTeXParser True
149+ (do choice (map controlSeq
150+ ["include", "input", "subfile", "usepackage"])
151+ skipMany opt
152+ braced
153+ return mempty) blocks)
154+ <|> rawLaTeXParser True
155+ (environment <|> blockCommand)
156+ (mconcat <$> (many (block <|> beginOrEndCommand))))
157+
158+-- See #4667 for motivation; sometimes people write macros
159+-- that just evaluate to a begin or end command, which blockCommand
160+-- won't accept.
161+beginOrEndCommand :: PandocMonad m => LP m Blocks
162+beginOrEndCommand = try $ do
163+ Tok _ (CtrlSeq name) txt <- anyControlSeq
164+ guard $ name == "begin" || name == "end"
165+ (envname, rawargs) <- withRaw braced
166+ if M.member (untokenize envname)
167+ (inlineEnvironments :: M.Map Text (LP PandocPure Inlines))
168+ then mzero
169+ else return $ rawBlock "latex"
170+ (T.unpack (txt <> untokenize rawargs))
290171
291172rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
292173 => ParserT String s m String
293174rawLaTeXInline = do
294175 lookAhead (try (char '\\' >> letter))
295− snd <$> rawLaTeXParser (inlineEnvironment <|> inlineCommand') inlines
176+ snd <$> ( rawLaTeXParser True
177+ (mempty <$ (controlSeq "input" >> skipMany opt >> braced))
178+ inlines
179+ <|> rawLaTeXParser True (inlineEnvironment <|> inlineCommand') inlines)
296180
297181inlineCommand :: PandocMonad m => ParserT String ParserState m Inlines
298182inlineCommand = do
299183 lookAhead (try (char '\\' >> letter))
300− fst <$> rawLaTeXParser (inlineEnvironment <|> inlineCommand') inlines
301−
302−tokenize :: SourceName -> Text -> [Tok]
303−tokenize sourcename = totoks (initialPos sourcename)
304−
305−totoks :: SourcePos -> Text -> [Tok]
306−totoks pos t =
307− case T.uncons t of
308− Nothing -> []
309− Just (c, rest)
310− | c == '\n' ->
311− Tok pos Newline "\n"
312− : totoks (setSourceColumn (incSourceLine pos 1) 1) rest
313− | isSpaceOrTab c ->
314− let (sps, rest') = T.span isSpaceOrTab t
315− in Tok pos Spaces sps
316− : totoks (incSourceColumn pos (T.length sps))
317− rest'
318− | isAlphaNum c ->
319− let (ws, rest') = T.span isAlphaNum t
320− in Tok pos Word ws
321− : totoks (incSourceColumn pos (T.length ws)) rest'
322− | c == '%' ->
323− let (cs, rest') = T.break (== '\n') rest
324− in Tok pos Comment ("%" <> cs)
325− : totoks (incSourceColumn pos (1 + T.length cs)) rest'
326− | c == '\\' ->
327− case T.uncons rest of
328− Nothing -> [Tok pos (CtrlSeq " ") "\\"]
329− Just (d, rest')
330− | isLetterOrAt d ->
331− -- \makeatletter is common in macro defs;
332− -- ideally we should make tokenization sensitive
333− -- to \makeatletter and \makeatother, but this is
334− -- probably best for now
335− let (ws, rest'') = T.span isLetterOrAt rest
336− (ss, rest''') = T.span isSpaceOrTab rest''
337− in Tok pos (CtrlSeq ws) ("\\" <> ws <> ss)
338− : totoks (incSourceColumn pos
339− (1 + T.length ws + T.length ss)) rest'''
340− | isSpaceOrTab d || d == '\n' ->
341− let (w1, r1) = T.span isSpaceOrTab rest
342− (w2, (w3, r3)) = case T.uncons r1 of
343− Just ('\n', r2)
344− -> (T.pack "\n",
345− T.span isSpaceOrTab r2)
346− _ -> (mempty, (mempty, r1))
347− ws = "\\" <> w1 <> w2 <> w3
348− in case T.uncons r3 of
349− Just ('\n', _) ->
350− Tok pos (CtrlSeq " ") ("\\" <> w1)
351− : totoks (incSourceColumn pos (T.length ws))
352− r1
353− _ ->
354− Tok pos (CtrlSeq " ") ws
355− : totoks (incSourceColumn pos (T.length ws))
356− r3
357− | otherwise ->
358− Tok pos (CtrlSeq (T.singleton d)) (T.pack [c,d])
359− : totoks (incSourceColumn pos 2) rest'
360− | c == '#' ->
361− let (t1, t2) = T.span (\d -> d >= '0' && d <= '9') rest
362− in case safeRead (T.unpack t1) of
363− Just i ->
364− Tok pos (Arg i) ("#" <> t1)
365− : totoks (incSourceColumn pos (1 + T.length t1)) t2
366− Nothing ->
367− Tok pos Symbol "#"
368− : totoks (incSourceColumn pos 1) t2
369− | c == '^' ->
370− case T.uncons rest of
371− Just ('^', rest') ->
372− case T.uncons rest' of
373− Just (d, rest'')
374− | isLowerHex d ->
375− case T.uncons rest'' of
376− Just (e, rest''') | isLowerHex e ->
377− Tok pos Esc2 (T.pack ['^','^',d,e])
378− : totoks (incSourceColumn pos 4) rest'''
379− _ ->
380− Tok pos Esc1 (T.pack ['^','^',d])
381− : totoks (incSourceColumn pos 3) rest''
382− | d < '\128' ->
383− Tok pos Esc1 (T.pack ['^','^',d])
384− : totoks (incSourceColumn pos 3) rest''
385− _ -> Tok pos Symbol "^" :
386− Tok (incSourceColumn pos 1) Symbol "^" :
387− totoks (incSourceColumn pos 2) rest'
388− _ -> Tok pos Symbol "^"
389− : totoks (incSourceColumn pos 1) rest
390− | otherwise ->
391− Tok pos Symbol (T.singleton c) : totoks (incSourceColumn pos 1) rest
392−
393−isSpaceOrTab :: Char -> Bool
394−isSpaceOrTab ' ' = True
395−isSpaceOrTab '\t' = True
396−isSpaceOrTab _ = False
397−
398−isLetterOrAt :: Char -> Bool
399−isLetterOrAt '@' = True
400−isLetterOrAt c = isLetter c
401−
402−isLowerHex :: Char -> Bool
403−isLowerHex x = x >= '0' && x <= '9' || x >= 'a' && x <= 'f'
404−
405−untokenize :: [Tok] -> Text
406−untokenize = mconcat . map untoken
407−
408−untoken :: Tok -> Text
409−untoken (Tok _ _ t) = t
410−
411−satisfyTok :: PandocMonad m => (Tok -> Bool) -> LP m Tok
412−satisfyTok f =
413− try $ do
414− res <- tokenPrim (T.unpack . untoken) updatePos matcher
415− doMacros 0 -- apply macros on remaining input stream
416− return res
417− where matcher t | f t = Just t
418− | otherwise = Nothing
419− updatePos :: SourcePos -> Tok -> [Tok] -> SourcePos
420− updatePos _spos _ (Tok pos _ _ : _) = pos
421− updatePos spos _ [] = incSourceColumn spos 1
422−
423−doMacros :: PandocMonad m => Int -> LP m ()
424−doMacros n = do
425− verbatimMode <- sVerbatimMode <$> getState
426− unless verbatimMode $ do
427− inp <- getInput
428− case inp of
429− Tok spos (CtrlSeq "begin") _ : Tok _ Symbol "{" :
430− Tok _ Word name : Tok _ Symbol "}" : ts
431− -> handleMacros spos name ts
432− Tok spos (CtrlSeq "end") _ : Tok _ Symbol "{" :
433− Tok _ Word name : Tok _ Symbol "}" : ts
434− -> handleMacros spos ("end" <> name) ts
435− Tok _ (CtrlSeq "expandafter") _ : t : ts
436− -> do setInput ts
437− doMacros n
438− getInput >>= setInput . combineTok t
439− Tok spos (CtrlSeq name) _ : ts
440− -> handleMacros spos name ts
441− _ -> return ()
442− where combineTok (Tok spos (CtrlSeq name) x) (Tok _ Word w : ts)
443− | T.all isLetterOrAt w =
444− Tok spos (CtrlSeq (name <> w)) (x1 <> w <> x2) : ts
445− where (x1, x2) = T.break isSpaceOrTab x
446− combineTok t ts = t:ts
447− handleMacros spos name ts = do
448− macros <- sMacros <$> getState
449− case M.lookup name macros of
450− Nothing -> return ()
451− Just (Macro expansionPoint numargs optarg newtoks) -> do
452− setInput ts
453− let getarg = try $ spaces >> bracedOrToken
454− args <- case optarg of
455− Nothing -> count numargs getarg
456− Just o ->
457− (:) <$> option o bracketedToks
458− <*> count (numargs - 1) getarg
459− -- first boolean param is true if we're tokenizing
460− -- an argument (in which case we don't want to
461− -- expand #1 etc.)
462− let addTok False (Tok _ (Arg i) _) acc | i > 0
463− , i <= numargs =
464− foldr (addTok True) acc (args !! (i - 1))
465− -- add space if needed after control sequence
466− -- see #4007
467− addTok _ (Tok _ (CtrlSeq x) txt)
468− acc@(Tok _ Word _ : _)
469− | not (T.null txt) &&
470− isLetter (T.last txt) =
471− Tok spos (CtrlSeq x) (txt <> " ") : acc
472− addTok _ t acc = setpos spos t : acc
473− ts' <- getInput
474− setInput $ foldr (addTok False) ts' newtoks
475− case expansionPoint of
476− ExpandWhenUsed ->
477− if n > 20 -- detect macro expansion loops
478− then throwError $ PandocMacroLoop (T.unpack name)
479− else doMacros (n + 1)
480− ExpandWhenDefined -> return ()
481−
482−
483−setpos :: SourcePos -> Tok -> Tok
484−setpos spos (Tok _ tt txt) = Tok spos tt txt
485−
486−anyControlSeq :: PandocMonad m => LP m Tok
487−anyControlSeq = satisfyTok isCtrlSeq
488− where isCtrlSeq (Tok _ (CtrlSeq _) _) = True
489− isCtrlSeq _ = False
490−
491−anySymbol :: PandocMonad m => LP m Tok
492−anySymbol = satisfyTok isSym
493− where isSym (Tok _ Symbol _) = True
494− isSym _ = False
495−
496−spaces :: PandocMonad m => LP m ()
497−spaces = skipMany (satisfyTok (tokTypeIn [Comment, Spaces, Newline]))
498−
499−spaces1 :: PandocMonad m => LP m ()
500−spaces1 = skipMany1 (satisfyTok (tokTypeIn [Comment, Spaces, Newline]))
501−
502−tokTypeIn :: [TokType] -> Tok -> Bool
503−tokTypeIn toktypes (Tok _ tt _) = tt `elem` toktypes
504−
505−controlSeq :: PandocMonad m => Text -> LP m Tok
506−controlSeq name = satisfyTok isNamed
507− where isNamed (Tok _ (CtrlSeq n) _) = n == name
508− isNamed _ = False
509−
510−symbol :: PandocMonad m => Char -> LP m Tok
511−symbol c = satisfyTok isc
512− where isc (Tok _ Symbol d) = case T.uncons d of
513− Just (c',_) -> c == c'
514− _ -> False
515− isc _ = False
516−
517−symbolIn :: PandocMonad m => [Char] -> LP m Tok
518−symbolIn cs = satisfyTok isInCs
519− where isInCs (Tok _ Symbol d) = case T.uncons d of
520− Just (c,_) -> c `elem` cs
521− _ -> False
522− isInCs _ = False
523−
524−sp :: PandocMonad m => LP m ()
525−sp = whitespace <|> endline
526−
527−whitespace :: PandocMonad m => LP m ()
528−whitespace = () <$ satisfyTok isSpaceTok
529− where isSpaceTok (Tok _ Spaces _) = True
530− isSpaceTok _ = False
531−
532−newlineTok :: PandocMonad m => LP m ()
533−newlineTok = () <$ satisfyTok isNewlineTok
534−
535−isNewlineTok :: Tok -> Bool
536−isNewlineTok (Tok _ Newline _) = True
537−isNewlineTok _ = False
538−
539−comment :: PandocMonad m => LP m ()
540−comment = () <$ satisfyTok isCommentTok
541− where isCommentTok (Tok _ Comment _) = True
542− isCommentTok _ = False
543−
544−anyTok :: PandocMonad m => LP m Tok
545−anyTok = satisfyTok (const True)
546−
547−endline :: PandocMonad m => LP m ()
548−endline = try $ do
549− newlineTok
550− lookAhead anyTok
551− notFollowedBy blankline
552−
553−blankline :: PandocMonad m => LP m ()
554−blankline = try $ skipMany whitespace *> newlineTok
555−
556−primEscape :: PandocMonad m => LP m Char
557−primEscape = do
558− Tok _ toktype t <- satisfyTok (tokTypeIn [Esc1, Esc2])
559− case toktype of
560− Esc1 -> case T.uncons (T.drop 2 t) of
561− Just (c, _)
562− | c >= '\64' && c <= '\127' -> return (chr (ord c - 64))
563− | otherwise -> return (chr (ord c + 64))
564− Nothing -> fail "Empty content of Esc1"
565− Esc2 -> case safeRead ('0':'x':T.unpack (T.drop 2 t)) of
566− Just x -> return (chr x)
567− Nothing -> fail $ "Could not read: " ++ T.unpack t
568− _ -> fail "Expected an Esc1 or Esc2 token" -- should not happen
569−
570−bgroup :: PandocMonad m => LP m Tok
571−bgroup = try $ do
572− skipMany sp
573− symbol '{' <|> controlSeq "bgroup" <|> controlSeq "begingroup"
574−
575−egroup :: PandocMonad m => LP m Tok
576−egroup = symbol '}' <|> controlSeq "egroup" <|> controlSeq "endgroup"
577−
578−grouped :: (PandocMonad m, Monoid a) => LP m a -> LP m a
579−grouped parser = try $ do
580− bgroup
581− -- first we check for an inner 'grouped', because
582− -- {{a,b}} should be parsed the same as {a,b}
583− try (grouped parser <* egroup) <|> (mconcat <$> manyTill parser egroup)
584−
585−braced :: PandocMonad m => LP m [Tok]
586−braced = bgroup *> braced' 1
587− where braced' (n :: Int) =
588− handleEgroup n <|> handleBgroup n <|> handleOther n
589− handleEgroup n = do
590− t <- egroup
591− if n == 1
592− then return []
593− else (t:) <$> braced' (n - 1)
594− handleBgroup n = do
595− t <- bgroup
596− (t:) <$> braced' (n + 1)
597− handleOther n = do
598− t <- anyTok
599− (t:) <$> braced' n
600−
601−bracketed :: PandocMonad m => Monoid a => LP m a -> LP m a
602−bracketed parser = try $ do
603− symbol '['
604− mconcat <$> manyTill parser (symbol ']')
605−
606−dimenarg :: PandocMonad m => LP m Text
607−dimenarg = try $ do
608− ch <- option False $ True <$ symbol '='
609− Tok _ _ s <- satisfyTok isWordTok
610− guard $ T.take 2 (T.reverse s) `elem`
611− ["pt","pc","in","bp","cm","mm","dd","cc","sp"]
612− let num = T.take (T.length s - 2) s
613− guard $ T.length num > 0
614− guard $ T.all isDigit num
615− return $ T.pack ['=' | ch] <> s
184+ fst <$> rawLaTeXParser True (inlineEnvironment <|> inlineCommand') inlines
616185
617186-- inline elements:
618187
@@ -625,13 +194,6 @@ regularSymbol = (str . T.unpack . untoken) <$> satisfyTok isRegularSymbol
625194 isRegularSymbol _ = False
626195 isSpecial c = c `Set.member` specialChars
627196
628−specialChars :: Set.Set Char
629−specialChars = Set.fromList "#$%&~_^\\{}"
630−
631−isWordTok :: Tok -> Bool
632−isWordTok (Tok _ Word _) = True
633−isWordTok _ = False
634−
635197inlineGroup :: PandocMonad m => LP m Inlines
636198inlineGroup = do
637199 ils <- grouped inline
@@ -678,7 +240,7 @@ dosiunitx = do
678240 skipopts
679241 value <- tok
680242 valueprefix <- option "" $ bracketed tok
681− unit <- inlineCommand' <|> tok
243+ unit <- grouped (mconcat <$> many1 siUnit) <|> siUnit <|> tok
682244 let emptyOr160 "" = ""
683245 emptyOr160 _ = "\160"
684246 return . mconcat $ [valueprefix,
@@ -687,11 +249,187 @@ dosiunitx = do
687249 emptyOr160 unit,
688250 unit]
689251
690−-- siunitx's \square command
691−dosquare :: PandocMonad m => LP m Inlines
692−dosquare = do
693− unit <- inlineCommand' <|> tok
694− return . mconcat $ [unit, "\178"]
252+siUnit :: PandocMonad m => LP m Inlines
253+siUnit = do
254+ Tok _ (CtrlSeq name) _ <- anyControlSeq
255+ if name == "square"
256+ then do
257+ unit <- grouped (mconcat <$> many1 siUnit) <|> siUnit <|> tok
258+ return . mconcat $ [unit, "\178"]
259+ else
260+ case M.lookup name siUnitMap of
261+ Just il -> return il
262+ Nothing -> mzero
263+
264+siUnitMap :: M.Map Text Inlines
265+siUnitMap = M.fromList
266+ [ ("fg", str "fg")
267+ , ("pg", str "pg")
268+ , ("ng", str "ng")
269+ , ("ug", str "μg")
270+ , ("mg", str "mg")
271+ , ("g", str "g")
272+ , ("kg", str "kg")
273+ , ("amu", str "u")
274+ , ("pm", str "pm")
275+ , ("nm", str "nm")
276+ , ("um", str "μm")
277+ , ("mm", str "mm")
278+ , ("cm", str "cm")
279+ , ("dm", str "dm")
280+ , ("m", str "m")
281+ , ("km", str "km")
282+ , ("as", str "as")
283+ , ("fs", str "fs")
284+ , ("ps", str "ps")
285+ , ("ns", str "ns")
286+ , ("us", str "μs")
287+ , ("ms", str "ms")
288+ , ("s", str "s")
289+ , ("fmol", str "fmol")
290+ , ("pmol", str "pmol")
291+ , ("nmol", str "nmol")
292+ , ("umol", str "μmol")
293+ , ("mmol", str "mmol")
294+ , ("mol", str "mol")
295+ , ("kmol", str "kmol")
296+ , ("pA", str "pA")
297+ , ("nA", str "nA")
298+ , ("uA", str "μA")
299+ , ("mA", str "mA")
300+ , ("A", str "A")
301+ , ("kA", str "kA")
302+ , ("ul", str "μl")
303+ , ("ml", str "ml")
304+ , ("l", str "l")
305+ , ("hl", str "hl")
306+ , ("uL", str "μL")
307+ , ("mL", str "mL")
308+ , ("L", str "L")
309+ , ("hL", str "hL")
310+ , ("mHz", str "mHz")
311+ , ("Hz", str "Hz")
312+ , ("kHz", str "kHz")
313+ , ("MHz", str "MHz")
314+ , ("GHz", str "GHz")
315+ , ("THz", str "THz")
316+ , ("mN", str "mN")
317+ , ("N", str "N")
318+ , ("kN", str "kN")
319+ , ("MN", str "MN")
320+ , ("Pa", str "Pa")
321+ , ("kPa", str "kPa")
322+ , ("MPa", str "MPa")
323+ , ("GPa", str "GPa")
324+ , ("mohm", str "mΩ")
325+ , ("kohm", str "kΩ")
326+ , ("Mohm", str "MΩ")
327+ , ("pV", str "pV")
328+ , ("nV", str "nV")
329+ , ("uV", str "μV")
330+ , ("mV", str "mV")
331+ , ("V", str "V")
332+ , ("kV", str "kV")
333+ , ("W", str "W")
334+ , ("uW", str "μW")
335+ , ("mW", str "mW")
336+ , ("kW", str "kW")
337+ , ("MW", str "MW")
338+ , ("GW", str "GW")
339+ , ("J", str "J")
340+ , ("uJ", str "μJ")
341+ , ("mJ", str "mJ")
342+ , ("kJ", str "kJ")
343+ , ("eV", str "eV")
344+ , ("meV", str "meV")
345+ , ("keV", str "keV")
346+ , ("MeV", str "MeV")
347+ , ("GeV", str "GeV")
348+ , ("TeV", str "TeV")
349+ , ("kWh", str "kWh")
350+ , ("F", str "F")
351+ , ("fF", str "fF")
352+ , ("pF", str "pF")
353+ , ("K", str "K")
354+ , ("dB", str "dB")
355+ , ("angstrom", str "Å")
356+ , ("arcmin", str "′")
357+ , ("arcminute", str "′")
358+ , ("arcsecond", str "″")
359+ , ("astronomicalunit", str "ua")
360+ , ("atomicmassunit", str "u")
361+ , ("atto", str "a")
362+ , ("bar", str "bar")
363+ , ("barn", str "b")
364+ , ("becquerel", str "Bq")
365+ , ("bel", str "B")
366+ , ("candela", str "cd")
367+ , ("celsius", str "°C")
368+ , ("centi", str "c")
369+ , ("coulomb", str "C")
370+ , ("dalton", str "Da")
371+ , ("day", str "d")
372+ , ("deca", str "d")
373+ , ("deci", str "d")
374+ , ("decibel", str "db")
375+ , ("degreeCelsius",str "°C")
376+ , ("degree", str "°")
377+ , ("deka", str "d")
378+ , ("electronvolt", str "eV")
379+ , ("exa", str "E")
380+ , ("farad", str "F")
381+ , ("femto", str "f")
382+ , ("giga", str "G")
383+ , ("gram", str "g")
384+ , ("hectare", str "ha")
385+ , ("hecto", str "h")
386+ , ("henry", str "H")
387+ , ("hertz", str "Hz")
388+ , ("hour", str "h")
389+ , ("joule", str "J")
390+ , ("katal", str "kat")
391+ , ("kelvin", str "K")
392+ , ("kilo", str "k")
393+ , ("kilogram", str "kg")
394+ , ("knot", str "kn")
395+ , ("liter", str "L")
396+ , ("litre", str "l")
397+ , ("lumen", str "lm")
398+ , ("lux", str "lx")
399+ , ("mega", str "M")
400+ , ("meter", str "m")
401+ , ("metre", str "m")
402+ , ("milli", str "m")
403+ , ("minute", str "min")
404+ , ("mmHg", str "mmHg")
405+ , ("mole", str "mol")
406+ , ("nano", str "n")
407+ , ("nauticalmile", str "M")
408+ , ("neper", str "Np")
409+ , ("newton", str "N")
410+ , ("ohm", str "Ω")
411+ , ("Pa", str "Pa")
412+ , ("pascal", str "Pa")
413+ , ("percent", str "%")
414+ , ("per", str "/")
415+ , ("peta", str "P")
416+ , ("pico", str "p")
417+ , ("radian", str "rad")
418+ , ("second", str "s")
419+ , ("siemens", str "S")
420+ , ("sievert", str "Sv")
421+ , ("steradian", str "sr")
422+ , ("tera", str "T")
423+ , ("tesla", str "T")
424+ , ("tonne", str "t")
425+ , ("volt", str "V")
426+ , ("watt", str "W")
427+ , ("weber", str "Wb")
428+ , ("yocto", str "y")
429+ , ("yotta", str "Y")
430+ , ("zepto", str "z")
431+ , ("zetta", str "Z")
432+ ]
695433
696434lit :: String -> LP m Inlines
697435lit = pure . str
@@ -742,13 +480,31 @@ quoted' f starter ender = do
742480 cs -> cs)
743481 else lit startchs
744482
745−enquote :: PandocMonad m => LP m Inlines
746−enquote = do
483+enquote :: PandocMonad m => Bool -> Maybe Text -> LP m Inlines
484+enquote starred mblang = do
747485 skipopts
486+ let lang = (T.unpack <$> mblang) >>= babelLangToBCP47
487+ let langspan = case lang of
488+ Nothing -> id
489+ Just l -> spanWith ("",[],[("lang", renderLang l)])
748490 quoteContext <- sQuoteContext <$> getState
749− if quoteContext == InDoubleQuote
750− then singleQuoted <$> withQuoteContext InSingleQuote tok
751− else doubleQuoted <$> withQuoteContext InDoubleQuote tok
491+ if starred || quoteContext == InDoubleQuote
492+ then singleQuoted . langspan <$> withQuoteContext InSingleQuote tok
493+ else doubleQuoted . langspan <$> withQuoteContext InDoubleQuote tok
494+
495+blockquote :: PandocMonad m => Bool -> Maybe Text -> LP m Blocks
496+blockquote citations mblang = do
497+ citePar <- if citations
498+ then do
499+ cs <- cites NormalCitation False
500+ return $ para (cite cs mempty)
501+ else return mempty
502+ let lang = (T.unpack <$> mblang) >>= babelLangToBCP47
503+ let langdiv = case lang of
504+ Nothing -> id
505+ Just l -> divWith ("",[],[("lang", renderLang l)])
506+ bs <- grouped block
507+ return $ blockQuote . langdiv $ (bs <> citePar)
752508
753509doAcronym :: PandocMonad m => String -> LP m Inlines
754510doAcronym form = do
@@ -791,6 +547,16 @@ dolstinline :: PandocMonad m => LP m Inlines
791547dolstinline = do
792548 options <- option [] keyvals
793549 let classes = maybeToList $ lookup "language" options >>= fromListingsLanguage
550+ doinlinecode classes
551+
552+domintinline :: PandocMonad m => LP m Inlines
553+domintinline = do
554+ skipopts
555+ cls <- toksToString <$> braced
556+ doinlinecode [cls]
557+
558+doinlinecode :: PandocMonad m => [String] -> LP m Inlines
559+doinlinecode classes = do
794560 Tok _ Symbol t <- anySymbol
795561 marker <- case T.uncons t of
796562 Just (c, ts) | T.null ts -> return c
@@ -803,246 +569,41 @@ dolstinline = do
803569keyval :: PandocMonad m => LP m (String, String)
804570keyval = try $ do
805571 Tok _ Word key <- satisfyTok isWordTok
806− let isSpecSym (Tok _ Symbol t) = t /= "]" && t /= ","
807− isSpecSym _ = False
808572 optional sp
809− val <- option [] $ do
573+ val <- option mempty $ do
810574 symbol '='
811575 optional sp
812− braced <|> many1 (satisfyTok isWordTok <|> satisfyTok isSpecSym
813− <|> anyControlSeq)
814− optional sp
576+ (untokenize <$> braced) <|>
577+ (mconcat <$> many1 (
578+ (untokenize . snd <$> withRaw braced)
579+ <|>
580+ (untokenize <$> (many1
581+ (satisfyTok
582+ (\t -> case t of
583+ Tok _ Symbol "]" -> False
584+ Tok _ Symbol "," -> False
585+ Tok _ Symbol "{" -> False
586+ Tok _ Symbol "}" -> False
587+ _ -> True))))))
815588 optional (symbol ',')
816589 optional sp
817− return (T.unpack key, T.unpack . untokenize $ val)
590+ return (T.unpack key, T.unpack $ T.strip val)
818591
819592keyvals :: PandocMonad m => LP m [(String, String)]
820593keyvals = try $ symbol '[' >> manyTill keyval (symbol ']')
821594
822−accent :: PandocMonad m => Char -> (Char -> String) -> LP m Inlines
823−accent c f = try $ do
595+accent :: PandocMonad m => Char -> Maybe Char -> LP m Inlines
596+accent combiningAccent fallBack = try $ do
824597 ils <- tok
825598 case toList ils of
826− (Str (x:xs) : ys) -> return $ fromList (Str (f x ++ xs) : ys)
827− [Space] -> return $ str [c]
828− [] -> return $ str [c]
599+ (Str (x:xs) : ys) -> return $ fromList $
600+ -- try to normalize to the combined character:
601+ Str (T.unpack
602+ (Normalize.normalize Normalize.NFC
603+ (T.pack [x, combiningAccent])) ++ xs) : ys
604+ [Space] -> return $ str [fromMaybe combiningAccent fallBack]
605+ [] -> return $ str [fromMaybe combiningAccent fallBack]
829606 _ -> return ils
830−
831−grave :: Char -> String
832−grave 'A' = "À"
833−grave 'E' = "È"
834−grave 'I' = "Ì"
835−grave 'O' = "Ò"
836−grave 'U' = "Ù"
837−grave 'a' = "à"
838−grave 'e' = "è"
839−grave 'i' = "ì"
840−grave 'o' = "ò"
841−grave 'u' = "ù"
842−grave c = [c]
843−
844−acute :: Char -> String
845−acute 'A' = "Á"
846−acute 'E' = "É"
847−acute 'I' = "Í"
848−acute 'O' = "Ó"
849−acute 'U' = "Ú"
850−acute 'Y' = "Ý"
851−acute 'a' = "á"
852−acute 'e' = "é"
853−acute 'i' = "í"
854−acute 'o' = "ó"
855−acute 'u' = "ú"
856−acute 'y' = "ý"
857−acute 'C' = "Ć"
858−acute 'c' = "ć"
859−acute 'L' = "Ĺ"
860−acute 'l' = "ĺ"
861−acute 'N' = "Ń"
862−acute 'n' = "ń"
863−acute 'R' = "Ŕ"
864−acute 'r' = "ŕ"
865−acute 'S' = "Ś"
866−acute 's' = "ś"
867−acute 'Z' = "Ź"
868−acute 'z' = "ź"
869−acute c = [c]
870−
871−circ :: Char -> String
872−circ 'A' = "Â"
873−circ 'E' = "Ê"
874−circ 'I' = "Î"
875−circ 'O' = "Ô"
876−circ 'U' = "Û"
877−circ 'a' = "â"
878−circ 'e' = "ê"
879−circ 'i' = "î"
880−circ 'o' = "ô"
881−circ 'u' = "û"
882−circ 'C' = "Ĉ"
883−circ 'c' = "ĉ"
884−circ 'G' = "Ĝ"
885−circ 'g' = "ĝ"
886−circ 'H' = "Ĥ"
887−circ 'h' = "ĥ"
888−circ 'J' = "Ĵ"
889−circ 'j' = "ĵ"
890−circ 'S' = "Ŝ"
891−circ 's' = "ŝ"
892−circ 'W' = "Ŵ"
893−circ 'w' = "ŵ"
894−circ 'Y' = "Ŷ"
895−circ 'y' = "ŷ"
896−circ c = [c]
897−
898−tilde :: Char -> String
899−tilde 'A' = "Ã"
900−tilde 'a' = "ã"
901−tilde 'O' = "Õ"
902−tilde 'o' = "õ"
903−tilde 'I' = "Ĩ"
904−tilde 'i' = "ĩ"
905−tilde 'U' = "Ũ"
906−tilde 'u' = "ũ"
907−tilde 'N' = "Ñ"
908−tilde 'n' = "ñ"
909−tilde c = [c]
910−
911−umlaut :: Char -> String
912−umlaut 'A' = "Ä"
913−umlaut 'E' = "Ë"
914−umlaut 'I' = "Ï"
915−umlaut 'O' = "Ö"
916−umlaut 'U' = "Ü"
917−umlaut 'a' = "ä"
918−umlaut 'e' = "ë"
919−umlaut 'i' = "ï"
920−umlaut 'o' = "ö"
921−umlaut 'u' = "ü"
922−umlaut c = [c]
923−
924−hungarumlaut :: Char -> String
925−hungarumlaut 'A' = "A̋"
926−hungarumlaut 'E' = "E̋"
927−hungarumlaut 'I' = "I̋"
928−hungarumlaut 'O' = "Ő"
929−hungarumlaut 'U' = "Ű"
930−hungarumlaut 'Y' = "ӳ"
931−hungarumlaut 'a' = "a̋"
932−hungarumlaut 'e' = "e̋"
933−hungarumlaut 'i' = "i̋"
934−hungarumlaut 'o' = "ő"
935−hungarumlaut 'u' = "ű"
936−hungarumlaut 'y' = "ӳ"
937−hungarumlaut c = [c]
938−
939−dot :: Char -> String
940−dot 'C' = "Ċ"
941−dot 'c' = "ċ"
942−dot 'E' = "Ė"
943−dot 'e' = "ė"
944−dot 'G' = "Ġ"
945−dot 'g' = "ġ"
946−dot 'I' = "İ"
947−dot 'Z' = "Ż"
948−dot 'z' = "ż"
949−dot c = [c]
950−
951−macron :: Char -> String
952−macron 'A' = "Ā"
953−macron 'E' = "Ē"
954−macron 'I' = "Ī"
955−macron 'O' = "Ō"
956−macron 'U' = "Ū"
957−macron 'a' = "ā"
958−macron 'e' = "ē"
959−macron 'i' = "ī"
960−macron 'o' = "ō"
961−macron 'u' = "ū"
962−macron c = [c]
963−
964−cedilla :: Char -> String
965−cedilla 'c' = "ç"
966−cedilla 'C' = "Ç"
967−cedilla 's' = "ş"
968−cedilla 'S' = "Ş"
969−cedilla 't' = "ţ"
970−cedilla 'T' = "Ţ"
971−cedilla 'e' = "ȩ"
972−cedilla 'E' = "Ȩ"
973−cedilla 'h' = "ḩ"
974−cedilla 'H' = "Ḩ"
975−cedilla 'o' = "o̧"
976−cedilla 'O' = "O̧"
977−cedilla c = [c]
978−
979−hacek :: Char -> String
980−hacek 'A' = "Ǎ"
981−hacek 'a' = "ǎ"
982−hacek 'C' = "Č"
983−hacek 'c' = "č"
984−hacek 'D' = "Ď"
985−hacek 'd' = "ď"
986−hacek 'E' = "Ě"
987−hacek 'e' = "ě"
988−hacek 'G' = "Ǧ"
989−hacek 'g' = "ǧ"
990−hacek 'H' = "Ȟ"
991−hacek 'h' = "ȟ"
992−hacek 'I' = "Ǐ"
993−hacek 'i' = "ǐ"
994−hacek 'j' = "ǰ"
995−hacek 'K' = "Ǩ"
996−hacek 'k' = "ǩ"
997−hacek 'L' = "Ľ"
998−hacek 'l' = "ľ"
999−hacek 'N' = "Ň"
1000−hacek 'n' = "ň"
1001−hacek 'O' = "Ǒ"
1002−hacek 'o' = "ǒ"
1003−hacek 'R' = "Ř"
1004−hacek 'r' = "ř"
1005−hacek 'S' = "Š"
1006−hacek 's' = "š"
1007−hacek 'T' = "Ť"
1008−hacek 't' = "ť"
1009−hacek 'U' = "Ǔ"
1010−hacek 'u' = "ǔ"
1011−hacek 'Z' = "Ž"
1012−hacek 'z' = "ž"
1013−hacek c = [c]
1014−
1015−ogonek :: Char -> String
1016−ogonek 'a' = "ą"
1017−ogonek 'e' = "ę"
1018−ogonek 'o' = "ǫ"
1019−ogonek 'i' = "į"
1020−ogonek 'u' = "ų"
1021−ogonek 'A' = "Ą"
1022−ogonek 'E' = "Ę"
1023−ogonek 'I' = "Į"
1024−ogonek 'O' = "Ǫ"
1025−ogonek 'U' = "Ų"
1026−ogonek c = [c]
1027−
1028−breve :: Char -> String
1029−breve 'A' = "Ă"
1030−breve 'a' = "ă"
1031−breve 'E' = "Ĕ"
1032−breve 'e' = "ĕ"
1033−breve 'G' = "Ğ"
1034−breve 'g' = "ğ"
1035−breve 'I' = "Ĭ"
1036−breve 'i' = "ĭ"
1037−breve 'O' = "Ŏ"
1038−breve 'o' = "ŏ"
1039−breve 'U' = "Ŭ"
1040−breve 'u' = "ŭ"
1041−breve c = [c]
1042−
1043−toksToString :: [Tok] -> String
1044−toksToString = T.unpack . untokenize
1045−
1046607mathDisplay :: String -> Inlines
1047608mathDisplay = displayMath . trim
1048609
@@ -1119,7 +680,21 @@ citationLabel = do
1119680cites :: PandocMonad m => CitationMode -> Bool -> LP m [Citation]
1120681cites mode multi = try $ do
1121682 cits <- if multi
1122− then many1 simpleCiteArgs
683+ then do
684+ multiprenote <- optionMaybe $ toList <$> paropt
685+ multipostnote <- optionMaybe $ toList <$> paropt
686+ let (pre, suf) = case (multiprenote, multipostnote) of
687+ (Just s , Nothing) -> (mempty, s)
688+ (Nothing , Just t) -> (mempty, t)
689+ (Just s , Just t ) -> (s, t)
690+ _ -> (mempty, mempty)
691+ tempCits <- many1 simpleCiteArgs
692+ case tempCits of
693+ (k:ks) -> case ks of
694+ (_:_) -> return $ ((addMprenote pre k):init ks) ++
695+ [addMpostnote suf (last ks)]
696+ _ -> return [addMprenote pre (addMpostnote suf k)]
697+ _ -> return [[]]
1123698 else count 1 simpleCiteArgs
1124699 let cs = concat cits
1125700 return $ case mode of
@@ -1127,6 +702,17 @@ cites mode multi = try $ do
1127702 (c:rest) -> c {citationMode = mode} : rest
1128703 [] -> []
1129704 _ -> map (\a -> a {citationMode = mode}) cs
705+ where mprenote (k:ks) = (k:ks) ++ [Space]
706+ mprenote _ = mempty
707+ mpostnote (k:ks) = [Str ",", Space] ++ (k:ks)
708+ mpostnote _ = mempty
709+ addMprenote mpn (k:ks) =
710+ let mpnfinal = case citationPrefix k of
711+ (_:_) -> mprenote mpn
712+ _ -> mpn
713+ in addPrefix mpnfinal (k:ks)
714+ addMprenote _ _ = []
715+ addMpostnote = addSuffix . mpostnote
1130716
1131717citation :: PandocMonad m => String -> CitationMode -> Bool -> LP m Inlines
1132718citation name mode multi = do
@@ -1181,22 +767,12 @@ tok = try $ spaces >> grouped inline <|> inlineCommand' <|> singleChar'
1181767 Tok _ _ t <- singleChar
1182768 return (str (T.unpack t))
1183769
1184−singleChar :: PandocMonad m => LP m Tok
1185−singleChar = try $ do
1186− Tok pos toktype t <- satisfyTok (tokTypeIn [Word, Symbol])
1187− guard $ not $ toktype == Symbol &&
1188− T.any (`Set.member` specialChars) t
1189− if T.length t > 1
1190− then do
1191− let (t1, t2) = (T.take 1 t, T.drop 1 t)
1192− inp <- getInput
1193− setInput $ Tok (incSourceColumn pos 1) toktype t2 : inp
1194− return $ Tok pos toktype t1
1195− else return $ Tok pos toktype t
1196−
1197770opt :: PandocMonad m => LP m Inlines
1198771opt = bracketed inline <|> (str . T.unpack <$> rawopt)
1199772
773+paropt :: PandocMonad m => LP m Inlines
774+paropt = parenWrapped inline
775+
1200776rawopt :: PandocMonad m => LP m Text
1201777rawopt = do
1202778 inner <- untokenize <$> bracketedToks
@@ -1204,30 +780,28 @@ rawopt = do
1204780 return $ "[" <> inner <> "]"
1205781
1206782skipopts :: PandocMonad m => LP m ()
1207−skipopts = skipMany rawopt
783+skipopts = skipMany (overlaySpecification <|> void rawopt)
1208784
1209785-- opts in angle brackets are used in beamer
1210−rawangle :: PandocMonad m => LP m ()
1211−rawangle = try $ do
786+overlaySpecification :: PandocMonad m => LP m ()
787+overlaySpecification = try $ do
1212788 symbol '<'
1213− () <$ manyTill anyTok (symbol '>')
1214−
1215−skipangles :: PandocMonad m => LP m ()
1216−skipangles = skipMany rawangle
1217−
1218−ignore :: (Monoid a, PandocMonad m) => String -> ParserT s u m a
1219−ignore raw = do
1220− pos <- getPosition
1221− report $ SkippedContent raw pos
1222− return mempty
1223−
1224−withRaw :: PandocMonad m => LP m a -> LP m (a, [Tok])
1225−withRaw parser = do
1226− inp <- getInput
1227− result <- parser
1228− nxt <- option (Tok (initialPos "source") Word "") (lookAhead anyTok)
1229− let raw = takeWhile (/= nxt) inp
1230− return (result, raw)
789+ ts <- manyTill overlayTok (symbol '>')
790+ guard $ case ts of
791+ -- see issue #3368
792+ [Tok _ Word s] | T.all isLetter s -> s `elem`
793+ ["beamer","presentation", "trans",
794+ "handout","article", "second"]
795+ _ -> True
796+
797+overlayTok :: PandocMonad m => LP m Tok
798+overlayTok =
799+ satisfyTok (\t ->
800+ case t of
801+ Tok _ Word _ -> True
802+ Tok _ Spaces _ -> True
803+ Tok _ Symbol c -> c `elem` ["-","+","@","|",":",","]
804+ _ -> False)
1231805
1232806inBrackets :: Inlines -> Inlines
1233807inBrackets x = str "[" <> x <> str "]"
@@ -1275,6 +849,12 @@ inlineEnvironments = M.fromList [
1275849 , ("align*", mathEnvWith id (Just "aligned") "align*")
1276850 , ("alignat", mathEnvWith id (Just "aligned") "alignat")
1277851 , ("alignat*", mathEnvWith id (Just "aligned") "alignat*")
852+ , ("dmath", mathEnvWith id Nothing "dmath")
853+ , ("dmath*", mathEnvWith id Nothing "dmath*")
854+ , ("dgroup", mathEnvWith id (Just "aligned") "dgroup")
855+ , ("dgroup*", mathEnvWith id (Just "aligned") "dgroup*")
856+ , ("darray", mathEnvWith id (Just "aligned") "darray")
857+ , ("darray*", mathEnvWith id (Just "aligned") "darray*")
1278858 ]
1279859
1280860inlineCommands :: PandocMonad m => M.Map Text (LP m Inlines)
@@ -1289,7 +869,7 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
1289869 , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
1290870 , ("texttt", ttfamily)
1291871 , ("sout", extractSpaces strikeout <$> tok)
1292− , ("alert", skipangles >> spanWith ("",["alert"],[]) <$> tok) -- beamer
872+ , ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
1293873 , ("lq", return (str "‘"))
1294874 , ("rq", return (str "’"))
1295875 , ("textquoteleft", return (str "‘"))
@@ -1318,7 +898,7 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
1318898 , ("(", mathInline . toksToString <$> manyTill anyTok (controlSeq ")"))
1319899 , ("[", mathDisplay . toksToString <$> manyTill anyTok (controlSeq "]"))
1320900 , ("ensuremath", mathInline . toksToString <$> braced)
1321− , ("texorpdfstring", (\_ x -> x) <$> tok <*> tok)
901+ , ("texorpdfstring", (\x _ -> x) <$> tok <*> tok)
1322902 , ("P", lit "¶")
1323903 , ("S", lit "§")
1324904 , ("$", lit "$")
@@ -1361,20 +941,32 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
1361941 , ("copyright", lit "©")
1362942 , ("textasciicircum", lit "^")
1363943 , ("textasciitilde", lit "~")
1364− , ("H", accent '\779' hungarumlaut)
1365− , ("`", accent '`' grave)
1366− , ("'", accent '\'' acute)
1367− , ("^", accent '^' circ)
1368− , ("~", accent '~' tilde)
1369− , ("\"", accent '\776' umlaut)
1370− , (".", accent '\775' dot)
1371− , ("=", accent '\772' macron)
1372− , ("c", accent '\807' cedilla)
1373− , ("v", accent 'ˇ' hacek)
1374− , ("u", accent '\774' breve)
1375− , ("k", accent '\808' ogonek)
1376− , ("textogonekcentered", accent '\808' ogonek)
1377− , ("i", lit "i")
944+ , ("H", accent '\779' Nothing) -- hungarumlaut
945+ , ("`", accent '\768' (Just '`')) -- grave
946+ , ("'", accent '\769' (Just '\'')) -- acute
947+ , ("^", accent '\770' (Just '^')) -- circ
948+ , ("~", accent '\771' (Just '~')) -- tilde
949+ , ("\"", accent '\776' Nothing) -- umlaut
950+ , (".", accent '\775' Nothing) -- dot
951+ , ("=", accent '\772' Nothing) -- macron
952+ , ("|", accent '\781' Nothing) -- vertical line above
953+ , ("b", accent '\817' Nothing) -- macron below
954+ , ("c", accent '\807' Nothing) -- cedilla
955+ , ("G", accent '\783' Nothing) -- doublegrave
956+ , ("h", accent '\777' Nothing) -- hookabove
957+ , ("d", accent '\803' Nothing) -- dotbelow
958+ , ("f", accent '\785' Nothing) -- inverted breve
959+ , ("r", accent '\778' Nothing) -- ringabove
960+ , ("t", accent '\865' Nothing) -- double inverted breve
961+ , ("U", accent '\782' Nothing) -- double vertical line above
962+ , ("v", accent '\780' Nothing) -- hacek
963+ , ("u", accent '\774' Nothing) -- breve
964+ , ("k", accent '\808' Nothing) -- ogonek
965+ , ("textogonekcentered", accent '\808' Nothing) -- ogonek
966+ , ("i", lit "ı") -- dotless i
967+ , ("j", lit "ȷ") -- dotless j
968+ , ("newtie", accent '\785' Nothing) -- inverted breve
969+ , ("textcircled", accent '\8413' Nothing) -- combining circle
1378970 , ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState
1379971 guard $ not inTableCell
1380972 optional opt
@@ -1392,17 +984,25 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
1392984 , ("footnote", skipopts >> note <$> grouped block)
1393985 , ("verb", doverb)
1394986 , ("lstinline", dolstinline)
987+ , ("mintinline", domintinline)
1395988 , ("Verb", doverb)
1396− , ("url", ((unescapeURL . T.unpack . untokenize) <$> braced) >>= \url ->
989+ , ("url", ((unescapeURL . T.unpack . untokenize) <$> bracedUrl) >>= \url ->
1397990 pure (link url "" (str url)))
1398991 , ("href", (unescapeURL . toksToString <$>
1399− braced <* optional sp) >>= \url ->
992+ bracedUrl <* optional sp) >>= \url ->
1400993 tok >>= \lab -> pure (link url "" lab))
1401994 , ("includegraphics", do options <- option [] keyvals
1402995 src <- unescapeURL . T.unpack .
1403996 removeDoubleQuotes . untokenize <$> braced
1404997 mkImage options src)
1405− , ("enquote", enquote)
998+ , ("enquote*", enquote True Nothing)
999+ , ("enquote", enquote False Nothing)
1000+ -- foreignquote is supposed to use native quote marks
1001+ , ("foreignquote*", braced >>= enquote True . Just . untokenize)
1002+ , ("foreignquote", braced >>= enquote False . Just . untokenize)
1003+ -- hypehnquote uses regular quotes
1004+ , ("hyphenquote*", braced >>= enquote True . Just . untokenize)
1005+ , ("hyphenquote", braced >>= enquote False . Just . untokenize)
14061006 , ("figurename", doTerm Translations.Figure)
14071007 , ("prefacename", doTerm Translations.Preface)
14081008 , ("refname", doTerm Translations.References)
@@ -1507,13 +1107,6 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
15071107 , ("acsp", doAcronymPlural "abbrv")
15081108 -- siuntix
15091109 , ("SI", dosiunitx)
1510− -- units of siuntix
1511− , ("celsius", lit "°C")
1512− , ("degreeCelsius", lit "°C")
1513− , ("gram", lit "g")
1514− , ("meter", lit "m")
1515− , ("milli", lit "m")
1516− , ("square", dosquare)
15171110 -- hyphenat
15181111 , ("bshyp", lit "\\\173")
15191112 , ("fshyp", lit "/\173")
@@ -1542,8 +1135,18 @@ inlineCommands = M.union inlineLanguageCommands $ M.fromList
15421135 , ("Rn", romanNumeralLower)
15431136 -- babel
15441137 , ("foreignlanguage", foreignlanguage)
1138+ -- include
1139+ , ("input", include "input")
1140+ -- plain tex stuff that should just be passed through as raw tex
1141+ , ("ifdim", ifdim)
15451142 ]
15461143
1144+ifdim :: PandocMonad m => LP m Inlines
1145+ifdim = do
1146+ contents <- manyTill anyTok (controlSeq "fi")
1147+ return $ rawInline "latex" $ T.unpack $
1148+ "\\ifdim" <> untokenize contents <> "\\fi"
1149+
15471150makeUppercase :: Inlines -> Inlines
15481151makeUppercase = fromList . walk (alterStr (map toUpper)) . toList
15491152
@@ -1693,7 +1296,6 @@ getRawCommand name txt = do
16931296 "def" ->
16941297 void $ manyTill anyTok braced
16951298 _ -> do
1696− skipangles
16971299 skipopts
16981300 option "" (try (optional sp *> dimenarg))
16991301 void $ many braced
@@ -1818,7 +1420,6 @@ end_ t = try (do
18181420preamble :: PandocMonad m => LP m Blocks
18191421preamble = mempty <$ many preambleBlock
18201422 where preambleBlock = spaces1
1821− <|> void include
18221423 <|> void macroDef
18231424 <|> void blockCommand
18241425 <|> void braced
@@ -1831,11 +1432,8 @@ paragraph = do
18311432 then return mempty
18321433 else return $ para x
18331434
1834−include :: PandocMonad m => LP m Blocks
1835−include = do
1836− (Tok _ (CtrlSeq name) _) <-
1837− controlSeq "include" <|> controlSeq "input" <|>
1838− controlSeq "subfile" <|> controlSeq "usepackage"
1435+include :: (PandocMonad m, Monoid a) => Text -> LP m a
1436+include name = do
18391437 skipMany opt
18401438 fs <- (map (T.unpack . removeDoubleQuotes . T.strip) . T.splitOn "," .
18411439 untokenize) <$> braced
@@ -1912,31 +1510,28 @@ letmacro = do
19121510 optional $ symbol '='
19131511 spaces
19141512 contents <- bracedOrToken
1915− return (name, Macro ExpandWhenDefined 0 Nothing contents)
1513+ return (name, Macro ExpandWhenDefined [] Nothing contents)
19161514
19171515defmacro :: PandocMonad m => LP m (Text, Macro)
19181516defmacro = try $ do
19191517 controlSeq "def"
19201518 Tok _ (CtrlSeq name) _ <- anyControlSeq
1921− numargs <- option 0 $ argSeq 1
1519+ argspecs <- many (argspecArg <|> argspecPattern)
19221520 -- we use withVerbatimMode, because macros are to be expanded
19231521 -- at point of use, not point of definition
19241522 contents <- withVerbatimMode bracedOrToken
1925− return (name, Macro ExpandWhenUsed numargs Nothing contents)
1523+ return (name, Macro ExpandWhenUsed argspecs Nothing contents)
19261524
1927−-- Note: we don't yet support fancy things like #1.#2
1928−argSeq :: PandocMonad m => Int -> LP m Int
1929−argSeq n = do
1525+argspecArg :: PandocMonad m => LP m ArgSpec
1526+argspecArg = do
19301527 Tok _ (Arg i) _ <- satisfyTok isArgTok
1931− guard $ i == n
1932− argSeq (n+1) <|> return n
1528+ return $ ArgNum i
19331529
1934−isArgTok :: Tok -> Bool
1935−isArgTok (Tok _ (Arg _) _) = True
1936−isArgTok _ = False
1937−
1938−bracedOrToken :: PandocMonad m => LP m [Tok]
1939−bracedOrToken = braced <|> ((:[]) <$> (anyControlSeq <|> singleChar))
1530+argspecPattern :: PandocMonad m => LP m ArgSpec
1531+argspecPattern =
1532+ Pattern <$> many1 (satisfyTok (\(Tok _ toktype' txt) ->
1533+ (toktype' == Symbol || toktype' == Word) &&
1534+ (txt /= "{" && txt /= "\\" && txt /= "}")))
19401535
19411536newcommand :: PandocMonad m => LP m (Text, Macro)
19421537newcommand = do
@@ -1950,6 +1545,7 @@ newcommand = do
19501545 (symbol '{' *> spaces *> anyControlSeq <* spaces <* symbol '}')
19511546 spaces
19521547 numargs <- option 0 $ try bracketedNum
1548+ let argspecs = map (\i -> ArgNum i) [1..numargs]
19531549 spaces
19541550 optarg <- option Nothing $ Just <$> try bracketedToks
19551551 spaces
@@ -1959,7 +1555,7 @@ newcommand = do
19591555 case M.lookup name macros of
19601556 Just _ -> report $ MacroAlreadyDefined (T.unpack txt) pos
19611557 Nothing -> return ()
1962− return (name, Macro ExpandWhenUsed numargs optarg contents)
1558+ return (name, Macro ExpandWhenUsed argspecs optarg contents)
19631559
19641560newenvironment :: PandocMonad m => LP m (Text, Macro, Macro)
19651561newenvironment = do
@@ -1972,6 +1568,7 @@ newenvironment = do
19721568 name <- untokenize <$> braced
19731569 spaces
19741570 numargs <- option 0 $ try bracketedNum
1571+ let argspecs = map (\i -> ArgNum i) [1..numargs]
19751572 spaces
19761573 optarg <- option Nothing $ Just <$> try bracketedToks
19771574 spaces
@@ -1983,13 +1580,8 @@ newenvironment = do
19831580 case M.lookup name macros of
19841581 Just _ -> report $ MacroAlreadyDefined (T.unpack name) pos
19851582 Nothing -> return ()
1986− return (name, Macro ExpandWhenUsed numargs optarg startcontents,
1987− Macro ExpandWhenUsed 0 Nothing endcontents)
1988−
1989−bracketedToks :: PandocMonad m => LP m [Tok]
1990−bracketedToks = do
1991− symbol '['
1992− mconcat <$> manyTill (braced <|> (:[]) <$> anyTok) (symbol ']')
1583+ return (name, Macro ExpandWhenUsed argspecs optarg startcontents,
1584+ Macro ExpandWhenUsed [] Nothing endcontents)
19931585
19941586bracketedNum :: PandocMonad m => LP m Int
19951587bracketedNum = do
@@ -2003,11 +1595,13 @@ setCaption = do
20031595 ils <- tok
20041596 mblabel <- option Nothing $
20051597 try $ spaces >> controlSeq "label" >> (Just <$> tok)
2006− let ils' = case mblabel of
2007− Just lab -> ils <> spanWith
2008− ("",[],[("label", stringify lab)]) mempty
2009− Nothing -> ils
2010− updateState $ \st -> st{ sCaption = Just ils' }
1598+ let capt = case mblabel of
1599+ Just lab -> let slab = stringify lab
1600+ ils' = ils <> spanWith
1601+ ("",[],[("label", slab)]) mempty
1602+ in (Just ils', Just slab)
1603+ Nothing -> (Just ils, Nothing)
1604+ updateState $ \st -> st{ sCaption = capt }
20111605 return mempty
20121606
20131607looseItem :: PandocMonad m => LP m Blocks
@@ -2018,28 +1612,27 @@ looseItem = do
20181612 return mempty
20191613
20201614resetCaption :: PandocMonad m => LP m ()
2021−resetCaption = updateState $ \st -> st{ sCaption = Nothing }
1615+resetCaption = updateState $ \st -> st{ sCaption = (Nothing, Nothing) }
20221616
2023−section :: PandocMonad m => Bool -> Attr -> Int -> LP m Blocks
2024−section starred (ident, classes, kvs) lvl = do
1617+section :: PandocMonad m => Attr -> Int -> LP m Blocks
1618+section (ident, classes, kvs) lvl = do
20251619 skipopts
20261620 contents <- grouped inline
20271621 lab <- option ident $
20281622 try (spaces >> controlSeq "label"
20291623 >> spaces >> toksToString <$> braced)
2030− let classes' = if starred then "unnumbered" : classes else classes
20311624 when (lvl == 0) $
20321625 updateState $ \st -> st{ sHasChapters = True }
2033− unless starred $ do
1626+ unless ("unnumbered" `elem` classes) $ do
20341627 hn <- sLastHeaderNum <$> getState
20351628 hasChapters <- sHasChapters <$> getState
20361629 let lvl' = lvl + if hasChapters then 1 else 0
2037− let num = incrementHeaderNum lvl' hn
2038− updateState $ \st -> st{ sLastHeaderNum = num }
2039− updateState $ \st -> st{ sLabels = M.insert lab
2040− [Str (renderHeaderNum num)]
2041− (sLabels st) }
2042− attr' <- registerHeader (lab, classes', kvs) contents
1630+ let num = incrementDottedNum lvl' hn
1631+ updateState $ \st -> st{ sLastHeaderNum = num
1632+ , sLabels = M.insert lab
1633+ [Str (renderDottedNum num)]
1634+ (sLabels st) }
1635+ attr' <- registerHeader (lab, classes, kvs) contents
20431636 return $ headerWith attr' lvl contents
20441637
20451638blockCommand :: PandocMonad m => LP m Blocks
@@ -2100,23 +1693,23 @@ blockCommands = M.fromList
21001693 -- Koma-script metadata commands
21011694 , ("dedication", mempty <$ (skipopts *> tok >>= addMeta "dedication"))
21021695 -- sectioning
2103− , ("part", section False nullAttr (-1))
2104− , ("part*", section True nullAttr (-1))
2105− , ("chapter", section False nullAttr 0)
2106− , ("chapter*", section True ("",["unnumbered"],[]) 0)
2107− , ("section", section False nullAttr 1)
2108− , ("section*", section True ("",["unnumbered"],[]) 1)
2109− , ("subsection", section False nullAttr 2)
2110− , ("subsection*", section True ("",["unnumbered"],[]) 2)
2111− , ("subsubsection", section False nullAttr 3)
2112− , ("subsubsection*", section True ("",["unnumbered"],[]) 3)
2113− , ("paragraph", section False nullAttr 4)
2114− , ("paragraph*", section True ("",["unnumbered"],[]) 4)
2115− , ("subparagraph", section False nullAttr 5)
2116− , ("subparagraph*", section True ("",["unnumbered"],[]) 5)
1696+ , ("part", section nullAttr (-1))
1697+ , ("part*", section nullAttr (-1))
1698+ , ("chapter", section nullAttr 0)
1699+ , ("chapter*", section ("",["unnumbered"],[]) 0)
1700+ , ("section", section nullAttr 1)
1701+ , ("section*", section ("",["unnumbered"],[]) 1)
1702+ , ("subsection", section nullAttr 2)
1703+ , ("subsection*", section ("",["unnumbered"],[]) 2)
1704+ , ("subsubsection", section nullAttr 3)
1705+ , ("subsubsection*", section ("",["unnumbered"],[]) 3)
1706+ , ("paragraph", section nullAttr 4)
1707+ , ("paragraph*", section ("",["unnumbered"],[]) 4)
1708+ , ("subparagraph", section nullAttr 5)
1709+ , ("subparagraph*", section ("",["unnumbered"],[]) 5)
21171710 -- beamer slides
2118− , ("frametitle", section False nullAttr 3)
2119− , ("framesubtitle", section False nullAttr 4)
1711+ , ("frametitle", section nullAttr 3)
1712+ , ("framesubtitle", section nullAttr 4)
21201713 -- letters
21211714 , ("opening", (para . trimInlines) <$> (skipopts *> tok))
21221715 , ("closing", skipopts *> closing)
@@ -2152,6 +1745,18 @@ blockCommands = M.fromList
21521745 -- LaTeX colors
21531746 , ("textcolor", coloredBlock "color")
21541747 , ("colorbox", coloredBlock "background-color")
1748+ -- csquotes
1749+ , ("blockquote", blockquote False Nothing)
1750+ , ("blockcquote", blockquote True Nothing)
1751+ , ("foreignblockquote", braced >>= blockquote False . Just . untokenize)
1752+ , ("foreignblockcquote", braced >>= blockquote True . Just . untokenize)
1753+ , ("hyphenblockquote", braced >>= blockquote False . Just . untokenize)
1754+ , ("hyphenblockcquote", braced >>= blockquote True . Just . untokenize)
1755+ -- include
1756+ , ("include", include "include")
1757+ , ("input", include "input")
1758+ , ("subfile", include "subfile")
1759+ , ("usepackage", include "usepackage")
21551760 ]
21561761
21571762
@@ -2192,6 +1797,7 @@ environments = M.fromList
21921797 , ("minted", minted)
21931798 , ("obeylines", obeylines)
21941799 , ("tikzpicture", rawVerbEnv "tikzpicture")
1800+ , ("lilypond", rawVerbEnv "lilypond")
21951801 -- etoolbox
21961802 , ("ifstrequal", ifstrequal)
21971803 , ("newtoggle", braced >>= newToggle)
@@ -2234,7 +1840,7 @@ rawVerbEnv :: PandocMonad m => Text -> LP m Blocks
22341840rawVerbEnv name = do
22351841 pos <- getPosition
22361842 (_, raw) <- withRaw $ verbEnv name
2237− let raw' = "\\begin{tikzpicture}" ++ toksToString raw
1843+ let raw' = "\\begin{" ++ T.unpack name ++ "}" ++ toksToString raw
22381844 exts <- getOption readerExtensions
22391845 let parseRaw = extensionEnabled Ext_raw_tex exts
22401846 if parseRaw
@@ -2248,7 +1854,20 @@ verbEnv name = withVerbatimMode $ do
22481854 skipopts
22491855 optional blankline
22501856 res <- manyTill anyTok (end_ name)
2251− return $ stripTrailingNewlines $ toksToString res
1857+ return $ T.unpack
1858+ $ stripTrailingNewline
1859+ $ untokenize
1860+ $ res
1861+
1862+-- Strip single final newline and any spaces following it.
1863+-- Input is unchanged if it doesn't end with newline +
1864+-- optional spaces.
1865+stripTrailingNewline :: Text -> Text
1866+stripTrailingNewline t =
1867+ let (b, e) = T.breakOnEnd "\n" t
1868+ in if T.all (== ' ') e
1869+ then T.dropEnd 1 b
1870+ else t
22521871
22531872fancyverbEnv :: PandocMonad m => Text -> LP m Blocks
22541873fancyverbEnv name = do
@@ -2303,12 +1922,43 @@ figure = try $ do
23031922
23041923addImageCaption :: PandocMonad m => Blocks -> LP m Blocks
23051924addImageCaption = walkM go
2306− where go (Image attr alt (src,tit))
1925+ where go (Image attr@(_, cls, kvs) alt (src,tit))
23071926 | not ("fig:" `isPrefixOf` tit) = do
2308− mbcapt <- sCaption <$> getState
2309− return $ case mbcapt of
2310− Just ils -> Image attr (toList ils) (src, "fig:" ++ tit)
2311− Nothing -> Image attr alt (src,tit)
1927+ (mbcapt, mblab) <- sCaption <$> getState
1928+ let (alt', tit') = case mbcapt of
1929+ Just ils -> (toList ils, "fig:" ++ tit)
1930+ Nothing -> (alt, tit)
1931+ attr' = case mblab of
1932+ Just lab -> (lab, cls, kvs)
1933+ Nothing -> attr
1934+ case attr' of
1935+ ("", _, _) -> return ()
1936+ (ident, _, _) -> do
1937+ st <- getState
1938+ let chapnum =
1939+ case (sHasChapters st, sLastHeaderNum st) of
1940+ (True, DottedNum (n:_)) -> Just n
1941+ _ -> Nothing
1942+ let num = case sLastFigureNum st of
1943+ DottedNum [m,n] ->
1944+ case chapnum of
1945+ Just m' | m' == m -> DottedNum [m, n+1]
1946+ | otherwise -> DottedNum [m', 1]
1947+ Nothing -> DottedNum [1]
1948+ -- shouldn't happen
1949+ DottedNum [n] ->
1950+ case chapnum of
1951+ Just m -> DottedNum [m, 1]
1952+ Nothing -> DottedNum [n + 1]
1953+ _ ->
1954+ case chapnum of
1955+ Just n -> DottedNum [n, 1]
1956+ Nothing -> DottedNum [1]
1957+ setState $
1958+ st{ sLastFigureNum = num
1959+ , sLabels = M.insert ident
1960+ [Str (renderDottedNum num)] (sLabels st) }
1961+ return $ Image attr' alt' (src, tit')
23121962 go x = return x
23131963
23141964coloredBlock :: PandocMonad m => String -> LP m Blocks
@@ -2321,7 +1971,8 @@ coloredBlock stylename = try $ do
23211971
23221972graphicsPath :: PandocMonad m => LP m Blocks
23231973graphicsPath = do
2324− ps <- map toksToString <$> (bgroup *> manyTill braced egroup)
1974+ ps <- map toksToString <$>
1975+ (bgroup *> spaces *> manyTill (braced <* spaces) egroup)
23251976 getResourcePath >>= setResourcePath . (++ ps)
23261977 return mempty
23271978
@@ -2579,7 +2230,7 @@ simpTable envname hasWidthParameter = try $ do
25792230addTableCaption :: PandocMonad m => Blocks -> LP m Blocks
25802231addTableCaption = walkM go
25812232 where go (Table c als ws hs rs) = do
2582− mbcapt <- sCaption <$> getState
2233+ (mbcapt, _) <- sCaption <$> getState
25832234 return $ case mbcapt of
25842235 Just ils -> Table (toList ils) als ws hs rs
25852236 Nothing -> Table c als ws hs rs
@@ -2590,7 +2241,6 @@ block :: PandocMonad m => LP m Blocks
25902241block = do
25912242 res <- (mempty <$ spaces1)
25922243 <|> environment
2593− <|> include
25942244 <|> macroDef
25952245 <|> blockCommand
25962246 <|> paragraph
@@ -2613,137 +2263,3 @@ setDefaultLanguage = do
26132263 setTranslations l
26142264 updateState $ setMeta "lang" $ str (renderLang l)
26152265 return mempty
2616−
2617−polyglossiaLangToBCP47 :: M.Map String (String -> Lang)
2618−polyglossiaLangToBCP47 = M.fromList
2619− [ ("arabic", \o -> case filter (/=' ') o of
2620− "locale=algeria" -> Lang "ar" "" "DZ" []
2621− "locale=mashriq" -> Lang "ar" "" "SY" []
2622− "locale=libya" -> Lang "ar" "" "LY" []
2623− "locale=morocco" -> Lang "ar" "" "MA" []
2624− "locale=mauritania" -> Lang "ar" "" "MR" []
2625− "locale=tunisia" -> Lang "ar" "" "TN" []
2626− _ -> Lang "ar" "" "" [])
2627− , ("german", \o -> case filter (/=' ') o of
2628− "spelling=old" -> Lang "de" "" "DE" ["1901"]
2629− "variant=austrian,spelling=old"
2630− -> Lang "de" "" "AT" ["1901"]
2631− "variant=austrian" -> Lang "de" "" "AT" []
2632− "variant=swiss,spelling=old"
2633− -> Lang "de" "" "CH" ["1901"]
2634− "variant=swiss" -> Lang "de" "" "CH" []
2635− _ -> Lang "de" "" "" [])
2636− , ("lsorbian", \_ -> Lang "dsb" "" "" [])
2637− , ("greek", \o -> case filter (/=' ') o of
2638− "variant=poly" -> Lang "el" "" "polyton" []
2639− "variant=ancient" -> Lang "grc" "" "" []
2640− _ -> Lang "el" "" "" [])
2641− , ("english", \o -> case filter (/=' ') o of
2642− "variant=australian" -> Lang "en" "" "AU" []
2643− "variant=canadian" -> Lang "en" "" "CA" []
2644− "variant=british" -> Lang "en" "" "GB" []
2645− "variant=newzealand" -> Lang "en" "" "NZ" []
2646− "variant=american" -> Lang "en" "" "US" []
2647− _ -> Lang "en" "" "" [])
2648− , ("usorbian", \_ -> Lang "hsb" "" "" [])
2649− , ("latin", \o -> case filter (/=' ') o of
2650− "variant=classic" -> Lang "la" "" "" ["x-classic"]
2651− _ -> Lang "la" "" "" [])
2652− , ("slovenian", \_ -> Lang "sl" "" "" [])
2653− , ("serbianc", \_ -> Lang "sr" "cyrl" "" [])
2654− , ("pinyin", \_ -> Lang "zh" "Latn" "" ["pinyin"])
2655− , ("afrikaans", \_ -> Lang "af" "" "" [])
2656− , ("amharic", \_ -> Lang "am" "" "" [])
2657− , ("assamese", \_ -> Lang "as" "" "" [])
2658− , ("asturian", \_ -> Lang "ast" "" "" [])
2659− , ("bulgarian", \_ -> Lang "bg" "" "" [])
2660− , ("bengali", \_ -> Lang "bn" "" "" [])
2661− , ("tibetan", \_ -> Lang "bo" "" "" [])
2662− , ("breton", \_ -> Lang "br" "" "" [])
2663− , ("catalan", \_ -> Lang "ca" "" "" [])
2664− , ("welsh", \_ -> Lang "cy" "" "" [])
2665− , ("czech", \_ -> Lang "cs" "" "" [])
2666− , ("coptic", \_ -> Lang "cop" "" "" [])
2667− , ("danish", \_ -> Lang "da" "" "" [])
2668− , ("divehi", \_ -> Lang "dv" "" "" [])
2669− , ("esperanto", \_ -> Lang "eo" "" "" [])
2670− , ("spanish", \_ -> Lang "es" "" "" [])
2671− , ("estonian", \_ -> Lang "et" "" "" [])
2672− , ("basque", \_ -> Lang "eu" "" "" [])
2673− , ("farsi", \_ -> Lang "fa" "" "" [])
2674− , ("finnish", \_ -> Lang "fi" "" "" [])
2675− , ("french", \_ -> Lang "fr" "" "" [])
2676− , ("friulan", \_ -> Lang "fur" "" "" [])
2677− , ("irish", \_ -> Lang "ga" "" "" [])
2678− , ("scottish", \_ -> Lang "gd" "" "" [])
2679− , ("ethiopic", \_ -> Lang "gez" "" "" [])
2680− , ("galician", \_ -> Lang "gl" "" "" [])
2681− , ("hebrew", \_ -> Lang "he" "" "" [])
2682− , ("hindi", \_ -> Lang "hi" "" "" [])
2683− , ("croatian", \_ -> Lang "hr" "" "" [])
2684− , ("magyar", \_ -> Lang "hu" "" "" [])
2685− , ("armenian", \_ -> Lang "hy" "" "" [])
2686− , ("interlingua", \_ -> Lang "ia" "" "" [])
2687− , ("indonesian", \_ -> Lang "id" "" "" [])
2688− , ("icelandic", \_ -> Lang "is" "" "" [])
2689− , ("italian", \_ -> Lang "it" "" "" [])
2690− , ("japanese", \_ -> Lang "jp" "" "" [])
2691− , ("khmer", \_ -> Lang "km" "" "" [])
2692− , ("kurmanji", \_ -> Lang "kmr" "" "" [])
2693− , ("kannada", \_ -> Lang "kn" "" "" [])
2694− , ("korean", \_ -> Lang "ko" "" "" [])
2695− , ("lao", \_ -> Lang "lo" "" "" [])
2696− , ("lithuanian", \_ -> Lang "lt" "" "" [])
2697− , ("latvian", \_ -> Lang "lv" "" "" [])
2698− , ("malayalam", \_ -> Lang "ml" "" "" [])
2699− , ("mongolian", \_ -> Lang "mn" "" "" [])
2700− , ("marathi", \_ -> Lang "mr" "" "" [])
2701− , ("dutch", \_ -> Lang "nl" "" "" [])
2702− , ("nynorsk", \_ -> Lang "nn" "" "" [])
2703− , ("norsk", \_ -> Lang "no" "" "" [])
2704− , ("nko", \_ -> Lang "nqo" "" "" [])
2705− , ("occitan", \_ -> Lang "oc" "" "" [])
2706− , ("panjabi", \_ -> Lang "pa" "" "" [])
2707− , ("polish", \_ -> Lang "pl" "" "" [])
2708− , ("piedmontese", \_ -> Lang "pms" "" "" [])
2709− , ("portuguese", \_ -> Lang "pt" "" "" [])
2710− , ("romansh", \_ -> Lang "rm" "" "" [])
2711− , ("romanian", \_ -> Lang "ro" "" "" [])
2712− , ("russian", \_ -> Lang "ru" "" "" [])
2713− , ("sanskrit", \_ -> Lang "sa" "" "" [])
2714− , ("samin", \_ -> Lang "se" "" "" [])
2715− , ("slovak", \_ -> Lang "sk" "" "" [])
2716− , ("albanian", \_ -> Lang "sq" "" "" [])
2717− , ("serbian", \_ -> Lang "sr" "" "" [])
2718− , ("swedish", \_ -> Lang "sv" "" "" [])
2719− , ("syriac", \_ -> Lang "syr" "" "" [])
2720− , ("tamil", \_ -> Lang "ta" "" "" [])
2721− , ("telugu", \_ -> Lang "te" "" "" [])
2722− , ("thai", \_ -> Lang "th" "" "" [])
2723− , ("turkmen", \_ -> Lang "tk" "" "" [])
2724− , ("turkish", \_ -> Lang "tr" "" "" [])
2725− , ("ukrainian", \_ -> Lang "uk" "" "" [])
2726− , ("urdu", \_ -> Lang "ur" "" "" [])
2727− , ("vietnamese", \_ -> Lang "vi" "" "" [])
2728− ]
2729−
2730−babelLangToBCP47 :: String -> Maybe Lang
2731−babelLangToBCP47 s =
2732− case s of
2733− "austrian" -> Just $ Lang "de" "" "AT" ["1901"]
2734− "naustrian" -> Just $ Lang "de" "" "AT" []
2735− "swissgerman" -> Just $ Lang "de" "" "CH" ["1901"]
2736− "nswissgerman" -> Just $ Lang "de" "" "CH" []
2737− "german" -> Just $ Lang "de" "" "DE" ["1901"]
2738− "ngerman" -> Just $ Lang "de" "" "DE" []
2739− "lowersorbian" -> Just $ Lang "dsb" "" "" []
2740− "uppersorbian" -> Just $ Lang "hsb" "" "" []
2741− "polutonikogreek" -> Just $ Lang "el" "" "" ["polyton"]
2742− "slovene" -> Just $ Lang "sl" "" "" []
2743− "australian" -> Just $ Lang "en" "" "AU" []
2744− "canadian" -> Just $ Lang "en" "" "CA" []
2745− "british" -> Just $ Lang "en" "" "GB" []
2746− "newzealand" -> Just $ Lang "en" "" "NZ" []
2747− "american" -> Just $ Lang "en" "" "US" []
2748− "classiclatin" -> Just $ Lang "la" "" "" ["x-classic"]
2749− _ -> fmap ($ "") $ M.lookup s polyglossiaLangToBCP47
src/Text/Pandoc/Readers/LaTeX/Lang.hsnew file+173
@@ -0,0 +1,173 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-
3+Copyright (C) 2018 John MacFarlane <jgm@berkeley.edu>
4+
5+This program is free software; you can redistribute it and/or modify
6+it under the terms of the GNU General Public License as published by
7+the Free Software Foundation; either version 2 of the License, or
8+(at your option) any later version.
9+
10+This program is distributed in the hope that it will be useful,
11+but WITHOUT ANY WARRANTY; without even the implied warranty of
12+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+GNU General Public License for more details.
14+
15+You should have received a copy of the GNU General Public License
16+along with this program; if not, write to the Free Software
17+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18+-}
19+
20+{- |
21+ Module : Text.Pandoc.Readers.LaTeX.Lang
22+ Copyright : Copyright (C) 2018 John MacFarlane
23+ License : GNU GPL, version 2 or above
24+
25+ Maintainer : John MacFarlane <jgm@berkeley.edu>
26+ Stability : alpha
27+ Portability : portable
28+
29+Functions for parsing polyglossia and babel language specifiers to
30+BCP47 'Lang'.
31+-}
32+module Text.Pandoc.Readers.LaTeX.Lang
33+ ( polyglossiaLangToBCP47
34+ , babelLangToBCP47
35+ )
36+where
37+import Prelude
38+import qualified Data.Map as M
39+import Text.Pandoc.BCP47 (Lang(..))
40+
41+polyglossiaLangToBCP47 :: M.Map String (String -> Lang)
42+polyglossiaLangToBCP47 = M.fromList
43+ [ ("arabic", \o -> case filter (/=' ') o of
44+ "locale=algeria" -> Lang "ar" "" "DZ" []
45+ "locale=mashriq" -> Lang "ar" "" "SY" []
46+ "locale=libya" -> Lang "ar" "" "LY" []
47+ "locale=morocco" -> Lang "ar" "" "MA" []
48+ "locale=mauritania" -> Lang "ar" "" "MR" []
49+ "locale=tunisia" -> Lang "ar" "" "TN" []
50+ _ -> Lang "ar" "" "" [])
51+ , ("german", \o -> case filter (/=' ') o of
52+ "spelling=old" -> Lang "de" "" "DE" ["1901"]
53+ "variant=austrian,spelling=old"
54+ -> Lang "de" "" "AT" ["1901"]
55+ "variant=austrian" -> Lang "de" "" "AT" []
56+ "variant=swiss,spelling=old"
57+ -> Lang "de" "" "CH" ["1901"]
58+ "variant=swiss" -> Lang "de" "" "CH" []
59+ _ -> Lang "de" "" "" [])
60+ , ("lsorbian", \_ -> Lang "dsb" "" "" [])
61+ , ("greek", \o -> case filter (/=' ') o of
62+ "variant=poly" -> Lang "el" "" "polyton" []
63+ "variant=ancient" -> Lang "grc" "" "" []
64+ _ -> Lang "el" "" "" [])
65+ , ("english", \o -> case filter (/=' ') o of
66+ "variant=australian" -> Lang "en" "" "AU" []
67+ "variant=canadian" -> Lang "en" "" "CA" []
68+ "variant=british" -> Lang "en" "" "GB" []
69+ "variant=newzealand" -> Lang "en" "" "NZ" []
70+ "variant=american" -> Lang "en" "" "US" []
71+ _ -> Lang "en" "" "" [])
72+ , ("usorbian", \_ -> Lang "hsb" "" "" [])
73+ , ("latin", \o -> case filter (/=' ') o of
74+ "variant=classic" -> Lang "la" "" "" ["x-classic"]
75+ _ -> Lang "la" "" "" [])
76+ , ("slovenian", \_ -> Lang "sl" "" "" [])
77+ , ("serbianc", \_ -> Lang "sr" "cyrl" "" [])
78+ , ("pinyin", \_ -> Lang "zh" "Latn" "" ["pinyin"])
79+ , ("afrikaans", \_ -> Lang "af" "" "" [])
80+ , ("amharic", \_ -> Lang "am" "" "" [])
81+ , ("assamese", \_ -> Lang "as" "" "" [])
82+ , ("asturian", \_ -> Lang "ast" "" "" [])
83+ , ("bulgarian", \_ -> Lang "bg" "" "" [])
84+ , ("bengali", \_ -> Lang "bn" "" "" [])
85+ , ("tibetan", \_ -> Lang "bo" "" "" [])
86+ , ("breton", \_ -> Lang "br" "" "" [])
87+ , ("catalan", \_ -> Lang "ca" "" "" [])
88+ , ("welsh", \_ -> Lang "cy" "" "" [])
89+ , ("czech", \_ -> Lang "cs" "" "" [])
90+ , ("coptic", \_ -> Lang "cop" "" "" [])
91+ , ("danish", \_ -> Lang "da" "" "" [])
92+ , ("divehi", \_ -> Lang "dv" "" "" [])
93+ , ("esperanto", \_ -> Lang "eo" "" "" [])
94+ , ("spanish", \_ -> Lang "es" "" "" [])
95+ , ("estonian", \_ -> Lang "et" "" "" [])
96+ , ("basque", \_ -> Lang "eu" "" "" [])
97+ , ("farsi", \_ -> Lang "fa" "" "" [])
98+ , ("finnish", \_ -> Lang "fi" "" "" [])
99+ , ("french", \_ -> Lang "fr" "" "" [])
100+ , ("friulan", \_ -> Lang "fur" "" "" [])
101+ , ("irish", \_ -> Lang "ga" "" "" [])
102+ , ("scottish", \_ -> Lang "gd" "" "" [])
103+ , ("ethiopic", \_ -> Lang "gez" "" "" [])
104+ , ("galician", \_ -> Lang "gl" "" "" [])
105+ , ("hebrew", \_ -> Lang "he" "" "" [])
106+ , ("hindi", \_ -> Lang "hi" "" "" [])
107+ , ("croatian", \_ -> Lang "hr" "" "" [])
108+ , ("magyar", \_ -> Lang "hu" "" "" [])
109+ , ("armenian", \_ -> Lang "hy" "" "" [])
110+ , ("interlingua", \_ -> Lang "ia" "" "" [])
111+ , ("indonesian", \_ -> Lang "id" "" "" [])
112+ , ("icelandic", \_ -> Lang "is" "" "" [])
113+ , ("italian", \_ -> Lang "it" "" "" [])
114+ , ("japanese", \_ -> Lang "jp" "" "" [])
115+ , ("khmer", \_ -> Lang "km" "" "" [])
116+ , ("kurmanji", \_ -> Lang "kmr" "" "" [])
117+ , ("kannada", \_ -> Lang "kn" "" "" [])
118+ , ("korean", \_ -> Lang "ko" "" "" [])
119+ , ("lao", \_ -> Lang "lo" "" "" [])
120+ , ("lithuanian", \_ -> Lang "lt" "" "" [])
121+ , ("latvian", \_ -> Lang "lv" "" "" [])
122+ , ("malayalam", \_ -> Lang "ml" "" "" [])
123+ , ("mongolian", \_ -> Lang "mn" "" "" [])
124+ , ("marathi", \_ -> Lang "mr" "" "" [])
125+ , ("dutch", \_ -> Lang "nl" "" "" [])
126+ , ("nynorsk", \_ -> Lang "nn" "" "" [])
127+ , ("norsk", \_ -> Lang "no" "" "" [])
128+ , ("nko", \_ -> Lang "nqo" "" "" [])
129+ , ("occitan", \_ -> Lang "oc" "" "" [])
130+ , ("panjabi", \_ -> Lang "pa" "" "" [])
131+ , ("polish", \_ -> Lang "pl" "" "" [])
132+ , ("piedmontese", \_ -> Lang "pms" "" "" [])
133+ , ("portuguese", \_ -> Lang "pt" "" "" [])
134+ , ("romansh", \_ -> Lang "rm" "" "" [])
135+ , ("romanian", \_ -> Lang "ro" "" "" [])
136+ , ("russian", \_ -> Lang "ru" "" "" [])
137+ , ("sanskrit", \_ -> Lang "sa" "" "" [])
138+ , ("samin", \_ -> Lang "se" "" "" [])
139+ , ("slovak", \_ -> Lang "sk" "" "" [])
140+ , ("albanian", \_ -> Lang "sq" "" "" [])
141+ , ("serbian", \_ -> Lang "sr" "" "" [])
142+ , ("swedish", \_ -> Lang "sv" "" "" [])
143+ , ("syriac", \_ -> Lang "syr" "" "" [])
144+ , ("tamil", \_ -> Lang "ta" "" "" [])
145+ , ("telugu", \_ -> Lang "te" "" "" [])
146+ , ("thai", \_ -> Lang "th" "" "" [])
147+ , ("turkmen", \_ -> Lang "tk" "" "" [])
148+ , ("turkish", \_ -> Lang "tr" "" "" [])
149+ , ("ukrainian", \_ -> Lang "uk" "" "" [])
150+ , ("urdu", \_ -> Lang "ur" "" "" [])
151+ , ("vietnamese", \_ -> Lang "vi" "" "" [])
152+ ]
153+
154+babelLangToBCP47 :: String -> Maybe Lang
155+babelLangToBCP47 s =
156+ case s of
157+ "austrian" -> Just $ Lang "de" "" "AT" ["1901"]
158+ "naustrian" -> Just $ Lang "de" "" "AT" []
159+ "swissgerman" -> Just $ Lang "de" "" "CH" ["1901"]
160+ "nswissgerman" -> Just $ Lang "de" "" "CH" []
161+ "german" -> Just $ Lang "de" "" "DE" ["1901"]
162+ "ngerman" -> Just $ Lang "de" "" "DE" []
163+ "lowersorbian" -> Just $ Lang "dsb" "" "" []
164+ "uppersorbian" -> Just $ Lang "hsb" "" "" []
165+ "polutonikogreek" -> Just $ Lang "el" "" "" ["polyton"]
166+ "slovene" -> Just $ Lang "sl" "" "" []
167+ "australian" -> Just $ Lang "en" "" "AU" []
168+ "canadian" -> Just $ Lang "en" "" "CA" []
169+ "british" -> Just $ Lang "en" "" "GB" []
170+ "newzealand" -> Just $ Lang "en" "" "NZ" []
171+ "american" -> Just $ Lang "en" "" "US" []
172+ "classiclatin" -> Just $ Lang "la" "" "" ["x-classic"]
173+ _ -> fmap ($ "") $ M.lookup s polyglossiaLangToBCP47
src/Text/Pandoc/Readers/LaTeX/Parsing.hsnew file+668
@@ -0,0 +1,668 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+{-# LANGUAGE OverloadedStrings #-}
5+{-# LANGUAGE ScopedTypeVariables #-}
6+{-
7+Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
8+
9+This program is free software; you can redistribute it and/or modify
10+it under the terms of the GNU General Public License as published by
11+the Free Software Foundation; either version 2 of the License, or
12+(at your option) any later version.
13+
14+This program is distributed in the hope that it will be useful,
15+but WITHOUT ANY WARRANTY; without even the implied warranty of
16+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+GNU General Public License for more details.
18+
19+You should have received a copy of the GNU General Public License
20+along with this program; if not, write to the Free Software
21+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22+-}
23+
24+{- |
25+ Module : Text.Pandoc.Readers.LaTeX.Parsing
26+ Copyright : Copyright (C) 2006-2018 John MacFarlane
27+ License : GNU GPL, version 2 or above
28+
29+ Maintainer : John MacFarlane <jgm@berkeley.edu>
30+ Stability : alpha
31+ Portability : portable
32+
33+General parsing types and functions for LaTeX.
34+-}
35+module Text.Pandoc.Readers.LaTeX.Parsing
36+ ( DottedNum(..)
37+ , renderDottedNum
38+ , incrementDottedNum
39+ , LaTeXState(..)
40+ , defaultLaTeXState
41+ , LP
42+ , withVerbatimMode
43+ , rawLaTeXParser
44+ , applyMacros
45+ , tokenize
46+ , untokenize
47+ , untoken
48+ , totoks
49+ , toksToString
50+ , satisfyTok
51+ , doMacros
52+ , setpos
53+ , anyControlSeq
54+ , anySymbol
55+ , isNewlineTok
56+ , isWordTok
57+ , isArgTok
58+ , spaces
59+ , spaces1
60+ , tokTypeIn
61+ , controlSeq
62+ , symbol
63+ , symbolIn
64+ , sp
65+ , whitespace
66+ , newlineTok
67+ , comment
68+ , anyTok
69+ , singleChar
70+ , specialChars
71+ , endline
72+ , blankline
73+ , primEscape
74+ , bgroup
75+ , egroup
76+ , grouped
77+ , braced
78+ , braced'
79+ , bracedUrl
80+ , bracedOrToken
81+ , bracketed
82+ , bracketedToks
83+ , parenWrapped
84+ , dimenarg
85+ , ignore
86+ , withRaw
87+ ) where
88+
89+import Prelude
90+import Control.Applicative (many, (<|>))
91+import Control.Monad
92+import Control.Monad.Except (throwError)
93+import Control.Monad.Trans (lift)
94+import Data.Char (chr, isAlphaNum, isDigit, isLetter, ord)
95+import Data.Default
96+import Data.List (intercalate)
97+import qualified Data.Map as M
98+import qualified Data.Set as Set
99+import Data.Text (Text)
100+import qualified Data.Text as T
101+import Text.Pandoc.Builder
102+import Text.Pandoc.Class (PandocMonad, report)
103+import Text.Pandoc.Error (PandocError (PandocMacroLoop))
104+import Text.Pandoc.Logging
105+import Text.Pandoc.Options
106+import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
107+ optional, space, spaces, withRaw, (<|>))
108+import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
109+ ArgSpec (..), Tok (..), TokType (..))
110+import Text.Pandoc.Shared
111+import Text.Parsec.Pos
112+
113+newtype DottedNum = DottedNum [Int]
114+ deriving (Show)
115+
116+renderDottedNum :: DottedNum -> String
117+renderDottedNum (DottedNum xs) =
118+ intercalate "." (map show xs)
119+
120+incrementDottedNum :: Int -> DottedNum -> DottedNum
121+incrementDottedNum level (DottedNum ns) = DottedNum $
122+ case reverse (take level (ns ++ repeat 0)) of
123+ (x:xs) -> reverse (x+1 : xs)
124+ [] -> [] -- shouldn't happen
125+
126+data LaTeXState = LaTeXState{ sOptions :: ReaderOptions
127+ , sMeta :: Meta
128+ , sQuoteContext :: QuoteContext
129+ , sMacros :: M.Map Text Macro
130+ , sContainers :: [String]
131+ , sHeaders :: M.Map Inlines String
132+ , sLogMessages :: [LogMessage]
133+ , sIdentifiers :: Set.Set String
134+ , sVerbatimMode :: Bool
135+ , sCaption :: (Maybe Inlines, Maybe String)
136+ , sInListItem :: Bool
137+ , sInTableCell :: Bool
138+ , sLastHeaderNum :: DottedNum
139+ , sLastFigureNum :: DottedNum
140+ , sLabels :: M.Map String [Inline]
141+ , sHasChapters :: Bool
142+ , sToggles :: M.Map String Bool
143+ }
144+ deriving Show
145+
146+defaultLaTeXState :: LaTeXState
147+defaultLaTeXState = LaTeXState{ sOptions = def
148+ , sMeta = nullMeta
149+ , sQuoteContext = NoQuote
150+ , sMacros = M.empty
151+ , sContainers = []
152+ , sHeaders = M.empty
153+ , sLogMessages = []
154+ , sIdentifiers = Set.empty
155+ , sVerbatimMode = False
156+ , sCaption = (Nothing, Nothing)
157+ , sInListItem = False
158+ , sInTableCell = False
159+ , sLastHeaderNum = DottedNum []
160+ , sLastFigureNum = DottedNum []
161+ , sLabels = M.empty
162+ , sHasChapters = False
163+ , sToggles = M.empty
164+ }
165+
166+instance PandocMonad m => HasQuoteContext LaTeXState m where
167+ getQuoteContext = sQuoteContext <$> getState
168+ withQuoteContext context parser = do
169+ oldState <- getState
170+ let oldQuoteContext = sQuoteContext oldState
171+ setState oldState { sQuoteContext = context }
172+ result <- parser
173+ newState <- getState
174+ setState newState { sQuoteContext = oldQuoteContext }
175+ return result
176+
177+instance HasLogMessages LaTeXState where
178+ addLogMessage msg st = st{ sLogMessages = msg : sLogMessages st }
179+ getLogMessages st = reverse $ sLogMessages st
180+
181+instance HasIdentifierList LaTeXState where
182+ extractIdentifierList = sIdentifiers
183+ updateIdentifierList f st = st{ sIdentifiers = f $ sIdentifiers st }
184+
185+instance HasIncludeFiles LaTeXState where
186+ getIncludeFiles = sContainers
187+ addIncludeFile f s = s{ sContainers = f : sContainers s }
188+ dropLatestIncludeFile s = s { sContainers = drop 1 $ sContainers s }
189+
190+instance HasHeaderMap LaTeXState where
191+ extractHeaderMap = sHeaders
192+ updateHeaderMap f st = st{ sHeaders = f $ sHeaders st }
193+
194+instance HasMacros LaTeXState where
195+ extractMacros st = sMacros st
196+ updateMacros f st = st{ sMacros = f (sMacros st) }
197+
198+instance HasReaderOptions LaTeXState where
199+ extractReaderOptions = sOptions
200+
201+instance HasMeta LaTeXState where
202+ setMeta field val st =
203+ st{ sMeta = setMeta field val $ sMeta st }
204+ deleteMeta field st =
205+ st{ sMeta = deleteMeta field $ sMeta st }
206+
207+instance Default LaTeXState where
208+ def = defaultLaTeXState
209+
210+type LP m = ParserT [Tok] LaTeXState m
211+
212+withVerbatimMode :: PandocMonad m => LP m a -> LP m a
213+withVerbatimMode parser = do
214+ updateState $ \st -> st{ sVerbatimMode = True }
215+ result <- parser
216+ updateState $ \st -> st{ sVerbatimMode = False }
217+ return result
218+
219+rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s)
220+ => Bool -> LP m a -> LP m a -> ParserT String s m (a, String)
221+rawLaTeXParser retokenize parser valParser = do
222+ inp <- getInput
223+ let toks = tokenize "source" $ T.pack inp
224+ pstate <- getState
225+ let lstate = def{ sOptions = extractReaderOptions pstate }
226+ let lstate' = lstate { sMacros = extractMacros pstate }
227+ let rawparser = (,) <$> withRaw valParser <*> getState
228+ res' <- lift $ runParserT (snd <$> withRaw parser) lstate "chunk" toks
229+ case res' of
230+ Left _ -> mzero
231+ Right toks' -> do
232+ res <- lift $ runParserT (do when retokenize $ do
233+ -- retokenize, applying macros
234+ doMacros 0
235+ ts <- many (satisfyTok (const True))
236+ setInput ts
237+ rawparser)
238+ lstate' "chunk" toks'
239+ case res of
240+ Left _ -> mzero
241+ Right ((val, raw), st) -> do
242+ updateState (updateMacros (sMacros st <>))
243+ _ <- takeP (T.length (untokenize toks'))
244+ return (val, T.unpack (untokenize raw))
245+
246+applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
247+ => String -> ParserT String s m String
248+applyMacros s = (guardDisabled Ext_latex_macros >> return s) <|>
249+ do let retokenize = doMacros 0 *>
250+ (toksToString <$> many (satisfyTok (const True)))
251+ pstate <- getState
252+ let lstate = def{ sOptions = extractReaderOptions pstate
253+ , sMacros = extractMacros pstate }
254+ res <- runParserT retokenize lstate "math" (tokenize "math" (T.pack s))
255+ case res of
256+ Left e -> fail (show e)
257+ Right s' -> return s'
258+tokenize :: SourceName -> Text -> [Tok]
259+tokenize sourcename = totoks (initialPos sourcename)
260+
261+totoks :: SourcePos -> Text -> [Tok]
262+totoks pos t =
263+ case T.uncons t of
264+ Nothing -> []
265+ Just (c, rest)
266+ | c == '\n' ->
267+ Tok pos Newline "\n"
268+ : totoks (setSourceColumn (incSourceLine pos 1) 1) rest
269+ | isSpaceOrTab c ->
270+ let (sps, rest') = T.span isSpaceOrTab t
271+ in Tok pos Spaces sps
272+ : totoks (incSourceColumn pos (T.length sps))
273+ rest'
274+ | isAlphaNum c ->
275+ let (ws, rest') = T.span isAlphaNum t
276+ in Tok pos Word ws
277+ : totoks (incSourceColumn pos (T.length ws)) rest'
278+ | c == '%' ->
279+ let (cs, rest') = T.break (== '\n') rest
280+ in Tok pos Comment ("%" <> cs)
281+ : totoks (incSourceColumn pos (1 + T.length cs)) rest'
282+ | c == '\\' ->
283+ case T.uncons rest of
284+ Nothing -> [Tok pos (CtrlSeq " ") "\\"]
285+ Just (d, rest')
286+ | isLetterOrAt d ->
287+ -- \makeatletter is common in macro defs;
288+ -- ideally we should make tokenization sensitive
289+ -- to \makeatletter and \makeatother, but this is
290+ -- probably best for now
291+ let (ws, rest'') = T.span isLetterOrAt rest
292+ (ss, rest''') = T.span isSpaceOrTab rest''
293+ in Tok pos (CtrlSeq ws) ("\\" <> ws <> ss)
294+ : totoks (incSourceColumn pos
295+ (1 + T.length ws + T.length ss)) rest'''
296+ | isSpaceOrTab d || d == '\n' ->
297+ let (w1, r1) = T.span isSpaceOrTab rest
298+ (w2, (w3, r3)) = case T.uncons r1 of
299+ Just ('\n', r2)
300+ -> (T.pack "\n",
301+ T.span isSpaceOrTab r2)
302+ _ -> (mempty, (mempty, r1))
303+ ws = "\\" <> w1 <> w2 <> w3
304+ in case T.uncons r3 of
305+ Just ('\n', _) ->
306+ Tok pos (CtrlSeq " ") ("\\" <> w1)
307+ : totoks (incSourceColumn pos (T.length ws))
308+ r1
309+ _ ->
310+ Tok pos (CtrlSeq " ") ws
311+ : totoks (incSourceColumn pos (T.length ws))
312+ r3
313+ | otherwise ->
314+ Tok pos (CtrlSeq (T.singleton d)) (T.pack [c,d])
315+ : totoks (incSourceColumn pos 2) rest'
316+ | c == '#' ->
317+ let (t1, t2) = T.span (\d -> d >= '0' && d <= '9') rest
318+ in case safeRead (T.unpack t1) of
319+ Just i ->
320+ Tok pos (Arg i) ("#" <> t1)
321+ : totoks (incSourceColumn pos (1 + T.length t1)) t2
322+ Nothing ->
323+ Tok pos Symbol "#"
324+ : totoks (incSourceColumn pos 1) t2
325+ | c == '^' ->
326+ case T.uncons rest of
327+ Just ('^', rest') ->
328+ case T.uncons rest' of
329+ Just (d, rest'')
330+ | isLowerHex d ->
331+ case T.uncons rest'' of
332+ Just (e, rest''') | isLowerHex e ->
333+ Tok pos Esc2 (T.pack ['^','^',d,e])
334+ : totoks (incSourceColumn pos 4) rest'''
335+ _ ->
336+ Tok pos Esc1 (T.pack ['^','^',d])
337+ : totoks (incSourceColumn pos 3) rest''
338+ | d < '\128' ->
339+ Tok pos Esc1 (T.pack ['^','^',d])
340+ : totoks (incSourceColumn pos 3) rest''
341+ _ -> Tok pos Symbol "^" :
342+ Tok (incSourceColumn pos 1) Symbol "^" :
343+ totoks (incSourceColumn pos 2) rest'
344+ _ -> Tok pos Symbol "^"
345+ : totoks (incSourceColumn pos 1) rest
346+ | otherwise ->
347+ Tok pos Symbol (T.singleton c) : totoks (incSourceColumn pos 1) rest
348+
349+isSpaceOrTab :: Char -> Bool
350+isSpaceOrTab ' ' = True
351+isSpaceOrTab '\t' = True
352+isSpaceOrTab _ = False
353+
354+isLetterOrAt :: Char -> Bool
355+isLetterOrAt '@' = True
356+isLetterOrAt c = isLetter c
357+
358+isLowerHex :: Char -> Bool
359+isLowerHex x = x >= '0' && x <= '9' || x >= 'a' && x <= 'f'
360+
361+untokenize :: [Tok] -> Text
362+untokenize = mconcat . map untoken
363+
364+untoken :: Tok -> Text
365+untoken (Tok _ _ t) = t
366+
367+toksToString :: [Tok] -> String
368+toksToString = T.unpack . untokenize
369+
370+satisfyTok :: PandocMonad m => (Tok -> Bool) -> LP m Tok
371+satisfyTok f =
372+ try $ do
373+ res <- tokenPrim (T.unpack . untoken) updatePos matcher
374+ doMacros 0 -- apply macros on remaining input stream
375+ return res
376+ where matcher t | f t = Just t
377+ | otherwise = Nothing
378+ updatePos :: SourcePos -> Tok -> [Tok] -> SourcePos
379+ updatePos _spos _ (Tok pos _ _ : _) = pos
380+ updatePos spos _ [] = incSourceColumn spos 1
381+
382+doMacros :: PandocMonad m => Int -> LP m ()
383+doMacros n = do
384+ verbatimMode <- sVerbatimMode <$> getState
385+ unless verbatimMode $ do
386+ inp <- getInput
387+ case inp of
388+ Tok spos (CtrlSeq "begin") _ : Tok _ Symbol "{" :
389+ Tok _ Word name : Tok _ Symbol "}" : ts
390+ -> handleMacros spos name ts
391+ Tok spos (CtrlSeq "end") _ : Tok _ Symbol "{" :
392+ Tok _ Word name : Tok _ Symbol "}" : ts
393+ -> handleMacros spos ("end" <> name) ts
394+ Tok _ (CtrlSeq "expandafter") _ : t : ts
395+ -> do setInput ts
396+ doMacros n
397+ getInput >>= setInput . combineTok t
398+ Tok spos (CtrlSeq name) _ : ts
399+ -> handleMacros spos name ts
400+ _ -> return ()
401+ where combineTok (Tok spos (CtrlSeq name) x) (Tok _ Word w : ts)
402+ | T.all isLetterOrAt w =
403+ Tok spos (CtrlSeq (name <> w)) (x1 <> w <> x2) : ts
404+ where (x1, x2) = T.break isSpaceOrTab x
405+ combineTok t ts = t:ts
406+ handleMacros spos name ts = do
407+ macros <- sMacros <$> getState
408+ case M.lookup name macros of
409+ Nothing -> return ()
410+ Just (Macro expansionPoint argspecs optarg newtoks) -> do
411+ setInput ts
412+ let matchTok (Tok _ toktype txt) =
413+ satisfyTok (\(Tok _ toktype' txt') ->
414+ toktype == toktype' &&
415+ txt == txt')
416+ let matchPattern toks = try $ mapM_ matchTok toks
417+ let getargs argmap [] = return argmap
418+ getargs argmap (Pattern toks : rest) = try $ do
419+ matchPattern toks
420+ getargs argmap rest
421+ getargs argmap (ArgNum i : Pattern toks : rest) =
422+ try $ do
423+ x <- mconcat <$> manyTill
424+ (braced <|> ((:[]) <$> anyTok))
425+ (matchPattern toks)
426+ getargs (M.insert i x argmap) rest
427+ getargs argmap (ArgNum i : rest) = do
428+ x <- try $ spaces >> bracedOrToken
429+ getargs (M.insert i x argmap) rest
430+ args <- case optarg of
431+ Nothing -> getargs M.empty argspecs
432+ Just o -> do
433+ x <- option o bracketedToks
434+ getargs (M.singleton 1 x) argspecs
435+ -- first boolean param is true if we're tokenizing
436+ -- an argument (in which case we don't want to
437+ -- expand #1 etc.)
438+ let addTok False (Tok _ (Arg i) _) acc =
439+ case M.lookup i args of
440+ Nothing -> mzero
441+ Just xs -> foldr (addTok True) acc xs
442+ -- see #4007
443+ addTok _ (Tok _ (CtrlSeq x) txt)
444+ acc@(Tok _ Word _ : _)
445+ | not (T.null txt) &&
446+ isLetter (T.last txt) =
447+ Tok spos (CtrlSeq x) (txt <> " ") : acc
448+ addTok _ t acc = setpos spos t : acc
449+ ts' <- getInput
450+ setInput $ foldr (addTok False) ts' newtoks
451+ case expansionPoint of
452+ ExpandWhenUsed ->
453+ if n > 20 -- detect macro expansion loops
454+ then throwError $ PandocMacroLoop (T.unpack name)
455+ else doMacros (n + 1)
456+ ExpandWhenDefined -> return ()
457+
458+
459+setpos :: SourcePos -> Tok -> Tok
460+setpos spos (Tok _ tt txt) = Tok spos tt txt
461+
462+anyControlSeq :: PandocMonad m => LP m Tok
463+anyControlSeq = satisfyTok isCtrlSeq
464+
465+isCtrlSeq :: Tok -> Bool
466+isCtrlSeq (Tok _ (CtrlSeq _) _) = True
467+isCtrlSeq _ = False
468+
469+anySymbol :: PandocMonad m => LP m Tok
470+anySymbol = satisfyTok isSymbolTok
471+
472+isSymbolTok :: Tok -> Bool
473+isSymbolTok (Tok _ Symbol _) = True
474+isSymbolTok _ = False
475+
476+isWordTok :: Tok -> Bool
477+isWordTok (Tok _ Word _) = True
478+isWordTok _ = False
479+
480+isArgTok :: Tok -> Bool
481+isArgTok (Tok _ (Arg _) _) = True
482+isArgTok _ = False
483+
484+spaces :: PandocMonad m => LP m ()
485+spaces = skipMany (satisfyTok (tokTypeIn [Comment, Spaces, Newline]))
486+
487+spaces1 :: PandocMonad m => LP m ()
488+spaces1 = skipMany1 (satisfyTok (tokTypeIn [Comment, Spaces, Newline]))
489+
490+tokTypeIn :: [TokType] -> Tok -> Bool
491+tokTypeIn toktypes (Tok _ tt _) = tt `elem` toktypes
492+
493+controlSeq :: PandocMonad m => Text -> LP m Tok
494+controlSeq name = satisfyTok isNamed
495+ where isNamed (Tok _ (CtrlSeq n) _) = n == name
496+ isNamed _ = False
497+
498+symbol :: PandocMonad m => Char -> LP m Tok
499+symbol c = satisfyTok isc
500+ where isc (Tok _ Symbol d) = case T.uncons d of
501+ Just (c',_) -> c == c'
502+ _ -> False
503+ isc _ = False
504+
505+symbolIn :: PandocMonad m => [Char] -> LP m Tok
506+symbolIn cs = satisfyTok isInCs
507+ where isInCs (Tok _ Symbol d) = case T.uncons d of
508+ Just (c,_) -> c `elem` cs
509+ _ -> False
510+ isInCs _ = False
511+
512+sp :: PandocMonad m => LP m ()
513+sp = whitespace <|> endline
514+
515+whitespace :: PandocMonad m => LP m ()
516+whitespace = () <$ satisfyTok isSpaceTok
517+
518+isSpaceTok :: Tok -> Bool
519+isSpaceTok (Tok _ Spaces _) = True
520+isSpaceTok _ = False
521+
522+newlineTok :: PandocMonad m => LP m ()
523+newlineTok = () <$ satisfyTok isNewlineTok
524+
525+isNewlineTok :: Tok -> Bool
526+isNewlineTok (Tok _ Newline _) = True
527+isNewlineTok _ = False
528+
529+comment :: PandocMonad m => LP m ()
530+comment = () <$ satisfyTok isCommentTok
531+
532+isCommentTok :: Tok -> Bool
533+isCommentTok (Tok _ Comment _) = True
534+isCommentTok _ = False
535+
536+anyTok :: PandocMonad m => LP m Tok
537+anyTok = satisfyTok (const True)
538+
539+singleChar :: PandocMonad m => LP m Tok
540+singleChar = try $ do
541+ Tok pos toktype t <- satisfyTok (tokTypeIn [Word, Symbol])
542+ guard $ not $ toktype == Symbol &&
543+ T.any (`Set.member` specialChars) t
544+ if T.length t > 1
545+ then do
546+ let (t1, t2) = (T.take 1 t, T.drop 1 t)
547+ inp <- getInput
548+ setInput $ Tok (incSourceColumn pos 1) toktype t2 : inp
549+ return $ Tok pos toktype t1
550+ else return $ Tok pos toktype t
551+
552+specialChars :: Set.Set Char
553+specialChars = Set.fromList "#$%&~_^\\{}"
554+
555+endline :: PandocMonad m => LP m ()
556+endline = try $ do
557+ newlineTok
558+ lookAhead anyTok
559+ notFollowedBy blankline
560+
561+blankline :: PandocMonad m => LP m ()
562+blankline = try $ skipMany whitespace *> newlineTok
563+
564+primEscape :: PandocMonad m => LP m Char
565+primEscape = do
566+ Tok _ toktype t <- satisfyTok (tokTypeIn [Esc1, Esc2])
567+ case toktype of
568+ Esc1 -> case T.uncons (T.drop 2 t) of
569+ Just (c, _)
570+ | c >= '\64' && c <= '\127' -> return (chr (ord c - 64))
571+ | otherwise -> return (chr (ord c + 64))
572+ Nothing -> fail "Empty content of Esc1"
573+ Esc2 -> case safeRead ('0':'x':T.unpack (T.drop 2 t)) of
574+ Just x -> return (chr x)
575+ Nothing -> fail $ "Could not read: " ++ T.unpack t
576+ _ -> fail "Expected an Esc1 or Esc2 token" -- should not happen
577+
578+bgroup :: PandocMonad m => LP m Tok
579+bgroup = try $ do
580+ skipMany sp
581+ symbol '{' <|> controlSeq "bgroup" <|> controlSeq "begingroup"
582+
583+egroup :: PandocMonad m => LP m Tok
584+egroup = symbol '}' <|> controlSeq "egroup" <|> controlSeq "endgroup"
585+
586+grouped :: (PandocMonad m, Monoid a) => LP m a -> LP m a
587+grouped parser = try $ do
588+ bgroup
589+ -- first we check for an inner 'grouped', because
590+ -- {{a,b}} should be parsed the same as {a,b}
591+ try (grouped parser <* egroup) <|> (mconcat <$> manyTill parser egroup)
592+
593+braced' :: PandocMonad m => LP m Tok -> Int -> LP m [Tok]
594+braced' getTok n =
595+ handleEgroup <|> handleBgroup <|> handleOther
596+ where handleEgroup = do
597+ t <- egroup
598+ if n == 1
599+ then return []
600+ else (t:) <$> braced' getTok (n - 1)
601+ handleBgroup = do
602+ t <- bgroup
603+ (t:) <$> braced' getTok (n + 1)
604+ handleOther = do
605+ t <- getTok
606+ (t:) <$> braced' getTok n
607+
608+braced :: PandocMonad m => LP m [Tok]
609+braced = bgroup *> braced' anyTok 1
610+
611+-- URLs require special handling, because they can contain %
612+-- characters. So we retonenize comments as we go...
613+bracedUrl :: PandocMonad m => LP m [Tok]
614+bracedUrl = bgroup *> braced' (retokenizeComment >> anyTok) 1
615+
616+-- For handling URLs, which allow literal % characters...
617+retokenizeComment :: PandocMonad m => LP m ()
618+retokenizeComment = (do
619+ Tok pos Comment txt <- satisfyTok isCommentTok
620+ let updPos (Tok pos' toktype' txt') =
621+ Tok (incSourceColumn (incSourceLine pos' (sourceLine pos - 1))
622+ (sourceColumn pos)) toktype' txt'
623+ let newtoks = map updPos $ tokenize (sourceName pos) $ T.tail txt
624+ getInput >>= setInput . ((Tok pos Symbol "%" : newtoks) ++))
625+ <|> return ()
626+
627+bracedOrToken :: PandocMonad m => LP m [Tok]
628+bracedOrToken = braced <|> ((:[]) <$> (anyControlSeq <|> singleChar))
629+
630+bracketed :: PandocMonad m => Monoid a => LP m a -> LP m a
631+bracketed parser = try $ do
632+ symbol '['
633+ mconcat <$> manyTill parser (symbol ']')
634+
635+bracketedToks :: PandocMonad m => LP m [Tok]
636+bracketedToks = do
637+ symbol '['
638+ mconcat <$> manyTill (braced <|> (:[]) <$> anyTok) (symbol ']')
639+
640+parenWrapped :: PandocMonad m => Monoid a => LP m a -> LP m a
641+parenWrapped parser = try $ do
642+ symbol '('
643+ mconcat <$> manyTill parser (symbol ')')
644+
645+dimenarg :: PandocMonad m => LP m Text
646+dimenarg = try $ do
647+ ch <- option False $ True <$ symbol '='
648+ Tok _ _ s <- satisfyTok isWordTok
649+ guard $ T.take 2 (T.reverse s) `elem`
650+ ["pt","pc","in","bp","cm","mm","dd","cc","sp"]
651+ let num = T.take (T.length s - 2) s
652+ guard $ T.length num > 0
653+ guard $ T.all isDigit num
654+ return $ T.pack ['=' | ch] <> s
655+
656+ignore :: (Monoid a, PandocMonad m) => String -> ParserT s u m a
657+ignore raw = do
658+ pos <- getPosition
659+ report $ SkippedContent raw pos
660+ return mempty
661+
662+withRaw :: PandocMonad m => LP m a -> LP m (a, [Tok])
663+withRaw parser = do
664+ inp <- getInput
665+ result <- parser
666+ nxt <- option (Tok (initialPos "source") Word "") (lookAhead anyTok)
667+ let raw = takeWhile (/= nxt) inp
668+ return (result, raw)
src/Text/Pandoc/Readers/LaTeX/Types.hs+5−1
@@ -31,6 +31,7 @@ Types for LaTeX tokens and macros.
3131module Text.Pandoc.Readers.LaTeX.Types ( Tok(..)
3232 , TokType(..)
3333 , Macro(..)
34+ , ArgSpec(..)
3435 , ExpansionPoint(..)
3536 , SourcePos
3637 )
@@ -49,5 +50,8 @@ data Tok = Tok SourcePos TokType Text
4950data ExpansionPoint = ExpandWhenDefined | ExpandWhenUsed
5051 deriving (Eq, Ord, Show)
5152
52−data Macro = Macro ExpansionPoint Int (Maybe [Tok]) [Tok]
53+data Macro = Macro ExpansionPoint [ArgSpec] (Maybe [Tok]) [Tok]
54+ deriving Show
55+
56+data ArgSpec = ArgNum Int | Pattern [Tok]
5357 deriving Show
src/Text/Pandoc/Readers/Markdown.hs+98−94
@@ -1,6 +1,7 @@
11{-# LANGUAGE NoImplicitPrelude #-}
22{-# LANGUAGE RelaxedPolyRec #-}
33{-# LANGUAGE ScopedTypeVariables #-}
4+{-# LANGUAGE TupleSections #-}
45
56{-
67Copyright (C) 2006-2018 John MacFarlane <jgm@berkeley.edu>
@@ -31,31 +32,28 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3132
3233Conversion of markdown-formatted plain text to 'Pandoc' document.
3334-}
34−module Text.Pandoc.Readers.Markdown ( readMarkdown ) where
35+module Text.Pandoc.Readers.Markdown ( readMarkdown, yamlToMeta ) where
3536
3637import Prelude
3738import Control.Monad
3839import Control.Monad.Except (throwError)
40+import qualified Data.ByteString.Lazy as BS
3941import Data.Char (isAlphaNum, isPunctuation, isSpace, toLower)
40−import qualified Data.HashMap.Strict as H
4142import Data.List (intercalate, sortBy, transpose, elemIndex)
4243import qualified Data.Map as M
4344import Data.Maybe
4445import Data.Ord (comparing)
45−import Data.Scientific (base10Exponent, coefficient)
4646import qualified Data.Set as Set
4747import Data.Text (Text)
4848import qualified Data.Text as T
49−import qualified Data.Vector as V
50−import Data.Yaml (ParseException (..), YamlException (..), YamlMark (..))
51−import qualified Data.Yaml as Yaml
49+import qualified Data.YAML as YAML
5250import System.FilePath (addExtension, takeExtension)
5351import Text.HTML.TagSoup
5452import Text.Pandoc.Builder (Blocks, Inlines)
5553import qualified Text.Pandoc.Builder as B
5654import Text.Pandoc.Class (PandocMonad (..), report)
5755import Text.Pandoc.Definition
58−import Text.Pandoc.Emoji (emojis)
56+import Text.Pandoc.Emoji (emojiToInline)
5957import Text.Pandoc.Error
6058import Text.Pandoc.Logging
6159import Text.Pandoc.Options
@@ -234,11 +232,9 @@ pandocTitleBlock = try $ do
234232 $ nullMeta
235233 updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }
236234
237−
238235yamlMetaBlock :: PandocMonad m => MarkdownParser m (F Blocks)
239236yamlMetaBlock = try $ do
240237 guardEnabled Ext_yaml_metadata_block
241− pos <- getPosition
242238 string "---"
243239 blankline
244240 notFollowedBy blankline -- if --- is followed by a blank it's an HRULE
@@ -246,52 +242,44 @@ yamlMetaBlock = try $ do
246242 -- by including --- and ..., we allow yaml blocks with just comments:
247243 let rawYaml = unlines ("---" : (rawYamlLines ++ ["..."]))
248244 optional blanklines
249− case Yaml.decodeEither' $ UTF8.fromString rawYaml of
250− Right (Yaml.Object hashmap) -> do
251− let alist = H.toList hashmap
252− mapM_ (\(k, v) ->
253− if ignorable k
254− then return ()
255− else do
256− v' <- yamlToMeta v
257− let k' = T.unpack k
258− updateState $ \st -> st{ stateMeta' =
259− do m <- stateMeta' st
260− -- if there's already a value, leave it unchanged
261− case lookupMeta k' m of
262− Just _ -> return m
263− Nothing -> do
264− v'' <- v'
265− return $ B.setMeta (T.unpack k) v'' m}
266− ) alist
267− Right Yaml.Null -> return ()
245+ newMetaF <- yamlBsToMeta $ UTF8.fromStringLazy rawYaml
246+ -- Since `<>` is left-biased, existing values are not touched:
247+ updateState $ \st -> st{ stateMeta' = (stateMeta' st) <> newMetaF }
248+ return mempty
249+
250+-- | Read a YAML string and convert it to pandoc metadata.
251+-- String scalars in the YAML are parsed as Markdown.
252+yamlToMeta :: PandocMonad m => BS.ByteString -> m Meta
253+yamlToMeta bstr = do
254+ let parser = do
255+ meta <- yamlBsToMeta bstr
256+ return $ runF meta defaultParserState
257+ parsed <- readWithM parser def ""
258+ case parsed of
259+ Right result -> return result
260+ Left e -> throwError e
261+
262+yamlBsToMeta :: PandocMonad m => BS.ByteString -> MarkdownParser m (F Meta)
263+yamlBsToMeta bstr = do
264+ pos <- getPosition
265+ case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
266+ Right ((YAML.Doc (YAML.Mapping _ o)):_) -> (fmap Meta) <$> yamlMap o
267+ Right [] -> return . return $ mempty
268+ Right [YAML.Doc (YAML.Scalar YAML.SNull)] -> return . return $ mempty
268269 Right _ -> do
269− logMessage $
270− CouldNotParseYamlMetadata "not an object"
271− pos
272− return ()
270+ logMessage $
271+ CouldNotParseYamlMetadata "not an object"
272+ pos
273+ return . return $ mempty
273274 Left err' -> do
274− case err' of
275− InvalidYaml (Just YamlParseException{
276− yamlProblem = problem
277− , yamlContext = _ctxt
278− , yamlProblemMark = Yaml.YamlMark {
279− yamlLine = yline
280− , yamlColumn = ycol
281− }}) ->
282− logMessage $ CouldNotParseYamlMetadata
283− problem (setSourceLine
284− (setSourceColumn pos
285− (sourceColumn pos + ycol))
286− (sourceLine pos + 1 + yline))
287− _ -> logMessage $ CouldNotParseYamlMetadata
288− (show err') pos
289− return ()
290− return mempty
275+ logMessage $ CouldNotParseYamlMetadata
276+ err' pos
277+ return . return $ mempty
291278
292−-- ignore fields ending with _
293−ignorable :: Text -> Bool
294−ignorable t = (T.pack "_") `T.isSuffixOf` t
279+nodeToKey :: Monad m => YAML.Node -> m Text
280+nodeToKey (YAML.Scalar (YAML.SStr t)) = return t
281+nodeToKey (YAML.Scalar (YAML.SUnknown _ t)) = return t
282+nodeToKey _ = fail "Non-string key in YAML mapping"
295283
296284toMetaValue :: PandocMonad m
297285 => Text -> MarkdownParser m (F MetaValue)
@@ -312,34 +300,51 @@ toMetaValue x =
312300 -- not end in a newline, but a "block" set off with
313301 -- `|` or `>` will.
314302
315−yamlToMeta :: PandocMonad m
316− => Yaml.Value -> MarkdownParser m (F MetaValue)
317−yamlToMeta (Yaml.String t) = toMetaValue t
318−yamlToMeta (Yaml.Number n)
319− -- avoid decimal points for numbers that don't need them:
320− | base10Exponent n >= 0 = return $ return $ MetaString $ show
321− $ coefficient n * (10 ^ base10Exponent n)
322− | otherwise = return $ return $ MetaString $ show n
323−yamlToMeta (Yaml.Bool b) = return $ return $ MetaBool b
324−yamlToMeta (Yaml.Array xs) = do
325− xs' <- mapM yamlToMeta (V.toList xs)
303+checkBoolean :: Text -> Maybe Bool
304+checkBoolean t =
305+ if t == T.pack "true" || t == T.pack "True" || t == T.pack "TRUE"
306+ then Just True
307+ else if t == T.pack "false" || t == T.pack "False" || t == T.pack "FALSE"
308+ then Just False
309+ else Nothing
310+
311+yamlToMetaValue :: PandocMonad m
312+ => YAML.Node -> MarkdownParser m (F MetaValue)
313+yamlToMetaValue (YAML.Scalar x) =
314+ case x of
315+ YAML.SStr t -> toMetaValue t
316+ YAML.SBool b -> return $ return $ MetaBool b
317+ YAML.SFloat d -> return $ return $ MetaString (show d)
318+ YAML.SInt i -> return $ return $ MetaString (show i)
319+ YAML.SUnknown _ t ->
320+ case checkBoolean t of
321+ Just b -> return $ return $ MetaBool b
322+ Nothing -> toMetaValue t
323+ YAML.SNull -> return $ return $ MetaString ""
324+yamlToMetaValue (YAML.Sequence _ xs) = do
325+ xs' <- mapM yamlToMetaValue xs
326326 return $ do
327327 xs'' <- sequence xs'
328328 return $ B.toMetaValue xs''
329−yamlToMeta (Yaml.Object o) = do
330− let alist = H.toList o
331− foldM (\m (k,v) ->
332− if ignorable k
333− then return m
334− else do
335− v' <- yamlToMeta v
336− return $ do
337− MetaMap m' <- m
338− v'' <- v'
339− return (MetaMap $ M.insert (T.unpack k) v'' m'))
340− (return $ MetaMap M.empty)
341− alist
342−yamlToMeta _ = return $ return $ MetaString ""
329+yamlToMetaValue (YAML.Mapping _ o) = fmap B.toMetaValue <$> yamlMap o
330+yamlToMetaValue _ = return $ return $ MetaString ""
331+
332+yamlMap :: PandocMonad m
333+ => M.Map YAML.Node YAML.Node
334+ -> MarkdownParser m (F (M.Map String MetaValue))
335+yamlMap o = do
336+ kvs <- forM (M.toList o) $ \(key, v) -> do
337+ k <- nodeToKey key
338+ return (k, v)
339+ let kvs' = filter (not . ignorable . fst) kvs
340+ (fmap M.fromList . sequence) <$> mapM toMeta kvs'
341+ where
342+ ignorable t = (T.pack "_") `T.isSuffixOf` t
343+ toMeta (k, v) = do
344+ fv <- yamlToMetaValue v
345+ return $ do
346+ v' <- fv
347+ return (T.unpack k, v')
343348
344349stopLine :: PandocMonad m => MarkdownParser m ()
345350stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
@@ -966,7 +971,9 @@ orderedList = try $ do
966971 <|> return (style == Example)
967972 items <- fmap sequence $ many1 $ listItem fourSpaceRule
968973 (orderedListStart (Just (style, delim)))
969− start' <- (start <$ guardEnabled Ext_startnum) <|> return 1
974+ start' <- if style == Example
975+ then return start
976+ else (start <$ guardEnabled Ext_startnum) <|> return 1
970977 return $ B.orderedListWith (start', style, delim) <$> fmap compactify items
971978
972979bulletList :: PandocMonad m => MarkdownParser m (F Blocks)
@@ -1142,10 +1149,9 @@ rawTeXBlock :: PandocMonad m => MarkdownParser m (F Blocks)
11421149rawTeXBlock = do
11431150 guardEnabled Ext_raw_tex
11441151 lookAhead $ try $ char '\\' >> letter
1145− result <- (B.rawBlock "context" . trim . concat <$>
1146− many1 ((++) <$> (rawConTeXtEnvironment <|> conTeXtCommand)
1147− <*> spnl'))
1148− <|> (B.rawBlock "latex" . trim . concat <$>
1152+ result <- (B.rawBlock "tex" . trim . concat <$>
1153+ many1 ((++) <$> rawConTeXtEnvironment <*> spnl'))
1154+ <|> (B.rawBlock "tex" . trim . concat <$>
11491155 many1 ((++) <$> rawLaTeXBlock <*> spnl'))
11501156 return $ case B.toList result of
11511157 [RawBlock _ cs]
@@ -1153,9 +1159,6 @@ rawTeXBlock = do
11531159 -- don't create a raw block for suppressed macro defs
11541160 _ -> return result
11551161
1156−conTeXtCommand :: PandocMonad m => MarkdownParser m String
1157−conTeXtCommand = oneOfStrings ["\\placeformula"]
1158−
11591162rawHtmlBlocks :: PandocMonad m => MarkdownParser m (F Blocks)
11601163rawHtmlBlocks = do
11611164 (TagOpen tagtype _, raw) <- htmlTag isBlockTag
@@ -1591,7 +1594,7 @@ code = try $ do
15911594 starts <- many1 (char '`')
15921595 skipSpaces
15931596 result <- (trim . concat) <$>
1594− many1Till (many1 (noneOf "`\n") <|> many1 (char '`') <|>
1597+ manyTill (many1 (noneOf "`\n") <|> many1 (char '`') <|>
15951598 (char '\n' >> notFollowedBy' blankline >> return " "))
15961599 (try (skipSpaces >> count (length starts) (char '`') >>
15971600 notFollowedBy (char '`')))
@@ -1877,23 +1880,24 @@ bareURL :: PandocMonad m => MarkdownParser m (F Inlines)
18771880bareURL = try $ do
18781881 guardEnabled Ext_autolink_bare_uris
18791882 getState >>= guard . stateAllowLinks
1880− (orig, src) <- uri <|> emailAddress
1883+ (cls, (orig, src)) <- (("uri",) <$> uri) <|> (("email",) <$> emailAddress)
18811884 notFollowedBy $ try $ spaces >> htmlTag (~== TagClose "a")
1882− return $ return $ B.link src "" (B.str orig)
1885+ return $ return $ B.linkWith ("",[cls],[]) src "" (B.str orig)
18831886
18841887autoLink :: PandocMonad m => MarkdownParser m (F Inlines)
18851888autoLink = try $ do
18861889 getState >>= guard . stateAllowLinks
18871890 char '<'
1888− (orig, src) <- uri <|> emailAddress
1891+ (cls, (orig, src)) <- (("uri",) <$> uri) <|> (("email",) <$> emailAddress)
18891892 -- in rare cases, something may remain after the uri parser
18901893 -- is finished, because the uri parser tries to avoid parsing
18911894 -- final punctuation. for example: in `<http://hi---there>`,
18921895 -- the URI parser will stop before the dashes.
18931896 extra <- fromEntities <$> manyTill nonspaceChar (char '>')
1894− attr <- option nullAttr $ try $
1897+ attr <- option ("", [cls], []) $ try $
18951898 guardEnabled Ext_link_attributes >> attributes
1896− return $ return $ B.linkWith attr (src ++ escapeURI extra) "" (B.str $ orig ++ extra)
1899+ return $ return $ B.linkWith attr (src ++ escapeURI extra) ""
1900+ (B.str $ orig ++ extra)
18971901
18981902image :: PandocMonad m => MarkdownParser m (F Inlines)
18991903image = try $ do
@@ -2037,9 +2041,9 @@ emoji = try $ do
20372041 char ':'
20382042 emojikey <- many1 (oneOf emojiChars)
20392043 char ':'
2040− case M.lookup emojikey emojis of
2041− Just s -> return (return (B.str s))
2042− Nothing -> mzero
2044+ case emojiToInline emojikey of
2045+ Just i -> return (return $ B.singleton i)
2046+ Nothing -> mzero
20432047
20442048-- Citations
20452049
src/Text/Pandoc/Readers/Muse.hs+260−254
@@ -35,34 +35,32 @@ TODO:
3535- Page breaks (five "*")
3636- Org tables
3737- table.el tables
38−- Images with attributes (floating and width)
3938- <cite> tag
4039-}
4140module Text.Pandoc.Readers.Muse (readMuse) where
4241
4342import Prelude
4443import Control.Monad
44+import Control.Monad.Reader
4545import Control.Monad.Except (throwError)
4646import Data.Bifunctor
47−import Data.Char (isLetter)
47+import Data.Char (isAlphaNum)
4848import Data.Default
49−import Data.List (stripPrefix, intercalate)
49+import Data.List (intercalate)
5050import Data.List.Split (splitOn)
5151import qualified Data.Map as M
5252import qualified Data.Set as Set
53−import Data.Maybe (fromMaybe, isNothing)
53+import Data.Maybe (fromMaybe, isNothing, maybeToList)
5454import Data.Text (Text, unpack)
55−import System.FilePath (takeExtension)
56−import Text.HTML.TagSoup
5755import Text.Pandoc.Builder (Blocks, Inlines)
5856import qualified Text.Pandoc.Builder as B
5957import Text.Pandoc.Class (PandocMonad (..))
6058import Text.Pandoc.Definition
59+import Text.Pandoc.Error (PandocError (PandocParsecError))
6160import Text.Pandoc.Logging
6261import Text.Pandoc.Options
63−import Text.Pandoc.Parsing hiding (F)
64−import Text.Pandoc.Readers.HTML (htmlTag)
65−import Text.Pandoc.Shared (crFilter, underlineSpan)
62+import Text.Pandoc.Parsing hiding (F, enclosed)
63+import Text.Pandoc.Shared (crFilter, underlineSpan, mapLeft)
6664
6765-- | Read Muse from an input string and return a Pandoc document.
6866readMuse :: PandocMonad m
@@ -70,7 +68,8 @@ readMuse :: PandocMonad m
7068 -> Text
7169 -> m Pandoc
7270readMuse opts s = do
73− res <- readWithM parseMuse def{ museOptions = opts } (unpack (crFilter s))
71+ let input = crFilter s
72+ res <- mapLeft (PandocParsecError $ unpack input) `liftM` runReaderT (runParserT parseMuse def{ museOptions = opts } "source" input) def
7473 case res of
7574 Left e -> throwError e
7675 Right d -> return d
@@ -84,7 +83,6 @@ data MuseState = MuseState { museMeta :: F Meta -- ^ Document metadata
8483 , museLastStrPos :: Maybe SourcePos -- ^ Position after last str parsed
8584 , museLogMessages :: [LogMessage]
8685 , museNotes :: M.Map String (SourcePos, F Blocks)
87− , museInLink :: Bool -- ^ True when parsing a link description to avoid nested links
8886 , museInPara :: Bool -- ^ True when looking for a paragraph terminator
8987 }
9088
@@ -96,11 +94,17 @@ instance Default MuseState where
9694 , museLastStrPos = Nothing
9795 , museLogMessages = []
9896 , museNotes = M.empty
99− , museInLink = False
10097 , museInPara = False
10198 }
10299
103−type MuseParser = ParserT String MuseState
100+data MuseEnv =
101+ MuseEnv { museInLink :: Bool -- ^ True when parsing a link description to avoid nested links
102+ }
103+
104+instance Default MuseEnv where
105+ def = MuseEnv { museInLink = False }
106+
107+type MuseParser m = ParserT Text MuseState (ReaderT MuseEnv m)
104108
105109instance HasReaderOptions MuseState where
106110 extractReaderOptions = museOptions
@@ -125,11 +129,9 @@ instance HasLogMessages MuseState where
125129parseMuse :: PandocMonad m => MuseParser m Pandoc
126130parseMuse = do
127131 many directive
128− blocks <- parseBlocks
132+ blocks <- (:) <$> parseBlocks <*> many parseSection
129133 st <- getState
130− let doc = runF (do Pandoc _ bs <- B.doc <$> blocks
131− meta <- museMeta st
132− return $ Pandoc meta bs) st
134+ let doc = runF (Pandoc <$> museMeta st <*> fmap B.toList (mconcat blocks)) st
133135 reportLogMessages
134136 return doc
135137
@@ -144,9 +146,8 @@ commonPrefix (x:xs) (y:ys)
144146
145147-- | Trim up to one newline from the beginning of the string.
146148lchop :: String -> String
147−lchop s = case s of
148− '\n':ss -> ss
149− _ -> s
149+lchop ('\n':xs) = xs
150+lchop s = s
150151
151152-- | Trim up to one newline from the end of the string.
152153rchop :: String -> String
@@ -165,12 +166,19 @@ atStart p = do
165166 guard $ museLastStrPos st /= Just pos
166167 p
167168
169+firstColumn :: PandocMonad m => MuseParser m ()
170+firstColumn = getPosition >>= \pos -> guard (sourceColumn pos == 1)
171+
168172-- * Parsers
169173
170174-- | Parse end-of-line, which can be either a newline or end-of-file.
171175eol :: Stream s m Char => ParserT s st m ()
172176eol = void newline <|> eof
173177
178+getIndent :: PandocMonad m
179+ => MuseParser m Int
180+getIndent = subtract 1 . sourceColumn <$ many spaceChar <*> getPosition
181+
174182someUntil :: (Stream s m t)
175183 => ParserT s u m a
176184 -> ParserT s u m b
@@ -179,28 +187,21 @@ someUntil p end = first <$> ((:) <$> p) <*> manyUntil p end
179187
180188-- ** HTML parsers
181189
182−-- | Parse HTML tag, returning its attributes and literal contents.
183−htmlElement :: PandocMonad m
184− => String -- ^ Tag name
185− -> MuseParser m (Attr, String)
186−htmlElement tag = try $ do
187− (TagOpen _ attr, _) <- htmlTag (~== TagOpen tag [])
188− content <- manyTill anyChar endtag
189− return (htmlAttrToPandoc attr, content)
190+openTag :: PandocMonad m => String -> MuseParser m [(String, String)]
191+openTag tag = try $
192+ char '<' *> string tag *> manyTill attr (char '>')
190193 where
191− endtag = void $ htmlTag (~== TagClose tag)
194+ attr = try $ (,)
195+ <$ many1 spaceChar
196+ <*> many1 (noneOf "=\n")
197+ <* string "=\""
198+ <*> manyTill (noneOf "\"") (char '"')
192199
193−htmlBlock :: PandocMonad m
194− => String -- ^ Tag name
195− -> MuseParser m (Attr, String)
196−htmlBlock tag = try $ do
197− many spaceChar
198− res <- htmlElement tag
199− manyTill spaceChar eol
200− return res
200+closeTag :: PandocMonad m => String -> MuseParser m ()
201+closeTag tag = try $ string "</" *> string tag *> void (char '>')
201202
202203-- | Convert HTML attributes to Pandoc 'Attr'
203−htmlAttrToPandoc :: [Attribute String] -> Attr
204+htmlAttrToPandoc :: [(String, String)] -> Attr
204205htmlAttrToPandoc attrs = (ident, classes, keyvals)
205206 where
206207 ident = fromMaybe "" $ lookup "id" attrs
@@ -211,15 +212,12 @@ parseHtmlContent :: PandocMonad m
211212 => String -- ^ Tag name
212213 -> MuseParser m (Attr, F Blocks)
213214parseHtmlContent tag = try $ do
214− many spaceChar
215− pos <- getPosition
216− (TagOpen _ attr, _) <- htmlTag (~== TagOpen tag [])
215+ indent <- getIndent
216+ attr <- openTag tag
217217 manyTill spaceChar eol
218− content <- parseBlocksTill $ try $ count (sourceColumn pos - 1) spaceChar >> endtag
218+ content <- parseBlocksTill $ try $ count indent spaceChar *> closeTag tag
219219 manyTill spaceChar eol -- closing tag must be followed by optional whitespace and newline
220220 return (htmlAttrToPandoc attr, content)
221− where
222− endtag = void $ htmlTag (~== TagClose tag)
223221
224222-- ** Directive parsers
225223
@@ -228,21 +226,19 @@ parseDirectiveKey :: PandocMonad m => MuseParser m String
228226parseDirectiveKey = char '#' *> many (letter <|> char '-')
229227
230228parseEmacsDirective :: PandocMonad m => MuseParser m (String, F Inlines)
231−parseEmacsDirective = do
232− key <- parseDirectiveKey
233− spaceChar
234− value <- trimInlinesF . mconcat <$> manyTill (choice inlineList) eol
235− return (key, value)
229+parseEmacsDirective = (,)
230+ <$> parseDirectiveKey
231+ <* spaceChar
232+ <*> (trimInlinesF . mconcat <$> manyTill inline' eol)
236233
237234parseAmuseDirective :: PandocMonad m => MuseParser m (String, F Inlines)
238−parseAmuseDirective = do
239− key <- parseDirectiveKey
240− many1 spaceChar
241− value <- trimInlinesF . mconcat <$> many1Till inline endOfDirective
242− many blankline
243− return (key, value)
235+parseAmuseDirective = (,)
236+ <$> parseDirectiveKey
237+ <* many1 spaceChar
238+ <*> (trimInlinesF . mconcat <$> many1Till inline endOfDirective)
239+ <* many blankline
244240 where
245− endOfDirective = lookAhead $ eof <|> try (newline >> (void blankline <|> void parseDirectiveKey))
241+ endOfDirective = lookAhead $ eof <|> try (newline *> (void blankline <|> void parseDirectiveKey))
246242
247243directive :: PandocMonad m => MuseParser m ()
248244directive = do
@@ -254,17 +250,20 @@ directive = do
254250
255251-- ** Block parsers
256252
253+-- | Parse section contents until EOF or next header
257254parseBlocks :: PandocMonad m
258255 => MuseParser m (F Blocks)
259256parseBlocks =
260257 try (parseEnd <|>
258+ nextSection <|>
261259 blockStart <|>
262260 listStart <|>
263261 paraStart)
264262 where
263+ nextSection = mempty <$ lookAhead headingStart
265264 parseEnd = mempty <$ eof
266− blockStart = ((B.<>) <$> (emacsHeading <|> blockElements <|> emacsNoteBlock)
267− <*> parseBlocks) <|> (uncurry (B.<>) <$> amuseHeadingUntil parseBlocks)
265+ blockStart = (B.<>) <$> (blockElements <|> emacsNoteBlock)
266+ <*> parseBlocks
268267 listStart = do
269268 updateState (\st -> st { museInPara = False })
270269 uncurry (B.<>) <$> (anyListUntil parseBlocks <|> amuseNoteBlockUntil parseBlocks)
@@ -273,6 +272,13 @@ parseBlocks =
273272 uncurry (B.<>) . first (p indent) <$> paraUntil parseBlocks
274273 where p indent = if indent >= 2 && indent < 6 then fmap B.blockQuote else id
275274
275+-- | Parse section that starts with a header
276+parseSection :: PandocMonad m
277+ => MuseParser m (F Blocks)
278+parseSection =
279+ ((B.<>) <$> emacsHeading <*> parseBlocks) <|>
280+ (uncurry (B.<>) <$> amuseHeadingUntil parseBlocks)
281+
276282parseBlocksTill :: PandocMonad m
277283 => MuseParser m a
278284 -> MuseParser m (F Blocks)
@@ -347,31 +353,32 @@ blockElements = do
347353
348354-- | Parse a line comment, starting with @;@ in the first column.
349355comment :: PandocMonad m => MuseParser m (F Blocks)
350−comment = try $ do
351− getPosition >>= \pos -> guard (sourceColumn pos == 1)
352− char ';'
353− optional (spaceChar >> many (noneOf "\n"))
354− eol
355− return mempty
356+comment = try $ mempty
357+ <$ firstColumn
358+ <* char ';'
359+ <* optional (spaceChar *> many (noneOf "\n"))
360+ <* eol
356361
357362-- | Parse a horizontal rule, consisting of 4 or more @\'-\'@ characters.
358363separator :: PandocMonad m => MuseParser m (F Blocks)
359−separator = try $ do
360− string "----"
361− many $ char '-'
362− many spaceChar
363− eol
364− return $ return B.horizontalRule
364+separator = try $ pure B.horizontalRule
365+ <$ string "----"
366+ <* many (char '-')
367+ <* many spaceChar
368+ <* eol
369+
370+headingStart :: PandocMonad m => MuseParser m (String, Int)
371+headingStart = try $ (,)
372+ <$> option "" (try (parseAnchor <* manyTill spaceChar eol))
373+ <* firstColumn
374+ <*> fmap length (many1 $ char '*')
375+ <* spaceChar
365376
366377-- | Parse a single-line heading.
367378emacsHeading :: PandocMonad m => MuseParser m (F Blocks)
368379emacsHeading = try $ do
369380 guardDisabled Ext_amuse
370− anchorId <- option "" $ try (parseAnchor <* manyTill spaceChar eol)
371− getPosition >>= \pos -> guard (sourceColumn pos == 1)
372− level <- fmap length $ many1 $ char '*'
373− guard $ level <= 5
374− spaceChar
381+ (anchorId, level) <- headingStart
375382 content <- trimInlinesF . mconcat <$> manyTill inline eol
376383 attr <- registerHeader (anchorId, [], []) (runF content def)
377384 return $ B.headerWith attr level <$> content
@@ -383,11 +390,7 @@ amuseHeadingUntil :: PandocMonad m
383390 -> MuseParser m (F Blocks, a)
384391amuseHeadingUntil end = try $ do
385392 guardEnabled Ext_amuse
386− anchorId <- option "" $ try (parseAnchor <* manyTill spaceChar eol)
387− getPosition >>= \pos -> guard (sourceColumn pos == 1)
388− level <- fmap length $ many1 $ char '*'
389− guard $ level <= 5
390− spaceChar
393+ (anchorId, level) <- headingStart
391394 (content, e) <- paraContentsUntil end
392395 attr <- registerHeader (anchorId, [], []) (runF content def)
393396 return (B.headerWith attr level <$> content, e)
@@ -395,33 +398,28 @@ amuseHeadingUntil end = try $ do
395398-- | Parse an example between @{{{@ and @}}}@.
396399-- It is an Amusewiki extension influenced by Creole wiki, as described in @Text::Amuse@ documentation.
397400example :: PandocMonad m => MuseParser m (F Blocks)
398−example = try $ do
399− string "{{{"
400− optional blankline
401− contents <- manyTill anyChar $ try (optional blankline >> string "}}}")
402− return $ return $ B.codeBlock contents
401+example = try $ pure . B.codeBlock
402+ <$ string "{{{"
403+ <* optional blankline
404+ <*> manyTill anyChar (try (optional blankline *> string "}}}"))
403405
404406-- | Parse an @\<example>@ tag.
405407exampleTag :: PandocMonad m => MuseParser m (F Blocks)
406−exampleTag = try $ do
407− (attr, contents) <- htmlBlock "example"
408− return $ return $ B.codeBlockWith attr $ rchop $ intercalate "\n" $ dropSpacePrefix $ splitOn "\n" $ lchop contents
408+exampleTag = try $ fmap pure $ B.codeBlockWith
409+ <$ many spaceChar
410+ <*> (htmlAttrToPandoc <$> openTag "example")
411+ <*> (rchop . intercalate "\n" . dropSpacePrefix . splitOn "\n" . lchop <$> manyTill anyChar (closeTag "example"))
412+ <* manyTill spaceChar eol
409413
410414-- | Parse a @\<literal>@ tag as a raw block.
411415-- For 'RawInline' @\<literal>@ parser, see 'inlineLiteralTag'.
412416literalTag :: PandocMonad m => MuseParser m (F Blocks)
413−literalTag = try $ do
414− many spaceChar
415− (TagOpen _ attr, _) <- htmlTag (~== TagOpen "literal" [])
416− manyTill spaceChar eol
417− content <- manyTill anyChar endtag
418− manyTill spaceChar eol
419− return $ return $ rawBlock (htmlAttrToPandoc attr, content)
420− where
421− endtag = void $ htmlTag (~== TagClose "literal")
422− -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML
423− format (_, _, kvs) = fromMaybe "html" $ lookup "style" kvs
424− rawBlock (attrs, content) = B.rawBlock (format attrs) $ rchop $ intercalate "\n" $ dropSpacePrefix $ splitOn "\n" $ lchop content
417+literalTag = try $ fmap pure $ B.rawBlock
418+ <$ many spaceChar
419+ <*> (fromMaybe "html" . lookup "style" <$> openTag "literal") -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML
420+ <* manyTill spaceChar eol
421+ <*> (rchop . intercalate "\n" . dropSpacePrefix . splitOn "\n" . lchop <$> manyTill anyChar (closeTag "literal"))
422+ <* manyTill spaceChar eol
425423
426424-- | Parse @\<center>@ tag.
427425-- Currently it is ignored as Pandoc cannot represent centered blocks.
@@ -459,25 +457,27 @@ playTag = do
459457 fmap (B.divWith ("", ["play"], [])) . snd <$> parseHtmlContent "play"
460458
461459verseLine :: PandocMonad m => MuseParser m (F Inlines)
462−verseLine = do
463− indent <- (B.str <$> many1 (char ' ' >> pure '\160')) <|> pure mempty
464− rest <- manyTill (choice inlineList) newline
465− return $ trimInlinesF $ mconcat (pure indent : rest)
466−
467−verseLines :: PandocMonad m => MuseParser m (F Blocks)
468−verseLines = do
469− lns <- many verseLine
470− return $ B.lineBlock <$> sequence lns
460+verseLine = (<>)
461+ <$> fmap pure (option mempty (B.str <$> many1 ('\160' <$ char ' ')))
462+ <*> fmap (trimInlinesF . mconcat) (manyTill inline' eol)
471463
472464-- | Parse @\<verse>@ tag.
473465verseTag :: PandocMonad m => MuseParser m (F Blocks)
474−verseTag = do
475− (_, content) <- htmlBlock "verse"
476− parseFromString verseLines (intercalate "\n" $ dropSpacePrefix $ splitOn "\n" $ lchop content)
466+verseTag = try $ do
467+ indent <- getIndent
468+ openTag "verse"
469+ manyTill spaceChar eol
470+ content <- sequence <$> manyTill (count indent spaceChar *> verseLine) (try $ count indent spaceChar *> closeTag "verse")
471+ manyTill spaceChar eol
472+ return $ B.lineBlock <$> content
477473
478474-- | Parse @\<comment>@ tag.
479475commentTag :: PandocMonad m => MuseParser m (F Blocks)
480−commentTag = htmlBlock "comment" >> return mempty
476+commentTag = try $ mempty
477+ <$ many spaceChar
478+ <* openTag "comment"
479+ <* manyTill anyChar (closeTag "comment")
480+ <* manyTill spaceChar eol
481481
482482-- | Parse paragraph contents.
483483paraContentsUntil :: PandocMonad m
@@ -485,7 +485,7 @@ paraContentsUntil :: PandocMonad m
485485 -> MuseParser m (F Inlines, a)
486486paraContentsUntil end = do
487487 updateState (\st -> st { museInPara = True })
488− (l, e) <- someUntil inline $ try (manyTill spaceChar eol >> end)
488+ (l, e) <- someUntil inline $ try (manyTill spaceChar eol *> end)
489489 updateState (\st -> st { museInPara = False })
490490 return (trimInlinesF $ mconcat l, e)
491491
@@ -499,9 +499,10 @@ paraUntil end = do
499499 first (fmap B.para) <$> paraContentsUntil end
500500
501501noteMarker :: PandocMonad m => MuseParser m String
502−noteMarker = try $ do
503− char '['
504− (:) <$> oneOf "123456789" <*> manyTill digit (char ']')
502+noteMarker = try $ (:)
503+ <$ char '['
504+ <*> oneOf "123456789"
505+ <*> manyTill digit (char ']')
505506
506507-- Amusewiki version of note
507508-- Parsing is similar to list item, except that note marker is used instead of list marker
@@ -541,27 +542,15 @@ emacsNoteBlock = try $ do
541542-- Verse markup
542543--
543544
544−lineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
545−lineVerseLine = try $ do
546− string "> "
547− indent <- many (char ' ' >> pure '\160')
548− let indentEl = if null indent then mempty else B.str indent
549− rest <- manyTill (choice inlineList) eol
550− return $ trimInlinesF $ mconcat (pure indentEl : rest)
551−
552−blanklineVerseLine :: PandocMonad m => MuseParser m (F Inlines)
553−blanklineVerseLine = try $ do
554− char '>'
555− blankline
556− pure mempty
557−
558545-- | Parse a line block indicated by @\'>\'@ characters.
559546lineBlock :: PandocMonad m => MuseParser m (F Blocks)
560547lineBlock = try $ do
561− many spaceChar
562− col <- sourceColumn <$> getPosition
563− lns <- (blanklineVerseLine <|> lineVerseLine) `sepBy1'` try (indentWith (col - 1))
548+ indent <- getIndent
549+ lns <- (blankVerseLine <|> nonblankVerseLine) `sepBy1'` try (indentWith indent)
564550 return $ B.lineBlock <$> sequence lns
551+ where
552+ blankVerseLine = try $ mempty <$ char '>' <* blankline
553+ nonblankVerseLine = try (string "> ") *> verseLine
565554
566555-- *** List parsers
567556
@@ -573,7 +562,7 @@ bulletListItemsUntil indent end = try $ do
573562 char '-'
574563 void spaceChar <|> lookAhead eol
575564 updateState (\st -> st { museInPara = False })
576− (x, (xs, e)) <- listItemContentsUntil (indent + 2) (try (optional blankline >> indentWith indent >> bulletListItemsUntil indent end)) (([],) <$> end)
565+ (x, (xs, e)) <- listItemContentsUntil (indent + 2) (try (optional blankline *> indentWith indent *> bulletListItemsUntil indent end)) (([],) <$> end)
577566 return (x:xs, e)
578567
579568-- | Parse a bullet list.
@@ -581,19 +570,9 @@ bulletListUntil :: PandocMonad m
581570 => MuseParser m a
582571 -> MuseParser m (F Blocks, a)
583572bulletListUntil end = try $ do
584− many spaceChar
585− pos <- getPosition
586− let indent = sourceColumn pos - 1
573+ indent <- getIndent
587574 guard $ indent /= 0
588− (items, e) <- bulletListItemsUntil indent end
589− return (B.bulletList <$> sequence items, e)
590−
591−-- | Parses an ordered list marker and returns list attributes.
592−anyMuseOrderedListMarker :: PandocMonad m => MuseParser m ListAttributes
593−anyMuseOrderedListMarker = do
594− (style, start) <- decimal <|> lowerRoman <|> upperRoman <|> lowerAlpha <|> upperAlpha
595− char '.'
596− return (start, style, Period)
575+ first (fmap B.bulletList . sequence) <$> bulletListItemsUntil indent end
597576
598577museOrderedListMarker :: PandocMonad m
599578 => ListNumberStyle
@@ -620,7 +599,7 @@ orderedListItemsUntil indent style end =
620599 pos <- getPosition
621600 void spaceChar <|> lookAhead eol
622601 updateState (\st -> st { museInPara = False })
623− (x, (xs, e)) <- listItemContentsUntil (sourceColumn pos) (try (optional blankline >> indentWith indent >> museOrderedListMarker style >> continuation)) (([],) <$> end)
602+ (x, (xs, e)) <- listItemContentsUntil (sourceColumn pos) (try (optional blankline *> indentWith indent *> museOrderedListMarker style *> continuation)) (([],) <$> end)
624603 return (x:xs, e)
625604
626605-- | Parse an ordered list.
@@ -628,14 +607,12 @@ orderedListUntil :: PandocMonad m
628607 => MuseParser m a
629608 -> MuseParser m (F Blocks, a)
630609orderedListUntil end = try $ do
631− many spaceChar
632− pos <- getPosition
633− let indent = sourceColumn pos - 1
610+ indent <- getIndent
634611 guard $ indent /= 0
635− p@(_, style, _) <- anyMuseOrderedListMarker
636− guard $ style `elem` [Decimal, LowerAlpha, UpperAlpha, LowerRoman, UpperRoman]
637− (items, e) <- orderedListItemsUntil indent style end
638− return (B.orderedListWith p <$> sequence items, e)
612+ (style, start) <- decimal <|> lowerRoman <|> upperRoman <|> lowerAlpha <|> upperAlpha
613+ char '.'
614+ first (fmap (B.orderedListWith (start, style, Period)) . sequence)
615+ <$> orderedListItemsUntil indent style end
639616
640617descriptionsUntil :: PandocMonad m
641618 => Int
@@ -644,7 +621,7 @@ descriptionsUntil :: PandocMonad m
644621descriptionsUntil indent end = do
645622 void spaceChar <|> lookAhead eol
646623 updateState (\st -> st { museInPara = False })
647− (x, (xs, e)) <- listItemContentsUntil indent (try (optional blankline >> indentWith indent >> manyTill spaceChar (string "::") >> descriptionsUntil indent end)) (([],) <$> end)
624+ (x, (xs, e)) <- listItemContentsUntil indent (try (optional blankline *> indentWith indent *> manyTill spaceChar (string "::") *> descriptionsUntil indent end)) (([],) <$> end)
648625 return (x:xs, e)
649626
650627definitionListItemsUntil :: PandocMonad m
@@ -656,8 +633,8 @@ definitionListItemsUntil indent end =
656633 where
657634 continuation = try $ do
658635 pos <- getPosition
659− term <- trimInlinesF . mconcat <$> manyTill (choice inlineList) (try $ string "::")
660− (x, (xs, e)) <- descriptionsUntil (sourceColumn pos) (try (optional blankline >> indentWith indent >> continuation) <|> (([],) <$> end))
636+ term <- trimInlinesF . mconcat <$> manyTill inline' (try $ string "::")
637+ (x, (xs, e)) <- descriptionsUntil (sourceColumn pos) (try (optional blankline *> indentWith indent *> continuation) <|> (([],) <$> end))
661638 let xx = (,) <$> term <*> sequence x
662639 return (xx:xs, e)
663640
@@ -666,9 +643,7 @@ definitionListUntil :: PandocMonad m
666643 => MuseParser m a -- ^ Terminator parser
667644 -> MuseParser m (F Blocks, a)
668645definitionListUntil end = try $ do
669− many spaceChar
670− pos <- getPosition
671− let indent = sourceColumn pos - 1
646+ indent <- getIndent
672647 guardDisabled Ext_amuse <|> guard (indent /= 0) -- Initial space is required by Amusewiki, but not Emacs Muse
673648 first (fmap B.definitionList . sequence) <$> definitionListItemsUntil indent end
674649
@@ -713,7 +688,7 @@ museAppendElement element tbl =
713688
714689tableCell :: PandocMonad m => MuseParser m (F Blocks)
715690tableCell = try $ fmap B.plain . trimInlinesF . mconcat <$> manyTill inline (lookAhead cellEnd)
716− where cellEnd = try $ void (many1 spaceChar >> char '|') <|> eol
691+ where cellEnd = try $ void (many1 spaceChar *> char '|') <|> eol
717692
718693tableElements :: PandocMonad m => MuseParser m (F [MuseTableElement])
719694tableElements = sequence <$> (tableParseElement `sepEndBy1` eol)
@@ -735,11 +710,10 @@ tableParseElement = tableParseHeader
735710tableParseRow :: PandocMonad m
736711 => Int -- ^ Number of separator characters
737712 -> MuseParser m (F [Blocks])
738−tableParseRow n = try $ do
739− fields <- tableCell `sepBy2` fieldSep
740− return $ sequence fields
741− where p `sepBy2` sep = (:) <$> p <*> many1 (sep >> p)
742− fieldSep = many1 spaceChar >> count n (char '|') >> (void (many1 spaceChar) <|> void (lookAhead newline))
713+tableParseRow n = try $
714+ sequence <$> (tableCell `sepBy2` fieldSep)
715+ where p `sepBy2` sep = (:) <$> p <*> many1 (sep *> p)
716+ fieldSep = many1 spaceChar *> count n (char '|') *> (void (many1 spaceChar) <|> void (lookAhead newline))
743717
744718-- | Parse a table header row.
745719tableParseHeader :: PandocMonad m => MuseParser m (F MuseTableElement)
@@ -755,53 +729,51 @@ tableParseFooter = fmap MuseFooterRow <$> tableParseRow 3
755729
756730-- | Parse table caption.
757731tableParseCaption :: PandocMonad m => MuseParser m (F MuseTableElement)
758−tableParseCaption = try $ do
759− many spaceChar
760− string "|+"
761− fmap MuseCaption <$> (trimInlinesF . mconcat <$> many1Till inline (string "+|"))
732+tableParseCaption = try $ fmap MuseCaption . trimInlinesF . mconcat
733+ <$ many spaceChar
734+ <* string "|+"
735+ <*> many1Till inline (try $ string "+|")
762736
763737-- ** Inline parsers
764738
765−inlineList :: PandocMonad m => [MuseParser m (F Inlines)]
766−inlineList = [ whitespace
767− , br
768− , anchor
769− , footnote
770− , strong
771− , strongTag
772− , emph
773− , emphTag
774− , underlined
775− , superscriptTag
776− , subscriptTag
777− , strikeoutTag
778− , verbatimTag
779− , classTag
780− , nbsp
781− , link
782− , code
783− , codeTag
784− , mathTag
785− , inlineLiteralTag
786− , str
787− , symbol
788− ]
739+inline' :: PandocMonad m => MuseParser m (F Inlines)
740+inline' = whitespace
741+ <|> br
742+ <|> anchor
743+ <|> footnote
744+ <|> strong
745+ <|> strongTag
746+ <|> emph
747+ <|> emphTag
748+ <|> underlined
749+ <|> superscriptTag
750+ <|> subscriptTag
751+ <|> strikeoutTag
752+ <|> verbatimTag
753+ <|> classTag
754+ <|> nbsp
755+ <|> linkOrImage
756+ <|> code
757+ <|> codeTag
758+ <|> mathTag
759+ <|> inlineLiteralTag
760+ <|> str
761+ <|> symbol
762+ <?> "inline"
789763
790764inline :: PandocMonad m => MuseParser m (F Inlines)
791−inline = endline <|> choice inlineList <?> "inline"
765+inline = endline <|> inline'
792766
793767-- | Parse a soft break.
794768endline :: PandocMonad m => MuseParser m (F Inlines)
795−endline = try $ do
796− newline
797− notFollowedBy blankline
798− return $ return B.softbreak
769+endline = try $ pure B.softbreak <$ newline <* notFollowedBy blankline
799770
800771parseAnchor :: PandocMonad m => MuseParser m String
801−parseAnchor = try $ do
802− getPosition >>= \pos -> guard (sourceColumn pos == 1)
803− char '#'
804− (:) <$> letter <*> many (letter <|> digit <|> char '-')
772+parseAnchor = try $ (:)
773+ <$ firstColumn
774+ <* char '#'
775+ <*> letter
776+ <*> many (letter <|> digit <|> char '-')
805777
806778anchor :: PandocMonad m => MuseParser m (F Inlines)
807779anchor = try $ do
@@ -812,7 +784,7 @@ anchor = try $ do
812784-- | Parse a footnote reference.
813785footnote :: PandocMonad m => MuseParser m (F Inlines)
814786footnote = try $ do
815− inLink <- museInLink <$> getState
787+ inLink <- asks museInLink
816788 guard $ not inLink
817789 ref <- noteMarker
818790 return $ do
@@ -825,33 +797,38 @@ footnote = try $ do
825797 return $ B.note contents'
826798
827799whitespace :: PandocMonad m => MuseParser m (F Inlines)
828−whitespace = try $ do
829− skipMany1 spaceChar
830− return $ return B.space
800+whitespace = try $ pure B.space <$ skipMany1 spaceChar
831801
832802-- | Parse @\<br>@ tag.
833803br :: PandocMonad m => MuseParser m (F Inlines)
834−br = try $ do
835− string "<br>"
836− return $ return B.linebreak
804+br = try $ pure B.linebreak <$ string "<br>"
837805
838806emphasisBetween :: (PandocMonad m, Show a) => MuseParser m a -> MuseParser m (F Inlines)
839807emphasisBetween c = try $ enclosedInlines c c
840808
809+-- | Parses material enclosed between start and end parsers.
810+enclosed :: (Show end, Stream s m Char) => ParserT s st m t -- ^ start parser
811+ -> ParserT s st m end -- ^ end parser
812+ -> ParserT s st m a -- ^ content parser (to be used repeatedly)
813+ -> ParserT s st m [a]
814+enclosed start end parser = try $
815+ start *> notFollowedBy spaceChar *> many1Till parser end
816+
841817enclosedInlines :: (PandocMonad m, Show a, Show b)
842818 => MuseParser m a
843819 -> MuseParser m b
844820 -> MuseParser m (F Inlines)
845−enclosedInlines start end = try $
846− trimInlinesF . mconcat <$> (enclosed (atStart start) end inline <* notFollowedBy (satisfy isLetter))
821+enclosedInlines start end = try $ trimInlinesF . mconcat
822+ <$> enclosed (atStart start) end inline
823+ <* notFollowedBy (satisfy isAlphaNum)
847824
848825-- | Parse an inline tag, such as @\<em>@ and @\<strong>@.
849826inlineTag :: PandocMonad m
850827 => String -- ^ Tag name
851828 -> MuseParser m (F Inlines)
852−inlineTag tag = try $ do
853− htmlTag (~== TagOpen tag [])
854− mconcat <$> manyTill inline (void $ htmlTag (~== TagClose tag))
829+inlineTag tag = try $ mconcat
830+ <$ openTag tag
831+ <*> manyTill inline (closeTag tag)
855832
856833-- | Parse strong inline markup, indicated by @**@.
857834strong :: PandocMonad m => MuseParser m (F Inlines)
@@ -864,9 +841,9 @@ emph = fmap B.emph <$> emphasisBetween (char '*')
864841-- | Parse underline inline markup, indicated by @_@.
865842-- Supported only in Emacs Muse mode, not Text::Amuse.
866843underlined :: PandocMonad m => MuseParser m (F Inlines)
867−underlined = do
868− guardDisabled Ext_amuse -- Supported only by Emacs Muse
869− fmap underlineSpan <$> emphasisBetween (char '_')
844+underlined = fmap underlineSpan
845+ <$ guardDisabled Ext_amuse -- Supported only by Emacs Muse
846+ <*> emphasisBetween (char '_')
870847
871848-- | Parse @\<strong>@ tag.
872849strongTag :: PandocMonad m => MuseParser m (F Inlines)
@@ -890,21 +867,20 @@ strikeoutTag = fmap B.strikeout <$> inlineTag "del"
890867
891868-- | Parse @\<verbatim>@ tag.
892869verbatimTag :: PandocMonad m => MuseParser m (F Inlines)
893−verbatimTag = return . B.text . snd <$> htmlElement "verbatim"
870+verbatimTag = return . B.text
871+ <$ openTag "verbatim"
872+ <*> manyTill anyChar (closeTag "verbatim")
894873
895874-- | Parse @\<class>@ tag.
896875classTag :: PandocMonad m => MuseParser m (F Inlines)
897876classTag = do
898− (TagOpen _ attrs, _) <- htmlTag (~== TagOpen "class" [])
899− res <- manyTill inline (void $ htmlTag (~== TagClose "class"))
900− let classes = maybe [] words $ lookup "name" attrs
877+ classes <- maybe [] words . lookup "name" <$> openTag "class"
878+ res <- manyTill inline $ closeTag "class"
901879 return $ B.spanWith ("", classes, []) <$> mconcat res
902880
903881-- | Parse "~~" as nonbreaking space.
904882nbsp :: PandocMonad m => MuseParser m (F Inlines)
905−nbsp = try $ do
906− string "~~"
907− return $ return $ B.str "\160"
883+nbsp = try $ pure (B.str "\160") <$ string "~~"
908884
909885-- | Parse code markup, indicated by @\'=\'@ characters.
910886code :: PandocMonad m => MuseParser m (F Inlines)
@@ -914,26 +890,27 @@ code = try $ do
914890 guard $ not $ null contents
915891 guard $ head contents `notElem` " \t\n"
916892 guard $ last contents `notElem` " \t\n"
917− notFollowedBy $ satisfy isLetter
893+ notFollowedBy $ satisfy isAlphaNum
918894 return $ return $ B.code contents
919895
920896-- | Parse @\<code>@ tag.
921897codeTag :: PandocMonad m => MuseParser m (F Inlines)
922−codeTag = return . uncurry B.codeWith <$> htmlElement "code"
898+codeTag = fmap pure $ B.codeWith
899+ <$> (htmlAttrToPandoc <$> openTag "code")
900+ <*> manyTill anyChar (closeTag "code")
923901
924902-- | Parse @\<math>@ tag.
925903-- @\<math>@ tag is an Emacs Muse extension enabled by @(require 'muse-latex2png)@
926904mathTag :: PandocMonad m => MuseParser m (F Inlines)
927−mathTag = return . B.math . snd <$> htmlElement "math"
905+mathTag = return . B.math
906+ <$ openTag "math"
907+ <*> manyTill anyChar (closeTag "math")
928908
929909-- | Parse inline @\<literal>@ tag as a raw inline.
930910inlineLiteralTag :: PandocMonad m => MuseParser m (F Inlines)
931−inlineLiteralTag =
932− (return . rawInline) <$> htmlElement "literal"
933− where
934− -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML
935− format (_, _, kvs) = fromMaybe "html" $ lookup "style" kvs
936− rawInline (attrs, content) = B.rawInline (format attrs) content
911+inlineLiteralTag = try $ fmap pure $ B.rawInline
912+ <$> (fromMaybe "html" . lookup "style" <$> openTag "literal") -- FIXME: Emacs Muse inserts <literal> without style into all output formats, but we assume HTML
913+ <*> manyTill anyChar (closeTag "literal")
937914
938915str :: PandocMonad m => MuseParser m (F Inlines)
939916str = return . B.str <$> many1 alphaNum <* updateLastStrPos
@@ -942,29 +919,58 @@ symbol :: PandocMonad m => MuseParser m (F Inlines)
942919symbol = return . B.str <$> count 1 nonspaceChar
943920
944921-- | Parse a link or image.
945−link :: PandocMonad m => MuseParser m (F Inlines)
946−link = try $ do
947− st <- getState
948− guard $ not $ museInLink st
949− setState $ st{ museInLink = True }
950− (url, content) <- linkText
951− updateState (\state -> state { museInLink = False })
952− return $ case stripPrefix "URL:" url of
953− Nothing -> if isImageUrl url
954− then B.image url "" <$> fromMaybe (return mempty) content
955− else B.link url "" <$> fromMaybe (return $ B.str url) content
956− Just url' -> B.link url' "" <$> fromMaybe (return $ B.str url') content
957− where -- Taken from muse-image-regexp defined in Emacs Muse file lisp/muse-regexps.el
958− imageExtensions = [".eps", ".gif", ".jpg", ".jpeg", ".pbm", ".png", ".tiff", ".xbm", ".xpm"]
959− isImageUrl = (`elem` imageExtensions) . takeExtension
922+linkOrImage :: PandocMonad m => MuseParser m (F Inlines)
923+linkOrImage = try $ do
924+ inLink <- asks museInLink
925+ guard $ not inLink
926+ local (\s -> s { museInLink = True }) (explicitLink <|> image <|> link)
960927
961928linkContent :: PandocMonad m => MuseParser m (F Inlines)
962−linkContent = char '[' >> trimInlinesF . mconcat <$> manyTill inline (string "]")
929+linkContent = trimInlinesF . mconcat
930+ <$ char '['
931+ <*> manyTill inline (char ']')
932+
933+-- | Parse a link starting with @URL:@
934+explicitLink :: PandocMonad m => MuseParser m (F Inlines)
935+explicitLink = try $ do
936+ string "[[URL:"
937+ url <- manyTill anyChar $ char ']'
938+ content <- option (pure $ B.str url) linkContent
939+ char ']'
940+ return $ B.link url "" <$> content
963941
964−linkText :: PandocMonad m => MuseParser m (String, Maybe (F Inlines))
965−linkText = do
942+image :: PandocMonad m => MuseParser m (F Inlines)
943+image = try $ do
944+ string "[["
945+ (url, (ext, width, align)) <- manyUntil (noneOf "]") (imageExtensionAndOptions <* char ']')
946+ content <- option mempty linkContent
947+ char ']'
948+ let widthAttr = case align of
949+ Just 'f' -> [("width", fromMaybe "100" width ++ "%"), ("height", "75%")]
950+ _ -> maybeToList (("width",) . (++ "%") <$> width)
951+ let alignClass = case align of
952+ Just 'r' -> ["align-right"]
953+ Just 'l' -> ["align-left"]
954+ Just 'f' -> []
955+ _ -> []
956+ return $ B.imageWith ("", alignClass, widthAttr) (url ++ ext) mempty <$> content
957+ where -- Taken from muse-image-regexp defined in Emacs Muse file lisp/muse-regexps.el
958+ imageExtensions = [".eps", ".gif", ".jpg", ".jpeg", ".pbm", ".png", ".tiff", ".xbm", ".xpm"]
959+ imageExtension = choice (try . string <$> imageExtensions)
960+ imageExtensionAndOptions = do
961+ ext <- imageExtension
962+ (width, align) <- option (Nothing, Nothing) imageAttrs
963+ return (ext, width, align)
964+ imageAttrs = (,)
965+ <$ many1 spaceChar
966+ <*> optionMaybe (many1 digit)
967+ <* many spaceChar
968+ <*> optionMaybe (oneOf "rlf")
969+
970+link :: PandocMonad m => MuseParser m (F Inlines)
971+link = try $ do
966972 string "[["
967973 url <- manyTill anyChar $ char ']'
968974 content <- optionMaybe linkContent
969975 char ']'
970− return (url, content)
976+ return $ B.link url "" <$> fromMaybe (return $ B.str url) content
src/Text/Pandoc/Readers/Odt/Arrows/Utils.hs+2−2
@@ -100,7 +100,7 @@ liftA fun a = a >>^ fun
100100-- | Duplicate a value to subsequently feed it into different arrows.
101101-- Can almost always be replaced with '(&&&)', 'keepingTheValue',
102102-- or even '(|||)'.
103−-- Aequivalent to
103+-- Equivalent to
104104-- > returnA &&& returnA
105105duplicate :: (Arrow a) => a b (b,b)
106106duplicate = arr $ join (,)
@@ -114,7 +114,7 @@ infixr 2 >>%
114114
115115
116116-- | Duplicate a value and apply an arrow to the second instance.
117−-- Aequivalent to
117+-- Equivalent to
118118-- > \a -> duplicate >>> second a
119119-- or
120120-- > \a -> returnA &&& a
src/Text/Pandoc/Readers/Odt/Generic/Namespaces.hs+1−1
@@ -50,7 +50,7 @@ class (Eq nsID, Ord nsID) => NameSpaceID nsID where
5050 getNamespaceID :: NameSpaceIRI
5151 -> NameSpaceIRIs nsID
5252 -> Maybe (NameSpaceIRIs nsID, nsID)
53− -- | Given a namespace id, lookup its IRI. May be overriden for performance.
53+ -- | Given a namespace id, lookup its IRI. May be overridden for performance.
5454 getIRI :: nsID
5555 -> NameSpaceIRIs nsID
5656 -> Maybe NameSpaceIRI
src/Text/Pandoc/Readers/Odt/Generic/Utils.hs+3−5
@@ -61,7 +61,7 @@ import qualified Data.Foldable as F (Foldable, foldr)
6161import Data.Maybe
6262
6363
64−-- | Aequivalent to
64+-- | Equivalent to
6565-- > foldr (.) id
6666-- where '(.)' are 'id' are the ones from "Control.Category"
6767-- and 'foldr' is the one from "Data.Foldable".
@@ -72,7 +72,7 @@ import Data.Maybe
7272composition :: (Category cat, F.Foldable f) => f (cat a a) -> cat a a
7373composition = F.foldr (<<<) Cat.id
7474
75−-- | Aequivalent to
75+-- | Equivalent to
7676-- > foldr (flip (.)) id
7777-- where '(.)' are 'id' are the ones from "Control.Category"
7878-- and 'foldr' is the one from "Data.Foldable".
@@ -133,9 +133,7 @@ class Lookupable a where
133133-- can be used directly in almost any case.
134134readLookupables :: (Lookupable a) => String -> [(a,String)]
135135readLookupables s = [ (a,rest) | (word,rest) <- lex s,
136− let result = lookup word lookupTable,
137− isJust result,
138− let Just a = result
136+ a <- maybeToList (lookup word lookupTable)
139137 ]
140138
141139-- | Very similar to a simple 'lookup' in the 'lookupTable', but with a lexer.
src/Text/Pandoc/Readers/Odt/Generic/XMLConverter.hs+1−1
@@ -261,7 +261,7 @@ convertingExtraState v a = withSubStateF setVAsExtraState modifyWithA
261261-- The resulting converter even behaves like an identity converter on the
262262-- value level.
263263--
264−-- Aequivalent to
264+-- Equivalent to
265265--
266266-- > \v x a -> convertingExtraState v (returnV x >>> a)
267267--
src/Text/Pandoc/Readers/Odt/StyleReader.hs+2−2
@@ -138,7 +138,7 @@ fontPitchReader = executeIn NsOffice "font-face-decls" (
138138 lookupDefaultingAttr NsStyle "font-pitch"
139139 ))
140140 >>?^ ( M.fromList . foldl accumLegalPitches [] )
141− )
141+ ) `ifFailedDo` (returnV (Right M.empty))
142142 where accumLegalPitches ls (Nothing,_) = ls
143143 accumLegalPitches ls (Just n,p) = (n,p):ls
144144
@@ -342,7 +342,7 @@ instance Read XslUnit where
342342 readsPrec _ _ = []
343343
344344-- | Rough conversion of measures into millimetres.
345−-- Pixels and em's are actually implementation dependant/relative measures,
345+-- Pixels and em's are actually implementation dependent/relative measures,
346346-- so I could not really easily calculate anything exact here even if I wanted.
347347-- But I do not care about exactness right now, as I only use measures
348348-- to determine if a paragraph is "indented" or not.
src/Text/Pandoc/Readers/Org/Blocks.hs+2−5
@@ -40,7 +40,7 @@ import Text.Pandoc.Readers.Org.Meta (metaExport, metaKey, metaLine)
4040import Text.Pandoc.Readers.Org.ParserState
4141import Text.Pandoc.Readers.Org.Parsing
4242import Text.Pandoc.Readers.Org.Shared (cleanLinkString, isImageFilename,
43− originalLang, translateLang)
43+ originalLang, translateLang, exportsCode)
4444
4545import Text.Pandoc.Builder (Blocks, Inlines)
4646import Text.Pandoc.Class (PandocMonad)
@@ -314,9 +314,6 @@ codeBlock blockAttrs blockType = do
314314 labelledBlock :: F Inlines -> F Blocks
315315 labelledBlock = fmap (B.plain . B.spanWith ("", ["label"], []))
316316
317− exportsCode :: [(String, String)] -> Bool
318− exportsCode = maybe True (`elem` ["code", "both"]) . lookup "exports"
319−
320317 exportsResults :: [(String, String)] -> Bool
321318 exportsResults = maybe False (`elem` ["results", "both"]) . lookup "exports"
322319
@@ -743,7 +740,7 @@ latexEnd envName = try $
743740
744741
745742--
746−-- Footnote defintions
743+-- Footnote definitions
747744--
748745noteBlock :: PandocMonad m => OrgParser m (F Blocks)
749746noteBlock = try $ do
src/Text/Pandoc/Readers/Org/DocumentTree.hs+98−41
@@ -1,4 +1,3 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
21{-
32Copyright (C) 2014-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
43
@@ -17,8 +16,7 @@ along with this program; if not, write to the Free Software
1716Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817-}
1918{-# LANGUAGE FlexibleContexts #-}
20−{-# LANGUAGE RecordWildCards #-}
21−{-# LANGUAGE ViewPatterns #-}
19+{-# LANGUAGE NoImplicitPrelude #-}
2220{- |
2321 Module : Text.Pandoc.Readers.Org.DocumentTree
2422 Copyright : Copyright (C) 2014-2018 Albert Krewinkel
@@ -45,7 +43,7 @@ import Text.Pandoc.Readers.Org.BlockStarts
4543import Text.Pandoc.Readers.Org.ParserState
4644import Text.Pandoc.Readers.Org.Parsing
4745
48−import qualified Data.Map as Map
46+import qualified Data.Set as Set
4947import qualified Text.Pandoc.Builder as B
5048
5149--
@@ -60,7 +58,7 @@ documentTree :: PandocMonad m
6058documentTree blocks inline = do
6159 initialBlocks <- blocks
6260 headlines <- sequence <$> manyTill (headline blocks inline 1) eof
63− title <- fmap (getTitle . unMeta) . orgStateMeta <$> getState
61+ title <- fmap docTitle . orgStateMeta <$> getState
6462 return $ do
6563 headlines' <- headlines
6664 initialBlocks' <- initialBlocks
@@ -70,19 +68,11 @@ documentTree blocks inline = do
7068 , headlineTodoMarker = Nothing
7169 , headlineText = B.fromList title'
7270 , headlineTags = mempty
71+ , headlinePlanning = emptyPlanning
7372 , headlineProperties = mempty
7473 , headlineContents = initialBlocks'
7574 , headlineChildren = headlines'
7675 }
77− where
78− getTitle :: Map.Map String MetaValue -> [Inline]
79− getTitle metamap =
80− case Map.lookup "title" metamap of
81− Just (MetaInlines inlns) -> inlns
82− _ -> []
83−
84−newtype Tag = Tag { fromTag :: String }
85− deriving (Show, Eq)
8676
8777-- | Create a tag containing the given string.
8878toTag :: String -> Tag
@@ -117,6 +107,7 @@ data Headline = Headline
117107 , headlineTodoMarker :: Maybe TodoMarker
118108 , headlineText :: Inlines
119109 , headlineTags :: [Tag]
110+ , headlinePlanning :: PlanningInfo -- ^ subtree planning information
120111 , headlineProperties :: Properties
121112 , headlineContents :: Blocks
122113 , headlineChildren :: [Headline]
@@ -136,6 +127,7 @@ headline blocks inline lvl = try $ do
136127 title <- trimInlinesF . mconcat <$> manyTill inline endOfTitle
137128 tags <- option [] headerTags
138129 newline
130+ planning <- option emptyPlanning planningInfo
139131 properties <- option mempty propertiesDrawer
140132 contents <- blocks
141133 children <- many (headline blocks inline (level + 1))
@@ -148,6 +140,7 @@ headline blocks inline lvl = try $ do
148140 , headlineTodoMarker = todoKw
149141 , headlineText = title'
150142 , headlineTags = tags
143+ , headlinePlanning = planning
151144 , headlineProperties = properties
152145 , headlineContents = contents'
153146 , headlineChildren = children'
@@ -158,22 +151,27 @@ headline blocks inline lvl = try $ do
158151
159152 headerTags :: Monad m => OrgParser m [Tag]
160153 headerTags = try $
161− let tag = many1 (alphaNum <|> oneOf "@%#_") <* char ':'
154+ let tag = orgTagWord <* char ':'
162155 in map toTag <$> (skipSpaces *> char ':' *> many1 tag <* skipSpaces)
163156
164157-- | Convert an Org mode headline (i.e. a document tree) into pandoc's Blocks
165158headlineToBlocks :: Monad m => Headline -> OrgParser m Blocks
166−headlineToBlocks hdln@Headline {..} = do
167− maxHeadlineLevels <- getExportSetting exportHeadlineLevels
159+headlineToBlocks hdln = do
160+ maxLevel <- getExportSetting exportHeadlineLevels
161+ let tags = headlineTags hdln
162+ let text = headlineText hdln
163+ let level = headlineLevel hdln
164+ shouldNotExport <- hasDoNotExportTag tags
168165 case () of
169− _ | any isNoExportTag headlineTags -> return mempty
170− _ | any isArchiveTag headlineTags -> archivedHeadlineToBlocks hdln
171− _ | isCommentTitle headlineText -> return mempty
172− _ | headlineLevel >= maxHeadlineLevels -> headlineToHeaderWithList hdln
173− _ | otherwise -> headlineToHeaderWithContents hdln
166+ _ | shouldNotExport -> return mempty
167+ _ | any isArchiveTag tags -> archivedHeadlineToBlocks hdln
168+ _ | isCommentTitle text -> return mempty
169+ _ | maxLevel <= level -> headlineToHeaderWithList hdln
170+ _ | otherwise -> headlineToHeaderWithContents hdln
174171
175−isNoExportTag :: Tag -> Bool
176−isNoExportTag = (== toTag "noexport")
172+hasDoNotExportTag :: Monad m => [Tag] -> OrgParser m Bool
173+hasDoNotExportTag tags = containsExcludedTag . orgStateExcludedTags <$> getState
174+ where containsExcludedTag s = any (`Set.member` s) tags
177175
178176isArchiveTag :: Tag -> Bool
179177isArchiveTag = (== toTag "ARCHIVE")
@@ -182,8 +180,9 @@ isArchiveTag = (== toTag "ARCHIVE")
182180-- FIXME: This accesses builder internals not intended for use in situations
183181-- like these. Replace once keyword parsing is supported.
184182isCommentTitle :: Inlines -> Bool
185−isCommentTitle (B.toList -> (Str "COMMENT":_)) = True
186−isCommentTitle _ = False
183+isCommentTitle inlns = case B.toList inlns of
184+ (Str "COMMENT":_) -> True
185+ _ -> False
187186
188187archivedHeadlineToBlocks :: Monad m => Headline -> OrgParser m Blocks
189188archivedHeadlineToBlocks hdln = do
@@ -194,17 +193,23 @@ archivedHeadlineToBlocks hdln = do
194193 ArchivedTreesHeadlineOnly -> headlineToHeader hdln
195194
196195headlineToHeaderWithList :: Monad m => Headline -> OrgParser m Blocks
197−headlineToHeaderWithList hdln@Headline {..} = do
196+headlineToHeaderWithList hdln = do
198197 maxHeadlineLevels <- getExportSetting exportHeadlineLevels
199198 header <- headlineToHeader hdln
200− listElements <- mapM headlineToBlocks headlineChildren
199+ listElements <- mapM headlineToBlocks (headlineChildren hdln)
200+ planningBlock <- planningToBlock (headlinePlanning hdln)
201201 let listBlock = if null listElements
202202 then mempty
203203 else B.orderedList listElements
204− let headerText = if maxHeadlineLevels == headlineLevel
204+ let headerText = if maxHeadlineLevels == headlineLevel hdln
205205 then header
206206 else flattenHeader header
207− return $ headerText <> headlineContents <> listBlock
207+ return . mconcat $
208+ [ headerText
209+ , headlineContents hdln
210+ , planningBlock
211+ , listBlock
212+ ]
208213 where
209214 flattenHeader :: Blocks -> Blocks
210215 flattenHeader blks =
@@ -213,27 +218,28 @@ headlineToHeaderWithList hdln@Headline {..} = do
213218 _ -> mempty
214219
215220headlineToHeaderWithContents :: Monad m => Headline -> OrgParser m Blocks
216−headlineToHeaderWithContents hdln@Headline {..} = do
221+headlineToHeaderWithContents hdln = do
217222 header <- headlineToHeader hdln
218− childrenBlocks <- mconcat <$> mapM headlineToBlocks headlineChildren
219− return $ header <> headlineContents <> childrenBlocks
223+ planningBlock <- planningToBlock (headlinePlanning hdln)
224+ childrenBlocks <- mconcat <$> mapM headlineToBlocks (headlineChildren hdln)
225+ return $ header <> planningBlock <> headlineContents hdln <> childrenBlocks
220226
221227headlineToHeader :: Monad m => Headline -> OrgParser m Blocks
222−headlineToHeader Headline {..} = do
228+headlineToHeader hdln = do
223229 exportTodoKeyword <- getExportSetting exportWithTodoKeywords
224230 exportTags <- getExportSetting exportWithTags
225231 let todoText = if exportTodoKeyword
226− then case headlineTodoMarker of
232+ then case headlineTodoMarker hdln of
227233 Just kw -> todoKeywordToInlines kw <> B.space
228234 Nothing -> mempty
229235 else mempty
230− let text = todoText <> headlineText <>
236+ let text = todoText <> headlineText hdln <>
231237 if exportTags
232− then tagsToInlines headlineTags
238+ then tagsToInlines (headlineTags hdln)
233239 else mempty
234− let propAttr = propertiesToAttr headlineProperties
235− attr <- registerHeader propAttr headlineText
236− return $ B.headerWith attr headlineLevel text
240+ let propAttr = propertiesToAttr (headlineProperties hdln)
241+ attr <- registerHeader propAttr (headlineText hdln)
242+ return $ B.headerWith attr (headlineLevel hdln) text
237243
238244todoKeyword :: Monad m => OrgParser m TodoMarker
239245todoKeyword = try $ do
@@ -277,9 +283,60 @@ tagsToInlines tags =
277283tagSpan :: Tag -> Inlines -> Inlines
278284tagSpan t = B.spanWith ("", ["tag"], [("tag-name", fromTag t)])
279285
286+-- | Render planning info as a block iff the respective export setting is
287+-- enabled.
288+planningToBlock :: Monad m => PlanningInfo -> OrgParser m Blocks
289+planningToBlock planning = do
290+ includePlanning <- getExportSetting exportWithPlanning
291+ return $
292+ if includePlanning
293+ then B.plain . mconcat . intersperse B.space . filter (/= mempty) $
294+ [ datumInlines planningClosed "CLOSED"
295+ , datumInlines planningDeadline "DEADLINE"
296+ , datumInlines planningScheduled "SCHEDULED"
297+ ]
298+ else mempty
299+ where
300+ datumInlines field name =
301+ case field planning of
302+ Nothing -> mempty
303+ Just time -> B.strong (B.str name <> B.str ":")
304+ <> B.space
305+ <> B.emph (B.str time)
306+
307+-- | An Org timestamp, including repetition marks. TODO: improve
308+type Timestamp = String
309+
310+timestamp :: Monad m => OrgParser m Timestamp
311+timestamp = try $ do
312+ openChar <- oneOf "<["
313+ let isActive = openChar == '<'
314+ let closeChar = if isActive then '>' else ']'
315+ content <- many1Till anyChar (char closeChar)
316+ return (openChar : content ++ [closeChar])
317+
318+-- | Planning information for a subtree/headline.
319+data PlanningInfo = PlanningInfo
320+ { planningClosed :: Maybe Timestamp
321+ , planningDeadline :: Maybe Timestamp
322+ , planningScheduled :: Maybe Timestamp
323+ }
280324
325+emptyPlanning :: PlanningInfo
326+emptyPlanning = PlanningInfo Nothing Nothing Nothing
281327
282−
328+-- | Read a single planning-related and timestamped line.
329+planningInfo :: Monad m => OrgParser m PlanningInfo
330+planningInfo = try $ do
331+ updaters <- many1 planningDatum <* skipSpaces <* newline
332+ return $ foldr ($) emptyPlanning updaters
333+ where
334+ planningDatum = skipSpaces *> choice
335+ [ updateWith (\s p -> p { planningScheduled = Just s}) "SCHEDULED"
336+ , updateWith (\d p -> p { planningDeadline = Just d}) "DEADLINE"
337+ , updateWith (\c p -> p { planningClosed = Just c}) "CLOSED"
338+ ]
339+ updateWith fn cs = fn <$> (string cs *> char ':' *> skipSpaces *> timestamp)
283340
284341-- | Read a :PROPERTIES: drawer and return the key/value pairs contained
285342-- within.
src/Text/Pandoc/Readers/Org/ExportSettings.hs+1−1
@@ -69,7 +69,7 @@ exportSetting = choice
6969 , integerSetting "H" (\val es -> es { exportHeadlineLevels = val })
7070 , ignoredSetting "inline"
7171 , ignoredSetting "num"
72− , ignoredSetting "p"
72+ , booleanSetting "p" (\val es -> es { exportWithPlanning = val })
7373 , ignoredSetting "pri"
7474 , ignoredSetting "prop"
7575 , ignoredSetting "stat"
src/Text/Pandoc/Readers/Org/Inlines.hs+6−4
@@ -39,7 +39,7 @@ import Text.Pandoc.Readers.Org.BlockStarts (endOfBlock, noteMarker)
3939import Text.Pandoc.Readers.Org.ParserState
4040import Text.Pandoc.Readers.Org.Parsing
4141import Text.Pandoc.Readers.Org.Shared (cleanLinkString, isImageFilename,
42− originalLang, translateLang)
42+ originalLang, translateLang, exportsCode)
4343
4444import Text.Pandoc.Builder (Inlines)
4545import qualified Text.Pandoc.Builder as B
@@ -510,7 +510,7 @@ anchor = try $ do
510510 <* string ">>"
511511 <* skipSpaces
512512
513−-- | Replace every char but [a-zA-Z0-9_.-:] with a hypen '-'. This mirrors
513+-- | Replace every char but [a-zA-Z0-9_.-:] with a hyphen '-'. This mirrors
514514-- the org function @org-export-solidify-link-text@.
515515
516516solidify :: String -> String
@@ -525,11 +525,13 @@ inlineCodeBlock :: PandocMonad m => OrgParser m (F Inlines)
525525inlineCodeBlock = try $ do
526526 string "src_"
527527 lang <- many1 orgArgWordChar
528− opts <- option [] $ enclosedByPair '[' ']' inlineBlockOption
528+ opts <- option [] $ try (enclosedByPair '[' ']' inlineBlockOption)
529+ <|> (mempty <$ string "[]")
529530 inlineCode <- enclosedByPair '{' '}' (noneOf "\n\r")
530531 let attrClasses = [translateLang lang]
531532 let attrKeyVal = originalLang lang <> opts
532− returnF $ B.codeWith ("", attrClasses, attrKeyVal) inlineCode
533+ let codeInlineBlck = B.codeWith ("", attrClasses, attrKeyVal) inlineCode
534+ returnF $ (if exportsCode opts then codeInlineBlck else mempty)
533535 where
534536 inlineBlockOption :: PandocMonad m => OrgParser m (String, String)
535537 inlineBlockOption = try $ do
src/Text/Pandoc/Readers/Org/Meta.hs+14
@@ -52,6 +52,7 @@ import Data.Char (toLower)
5252import Data.List (intersperse)
5353import Data.Maybe (fromMaybe)
5454import qualified Data.Map as M
55+import qualified Data.Set as Set
5556import Network.HTTP (urlEncode)
5657
5758-- | Returns the current meta, respecting export options.
@@ -158,6 +159,7 @@ optionLine = try $ do
158159 "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
159160 "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
160161 "macro" -> macroDefinition >>= updateState . registerMacro
162+ "exclude_tags" -> excludedTagList >>= updateState . setExcludedTags
161163 "pandoc-emphasis-pre" -> emphChars >>= updateState . setEmphasisPreChar
162164 "pandoc-emphasis-post" -> emphChars >>= updateState . setEmphasisPostChar
163165 _ -> mzero
@@ -190,6 +192,18 @@ parseFormat = try $ replacePlain <|> replaceUrl <|> justAppend
190192 rest = manyTill anyChar (eof <|> () <$ oneOf "\n\r")
191193 tillSpecifier c = manyTill (noneOf "\n\r") (try $ string ('%':c:""))
192194
195+excludedTagList :: Monad m => OrgParser m [Tag]
196+excludedTagList = do
197+ skipSpaces
198+ map Tag <$> many (orgTagWord <* skipSpaces) <* newline
199+
200+setExcludedTags :: [Tag] -> OrgParserState -> OrgParserState
201+setExcludedTags tagList st =
202+ let finalSet = if orgStateExcludedTagsChanged st
203+ then foldr Set.insert (orgStateExcludedTags st) tagList
204+ else Set.fromList tagList
205+ in st { orgStateExcludedTags = finalSet, orgStateExcludedTagsChanged = True}
206+
193207setEmphasisPreChar :: Maybe [Char] -> OrgParserState -> OrgParserState
194208setEmphasisPreChar csMb st =
195209 let preChars = fromMaybe (orgStateEmphasisPostChars defaultOrgParserState) csMb
src/Text/Pandoc/Readers/Org/ParserState.hs+10
@@ -33,6 +33,7 @@ module Text.Pandoc.Readers.Org.ParserState
3333 , defaultOrgParserState
3434 , OrgParserLocal (..)
3535 , OrgNoteRecord
36+ , Tag(..)
3637 , HasReaderOptions (..)
3738 , HasQuoteContext (..)
3839 , HasMacros (..)
@@ -88,6 +89,9 @@ type OrgNoteTable = [OrgNoteRecord]
8889type OrgLinkFormatters = M.Map String (String -> String)
8990-- | Macro expander function
9091type MacroExpander = [String] -> String
92+-- | Tag
93+newtype Tag = Tag { fromTag :: String }
94+ deriving (Show, Eq, Ord)
9195
9296-- | The states in which a todo item can be
9397data TodoState = Todo | Done
@@ -113,6 +117,8 @@ data OrgParserState = OrgParserState
113117 -- specified here.
114118 , orgStateEmphasisPostChars :: [Char] -- ^ Chars allowed at after emphasis
115119 , orgStateEmphasisNewlines :: Maybe Int
120+ , orgStateExcludedTags :: Set.Set Tag
121+ , orgStateExcludedTagsChanged :: Bool
116122 , orgStateExportSettings :: ExportSettings
117123 , orgStateHeaderMap :: M.Map Inlines String
118124 , orgStateIdentifiers :: Set.Set String
@@ -183,6 +189,8 @@ defaultOrgParserState = OrgParserState
183189 , orgStateEmphasisCharStack = []
184190 , orgStateEmphasisNewlines = Nothing
185191 , orgStateExportSettings = def
192+ , orgStateExcludedTags = Set.singleton $ Tag "noexport"
193+ , orgStateExcludedTagsChanged = False
186194 , orgStateHeaderMap = M.empty
187195 , orgStateIdentifiers = Set.empty
188196 , orgStateIncludeFiles = []
@@ -260,6 +268,7 @@ data ExportSettings = ExportSettings
260268 , exportWithAuthor :: Bool -- ^ Include author in final meta-data
261269 , exportWithCreator :: Bool -- ^ Include creator in final meta-data
262270 , exportWithEmail :: Bool -- ^ Include email in final meta-data
271+ , exportWithPlanning :: Bool -- ^ Keep planning info after headlines
263272 , exportWithTags :: Bool -- ^ Keep tags as part of headlines
264273 , exportWithTodoKeywords :: Bool -- ^ Keep TODO keywords in headers
265274 }
@@ -280,6 +289,7 @@ defaultExportSettings = ExportSettings
280289 , exportWithAuthor = True
281290 , exportWithCreator = True
282291 , exportWithEmail = True
292+ , exportWithPlanning = False
283293 , exportWithTags = True
284294 , exportWithTodoKeywords = True
285295 }
src/Text/Pandoc/Readers/Org/Parsing.hs+11−4
@@ -46,6 +46,8 @@ module Text.Pandoc.Readers.Org.Parsing
4646 , orgArgKey
4747 , orgArgWord
4848 , orgArgWordChar
49+ , orgTagWord
50+ , orgTagWordChar
4951 -- * Re-exports from Text.Pandoc.Parser
5052 , ParserContext (..)
5153 , many1Till
@@ -137,14 +139,13 @@ anyLine =
137139 <* updateLastPreCharPos
138140 <* updateLastForbiddenCharPos
139141
140−-- The version Text.Pandoc.Parsing cannot be used, as we need additional parts
141−-- of the state saved and restored.
142+-- | Like @'Text.Pandoc.Parsing'@, but resets the position of the last character
143+-- allowed before emphasised text.
142144parseFromString :: Monad m => OrgParser m a -> String -> OrgParser m a
143145parseFromString parser str' = do
144− oldLastPreCharPos <- orgStateLastPreCharPos <$> getState
145146 updateState $ \s -> s{ orgStateLastPreCharPos = Nothing }
146147 result <- P.parseFromString parser str'
147− updateState $ \s -> s{ orgStateLastPreCharPos = oldLastPreCharPos }
148+ updateState $ \s -> s { orgStateLastPreCharPos = Nothing }
148149 return result
149150
150151-- | Skip one or more tab or space characters.
@@ -221,3 +222,9 @@ orgArgWord = many1 orgArgWordChar
221222-- | Chars treated as part of a word in plists.
222223orgArgWordChar :: Monad m => OrgParser m Char
223224orgArgWordChar = alphaNum <|> oneOf "-_"
225+
226+orgTagWord :: Monad m => OrgParser m String
227+orgTagWord = many1 orgTagWordChar
228+
229+orgTagWordChar :: Monad m => OrgParser m Char
230+orgTagWordChar = alphaNum <|> oneOf "@%#_"
src/Text/Pandoc/Readers/Org/Shared.hs+4
@@ -32,6 +32,7 @@ module Text.Pandoc.Readers.Org.Shared
3232 , isImageFilename
3333 , originalLang
3434 , translateLang
35+ , exportsCode
3536 ) where
3637
3738import Prelude
@@ -96,3 +97,6 @@ translateLang cs =
9697 "sh" -> "bash"
9798 "sqlite" -> "sql"
9899 _ -> cs
100+
101+exportsCode :: [(String, String)] -> Bool
102+exportsCode = maybe True (`elem` ["code", "both"]) . lookup "exports"
src/Text/Pandoc/Readers/RST.hs+45−23
@@ -37,7 +37,7 @@ import Control.Arrow (second)
3737import Control.Monad (forM_, guard, liftM, mplus, mzero, when)
3838import Control.Monad.Except (throwError)
3939import Control.Monad.Identity (Identity (..))
40−import Data.Char (isHexDigit, isSpace, toLower, toUpper)
40+import Data.Char (isHexDigit, isSpace, toLower, toUpper, isAlphaNum)
4141import Data.List (deleteFirstsBy, elemIndex, intercalate, isInfixOf, isSuffixOf,
4242 nub, sort, transpose, union)
4343import qualified Data.Map as M
@@ -172,6 +172,7 @@ parseRST = do
172172 docMinusKeys <- concat <$>
173173 manyTill (referenceKey <|> anchorDef <|>
174174 noteBlock <|> citationBlock <|>
175+ (snd <$> withRaw comment) <|>
175176 headerBlock <|> lineClump) eof
176177 setInput docMinusKeys
177178 setPosition startPos
@@ -1089,7 +1090,7 @@ referenceKey = do
10891090targetURI :: Monad m => ParserT [Char] st m [Char]
10901091targetURI = do
10911092 skipSpaces
1092− optional newline
1093+ optional $ try $ newline >> notFollowedBy blankline
10931094 contents <- trim <$>
10941095 many1 (satisfy (/='\n')
10951096 <|> try (newline >> many1 spaceChar >> noneOf " \t\n"))
@@ -1313,19 +1314,24 @@ table = gridTable False <|> simpleTable False <|>
13131314
13141315inline :: PandocMonad m => RSTParser m Inlines
13151316inline = choice [ note -- can start with whitespace, so try before ws
1316− , whitespace
13171317 , link
1318− , str
1319− , endline
13201318 , strong
13211319 , emph
13221320 , code
13231321 , subst
13241322 , interpretedRole
1325− , smart
1326− , hyphens
1327− , escapedChar
1328− , symbol ] <?> "inline"
1323+ , inlineContent ] <?> "inline"
1324+
1325+-- strings, spaces and other characters that can appear either by
1326+-- themselves or within inline markup
1327+inlineContent :: PandocMonad m => RSTParser m Inlines
1328+inlineContent = choice [ whitespace
1329+ , str
1330+ , endline
1331+ , smart
1332+ , hyphens
1333+ , escapedChar
1334+ , symbol ] <?> "inline content"
13291335
13301336parseInlineFromString :: PandocMonad m => String -> RSTParser m Inlines
13311337parseInlineFromString = parseFromString' (trimInlines . mconcat <$> many inline)
@@ -1368,11 +1374,11 @@ atStart p = do
13681374
13691375emph :: PandocMonad m => RSTParser m Inlines
13701376emph = B.emph . trimInlines . mconcat <$>
1371− enclosed (atStart $ char '*') (char '*') inline
1377+ enclosed (atStart $ char '*') (char '*') inlineContent
13721378
13731379strong :: PandocMonad m => RSTParser m Inlines
13741380strong = B.strong . trimInlines . mconcat <$>
1375− enclosed (atStart $ string "**") (try $ string "**") inline
1381+ enclosed (atStart $ string "**") (try $ string "**") inlineContent
13761382
13771383-- Note, this doesn't precisely implement the complex rule in
13781384-- http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
@@ -1380,7 +1386,6 @@ strong = B.strong . trimInlines . mconcat <$>
13801386--
13811387-- TODO:
13821388-- - Classes are silently discarded in addNewRole
1383−-- - Lacks sensible implementation for title-reference (which is the default)
13841389-- - Allows direct use of the :raw: role, rST only allows inherited use.
13851390interpretedRole :: PandocMonad m => RSTParser m Inlines
13861391interpretedRole = try $ do
@@ -1390,12 +1395,12 @@ interpretedRole = try $ do
13901395renderRole :: PandocMonad m
13911396 => String -> Maybe String -> String -> Attr -> RSTParser m Inlines
13921397renderRole contents fmt role attr = case role of
1393− "sup" -> return $ B.superscript $ B.str contents
1394− "superscript" -> return $ B.superscript $ B.str contents
1395− "sub" -> return $ B.subscript $ B.str contents
1396− "subscript" -> return $ B.subscript $ B.str contents
1397− "emphasis" -> return $ B.emph $ B.str contents
1398− "strong" -> return $ B.strong $ B.str contents
1398+ "sup" -> return $ B.superscript $ treatAsText contents
1399+ "superscript" -> return $ B.superscript $ treatAsText contents
1400+ "sub" -> return $ B.subscript $ treatAsText contents
1401+ "subscript" -> return $ B.subscript $ treatAsText contents
1402+ "emphasis" -> return $ B.emph $ treatAsText contents
1403+ "strong" -> return $ B.strong $ treatAsText contents
13991404 "rfc-reference" -> return $ rfcLink contents
14001405 "RFC" -> return $ rfcLink contents
14011406 "pep-reference" -> return $ pepLink contents
@@ -1406,7 +1411,7 @@ renderRole contents fmt role attr = case role of
14061411 "title" -> titleRef contents
14071412 "t" -> titleRef contents
14081413 "code" -> return $ B.codeWith (addClass "sourceCode" attr) contents
1409− "span" -> return $ B.spanWith attr $ B.str contents
1414+ "span" -> return $ B.spanWith attr $ treatAsText contents
14101415 "raw" -> return $ B.rawInline (fromMaybe "" fmt) contents
14111416 custom -> do
14121417 customRoles <- stateRstCustomRoles <$> getState
@@ -1414,14 +1419,20 @@ renderRole contents fmt role attr = case role of
14141419 Just (newRole, newFmt, newAttr) ->
14151420 renderRole contents newFmt newRole newAttr
14161421 Nothing -> -- undefined role
1417− return $ B.spanWith ("",[],[("role",role)]) (B.str contents)
1422+ return $ B.codeWith ("",["interpreted-text"],[("role",role)])
1423+ contents
14181424 where
1419− titleRef ref = return $ B.str ref -- FIXME: Not a sensible behaviour
1425+ titleRef ref = return $ B.spanWith ("",["title-ref"],[]) $ treatAsText ref
14201426 rfcLink rfcNo = B.link rfcUrl ("RFC " ++ rfcNo) $ B.str ("RFC " ++ rfcNo)
14211427 where rfcUrl = "http://www.faqs.org/rfcs/rfc" ++ rfcNo ++ ".html"
14221428 pepLink pepNo = B.link pepUrl ("PEP " ++ pepNo) $ B.str ("PEP " ++ pepNo)
14231429 where padNo = replicate (4 - length pepNo) '0' ++ pepNo
14241430 pepUrl = "http://www.python.org/dev/peps/pep-" ++ padNo ++ "/"
1431+ treatAsText = B.text . handleEscapes
1432+ handleEscapes [] = []
1433+ handleEscapes ('\\':' ':cs) = handleEscapes cs
1434+ handleEscapes ('\\':c:cs) = c : handleEscapes cs
1435+ handleEscapes (c:cs) = c : handleEscapes cs
14251436
14261437addClass :: String -> Attr -> Attr
14271438addClass c (ident, classes, keyValues) = (ident, classes `union` [c], keyValues)
@@ -1445,7 +1456,18 @@ roleAfter = try $ do
14451456 return (role,contents)
14461457
14471458unmarkedInterpretedText :: PandocMonad m => RSTParser m [Char]
1448−unmarkedInterpretedText = enclosed (atStart $ char '`') (char '`') anyChar
1459+unmarkedInterpretedText = try $ do
1460+ atStart (char '`')
1461+ contents <- mconcat <$> (many1
1462+ ( many1 (noneOf "`\\\n")
1463+ <|> (char '\\' >> ((\c -> ['\\',c]) <$> noneOf "\n"))
1464+ <|> (string "\n" <* notFollowedBy blankline)
1465+ <|> try (string "`" <*
1466+ notFollowedBy (() <$ roleMarker) <*
1467+ lookAhead (satisfy isAlphaNum))
1468+ ))
1469+ char '`'
1470+ return contents
14491471
14501472whitespace :: PandocMonad m => RSTParser m Inlines
14511473whitespace = B.space <$ skipMany1 spaceChar <?> "whitespace"
@@ -1480,7 +1502,7 @@ explicitLink = try $ do
14801502 char '`'
14811503 notFollowedBy (char '`') -- `` marks start of inline code
14821504 label' <- trimInlines . mconcat <$>
1483− manyTill (notFollowedBy (char '`') >> inline) (char '<')
1505+ manyTill (notFollowedBy (char '`') >> inlineContent) (char '<')
14841506 src <- trim <$> manyTill (noneOf ">\n") (char '>')
14851507 skipSpaces
14861508 string "`_"
src/Text/Pandoc/Readers/TWiki.hs+50−61
@@ -74,9 +74,6 @@ type TWParser = ParserT [Char] ParserState
7474tryMsg :: String -> TWParser m a -> TWParser m a
7575tryMsg msg p = try p <?> msg
7676
77−skip :: TWParser m a -> TWParser m ()
78−skip parser = parser >> return ()
79−
8077nested :: PandocMonad m => TWParser m a -> TWParser m a
8178nested p = do
8279 nestlevel <- stateMaxNestingLevel <$> getState
@@ -92,7 +89,7 @@ htmlElement tag = tryMsg tag $ do
9289 content <- manyTill anyChar (endtag <|> endofinput)
9390 return (htmlAttrToPandoc attr, trim content)
9491 where
95− endtag = skip $ htmlTag (~== TagClose tag)
92+ endtag = void $ htmlTag (~== TagClose tag)
9693 endofinput = lookAhead $ try $ skipMany blankline >> skipSpaces >> eof
9794 trim = dropWhile (=='\n') . reverse . dropWhile (=='\n') . reverse
9895
@@ -114,18 +111,15 @@ parseHtmlContentWithAttrs tag parser = do
114111 endOfContent = try $ skipMany blankline >> skipSpaces >> eof
115112
116113parseHtmlContent :: PandocMonad m => String -> TWParser m a -> TWParser m [a]
117−parseHtmlContent tag p = parseHtmlContentWithAttrs tag p >>= return . snd
114+parseHtmlContent tag p = snd <$> parseHtmlContentWithAttrs tag p
118115
119116--
120117-- main parser
121118--
122119
123120parseTWiki :: PandocMonad m => TWParser m Pandoc
124−parseTWiki = do
125− bs <- mconcat <$> many block
126− spaces
127− eof
128− return $ B.doc bs
121+parseTWiki =
122+ B.doc . mconcat <$> many block <* spaces <* eof
129123
130124
131125--
@@ -158,7 +152,7 @@ separator = tryMsg "separator" $ string "---" >> newline >> return B.horizontalR
158152header :: PandocMonad m => TWParser m B.Blocks
159153header = tryMsg "header" $ do
160154 string "---"
161− level <- many1 (char '+') >>= return . length
155+ level <- length <$> many1 (char '+')
162156 guard $ level <= 6
163157 classes <- option [] $ string "!!" >> return ["unnumbered"]
164158 skipSpaces
@@ -167,11 +161,10 @@ header = tryMsg "header" $ do
167161 return $ B.headerWith attr level content
168162
169163verbatim :: PandocMonad m => TWParser m B.Blocks
170−verbatim = (htmlElement "verbatim" <|> htmlElement "pre")
171− >>= return . (uncurry B.codeBlockWith)
164+verbatim = uncurry B.codeBlockWith <$> (htmlElement "verbatim" <|> htmlElement "pre")
172165
173166literal :: PandocMonad m => TWParser m B.Blocks
174−literal = htmlElement "literal" >>= return . rawBlock
167+literal = rawBlock <$> htmlElement "literal"
175168 where
176169 format (_, _, kvs) = fromMaybe "html" $ lookup "format" kvs
177170 rawBlock (attrs, content) = B.rawBlock (format attrs) content
@@ -183,7 +176,7 @@ list prefix = choice [ bulletList prefix
183176
184177definitionList :: PandocMonad m => String -> TWParser m B.Blocks
185178definitionList prefix = tryMsg "definitionList" $ do
186− indent <- lookAhead $ string prefix *> (many1 $ string " ") <* string "$ "
179+ indent <- lookAhead $ string prefix *> many1 (string " ") <* string "$ "
187180 elements <- many $ parseDefinitionListItem (prefix ++ concat indent)
188181 return $ B.definitionList elements
189182 where
@@ -193,7 +186,7 @@ definitionList prefix = tryMsg "definitionList" $ do
193186 string (indent ++ "$ ") >> skipSpaces
194187 term <- many1Till inline $ string ": "
195188 line <- listItemLine indent $ string "$ "
196− return $ (mconcat term, [line])
189+ return (mconcat term, [line])
197190
198191bulletList :: PandocMonad m => String -> TWParser m B.Blocks
199192bulletList prefix = tryMsg "bulletList" $
@@ -227,25 +220,24 @@ parseListItem prefix marker = string prefix >> marker >> listItemLine prefix mar
227220
228221listItemLine :: (PandocMonad m, Show a)
229222 => String -> TWParser m a -> TWParser m B.Blocks
230−listItemLine prefix marker = lineContent >>= parseContent >>= return . mconcat
223+listItemLine prefix marker = mconcat <$> (lineContent >>= parseContent)
231224 where
232225 lineContent = do
233226 content <- anyLine
234227 continuation <- optionMaybe listContinuation
235− return $ filterSpaces content ++ "\n" ++ (maybe "" (" " ++) continuation)
228+ return $ filterSpaces content ++ "\n" ++ maybe "" (" " ++) continuation
236229 filterSpaces = reverse . dropWhile (== ' ') . reverse
237230 listContinuation = notFollowedBy (string prefix >> marker) >>
238231 string " " >> lineContent
239232 parseContent = parseFromString' $ many1 $ nestedList <|> parseInline
240− parseInline = many1Till inline (lastNewline <|> newlineBeforeNestedList) >>=
241− return . B.plain . mconcat
233+ parseInline = (B.plain . mconcat) <$> many1Till inline (lastNewline <|> newlineBeforeNestedList)
242234 nestedList = list prefix
243235 lastNewline = try $ char '\n' <* eof
244236 newlineBeforeNestedList = try $ char '\n' <* lookAhead nestedList
245237
246238table :: PandocMonad m => TWParser m B.Blocks
247239table = try $ do
248− tableHead <- optionMaybe $ many1Till tableParseHeader newline >>= return . unzip
240+ tableHead <- optionMaybe (unzip <$> many1Till tableParseHeader newline)
249241 rows <- many1 tableParseRow
250242 return $ buildTable mempty rows $ fromMaybe (align rows, columns rows) tableHead
251243 where
@@ -258,11 +250,11 @@ table = try $ do
258250tableParseHeader :: PandocMonad m => TWParser m ((Alignment, Double), B.Blocks)
259251tableParseHeader = try $ do
260252 char '|'
261− leftSpaces <- many spaceChar >>= return . length
253+ leftSpaces <- length <$> many spaceChar
262254 char '*'
263255 content <- tableColumnContent (char '*' >> skipSpaces >> char '|')
264256 char '*'
265− rightSpaces <- many spaceChar >>= return . length
257+ rightSpaces <- length <$> many spaceChar
266258 optional tableEndOfRow
267259 return (tableAlign leftSpaces rightSpaces, content)
268260 where
@@ -283,13 +275,13 @@ tableEndOfRow :: PandocMonad m => TWParser m Char
283275tableEndOfRow = lookAhead (try $ char '|' >> char '\n') >> char '|'
284276
285277tableColumnContent :: PandocMonad m => TWParser m a -> TWParser m B.Blocks
286−tableColumnContent end = manyTill content (lookAhead $ try end) >>= return . B.plain . mconcat
278+tableColumnContent end = (B.plain . mconcat) <$> manyTill content (lookAhead $ try end)
287279 where
288280 content = continuation <|> inline
289281 continuation = try $ char '\\' >> newline >> return mempty
290282
291283blockQuote :: PandocMonad m => TWParser m B.Blocks
292−blockQuote = parseHtmlContent "blockquote" block >>= return . B.blockQuote . mconcat
284+blockQuote = (B.blockQuote . mconcat) <$> parseHtmlContent "blockquote" block
293285
294286noautolink :: PandocMonad m => TWParser m B.Blocks
295287noautolink = do
@@ -300,15 +292,15 @@ noautolink = do
300292 setState $ st{ stateAllowLinks = True }
301293 return $ mconcat blocks
302294 where
303− parseContent = parseFromString' $ many $ block
295+ parseContent = parseFromString' $ many block
304296
305297para :: PandocMonad m => TWParser m B.Blocks
306−para = many1Till inline endOfParaElement >>= return . result . mconcat
298+para = (result . mconcat) <$> many1Till inline endOfParaElement
307299 where
308300 endOfParaElement = lookAhead $ endOfInput <|> endOfPara <|> newBlockElement
309301 endOfInput = try $ skipMany blankline >> skipSpaces >> eof
310302 endOfPara = try $ blankline >> skipMany1 blankline
311− newBlockElement = try $ blankline >> skip blockElements
303+ newBlockElement = try $ blankline >> void blockElements
312304 result content = if F.all (==Space) content
313305 then mempty
314306 else B.para $ B.trimInlines content
@@ -340,7 +332,7 @@ inline = choice [ whitespace
340332 ] <?> "inline"
341333
342334whitespace :: PandocMonad m => TWParser m B.Inlines
343−whitespace = (lb <|> regsp) >>= return
335+whitespace = lb <|> regsp
344336 where lb = try $ skipMany spaceChar >> linebreak >> return B.space
345337 regsp = try $ skipMany1 spaceChar >> return B.space
346338
@@ -362,13 +354,13 @@ enclosed :: (Monoid b, PandocMonad m, Show a)
362354 => TWParser m a -> (TWParser m a -> TWParser m b) -> TWParser m b
363355enclosed sep p = between sep (try $ sep <* endMarker) p
364356 where
365− endMarker = lookAhead $ skip endSpace <|> skip (oneOf ".,!?:)|") <|> eof
357+ endMarker = lookAhead $ void endSpace <|> void (oneOf ".,!?:)|") <|> eof
366358 endSpace = (spaceChar <|> newline) >> return B.space
367359
368360macro :: PandocMonad m => TWParser m B.Inlines
369361macro = macroWithParameters <|> withoutParameters
370362 where
371− withoutParameters = enclosed (char '%') (\_ -> macroName) >>= return . emptySpan
363+ withoutParameters = emptySpan <$> enclosed (char '%') (const macroName)
372364 emptySpan name = buildSpan name [] mempty
373365
374366macroWithParameters :: PandocMonad m => TWParser m B.Inlines
@@ -393,13 +385,13 @@ macroName = do
393385 return (first:rest)
394386
395387attributes :: PandocMonad m => TWParser m (String, [(String, String)])
396−attributes = char '{' *> spnl *> many (attribute <* spnl) <* char '}' >>=
397− return . foldr (either mkContent mkKvs) ([], [])
388+attributes = foldr (either mkContent mkKvs) ([], [])
389+ <$> (char '{' *> spnl *> many (attribute <* spnl) <* char '}')
398390 where
399391 spnl = skipMany (spaceChar <|> newline)
400392 mkContent c ([], kvs) = (c, kvs)
401393 mkContent c (rest, kvs) = (c ++ " " ++ rest, kvs)
402− mkKvs kv (cont, rest) = (cont, (kv : rest))
394+ mkKvs kv (cont, rest) = (cont, kv : rest)
403395
404396attribute :: PandocMonad m => TWParser m (Either String (String, String))
405397attribute = withKey <|> withoutKey
@@ -407,52 +399,50 @@ attribute = withKey <|> withoutKey
407399 withKey = try $ do
408400 key <- macroName
409401 char '='
410− parseValue False >>= return . (curry Right key)
411− withoutKey = try $ parseValue True >>= return . Left
412− parseValue allowSpaces = (withQuotes <|> withoutQuotes allowSpaces) >>= return . fromEntities
402+ curry Right key <$> parseValue False
403+ withoutKey = try $ Left <$> parseValue True
404+ parseValue allowSpaces = fromEntities <$> (withQuotes <|> withoutQuotes allowSpaces)
413405 withQuotes = between (char '"') (char '"') (\_ -> count 1 $ noneOf ['"'])
414406 withoutQuotes allowSpaces
415− | allowSpaces == True = many1 $ noneOf "}"
416− | otherwise = many1 $ noneOf " }"
407+ | allowSpaces = many1 $ noneOf "}"
408+ | otherwise = many1 $ noneOf " }"
417409
418410nestedInlines :: (Show a, PandocMonad m)
419411 => TWParser m a -> TWParser m B.Inlines
420412nestedInlines end = innerSpace <|> nestedInline
421413 where
422− innerSpace = try $ whitespace <* (notFollowedBy end)
414+ innerSpace = try $ whitespace <* notFollowedBy end
423415 nestedInline = notFollowedBy whitespace >> nested inline
424416
425417strong :: PandocMonad m => TWParser m B.Inlines
426−strong = try $ enclosed (char '*') nestedInlines >>= return . B.strong
418+strong = try $ B.strong <$> enclosed (char '*') nestedInlines
427419
428420strongHtml :: PandocMonad m => TWParser m B.Inlines
429−strongHtml = (parseHtmlContent "strong" inline <|> parseHtmlContent "b" inline)
430− >>= return . B.strong . mconcat
421+strongHtml = B.strong . mconcat <$> (parseHtmlContent "strong" inline <|> parseHtmlContent "b" inline)
431422
432423strongAndEmph :: PandocMonad m => TWParser m B.Inlines
433−strongAndEmph = try $ enclosed (string "__") nestedInlines >>= return . B.emph . B.strong
424+strongAndEmph = try $ B.emph . B.strong <$> enclosed (string "__") nestedInlines
434425
435426emph :: PandocMonad m => TWParser m B.Inlines
436−emph = try $ enclosed (char '_') nestedInlines >>= return . B.emph
427+emph = try $ B.emph <$> enclosed (char '_') nestedInlines
437428
438429emphHtml :: PandocMonad m => TWParser m B.Inlines
439−emphHtml = (parseHtmlContent "em" inline <|> parseHtmlContent "i" inline)
440− >>= return . B.emph . mconcat
430+emphHtml = B.emph . mconcat <$> (parseHtmlContent "em" inline <|> parseHtmlContent "i" inline)
441431
442432nestedString :: (Show a, PandocMonad m)
443433 => TWParser m a -> TWParser m String
444−nestedString end = innerSpace <|> (count 1 nonspaceChar)
434+nestedString end = innerSpace <|> count 1 nonspaceChar
445435 where
446436 innerSpace = try $ many1 spaceChar <* notFollowedBy end
447437
448438boldCode :: PandocMonad m => TWParser m B.Inlines
449−boldCode = try $ enclosed (string "==") nestedString >>= return . B.strong . B.code . fromEntities
439+boldCode = try $ (B.strong . B.code . fromEntities) <$> enclosed (string "==") nestedString
450440
451441htmlComment :: PandocMonad m => TWParser m B.Inlines
452442htmlComment = htmlTag isCommentTag >> return mempty
453443
454444code :: PandocMonad m => TWParser m B.Inlines
455−code = try $ enclosed (char '=') nestedString >>= return . B.code . fromEntities
445+code = try $ (B.code . fromEntities) <$> enclosed (char '=') nestedString
456446
457447codeHtml :: PandocMonad m => TWParser m B.Inlines
458448codeHtml = do
@@ -464,7 +454,7 @@ autoLink = try $ do
464454 state <- getState
465455 guard $ stateAllowLinks state
466456 (text, url) <- parseLink
467− guard $ checkLink (head $ reverse url)
457+ guard $ checkLink (last url)
468458 return $ makeLink (text, url)
469459 where
470460 parseLink = notFollowedBy nop >> (uri <|> emailAddress)
@@ -474,17 +464,17 @@ autoLink = try $ do
474464 | otherwise = isAlphaNum c
475465
476466str :: PandocMonad m => TWParser m B.Inlines
477−str = (many1 alphaNum <|> count 1 characterReference) >>= return . B.str
467+str = B.str <$> (many1 alphaNum <|> count 1 characterReference)
478468
479469nop :: PandocMonad m => TWParser m B.Inlines
480−nop = try $ (skip exclamation <|> skip nopTag) >> followContent
470+nop = try $ (void exclamation <|> void nopTag) >> followContent
481471 where
482472 exclamation = char '!'
483473 nopTag = stringAnyCase "<nop>"
484− followContent = many1 nonspaceChar >>= return . B.str . fromEntities
474+ followContent = B.str . fromEntities <$> many1 nonspaceChar
485475
486476symbol :: PandocMonad m => TWParser m B.Inlines
487−symbol = count 1 nonspaceChar >>= return . B.str
477+symbol = B.str <$> count 1 nonspaceChar
488478
489479smart :: PandocMonad m => TWParser m B.Inlines
490480smart = do
@@ -498,17 +488,16 @@ smart = do
498488singleQuoted :: PandocMonad m => TWParser m B.Inlines
499489singleQuoted = try $ do
500490 singleQuoteStart
501− withQuoteContext InSingleQuote $
502− many1Till inline singleQuoteEnd >>=
503− (return . B.singleQuoted . B.trimInlines . mconcat)
491+ withQuoteContext InSingleQuote
492+ (B.singleQuoted . B.trimInlines . mconcat <$> many1Till inline singleQuoteEnd)
504493
505494doubleQuoted :: PandocMonad m => TWParser m B.Inlines
506495doubleQuoted = try $ do
507496 doubleQuoteStart
508497 contents <- mconcat <$> many (try $ notFollowedBy doubleQuoteEnd >> inline)
509− (withQuoteContext InDoubleQuote $ doubleQuoteEnd >>
498+ withQuoteContext InDoubleQuote (doubleQuoteEnd >>
510499 return (B.doubleQuoted $ B.trimInlines contents))
511− <|> (return $ (B.str "\8220") B.<> contents)
500+ <|> return (B.str "\8220" B.<> contents)
512501
513502link :: PandocMonad m => TWParser m B.Inlines
514503link = try $ do
@@ -527,5 +516,5 @@ linkText = do
527516 char ']'
528517 return (url, "", content)
529518 where
530− linkContent = (char '[') >> many1Till anyChar (char ']') >>= parseLinkContent
519+ linkContent = char '[' >> many1Till anyChar (char ']') >>= parseLinkContent
531520 parseLinkContent = parseFromString' $ many1 inline
src/Text/Pandoc/Readers/Textile.hs+1−1
@@ -540,7 +540,7 @@ wordChunk = try $ do
540540str :: PandocMonad m => ParserT [Char] ParserState m Inlines
541541str = do
542542 baseStr <- hyphenedWords
543− -- RedCloth compliance : if parsed word is uppercase and immediatly
543+ -- RedCloth compliance : if parsed word is uppercase and immediately
544544 -- followed by parens, parens content is unconditionally word acronym
545545 fullStr <- option baseStr $ try $ do
546546 guard $ all isUpper baseStr
src/Text/Pandoc/Readers/TikiWiki.hs+5−4
@@ -22,6 +22,7 @@ import Prelude
2222import Control.Monad
2323import Control.Monad.Except (throwError)
2424import qualified Data.Foldable as F
25+import Data.List (dropWhileEnd)
2526import Data.Maybe (fromMaybe)
2627import Data.Text (Text)
2728import qualified Data.Text as T
@@ -166,7 +167,7 @@ table = try $ do
166167 -- return $ B.simpleTable (headers rows) $ trace ("rows: " ++ (show rows)) rows
167168 return $B.simpleTable (headers rows) rows
168169 where
169− -- The headers are as many empty srings as the number of columns
170+ -- The headers are as many empty strings as the number of columns
170171 -- in the first row
171172 headers rows = map (B.plain . B.str) $replicate (length $ head rows) ""
172173
@@ -319,7 +320,7 @@ listItem = choice [
319320bulletItem :: PandocMonad m => TikiWikiParser m (ListNesting, B.Blocks)
320321bulletItem = try $ do
321322 prefix <- many1 $ char '*'
322− many1 $ char ' '
323+ many $ char ' '
323324 content <- listItemLine (length prefix)
324325 return (LN Bullet (length prefix), B.plain content)
325326
@@ -331,7 +332,7 @@ bulletItem = try $ do
331332numberedItem :: PandocMonad m => TikiWikiParser m (ListNesting, B.Blocks)
332333numberedItem = try $ do
333334 prefix <- many1 $ char '#'
334− many1 $ char ' '
335+ many $ char ' '
335336 content <- listItemLine (length prefix)
336337 return (LN Numbered (length prefix), B.plain content)
337338
@@ -346,7 +347,7 @@ listItemLine nest = lineContent >>= parseContent
346347 listContinuation = string (replicate nest '+') >> lineContent
347348 parseContent x = do
348349 parsed <- parseFromString (many1 inline) x
349− return $ mconcat parsed
350+ return $ mconcat $ dropWhileEnd (== B.space) parsed
350351
351352-- Turn the CODE macro attributes into Pandoc code block attributes.
352353mungeAttrs :: [(String, String)] -> (String, [String], [(String, String)])
src/Text/Pandoc/Readers/Txt2Tags.hs+5−3
@@ -198,7 +198,7 @@ para = try $ do
198198commentBlock :: T2T Blocks
199199commentBlock = try (blockMarkupArea anyLine (const mempty) "%%%") <|> comment
200200
201−-- Seperator and Strong line treated the same
201+-- Separator and Strong line treated the same
202202hrule :: T2T Blocks
203203hrule = try $ do
204204 spaces
@@ -575,8 +575,10 @@ symbol = B.str . (:[]) <$> oneOf specialChars
575575getTarget :: T2T String
576576getTarget = do
577577 mv <- lookupMeta "target" . stateMeta <$> getState
578− let MetaString target = fromMaybe (MetaString "html") mv
579− return target
578+ return $ case mv of
579+ Just (MetaString target) -> target
580+ Just (MetaInlines [Str target]) -> target
581+ _ -> "html"
580582
581583atStart :: T2T ()
582584atStart = (sourceColumn <$> getPosition) >>= guard . (== 1)
src/Text/Pandoc/Readers/Vimwiki.hs+7−11
@@ -429,9 +429,7 @@ tableRow = try $ do
429429 s <- lookAhead $ manyTill anyChar (try (char '|' >> many spaceChar
430430 >> newline))
431431 guard $ not $ "||" `isInfixOf` ("|" ++ s ++ "|")
432− tr <- many tableCell
433− many spaceChar >> char '\n'
434− return tr
432+ many tableCell <* many spaceChar <* char '\n'
435433
436434tableCell :: PandocMonad m => VwParser m Blocks
437435tableCell = try $
@@ -451,13 +449,13 @@ ph s = try $ do
451449
452450noHtmlPh :: PandocMonad m => VwParser m ()
453451noHtmlPh = try $
454− () <$ (many spaceChar >> string "%nohtml" >> many spaceChar
455− >> lookAhead newline)
452+ () <$ many spaceChar <* string "%nohtml" <* many spaceChar
453+ <* lookAhead newline
456454
457455templatePh :: PandocMonad m => VwParser m ()
458456templatePh = try $
459− () <$ (many spaceChar >> string "%template" >>many (noneOf "\n")
460− >> lookAhead newline)
457+ () <$ many spaceChar <* string "%template" <* many (noneOf "\n")
458+ <* lookAhead newline
461459
462460-- inline parser
463461
@@ -617,10 +615,8 @@ procImgurl :: String -> String
617615procImgurl s = if take 6 s == "local:" then "file" ++ drop 5 s else s
618616
619617inlineMath :: PandocMonad m => VwParser m Inlines
620−inlineMath = try $ do
621− char '$'
622− contents <- many1Till (noneOf "\n") (char '$')
623− return $ B.math contents
618+inlineMath = try $
619+ B.math <$ char '$' <*> many1Till (noneOf "\n") (char '$')
624620
625621tag :: PandocMonad m => VwParser m Inlines
626622tag = try $ do
src/Text/Pandoc/Shared.hs+38−3
@@ -79,6 +79,7 @@ module Text.Pandoc.Shared (
7979 makeMeta,
8080 eastAsianLineBreakFilter,
8181 underlineSpan,
82+ splitSentences,
8283 -- * TagSoup HTML handling
8384 renderTags',
8485 -- * File handling
@@ -94,6 +95,8 @@ module Text.Pandoc.Shared (
9495 -- * for squashing blocks
9596 blocksToInlines,
9697 blocksToInlines',
98+ blocksToInlinesWithSep,
99+ defaultBlocksSeparator,
97100 -- * Safe read
98101 safeRead,
99102 -- * Temp directory
@@ -580,6 +583,31 @@ eastAsianLineBreakFilter = bottomUp go
580583underlineSpan :: Inlines -> Inlines
581584underlineSpan = B.spanWith ("", ["underline"], [])
582585
586+-- | Returns the first sentence in a list of inlines, and the rest.
587+breakSentence :: [Inline] -> ([Inline], [Inline])
588+breakSentence [] = ([],[])
589+breakSentence xs =
590+ let isSentenceEndInline (Str ys@(_:_)) | last ys == '.' = True
591+ isSentenceEndInline (Str ys@(_:_)) | last ys == '?' = True
592+ isSentenceEndInline LineBreak = True
593+ isSentenceEndInline _ = False
594+ (as, bs) = break isSentenceEndInline xs
595+ in case bs of
596+ [] -> (as, [])
597+ [c] -> (as ++ [c], [])
598+ (c:Space:cs) -> (as ++ [c], cs)
599+ (c:SoftBreak:cs) -> (as ++ [c], cs)
600+ (Str ".":Str (')':ys):cs) -> (as ++ [Str ".", Str (')':ys)], cs)
601+ (x@(Str ('.':')':_)):cs) -> (as ++ [x], cs)
602+ (LineBreak:x@(Str ('.':_)):cs) -> (as ++[LineBreak], x:cs)
603+ (c:cs) -> (as ++ [c] ++ ds, es)
604+ where (ds, es) = breakSentence cs
605+
606+-- | Split a list of inlines into sentences.
607+splitSentences :: [Inline] -> [[Inline]]
608+splitSentences xs =
609+ let (sent, rest) = breakSentence xs
610+ in if null rest then [sent] else sent : splitSentences rest
583611
584612--
585613-- TagSoup HTML handling
@@ -712,7 +740,7 @@ schemes = Set.fromList
712740 , "ws", "wss", "wtai", "wyciwyg", "xcon", "xcon-userid", "xfire"
713741 , "xmlrpc.beep", "xmlrpc.beeps", "xmpp", "xri", "ymsgr", "z39.50", "z39.50r"
714742 , "z39.50s"
715− -- Inofficial schemes
743+ -- Unofficial schemes
716744 , "doi", "isbn", "javascript", "pmid"
717745 ]
718746
@@ -757,12 +785,19 @@ blocksToInlinesWithSep sep =
757785 mconcat . intersperse sep . map blockToInlines
758786
759787blocksToInlines' :: [Block] -> Inlines
760−blocksToInlines' = blocksToInlinesWithSep parSep
761− where parSep = B.space <> B.str "¶" <> B.space
788+blocksToInlines' = blocksToInlinesWithSep defaultBlocksSeparator
762789
763790blocksToInlines :: [Block] -> [Inline]
764791blocksToInlines = B.toList . blocksToInlines'
765792
793+-- | Inline elements used to separate blocks when squashing blocks into
794+-- inlines.
795+defaultBlocksSeparator :: Inlines
796+defaultBlocksSeparator =
797+ -- This is used in the pandoc.utils.blocks_to_inlines function. Docs
798+ -- there should be updated if this is changed.
799+ B.space <> B.str "¶" <> B.space
800+
766801
767802--
768803-- Safe read
src/Text/Pandoc/Translations.hs+31−8
@@ -48,11 +48,12 @@ module Text.Pandoc.Translations (
4848 )
4949where
5050import Prelude
51−import Data.Aeson.Types (typeMismatch)
51+import Data.Aeson.Types (Value(..), FromJSON(..))
52+import qualified Data.Aeson.Types as Aeson
5253import qualified Data.HashMap.Strict as HM
5354import qualified Data.Map as M
5455import Data.Text as T
55−import Data.Yaml as Yaml
56+import qualified Data.YAML as YAML
5657import GHC.Generics (Generic)
5758import Text.Pandoc.Shared (safeRead)
5859import qualified Text.Pandoc.UTF8 as UTF8
@@ -90,7 +91,15 @@ instance FromJSON Term where
9091 Just t' -> pure t'
9192 Nothing -> fail $ "Invalid Term name " ++
9293 show t
93− parseJSON invalid = typeMismatch "Term" invalid
94+ parseJSON invalid = Aeson.typeMismatch "Term" invalid
95+
96+instance YAML.FromYAML Term where
97+ parseYAML (YAML.Scalar (YAML.SStr t)) =
98+ case safeRead (T.unpack t) of
99+ Just t' -> pure t'
100+ Nothing -> fail $ "Invalid Term name " ++
101+ show t
102+ parseYAML invalid = YAML.typeMismatch "Term" invalid
94103
95104instance FromJSON Translations where
96105 parseJSON (Object hm) = do
@@ -102,14 +111,28 @@ instance FromJSON Translations where
102111 Just t ->
103112 case v of
104113 (String s) -> return (t, T.unpack $ T.strip s)
105− inv -> typeMismatch "String" inv
106− parseJSON invalid = typeMismatch "Translations" invalid
114+ inv -> Aeson.typeMismatch "String" inv
115+ parseJSON invalid = Aeson.typeMismatch "Translations" invalid
116+
117+instance YAML.FromYAML Translations where
118+ parseYAML = YAML.withMap "Translations" $
119+ \tr -> Translations .M.fromList <$> mapM addItem (M.toList tr)
120+ where addItem (n@(YAML.Scalar (YAML.SStr k)), v) =
121+ case safeRead (T.unpack k) of
122+ Nothing -> YAML.typeMismatch "Term" n
123+ Just t ->
124+ case v of
125+ (YAML.Scalar (YAML.SStr s)) ->
126+ return (t, T.unpack (T.strip s))
127+ n' -> YAML.typeMismatch "String" n'
128+ addItem (n, _) = YAML.typeMismatch "String" n
107129
108130lookupTerm :: Term -> Translations -> Maybe String
109131lookupTerm t (Translations tm) = M.lookup t tm
110132
111133readTranslations :: String -> Either String Translations
112134readTranslations s =
113− case Yaml.decodeEither' $ UTF8.fromString s of
114− Left err' -> Left $ prettyPrintParseException err'
115− Right t -> Right t
135+ case YAML.decodeStrict $ UTF8.fromString s of
136+ Left err' -> Left err'
137+ Right (t:_) -> Right t
138+ Right [] -> Left "empty YAML document"
src/Text/Pandoc/UUID.hs+8−7
@@ -67,13 +67,14 @@ instance Show UUID where
6767
6868getUUID :: RandomGen g => g -> UUID
6969getUUID gen =
70− let [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p] = take 16 $ randoms gen :: [Word8]
71− -- set variant
72− i' = i `setBit` 7 `clearBit` 6
73− -- set version (0100 for random)
74− g' = g `clearBit` 7 `setBit` 6 `clearBit` 5 `clearBit` 4
75− in
76− UUID a b c d e f g' h i' j k l m n o p
70+ case take 16 (randoms gen :: [Word8]) of
71+ [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p] ->
72+ -- set variant
73+ let i' = i `setBit` 7 `clearBit` 6
74+ -- set version (0100 for random)
75+ g' = g `clearBit` 7 `setBit` 6 `clearBit` 5 `clearBit` 4
76+ in UUID a b c d e f g' h i' j k l m n o p
77+ _ -> error "not enough random numbers for UUID" -- should not happen
7778
7879getRandomUUID :: IO UUID
7980getRandomUUID = getUUID <$> getStdGen
src/Text/Pandoc/Writers/AsciiDoc.hs+15−10
@@ -44,7 +44,7 @@ import Data.Aeson (Result (..), Value (String), fromJSON, toJSON)
4444import Data.Char (isPunctuation, isSpace)
4545import Data.List (intercalate, intersperse, stripPrefix)
4646import qualified Data.Map as M
47−import Data.Maybe (fromMaybe, isJust)
47+import Data.Maybe (fromMaybe, isJust, listToMaybe)
4848import qualified Data.Set as Set
4949import Data.Text (Text)
5050import qualified Data.Text as T
@@ -126,11 +126,16 @@ olMarker = do (start, style', delim) <- anyOrderedListMarker
126126 else spaceChar
127127
128128-- | True if string begins with an ordered list marker
129−beginsWithOrderedListMarker :: String -> Bool
130−beginsWithOrderedListMarker str =
131− case runParser olMarker defaultParserState "para start" (take 10 str) of
132− Left _ -> False
133− Right _ -> True
129+-- or would be interpreted as an AsciiDoc option command
130+needsEscaping :: String -> Bool
131+needsEscaping s = beginsWithOrderedListMarker s || isBracketed s
132+ where
133+ beginsWithOrderedListMarker str =
134+ case runParser olMarker defaultParserState "para start" (take 10 str) of
135+ Left _ -> False
136+ Right _ -> True
137+ isBracketed ('[':cs) = listToMaybe (reverse cs) == Just ']'
138+ isBracketed _ = False
134139
135140-- | Convert Pandoc block element to asciidoc.
136141blockToAsciiDoc :: PandocMonad m
@@ -146,8 +151,8 @@ blockToAsciiDoc opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) =
146151blockToAsciiDoc opts (Para inlines) = do
147152 contents <- inlineListToAsciiDoc opts inlines
148153 -- escape if para starts with ordered list marker
149− let esc = if beginsWithOrderedListMarker (render Nothing contents)
150− then text "\\"
154+ let esc = if needsEscaping (render Nothing contents)
155+ then text "{empty}"
151156 else empty
152157 return $ esc <> contents <> blankline
153158blockToAsciiDoc opts (LineBlock lns) = do
@@ -280,7 +285,7 @@ blockToAsciiDoc opts (DefinitionList items) = do
280285 contents <- mapM (definitionListItemToAsciiDoc opts) items
281286 return $ cat contents <> blankline
282287blockToAsciiDoc opts (Div (ident,_,_) bs) = do
283− let identifier = if null ident then empty else ("[[" <> text ident <> "]]")
288+ let identifier = if null ident then empty else "[[" <> text ident <> "]]"
284289 contents <- blockListToAsciiDoc opts bs
285290 return $ identifier $$ contents
286291
@@ -487,6 +492,6 @@ inlineToAsciiDoc opts (Note [Plain inlines]) = do
487492-- asciidoc can't handle blank lines in notes
488493inlineToAsciiDoc _ (Note _) = return "[multiblock footnote omitted]"
489494inlineToAsciiDoc opts (Span (ident,_,_) ils) = do
490− let identifier = if null ident then empty else ("[[" <> text ident <> "]]")
495+ let identifier = if null ident then empty else "[[" <> text ident <> "]]"
491496 contents <- inlineListToAsciiDoc opts ils
492497 return $ identifier <> contents
src/Text/Pandoc/Writers/CommonMark.hs+47−10
@@ -45,7 +45,7 @@ import Network.HTTP (urlEncode)
4545import Text.Pandoc.Class (PandocMonad)
4646import Text.Pandoc.Definition
4747import Text.Pandoc.Options
48−import Text.Pandoc.Shared (isTightList, linesToPara, substitute)
48+import Text.Pandoc.Shared (isTightList, linesToPara, substitute, capitalize)
4949import Text.Pandoc.Templates (renderTemplate')
5050import Text.Pandoc.Walk (query, walk, walkM)
5151import Text.Pandoc.Writers.HTML (writeHtml5String, tagWithAttributes)
@@ -253,18 +253,34 @@ inlineToNodes opts (Strong xs) = (node STRONG (inlinesToNodes opts xs) :)
253253inlineToNodes opts (Strikeout xs) =
254254 if isEnabled Ext_strikeout opts
255255 then (node (CUSTOM_INLINE "~~" "~~") (inlinesToNodes opts xs) :)
256− else ((node (HTML_INLINE (T.pack "<s>")) [] : inlinesToNodes opts xs ++
257− [node (HTML_INLINE (T.pack "</s>")) []]) ++ )
256+ else if isEnabled Ext_raw_html opts
257+ then ((node (HTML_INLINE (T.pack "<s>")) [] : inlinesToNodes opts xs ++
258+ [node (HTML_INLINE (T.pack "</s>")) []]) ++ )
259+ else (inlinesToNodes opts xs ++)
258260inlineToNodes opts (Superscript xs) =
259− ((node (HTML_INLINE (T.pack "<sup>")) [] : inlinesToNodes opts xs ++
260− [node (HTML_INLINE (T.pack "</sup>")) []]) ++ )
261+ if isEnabled Ext_raw_html opts
262+ then ((node (HTML_INLINE (T.pack "<sup>")) [] : inlinesToNodes opts xs ++
263+ [node (HTML_INLINE (T.pack "</sup>")) []]) ++ )
264+ else case traverse toSuperscriptInline xs of
265+ Nothing ->
266+ ((node (TEXT (T.pack "^(")) [] : inlinesToNodes opts xs ++
267+ [node (TEXT (T.pack ")")) []]) ++ )
268+ Just xs' -> (inlinesToNodes opts xs' ++)
261269inlineToNodes opts (Subscript xs) =
262− ((node (HTML_INLINE (T.pack "<sub>")) [] : inlinesToNodes opts xs ++
263− [node (HTML_INLINE (T.pack "</sub>")) []]) ++ )
270+ if isEnabled Ext_raw_html opts
271+ then ((node (HTML_INLINE (T.pack "<sub>")) [] : inlinesToNodes opts xs ++
272+ [node (HTML_INLINE (T.pack "</sub>")) []]) ++ )
273+ else case traverse toSubscriptInline xs of
274+ Nothing ->
275+ ((node (TEXT (T.pack "_(")) [] : inlinesToNodes opts xs ++
276+ [node (TEXT (T.pack ")")) []]) ++ )
277+ Just xs' -> (inlinesToNodes opts xs' ++)
264278inlineToNodes opts (SmallCaps xs) =
265− ((node (HTML_INLINE (T.pack "<span class=\"smallcaps\">")) []
266− : inlinesToNodes opts xs ++
267− [node (HTML_INLINE (T.pack "</span>")) []]) ++ )
279+ if isEnabled Ext_raw_html opts
280+ then ((node (HTML_INLINE (T.pack "<span class=\"smallcaps\">")) []
281+ : inlinesToNodes opts xs ++
282+ [node (HTML_INLINE (T.pack "</span>")) []]) ++ )
283+ else (inlinesToNodes opts (capitalize xs) ++)
268284inlineToNodes opts (Link _ ils (url,tit)) =
269285 (node (LINK (T.pack url) (T.pack tit)) (inlinesToNodes opts ils) :)
270286-- title beginning with fig: indicates implicit figure
@@ -304,6 +320,11 @@ inlineToNodes opts (Math mt str) =
304320 (node (HTML_INLINE (T.pack ("\\(" ++ str ++ "\\)"))) [] :)
305321 DisplayMath ->
306322 (node (HTML_INLINE (T.pack ("\\[" ++ str ++ "\\]"))) [] :)
323+inlineToNodes opts (Span ("",["emoji"],kvs) [Str s]) = do
324+ case lookup "data-emoji" kvs of
325+ Just emojiname | isEnabled Ext_emoji opts ->
326+ (node (TEXT (":" <> T.pack emojiname <> ":")) [] :)
327+ _ -> (node (TEXT (T.pack s)) [] :)
307328inlineToNodes opts (Span attr ils) =
308329 let nodes = inlinesToNodes opts ils
309330 op = tagWithAttributes opts True False "span" attr
@@ -314,3 +335,19 @@ inlineToNodes opts (Span attr ils) =
314335inlineToNodes opts (Cite _ ils) = (inlinesToNodes opts ils ++)
315336inlineToNodes _ (Note _) = id -- should not occur
316337-- we remove Note elements in preprocessing
338+
339+toSubscriptInline :: Inline -> Maybe Inline
340+toSubscriptInline Space = Just Space
341+toSubscriptInline (Span attr ils) = Span attr <$> traverse toSubscriptInline ils
342+toSubscriptInline (Str s) = Str <$> traverse toSubscript s
343+toSubscriptInline LineBreak = Just LineBreak
344+toSubscriptInline SoftBreak = Just SoftBreak
345+toSubscriptInline _ = Nothing
346+
347+toSuperscriptInline :: Inline -> Maybe Inline
348+toSuperscriptInline Space = Just Space
349+toSuperscriptInline (Span attr ils) = Span attr <$> traverse toSuperscriptInline ils
350+toSuperscriptInline (Str s) = Str <$> traverse toSuperscript s
351+toSuperscriptInline LineBreak = Just LineBreak
352+toSuperscriptInline SoftBreak = Just SoftBreak
353+toSuperscriptInline _ = Nothing
src/Text/Pandoc/Writers/ConTeXt.hs+13−12
@@ -190,10 +190,9 @@ blockToConTeXt (BlockQuote lst) = do
190190blockToConTeXt (CodeBlock _ str) =
191191 return $ flush ("\\starttyping" <> cr <> text str <> cr <> "\\stoptyping") $$ blankline
192192 -- blankline because \stoptyping can't have anything after it, inc. '}'
193−blockToConTeXt (RawBlock "context" str) = return $ text str <> blankline
194−blockToConTeXt b@(RawBlock _ _ ) = do
195− report $ BlockNotRendered b
196− return empty
193+blockToConTeXt b@(RawBlock f str)
194+ | f == Format "context" || f == Format "tex" = return $ text str <> blankline
195+ | otherwise = empty <$ report (BlockNotRendered b)
197196blockToConTeXt (Div (ident,_,kvs) bs) = do
198197 let align dir txt = "\\startalignment[" <> dir <> "]" $$ txt $$ "\\stopalignment"
199198 mblang <- fromBCP47 (lookup "lang" kvs)
@@ -330,8 +329,7 @@ alignToConTeXt align = case align of
330329 AlignDefault -> empty
331330
332331listItemToConTeXt :: PandocMonad m => [Block] -> WM m Doc
333−listItemToConTeXt list = blockListToConTeXt list >>=
334− return . ("\\item" $$) . nest 2
332+listItemToConTeXt list = (("\\item" $$) . nest 2) <$> blockListToConTeXt list
335333
336334defListItemToConTeXt :: PandocMonad m => ([Inline], [[Block]]) -> WM m Doc
337335defListItemToConTeXt (term, defs) = do
@@ -401,11 +399,9 @@ inlineToConTeXt (Math InlineMath str) =
401399 return $ char '$' <> text str <> char '$'
402400inlineToConTeXt (Math DisplayMath str) =
403401 return $ text "\\startformula " <> text str <> text " \\stopformula" <> space
404−inlineToConTeXt (RawInline "context" str) = return $ text str
405−inlineToConTeXt (RawInline "tex" str) = return $ text str
406−inlineToConTeXt il@(RawInline _ _) = do
407− report $ InlineNotRendered il
408− return empty
402+inlineToConTeXt il@(RawInline f str)
403+ | f == Format "tex" || f == Format "context" = return $ text str
404+ | otherwise = empty <$ report (InlineNotRendered il)
409405inlineToConTeXt LineBreak = return $ text "\\crlf" <> cr
410406inlineToConTeXt SoftBreak = do
411407 wrapText <- gets (writerWrapText . stOptions)
@@ -457,7 +453,12 @@ inlineToConTeXt (Image attr@(_,cls,_) _ (src, _)) = do
457453 clas = if null cls
458454 then empty
459455 else brackets $ text $ toLabel $ head cls
460− src' = if isURI src
456+ -- Use / for path separators on Windows; see #4918
457+ fixPathSeparators = map $ \c -> case c of
458+ '\\' -> '/'
459+ _ -> c
460+ src' = fixPathSeparators $
461+ if isURI src
461462 then src
462463 else unEscapeString src
463464 return $ braces $ "\\externalfigure" <> brackets (text src') <> dims <> clas
src/Text/Pandoc/Writers/Custom.hs+80−75
@@ -1,6 +1,6 @@
1−{-# LANGUAGE NoImplicitPrelude #-}
2−{-# LANGUAGE DeriveDataTypeable #-}
3−{-# LANGUAGE FlexibleInstances #-}
1+{-# LANGUAGE DeriveDataTypeable #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE NoImplicitPrelude #-}
44{- Copyright (C) 2012-2018 John MacFarlane <jgm@berkeley.edu>
55
66This program is free software; you can redistribute it and/or modify
@@ -35,25 +35,26 @@ import Prelude
3535import Control.Arrow ((***))
3636import Control.Exception
3737import Control.Monad (when)
38−import Control.Monad.Trans (MonadIO (liftIO))
3938import Data.Char (toLower)
4039import Data.List (intersperse)
4140import qualified Data.Map as M
4241import Data.Text (Text, pack)
4342import Data.Typeable
44−import Foreign.Lua (Lua, ToLuaStack (..), callFunc)
45−import Foreign.Lua.Api
43+import Foreign.Lua (Lua, Pushable)
4644import Text.Pandoc.Class (PandocIO)
4745import Text.Pandoc.Definition
4846import Text.Pandoc.Error
49−import Text.Pandoc.Lua.Init (runPandocLua, registerScriptPath)
47+import Text.Pandoc.Lua.Init (LuaException (LuaException), runPandocLua,
48+ registerScriptPath)
5049import Text.Pandoc.Lua.StackInstances ()
51−import Text.Pandoc.Lua.Util (addValue, dostring')
50+import Text.Pandoc.Lua.Util (addField, dofileWithTraceback)
5251import Text.Pandoc.Options
5352import Text.Pandoc.Templates
5453import qualified Text.Pandoc.UTF8 as UTF8
5554import Text.Pandoc.Writers.Shared
5655
56+import qualified Foreign.Lua as Lua
57+
5758attrToMap :: Attr -> M.Map String String
5859attrToMap (id',classes,keyvals) = M.fromList
5960 $ ("id", id')
@@ -62,41 +63,43 @@ attrToMap (id',classes,keyvals) = M.fromList
6263
6364newtype Stringify a = Stringify a
6465
65−instance ToLuaStack (Stringify Format) where
66− push (Stringify (Format f)) = push (map toLower f)
66+instance Pushable (Stringify Format) where
67+ push (Stringify (Format f)) = Lua.push (map toLower f)
6768
68−instance ToLuaStack (Stringify [Inline]) where
69− push (Stringify ils) = push =<< inlineListToCustom ils
69+instance Pushable (Stringify [Inline]) where
70+ push (Stringify ils) = Lua.push =<< inlineListToCustom ils
7071
71−instance ToLuaStack (Stringify [Block]) where
72− push (Stringify blks) = push =<< blockListToCustom blks
72+instance Pushable (Stringify [Block]) where
73+ push (Stringify blks) = Lua.push =<< blockListToCustom blks
7374
74−instance ToLuaStack (Stringify MetaValue) where
75− push (Stringify (MetaMap m)) = push (fmap Stringify m)
76− push (Stringify (MetaList xs)) = push (map Stringify xs)
77− push (Stringify (MetaBool x)) = push x
78− push (Stringify (MetaString s)) = push s
79− push (Stringify (MetaInlines ils)) = push (Stringify ils)
80− push (Stringify (MetaBlocks bs)) = push (Stringify bs)
75+instance Pushable (Stringify MetaValue) where
76+ push (Stringify (MetaMap m)) = Lua.push (fmap Stringify m)
77+ push (Stringify (MetaList xs)) = Lua.push (map Stringify xs)
78+ push (Stringify (MetaBool x)) = Lua.push x
79+ push (Stringify (MetaString s)) = Lua.push s
80+ push (Stringify (MetaInlines ils)) = Lua.push (Stringify ils)
81+ push (Stringify (MetaBlocks bs)) = Lua.push (Stringify bs)
8182
82−instance ToLuaStack (Stringify Citation) where
83+instance Pushable (Stringify Citation) where
8384 push (Stringify cit) = do
84− createtable 6 0
85− addValue "citationId" $ citationId cit
86− addValue "citationPrefix" . Stringify $ citationPrefix cit
87− addValue "citationSuffix" . Stringify $ citationSuffix cit
88− addValue "citationMode" $ show (citationMode cit)
89− addValue "citationNoteNum" $ citationNoteNum cit
90− addValue "citationHash" $ citationHash cit
85+ Lua.createtable 6 0
86+ addField "citationId" $ citationId cit
87+ addField "citationPrefix" . Stringify $ citationPrefix cit
88+ addField "citationSuffix" . Stringify $ citationSuffix cit
89+ addField "citationMode" $ show (citationMode cit)
90+ addField "citationNoteNum" $ citationNoteNum cit
91+ addField "citationHash" $ citationHash cit
9192
9293-- | Key-value pair, pushed as a table with @a@ as the only key and @v@ as the
9394-- associated value.
9495newtype KeyValue a b = KeyValue (a, b)
9596
96−instance (ToLuaStack a, ToLuaStack b) => ToLuaStack (KeyValue a b) where
97+instance (Pushable a, Pushable b) => Pushable (KeyValue a b) where
9798 push (KeyValue (k, v)) = do
98− newtable
99− addValue k v
99+ Lua.newtable
100+ Lua.push k
101+ Lua.push v
102+ Lua.rawset (Lua.nthFromTop 3)
100103
101104data PandocLuaException = PandocLuaException String
102105 deriving (Show, Typeable)
@@ -106,14 +109,13 @@ instance Exception PandocLuaException
106109-- | Convert Pandoc to custom markup.
107110writeCustom :: FilePath -> WriterOptions -> Pandoc -> PandocIO Text
108111writeCustom luaFile opts doc@(Pandoc meta _) = do
109− luaScript <- liftIO $ UTF8.readFile luaFile
110112 res <- runPandocLua $ do
111113 registerScriptPath luaFile
112− stat <- dostring' luaScript
114+ stat <- dofileWithTraceback luaFile
113115 -- check for error in lua script (later we'll change the return type
114116 -- to handle this more gracefully):
115− when (stat /= OK) $
116− tostring 1 >>= throw . PandocLuaException . UTF8.toString
117+ when (stat /= Lua.OK) $
118+ Lua.tostring' (-1) >>= throw . PandocLuaException . UTF8.toString
117119 -- TODO - call hierarchicalize, so we have that info
118120 rendered <- docToCustom opts doc
119121 context <- metaToJSON opts
@@ -122,7 +124,7 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
122124 meta
123125 return (rendered, context)
124126 let (body, context) = case res of
125− Left e -> throw (PandocLuaException (show e))
127+ Left (LuaException msg) -> throw (PandocLuaException msg)
126128 Right x -> x
127129 case writerTemplate opts of
128130 Nothing -> return $ pack body
@@ -134,7 +136,7 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
134136docToCustom :: WriterOptions -> Pandoc -> Lua String
135137docToCustom opts (Pandoc (Meta metamap) blocks) = do
136138 body <- blockListToCustom blocks
137− callFunc "Doc" body (fmap Stringify metamap) (writerVariables opts)
139+ Lua.callFunc "Doc" body (fmap Stringify metamap) (writerVariables opts)
138140
139141-- | Convert Pandoc block element to Custom.
140142blockToCustom :: Block -- ^ Block element
@@ -142,52 +144,55 @@ blockToCustom :: Block -- ^ Block element
142144
143145blockToCustom Null = return ""
144146
145−blockToCustom (Plain inlines) = callFunc "Plain" (Stringify inlines)
147+blockToCustom (Plain inlines) = Lua.callFunc "Plain" (Stringify inlines)
146148
147149blockToCustom (Para [Image attr txt (src,tit)]) =
148− callFunc "CaptionedImage" src tit (Stringify txt) (attrToMap attr)
150+ Lua.callFunc "CaptionedImage" src tit (Stringify txt) (attrToMap attr)
149151
150−blockToCustom (Para inlines) = callFunc "Para" (Stringify inlines)
152+blockToCustom (Para inlines) = Lua.callFunc "Para" (Stringify inlines)
151153
152−blockToCustom (LineBlock linesList) = callFunc "LineBlock" (map Stringify linesList)
154+blockToCustom (LineBlock linesList) =
155+ Lua.callFunc "LineBlock" (map Stringify linesList)
153156
154157blockToCustom (RawBlock format str) =
155− callFunc "RawBlock" (Stringify format) str
158+ Lua.callFunc "RawBlock" (Stringify format) str
156159
157−blockToCustom HorizontalRule = callFunc "HorizontalRule"
160+blockToCustom HorizontalRule = Lua.callFunc "HorizontalRule"
158161
159162blockToCustom (Header level attr inlines) =
160− callFunc "Header" level (Stringify inlines) (attrToMap attr)
163+ Lua.callFunc "Header" level (Stringify inlines) (attrToMap attr)
161164
162165blockToCustom (CodeBlock attr str) =
163− callFunc "CodeBlock" str (attrToMap attr)
166+ Lua.callFunc "CodeBlock" str (attrToMap attr)
164167
165−blockToCustom (BlockQuote blocks) = callFunc "BlockQuote" (Stringify blocks)
168+blockToCustom (BlockQuote blocks) =
169+ Lua.callFunc "BlockQuote" (Stringify blocks)
166170
167171blockToCustom (Table capt aligns widths headers rows) =
168172 let aligns' = map show aligns
169173 capt' = Stringify capt
170174 headers' = map Stringify headers
171175 rows' = map (map Stringify) rows
172− in callFunc "Table" capt' aligns' widths headers' rows'
176+ in Lua.callFunc "Table" capt' aligns' widths headers' rows'
173177
174−blockToCustom (BulletList items) = callFunc "BulletList" (map Stringify items)
178+blockToCustom (BulletList items) =
179+ Lua.callFunc "BulletList" (map Stringify items)
175180
176181blockToCustom (OrderedList (num,sty,delim) items) =
177− callFunc "OrderedList" (map Stringify items) num (show sty) (show delim)
182+ Lua.callFunc "OrderedList" (map Stringify items) num (show sty) (show delim)
178183
179184blockToCustom (DefinitionList items) =
180− callFunc "DefinitionList"
181− (map (KeyValue . (Stringify *** map Stringify)) items)
185+ Lua.callFunc "DefinitionList"
186+ (map (KeyValue . (Stringify *** map Stringify)) items)
182187
183188blockToCustom (Div attr items) =
184− callFunc "Div" (Stringify items) (attrToMap attr)
189+ Lua.callFunc "Div" (Stringify items) (attrToMap attr)
185190
186191-- | Convert list of Pandoc block elements to Custom.
187192blockListToCustom :: [Block] -- ^ List of block elements
188193 -> Lua String
189194blockListToCustom xs = do
190− blocksep <- callFunc "Blocksep"
195+ blocksep <- Lua.callFunc "Blocksep"
191196 bs <- mapM blockToCustom xs
192197 return $ mconcat $ intersperse blocksep bs
193198
@@ -200,51 +205,51 @@ inlineListToCustom lst = do
200205-- | Convert Pandoc inline element to Custom.
201206inlineToCustom :: Inline -> Lua String
202207
203−inlineToCustom (Str str) = callFunc "Str" str
208+inlineToCustom (Str str) = Lua.callFunc "Str" str
204209
205−inlineToCustom Space = callFunc "Space"
210+inlineToCustom Space = Lua.callFunc "Space"
206211
207−inlineToCustom SoftBreak = callFunc "SoftBreak"
212+inlineToCustom SoftBreak = Lua.callFunc "SoftBreak"
208213
209−inlineToCustom (Emph lst) = callFunc "Emph" (Stringify lst)
214+inlineToCustom (Emph lst) = Lua.callFunc "Emph" (Stringify lst)
210215
211−inlineToCustom (Strong lst) = callFunc "Strong" (Stringify lst)
216+inlineToCustom (Strong lst) = Lua.callFunc "Strong" (Stringify lst)
212217
213−inlineToCustom (Strikeout lst) = callFunc "Strikeout" (Stringify lst)
218+inlineToCustom (Strikeout lst) = Lua.callFunc "Strikeout" (Stringify lst)
214219
215−inlineToCustom (Superscript lst) = callFunc "Superscript" (Stringify lst)
220+inlineToCustom (Superscript lst) = Lua.callFunc "Superscript" (Stringify lst)
216221
217−inlineToCustom (Subscript lst) = callFunc "Subscript" (Stringify lst)
222+inlineToCustom (Subscript lst) = Lua.callFunc "Subscript" (Stringify lst)
218223
219−inlineToCustom (SmallCaps lst) = callFunc "SmallCaps" (Stringify lst)
224+inlineToCustom (SmallCaps lst) = Lua.callFunc "SmallCaps" (Stringify lst)
220225
221−inlineToCustom (Quoted SingleQuote lst) = callFunc "SingleQuoted" (Stringify lst)
226+inlineToCustom (Quoted SingleQuote lst) = Lua.callFunc "SingleQuoted" (Stringify lst)
222227
223−inlineToCustom (Quoted DoubleQuote lst) = callFunc "DoubleQuoted" (Stringify lst)
228+inlineToCustom (Quoted DoubleQuote lst) = Lua.callFunc "DoubleQuoted" (Stringify lst)
224229
225−inlineToCustom (Cite cs lst) = callFunc "Cite" (Stringify lst) (map Stringify cs)
230+inlineToCustom (Cite cs lst) = Lua.callFunc "Cite" (Stringify lst) (map Stringify cs)
226231
227232inlineToCustom (Code attr str) =
228− callFunc "Code" str (attrToMap attr)
233+ Lua.callFunc "Code" str (attrToMap attr)
229234
230235inlineToCustom (Math DisplayMath str) =
231− callFunc "DisplayMath" str
236+ Lua.callFunc "DisplayMath" str
232237
233238inlineToCustom (Math InlineMath str) =
234− callFunc "InlineMath" str
239+ Lua.callFunc "InlineMath" str
235240
236241inlineToCustom (RawInline format str) =
237− callFunc "RawInline" (Stringify format) str
242+ Lua.callFunc "RawInline" (Stringify format) str
238243
239−inlineToCustom LineBreak = callFunc "LineBreak"
244+inlineToCustom LineBreak = Lua.callFunc "LineBreak"
240245
241246inlineToCustom (Link attr txt (src,tit)) =
242− callFunc "Link" (Stringify txt) src tit (attrToMap attr)
247+ Lua.callFunc "Link" (Stringify txt) src tit (attrToMap attr)
243248
244249inlineToCustom (Image attr alt (src,tit)) =
245− callFunc "Image" (Stringify alt) src tit (attrToMap attr)
250+ Lua.callFunc "Image" (Stringify alt) src tit (attrToMap attr)
246251
247−inlineToCustom (Note contents) = callFunc "Note" (Stringify contents)
252+inlineToCustom (Note contents) = Lua.callFunc "Note" (Stringify contents)
248253
249254inlineToCustom (Span attr items) =
250− callFunc "Span" (Stringify items) (attrToMap attr)
255+ Lua.callFunc "Span" (Stringify items) (attrToMap attr)
src/Text/Pandoc/Writers/Docbook.hs+4−3
@@ -126,9 +126,10 @@ writeDocbook opts (Pandoc meta blocks) = do
126126 defField "mathml" (case writerHTMLMathMethod opts of
127127 MathML -> True
128128 _ -> False) metadata
129− case writerTemplate opts of
130− Nothing -> return main
131− Just tpl -> renderTemplate' tpl context
129+ (if writerPreferAscii opts then toEntities else id) <$>
130+ case writerTemplate opts of
131+ Nothing -> return main
132+ Just tpl -> renderTemplate' tpl context
132133
133134-- | Convert an Element to Docbook.
134135elementToDocbook :: PandocMonad m => WriterOptions -> Int -> Element -> DB m Doc
src/Text/Pandoc/Writers/Docx.hs+16−20
@@ -66,7 +66,7 @@ import Text.Pandoc.Readers.Docx.StyleMap
6666import Text.Pandoc.Shared hiding (Element)
6767import Text.Pandoc.Walk
6868import Text.Pandoc.Writers.Math
69−import Text.Pandoc.Writers.Shared (fixDisplayMath, metaValueToInlines)
69+import Text.Pandoc.Writers.Shared
7070import Text.Printf (printf)
7171import Text.TeXMath
7272import Text.XML.Light as XML
@@ -230,7 +230,7 @@ writeDocx opts doc@(Pandoc meta _) = do
230230 let mbAttrMarLeft = (elAttribs <$> mbpgmar) >>= lookupAttrBy ((=="left") . qName)
231231 let mbAttrMarRight = (elAttribs <$> mbpgmar) >>= lookupAttrBy ((=="right") . qName)
232232
233− -- Get the avaible area (converting the size and the margins to int and
233+ -- Get the available area (converting the size and the margins to int and
234234 -- doing the difference
235235 let pgContentWidth = (-) <$> (read <$> mbAttrSzWidth ::Maybe Integer)
236236 <*> (
@@ -266,8 +266,9 @@ writeDocx opts doc@(Pandoc meta _) = do
266266 -- parse styledoc for heading styles
267267 let styleMaps = getStyleMaps styledoc
268268
269− let tocTitle = fromMaybe (stTocTitle defaultWriterState) $
270− metaValueToInlines <$> lookupMeta "toc-title" meta
269+ let tocTitle = case lookupMetaInlines "toc-title" meta of
270+ [] -> stTocTitle defaultWriterState
271+ ls -> ls
271272
272273 let initialSt = defaultWriterState {
273274 stStyleMaps = styleMaps
@@ -727,7 +728,7 @@ getNumId = (((baseListId - 1) +) . length) `fmap` gets stLists
727728
728729
729730makeTOC :: (PandocMonad m) => WriterOptions -> WS m [Element]
730−makeTOC opts | writerTableOfContents opts = do
731+makeTOC opts = do
731732 let depth = "1-"++show (writerTOCDepth opts)
732733 let tocCmd = "TOC \\o \""++depth++"\" \\h \\z \\u"
733734 tocTitle <- gets stTocTitle
@@ -751,8 +752,6 @@ makeTOC opts | writerTableOfContents opts = do
751752 ) -- w:p
752753 ])
753754 ])] -- w:sdt
754−makeTOC _ = return []
755−
756755
757756-- | Convert Pandoc document to two lists of
758757-- OpenXML elements (the main document and footnotes).
@@ -761,15 +760,9 @@ writeOpenXML opts (Pandoc meta blocks) = do
761760 let tit = docTitle meta
762761 let auths = docAuthors meta
763762 let dat = docDate meta
764− let abstract' = case lookupMeta "abstract" meta of
765− Just (MetaBlocks bs) -> bs
766− Just (MetaInlines ils) -> [Plain ils]
767− _ -> []
768− let subtitle' = case lookupMeta "subtitle" meta of
769− Just (MetaBlocks [Plain xs]) -> xs
770− Just (MetaBlocks [Para xs]) -> xs
771− Just (MetaInlines xs) -> xs
772− _ -> []
763+ let abstract' = lookupMetaBlocks "abstract" meta
764+ let subtitle' = lookupMetaInlines "subtitle" meta
765+ let includeTOC = writerTableOfContents opts || lookupMetaBool "toc" meta
773766 title <- withParaPropM (pStyleM "Title") $ blocksToOpenXML opts [Para tit | not (null tit)]
774767 subtitle <- withParaPropM (pStyleM "Subtitle") $ blocksToOpenXML opts [Para subtitle' | not (null subtitle')]
775768 authors <- withParaProp (pCustomStyle "Author") $ blocksToOpenXML opts $
@@ -801,7 +794,9 @@ writeOpenXML opts (Pandoc meta blocks) = do
801794 ] ++ annotation
802795 ]
803796 comments' <- mapM toComment comments
804− toc <- makeTOC opts
797+ toc <- if includeTOC
798+ then makeTOC opts
799+ else return []
805800 let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ toc
806801 return (meta' ++ doc', notes', comments')
807802
@@ -908,9 +903,10 @@ blockToOpenXML' opts (Para lst)
908903 | null lst && not (isEnabled Ext_empty_paragraphs opts) = return []
909904 | otherwise = do
910905 isFirstPara <- gets stFirstPara
911− paraProps <- getParaProps $ case lst of
912− [Math DisplayMath _] -> True
913− _ -> False
906+ let displayMathPara = case lst of
907+ [x] -> isDisplayMath x
908+ _ -> False
909+ paraProps <- getParaProps displayMathPara
914910 bodyTextStyle <- pStyleM "Body Text"
915911 let paraProps' = case paraProps of
916912 [] | isFirstPara -> [mknode "w:pPr" []
src/Text/Pandoc/Writers/EPUB.hs+29−10
@@ -74,6 +74,7 @@ import Text.Printf (printf)
7474import Text.XML.Light (Attr (..), Element (..), Node (..), QName (..),
7575 add_attrs, lookupAttr, node, onlyElems, parseXML,
7676 ppElement, showElement, strContent, unode, unqual)
77+import Text.Pandoc.XML (escapeStringForXML)
7778
7879-- A Chapter includes a list of blocks and maybe a section
7980-- number offset. Note, some chapters are unnumbered. The section
@@ -446,7 +447,8 @@ pandocToEPUB version opts doc@(Pandoc meta _) = do
446447 cpContent <- lift $ writeHtml
447448 opts'{ writerVariables =
448449 ("coverpage","true"):
449− ("pagetitle",plainTitle):
450+ ("pagetitle",
451+ escapeStringForXML plainTitle):
450452 cssvars True ++ vars }
451453 (Pandoc meta [RawBlock (Format "html") $ "<div id=\"cover-image\">\n<img src=\"../media/" ++ coverImage ++ "\" alt=\"cover image\" />\n</div>"])
452454 imgContent <- lift $ P.readFileLazy img
@@ -459,7 +461,8 @@ pandocToEPUB version opts doc@(Pandoc meta _) = do
459461 -- title page
460462 tpContent <- lift $ writeHtml opts'{
461463 writerVariables = ("titlepage","true"):
462− ("pagetitle",plainTitle):
464+ ("body-type", "frontmatter"):
465+ ("pagetitle", escapeStringForXML plainTitle):
463466 cssvars True ++ vars }
464467 (Pandoc meta [])
465468 tpEntry <- mkEntry "text/title_page.xhtml" tpContent
@@ -563,13 +566,28 @@ pandocToEPUB version opts doc@(Pandoc meta _) = do
563566 let chapToEntry num (Chapter mbnum bs) =
564567 mkEntry ("text/" ++ showChapter num) =<<
565568 writeHtml opts'{ writerNumberOffset = fromMaybe [] mbnum
566− , writerVariables = cssvars True ++ vars }
567− (case bs of
568− (Header _ _ xs : _) ->
569+ , writerVariables = ("body-type", bodyType) :
570+ cssvars True ++ vars } pdoc
571+ where (pdoc, bodyType) =
572+ case bs of
573+ (Header _ (_,_,kvs) xs : _) ->
569574 -- remove notes or we get doubled footnotes
570− Pandoc (setMeta "title" (walk removeNote $ fromList xs)
571− nullMeta) bs
572− _ -> Pandoc nullMeta bs)
575+ (Pandoc (setMeta "title"
576+ (walk removeNote $ fromList xs) nullMeta) bs,
577+ case lookup "epub:type" kvs of
578+ Nothing -> "bodymatter"
579+ Just x
580+ | x `elem` frontMatterTypes -> "frontmatter"
581+ | x `elem` backMatterTypes -> "backmatter"
582+ | otherwise -> "bodymatter")
583+ _ -> (Pandoc nullMeta bs, "bodymatter")
584+ frontMatterTypes = ["prologue", "abstract", "acknowledgments",
585+ "copyright-page", "dedication",
586+ "foreword", "halftitle",
587+ "introduction", "preface",
588+ "seriespage", "titlepage"]
589+ backMatterTypes = ["afterword", "appendix", "colophon",
590+ "conclusion", "epigraph"]
573591
574592 chapterEntries <- zipWithM chapToEntry [1..] chapters
575593
@@ -754,7 +772,8 @@ pandocToEPUB version opts doc@(Pandoc meta _) = do
754772 (writeHtmlStringForEPUB version
755773 opts{ writerTemplate = Nothing
756774 , writerVariables =
757− ("pagetitle",plainTitle):
775+ ("pagetitle",
776+ escapeStringForXML plainTitle):
758777 writerVariables opts}
759778 (Pandoc nullMeta
760779 [Plain $ walk clean tit])) of
@@ -782,7 +801,7 @@ pandocToEPUB version opts doc@(Pandoc meta _) = do
782801 [ unode "a" ! [("href", "text/cover.xhtml")
783802 ,("epub:type", "cover")] $
784803 "Cover"] |
785− epubCoverImage metadata /= Nothing
804+ isJust (epubCoverImage metadata)
786805 ] ++
787806 [ unode "li"
788807 [ unode "a" ! [("href", "#toc")
src/Text/Pandoc/Writers/FB2.hs+9−3
@@ -119,7 +119,7 @@ description meta' = do
119119 let as = authors meta'
120120 dd <- docdate meta'
121121 annotation <- case lookupMeta "abstract" meta' of
122− Just (MetaBlocks bs) -> (list . el "annotation") <$> cMapM blockToXml bs
122+ Just (MetaBlocks bs) -> (list . el "annotation") <$> cMapM blockToXml (map unPlain bs)
123123 _ -> pure mempty
124124 let lang = case lookupMeta "lang" meta' of
125125 Just (MetaInlines [Str s]) -> [el "lang" $ iso639 s]
@@ -135,8 +135,9 @@ description meta' = do
135135 Just (MetaString s) -> coverimage s
136136 _ -> return []
137137 return $ el "description"
138− [ el "title-info" (genre : (bt ++ annotation ++ as ++ dd ++ lang))
139− , el "document-info" (el "program-used" "pandoc" : coverpage)
138+ [ el "title-info" (genre :
139+ (as ++ bt ++ annotation ++ dd ++ coverpage ++ lang))
140+ , el "document-info" [el "program-used" "pandoc"]
140141 ]
141142
142143booktitle :: PandocMonad m => Meta -> FBM m [Content]
@@ -398,6 +399,11 @@ plainToPara (Para inlines : rest) =
398399 Para inlines : HorizontalRule : plainToPara rest -- HorizontalRule will be converted to <empty-line />
399400plainToPara (p:rest) = p : plainToPara rest
400401
402+-- Replace plain text with paragraphs
403+unPlain :: Block -> Block
404+unPlain (Plain inlines) = Para inlines
405+unPlain x = x
406+
401407-- Simulate increased indentation level. Will not really work
402408-- for multi-line paragraphs.
403409indentPrefix :: String -> Block -> Block
src/Text/Pandoc/Writers/HTML.hs+166−33
@@ -50,13 +50,13 @@ import Prelude
5050import Control.Monad.State.Strict
5151import Data.Char (ord, toLower)
5252import Data.List (intercalate, intersperse, isPrefixOf, partition)
53−import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing)
53+import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, mapMaybe)
5454import qualified Data.Set as Set
5555import Data.String (fromString)
5656import Data.Text (Text)
5757import qualified Data.Text.Lazy as TL
5858import Network.HTTP (urlEncode)
59−import Network.URI (URI (..), parseURIReference, unEscapeString)
59+import Network.URI (URI (..), parseURIReference)
6060import Numeric (showHex)
6161import Text.Blaze.Internal (customLeaf, customParent, MarkupM(Empty))
6262#if MIN_VERSION_blaze_markup(0,6,3)
@@ -75,7 +75,7 @@ import Text.Pandoc.Templates
7575import Text.Pandoc.Walk
7676import Text.Pandoc.Writers.Math
7777import Text.Pandoc.Writers.Shared
78−import Text.Pandoc.XML (escapeStringForXML, fromEntities)
78+import Text.Pandoc.XML (escapeStringForXML, fromEntities, toEntities)
7979#if MIN_VERSION_blaze_markup(0,6,3)
8080#else
8181import Text.Blaze.Internal (preEscapedString, preEscapedText)
@@ -206,7 +206,8 @@ writeHtmlString' :: PandocMonad m
206206 => WriterState -> WriterOptions -> Pandoc -> m Text
207207writeHtmlString' st opts d = do
208208 (body, context) <- evalStateT (pandocToHtml opts d) st
209− case writerTemplate opts of
209+ (if writerPreferAscii opts then toEntities else id) <$>
210+ case writerTemplate opts of
210211 Nothing -> return $ renderHtml' body
211212 Just tpl -> do
212213 -- warn if empty lang
@@ -221,16 +222,19 @@ writeHtmlString' st opts d = do
221222 lookup "sourcefile" (writerVariables opts)
222223 report $ NoTitleElement fallback
223224 return $ resetField "pagetitle" fallback context
224− renderTemplate' tpl $
225− defField "body" (renderHtml' body) context'
225+ renderTemplate' tpl
226+ (defField "body" (renderHtml' body) context')
226227
227228writeHtml' :: PandocMonad m => WriterState -> WriterOptions -> Pandoc -> m Html
228229writeHtml' st opts d =
229230 case writerTemplate opts of
230231 Just _ -> preEscapedText <$> writeHtmlString' st opts d
231− Nothing -> do
232− (body, _) <- evalStateT (pandocToHtml opts d) st
233− return body
232+ Nothing
233+ | writerPreferAscii opts
234+ -> preEscapedText <$> writeHtmlString' st opts d
235+ | otherwise -> do
236+ (body, _) <- evalStateT (pandocToHtml opts d) st
237+ return body
234238
235239-- result is (title, authors, date, toc, body, new variables)
236240pandocToHtml :: PandocMonad m
@@ -259,7 +263,7 @@ pandocToHtml opts (Pandoc meta blocks) = do
259263 st <- get
260264 notes <- footnoteSection opts (reverse (stNotes st))
261265 let thebody = blocks' >> notes
262− let math = case writerHTMLMathMethod opts of
266+ let math = case writerHTMLMathMethod opts of
263267 MathJax url
264268 | slideVariant /= RevealJsSlides ->
265269 -- mathjax is handled via a special plugin in revealjs
@@ -273,10 +277,10 @@ pandocToHtml opts (Pandoc meta blocks) = do
273277 KaTeX url -> do
274278 H.script !
275279 A.src (toValue $ url ++ "katex.min.js") $ mempty
276− H.script !
277− A.src (toValue $ url ++ "contrib/auto-render.min.js") $ mempty
280+ nl opts
278281 H.script
279− "document.addEventListener(\"DOMContentLoaded\", function() {\n renderMathInElement(document.body);\n});"
282+ "document.addEventListener(\"DOMContentLoaded\", function () {\n var mathElements = document.getElementsByClassName(\"math\");\n for (var i = 0; i < mathElements.length; i++) {\n var texText = mathElements[i].firstChild;\n if (mathElements[i].tagName == \"SPAN\") { katex.render(texText.data, mathElements[i], { displayMode: mathElements[i].classList.contains(\"display\"), throwOnError: false } );\n }}});"
283+ nl opts
280284 H.link ! A.rel "stylesheet" !
281285 A.href (toValue $ url ++ "katex.min.css")
282286
@@ -296,10 +300,11 @@ pandocToHtml opts (Pandoc meta blocks) = do
296300 (if stMath st
297301 then defField "math" (renderHtml' math)
298302 else id) $
299− defField "mathjax"
300− (case writerHTMLMathMethod opts of
301− MathJax _ -> True
302− _ -> False) $
303+ (case writerHTMLMathMethod opts of
304+ MathJax u -> defField "mathjax" True .
305+ defField "mathjaxurl"
306+ (takeWhile (/='?') u)
307+ _ -> defField "mathjax" False) $
303308 defField "quotes" (stQuotes st) $
304309 -- for backwards compatibility we populate toc
305310 -- with the contents of the toc, rather than a
@@ -460,7 +465,7 @@ elementToHtml slideLevel opts (Sec level num (id',classes,keyvals) title' elemen
460465 t <- addAttrs opts attr $
461466 secttag header'
462467 return $
463− (if slideVariant == RevealJsSlides
468+ (if slideVariant == RevealJsSlides && not (null innerContents)
464469 then H5.section
465470 else id) $ mconcat $ t : innerContents
466471 else if writerSectionDivs opts || slide
@@ -576,12 +581,23 @@ toAttrs :: PandocMonad m
576581 => [(String, String)] -> StateT WriterState m [Attribute]
577582toAttrs kvs = do
578583 html5 <- gets stHtml5
579− return $ map (\(x,y) ->
580− customAttribute
581− (fromString (if not html5 || x `Set.member` html5Attributes
582− || "data-" `isPrefixOf` x
583− then x
584− else "data-" ++ x)) (toValue y)) kvs
584+ mbEpubVersion <- gets stEPUBVersion
585+ return $ mapMaybe (\(x,y) ->
586+ if html5
587+ then
588+ if x `Set.member` html5Attributes
589+ || ':' `elem` x -- e.g. epub: namespace
590+ || "data-" `isPrefixOf` x
591+ then Just $ customAttribute (fromString x) (toValue y)
592+ else Just $ customAttribute (fromString ("data-" ++ x))
593+ (toValue y)
594+ else
595+ if mbEpubVersion == Just EPUB2 &&
596+ not (x `Set.member` html4Attributes ||
597+ "xml:" `isPrefixOf` x)
598+ then Nothing
599+ else Just $ customAttribute (fromString x) (toValue y))
600+ kvs
585601
586602attrsToHtml :: PandocMonad m
587603 => WriterOptions -> Attr -> StateT WriterState m [Attribute]
@@ -828,9 +844,7 @@ blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do
828844 return $ foldl (!) l attribs
829845blockToHtml opts (DefinitionList lst) = do
830846 contents <- mapM (\(term, defs) ->
831− do term' <- if null term
832− then return mempty
833− else liftM H.dt $ inlineListToHtml opts term
847+ do term' <- liftM H.dt $ inlineListToHtml opts term
834848 defs' <- mapM (liftM (\x -> H.dd (x >> nl opts)) .
835849 blockListToHtml opts) defs
836850 return $ mconcat $ nl opts : term' : nl opts :
@@ -1051,8 +1065,8 @@ inlineToHtml opts inline = do
10511065 DisplayMath -> "\\[" ++ str ++ "\\]"
10521066 KaTeX _ -> return $ H.span ! A.class_ mathClass $ toHtml $
10531067 case t of
1054− InlineMath -> "\\(" ++ str ++ "\\)"
1055− DisplayMath -> "\\[" ++ str ++ "\\]"
1068+ InlineMath -> str
1069+ DisplayMath -> str
10561070 PlainMath -> do
10571071 x <- lift (texMathToInlines t str) >>= inlineListToHtml opts
10581072 let m = H.span ! A.class_ mathClass $ x
@@ -1084,10 +1098,7 @@ inlineToHtml opts inline = do
10841098 in '#' : prefix ++ xs
10851099 _ -> s
10861100 let link = H.a ! A.href (toValue s') $ linkText
1087− let attr = if txt == [Str (unEscapeString s)]
1088− then (ident, "uri" : classes, kvs)
1089− else (ident, classes, kvs)
1090− link' <- addAttrs opts attr link
1101+ link' <- addAttrs opts (ident, classes, kvs) link
10911102 return $ if null tit
10921103 then link'
10931104 else link' ! A.title (toValue tit)
@@ -1422,3 +1433,125 @@ html5Attributes = Set.fromList
14221433 , "workertype"
14231434 , "wrap"
14241435 ]
1436+
1437+html4Attributes :: Set.Set String
1438+html4Attributes = Set.fromList
1439+ [ "abbr"
1440+ , "accept"
1441+ , "accept-charset"
1442+ , "accesskey"
1443+ , "action"
1444+ , "align"
1445+ , "alink"
1446+ , "alt"
1447+ , "archive"
1448+ , "axis"
1449+ , "background"
1450+ , "bgcolor"
1451+ , "border"
1452+ , "cellpadding"
1453+ , "cellspacing"
1454+ , "char"
1455+ , "charoff"
1456+ , "charset"
1457+ , "checked"
1458+ , "cite"
1459+ , "class"
1460+ , "classid"
1461+ , "clear"
1462+ , "code"
1463+ , "codebase"
1464+ , "codetype"
1465+ , "color"
1466+ , "cols"
1467+ , "colspan"
1468+ , "compact"
1469+ , "content"
1470+ , "coords"
1471+ , "data"
1472+ , "datetime"
1473+ , "declare"
1474+ , "defer"
1475+ , "dir"
1476+ , "disabled"
1477+ , "enctype"
1478+ , "face"
1479+ , "for"
1480+ , "frame"
1481+ , "frameborder"
1482+ , "headers"
1483+ , "height"
1484+ , "href"
1485+ , "hreflang"
1486+ , "hspace"
1487+ , "http-equiv"
1488+ , "id"
1489+ , "ismap"
1490+ , "label"
1491+ , "lang"
1492+ , "language"
1493+ , "link"
1494+ , "longdesc"
1495+ , "marginheight"
1496+ , "marginwidth"
1497+ , "maxlength"
1498+ , "media"
1499+ , "method"
1500+ , "multiple"
1501+ , "name"
1502+ , "nohref"
1503+ , "noresize"
1504+ , "noshade"
1505+ , "nowrap"
1506+ , "object"
1507+ , "onblur"
1508+ , "onchange"
1509+ , "onclick"
1510+ , "ondblclick"
1511+ , "onfocus"
1512+ , "onkeydown"
1513+ , "onkeypress"
1514+ , "onkeyup"
1515+ , "onload"
1516+ , "onmousedown"
1517+ , "onmousemove"
1518+ , "onmouseout"
1519+ , "onmouseover"
1520+ , "onmouseup"
1521+ , "onreset"
1522+ , "onselect"
1523+ , "onsubmit"
1524+ , "onunload"
1525+ , "profile"
1526+ , "prompt"
1527+ , "readonly"
1528+ , "rel"
1529+ , "rev"
1530+ , "rows"
1531+ , "rowspan"
1532+ , "rules"
1533+ , "scheme"
1534+ , "scope"
1535+ , "scrolling"
1536+ , "selected"
1537+ , "shape"
1538+ , "size"
1539+ , "span"
1540+ , "src"
1541+ , "standby"
1542+ , "start"
1543+ , "style"
1544+ , "summary"
1545+ , "tabindex"
1546+ , "target"
1547+ , "text"
1548+ , "title"
1549+ , "usemap"
1550+ , "valign"
1551+ , "value"
1552+ , "valuetype"
1553+ , "version"
1554+ , "vlink"
1555+ , "vspace"
1556+ , "width"
1557+ ]
src/Text/Pandoc/Writers/Haddock.hs+6−8
@@ -45,7 +45,6 @@ import Text.Pandoc.Options
4545import Text.Pandoc.Pretty
4646import Text.Pandoc.Shared
4747import Text.Pandoc.Templates (renderTemplate')
48−import Text.Pandoc.Writers.Math (texMathToInlines)
4948import Text.Pandoc.Writers.Shared
5049
5150type Notes = [[Block]]
@@ -208,13 +207,13 @@ blockListToHaddock :: PandocMonad m
208207 -> [Block] -- ^ List of block elements
209208 -> StateT WriterState m Doc
210209blockListToHaddock opts blocks =
211− mapM (blockToHaddock opts) blocks >>= return . cat
210+ cat <$> mapM (blockToHaddock opts) blocks
212211
213212-- | Convert list of Pandoc inline elements to haddock.
214213inlineListToHaddock :: PandocMonad m
215214 => WriterOptions -> [Inline] -> StateT WriterState m Doc
216215inlineListToHaddock opts lst =
217− mapM (inlineToHaddock opts) lst >>= return . cat
216+ cat <$> mapM (inlineToHaddock opts) lst
218217
219218-- | Convert Pandoc inline element to haddock.
220219inlineToHaddock :: PandocMonad m
@@ -250,11 +249,10 @@ inlineToHaddock _ (Code _ str) =
250249 return $ "@" <> text (escapeString str) <> "@"
251250inlineToHaddock _ (Str str) =
252251 return $ text $ escapeString str
253−inlineToHaddock opts (Math mt str) = do
254− let adjust x = case mt of
255− DisplayMath -> cr <> x <> cr
256− InlineMath -> x
257− adjust <$> (lift (texMathToInlines mt str) >>= inlineListToHaddock opts)
252+inlineToHaddock _ (Math mt str) =
253+ return $ case mt of
254+ DisplayMath -> cr <> "\\[" <> text str <> "\\]" <> cr
255+ InlineMath -> "\\(" <> text str <> "\\)"
258256inlineToHaddock _ il@(RawInline f str)
259257 | f == "haddock" = return $ text str
260258 | otherwise = do
src/Text/Pandoc/Writers/ICML.hs+3−2
@@ -149,11 +149,12 @@ writeICML opts (Pandoc meta blocks) = do
149149 $ defField "charStyles" (render' $ charStylesToDoc st)
150150 $ defField "parStyles" (render' $ parStylesToDoc st)
151151 $ defField "hyperlinks" (render' $ hyperlinksToDoc $ links st) metadata
152− case writerTemplate opts of
152+ (if writerPreferAscii opts then toEntities else id) <$>
153+ case writerTemplate opts of
153154 Nothing -> return main
154155 Just tpl -> renderTemplate' tpl context
155156
156−-- | Auxilary functions for parStylesToDoc and charStylesToDoc.
157+-- | Auxiliary functions for parStylesToDoc and charStylesToDoc.
157158contains :: String -> (String, (String, String)) -> [(String, String)]
158159contains s rule =
159160 [snd rule | (fst rule) `isInfixOf` s]
src/Text/Pandoc/Writers/JATS.hs+4−4
@@ -102,7 +102,8 @@ docToJATS opts (Pandoc meta blocks) = do
102102 $ defField "mathml" (case writerHTMLMathMethod opts of
103103 MathML -> True
104104 _ -> False) metadata
105− case writerTemplate opts of
105+ (if writerPreferAscii opts then toEntities else id) <$>
106+ case writerTemplate opts of
106107 Nothing -> return main
107108 Just tpl -> renderTemplate' tpl context
108109
@@ -344,7 +345,7 @@ inlineToJATS _ (Str str) = return $ text $ escapeStringForXML str
344345inlineToJATS opts (Emph lst) =
345346 inTagsSimple "italic" <$> inlinesToJATS opts lst
346347inlineToJATS opts (Strong lst) =
347− inTags False "bold" [("role", "strong")] <$> inlinesToJATS opts lst
348+ inTagsSimple "bold" <$> inlinesToJATS opts lst
348349inlineToJATS opts (Strikeout lst) =
349350 inTagsSimple "strike" <$> inlinesToJATS opts lst
350351inlineToJATS opts (Superscript lst) =
@@ -352,8 +353,7 @@ inlineToJATS opts (Superscript lst) =
352353inlineToJATS opts (Subscript lst) =
353354 inTagsSimple "sub" <$> inlinesToJATS opts lst
354355inlineToJATS opts (SmallCaps lst) =
355− inTags False "sc" [("role", "smallcaps")] <$>
356− inlinesToJATS opts lst
356+ inTagsSimple "sc" <$> inlinesToJATS opts lst
357357inlineToJATS opts (Quoted SingleQuote lst) = do
358358 contents <- inlinesToJATS opts lst
359359 return $ char '‘' <> contents <> char '’'
src/Text/Pandoc/Writers/LaTeX.hs+139−64
@@ -42,8 +42,9 @@ import Data.Aeson (FromJSON, object, (.=))
4242import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isPunctuation, ord,
4343 toLower)
4444import Data.List (foldl', intercalate, intersperse, isInfixOf, nubBy,
45− stripPrefix, (\\))
45+ stripPrefix, (\\), uncons)
4646import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing)
47+import qualified Data.Map as M
4748import Data.Text (Text)
4849import qualified Data.Text as T
4950import Network.URI (unEscapeString)
@@ -63,6 +64,7 @@ import Text.Pandoc.Walk
6364import Text.Pandoc.Writers.Shared
6465import qualified Text.Parsec as P
6566import Text.Printf (printf)
67+import qualified Data.Text.Normalize as Normalize
6668
6769data WriterState =
6870 WriterState { stInNote :: Bool -- true if we're in a note
@@ -176,9 +178,9 @@ pandocToLaTeX options (Pandoc meta blocks) = do
176178 modify $ \s -> s{stCsquotes = True}
177179 let (blocks'', lastHeader) = if writerCiteMethod options == Citeproc then
178180 (blocks', [])
179− else case last blocks' of
180− Header 1 _ il -> (init blocks', il)
181− _ -> (blocks', [])
181+ else case reverse blocks' of
182+ Header 1 _ il : _ -> (init blocks', il)
183+ _ -> (blocks', [])
182184 beamer <- gets stBeamer
183185 blocks''' <- if beamer
184186 then toSlides blocks''
@@ -248,7 +250,8 @@ pandocToLaTeX options (Pandoc meta blocks) = do
248250 defField "biblatex" True
249251 _ -> id) $
250252 defField "colorlinks" (any hasStringValue
251− ["citecolor", "urlcolor", "linkcolor", "toccolor"]) $
253+ ["citecolor", "urlcolor", "linkcolor", "toccolor",
254+ "filecolor"]) $
252255 (if null dirs
253256 then id
254257 else defField "dir" ("ltr" :: String)) $
@@ -317,46 +320,110 @@ data StringContext = TextString
317320
318321-- escape things as needed for LaTeX
319322stringToLaTeX :: PandocMonad m => StringContext -> String -> LW m String
320−stringToLaTeX _ [] = return ""
321−stringToLaTeX ctx (x:xs) = do
323+stringToLaTeX context zs = do
322324 opts <- gets stOptions
323− rest <- stringToLaTeX ctx xs
324− let ligatures = isEnabled Ext_smart opts && ctx == TextString
325− let isUrl = ctx == URLString
326− return $
325+ go opts context $
326+ if writerPreferAscii opts
327+ then T.unpack $ Normalize.normalize Normalize.NFD $ T.pack zs
328+ else zs
329+ where
330+ go _ _ [] = return ""
331+ go opts ctx (x:xs) = do
332+ let ligatures = isEnabled Ext_smart opts && ctx == TextString
333+ let isUrl = ctx == URLString
334+ let mbAccentCmd =
335+ if writerPreferAscii opts && ctx == TextString
336+ then uncons xs >>= \(c,_) -> M.lookup c accents
337+ else Nothing
338+ let emits s =
339+ case mbAccentCmd of
340+ Just cmd -> ((cmd ++ "{" ++ s ++ "}") ++)
341+ <$> go opts ctx (drop 1 xs) -- drop combining accent
342+ Nothing -> (s++) <$> go opts ctx xs
343+ let emitc c =
344+ case mbAccentCmd of
345+ Just cmd -> ((cmd ++ "{" ++ [c] ++ "}") ++)
346+ <$> go opts ctx (drop 1 xs) -- drop combining accent
347+ Nothing -> (c:) <$> go opts ctx xs
327348 case x of
328− '{' -> "\\{" ++ rest
329− '}' -> "\\}" ++ rest
330− '`' | ctx == CodeString -> "\\textasciigrave{}" ++ rest
331− '$' | not isUrl -> "\\$" ++ rest
332− '%' -> "\\%" ++ rest
333− '&' -> "\\&" ++ rest
334− '_' | not isUrl -> "\\_" ++ rest
335− '#' -> "\\#" ++ rest
336− '-' | not isUrl -> case xs of
337− -- prevent adjacent hyphens from forming ligatures
338− ('-':_) -> "-\\/" ++ rest
339− _ -> '-' : rest
340− '~' | not isUrl -> "\\textasciitilde{}" ++ rest
341− '^' -> "\\^{}" ++ rest
342− '\\'| isUrl -> '/' : rest -- NB. / works as path sep even on Windows
343− | otherwise -> "\\textbackslash{}" ++ rest
344− '|' | not isUrl -> "\\textbar{}" ++ rest
345− '<' -> "\\textless{}" ++ rest
346− '>' -> "\\textgreater{}" ++ rest
347− '[' -> "{[}" ++ rest -- to avoid interpretation as
348− ']' -> "{]}" ++ rest -- optional arguments
349− '\'' | ctx == CodeString -> "\\textquotesingle{}" ++ rest
350− '\160' -> "~" ++ rest
351− '\x202F' -> "\\," ++ rest
352− '\x2026' -> "\\ldots{}" ++ rest
353− '\x2018' | ligatures -> "`" ++ rest
354− '\x2019' | ligatures -> "'" ++ rest
355− '\x201C' | ligatures -> "``" ++ rest
356− '\x201D' | ligatures -> "''" ++ rest
357− '\x2014' | ligatures -> "---" ++ rest
358− '\x2013' | ligatures -> "--" ++ rest
359− _ -> x : rest
349+ '{' -> emits "\\{"
350+ '}' -> emits "\\}"
351+ '`' | ctx == CodeString -> emits "\\textasciigrave{}"
352+ '$' | not isUrl -> emits "\\$"
353+ '%' -> emits "\\%"
354+ '&' -> emits "\\&"
355+ '_' | not isUrl -> emits "\\_"
356+ '#' -> emits "\\#"
357+ '-' | not isUrl -> case xs of
358+ -- prevent adjacent hyphens from forming ligatures
359+ ('-':_) -> emits "-\\/"
360+ _ -> emitc '-'
361+ '~' | not isUrl -> emits "\\textasciitilde{}"
362+ '^' -> emits "\\^{}"
363+ '\\'| isUrl -> emitc '/' -- NB. / works as path sep even on Windows
364+ | otherwise -> emits "\\textbackslash{}"
365+ '|' | not isUrl -> emits "\\textbar{}"
366+ '<' -> emits "\\textless{}"
367+ '>' -> emits "\\textgreater{}"
368+ '[' -> emits "{[}" -- to avoid interpretation as
369+ ']' -> emits "{]}" -- optional arguments
370+ '\'' | ctx == CodeString -> emits "\\textquotesingle{}"
371+ '\160' -> emits "~"
372+ '\x202F' -> emits "\\,"
373+ '\x2026' -> emits "\\ldots{}"
374+ '\x2018' | ligatures -> emits "`"
375+ '\x2019' | ligatures -> emits "'"
376+ '\x201C' | ligatures -> emits "``"
377+ '\x201D' | ligatures -> emits "''"
378+ '\x2014' | ligatures -> emits "---"
379+ '\x2013' | ligatures -> emits "--"
380+ _ | writerPreferAscii opts
381+ -> case x of
382+ 'ı' -> emits "\\i "
383+ 'ȷ' -> emits "\\j "
384+ 'å' -> emits "\\aa "
385+ 'Å' -> emits "\\AA "
386+ 'ß' -> emits "\\ss "
387+ 'ø' -> emits "\\o "
388+ 'Ø' -> emits "\\O "
389+ 'Ł' -> emits "\\L "
390+ 'ł' -> emits "\\l "
391+ 'æ' -> emits "\\ae "
392+ 'Æ' -> emits "\\AE "
393+ 'œ' -> emits "\\oe "
394+ 'Œ' -> emits "\\OE "
395+ '£' -> emits "\\pounds "
396+ '€' -> emits "\\euro "
397+ '©' -> emits "\\copyright "
398+ _ -> emitc x
399+ | otherwise -> emitc x
400+
401+accents :: M.Map Char String
402+accents = M.fromList
403+ [ ('\779' , "\\H")
404+ , ('\768' , "\\`")
405+ , ('\769' , "\\'")
406+ , ('\770' , "\\^")
407+ , ('\771' , "\\~")
408+ , ('\776' , "\\\"")
409+ , ('\775' , "\\.")
410+ , ('\772' , "\\=")
411+ , ('\781' , "\\|")
412+ , ('\817' , "\\b")
413+ , ('\807' , "\\c")
414+ , ('\783' , "\\G")
415+ , ('\777' , "\\h")
416+ , ('\803' , "\\d")
417+ , ('\785' , "\\f")
418+ , ('\778' , "\\r")
419+ , ('\865' , "\\t")
420+ , ('\782' , "\\U")
421+ , ('\780' , "\\v")
422+ , ('\774' , "\\u")
423+ , ('\808' , "\\k")
424+ , ('\785' , "\\newtie")
425+ , ('\8413', "\\textcircled")
426+ ]
360427
361428toLabel :: PandocMonad m => String -> LW m String
362429toLabel z = go `fmap` stringToLaTeX URLString z
@@ -402,7 +469,8 @@ elementToBeamer slideLevel (Sec lvl _num (ident,classes,kvs) tit elts)
402469 not (null $ query hasCodeBlock elts ++ query hasCode elts)
403470 let frameoptions = ["allowdisplaybreaks", "allowframebreaks", "fragile",
404471 "b", "c", "t", "environment",
405− "label", "plain", "shrink", "standout"]
472+ "label", "plain", "shrink", "standout",
473+ "noframenumbering"]
406474 let optionslist = ["fragile" | fragile && isNothing (lookup "fragile" kvs)] ++
407475 [k | k <- classes, k `elem` frameoptions] ++
408476 [k ++ "=" ++ v | (k,v) <- kvs, k `elem` frameoptions]
@@ -487,7 +555,7 @@ blockToLaTeX (Div (identifier,classes,kvs) bs)
487555 then \contents ->
488556 let fromPct xs =
489557 case reverse xs of
490− '%':ds -> '0':'.': reverse ds
558+ '%':ds -> showFl (read (reverse ds) / 100 :: Double)
491559 _ -> xs
492560 w = maybe "0.48" fromPct (lookup "width" kvs)
493561 in inCmd "begin" "column" <>
@@ -517,25 +585,15 @@ blockToLaTeX (Plain lst) =
517585 inlineListToLaTeX $ dropWhile isLineBreakOrSpace lst
518586-- title beginning with fig: indicates that the image is a figure
519587blockToLaTeX (Para [Image attr@(ident, _, _) txt (src,'f':'i':'g':':':tit)]) = do
520− inNote <- gets stInNote
521− inMinipage <- gets stInMinipage
522− modify $ \st -> st{ stInMinipage = True, stNotes = [] }
523− capt <- inlineListToLaTeX txt
524− notes <- gets stNotes
525− modify $ \st -> st{ stInMinipage = False, stNotes = [] }
526−
527− -- We can't have footnotes in the list of figures, so remove them:
528− captForLof <- if null notes
529− then return empty
530− else brackets <$> inlineListToLaTeX (walk deNote txt)
531− img <- inlineToLaTeX (Image attr txt (src,tit))
532− let footnotes = notesToLaTeX notes
588+ (capt, captForLof, footnotes) <- getCaption txt
533589 lab <- labelFor ident
534590 let caption = "\\caption" <> captForLof <> braces capt <> lab
591+ img <- inlineToLaTeX (Image attr txt (src,tit))
535592 innards <- hypertarget True ident $
536593 "\\centering" $$ img $$ caption <> cr
537594 let figure = cr <> "\\begin{figure}" $$ innards $$ "\\end{figure}"
538− return $ if inNote || inMinipage
595+ st <- get
596+ return $ if stInNote st || stInMinipage st
539597 -- can't have figures in notes or minipage (here, table cell)
540598 -- http://www.tex.ac.uk/FAQ-ouparmd.html
541599 then "\\begin{center}" $$ img $+$ capt $$ "\\end{center}"
@@ -714,11 +772,11 @@ blockToLaTeX (Header level (id',classes,_) lst) = do
714772 modify $ \s -> s{stInHeading = False}
715773 return hdr
716774blockToLaTeX (Table caption aligns widths heads rows) = do
775+ (captionText, captForLof, footnotes) <- getCaption caption
717776 let toHeaders hs = do contents <- tableRowToLaTeX True aligns widths hs
718777 return ("\\toprule" $$ contents $$ "\\midrule")
719778 let removeNote (Note _) = Span ("", [], []) []
720779 removeNote x = x
721− captionText <- inlineListToLaTeX caption
722780 firsthead <- if isEmpty captionText || all null heads
723781 then return empty
724782 else ($$ text "\\endfirsthead") <$> toHeaders heads
@@ -730,8 +788,8 @@ blockToLaTeX (Table caption aligns widths heads rows) = do
730788 else walk removeNote heads)
731789 let capt = if isEmpty captionText
732790 then empty
733− else text "\\caption" <>
734− braces captionText <> "\\tabularnewline"
791+ else "\\caption" <> captForLof <> braces captionText
792+ <> "\\tabularnewline"
735793 rows' <- mapM (tableRowToLaTeX False aligns widths) rows
736794 let colDescriptors = text $ concatMap toColDescriptor aligns
737795 modify $ \s -> s{ stTable = True }
@@ -745,6 +803,21 @@ blockToLaTeX (Table caption aligns widths heads rows) = do
745803 $$ vcat rows'
746804 $$ "\\bottomrule"
747805 $$ "\\end{longtable}"
806+ $$ footnotes
807+
808+getCaption :: PandocMonad m => [Inline] -> LW m (Doc, Doc, Doc)
809+getCaption txt = do
810+ inMinipage <- gets stInMinipage
811+ modify $ \st -> st{ stInMinipage = True, stNotes = [] }
812+ capt <- inlineListToLaTeX txt
813+ notes <- gets stNotes
814+ modify $ \st -> st{ stInMinipage = inMinipage, stNotes = [] }
815+ -- We can't have footnotes in the list of figures/tables, so remove them:
816+ captForLof <- if null notes
817+ then return empty
818+ else brackets <$> inlineListToLaTeX (walk deNote txt)
819+ let footnotes = notesToLaTeX notes
820+ return (capt, captForLof, footnotes)
748821
749822toColDescriptor :: Alignment -> String
750823toColDescriptor align =
@@ -863,9 +936,11 @@ defListItemToLaTeX (term, defs) = do
863936 else term'
864937 def' <- liftM vsep $ mapM blockListToLaTeX defs
865938 return $ case defs of
866− ((Header{} : _) : _) ->
939+ ((Header{} : _) : _) ->
940+ "\\item" <> brackets term'' <> " ~ " $$ def'
941+ ((CodeBlock{} : _) : _) -> -- see #4662
867942 "\\item" <> brackets term'' <> " ~ " $$ def'
868− _ ->
943+ _ ->
869944 "\\item" <> brackets term'' $$ def'
870945
871946-- | Craft the section header, inserting the secton reference, if supplied.
src/Text/Pandoc/Writers/Man.hs+4−29
@@ -107,7 +107,8 @@ pandocToMan opts (Pandoc meta blocks) = do
107107 $ defField "has-tables" hasTables
108108 $ defField "hyphenate" True
109109 $ defField "pandoc-version" pandocVersion metadata
110− case writerTemplate opts of
110+ (if writerPreferAscii opts then groffEscape else id) <$>
111+ case writerTemplate opts of
111112 Nothing -> return main
112113 Just tpl -> renderTemplate' tpl context
113114
@@ -152,32 +153,6 @@ escapeCode = intercalate "\n" . map escapeLine . lines where
152153-- line. groff/troff treats the line-ending period differently.
153154-- See http://code.google.com/p/pandoc/issues/detail?id=148.
154155
155−-- | Returns the first sentence in a list of inlines, and the rest.
156−breakSentence :: [Inline] -> ([Inline], [Inline])
157−breakSentence [] = ([],[])
158−breakSentence xs =
159− let isSentenceEndInline (Str ys@(_:_)) | last ys == '.' = True
160− isSentenceEndInline (Str ys@(_:_)) | last ys == '?' = True
161− isSentenceEndInline LineBreak = True
162− isSentenceEndInline _ = False
163− (as, bs) = break isSentenceEndInline xs
164− in case bs of
165− [] -> (as, [])
166− [c] -> (as ++ [c], [])
167− (c:Space:cs) -> (as ++ [c], cs)
168− (c:SoftBreak:cs) -> (as ++ [c], cs)
169− (Str ".":Str (')':ys):cs) -> (as ++ [Str ".", Str (')':ys)], cs)
170− (x@(Str ('.':')':_)):cs) -> (as ++ [x], cs)
171− (LineBreak:x@(Str ('.':_)):cs) -> (as ++[LineBreak], x:cs)
172− (c:cs) -> (as ++ [c] ++ ds, es)
173− where (ds, es) = breakSentence cs
174−
175−-- | Split a list of inlines into sentences.
176−splitSentences :: [Inline] -> [[Inline]]
177−splitSentences xs =
178− let (sent, rest) = breakSentence xs
179− in if null rest then [sent] else sent : splitSentences rest
180−
181156-- | Convert Pandoc block element to man.
182157blockToMan :: PandocMonad m
183158 => WriterOptions -- ^ Options
@@ -325,11 +300,11 @@ blockListToMan :: PandocMonad m
325300 -> [Block] -- ^ List of block elements
326301 -> StateT WriterState m Doc
327302blockListToMan opts blocks =
328− mapM (blockToMan opts) blocks >>= (return . vcat)
303+ vcat <$> mapM (blockToMan opts) blocks
329304
330305-- | Convert list of Pandoc inline elements to man.
331306inlineListToMan :: PandocMonad m => WriterOptions -> [Inline] -> StateT WriterState m Doc
332−inlineListToMan opts lst = mapM (inlineToMan opts) lst >>= (return . hcat)
307+inlineListToMan opts lst = hcat <$> mapM (inlineToMan opts) lst
333308
334309-- | Convert Pandoc inline element to man.
335310inlineToMan :: PandocMonad m => WriterOptions -> Inline -> StateT WriterState m Doc
src/Text/Pandoc/Writers/Markdown.hs+20−35
@@ -38,7 +38,7 @@ module Text.Pandoc.Writers.Markdown (writeMarkdown, writePlain) where
3838import Prelude
3939import Control.Monad.Reader
4040import Control.Monad.State.Strict
41−import Data.Char (chr, isPunctuation, isSpace, ord, isAlphaNum)
41+import Data.Char (isPunctuation, isSpace, isAlphaNum)
4242import Data.Default
4343import qualified Data.HashMap.Strict as H
4444import Data.List (find, group, intersperse, sortBy, stripPrefix, transpose)
@@ -50,7 +50,7 @@ import qualified Data.Set as Set
5050import Data.Text (Text)
5151import qualified Data.Text as T
5252import qualified Data.Vector as V
53−import Data.Yaml (Value (Array, Bool, Number, Object, String))
53+import Data.Aeson (Value (Array, Bool, Number, Object, String))
5454import Network.HTTP (urlEncode)
5555import Text.HTML.TagSoup (Tag (..), isTagText, parseTags)
5656import Text.Pandoc.Class (PandocMonad, report)
@@ -298,7 +298,8 @@ escapeString opts (c:cs) =
298298 '\\':c:escapeString opts cs
299299 '|' | isEnabled Ext_pipe_tables opts -> '\\':'|':escapeString opts cs
300300 '^' | isEnabled Ext_superscript opts -> '\\':'^':escapeString opts cs
301− '~' | isEnabled Ext_subscript opts -> '\\':'~':escapeString opts cs
301+ '~' | isEnabled Ext_subscript opts ||
302+ isEnabled Ext_strikeout opts -> '\\':'~':escapeString opts cs
302303 '$' | isEnabled Ext_tex_math_dollars opts -> '\\':'$':escapeString opts cs
303304 '\'' | isEnabled Ext_smart opts -> '\\':'\'':escapeString opts cs
304305 '"' | isEnabled Ext_smart opts -> '\\':'"':escapeString opts cs
@@ -452,8 +453,14 @@ blockToMarkdown' opts (Plain inlines) = do
452453 | otherwise -> contents
453454 return $ contents' <> cr
454455-- title beginning with fig: indicates figure
455−blockToMarkdown' opts (Para [Image attr alt (src,'f':'i':'g':':':tit)]) =
456− blockToMarkdown opts (Para [Image attr alt (src,tit)])
456+blockToMarkdown' opts (Para [Image attr alt (src,'f':'i':'g':':':tit)])
457+ | isEnabled Ext_raw_html opts &&
458+ not (isEnabled Ext_link_attributes opts) &&
459+ attr /= nullAttr = -- use raw HTML
460+ (text . T.unpack . T.strip) <$>
461+ writeHtml5String opts{ writerTemplate = Nothing }
462+ (Pandoc nullMeta [Para [Image attr alt (src,"fig:" ++ tit)]])
463+ | otherwise = blockToMarkdown opts (Para [Image attr alt (src,tit)])
457464blockToMarkdown' opts (Para inlines) =
458465 (<> blankline) `fmap` blockToMarkdown opts (Plain inlines)
459466blockToMarkdown' opts (LineBlock lns) =
@@ -619,7 +626,7 @@ blockToMarkdown' opts t@(Table caption aligns widths headers rows) = do
619626 (all null headers) aligns' widths' headers rows
620627 | isEnabled Ext_raw_html opts -> fmap (id,) $
621628 (text . T.unpack) <$>
622− (writeHtml5String def $ Pandoc nullMeta [t])
629+ (writeHtml5String opts{ writerTemplate = Nothing } $ Pandoc nullMeta [t])
623630 | hasSimpleCells &&
624631 isEnabled Ext_pipe_tables opts -> do
625632 rawHeaders <- padRow <$> mapM (blockListToMarkdown opts) headers
@@ -976,6 +983,11 @@ isRight (Left _) = False
976983
977984-- | Convert Pandoc inline element to markdown.
978985inlineToMarkdown :: PandocMonad m => WriterOptions -> Inline -> MD m Doc
986+inlineToMarkdown opts (Span ("",["emoji"],kvs) [Str s]) = do
987+ case lookup "data-emoji" kvs of
988+ Just emojiname | isEnabled Ext_emoji opts ->
989+ return $ ":" <> text emojiname <> ":"
990+ _ -> inlineToMarkdown opts (Str s)
979991inlineToMarkdown opts (Span attrs ils) = do
980992 plain <- asks envPlain
981993 contents <- inlineListToMarkdown opts ils
@@ -1172,7 +1184,7 @@ inlineToMarkdown opts lnk@(Link attr txt (src, tit))
11721184 not (isEnabled Ext_link_attributes opts) &&
11731185 attr /= nullAttr = -- use raw HTML
11741186 (text . T.unpack . T.strip) <$>
1175− writeHtml5String def (Pandoc nullMeta [Plain [lnk]])
1187+ writeHtml5String opts{ writerTemplate = Nothing } (Pandoc nullMeta [Plain [lnk]])
11761188 | otherwise = do
11771189 plain <- asks envPlain
11781190 linktext <- inlineListToMarkdown opts txt
@@ -1212,7 +1224,7 @@ inlineToMarkdown opts img@(Image attr alternate (source, tit))
12121224 not (isEnabled Ext_link_attributes opts) &&
12131225 attr /= nullAttr = -- use raw HTML
12141226 (text . T.unpack . T.strip) <$>
1215− writeHtml5String def (Pandoc nullMeta [Plain [img]])
1227+ writeHtml5String opts{ writerTemplate = Nothing } (Pandoc nullMeta [Plain [img]])
12161228 | otherwise = do
12171229 plain <- asks envPlain
12181230 let txt = if null alternate || alternate == [Str source]
@@ -1237,33 +1249,6 @@ makeMathPlainer = walk go
12371249 go (Emph xs) = Span nullAttr xs
12381250 go x = x
12391251
1240−toSuperscript :: Char -> Maybe Char
1241−toSuperscript '1' = Just '\x00B9'
1242−toSuperscript '2' = Just '\x00B2'
1243−toSuperscript '3' = Just '\x00B3'
1244−toSuperscript '+' = Just '\x207A'
1245−toSuperscript '-' = Just '\x207B'
1246−toSuperscript '=' = Just '\x207C'
1247−toSuperscript '(' = Just '\x207D'
1248−toSuperscript ')' = Just '\x207E'
1249−toSuperscript c
1250− | c >= '0' && c <= '9' =
1251− Just $ chr (0x2070 + (ord c - 48))
1252− | isSpace c = Just c
1253− | otherwise = Nothing
1254−
1255−toSubscript :: Char -> Maybe Char
1256−toSubscript '+' = Just '\x208A'
1257−toSubscript '-' = Just '\x208B'
1258−toSubscript '=' = Just '\x208C'
1259−toSubscript '(' = Just '\x208D'
1260−toSubscript ')' = Just '\x208E'
1261−toSubscript c
1262− | c >= '0' && c <= '9' =
1263− Just $ chr (0x2080 + (ord c - 48))
1264− | isSpace c = Just c
1265− | otherwise = Nothing
1266−
12671252lineBreakToSpace :: Inline -> Inline
12681253lineBreakToSpace LineBreak = Space
12691254lineBreakToSpace SoftBreak = Space
src/Text/Pandoc/Writers/Math.hs+1−1
@@ -55,4 +55,4 @@ defaultMathJaxURL :: String
5555defaultMathJaxURL = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/"
5656
5757defaultKaTeXURL :: String
58−defaultKaTeXURL = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.8.3/"
58+defaultKaTeXURL = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/"
src/Text/Pandoc/Writers/MediaWiki.hs+1
@@ -313,6 +313,7 @@ tableCellToMediaWiki headless rownum (alignment, width, bs) = do
313313 let sep = case bs of
314314 [Plain _] -> " "
315315 [Para _] -> " "
316+ [] -> ""
316317 _ -> "\n"
317318 return $ marker ++ attr ++ sep ++ trimr contents
318319
src/Text/Pandoc/Writers/Ms.hs+3−28
@@ -127,7 +127,8 @@ pandocToMs opts (Pandoc meta blocks) = do
127127 $ defField "title-meta" titleMeta
128128 $ defField "author-meta" (intercalate "; " authorsMeta)
129129 $ defField "highlighting-macros" highlightingMacros metadata
130− case writerTemplate opts of
130+ (if writerPreferAscii opts then groffEscape else id) <$>
131+ case writerTemplate opts of
131132 Nothing -> return main
132133 Just tpl -> renderTemplate' tpl context
133134
@@ -188,32 +189,6 @@ escapeCode = intercalate "\n" . map escapeLine . lines
188189-- line. groff/troff treats the line-ending period differently.
189190-- See http://code.google.com/p/pandoc/issues/detail?id=148.
190191
191−-- | Returns the first sentence in a list of inlines, and the rest.
192−breakSentence :: [Inline] -> ([Inline], [Inline])
193−breakSentence [] = ([],[])
194−breakSentence xs =
195− let isSentenceEndInline (Str ys@(_:_)) | last ys == '.' = True
196− isSentenceEndInline (Str ys@(_:_)) | last ys == '?' = True
197− isSentenceEndInline LineBreak = True
198− isSentenceEndInline _ = False
199− (as, bs) = break isSentenceEndInline xs
200− in case bs of
201− [] -> (as, [])
202− [c] -> (as ++ [c], [])
203− (c:Space:cs) -> (as ++ [c], cs)
204− (c:SoftBreak:cs) -> (as ++ [c], cs)
205− (Str ".":Str (')':ys):cs) -> (as ++ [Str ".", Str (')':ys)], cs)
206− (x@(Str ('.':')':_)):cs) -> (as ++ [x], cs)
207− (LineBreak:x@(Str ('.':_)):cs) -> (as ++[LineBreak], x:cs)
208− (c:cs) -> (as ++ [c] ++ ds, es)
209− where (ds, es) = breakSentence cs
210−
211−-- | Split a list of inlines into sentences.
212−splitSentences :: [Inline] -> [[Inline]]
213−splitSentences xs =
214− let (sent, rest) = breakSentence xs
215− in if null rest then [sent] else sent : splitSentences rest
216−
217192blockToMs :: PandocMonad m
218193 => WriterOptions -- ^ Options
219194 -> Block -- ^ Block element
@@ -434,7 +409,7 @@ blockListToMs :: PandocMonad m
434409 -> [Block] -- ^ List of block elements
435410 -> MS m Doc
436411blockListToMs opts blocks =
437− mapM (blockToMs opts) blocks >>= (return . vcat)
412+ vcat <$> mapM (blockToMs opts) blocks
438413
439414-- | Convert list of Pandoc inline elements to ms.
440415inlineListToMs :: PandocMonad m => WriterOptions -> [Inline] -> MS m Doc
src/Text/Pandoc/Writers/Muse.hs+189−56
@@ -46,7 +46,7 @@ module Text.Pandoc.Writers.Muse (writeMuse) where
4646import Prelude
4747import Control.Monad.Reader
4848import Control.Monad.State.Strict
49−import Data.Char (isSpace, isDigit, isAsciiUpper, isAsciiLower)
49+import Data.Char (isSpace, isAlphaNum, isDigit, isAsciiUpper, isAsciiLower)
5050import Data.Default
5151import Data.Text (Text)
5252import Data.List (intersperse, transpose, isInfixOf)
@@ -70,20 +70,24 @@ data WriterEnv =
7070 WriterEnv { envOptions :: WriterOptions
7171 , envTopLevel :: Bool
7272 , envInsideBlock :: Bool
73− , envInlineStart :: Bool
73+ , envInlineStart :: Bool -- ^ True if there is only whitespace since last newline
7474 , envInsideLinkDescription :: Bool -- ^ Escape ] if True
75− , envAfterSpace :: Bool
75+ , envAfterSpace :: Bool -- ^ There is whitespace (not just newline) before
7676 , envOneLine :: Bool -- ^ True if newlines are not allowed
77+ , envInsideAsterisks :: Bool -- ^ True if outer element is emphasis with asterisks
78+ , envNearAsterisks :: Bool -- ^ Rendering inline near asterisks
7779 }
7880
7981data WriterState =
8082 WriterState { stNotes :: Notes
8183 , stIds :: Set.Set String
84+ , stUseTags :: Bool -- ^ Use tags for emphasis, for example because previous character is a letter
8285 }
8386
8487instance Default WriterState
8588 where def = WriterState { stNotes = []
8689 , stIds = Set.empty
90+ , stUseTags = False
8791 }
8892
8993evalMuse :: PandocMonad m => Muse m a -> WriterEnv -> WriterState -> m a
@@ -103,6 +107,8 @@ writeMuse opts document =
103107 , envInsideLinkDescription = False
104108 , envAfterSpace = False
105109 , envOneLine = False
110+ , envInsideAsterisks = False
111+ , envNearAsterisks = False
106112 }
107113
108114-- | Return Muse representation of document.
@@ -212,6 +218,7 @@ blockToMuse (BulletList items) = do
212218 => [Block]
213219 -> Muse m Doc
214220 bulletListItemToMuse item = do
221+ modify $ \st -> st { stUseTags = False }
215222 contents <- blockListToMuse item
216223 return $ hang 2 "- " contents
217224blockToMuse (DefinitionList items) = do
@@ -223,16 +230,18 @@ blockToMuse (DefinitionList items) = do
223230 => ([Inline], [[Block]])
224231 -> Muse m Doc
225232 definitionListItemToMuse (label, defs) = do
233+ modify $ \st -> st { stUseTags = False }
226234 label' <- local (\env -> env { envOneLine = True, envAfterSpace = True }) $ inlineListToMuse' label
227235 contents <- vcat <$> mapM descriptionToMuse defs
228236 let ind = offset label'
229− return $ hang ind label' contents
237+ return $ hang ind (nowrap label') contents
230238 descriptionToMuse :: PandocMonad m
231239 => [Block]
232240 -> Muse m Doc
233241 descriptionToMuse desc = hang 4 " :: " <$> blockListToMuse desc
234242blockToMuse (Header level (ident,_,_) inlines) = do
235243 opts <- asks envOptions
244+ topLevel <- asks envTopLevel
236245 contents <- local (\env -> env { envOneLine = True }) $ inlineListToMuse' inlines
237246 ids <- gets stIds
238247 let autoId = uniqueIdent inlines ids
@@ -241,8 +250,8 @@ blockToMuse (Header level (ident,_,_) inlines) = do
241250 let attr' = if null ident || (isEnabled Ext_auto_identifiers opts && ident == autoId)
242251 then empty
243252 else "#" <> text ident <> cr
244− let header' = text $ replicate level '*'
245− return $ blankline <> attr' $$ nowrap (header' <> space <> contents) <> blankline
253+ let header' = if topLevel then (text $ replicate level '*') <> space else mempty
254+ return $ blankline <> attr' $$ nowrap (header' <> contents) <> blankline
246255-- https://www.gnu.org/software/emacs-muse/manual/muse.html#Horizontal-Rules-and-Anchors
247256blockToMuse HorizontalRule = return $ blankline $$ "----" $$ blankline
248257blockToMuse (Table caption _ _ headers rows) = do
@@ -284,7 +293,11 @@ noteToMuse :: PandocMonad m
284293 -> [Block]
285294 -> Muse m Doc
286295noteToMuse num note =
287− hang (length marker) (text marker) <$> blockListToMuse note
296+ hang (length marker) (text marker) <$>
297+ (local (\env -> env { envInsideBlock = True
298+ , envInlineStart = True
299+ , envAfterSpace = True
300+ }) $ blockListToMuse note)
288301 where
289302 marker = "[" ++ show num ++ "] "
290303
@@ -295,6 +308,12 @@ escapeString s =
295308 substitute "</verbatim>" "<</verbatim><verbatim>/verbatim>" s ++
296309 "</verbatim>"
297310
311+-- | Replace newlines with spaces
312+replaceNewlines :: String -> String
313+replaceNewlines ('\n':xs) = ' ':replaceNewlines xs
314+replaceNewlines (x:xs) = x:replaceNewlines xs
315+replaceNewlines [] = []
316+
298317startsWithMarker :: (Char -> Bool) -> String -> Bool
299318startsWithMarker f (' ':xs) = startsWithMarker f xs
300319startsWithMarker f (x:xs) =
@@ -321,16 +340,28 @@ containsFootnotes = p
321340 s (_:xs) = p xs
322341 s [] = False
323342
324−conditionalEscapeString :: Bool -> String -> String
325−conditionalEscapeString isInsideLinkDescription s =
326− if any (`elem` ("#*<=|" :: String)) s ||
327− "::" `isInfixOf` s ||
328− "~~" `isInfixOf` s ||
329− "[[" `isInfixOf` s ||
330− ("]" `isInfixOf` s && isInsideLinkDescription) ||
331− containsFootnotes s
332− then escapeString s
333− else s
343+-- | Return True if string should be escaped with <verbatim> tags
344+shouldEscapeString :: PandocMonad m
345+ => String
346+ -> Muse m Bool
347+shouldEscapeString s = do
348+ insideLink <- asks envInsideLinkDescription
349+ return $ null s ||
350+ any (`elem` ("#*<=|" :: String)) s ||
351+ "::" `isInfixOf` s ||
352+ "~~" `isInfixOf` s ||
353+ "[[" `isInfixOf` s ||
354+ ("]" `isInfixOf` s && insideLink) ||
355+ containsFootnotes s
356+
357+conditionalEscapeString :: PandocMonad m
358+ => String
359+ -> Muse m String
360+conditionalEscapeString s = do
361+ shouldEscape <- shouldEscapeString s
362+ return $ if shouldEscape
363+ then escapeString s
364+ else s
334365
335366-- Expand Math and Cite before normalizing inline list
336367preprocessInlineList :: PandocMonad m
@@ -389,6 +420,19 @@ fixNotes (Space : n@Note{} : rest) = Str " " : n : fixNotes rest
389420fixNotes (SoftBreak : n@Note{} : rest) = Str " " : n : fixNotes rest
390421fixNotes (x:xs) = x : fixNotes xs
391422
423+startsWithSpace :: [Inline] -> Bool
424+startsWithSpace (Space:_) = True
425+startsWithSpace (SoftBreak:_) = True
426+startsWithSpace (Str s:_) = stringStartsWithSpace s
427+startsWithSpace _ = False
428+
429+endsWithSpace :: [Inline] -> Bool
430+endsWithSpace [Space] = True
431+endsWithSpace [SoftBreak] = True
432+endsWithSpace [Str s] = stringStartsWithSpace $ reverse s
433+endsWithSpace (_:xs) = endsWithSpace xs
434+endsWithSpace [] = False
435+
392436urlEscapeBrackets :: String -> String
393437urlEscapeBrackets (']':xs) = '%':'5':'D':urlEscapeBrackets xs
394438urlEscapeBrackets (x:xs) = x:urlEscapeBrackets xs
@@ -397,22 +441,33 @@ urlEscapeBrackets [] = []
397441isHorizontalRule :: String -> Bool
398442isHorizontalRule s = length s >= 4 && all (== '-') s
399443
400−startsWithSpace :: String -> Bool
401−startsWithSpace (x:_) = isSpace x
402−startsWithSpace [] = False
444+stringStartsWithSpace :: String -> Bool
445+stringStartsWithSpace (x:_) = isSpace x
446+stringStartsWithSpace "" = False
403447
404448fixOrEscape :: Bool -> Inline -> Bool
405449fixOrEscape sp (Str "-") = sp
406−fixOrEscape sp (Str ";") = not sp
407−fixOrEscape _ (Str ">") = True
450+fixOrEscape sp (Str s@('-':x:_)) = (sp && isSpace x) || isHorizontalRule s
451+fixOrEscape sp (Str (";")) = not sp
452+fixOrEscape sp (Str (';':x:_)) = not sp && isSpace x
453+fixOrEscape _ (Str (">")) = True
454+fixOrEscape _ (Str ('>':x:_)) = isSpace x
408455fixOrEscape sp (Str s) = (sp && (startsWithMarker isDigit s ||
409456 startsWithMarker isAsciiLower s ||
410457 startsWithMarker isAsciiUpper s))
411− || isHorizontalRule s || startsWithSpace s
458+ || stringStartsWithSpace s
412459fixOrEscape _ Space = True
413460fixOrEscape _ SoftBreak = True
414461fixOrEscape _ _ = False
415462
463+inlineListStartsWithAlnum :: PandocMonad m
464+ => [Inline]
465+ -> Muse m Bool
466+inlineListStartsWithAlnum (Str s:_) = do
467+ esc <- shouldEscapeString s
468+ return $ esc || isAlphaNum (head s)
469+inlineListStartsWithAlnum _ = return False
470+
416471-- | Convert list of Pandoc inline elements to Muse
417472renderInlineList :: PandocMonad m
418473 => [Inline]
@@ -424,86 +479,159 @@ renderInlineList (x:xs) = do
424479 start <- asks envInlineStart
425480 afterSpace <- asks envAfterSpace
426481 topLevel <- asks envTopLevel
427− r <- inlineToMuse x
482+ insideAsterisks <- asks envInsideAsterisks
483+ nearAsterisks <- asks envNearAsterisks
484+ useTags <- gets stUseTags
485+ alnumNext <- inlineListStartsWithAlnum xs
486+ let newUseTags = useTags || alnumNext
487+ modify $ \st -> st { stUseTags = newUseTags }
488+
489+ r <- local (\env -> env { envInlineStart = False
490+ , envInsideAsterisks = False
491+ , envNearAsterisks = nearAsterisks || (null xs && insideAsterisks)
492+ }) $ inlineToMuse x
428493 opts <- asks envOptions
429494 let isNewline = (x == SoftBreak && writerWrapText opts == WrapPreserve) || x == LineBreak
430495 lst' <- local (\env -> env { envInlineStart = isNewline
431496 , envAfterSpace = x == Space || (not topLevel && isNewline)
497+ , envNearAsterisks = False
432498 }) $ renderInlineList xs
433499 if start && fixOrEscape afterSpace x
434500 then pure (text "<verbatim></verbatim>" <> r <> lst')
435501 else pure (r <> lst')
436502
437503-- | Normalize and convert list of Pandoc inline elements to Muse.
438−inlineListToMuse'' :: PandocMonad m
439− => Bool
440− -> [Inline]
441− -> Muse m Doc
442−inlineListToMuse'' start lst = do
443− lst' <- (normalizeInlineList . fixNotes) <$> preprocessInlineList (map (removeKeyValues . replaceSmallCaps) lst)
444− topLevel <- asks envTopLevel
445− afterSpace <- asks envAfterSpace
446− local (\env -> env { envInlineStart = start
447− , envAfterSpace = afterSpace || (start && not topLevel)
448− }) $ renderInlineList lst'
504+inlineListToMuse :: PandocMonad m
505+ => [Inline]
506+ -> Muse m Doc
507+inlineListToMuse lst = do
508+ lst' <- normalizeInlineList . fixNotes <$> preprocessInlineList (map (removeKeyValues . replaceSmallCaps) lst)
509+ insideAsterisks <- asks envInsideAsterisks
510+ modify $ \st -> st { stUseTags = False } -- Previous character is likely a '>' or some other markup
511+ local (\env -> env { envNearAsterisks = insideAsterisks }) $ renderInlineList lst'
449512
450513inlineListToMuse' :: PandocMonad m => [Inline] -> Muse m Doc
451−inlineListToMuse' = inlineListToMuse'' True
452−
453−inlineListToMuse :: PandocMonad m => [Inline] -> Muse m Doc
454−inlineListToMuse = inlineListToMuse'' False
514+inlineListToMuse' lst = do
515+ topLevel <- asks envTopLevel
516+ afterSpace <- asks envAfterSpace
517+ local (\env -> env { envInlineStart = True
518+ , envAfterSpace = afterSpace || not topLevel
519+ }) $ inlineListToMuse lst
455520
456521-- | Convert Pandoc inline element to Muse.
457522inlineToMuse :: PandocMonad m
458523 => Inline
459524 -> Muse m Doc
460525inlineToMuse (Str str) = do
461− insideLink <- asks envInsideLinkDescription
462− return $ text $ conditionalEscapeString insideLink str
526+ escapedStr <- conditionalEscapeString $ replaceNewlines str
527+ let useTags = isAlphaNum $ last escapedStr -- escapedStr is never empty because empty strings are escaped
528+ modify $ \st -> st { stUseTags = useTags }
529+ return $ text escapedStr
530+inlineToMuse (Emph [Strong lst]) = do
531+ useTags <- gets stUseTags
532+ let lst' = normalizeInlineList lst
533+ if useTags
534+ then do contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
535+ modify $ \st -> st { stUseTags = False }
536+ return $ "<em>**" <> contents <> "**</em>"
537+ else if null lst' || startsWithSpace lst' || endsWithSpace lst'
538+ then do
539+ contents <- local (\env -> env { envInsideAsterisks = False }) $ inlineListToMuse lst'
540+ modify $ \st -> st { stUseTags = True }
541+ return $ "*<strong>" <> contents <> "</strong>*"
542+ else do
543+ contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
544+ modify $ \st -> st { stUseTags = True }
545+ return $ "***" <> contents <> "***"
463546inlineToMuse (Emph lst) = do
464− contents <- inlineListToMuse lst
465− return $ "<em>" <> contents <> "</em>"
547+ useTags <- gets stUseTags
548+ let lst' = normalizeInlineList lst
549+ if useTags || null lst' || startsWithSpace lst' || endsWithSpace lst'
550+ then do contents <- inlineListToMuse lst'
551+ return $ "<em>" <> contents <> "</em>"
552+ else do contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
553+ modify $ \st -> st { stUseTags = True }
554+ return $ "*" <> contents <> "*"
555+inlineToMuse (Strong [Emph lst]) = do
556+ useTags <- gets stUseTags
557+ let lst' = normalizeInlineList lst
558+ if useTags
559+ then do contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
560+ modify $ \st -> st { stUseTags = False }
561+ return $ "<strong>*" <> contents <> "*</strong>"
562+ else if null lst' || startsWithSpace lst' || endsWithSpace lst'
563+ then do
564+ contents <- local (\env -> env { envInsideAsterisks = False }) $ inlineListToMuse lst'
565+ modify $ \st -> st { stUseTags = True }
566+ return $ "**<em>" <> contents <> "</em>**"
567+ else do
568+ contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
569+ modify $ \st -> st { stUseTags = True }
570+ return $ "***" <> contents <> "***"
466571inlineToMuse (Strong lst) = do
467− contents <- inlineListToMuse lst
468− return $ "<strong>" <> contents <> "</strong>"
572+ useTags <- gets stUseTags
573+ let lst' = normalizeInlineList lst
574+ if useTags || null lst' || startsWithSpace lst' || endsWithSpace lst'
575+ then do contents <- inlineListToMuse lst'
576+ modify $ \st -> st { stUseTags = False }
577+ return $ "<strong>" <> contents <> "</strong>"
578+ else do contents <- local (\env -> env { envInsideAsterisks = True }) $ inlineListToMuse lst'
579+ modify $ \st -> st { stUseTags = True }
580+ return $ "**" <> contents <> "**"
469581inlineToMuse (Strikeout lst) = do
470582 contents <- inlineListToMuse lst
583+ modify $ \st -> st { stUseTags = False }
471584 return $ "<del>" <> contents <> "</del>"
472585inlineToMuse (Superscript lst) = do
473586 contents <- inlineListToMuse lst
587+ modify $ \st -> st { stUseTags = False }
474588 return $ "<sup>" <> contents <> "</sup>"
475589inlineToMuse (Subscript lst) = do
476590 contents <- inlineListToMuse lst
591+ modify $ \st -> st { stUseTags = False }
477592 return $ "<sub>" <> contents <> "</sub>"
478593inlineToMuse SmallCaps {} =
479594 fail "SmallCaps should be expanded before normalization"
480595inlineToMuse (Quoted SingleQuote lst) = do
481596 contents <- inlineListToMuse lst
597+ modify $ \st -> st { stUseTags = False }
482598 return $ "‘" <> contents <> "’"
483599inlineToMuse (Quoted DoubleQuote lst) = do
484600 contents <- inlineListToMuse lst
601+ modify $ \st -> st { stUseTags = False }
485602 return $ "“" <> contents <> "”"
486603inlineToMuse Cite {} =
487604 fail "Citations should be expanded before normalization"
488−inlineToMuse (Code _ str) = return $
489− "<code>" <> text (substitute "</code>" "<</code><code>/code>" str) <> "</code>"
605+inlineToMuse (Code _ str) = do
606+ useTags <- gets stUseTags
607+ modify $ \st -> st { stUseTags = False }
608+ return $ if useTags || null str || '=' `elem` str || isSpace (head str) || isSpace (last str)
609+ then "<code>" <> text (substitute "</code>" "<</code><code>/code>" str) <> "</code>"
610+ else "=" <> text str <> "="
490611inlineToMuse Math{} =
491612 fail "Math should be expanded before normalization"
492−inlineToMuse (RawInline (Format f) str) =
613+inlineToMuse (RawInline (Format f) str) = do
614+ modify $ \st -> st { stUseTags = False }
493615 return $ "<literal style=\"" <> text f <> "\">" <> text str <> "</literal>"
494616inlineToMuse LineBreak = do
495617 oneline <- asks envOneLine
618+ modify $ \st -> st { stUseTags = False }
496619 return $ if oneline then "<br>" else "<br>" <> cr
497−inlineToMuse Space = return space
620+inlineToMuse Space = do
621+ modify $ \st -> st { stUseTags = False }
622+ return space
498623inlineToMuse SoftBreak = do
499624 oneline <- asks envOneLine
500625 wrapText <- asks $ writerWrapText . envOptions
626+ modify $ \st -> st { stUseTags = False }
501627 return $ if not oneline && wrapText == WrapPreserve then cr else space
502628inlineToMuse (Link _ txt (src, _)) =
503629 case txt of
504− [Str x] | escapeURI x == src ->
630+ [Str x] | escapeURI x == src -> do
631+ modify $ \st -> st { stUseTags = False }
505632 return $ "[[" <> text (escapeLink x) <> "]]"
506633 _ -> do contents <- local (\env -> env { envInsideLinkDescription = True }) $ inlineListToMuse txt
634+ modify $ \st -> st { stUseTags = False }
507635 return $ "[[" <> text (escapeLink src) <> "][" <> contents <> "]]"
508636 where escapeLink lnk = if isImageUrl lnk then "URL:" ++ urlEscapeBrackets lnk else urlEscapeBrackets lnk
509637 -- Taken from muse-image-regexp defined in Emacs Muse file lisp/muse-regexps.el
@@ -514,11 +642,12 @@ inlineToMuse (Image attr alt (source,'f':'i':'g':':':title)) =
514642inlineToMuse (Image attr@(_, classes, _) inlines (source, title)) = do
515643 opts <- asks envOptions
516644 alt <- local (\env -> env { envInsideLinkDescription = True }) $ inlineListToMuse inlines
517− let title' = if null title
518− then if null inlines
519− then ""
520− else "[" <> alt <> "]"
521− else "[" <> text (conditionalEscapeString True title) <> "]"
645+ title' <- if null title
646+ then if null inlines
647+ then return ""
648+ else return $ "[" <> alt <> "]"
649+ else do s <- local (\env -> env { envInsideLinkDescription = True }) $ conditionalEscapeString title
650+ return $ "[" <> text s <> "]"
522651 let width = case dimension Width attr of
523652 Just (Percent x) | isEnabled Ext_amuse opts -> " " ++ show (round x :: Integer)
524653 _ -> ""
@@ -528,11 +657,14 @@ inlineToMuse (Image attr@(_, classes, _) inlines (source, title)) = do
528657 let rightalign = if "align-right" `elem` classes
529658 then " r"
530659 else ""
660+ modify $ \st -> st { stUseTags = False }
531661 return $ "[[" <> text (urlEscapeBrackets source ++ width ++ leftalign ++ rightalign) <> "]" <> title' <> "]"
532662inlineToMuse (Note contents) = do
533663 -- add to notes in state
534664 notes <- gets stNotes
535− modify $ \st -> st { stNotes = contents:notes }
665+ modify $ \st -> st { stNotes = contents:notes
666+ , stUseTags = False
667+ }
536668 let ref = show $ length notes + 1
537669 return $ "[" <> text ref <> "]"
538670inlineToMuse (Span (anchor,names,_) inlines) = do
@@ -540,6 +672,7 @@ inlineToMuse (Span (anchor,names,_) inlines) = do
540672 let anchorDoc = if null anchor
541673 then mempty
542674 else text ('#':anchor) <> space
675+ modify $ \st -> st { stUseTags = False }
543676 return $ anchorDoc <> (if null inlines && not (null anchor)
544677 then mempty
545678 else (if null names
src/Text/Pandoc/Writers/ODT.hs+2−2
@@ -189,8 +189,8 @@ transformPicMath opts (Image attr@(id', cls, _) lab (src,t)) = catchError
189189 let dims =
190190 case (getDim Width, getDim Height) of
191191 (Just w, Just h) -> [("width", show w), ("height", show h)]
192− (Just w@(Percent p), Nothing) -> [("width", show w), ("height", show (p / ratio) ++ "%")]
193− (Nothing, Just h@(Percent p)) -> [("width", show (p * ratio) ++ "%"), ("height", show h)]
192+ (Just w@(Percent _), Nothing) -> [("rel-width", show w),("rel-height", "scale"),("width", show ptX ++ "pt"),("height", show ptY ++ "pt")]
193+ (Nothing, Just h@(Percent _)) -> [("rel-width", "scale"),("rel-height", show h),("width", show ptX ++ "pt"),("height", show ptY ++ "pt")]
194194 (Just w@(Inch i), Nothing) -> [("width", show w), ("height", show (i / ratio) ++ "in")]
195195 (Nothing, Just h@(Inch i)) -> [("width", show (i * ratio) ++ "in"), ("height", show h)]
196196 _ -> [("width", show ptX ++ "pt"), ("height", show ptY ++ "pt")]
src/Text/Pandoc/Writers/OPML.hs+2−1
@@ -62,7 +62,8 @@ writeOPML opts (Pandoc meta blocks) = do
6262 meta'
6363 main <- (render colwidth . vcat) <$> mapM (elementToOPML opts) elements
6464 let context = defField "body" main metadata
65− case writerTemplate opts of
65+ (if writerPreferAscii opts then toEntities else id) <$>
66+ case writerTemplate opts of
6667 Nothing -> return main
6768 Just tpl -> renderTemplate' tpl context
6869
src/Text/Pandoc/Writers/OpenDocument.hs+109−47
@@ -39,17 +39,20 @@ import Control.Monad.State.Strict hiding (when)
3939import Data.Char (chr)
4040import Data.List (sortBy)
4141import qualified Data.Map as Map
42+import Data.Maybe (fromMaybe)
4243import Data.Ord (comparing)
4344import qualified Data.Set as Set
4445import Data.Text (Text)
4546import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
46−import Text.Pandoc.Class (PandocMonad, report)
47+import Text.Pandoc.Class (PandocMonad, report, translateTerm,
48+ setTranslations, toLang)
4749import Text.Pandoc.Definition
4850import Text.Pandoc.Logging
4951import Text.Pandoc.Options
5052import Text.Pandoc.Pretty
5153import Text.Pandoc.Shared (linesToPara)
5254import Text.Pandoc.Templates (renderTemplate')
55+import qualified Text.Pandoc.Translations as Term (Term(Figure, Table))
5356import Text.Pandoc.Writers.Math
5457import Text.Pandoc.Writers.Shared
5558import Text.Pandoc.XML
@@ -67,32 +70,36 @@ plainToPara x = x
6770type OD m = StateT WriterState m
6871
6972data WriterState =
70− WriterState { stNotes :: [Doc]
71− , stTableStyles :: [Doc]
72− , stParaStyles :: [Doc]
73− , stListStyles :: [(Int, [Doc])]
74− , stTextStyles :: Map.Map (Set.Set TextStyle) (String, Doc)
75− , stTextStyleAttr :: Set.Set TextStyle
76− , stIndentPara :: Int
77− , stInDefinition :: Bool
78− , stTight :: Bool
79− , stFirstPara :: Bool
80− , stImageId :: Int
73+ WriterState { stNotes :: [Doc]
74+ , stTableStyles :: [Doc]
75+ , stParaStyles :: [Doc]
76+ , stListStyles :: [(Int, [Doc])]
77+ , stTextStyles :: Map.Map (Set.Set TextStyle) (String, Doc)
78+ , stTextStyleAttr :: Set.Set TextStyle
79+ , stIndentPara :: Int
80+ , stInDefinition :: Bool
81+ , stTight :: Bool
82+ , stFirstPara :: Bool
83+ , stImageId :: Int
84+ , stTableCaptionId :: Int
85+ , stImageCaptionId :: Int
8186 }
8287
8388defaultWriterState :: WriterState
8489defaultWriterState =
85− WriterState { stNotes = []
86− , stTableStyles = []
87− , stParaStyles = []
88− , stListStyles = []
89− , stTextStyles = Map.empty
90− , stTextStyleAttr = Set.empty
91− , stIndentPara = 0
92− , stInDefinition = False
93− , stTight = False
94− , stFirstPara = False
95− , stImageId = 1
90+ WriterState { stNotes = []
91+ , stTableStyles = []
92+ , stParaStyles = []
93+ , stListStyles = []
94+ , stTextStyles = Map.empty
95+ , stTextStyleAttr = Set.empty
96+ , stIndentPara = 0
97+ , stInDefinition = False
98+ , stTight = False
99+ , stFirstPara = False
100+ , stImageId = 1
101+ , stTableCaptionId = 1
102+ , stImageCaptionId = 1
96103 }
97104
98105when :: Bool -> Doc -> Doc
@@ -193,10 +200,15 @@ formulaStyle mt = inTags False "style:style"
193200 ,("style:horizontal-rel", "paragraph-content")
194201 ,("style:wrap", "none")]
195202
196−inHeaderTags :: PandocMonad m => Int -> Doc -> OD m Doc
197−inHeaderTags i d =
203+inHeaderTags :: PandocMonad m => Int -> String -> Doc -> OD m Doc
204+inHeaderTags i ident d =
198205 return $ inTags False "text:h" [ ("text:style-name", "Heading_20_" ++ show i)
199− , ("text:outline-level", show i)] d
206+ , ("text:outline-level", show i)]
207+ $ if null ident
208+ then d
209+ else selfClosingTag "text:bookmark-start" [ ("text:name", ident) ]
210+ <> d <>
211+ selfClosingTag "text:bookmark-end" [ ("text:name", ident) ]
200212
201213inQuotes :: QuoteType -> Doc -> Doc
202214inQuotes SingleQuote s = char '\8216' <> s <> char '\8217'
@@ -218,6 +230,11 @@ handleSpaces s
218230-- | Convert Pandoc document to string in OpenDocument format.
219231writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m Text
220232writeOpenDocument opts (Pandoc meta blocks) = do
233+ let defLang = Lang "en" "US" "" []
234+ lang <- case lookupMetaString "lang" meta of
235+ "" -> pure defLang
236+ s -> fromMaybe defLang <$> toLang (Just s)
237+ setTranslations lang
221238 let colwidth = if writerWrapText opts == WrapAuto
222239 then Just $ writerColumns opts
223240 else Nothing
@@ -349,8 +366,9 @@ blockToOpenDocument o bs
349366 | LineBlock b <- bs = blockToOpenDocument o $ linesToPara b
350367 | Div attr xs <- bs = withLangFromAttr attr
351368 (blocksToOpenDocument o xs)
352− | Header i _ b <- bs = setFirstPara >>
353− (inHeaderTags i =<< inlinesToOpenDocument o b)
369+ | Header i (ident,_,_) b
370+ <- bs = setFirstPara >> (inHeaderTags i ident
371+ =<< inlinesToOpenDocument o b)
354372 | BlockQuote b <- bs = setFirstPara >> mkBlockQuote b
355373 | DefinitionList b <- bs = setFirstPara >> defList b
356374 | BulletList b <- bs = setFirstPara >> bulletListToOpenDocument o b
@@ -394,11 +412,11 @@ blockToOpenDocument o bs
394412 mapM_ addParaStyle . newPara $ paraHStyles ++ paraStyles
395413 captionDoc <- if null c
396414 then return empty
397− else withParagraphStyle o "Table" [Para c]
415+ else inlinesToOpenDocument o c >>= numberedTableCaption
398416 th <- if all null h
399417 then return empty
400− else colHeadsToOpenDocument o name (map fst paraHStyles) h
401− tr <- mapM (tableRowToOpenDocument o name (map fst paraStyles)) r
418+ else colHeadsToOpenDocument o (map fst paraHStyles) h
419+ tr <- mapM (tableRowToOpenDocument o (map fst paraStyles)) r
402420 return $ inTags True "table:table" [ ("table:name" , name)
403421 , ("table:style-name", name)
404422 ] (vcat columns $$ th $$ vcat tr) $$ captionDoc
@@ -406,28 +424,54 @@ blockToOpenDocument o bs
406424 withParagraphStyle o "Figure" [Para [Image attr caption (source,title)]]
407425 | otherwise = do
408426 imageDoc <- withParagraphStyle o "FigureWithCaption" [Para [Image attr caption (source,title)]]
409− captionDoc <- withParagraphStyle o "FigureCaption" [Para caption]
427+ captionDoc <- inlinesToOpenDocument o caption >>= numberedFigureCaption
410428 return $ imageDoc $$ captionDoc
411429
430+
431+numberedTableCaption :: PandocMonad m => Doc -> OD m Doc
432+numberedTableCaption caption = do
433+ id' <- gets stTableCaptionId
434+ modify (\st -> st{ stTableCaptionId = id' + 1 })
435+ capterm <- translateTerm Term.Table
436+ return $ numberedCaption "Table" capterm "Table" id' caption
437+
438+numberedFigureCaption :: PandocMonad m => Doc -> OD m Doc
439+numberedFigureCaption caption = do
440+ id' <- gets stImageCaptionId
441+ modify (\st -> st{ stImageCaptionId = id' + 1 })
442+ capterm <- translateTerm Term.Figure
443+ return $ numberedCaption "FigureCaption" capterm "Illustration" id' caption
444+
445+numberedCaption :: String -> String -> String -> Int -> Doc -> Doc
446+numberedCaption style term name num caption =
447+ let t = text term
448+ r = num - 1
449+ s = inTags False "text:sequence" [ ("text:ref-name", "ref" ++ name ++ show r),
450+ ("text:name", name),
451+ ("text:formula", "ooow:" ++ name ++ "+1"),
452+ ("style:num-format", "1") ] $ text $ show num
453+ c = text ": "
454+ in inParagraphTagsWithStyle style $ hcat [ t, text " ", s, c, caption ]
455+
412456colHeadsToOpenDocument :: PandocMonad m
413− => WriterOptions -> String -> [String] -> [[Block]]
457+ => WriterOptions -> [String] -> [[Block]]
414458 -> OD m Doc
415−colHeadsToOpenDocument o tn ns hs =
459+colHeadsToOpenDocument o ns hs =
416460 inTagsIndented "table:table-header-rows" . inTagsIndented "table:table-row" . vcat <$>
417− mapM (tableItemToOpenDocument o tn) (zip ns hs)
461+ mapM (tableItemToOpenDocument o "TableHeaderRowCell") (zip ns hs)
418462
419463tableRowToOpenDocument :: PandocMonad m
420− => WriterOptions -> String -> [String] -> [[Block]]
464+ => WriterOptions -> [String] -> [[Block]]
421465 -> OD m Doc
422−tableRowToOpenDocument o tn ns cs =
466+tableRowToOpenDocument o ns cs =
423467 inTagsIndented "table:table-row" . vcat <$>
424− mapM (tableItemToOpenDocument o tn) (zip ns cs)
468+ mapM (tableItemToOpenDocument o "TableRowCell") (zip ns cs)
425469
426470tableItemToOpenDocument :: PandocMonad m
427471 => WriterOptions -> String -> (String,[Block])
428472 -> OD m Doc
429−tableItemToOpenDocument o tn (n,i) =
430− let a = [ ("table:style-name" , tn ++ ".A1" )
473+tableItemToOpenDocument o s (n,i) =
474+ let a = [ ("table:style-name" , s )
431475 , ("office:value-type", "string" )
432476 ]
433477 in inTags True "table:table-cell" a <$>
@@ -500,7 +544,9 @@ inlineToOpenDocument o ils
500544 modify (\st -> st{ stImageId = id' + 1 })
501545 let getDims [] = []
502546 getDims (("width", w) :xs) = ("svg:width", w) : getDims xs
547+ getDims (("rel-width", w):xs) = ("style:rel-width", w) : getDims xs
503548 getDims (("height", h):xs) = ("svg:height", h) : getDims xs
549+ getDims (("rel-height", w):xs) = ("style:rel-height", w) : getDims xs
504550 getDims (_:xs) = getDims xs
505551 return $ inTags False "draw:frame"
506552 (("draw:name", "img" ++ show id') : getDims kvs) $
@@ -555,10 +601,18 @@ orderedListLevelStyle (s,n, d) (l,ls) =
555601
556602listLevelStyle :: Int -> Doc
557603listLevelStyle i =
558− let indent = show (0.4 * fromIntegral (i - 1) :: Double) in
559− selfClosingTag "style:list-level-properties"
560− [ ("text:space-before" , indent ++ "in")
561− , ("text:min-label-width", "0.4in")]
604+ let indent = show (0.5 * fromIntegral i :: Double) in
605+ inTags True "style:list-level-properties"
606+ [ ("text:list-level-position-and-space-mode",
607+ "label-alignment")
608+ , ("fo:text-align", "right")
609+ ] $
610+ selfClosingTag "style:list-level-label-alignment"
611+ [ ("text:label-followed-by", "listtab")
612+ , ("text:list-tab-stop-position", indent ++ "in")
613+ , ("fo:text-indent", "-0.1in")
614+ , ("fo:margin-left", indent ++ "in")
615+ ]
562616
563617tableStyle :: Int -> [(Char,Double)] -> Doc
564618tableStyle num wcs =
@@ -576,13 +630,21 @@ tableStyle num wcs =
576630 , ("style:family", "table-column" )] $
577631 selfClosingTag "style:table-column-properties"
578632 [("style:rel-column-width", printf "%d*" (floor $ w * 65535 :: Integer))]
579− cellStyle = inTags True "style:style"
580− [ ("style:name" , tableId ++ ".A1")
633+ headerRowCellStyle = inTags True "style:style"
634+ [ ("style:name" , "TableHeaderRowCell")
635+ , ("style:family", "table-cell" )] $
636+ selfClosingTag "style:table-cell-properties"
637+ [ ("fo:border", "none")]
638+ rowCellStyle = inTags True "style:style"
639+ [ ("style:name" , "TableRowCell")
581640 , ("style:family", "table-cell" )] $
582641 selfClosingTag "style:table-cell-properties"
583642 [ ("fo:border", "none")]
643+ cellStyles = if num == 0
644+ then headerRowCellStyle $$ rowCellStyle
645+ else empty
584646 columnStyles = map colStyle wcs
585− in table $$ vcat columnStyles $$ cellStyle
647+ in cellStyles $$ table $$ vcat columnStyles
586648
587649paraStyle :: PandocMonad m => [(String,String)] -> OD m Int
588650paraStyle attrs = do
src/Text/Pandoc/Writers/Org.hs+2−2
@@ -109,7 +109,7 @@ escapeString = escapeStringUsing $
109109 , ('\x2013',"--")
110110 , ('\x2019',"'")
111111 , ('\x2026',"...")
112− ] ++ backslashEscapes "^_"
112+ ]
113113
114114isRawFormat :: Format -> Bool
115115isRawFormat f =
@@ -266,7 +266,7 @@ orderedListItemToOrg marker items = do
266266 contents <- blockListToOrg items
267267 return $ hang (length marker + 1) (text marker <> space) (contents <> cr)
268268
269−-- | Convert defintion list item (label, list of blocks) to Org.
269+-- | Convert definition list item (label, list of blocks) to Org.
270270definitionListItemToOrg :: PandocMonad m
271271 => ([Inline], [[Block]]) -> Org m Doc
272272definitionListItemToOrg (label, defs) = do
src/Text/Pandoc/Writers/Powerpoint/Presentation.hs+8−14
@@ -72,7 +72,7 @@ import Text.Pandoc.Logging
7272import Text.Pandoc.Walk
7373import Data.Time (UTCTime)
7474import qualified Text.Pandoc.Shared as Shared -- so we don't overlap "Element"
75−import Text.Pandoc.Writers.Shared (metaValueToInlines)
75+import Text.Pandoc.Writers.Shared (lookupMetaInlines)
7676import qualified Data.Map as M
7777import qualified Data.Set as S
7878import Data.Maybe (maybeToList, fromMaybe)
@@ -731,9 +731,9 @@ makeEndNotesSlideBlocks = do
731731 anchorSet <- M.keysSet <$> gets stAnchorMap
732732 if M.null noteIds
733733 then return []
734− else let title = case lookupMeta "notes-title" meta of
735− Just val -> metaValueToInlines val
736− Nothing -> [Str "Notes"]
734+ else let title = case lookupMetaInlines "notes-title" meta of
735+ [] -> [Str "Notes"]
736+ ls -> ls
737737 ident = Shared.uniqueIdent title anchorSet
738738 hdr = Header slideLevel (ident, [], []) title
739739 blks = concatMap (\(n, bs) -> makeNoteEntry n bs) $
@@ -744,13 +744,7 @@ getMetaSlide :: Pres (Maybe Slide)
744744getMetaSlide = do
745745 meta <- asks envMetadata
746746 title <- inlinesToParElems $ docTitle meta
747− subtitle <- inlinesToParElems $
748− case lookupMeta "subtitle" meta of
749− Just (MetaString s) -> [Str s]
750− Just (MetaInlines ils) -> ils
751− Just (MetaBlocks [Plain ils]) -> ils
752− Just (MetaBlocks [Para ils]) -> ils
753− _ -> []
747+ subtitle <- inlinesToParElems $ lookupMetaInlines "subtitle" meta
754748 authors <- mapM inlinesToParElems $ docAuthors meta
755749 date <- inlinesToParElems $ docDate meta
756750 if null title && null subtitle && null authors && null date
@@ -785,9 +779,9 @@ makeTOCSlide blks = local (\env -> env{envCurSlideId = tocSlideId}) $ do
785779 contents <- BulletList <$> mapM elementToListItem (Shared.hierarchicalize blks)
786780 meta <- asks envMetadata
787781 slideLevel <- asks envSlideLevel
788− let tocTitle = case lookupMeta "toc-title" meta of
789− Just val -> metaValueToInlines val
790− Nothing -> [Str "Table of Contents"]
782+ let tocTitle = case lookupMetaInlines "toc-title" meta of
783+ [] -> [Str "Table of Contents"]
784+ ls -> ls
791785 hdr = Header slideLevel nullAttr tocTitle
792786 blocksToSlide [hdr, contents]
793787
src/Text/Pandoc/Writers/RST.hs+69−18
@@ -35,7 +35,7 @@ module Text.Pandoc.Writers.RST ( writeRST, flatten ) where
3535import Prelude
3636import Control.Monad.State.Strict
3737import Data.Char (isSpace, toLower)
38−import Data.List (isPrefixOf, stripPrefix)
38+import Data.List (isPrefixOf, stripPrefix, transpose)
3939import Data.Maybe (fromMaybe)
4040import Data.Text (Text, stripEnd)
4141import qualified Text.Pandoc.Builder as B
@@ -82,14 +82,12 @@ pandocToRST (Pandoc meta blocks) = do
8282 else Nothing
8383 let render' :: Doc -> Text
8484 render' = render colwidth
85− let subtit = case lookupMeta "subtitle" meta of
86− Just (MetaBlocks [Plain xs]) -> xs
87− _ -> []
85+ let subtit = lookupMetaInlines "subtitle" meta
8886 title <- titleToRST (docTitle meta) subtit
8987 metadata <- metaToJSON opts
9088 (fmap render' . blockListToRST)
9189 (fmap (stripEnd . render') . inlineListToRST)
92− $ B.deleteMeta "title" $ B.deleteMeta "subtitle" meta
90+ meta
9391 body <- blockListToRST' True $ case writerTemplate opts of
9492 Just _ -> normalizeHeadings 1 blocks
9593 Nothing -> blocks
@@ -103,8 +101,9 @@ pandocToRST (Pandoc meta blocks) = do
103101 let context = defField "body" main
104102 $ defField "toc" (writerTableOfContents opts)
105103 $ defField "toc-depth" (show $ writerTOCDepth opts)
104+ $ defField "number-sections" (writerNumberSections opts)
106105 $ defField "math" hasMath
107− $ defField "title" (render Nothing title :: String)
106+ $ defField "titleblock" (render Nothing title :: String)
108107 $ defField "math" hasMath
109108 $ defField "rawtex" rawTeX metadata
110109 case writerTemplate opts of
@@ -209,11 +208,26 @@ blockToRST :: PandocMonad m
209208 => Block -- ^ Block element
210209 -> RST m Doc
211210blockToRST Null = return empty
212−blockToRST (Div attr bs) = do
211+blockToRST (Div ("",["admonition-title"],[]) _) = return empty
212+ -- this is generated by the rst reader and can safely be
213+ -- omitted when we're generating rst
214+blockToRST (Div (ident,classes,_kvs) bs) = do
213215 contents <- blockListToRST bs
214− let startTag = ".. raw:: html" $+$ nest 3 (tagWithAttrs "div" attr)
215− let endTag = ".. raw:: html" $+$ nest 3 "</div>"
216− return $ blankline <> startTag $+$ contents $+$ endTag $$ blankline
216+ let admonitions = ["attention","caution","danger","error","hint",
217+ "important","note","tip","warning","admonition"]
218+ let admonition = case classes of
219+ (cl:_)
220+ | cl `elem` admonitions
221+ -> ".. " <> text cl <> "::"
222+ cls -> ".. container::" <> space <>
223+ text (unwords (filter (/= "container") cls))
224+ return $ blankline $$
225+ admonition $$
226+ (if null ident
227+ then blankline
228+ else " :name: " <> text ident $$ blankline) $$
229+ nest 3 contents $$
230+ blankline
217231blockToRST (Plain inlines) = inlineListToRST inlines
218232-- title beginning with fig: indicates that the image is a figure
219233blockToRST (Para [Image attr txt (src,'f':'i':'g':':':tit)]) = do
@@ -236,6 +250,7 @@ blockToRST (LineBlock lns) =
236250 linesToLineBlock lns
237251blockToRST (RawBlock f@(Format f') str)
238252 | f == "rst" = return $ text str
253+ | f == "tex" = blockToRST (RawBlock (Format "latex") str)
239254 | otherwise = return $ blankline <> ".. raw:: " <>
240255 text (map toLower f') $+$
241256 nest 3 (text str) $$ blankline
@@ -272,7 +287,8 @@ blockToRST (CodeBlock (_,classes,kvs) str) = do
272287 then return $ prefixed "> " (text str) $$ blankline
273288 else return $
274289 (case [c | c <- classes,
275− c `notElem` ["sourceCode","literate","numberLines"]] of
290+ c `notElem` ["sourceCode","literate","numberLines",
291+ "number-lines","example"]] of
276292 [] -> "::"
277293 (lang:_) -> (".. code:: " <> text lang) $$ numberlines)
278294 $+$ nest 3 (text str) $$ blankline
@@ -288,9 +304,12 @@ blockToRST (Table caption aligns widths headers rows) = do
288304 modify $ \st -> st{ stOptions = oldOpts }
289305 return result
290306 opts <- gets stOptions
291− tbl <- gridTable opts blocksToDoc (all null headers)
292− (map (const AlignDefault) aligns) widths
293− headers rows
307+ let isSimple = all (== 0) widths
308+ tbl <- if isSimple
309+ then simpleTable opts blocksToDoc headers rows
310+ else gridTable opts blocksToDoc (all null headers)
311+ (map (const AlignDefault) aligns) widths
312+ headers rows
294313 return $ if null caption
295314 then tbl $$ blankline
296315 else (".. table:: " <> caption') $$ blankline $$ nest 3 tbl $$
@@ -331,7 +350,7 @@ orderedListItemToRST marker items = do
331350 let marker' = marker ++ " "
332351 return $ hang (length marker') (text marker') $ contents <> cr
333352
334−-- | Convert defintion list item (label, list of blocks) to RST.
353+-- | Convert definition list item (label, list of blocks) to RST.
335354definitionListItemToRST :: PandocMonad m => ([Inline], [[Block]]) -> RST m Doc
336355definitionListItemToRST (label, defs) = do
337356 label' <- inlineListToRST label
@@ -470,6 +489,8 @@ flatten outer
470489 -- them and they will be readable and parsable
471490 (Quoted _ _, _) -> keep f i
472491 (_, Quoted _ _) -> keep f i
492+ -- inlineToRST handles this case properly so it's safe to keep
493+ (Link _ _ _, Image _ _ _) -> keep f i
473494 -- parent inlines would prevent links from being correctly
474495 -- parsed, in this case we prioritise the content over the
475496 -- style
@@ -569,15 +590,18 @@ inlineToRST (Quoted DoubleQuote lst) = do
569590 else return $ "“" <> contents <> "”"
570591inlineToRST (Cite _ lst) =
571592 writeInlines lst
593+inlineToRST (Code (_,["interpreted-text"],[("role",role)]) str) = do
594+ return $ ":" <> text role <> ":`" <> text str <> "`"
572595inlineToRST (Code _ str) = do
573596 opts <- gets stOptions
574597 -- we trim the string because the delimiters must adjoin a
575598 -- non-space character; see #3496
576599 -- we use :literal: when the code contains backticks, since
577600 -- :literal: allows backslash-escapes; see #3974
578− return $ if '`' `elem` str
579− then ":literal:`" <> text (escapeString opts (trim str)) <> "`"
580− else "``" <> text (trim str) <> "``"
601+ return $
602+ if '`' `elem` str
603+ then ":literal:`" <> text (escapeString opts (trim str)) <> "`"
604+ else "``" <> text (trim str) <> "``"
581605inlineToRST (Str str) = do
582606 opts <- gets stOptions
583607 return $ text $
@@ -672,3 +696,30 @@ imageDimsToRST attr = do
672696 Just dim -> cols dim
673697 Nothing -> empty
674698 return $ cr <> name $$ showDim Width $$ showDim Height
699+
700+simpleTable :: PandocMonad m
701+ => WriterOptions
702+ -> (WriterOptions -> [Block] -> m Doc)
703+ -> [[Block]]
704+ -> [[[Block]]]
705+ -> m Doc
706+simpleTable opts blocksToDoc headers rows = do
707+ -- can't have empty cells in first column:
708+ let fixEmpties (d:ds) = if isEmpty d
709+ then text "\\ " : ds
710+ else d : ds
711+ fixEmpties [] = []
712+ headerDocs <- if all null headers
713+ then return []
714+ else fixEmpties <$> mapM (blocksToDoc opts) headers
715+ rowDocs <- mapM (fmap fixEmpties . mapM (blocksToDoc opts)) rows
716+ let numChars [] = 0
717+ numChars xs = maximum . map offset $ xs
718+ let colWidths = map numChars $ transpose (headerDocs : rowDocs)
719+ let toRow = hsep . zipWith lblock colWidths
720+ let hline = hsep (map (\n -> text (replicate n '=')) colWidths)
721+ let hdr = if all null headers
722+ then mempty
723+ else hline $$ toRow headerDocs
724+ let bdy = vcat $ map toRow rowDocs
725+ return $ hdr $$ hline $$ bdy $$ hline
src/Text/Pandoc/Writers/RTF.hs+4−2
@@ -341,8 +341,10 @@ listItemToRTF :: PandocMonad m
341341listItemToRTF alignment indent marker [] = return $
342342 rtfCompact (indent + listIncrement) (negate listIncrement) alignment
343343 (marker ++ "\\tx" ++ show listIncrement ++ "\\tab ")
344−listItemToRTF alignment indent marker list = do
345− (first:rest) <- mapM (blockToRTF (indent + listIncrement) alignment) list
344+listItemToRTF alignment indent marker (listFirst:listRest) = do
345+ let f = blockToRTF (indent + listIncrement) alignment
346+ first <- f listFirst
347+ rest <- mapM f listRest
346348 let listMarker = "\\fi" ++ show (negate listIncrement) ++ " " ++ marker ++
347349 "\\tx" ++ show listIncrement ++ "\\tab"
348350 let insertListMarker ('\\':'f':'i':'-':d:xs) | isDigit d =
src/Text/Pandoc/Writers/Shared.hs+111−10
@@ -38,17 +38,27 @@ module Text.Pandoc.Writers.Shared (
3838 , resetField
3939 , defField
4040 , tagWithAttrs
41+ , isDisplayMath
4142 , fixDisplayMath
4243 , unsmartify
44+ , hasSimpleCells
4345 , gridTable
44− , metaValueToInlines
46+ , lookupMetaBool
47+ , lookupMetaBlocks
48+ , lookupMetaInlines
49+ , lookupMetaString
4550 , stripLeadingTrailingSpace
51+ , groffEscape
52+ , toSubscript
53+ , toSuperscript
4654 )
4755where
4856import Prelude
4957import Control.Monad (zipWithM)
58+import Data.Monoid (Any (..))
5059import Data.Aeson (FromJSON (..), Result (..), ToJSON (..), Value (Object),
5160 encode, fromJSON)
61+import Data.Char (chr, ord, isAscii, isSpace)
5262import qualified Data.HashMap.Strict as H
5363import Data.List (groupBy, intersperse, transpose)
5464import qualified Data.Map as M
@@ -59,9 +69,11 @@ import qualified Text.Pandoc.Builder as Builder
5969import Text.Pandoc.Definition
6070import Text.Pandoc.Options
6171import Text.Pandoc.Pretty
62−import Text.Pandoc.Walk (query)
72+import Text.Pandoc.Shared (stringify)
6373import Text.Pandoc.UTF8 (toStringLazy)
6474import Text.Pandoc.XML (escapeStringForXML)
75+import Text.Pandoc.Walk (query)
76+import Text.Printf (printf)
6577
6678-- | Create JSON value for template from a 'Meta' and an association list
6779-- of variables, specified at the command line or in the writer.
@@ -187,8 +199,9 @@ tagWithAttrs tag (ident,classes,kvs) = hsep
187199 ] <> ">"
188200
189201isDisplayMath :: Inline -> Bool
190−isDisplayMath (Math DisplayMath _) = True
191−isDisplayMath _ = False
202+isDisplayMath (Math DisplayMath _) = True
203+isDisplayMath (Span _ [Math DisplayMath _]) = True
204+isDisplayMath _ = False
192205
193206stripLeadingTrailingSpace :: [Inline] -> [Inline]
194207stripLeadingTrailingSpace = go . reverse . go . reverse
@@ -233,6 +246,21 @@ unsmartify opts ('\8216':xs) = '\'' : unsmartify opts xs
233246unsmartify opts (x:xs) = x : unsmartify opts xs
234247unsmartify _ [] = []
235248
249+-- | True if block is a table that can be represented with
250+-- one line per row.
251+hasSimpleCells :: Block -> Bool
252+hasSimpleCells (Table _caption _aligns _widths headers rows) =
253+ all isSimpleCell (concat (headers:rows))
254+ where
255+ isLineBreak LineBreak = Any True
256+ isLineBreak _ = Any False
257+ hasLineBreak = getAny . query isLineBreak
258+ isSimpleCell [Plain ils] = not (hasLineBreak ils)
259+ isSimpleCell [Para ils ] = not (hasLineBreak ils)
260+ isSimpleCell [] = True
261+ isSimpleCell _ = False
262+hasSimpleCells _ = False
263+
236264gridTable :: Monad m
237265 => WriterOptions
238266 -> (WriterOptions -> [Block] -> m Doc)
@@ -332,9 +360,82 @@ gridTable opts blocksToDoc headless aligns widths headers rows = do
332360 body $$
333361 border '-' (repeat AlignDefault) widthsInChars
334362
335−metaValueToInlines :: MetaValue -> [Inline]
336−metaValueToInlines (MetaString s) = [Str s]
337−metaValueToInlines (MetaInlines ils) = ils
338−metaValueToInlines (MetaBlocks bs) = query return bs
339−metaValueToInlines (MetaBool b) = [Str $ show b]
340−metaValueToInlines _ = []
363+
364+
365+-- | Retrieve the metadata value for a given @key@
366+-- and convert to Bool.
367+lookupMetaBool :: String -> Meta -> Bool
368+lookupMetaBool key meta =
369+ case lookupMeta key meta of
370+ Just (MetaBlocks _) -> True
371+ Just (MetaInlines _) -> True
372+ Just (MetaString (_:_)) -> True
373+ Just (MetaBool True) -> True
374+ _ -> False
375+
376+-- | Retrieve the metadata value for a given @key@
377+-- and extract blocks.
378+lookupMetaBlocks :: String -> Meta -> [Block]
379+lookupMetaBlocks key meta =
380+ case lookupMeta key meta of
381+ Just (MetaBlocks bs) -> bs
382+ Just (MetaInlines ils) -> [Plain ils]
383+ Just (MetaString s) -> [Plain [Str s]]
384+ _ -> []
385+
386+-- | Retrieve the metadata value for a given @key@
387+-- and extract inlines.
388+lookupMetaInlines :: String -> Meta -> [Inline]
389+lookupMetaInlines key meta =
390+ case lookupMeta key meta of
391+ Just (MetaString s) -> [Str s]
392+ Just (MetaInlines ils) -> ils
393+ Just (MetaBlocks [Plain ils]) -> ils
394+ Just (MetaBlocks [Para ils]) -> ils
395+ _ -> []
396+
397+-- | Retrieve the metadata value for a given @key@
398+-- and convert to String.
399+lookupMetaString :: String -> Meta -> String
400+lookupMetaString key meta =
401+ case lookupMeta key meta of
402+ Just (MetaString s) -> s
403+ Just (MetaInlines ils) -> stringify ils
404+ Just (MetaBlocks bs) -> stringify bs
405+ Just (MetaBool b) -> show b
406+ _ -> ""
407+
408+-- | Escape non-ASCII characters using groff \u[..] sequences.
409+groffEscape :: T.Text -> T.Text
410+groffEscape = T.concatMap toUchar
411+ where toUchar c
412+ | isAscii c = T.singleton c
413+ | otherwise = T.pack $ printf "\\[u%04X]" (ord c)
414+
415+
416+toSuperscript :: Char -> Maybe Char
417+toSuperscript '1' = Just '\x00B9'
418+toSuperscript '2' = Just '\x00B2'
419+toSuperscript '3' = Just '\x00B3'
420+toSuperscript '+' = Just '\x207A'
421+toSuperscript '-' = Just '\x207B'
422+toSuperscript '=' = Just '\x207C'
423+toSuperscript '(' = Just '\x207D'
424+toSuperscript ')' = Just '\x207E'
425+toSuperscript c
426+ | c >= '0' && c <= '9' =
427+ Just $ chr (0x2070 + (ord c - 48))
428+ | isSpace c = Just c
429+ | otherwise = Nothing
430+
431+toSubscript :: Char -> Maybe Char
432+toSubscript '+' = Just '\x208A'
433+toSubscript '-' = Just '\x208B'
434+toSubscript '=' = Just '\x208C'
435+toSubscript '(' = Just '\x208D'
436+toSubscript ')' = Just '\x208E'
437+toSubscript c
438+ | c >= '0' && c <= '9' =
439+ Just $ chr (0x2080 + (ord c - 48))
440+ | isSpace c = Just c
441+ | otherwise = Nothing
src/Text/Pandoc/Writers/TEI.hs+1−14
@@ -35,7 +35,6 @@ import Prelude
3535import Data.Char (toLower)
3636import Data.List (isPrefixOf, stripPrefix)
3737import Data.Text (Text)
38−import qualified Text.Pandoc.Builder as B
3938import Text.Pandoc.Class (PandocMonad, report)
4039import Text.Pandoc.Definition
4140import Text.Pandoc.Highlighting (languages, languagesByExtension)
@@ -48,16 +47,6 @@ import Text.Pandoc.Templates (renderTemplate')
4847import Text.Pandoc.Writers.Shared
4948import Text.Pandoc.XML
5049
51−-- | Convert list of authors to a docbook <author> section
52−authorToTEI :: PandocMonad m => WriterOptions -> [Inline] -> m B.Inlines
53−authorToTEI opts name' = do
54− name <- render Nothing <$> inlinesToTEI opts name'
55− let colwidth = if writerWrapText opts == WrapAuto
56− then Just $ writerColumns opts
57− else Nothing
58− return $ B.rawInline "tei" $ render colwidth $
59− inTagsSimple "author" (text $ escapeStringForXML name)
60−
6150-- | Convert Pandoc document to string in Docbook format.
6251writeTEI :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6352writeTEI opts (Pandoc meta blocks) = do
@@ -72,13 +61,11 @@ writeTEI opts (Pandoc meta blocks) = do
7261 TopLevelChapter -> 0
7362 TopLevelSection -> 1
7463 TopLevelDefault -> 1
75− auths' <- mapM (authorToTEI opts) $ docAuthors meta
76− let meta' = B.setMeta "author" auths' meta
7764 metadata <- metaToJSON opts
7865 (fmap (render' . vcat) .
7966 mapM (elementToTEI opts startLvl) . hierarchicalize)
8067 (fmap render' . inlinesToTEI opts)
81− meta'
68+ meta
8269 main <- (render' . vcat) <$> mapM (elementToTEI opts startLvl) elements
8370 let context = defField "body" main
8471 $
src/Text/Pandoc/Writers/Texinfo.hs+10−20
@@ -56,8 +56,6 @@ import Text.Printf (printf)
5656
5757data WriterState =
5858 WriterState { stStrikeout :: Bool -- document contains strikeout
59− , stSuperscript :: Bool -- document contains superscript
60− , stSubscript :: Bool -- document contains subscript
6159 , stEscapeComma :: Bool -- in a context where we need @comma
6260 , stIdentifiers :: Set.Set String -- header ids used already
6361 , stOptions :: WriterOptions -- writer options
@@ -74,8 +72,7 @@ type TI m = StateT WriterState m
7472writeTexinfo :: PandocMonad m => WriterOptions -> Pandoc -> m Text
7573writeTexinfo options document =
7674 evalStateT (pandocToTexinfo options $ wrapTop document)
77− WriterState { stStrikeout = False, stSuperscript = False,
78− stEscapeComma = False, stSubscript = False,
75+ WriterState { stStrikeout = False, stEscapeComma = False,
7976 stIdentifiers = Set.empty, stOptions = options}
8077
8178-- | Add a "Top" node around the document, needed by Texinfo.
@@ -102,8 +99,6 @@ pandocToTexinfo options (Pandoc meta blocks) = do
10299 let context = defField "body" body
103100 $ defField "toc" (writerTableOfContents options)
104101 $ defField "titlepage" titlePage
105− $ defField "subscript" (stSubscript st)
106− $ defField "superscript" (stSuperscript st)
107102 $
108103 defField "strikeout" (stStrikeout st) metadata
109104 case writerTemplate options of
@@ -351,12 +346,9 @@ collectNodes :: Int -> [Block] -> [Block]
351346collectNodes _ [] = []
352347collectNodes level (x:xs) =
353348 case x of
354− (Header hl _ _) ->
355− if hl < level
356− then []
357− else if hl == level
358− then x : collectNodes level xs
359− else collectNodes level xs
349+ (Header hl _ _) | hl < level -> []
350+ | hl == level -> x : collectNodes level xs
351+ | otherwise -> collectNodes level xs
360352 _ ->
361353 collectNodes level xs
362354
@@ -394,7 +386,7 @@ defListItemToTexinfo (term, defs) = do
394386inlineListToTexinfo :: PandocMonad m
395387 => [Inline] -- ^ Inlines to convert
396388 -> TI m Doc
397−inlineListToTexinfo lst = mapM inlineToTexinfo lst >>= return . hcat
389+inlineListToTexinfo lst = hcat <$> mapM inlineToTexinfo lst
398390
399391-- | Convert list of inline elements to Texinfo acceptable for a node name.
400392inlineListForNode :: PandocMonad m
@@ -416,10 +408,10 @@ inlineToTexinfo (Span _ lst) =
416408 inlineListToTexinfo lst
417409
418410inlineToTexinfo (Emph lst) =
419− inlineListToTexinfo lst >>= return . inCmd "emph"
411+ inCmd "emph" <$> inlineListToTexinfo lst
420412
421413inlineToTexinfo (Strong lst) =
422− inlineListToTexinfo lst >>= return . inCmd "strong"
414+ inCmd "strong" <$> inlineListToTexinfo lst
423415
424416inlineToTexinfo (Strikeout lst) = do
425417 modify $ \st -> st{ stStrikeout = True }
@@ -427,17 +419,15 @@ inlineToTexinfo (Strikeout lst) = do
427419 return $ text "@textstrikeout{" <> contents <> text "}"
428420
429421inlineToTexinfo (Superscript lst) = do
430− modify $ \st -> st{ stSuperscript = True }
431422 contents <- inlineListToTexinfo lst
432− return $ text "@textsuperscript{" <> contents <> char '}'
423+ return $ text "@sup{" <> contents <> char '}'
433424
434425inlineToTexinfo (Subscript lst) = do
435− modify $ \st -> st{ stSubscript = True }
436426 contents <- inlineListToTexinfo lst
437− return $ text "@textsubscript{" <> contents <> char '}'
427+ return $ text "@sub{" <> contents <> char '}'
438428
439429inlineToTexinfo (SmallCaps lst) =
440− inlineListToTexinfo lst >>= return . inCmd "sc"
430+ inCmd "sc" <$> inlineListToTexinfo lst
441431
442432inlineToTexinfo (Code _ str) =
443433 return $ text $ "@code{" ++ stringToTexinfo str ++ "}"
src/Text/Pandoc/Writers/Textile.hs+7−7
@@ -73,7 +73,7 @@ pandocToTextile opts (Pandoc meta blocks) = do
7373 (inlineListToTextile opts) meta
7474 body <- blockListToTextile opts blocks
7575 notes <- gets $ unlines . reverse . stNotes
76− let main = pack $ body ++ if null notes then "" else ("\n\n" ++ notes)
76+ let main = pack $ body ++ if null notes then "" else "\n\n" ++ notes
7777 let context = defField "body" main metadata
7878 case writerTemplate opts of
7979 Nothing -> return main
@@ -154,7 +154,7 @@ blockToTextile _ HorizontalRule = return "<hr />\n"
154154
155155blockToTextile opts (Header level (ident,classes,keyvals) inlines) = do
156156 contents <- inlineListToTextile opts inlines
157− let identAttr = if null ident then "" else ('#':ident)
157+ let identAttr = if null ident then "" else '#':ident
158158 let attribs = if null identAttr && null classes
159159 then ""
160160 else "(" ++ unwords classes ++ identAttr ++ ")"
@@ -382,13 +382,13 @@ blockListToTextile :: PandocMonad m
382382 -> [Block] -- ^ List of block elements
383383 -> TW m String
384384blockListToTextile opts blocks =
385− mapM (blockToTextile opts) blocks >>= return . vcat
385+ vcat <$> mapM (blockToTextile opts) blocks
386386
387387-- | Convert list of Pandoc inline elements to Textile.
388388inlineListToTextile :: PandocMonad m
389389 => WriterOptions -> [Inline] -> TW m String
390390inlineListToTextile opts lst =
391− mapM (inlineToTextile opts) lst >>= return . concat
391+ concat <$> mapM (inlineToTextile opts) lst
392392
393393-- | Convert Pandoc inline element to Textile.
394394inlineToTextile :: PandocMonad m => WriterOptions -> Inline -> TW m String
@@ -463,15 +463,15 @@ inlineToTextile _ SoftBreak = return " "
463463inlineToTextile _ Space = return " "
464464
465465inlineToTextile opts (Link (_, cls, _) txt (src, _)) = do
466− let classes = if null cls
467− then ""
468− else "(" ++ unwords cls ++ ")"
469466 label <- case txt of
470467 [Code _ s]
471468 | s == src -> return "$"
472469 [Str s]
473470 | s == src -> return "$"
474471 _ -> inlineListToTextile opts txt
472+ let classes = if null cls || cls == ["uri"] && label == "$"
473+ then ""
474+ else "(" ++ unwords cls ++ ")"
475475 return $ "\"" ++ classes ++ label ++ "\":" ++ src
476476
477477inlineToTextile opts (Image attr@(_, cls, _) alt (source, tit)) = do
stack.lts10.yamlnew file+31
@@ -0,0 +1,31 @@
1+flags:
2+ pandoc:
3+ trypandoc: false
4+ embed_data_files: true
5+ pandoc-citeproc:
6+ bibutils: true
7+ embed_data_files: true
8+ unicode_collation: false
9+ test_citeproc: false
10+ debug: false
11+packages:
12+- '.'
13+extra-deps:
14+- pandoc-citeproc-0.14.4
15+- skylighting-0.7.2
16+- skylighting-core-0.7.2
17+- ansi-terminal-0.8.0.2
18+- tasty-1.0.1.1
19+- test-framework-0.8.2.0
20+- pandoc-types-1.17.5.1
21+- cmark-gfm-0.1.3
22+- texmath-0.11.1
23+- haddock-library-1.6.0
24+- HsYAML-0.1.1.1
25+- text-1.2.3.0
26+- hs-bibutils-6.6.0.0
27+- hslua-1.0.1
28+- hslua-module-text-0.2.0
29+ghc-options:
30+ "$locals": -fhide-source-paths -XNoImplicitPrelude
31+resolver: lts-10.10
stack.lts11.yamlnew file+27
@@ -0,0 +1,27 @@
1+flags:
2+ pandoc:
3+ trypandoc: false
4+ embed_data_files: true
5+ pandoc-citeproc:
6+ bibutils: true
7+ embed_data_files: true
8+ unicode_collation: false
9+ test_citeproc: false
10+ debug: false
11+packages:
12+- '.'
13+extra-deps:
14+- pandoc-citeproc-0.14.4
15+- skylighting-0.7.2
16+- skylighting-core-0.7.2
17+- pandoc-types-1.17.5.1
18+- texmath-0.11.1
19+- haddock-library-1.6.0
20+- HsYAML-0.1.1.1
21+- hs-bibutils-6.6.0.0
22+- yaml-0.9.0
23+- hslua-1.0.1
24+- hslua-module-text-0.2.0
25+ghc-options:
26+ "$locals": -fhide-source-paths -XNoImplicitPrelude
27+resolver: lts-11.17
stack.lts9.yaml+17−10
@@ -2,7 +2,6 @@ flags:
22 pandoc:
33 trypandoc: false
44 embed_data_files: true
5− network-uri: true
65 pandoc-citeproc:
76 bibutils: true
87 embed_data_files: true
@@ -12,20 +11,28 @@ flags:
1211packages:
1312- '.'
1413extra-deps:
15−- hslua-0.9.5.1
16−- hslua-module-text-0.1.2.1
17−- skylighting-0.7.0.2
18−- skylighting-core-0.7.0.2
14+- pandoc-citeproc-0.14.4
15+- hslua-1.0.1
16+- hslua-module-text-0.2.0
1917- ansi-terminal-0.8.0.2
2018- cmark-gfm-0.1.3
2119- QuickCheck-2.11.3
2220- tasty-1.0.1.1
2321- tasty-quickcheck-0.9.1
2422- doctemplates-0.2.2.1
25−- hs-bibutils-6.2.0.1
26−- pandoc-citeproc-0.14.3.1
23+- hs-bibutils-6.6.0.0
2724- tagsoup-0.14.6
28−- pandoc-types-1.17.4.2
29−- haddock-library-1.5.0.1
30−- texmath-0.11
25+- pandoc-types-1.17.5.1
26+- haddock-library-1.6.0
27+- texmath-0.11.1
28+- HsYAML-0.1.1.1
29+- text-1.2.3.0
30+- Cabal-2.4.0.0
31+- dlist-0.8.0.4
32+- parsec-3.1.13.0
33+- skylighting-core-0.7.3
34+- skylighting-0.7.3
35+- yaml-0.9.0
36+- hslua-1.0.0
37+- hslua-module-text-0.2.0
3138resolver: lts-9.14
stack.yaml+16−12
@@ -2,7 +2,6 @@ flags:
22 pandoc:
33 trypandoc: false
44 embed_data_files: true
5− network-uri: true
65 pandoc-citeproc:
76 bibutils: true
87 embed_data_files: true
@@ -11,17 +10,22 @@ flags:
1110 debug: false
1211packages:
1312- '.'
13+# See https://github.com/haskell-foundation/foundation/pull/503
14+# We can go back to released foundation when this is fixed.
15+- location:
16+ git: https://github.com/jgm/foundation
17+ commit: '4294e39'
18+ subdirs:
19+ - foundation
20+ extra-dep: true
1421extra-deps:
15−- pandoc-citeproc-0.14.3.1
16−- skylighting-0.7.0.2
17−- skylighting-core-0.7.0.2
18−- ansi-terminal-0.8.0.2
19−- tasty-1.0.1.1
20−- test-framework-0.8.2.0
21−- pandoc-types-1.17.4.2
22−- cmark-gfm-0.1.3
23−- hslua-module-text-0.1.2.1
24−- texmath-0.11
22+- pandoc-citeproc-0.14.4
23+- haddock-library-1.6.0
24+- HsYAML-0.1.1.1
25+- texmath-0.11.1
26+- yaml-0.9.0
27+- hslua-1.0.1
28+- hslua-module-text-0.2.0
2529ghc-options:
2630 "$locals": -fhide-source-paths -XNoImplicitPrelude
27−resolver: lts-10.10
31+resolver: lts-12.6
test/Tests/Lua.hs+10−9
@@ -7,7 +7,7 @@ import Control.Monad (when)
77import Data.Version (Version (versionBranch))
88import System.FilePath ((</>))
99import Test.Tasty (TestTree, localOption)
10−import Test.Tasty.HUnit (Assertion, assertEqual, testCase)
10+import Test.Tasty.HUnit (Assertion, assertEqual, assertFailure, testCase)
1111import Test.Tasty.QuickCheck (QuickCheckTests (..), ioProperty, testProperty)
1212import Text.Pandoc.Arbitrary ()
1313import Text.Pandoc.Builder (bulletList, divWith, doc, doubleQuoted, emph,
@@ -109,7 +109,8 @@ tests = map (localOption (QuickCheckTests 20))
109109 assertFilterConversion "pandoc.utils doesn't work as expected."
110110 "test-pandoc-utils.lua"
111111 (doc $ para "doesn't matter")
112− (doc $ mconcat [ plain (str "hierarchicalize: OK")
112+ (doc $ mconcat [ plain (str "blocks_to_inlines: OK")
113+ , plain (str "hierarchicalize: OK")
113114 , plain (str "normalize_date: OK")
114115 , plain (str "pipe: OK")
115116 , plain (str "failing pipe: OK")
@@ -129,7 +130,7 @@ tests = map (localOption (QuickCheckTests 20))
129130 , testCase "Pandoc version is set" . runPandocLua' $ do
130131 Lua.getglobal' "table.concat"
131132 Lua.getglobal "PANDOC_VERSION"
132− Lua.push ("." :: String) -- seperator
133+ Lua.push ("." :: String) -- separator
133134 Lua.call 2 1
134135 Lua.liftIO . assertEqual "pandoc version is wrong" pandocVersion
135136 =<< Lua.peek Lua.stackTop
@@ -163,11 +164,11 @@ tests = map (localOption (QuickCheckTests 20))
163164
164165 , testCase "informative error messages" . runPandocLua' $ do
165166 Lua.pushboolean True
166− err <- Lua.peekEither Lua.stackTop :: Lua.Lua (Either String Pandoc)
167− case err of
167+ err <- Lua.peekEither Lua.stackTop
168+ case (err :: Either String Pandoc) of
168169 Left msg -> do
169170 let expectedMsg = "Could not get Pandoc value: "
170− ++ "expected table but got boolean."
171+ <> "table expected, got boolean"
171172 Lua.liftIO $ assertEqual "unexpected error message" expectedMsg msg
172173 Right _ -> error "Getting a Pandoc element from a bool should fail."
173174 ]
@@ -178,13 +179,13 @@ assertFilterConversion msg filterPath docIn docExpected = do
178179 setUserDataDir (Just "../data")
179180 runLuaFilter def ("lua" </> filterPath) [] docIn
180181 case docEither of
181− Left _ -> fail "lua filter failed"
182+ Left exception -> assertFailure (show exception)
182183 Right docRes -> assertEqual msg docExpected docRes
183184
184−roundtripEqual :: (Eq a, Lua.FromLuaStack a, Lua.ToLuaStack a) => a -> IO Bool
185+roundtripEqual :: (Eq a, Lua.Peekable a, Lua.Pushable a) => a -> IO Bool
185186roundtripEqual x = (x ==) <$> roundtripped
186187 where
187− roundtripped :: (Lua.FromLuaStack a, Lua.ToLuaStack a) => IO a
188+ roundtripped :: (Lua.Peekable a, Lua.Pushable a) => IO a
188189 roundtripped = runPandocLua' $ do
189190 oldSize <- Lua.gettop
190191 Lua.push x
test/Tests/Readers/HTML.hs+25
@@ -4,11 +4,14 @@ module Tests.Readers.HTML (tests) where
44
55import Prelude
66import Data.Text (Text)
7+import qualified Data.Text as T
78import Test.Tasty
9+import Test.Tasty.QuickCheck
810import Tests.Helpers
911import Text.Pandoc
1012import Text.Pandoc.Arbitrary ()
1113import Text.Pandoc.Builder
14+import Text.Pandoc.Walk (walk)
1215
1316html :: Text -> Pandoc
1417html = purely $ readHtml def
@@ -16,6 +19,27 @@ html = purely $ readHtml def
1619htmlNativeDivs :: Text -> Pandoc
1720htmlNativeDivs = purely $ readHtml def { readerExtensions = enableExtension Ext_native_divs $ readerExtensions def }
1821
22+makeRoundTrip :: Block -> Block
23+makeRoundTrip CodeBlock{} = Para [Str "code block was here"]
24+makeRoundTrip LineBlock{} = Para [Str "line block was here"]
25+makeRoundTrip RawBlock{} = Para [Str "raw block was here"]
26+makeRoundTrip x = x
27+
28+removeRawInlines :: Inline -> Inline
29+removeRawInlines RawInline{} = Str "raw inline was here"
30+removeRawInlines x = x
31+
32+roundTrip :: Blocks -> Bool
33+roundTrip b = d'' == d'''
34+ where d = walk removeRawInlines $
35+ walk makeRoundTrip $ Pandoc nullMeta $ toList b
36+ d' = rewrite d
37+ d'' = rewrite d'
38+ d''' = rewrite d''
39+ rewrite = html . T.pack . (++ "\n") . T.unpack .
40+ purely (writeHtml5String def
41+ { writerWrapText = WrapPreserve })
42+
1943tests :: [TestTree]
2044tests = [ testGroup "base tag"
2145 [ test html "simple" $
@@ -53,4 +77,5 @@ tests = [ testGroup "base tag"
5377 , test htmlNativeDivs "<main> followed by text" $ "<main>main content</main>non-main content" =?>
5478 doc (divWith ("", [], [("role", "main")]) (plain (text "main content")) <> plain (text "non-main content"))
5579 ]
80+ , testProperty "Round trip" (withMaxSuccess 25 roundTrip)
5681 ]
test/Tests/Readers/Markdown.hs+8−4
@@ -39,7 +39,7 @@ testBareLink (inp, ils) =
3939 (unpack inp) (inp, doc $ para ils)
4040
4141autolink :: String -> Inlines
42−autolink = autolinkWith nullAttr
42+autolink = autolinkWith ("",["uri"],[])
4343
4444autolinkWith :: Attr -> String -> Inlines
4545autolinkWith attr s = linkWith attr s "" (str s)
@@ -72,10 +72,12 @@ bareLinkTests =
7272 , ("http://en.wikipedia.org/wiki/Sprite_(computer_graphics)",
7373 autolink "http://en.wikipedia.org/wiki/Sprite_(computer_graphics)")
7474 , ("http://en.wikipedia.org/wiki/Sprite_[computer_graphics]",
75− link "http://en.wikipedia.org/wiki/Sprite_%5Bcomputer_graphics%5D" ""
75+ linkWith ("",["uri"],[])
76+ "http://en.wikipedia.org/wiki/Sprite_%5Bcomputer_graphics%5D" ""
7677 (str "http://en.wikipedia.org/wiki/Sprite_[computer_graphics]"))
7778 , ("http://en.wikipedia.org/wiki/Sprite_{computer_graphics}",
78− link "http://en.wikipedia.org/wiki/Sprite_%7Bcomputer_graphics%7D" ""
79+ linkWith ("",["uri"],[])
80+ "http://en.wikipedia.org/wiki/Sprite_%7Bcomputer_graphics%7D" ""
7981 (str "http://en.wikipedia.org/wiki/Sprite_{computer_graphics}"))
8082 , ("http://example.com/Notification_Center-GitHub-20101108-140050.jpg",
8183 autolink "http://example.com/Notification_Center-GitHub-20101108-140050.jpg")
@@ -199,7 +201,9 @@ tests = [ testGroup "inline code"
199201 ]
200202 , testGroup "emoji"
201203 [ test markdownGH "emoji symbols" $
202− ":smile: and :+1:" =?> para (text "😄 and 👍")
204+ ":smile: and :+1:" =?> para (spanWith ("", ["emoji"], [("data-emoji", "smile")]) "😄" <>
205+ space <> str "and" <> space <>
206+ spanWith ("", ["emoji"], [("data-emoji", "+1")]) "👍")
203207 ]
204208 , "unbalanced brackets" =:
205209 "[[[[[[[[[[[[hi" =?> para (text "[[[[[[[[[[[[hi")
test/Tests/Readers/Muse.hs+79−6
@@ -39,9 +39,9 @@ makeRoundTrip x = x
3939
4040-- Demand that any AST produced by Muse reader and written by Muse writer can be read back exactly the same way.
4141-- Currently we remove tables and compare first rewrite to the second.
42−roundTrip :: Block -> Bool
42+roundTrip :: Blocks -> Bool
4343roundTrip b = d' == d''
44− where d = walk makeRoundTrip $ Pandoc nullMeta [b]
44+ where d = walk makeRoundTrip $ Pandoc nullMeta $ toList b
4545 d' = rewrite d
4646 d'' = rewrite d'
4747 rewrite = amuse . T.pack . (++ "\n") . T.unpack .
@@ -62,6 +62,14 @@ tests =
6262 "*Foo bar*" =?>
6363 para (emph . spcSep $ ["Foo", "bar"])
6464
65+ -- Emacs Muse allows this
66+ , "Newline in the beginning of emphasis" =:
67+ "*\nFoo bar*" =?>
68+ para (emph ("Foo" <> space <> "bar"))
69+ , "Newline in the end of emphasis" =:
70+ "*Foo bar\n*" =?>
71+ para (emph ("Foo" <> space <> "bar"))
72+
6573 , "Comma after closing *" =:
6674 "Foo *bar*, baz" =?>
6775 para ("Foo " <> emph "bar" <> ", baz")
@@ -74,6 +82,10 @@ tests =
7482 "Foo x*bar* baz" =?>
7583 para "Foo x*bar* baz"
7684
85+ , "Digit after closing *" =:
86+ "Foo *bar*0 baz" =?>
87+ para "Foo *bar*0 baz"
88+
7789 , "Emphasis tag" =:
7890 "<em>Foo bar</em>" =?>
7991 para (emph . spcSep $ ["Foo", "bar"])
@@ -138,6 +150,10 @@ tests =
138150 "Foo =bar=, baz" =?>
139151 para (text "Foo " <> code "bar" <> text ", baz")
140152
153+ , "Not code if followed by digit" =:
154+ "Foo =bar=0 baz" =?>
155+ para (text "Foo =bar=0 baz")
156+
141157 , "One character code" =: "=c=" =?> para (code "c")
142158
143159 , "Three = characters is not a code" =: "===" =?> para "==="
@@ -194,9 +210,27 @@ tests =
194210 , "Image" =:
195211 "[[image.jpg]]" =?>
196212 para (image "image.jpg" "" mempty)
213+ , "Closing bracket is not allowed in image filename" =:
214+ "[[foo]bar.jpg]]" =?>
215+ para (text "[[foo]bar.jpg]]")
197216 , "Image with description" =:
198217 "[[image.jpg][Image]]" =?>
199218 para (image "image.jpg" "" (text "Image"))
219+ , "Image with space in filename" =:
220+ "[[image name.jpg]]" =?>
221+ para (image "image name.jpg" "" mempty)
222+ , "Image with width" =:
223+ "[[image.jpg 60]]" =?>
224+ para (imageWith ("", [], [("width", "60%")]) "image.jpg" mempty mempty)
225+ , "At least one space is required between image filename and width" =:
226+ "[[image.jpg60]]" =?>
227+ para (link "image.jpg60" mempty (str "image.jpg60"))
228+ , "Left-aligned image with width" =:
229+ "[[image.png 60 l][Image]]" =?>
230+ para (imageWith ("", ["align-left"], [("width", "60%")]) "image.png" "" (str "Image"))
231+ , "Right-aligned image with width" =:
232+ "[[image.png 60 r][Image]]" =?>
233+ para (imageWith ("", ["align-right"], [("width", "60%")]) "image.png" "" (str "Image"))
200234 , "Image link" =:
201235 "[[URL:image.jpg]]" =?>
202236 para (link "image.jpg" "" (str "image.jpg"))
@@ -225,8 +259,8 @@ tests =
225259 ]
226260 ]
227261
228− , testGroup "Blocks" $
229− [ testProperty "Round trip" roundTrip
262+ , testGroup "Blocks"
263+ [ testProperty "Round trip" (withMaxSuccess 25 roundTrip)
230264 , "Block elements end paragraphs" =:
231265 T.unlines [ "First paragraph"
232266 , "----"
@@ -385,6 +419,12 @@ tests =
385419 , "</verse>"
386420 ] =?>
387421 lineBlock [ "" ]
422+ , "Verse tag with verbatim close tag inside" =:
423+ T.unlines [ "<verse>"
424+ , "<verbatim></verse></verbatim>"
425+ , "</verse>"
426+ ] =?>
427+ lineBlock [ "</verse>" ]
388428 , testGroup "Example"
389429 [ "Braces on separate lines" =:
390430 T.unlines [ "{{{"
@@ -589,6 +629,18 @@ tests =
589629 T.unlines [ "* Foo"
590630 , "bar"
591631 ] =?> header 1 "Foo\nbar"
632+ , test (purely $ readMuse def { readerExtensions = extensionsFromList [Ext_amuse, Ext_auto_identifiers]})
633+ "Auto identifiers"
634+ (T.unlines [ "* foo"
635+ , "** Foo"
636+ , "* bar"
637+ , "** foo"
638+ , "* foo"
639+ ] =?> headerWith ("foo",[],[]) 1 "foo" <>
640+ headerWith ("foo-1",[],[]) 2 "Foo" <>
641+ headerWith ("bar",[],[]) 1 "bar" <>
642+ headerWith ("foo-2",[],[]) 2 "foo" <>
643+ headerWith ("foo-3",[],[]) 1 "foo")
592644 ]
593645 , testGroup "Directives"
594646 [ "Title" =:
@@ -710,6 +762,13 @@ tests =
710762 , " > Baz"
711763 ] =?>
712764 para ("Foo" <> note (para "Bar" <> lineBlock ["Baz"]))
765+ , "Footnote ending in self-terminating element and followed by paragraph" =:
766+ T.unlines [ "Foo[1]"
767+ , ""
768+ , "[1] > bar"
769+ , "baz"
770+ ] =?>
771+ para (str "Foo" <> note (lineBlock ["bar"])) <> para (str "baz")
713772 , test emacsMuse "Emacs multiparagraph footnotes"
714773 (T.unlines
715774 [ "First footnote reference[1] and second footnote reference[2]."
@@ -798,6 +857,14 @@ tests =
798857 [plain "Foo", plain "bar", plain "baz"]
799858 [[plain "First", plain "row", plain "here"],
800859 [plain "Second", plain "row", plain "there"]]
860+ , "Table caption with +" =:
861+ T.unlines
862+ [ "Foo | bar"
863+ , "|+ Table + caption +|"
864+ ] =?>
865+ table (text "Table + caption") (replicate 2 (AlignDefault, 0.0))
866+ []
867+ [[plain "Foo", plain "bar"]]
801868 , "Caption without table" =:
802869 "|+ Foo bar baz +|" =?>
803870 table (text "Foo bar baz") [] [] []
@@ -972,7 +1039,7 @@ tests =
9721039 , para "c"
9731040 ]
9741041 ]
975− , "List continuation afeter nested list" =:
1042+ , "List continuation after nested list" =:
9761043 T.unlines
9771044 [ " - - foo"
9781045 , ""
@@ -1118,6 +1185,11 @@ tests =
11181185 ] =?>
11191186 bulletList [ lineBlock [ "foo" ] ] <> bulletList [ para "bar" ]
11201187 ]
1188+ , "List ending in self-terminating element and followed by paragraph" =:
1189+ T.unlines [ " - > Foo"
1190+ , "bar"
1191+ ] =?>
1192+ bulletList [lineBlock ["Foo"]] <> para (str "bar")
11211193 -- Test that definition list requires a leading space.
11221194 -- Emacs Muse does not require a space, we follow Amusewiki here.
11231195 , "Not a definition list" =:
@@ -1335,7 +1407,8 @@ tests =
13351407 , " <verse>"
13361408 , " </quote>"
13371409 , " </verse>"
1410+ , "</quote>"
13381411 ] =?>
1339− para "<quote>" <> bulletList [ para "Foo" <> para "</quote>" <> para "bar" <> lineBlock [ "</quote>" ] ]
1412+ blockQuote (bulletList [ para "Foo" <> para "</quote>" <> para "bar" <> lineBlock [ "</quote>" ] ])
13401413 ]
13411414 ]
test/Tests/Readers/Org/Block/Header.hs+38
@@ -181,4 +181,42 @@ tests =
181181 , " :END:"
182182 ] =?>
183183 headerWith ("not-numbered", ["unnumbered"], []) 1 "Not numbered"
184+
185+ , testGroup "planning information"
186+ [ "Planning info is not included in output" =:
187+ T.unlines [ "* important"
188+ , T.unwords
189+ [ "CLOSED: [2018-09-05 Wed 13:58]"
190+ , "DEADLINE: <2018-09-17 Mon>"
191+ , "SCHEDULED: <2018-09-10 Mon>"
192+ ]
193+ ] =?>
194+ headerWith ("important", [], []) 1 "important"
195+
196+ , "Properties after planning info are recognized" =:
197+ T.unlines [ "* important "
198+ , " " <> T.unwords
199+ [ "CLOSED: [2018-09-05 Wed 13:58]"
200+ , "DEADLINE: <2018-09-17 Mon>"
201+ , "SCHEDULED: <2018-09-10 Mon>"
202+ ]
203+ , " :PROPERTIES:"
204+ , " :custom_id: look"
205+ , " :END:"
206+ ] =?>
207+ headerWith ("look", [], []) 1 "important"
208+
209+ , "Planning info followed by test" =:
210+ T.unlines [ "* important "
211+ , " " <> T.unwords
212+ [ "CLOSED: [2018-09-05 Wed 13:58]"
213+ , "DEADLINE: <2018-09-17 Mon>"
214+ , "SCHEDULED: <2018-09-10 Mon>"
215+ ]
216+ , " :PROPERTIES:"
217+ , " :custom_id: look"
218+ , " :END:"
219+ ] =?>
220+ headerWith ("look", [], []) 1 "important"
221+ ]
184222 ]
test/Tests/Readers/Org/Block/List.hs+11
@@ -243,4 +243,15 @@ tests =
243243 mconcat [ para "CLOSED: [2015-10-19 Mon 15:03]"
244244 , bulletList [ plain "Note taken on [2015-10-19 Mon 13:24]" ]
245245 ]
246+
247+ , "Markup after header and list" =:
248+ T.unlines [ "* headline"
249+ , "- list"
250+ , ""
251+ , "~variable name~"
252+ ] =?>
253+ mconcat [ headerWith ("headline", [], []) 1 "headline"
254+ , bulletList [ plain "list" ]
255+ , para (code "variable name")
256+ ]
246257 ]
test/Tests/Readers/Org/Directive.hs+23
@@ -150,6 +150,29 @@ tests =
150150 , "* Headline :hello:world:"
151151 ] =?>
152152 headerWith ("headline", [], mempty) 1 "Headline"
153+
154+ , testGroup "planning information"
155+ [ "include planning info after headlines" =:
156+ T.unlines [ "#+OPTIONS: p:t"
157+ , "* important"
158+ , " DEADLINE: <2018-10-01 Mon> SCHEDULED: <2018-09-15 Sat>"
159+ ] =?>
160+ mconcat [ headerWith ("important", mempty, mempty) 1 "important"
161+ , plain $ strong "DEADLINE:"
162+ <> space
163+ <> emph (str "<2018-10-01 Mon>")
164+ <> space
165+ <> strong "SCHEDULED:"
166+ <> space
167+ <> emph (str "<2018-09-15 Sat>")
168+ ]
169+
170+ , "empty planning info is not included" =:
171+ T.unlines [ "#+OPTIONS: p:t"
172+ , "* Wichtig"
173+ ] =?>
174+ headerWith ("wichtig", mempty, mempty) 1 "Wichtig"
175+ ]
153176 ]
154177
155178 , testGroup "Include"
test/Tests/Readers/Org/Inline.hs+8−1
@@ -96,7 +96,7 @@ tests =
9696 "[fn::Schreib mir eine E-Mail]" =?>
9797 para (note $ para "Schreib mir eine E-Mail")
9898
99− , "Markup-chars not occuring on word break are symbols" =:
99+ , "Markup-chars not occurring on word break are symbols" =:
100100 T.unlines [ "this+that+ +so+on"
101101 , "seven*eight* nine*"
102102 , "+not+funny+"
@@ -280,6 +280,13 @@ tests =
280280 )
281281 "echo 'Hello, World'")
282282
283+ , "Inline code block with a blank argument array" =:
284+ "src_sh[]{echo 'Hello, World'}" =?>
285+ para (codeWith ( ""
286+ , [ "bash" ]
287+ , [ ("org-language", "sh") ])
288+ "echo 'Hello, World'")
289+
283290 , "Inline code block with toggle" =:
284291 "src_sh[:toggle]{echo $HOME}" =?>
285292 para (codeWith ( ""
test/Tests/Readers/RST.hs+15−1
@@ -177,7 +177,7 @@ tests = [ "line block with blank line" =:
177177 =: ".. role:: haskell(code)\n.. role:: lhs(haskell)\n\n:lhs:`text`"
178178 =?> para (codeWith ("", ["lhs", "haskell", "sourceCode"], []) "text")
179179 , "unknown role" =: ":unknown:`text`" =?>
180− para (spanWith ("",[],[("role","unknown")]) (str "text"))
180+ para (codeWith ("",["interpreted-text"],[("role","unknown")]) "text")
181181 ]
182182 , testGroup "footnotes"
183183 [ "remove space before note" =: T.unlines
@@ -188,4 +188,18 @@ tests = [ "line block with blank line" =:
188188 ] =?>
189189 para ("foo" <> note (para "bar"))
190190 ]
191+ , testGroup "inlines"
192+ [ "links can contain an URI without being parsed twice (#4581)" =:
193+ "`http://loc <http://loc>`__" =?>
194+ para (link "http://loc" "" "http://loc")
195+ , "inline markup cannot be nested" =:
196+ "**a*b*c**" =?>
197+ para (strong "a*b*c")
198+ , "bare URI parsing disabled inside emphasis (#4561)" =:
199+ "*http://location*" =?>
200+ para (emph (text "http://location"))
201+ , "include newlines" =:
202+ "**before\nafter**" =?>
203+ para (strong (text "before\nafter"))
204+ ]
191205 ]
test/Tests/Writers/HTML.hs+5
@@ -43,4 +43,9 @@ tests = [ testGroup "inline code"
4343 image "/url" "title" ("my " <> emph "image")
4444 =?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"
4545 ]
46+ , testGroup "blocks"
47+ [ "definition list with empty <dt>" =:
48+ definitionList [(mempty, [para $ text "foo bar"])]
49+ =?> "<dl><dt></dt><dd><p>foo bar</p></dd></dl>"
50+ ]
4651 ]
test/Tests/Writers/Muse.hs+77−17
@@ -275,7 +275,7 @@ tests = [ testGroup "block elements"
275275 unlines [ "#bar"
276276 , "** Foo"
277277 ]
278− , "empty heading" =: header 4 (mempty) =?> "**** <verbatim></verbatim>"
278+ , "empty heading" =: header 4 mempty =?> "**** <verbatim></verbatim>"
279279 ]
280280 , "horizontal rule" =: horizontalRule =?> "----"
281281 , "escape horizontal rule" =: para (text "----") =?> "<verbatim></verbatim>----"
@@ -283,6 +283,7 @@ tests = [ testGroup "block elements"
283283 , "don't escape horizontal inside paragraph" =: para (text "foo ---- bar") =?> "foo ---- bar"
284284 , "escape nonbreaking space" =: para (text "~~") =?> "<verbatim>~~</verbatim>"
285285 , "escape > in the beginning of line" =: para (text "> foo bar") =?> "<verbatim></verbatim>> foo bar"
286+ , "escape string with > and space in the beginning of line" =: para (str "> foo bar") =?> "<verbatim></verbatim>> foo bar"
286287 , testGroup "tables"
287288 [ "table without header" =:
288289 let rows = [[para $ text "Para 1.1", para $ text "Para 1.2"]
@@ -341,36 +342,95 @@ tests = [ testGroup "block elements"
341342 , "do not escape colon" =: str ":" =?> ":"
342343 , "escape - to avoid accidental unordered lists" =: text " - foo" =?> "<verbatim></verbatim> - foo"
343344 , "escape - inside a list to avoid accidental nested unordered lists" =:
344− bulletList [ (para $ text "foo") <>
345− (para $ text "- bar")
345+ bulletList [ para (text "foo") <>
346+ para (text "- bar")
346347 ] =?>
347348 unlines [ " - foo"
348349 , ""
349350 , " <verbatim></verbatim>- bar"
350351 ]
352+ , "escape strings starting with - inside a list" =:
353+ bulletList [ para (str "foo") <>
354+ para (str "- bar")
355+ ] =?>
356+ unlines [ " - foo"
357+ , ""
358+ , " <verbatim></verbatim>- bar"
359+ ]
360+ , "escape - inside a note" =:
361+ note (para (text "- foo")) =?>
362+ unlines [ "[1]"
363+ , ""
364+ , "[1] <verbatim></verbatim>- foo"
365+ ]
366+ , "escape - after softbreak in note" =:
367+ note (para (str "foo" <> softbreak <> str "- bar")) =?>
368+ unlines [ "[1]"
369+ , ""
370+ , "[1] foo"
371+ , " <verbatim></verbatim>- bar"
372+ ]
351373 , "escape ; to avoid accidental comments" =: text "; foo" =?> "<verbatim></verbatim>; foo"
374+ , "escape strings starting with ; and space" =: str "; foo" =?> "<verbatim></verbatim>; foo"
352375 , "escape ; after softbreak" =: text "foo" <> softbreak <> text "; bar" =?> "foo\n<verbatim></verbatim>; bar"
353376 , "escape ; after linebreak" =: text "foo" <> linebreak <> text "; bar" =?> "foo<br>\n<verbatim></verbatim>; bar"
354377 , "do not escape ; inside paragraph" =: text "foo ; bar" =?> "foo ; bar"
378+ , "escape newlines" =: str "foo\nbar" =?> "foo bar"
355379 ]
356380 , testGroup "emphasis"
357− [ "emph" =: emph (text "foo") =?> "<em>foo</em>"
358− , "strong" =: strong (text "foo") =?> "<strong>foo</strong>"
381+ [ "emphasis" =: emph (text "foo") =?> "*foo*"
382+ , "emphasis inside word" =: text "foo" <> emph (text "bar") <> text "baz" =?> "foo<em>bar</em>baz"
383+ , "emphasis before comma" =: emph (text "foo") <> text ", bar" =?> "*foo*, bar"
384+ , "emphasis before period" =: emph (text "foobar") <> text "." =?> "*foobar*."
385+ , "empty emphasis" =: emph mempty =?> "<em></em>"
386+ , "empty strong" =: strong mempty =?> "<strong></strong>"
387+ , "empty strong emphasis" =: strong (emph mempty) =?> "**<em></em>**"
388+ , "empty emphasized strong" =: emph (strong mempty) =?> "*<strong></strong>*"
389+ , "emphasized empty string" =: emph (str "") =?> "<em></em>"
390+ , "strong empty string" =: strong (str "") =?> "<strong></strong>"
391+ , "strong emphasized empty string" =: strong (emph (str "")) =?> "**<em></em>**"
392+ , "emphasized strong empty string" =: emph (strong (str "")) =?> "*<strong></strong>*"
393+ , "emphasized string with space" =: emph (str " ") =?> "<em> </em>"
394+ , "emphasized string ending with space" =: emph (str "foo ") =?> "<em>foo </em>"
395+ , "emphasized string with tab" =: emph (str "\t") =?> "<em>\t</em>"
396+ , "emphasized space between empty strings" =: emph (str "" <> space <> str "") =?> "<em> </em>"
397+ , "strong" =: strong (text "foo") =?> "**foo**"
398+ , "strong inside word" =: text "foo" <> strong (text "bar") <> text "baz" =?> "foo<strong>bar</strong>baz"
399+ , "strong emphasis" =: strong (emph (text "foo")) =?> "***foo***"
400+ , "strong after emphasis" =: emph (text "foo") <> strong (text "bar") =?> "*foo*<strong>bar</strong>"
401+ , "strong emphasis after emphasis" =: emph (text "foo") <> strong (emph (text "bar")) =?> "*foo*<strong>*bar*</strong>"
402+ , "strong in the end of emphasis" =: emph (text "foo" <> strong (text "bar")) =?> "*foo<strong>bar</strong>*"
359403 , "strikeout" =: strikeout (text "foo") =?> "<del>foo</del>"
404+ , "space at the beginning of emphasis" =: emph (text " foo") =?> "<em> foo</em>"
405+ , "space at the end of emphasis" =: emph (text "foo ") =?> "<em>foo </em>"
406+ , "space at the beginning of strong" =: strong (text " foo") =?> "<strong> foo</strong>"
407+ , "space at the end of strong" =: strong (text "foo ") =?> "<strong>foo </strong>"
408+ , "space at the beginning of strong emphasis" =: strong (emph (text " foo")) =?> "**<em> foo</em>**"
409+ , "space at the end of strong emphasis" =: strong (emph (text "foo ")) =?> "**<em>foo </em>**"
410+ , "space at the beginning of emphasiszed strong" =: emph (strong (text " foo")) =?> "*<strong> foo</strong>*"
411+ , "space at the end of emphasized strong" =: emph (strong (text "foo ")) =?> "*<strong>foo </strong>*"
360412 ]
361413 , "superscript" =: superscript (text "foo") =?> "<sup>foo</sup>"
362414 , "subscript" =: subscript (text "foo") =?> "<sub>foo</sub>"
363− , "smallcaps" =: smallcaps (text "foo") =?> "<em>foo</em>"
364− , "smallcaps near emphasis" =: emph (str "foo") <> smallcaps (str "bar") =?> "<em>foobar</em>"
415+ , "smallcaps" =: smallcaps (text "foo") =?> "*foo*"
416+ , "smallcaps near emphasis" =: emph (str "foo") <> smallcaps (str "bar") =?> "*foobar*"
365417 , "single quoted" =: singleQuoted (text "foo") =?> "‘foo’"
366418 , "double quoted" =: doubleQuoted (text "foo") =?> "“foo”"
367419 -- Cite is trivial
368420 , testGroup "code"
369− [ "simple" =: code "foo" =?> "<code>foo</code>"
421+ [ "simple" =: code "foo" =?> "=foo="
422+ , "empty" =: code "" =?> "<code></code>"
423+ , "space" =: code " " =?> "<code> </code>"
424+ , "space at the beginning" =: code " foo" =?> "<code> foo</code>"
425+ , "space at the end" =: code "foo " =?> "<code>foo </code>"
426+ , "use tags for =" =: code "foo = bar" =?> "<code>foo = bar</code>"
370427 , "escape tag" =: code "<code>foo = bar</code> baz" =?> "<code><code>foo = bar<</code><code>/code> baz</code>"
371− , "normalization with attributes" =: codeWith ("",["haskell"],[]) "foo" <> code "bar" =?> "<code>foobar</code>"
372− , "normalization" =: code "</co" <> code "de>" =?> "<code><</code><code>/code></code>"
373− , "normalization with empty string" =: code "</co" <> str "" <> code "de>" =?> "<code><</code><code>/code></code>"
428+ , "normalization with attributes" =: codeWith ("",["haskell"],[]) "foo" <> code "bar" =?> "=foobar="
429+ , "code tag" =: code "<code>foo</code>" =?> "=<code>foo</code>="
430+ , "normalization" =: code "</co" <> code "de>" <> code "=" =?> "<code><</code><code>/code>=</code>"
431+ , "normalization with empty string" =: code "</co" <> str "" <> code "de>" <> code "=" =?> "<code><</code><code>/code>=</code>"
432+ , "emphasized code" =: emph (code "foo") =?> "*=foo=*"
433+ , "strong code" =: strong (code "foo") =?> "**=foo=**"
374434 ]
375435 , testGroup "spaces"
376436 [ "space" =: text "a" <> space <> text "b" =?> "a b"
@@ -385,7 +445,7 @@ tests = [ testGroup "block elements"
385445 , testGroup "math"
386446 [ "inline math" =: math "2^3" =?> "2<sup>3</sup>"
387447 , "display math" =: displayMath "2^3" =?> "2<sup>3</sup>"
388− , "multiple letters in inline math" =: math "abc" =?> "<em>abc</em>"
448+ , "multiple letters in inline math" =: math "abc" =?> "*abc*"
389449 , "expand math before normalization" =: math "[" <> str "2]" =?> "<verbatim>[2]</verbatim>"
390450 , "multiple math expressions inside one inline list" =: math "5_4" <> text ", " <> displayMath "3^2" =?> "5<sub>4</sub>, 3<sup>2</sup>"
391451 ]
@@ -441,11 +501,11 @@ tests = [ testGroup "block elements"
441501 =?> "<class name=\"foobar\">Some text</class>"
442502 , "span without class" =: spanWith ("",[],[]) (text "Some text")
443503 =?> "<class>Some text</class>"
444− , "span with anchor" =: spanWith ("anchor", [], []) (mempty) <> (text "Foo bar")
504+ , "span with anchor" =: spanWith ("anchor", [], []) mempty <> text "Foo bar"
445505 =?> "#anchor Foo bar"
446− , "empty span with anchor" =: spanWith ("anchor", [], []) (mempty)
506+ , "empty span with anchor" =: spanWith ("anchor", [], []) mempty
447507 =?> "#anchor"
448− , "empty span without class and anchor" =: spanWith ("", [], []) (mempty)
508+ , "empty span without class and anchor" =: spanWith ("", [], []) mempty
449509 =?> "<class></class>"
450510 , "span with class and anchor" =: spanWith ("anchor", ["foo"], []) (text "bar")
451511 =?> "#anchor <class name=\"foo\">bar</class>"
@@ -461,7 +521,7 @@ tests = [ testGroup "block elements"
461521 "<em>foo</em>bar"
462522 , "emph quoted" =:
463523 para (doubleQuoted (emph (text "foo"))) =?>
464− "“<em>foo</em>”"
524+ "“*foo*”"
465525 , "strong word before" =:
466526 para (text "foo" <> strong (text "bar")) =?>
467527 "foo<strong>bar</strong>"
@@ -470,7 +530,7 @@ tests = [ testGroup "block elements"
470530 "<strong>foo</strong>bar"
471531 , "strong quoted" =:
472532 para (singleQuoted (strong (text "foo"))) =?>
473− "‘<strong>foo</strong>’"
533+ "‘**foo**’"
474534 ]
475535 ]
476536 ]
test/Tests/Writers/RST.hs+8
@@ -16,6 +16,11 @@ infix 4 =:
1616 => String -> (a, String) -> TestTree
1717(=:) = test (purely (writeRST def . toPandoc))
1818
19+testTemplate :: (ToString a, ToString c, ToPandoc a) =>
20+ String -> String -> (a, c) -> TestTree
21+testTemplate t =
22+ test (purely (writeRST def{ writerTemplate = Just t }) . toPandoc)
23+
1924tests :: [TestTree]
2025tests = [ testGroup "rubrics"
2126 [ "in list item" =:
@@ -156,4 +161,7 @@ tests = [ testGroup "rubrics"
156161 , "Header 2"
157162 , "--------"]
158163 ]
164+ , testTemplate "$subtitle$\n" "subtitle" $
165+ (setMeta "subtitle" ("subtitle" :: Inlines) $ doc $ plain "") =?>
166+ ("subtitle" :: String)
159167 ]
test/command/1126.mdnew file+29
@@ -0,0 +1,29 @@
1+```
2+% pandoc -f html -t latex
3+\begin{eqnarray}
4+A&=&B,\\
5+C&=&D
6+\end{eqnarray}
7+^D
8+\textbackslash{}begin\{eqnarray\}
9+A\&=\&B,\textbackslash{}\textbackslash{} C\&=\&D
10+\textbackslash{}end\{eqnarray\}
11+```
12+
13+```
14+% pandoc -f html+raw_tex -t latex
15+<p>See \eqref{myeq}.</p>
16+\begin{eqnarray}
17+A&=&B,\\
18+C&amp;=&amp;D
19+\\label{myeq}
20+\end{eqnarray}
21+^D
22+See \eqref{myeq}.
23+
24+\begin{eqnarray}
25+A&=&B,\\
26+C&=&D
27+\\label{myeq}
28+\end{eqnarray}
29+```
test/command/1710.md+3−4
@@ -58,7 +58,7 @@ ok
5858\protect\hypertarget{slide-one}{}
5959
6060\begin{columns}[T]
61−\begin{column}{0.40\textwidth}
61+\begin{column}{0.4\textwidth}
6262\begin{itemize}
6363\tightlist
6464\item
@@ -68,7 +68,7 @@ ok
6868\end{itemize}
6969\end{column}
7070
71−\begin{column}{0.40\textwidth}
71+\begin{column}{0.4\textwidth}
7272\begin{itemize}
7373\tightlist
7474\item
@@ -78,11 +78,10 @@ ok
7878\end{itemize}
7979\end{column}
8080
81−\begin{column}{0.10\textwidth}
81+\begin{column}{0.1\textwidth}
8282ok
8383\end{column}
8484\end{columns}
8585
8686\end{frame}
8787```
88−
test/command/2118.md+1−1
@@ -7,5 +7,5 @@
77 \label{fig:setminus}
88\end{figure}
99^D
10−[Para [Image ("",[],[("width","80%")]) [Str "Set",Space,Str "subtraction",Span ("",[],[("label","fig:setminus")]) []] ("setminus.png","fig:")]]
10+[Para [Image ("fig:setminus",[],[("width","80%")]) [Str "Set",Space,Str "subtraction",Span ("",[],[("label","fig:setminus")]) []] ("setminus.png","fig:")]]
1111```
test/command/3407.md+2−2
@@ -1,6 +1,6 @@
11```
22% pandoc -f native -t rst
3−[Para [Span ("",[],[("role","foo")]) [Str "text"]]]
3+[Para [Code ("",["interpreted-text"],[("role","foo")]) "text"]]
44^D
55:foo:`text`
66```
@@ -9,5 +9,5 @@
99% pandoc -f rst -t native
1010:foo:`text`
1111^D
12−[Para [Span ("",[],[("role","foo")]) [Str "text"]]]
12+[Para [Code ("",["interpreted-text"],[("role","foo")]) "text"]]
1313```
test/command/3432.md+1−1
@@ -195,7 +195,7 @@ List-table without header-rows.
195195</table>
196196```
197197
198−List-table with empty cells. You need a space after '-', otherwise the row will disapear. Parser for Bulletlists causes this ristriction.
198+List-table with empty cells. You need a space after '-', otherwise the row will disappear. Parser for Bulletlists causes this restriction.
199199
200200```
201201% pandoc -f rst
test/command/3534.md+22
@@ -21,3 +21,25 @@ I want to explain the interface of \lstinline[language=Java]{public class MyClas
2121[Para [Str "I",Space,Str "want",Space,Str "to",Space,Str "explain",Space,Str "the",Space,Str "interface",Space,Str "of",Space,Code ("",["java"],[]) "public class MyClass",Str "."]]
2222```
2323
24+```
25+% pandoc -f latex -t html
26+I want to explain the interface of \mintinline{java}{public class MyClass}.
27+^D
28+<p>I want to explain the interface of <code class="sourceCode java"><span class="kw">public</span> <span class="kw">class</span> MyClass</code>.</p>
29+
30+```
31+
32+```
33+% pandoc -f latex -t html
34+I want to explain the interface of \mintinline{java}|public class MyClass|.
35+^D
36+<p>I want to explain the interface of <code class="sourceCode java"><span class="kw">public</span> <span class="kw">class</span> MyClass</code>.</p>
37+
38+```
39+
40+```
41+% pandoc -f latex -t native
42+I want to explain the interface of \mintinline[linenos]{java}{public class MyClass}.
43+^D
44+[Para [Str "I",Space,Str "want",Space,Str "to",Space,Str "explain",Space,Str "the",Space,Str "interface",Space,Str "of",Space,Code ("",["java"],[]) "public class MyClass",Str "."]]
45+```
test/command/3558.md+2−2
@@ -6,7 +6,7 @@ hello
66
77\endmulti
88^D
9−[RawBlock (Format "latex") "\\multi"
9+[RawBlock (Format "tex") "\\multi"
1010,Para [Str "hello"]
11−,RawBlock (Format "latex") "\\endmulti"]
11+,RawBlock (Format "tex") "\\endmulti"]
1212```
test/command/3716.md+1−1
@@ -2,5 +2,5 @@
22% pandoc
33<http://example.com>{.foo}
44^D
5−<p><a href="http://example.com" class="uri foo">http://example.com</a></p>
5+<p><a href="http://example.com" class="foo">http://example.com</a></p>
66```
test/command/3804.md+1−1
@@ -2,5 +2,5 @@
22% pandoc -t native
33\titleformat{\chapter}[display]{\normalfont\large\bfseries}{第\thechapter{}章}{20pt}{\Huge}
44^D
5−[RawBlock (Format "latex") "\\titleformat{\\chapter}[display]{\\normalfont\\large\\bfseries}{\31532\\thechapter{}\31456}{20pt}{\\Huge}"]
5+[RawBlock (Format "tex") "\\titleformat{\\chapter}[display]{\\normalfont\\large\\bfseries}{\31532\\thechapter{}\31456}{20pt}{\\Huge}"]
66```
test/command/3947.md+1−1
@@ -6,6 +6,6 @@
66
77 Another Code block
88^D
9−[RawBlock (Format "latex") "\\newpage"
9+[RawBlock (Format "tex") "\\newpage"
1010,CodeBlock ("",[],[]) "Code block\n\nAnother Code block"]
1111```
test/command/4016.md+2−2
@@ -17,7 +17,7 @@ pandoc -t beamer
1717\protect\hypertarget{level-2-blocks}{}
1818
1919\begin{columns}[T]
20−\begin{column}{0.40\textwidth}
20+\begin{column}{0.4\textwidth}
2121\begin{block}{Block one}
2222
2323\begin{itemize}
@@ -29,7 +29,7 @@ pandoc -t beamer
2929\end{block}
3030\end{column}
3131
32−\begin{column}{0.60\textwidth}
32+\begin{column}{0.6\textwidth}
3333\begin{block}{Block two}
3434
3535\begin{itemize}
test/command/4056.md+1−1
@@ -5,7 +5,7 @@
55\end{shaded}
66}
77^D
8−[RawBlock (Format "latex") "\\parbox[t]{0.4\\textwidth}{\n\\begin{shaded}\n\\end{shaded}\n}"]
8+[RawBlock (Format "tex") "\\parbox[t]{0.4\\textwidth}{\n\\begin{shaded}\n\\end{shaded}\n}"]
99```
1010
1111```
test/command/4159.md+1−1
@@ -3,6 +3,6 @@
33\newcommand{\gen}{a\ Gen\ b}
44abc
55^D
6−[RawBlock (Format "latex") "\\newcommand{\\gen}{a\\ Gen\\ b}"
6+[RawBlock (Format "tex") "\\newcommand{\\gen}{a\\ Gen\\ b}"
77,Para [Str "abc"]]
88```
test/command/4284.mdnew file+40
@@ -0,0 +1,40 @@
1+```
2+% pandoc -f org -t native
3+#+EXCLUDE_TAGS:apple cat bye dog %
4+
5+* This should not appear :apple:
6+* NOEXPORT should appear if not specified in EXCLUDE_TAGS :noexport:
7+* This should not appear :cat:hi:laptop:
8+** Children of headers with excluded tags should not appear :xylophone:
9+* This should not appear :%:
10+^D
11+[Header 1 ("noexport-should-appear-if-not-specified-in-excludetags",[],[]) [Str "NOEXPORT",Space,Str "should",Space,Str "appear",Space,Str "if",Space,Str "not",Space,Str "specified",Space,Str "in",Space,Str "EXCLUDE",Subscript [Str "TAGS"],Space,Span ("",["tag"],[("tag-name","noexport")]) [SmallCaps [Str "noexport"]]]]
12+```
13+
14+```
15+% pandoc -f org -t native
16+#+EXCLUDE_TAGS:elephant
17+* This should not appear :elephant:
18+* This should appear :fawn:
19+^D
20+[Header 1 ("this-should-appear",[],[]) [Str "This",Space,Str "should",Space,Str "appear",Space,Span ("",["tag"],[("tag-name","fawn")]) [SmallCaps [Str "fawn"]]]]
21+```
22+
23+```
24+% pandoc -f org -t native
25+#+EXCLUDE_TAGS: giraffe
26+#+EXCLUDE_TAGS: hippo
27+* This should not appear :giraffe:
28+* This should not appear :hippo:
29+* This should appear :noexport:
30+^D
31+[Header 1 ("this-should-appear",[],[]) [Str "This",Space,Str "should",Space,Str "appear",Space,Span ("",["tag"],[("tag-name","noexport")]) [SmallCaps [Str "noexport"]]]]
32+```
33+
34+```
35+% pandoc -f org -t native
36+#+EXCLUDE_TAGS:
37+* NOEXPORT should appear if not specified in EXCLUDE_TAGS :noexport:
38+^D
39+[Header 1 ("noexport-should-appear-if-not-specified-in-excludetags",[],[]) [Str "NOEXPORT",Space,Str "should",Space,Str "appear",Space,Str "if",Space,Str "not",Space,Str "specified",Space,Str "in",Space,Str "EXCLUDE",Subscript [Str "TAGS"],Space,Span ("",["tag"],[("tag-name","noexport")]) [SmallCaps [Str "noexport"]]]]
40+```
test/command/4528.mdnew file+156
@@ -0,0 +1,156 @@
1+# Rendering small caps, superscripts and subscripts with and without `raw_html`
2+
3+## Small caps
4+
5+```
6+% pandoc --wrap=none -f latex -t commonmark-raw_html
7+This has \textsc{small caps} in it.
8+^D
9+This has SMALL CAPS in it.
10+```
11+
12+```
13+% pandoc --wrap=none -f latex -t commonmark+raw_html
14+This has \textsc{small caps} in it.
15+^D
16+This has <span class="smallcaps">small caps</span> in it.
17+```
18+```
19+
20+```
21+% pandoc --wrap=none -f latex -t markdown_strict+raw_html
22+This has \textsc{small caps} in it.
23+^D
24+This has <span class="smallcaps">small caps</span> in it.
25+```
26+
27+## Strikeout
28+
29+```
30+% pandoc --wrap=none -f html -t commonmark-raw_html-strikeout
31+This has <s>strikeout</s> in it.
32+^D
33+This has strikeout in it.
34+
35+```
36+% pandoc --wrap=none -f html -t commonmark+raw_html-strikeout
37+This has <s>strikeout</s> in it.
38+^D
39+This has <s>strikeout</s> in it.
40+```
41+
42+```
43+% pandoc --wrap=none -f html -t commonmark-raw_html+strikeout
44+This has <s>strikeout</s> in it.
45+^D
46+This has ~~strikeout~~ in it.
47+```
48+
49+```
50+% pandoc --wrap=none -f html -t commonmark+raw_html+strikeout
51+This has <s>strikeout</s> in it.
52+^D
53+This has ~~strikeout~~ in it.
54+```
55+
56+```
57+% pandoc --wrap=none -f html -t markdown_strict-raw_html-strikeout
58+This has <s>strikeout</s> in it.
59+^D
60+This has strikeout in it.
61+```
62+
63+```
64+% pandoc --wrap=none -f html -t markdown_strict+raw_html-strikeout
65+This has <s>strikeout</s> in it.
66+^D
67+This has <s>strikeout</s> in it.
68+```
69+
70+```
71+% pandoc --wrap=none -f html -t markdown_strict-raw_html+strikeout
72+This has <s>strikeout</s> in it.
73+^D
74+This has ~~strikeout~~ in it.
75+```
76+
77+```
78+% pandoc --wrap=none -f html -t markdown_strict+raw_html+strikeout
79+This has <s>strikeout</s> in it.
80+^D
81+This has ~~strikeout~~ in it.
82+```
83+
84+## Superscript
85+
86+```
87+% pandoc --wrap=none -f html -t commonmark-raw_html
88+This has <sup>superscript</sup> in it and <sup>2 3</sup> again. With emphasis: <sup><em>2</em> 3</sup>. With letters: <sup>foo</sup>. With a span: <sup><span class=foo>2</span></sup>.
89+^D
90+This has ^(superscript) in it and ² ³ again. With emphasis: ^(*2* 3). With letters: ^(foo). With a span: ².
91+```
92+
93+```
94+% pandoc --wrap=none -f html -t commonmark+raw_html
95+This has <sup>superscript</sup> in it and <sup>2</sup> again.
96+^D
97+This has <sup>superscript</sup> in it and <sup>2</sup> again.
98+```
99+
100+```
101+% pandoc --wrap=none -f html -t markdown_strict-raw_html-superscript
102+This has <sup>superscript</sup> in it and <sup>2</sup> again.
103+^D
104+This has ^(superscript) in it and ² again.
105+```
106+
107+```
108+% pandoc --wrap=none -f html -t markdown_strict+raw_html-superscript
109+This has <sup>superscript</sup> in it and <sup>2</sup> again.
110+^D
111+This has <sup>superscript</sup> in it and <sup>2</sup> again.
112+```
113+
114+```
115+% pandoc --wrap=none -f html -t markdown_strict+raw_html+superscript
116+This has <sup>superscript</sup> in it and <sup>2</sup> again.
117+^D
118+This has ^superscript^ in it and ^2^ again.
119+```
120+
121+## Subscript
122+
123+```
124+% pandoc --wrap=none -f html -t commonmark-raw_html
125+This has <sub>subscript</sub> in it and <sub>2 3</sub> again. With emphasis: <sub><em>2</em> 3</sub>. With letters: <sub>foo</sub>. With a span: <sub><span class=foo>2</span></sub>.
126+^D
127+This has \_(subscript) in it and ₂ ₃ again. With emphasis: \_(*2* 3). With letters: \_(foo). With a span: ₂.
128+```
129+
130+```
131+% pandoc --wrap=none -f html -t commonmark+raw_html
132+This has <sub>subscript</sub> in it and <sub>2</sub> again.
133+^D
134+This has <sub>subscript</sub> in it and <sub>2</sub> again.
135+```
136+
137+```
138+% pandoc --wrap=none -f html -t markdown_strict-raw_html-subscript
139+This has <sub>subscript</sub> in it and <sub>2</sub> again.
140+^D
141+This has _(subscript) in it and ₂ again.
142+```
143+
144+```
145+% pandoc --wrap=none -f html -t markdown_strict+raw_html-subscript
146+This has <sub>subscript</sub> in it and <sub>2</sub> again.
147+^D
148+This has <sub>subscript</sub> in it and <sub>2</sub> again.
149+```
150+
151+```
152+% pandoc --wrap=none -f html -t markdown_strict+raw_html+subscript
153+This has <sub>subscript</sub> in it and <sub>2</sub> again.
154+^D
155+This has ~subscript~ in it and ~2~ again.
156+```
test/command/4545.mdnew file+20
@@ -0,0 +1,20 @@
1+```
2+% pandoc -t asciidoc
3+Test 1
4+
5+[my text]
6+
7+Test 2
8+^D
9+Test 1
10+
11+{empty}[my text]
12+
13+Test 2
14+```
15+```
16+% pandoc -t asciidoc
17+4\. foo
18+^D
19+{empty}4. foo
20+```
test/command/4553.mdnew file+15
@@ -0,0 +1,15 @@
1+```
2+pandoc -f latex -t native
3+foo \include{command/bar}
4+^D
5+[Para [Str "foo"]
6+,Para [Emph [Str "hi",Space,Str "there"]]]
7+```
8+
9+```
10+pandoc -f latex -t native
11+foo \input{command/bar}
12+^D
13+[Para [Str "foo",Space,Emph [Str "hi",Space,Str "there"]]]
14+```
15+
test/command/4624.mdnew file+30
@@ -0,0 +1,30 @@
1+```
2+% pandoc -f latex -t native
3+\begin{Verbatim}[key1=value1]
4+code1
5+
6+\end{Verbatim}
7+
8+
9+\begin{lstlisting}[key2=value2]
10+code2
11+
12+\end{lstlisting}
13+
14+\begin{verbatim}
15+code3
16+\end{verbatim}
17+
18+\begin{verbatim}
19+code4
20+ \end{verbatim}
21+
22+\begin{verbatim}
23+code5\end{verbatim}
24+^D
25+[CodeBlock ("",[],[("key1","value1")]) "code1\n"
26+,CodeBlock ("",[],[("key2","value2")]) "code2\n "
27+,CodeBlock ("",[],[]) "code3"
28+,CodeBlock ("",[],[]) "code4"
29+,CodeBlock ("",[],[]) "code5"]
30+```
test/command/4653.mdnew file+8
@@ -0,0 +1,8 @@
1+```
2+% pandoc -t latex
3+\let\tex\TeX
4+\renewcommand{\TeX}{\tex\xspace}
5+^D
6+\let\tex\TeX
7+\renewcommand{\TeX}{\tex\xspace}
8+```
test/command/4667.mdnew file+20
@@ -0,0 +1,20 @@
1+```
2+pandoc -t latex
3+---
4+header-includes:
5+- \newcommand{\blandscape}{\begin{landscape}}
6+- \newcommand{\elandscape}{\end{landscape}}
7+...
8+
9+\blandscape
10+
11+testing
12+
13+\elandscape
14+^D
15+\begin{landscape}
16+
17+testing
18+
19+\end{landscape}
20+```
test/command/4669.mdnew file+29
@@ -0,0 +1,29 @@
1+```
2+% pandoc -f latex -t native
3+{\tt <-}
4+
5+\begin{verbatim}
6+ while (n > 0) {
7+\end{verbatim}
8+^D
9+[Para [Span ("",[],[]) [Str "<-"]]
10+,CodeBlock ("",[],[]) " while (n > 0) {"]
11+```
12+
13+```
14+% pandoc -f latex -t native
15+\begin{itemize}
16+\item<1> one
17+\item<2-3,5> two
18+\item<2| @alert> three
19+\item<handout> four
20+\item<beamer:2> five
21+\end{itemize}
22+^D
23+[BulletList
24+ [[Para [Str "one"]]
25+ ,[Para [Str "two"]]
26+ ,[Para [Str "three"]]
27+ ,[Para [Str "four"]]
28+ ,[Para [Str "five"]]]]
29+```
test/command/4677.mdnew file+8
@@ -0,0 +1,8 @@
1+```
2+% pandoc --to "markdown-bracketed_spans-fenced_divs-link_attributes-simple_tables-multiline_tables-grid_tables-pipe_tables-fenced_code_attributes-markdown_in_html_blocks-table_captions-smart"
3+![Caption](img.png){#img:1}
4+^D
5+<figure>
6+<img src="img.png" alt="Caption" id="img:1" /><figcaption>Caption</figcaption>
7+</figure>
8+```
test/command/4690.mdnew file+28
@@ -0,0 +1,28 @@
1+```
2+% pandoc -t beamer
3+# title
4+
5+:::: {.columns}
6+::: {.column width="8%"}
7+content
8+:::
9+::: {.column width="84%"}
10+content2
11+:::
12+::::
13+^D
14+\begin{frame}{title}
15+\protect\hypertarget{title}{}
16+
17+\begin{columns}[T]
18+\begin{column}{0.08\textwidth}
19+content
20+\end{column}
21+
22+\begin{column}{0.84\textwidth}
23+content2
24+\end{column}
25+\end{columns}
26+
27+\end{frame}
28+```
test/command/4722.mdnew file+34
@@ -0,0 +1,34 @@
1+```
2+% pandoc -f tikiwiki -t native
3+*Level 1
4+*Level 1
5+**Level 2
6+***Level 3
7+*Level 1
8+^D
9+[BulletList
10+ [[Plain [Str "Level",Space,Str "1"]]
11+ ,[Plain [Str "Level",Space,Str "1"]
12+ ,BulletList
13+ [[Plain [Str "Level",Space,Str "2"]
14+ ,BulletList
15+ [[Plain [Str "Level",Space,Str "3"]]]]]]
16+ ,[Plain [Str "Level",Space,Str "1"]]]]
17+```
18+```
19+% pandoc -f tikiwiki -t native
20+#Level 1
21+#Level 1
22+##Level 2
23+###Level 3
24+#Level 1
25+^D
26+[OrderedList (1,DefaultStyle,DefaultDelim)
27+ [[Plain [Str "Level",Space,Str "1"]]
28+ ,[Plain [Str "Level",Space,Str "1"]
29+ ,OrderedList (1,DefaultStyle,DefaultDelim)
30+ [[Plain [Str "Level",Space,Str "2"]
31+ ,OrderedList (1,DefaultStyle,DefaultDelim)
32+ [[Plain [Str "Level",Space,Str "3"]]]]]]
33+ ,[Plain [Str "Level",Space,Str "1"]]]]
34+```
test/command/4742.mdnew file+25
@@ -0,0 +1,25 @@
1+Check that the commonmark reader handles the `ascii_identifiers`
2+extension properly.
3+
4+```
5+% pandoc -f commonmark+gfm_auto_identifiers+ascii_identifiers -t native
6+# non ascii ⚠️ räksmörgås
7+^D
8+[Header 1 ("non-ascii--raksmorgas",[],[]) [Str "non",Space,Str "ascii",Space,Str "\9888\65039",Space,Str "r\228ksm\246rg\229s"]]
9+```
10+
11+```
12+% pandoc -f commonmark+gfm_auto_identifiers-ascii_identifiers -t native
13+# non ascii ⚠️ räksmörgås
14+^D
15+[Header 1 ("non-ascii-\65039-r\228ksm\246rg\229s",[],[]) [Str "non",Space,Str "ascii",Space,Str "\9888\65039",Space,Str "r\228ksm\246rg\229s"]]
16+```
17+
18+`gfm` should have `ascii_identifiers` enabled by default.
19+
20+```
21+% pandoc -f gfm -t native
22+# non ascii ⚠️ räksmörgås
23+^D
24+[Header 1 ("non-ascii--raksmorgas",[],[]) [Str "non",Space,Str "ascii",Space,Str "\9888\65039",Space,Str "r\228ksm\246rg\229s"]]
25+```
test/command/4743.mdnew file+25
@@ -0,0 +1,25 @@
1+Test that emojis are wrapped in Span
2+
3+```
4+% pandoc -f commonmark+emoji -t native
5+My:thumbsup:emoji:heart:
6+^D
7+[Para [Str "My",Span ("",["emoji"],[("data-emoji","thumbsup")]) [Str "\128077"],Str "emoji",Span ("",["emoji"],[("data-emoji","heart")]) [Str "\10084\65039"]]]
8+```
9+
10+```
11+% pandoc -f markdown+emoji -t native
12+My:thumbsup:emoji:heart:
13+^D
14+[Para [Str "My",Span ("",["emoji"],[("data-emoji","thumbsup")]) [Str "\128077"],Str "emoji",Span ("",["emoji"],[("data-emoji","heart")]) [Str "\10084\65039"]]]
15+```
16+
17+```
18+% pandoc -f commonmark+emoji -t html
19+:zero: header
20+=============
21+My:thumbsup:emoji:heart:x :hearts: xyz
22+^D
23+<h1><span class="emoji" data-emoji="zero">0️⃣</span> header</h1>
24+<p>My<span class="emoji" data-emoji="thumbsup">👍</span>emoji<span class="emoji" data-emoji="heart">❤️</span>x <span class="emoji" data-emoji="hearts">♥️</span> xyz</p>
25+```
test/command/4748.mdnew file+16
@@ -0,0 +1,16 @@
1+```
2+% pandoc -f org -t rst
3+Before example block.
4+#+begin_example
5+This is in an example block.
6+#+end_example
7+After example block.
8+^D
9+Before example block.
10+
11+::
12+
13+ This is in an example block.
14+
15+After example block.
16+```
test/command/4768.mdnew file+7
@@ -0,0 +1,7 @@
1+```
2+% pandoc -f latex -t plain
3+\def\foo#1!#2!#3{#1 or #2 and #3}
4+\foo aa!bbb bbb!{ccc}
5+^D
6+aa or bbb bbb and ccc
7+```
test/command/4781.mdnew file+22
@@ -0,0 +1,22 @@
1+```
2+% pandoc -t native
3+Markdown parsed *here*
4+
5+\include{command/bar}
6+
7+*But not here*
8+^D
9+[Para [Str "Markdown",Space,Str "parsed",Space,Emph [Str "here"]]
10+,RawBlock (Format "tex") "\\include{command/bar}"
11+,Para [Emph [Str "But",Space,Str "not",Space,Str "here"]]]
12+```
13+
14+```
15+% pandoc -t native
16+*here* \input{command/bar}
17+
18+*But not here*
19+^D
20+[Para [Emph [Str "here"],Space,RawInline (Format "tex") "\\input{command/bar}"]
21+,Para [Emph [Str "But",Space,Str "not",Space,Str "here"]]]
22+```
test/command/4794.mdnew file+18
@@ -0,0 +1,18 @@
1+```
2+% pandoc -f markdown -t mediawiki
3+| Column1 | Column2 | Column3 |
4+| ------- | ------- | ------- |
5+| text | | text |
6+^D
7+{|
8+! Column1
9+! Column2
10+! Column3
11+|-
12+| text
13+|
14+| text
15+|}
16+
17+
18+```
test/command/4811.mdnew file+48
@@ -0,0 +1,48 @@
1+No blank lines in inline interpreted roles:
2+
3+```
4+% pandoc -f rst -t native
5+`no
6+
7+blank`:myrole:
8+^D
9+[Para [Str "`no"]
10+,Para [Str "blank`:myrole:"]]
11+```
12+
13+Backslash escape behaves properly in interpreted roles:
14+
15+```
16+% pandoc -f rst -t native
17+`hi\ there`:sup:
18+
19+`hi\ there`:code:
20+^D
21+[Para [Superscript [Str "hithere"]]
22+,Para [Code ("",["sourceCode"],[]) "hi\\ there"]]
23+```
24+
25+Backtick followed by alphanumeric doesn't end the span:
26+```
27+% pandoc -f rst -t native
28+`hi`there`:myrole:
29+^D
30+[Para [Code ("",["interpreted-text"],[("role","myrole")]) "hi`there"]]
31+```
32+
33+Newline is okay, as long as not blank:
34+```
35+% pandoc -f rst -t native
36+`hi
37+there`:myrole:
38+^D
39+[Para [Code ("",["interpreted-text"],[("role","myrole")]) "hi\nthere"]]
40+```
41+
42+Use span for title-reference:
43+```
44+% pandoc -f rst -t native
45+`default`
46+^D
47+[Para [Span ("",["title-ref"],[]) [Str "default"]]]
48+```
test/command/4817.mdnew file+10
@@ -0,0 +1,10 @@
1+```
2+% pandoc -t native -s
3+---
4+foo:
5+- bar: bam
6+...
7+^D
8+Pandoc (Meta {unMeta = fromList [("foo",MetaList [MetaMap (fromList [("bar",MetaInlines [Str "bam"])])])]})
9+[]
10+```
test/command/4819.mdnew file+50
@@ -0,0 +1,50 @@
1+```
2+% pandoc -f markdown -t native -s
3+---
4+foo: 42
5+...
6+^D
7+Pandoc (Meta {unMeta = fromList [("foo",MetaInlines [Str "42"])]})
8+[]
9+```
10+
11+```
12+% pandoc -f markdown -t native -s
13+---
14+foo: true
15+...
16+^D
17+Pandoc (Meta {unMeta = fromList [("foo",MetaBool True)]})
18+[]
19+```
20+
21+```
22+% pandoc -f markdown -t native -s
23+---
24+foo: True
25+...
26+^D
27+Pandoc (Meta {unMeta = fromList [("foo",MetaBool True)]})
28+[]
29+```
30+
31+```
32+% pandoc -f markdown -t native -s
33+---
34+foo: FALSE
35+...
36+^D
37+Pandoc (Meta {unMeta = fromList [("foo",MetaBool False)]})
38+[]
39+```
40+
41+```
42+% pandoc -f markdown -t native -s
43+---
44+foo: no
45+...
46+^D
47+Pandoc (Meta {unMeta = fromList [("foo",MetaInlines [Str "no"])]})
48+[]
49+```
50+
test/command/4832.mdnew file+21
@@ -0,0 +1,21 @@
1+```
2+% pandoc -f latex -t native
3+\url{http://example.com/foo%20bar.htm}
4+^D
5+[Para [Link ("",[],[]) [Str "http://example.com/foo%20bar.htm"] ("http://example.com/foo%20bar.htm","")]]
6+```
7+
8+```
9+% pandoc -f latex -t native
10+\url{http://example.com/foo{bar}.htm}
11+^D
12+[Para [Link ("",[],[]) [Str "http://example.com/foo{bar}.htm"] ("http://example.com/foo{bar}.htm","")]]
13+```
14+
15+```
16+% pandoc -f latex -t native
17+\href{http://example.com/foo%20bar}{Foobar}
18+^D
19+[Para [Link ("",[],[]) [Str "Foobar"] ("http://example.com/foo%20bar","")]]
20+```
21+
test/command/4833.mdnew file+20
@@ -0,0 +1,20 @@
1+```
2+pandoc -f native -t rst
3+[Div ("",["warning"],[])
4+ [Div ("",["admonition-title"],[])
5+ [Para [Str "Warning"]]
6+ ,Para [Str "Hi"]]]
7+^D
8+.. warning::
9+
10+ Hi
11+```
12+```
13+pandoc -f native -t rst
14+[Div ("",["unknown"],[])
15+ [Para [Str "Hi"]]]
16+^D
17+.. container:: unknown
18+
19+ Hi
20+```
test/command/4842.mdnew file+6
@@ -0,0 +1,6 @@
1+```
2+pandoc -f latex -t native
3+\l
4+^D
5+[Para [Str "\322"]]
6+```
test/command/4845.mdnew file+6
@@ -0,0 +1,6 @@
1+```
2+% pandoc -f html -t native
3+x<a href="/foo"> leading trailing space </a>x
4+^D
5+[Plain [Str "x",Space,Link ("",[],[]) [Str "leading",Space,Str "trailing",Space,Str "space"] ("/foo",""),Space,Str "x"]]
6+```
test/command/4848.mdnew file+59
@@ -0,0 +1,59 @@
1+```
2+% pandoc -f latex -t native
3+\enquote*{hi}
4+^D
5+[Para [Quoted SingleQuote [Str "hi"]]]
6+```
7+
8+```
9+% pandoc -f latex -t native
10+\foreignquote{italian}{hi}
11+^D
12+[Para [Quoted DoubleQuote [Span ("",[],[("lang","it")]) [Str "hi"]]]]
13+```
14+
15+```
16+% pandoc -f latex -t native
17+\hyphenquote*{italian}{hi}
18+^D
19+[Para [Quoted SingleQuote [Span ("",[],[("lang","it")]) [Str "hi"]]]]
20+```
21+
22+```
23+% pandoc -f latex -t native
24+Lorem ipsum
25+\blockquote{dolor sit amet}
26+consectetuer.
27+^D
28+[Para [Str "Lorem",Space,Str "ipsum"]
29+,BlockQuote
30+ [Para [Str "dolor",Space,Str "sit",Space,Str "amet"]]
31+,Para [Str "consectetuer."]]
32+```
33+
34+```
35+% pandoc -f latex -t native
36+Lorem ipsum
37+\blockcquote[198]{Knu86}{dolor sit amet}
38+consectetuer.
39+^D
40+[Para [Str "Lorem",Space,Str "ipsum"]
41+,BlockQuote
42+ [Para [Str "dolor",Space,Str "sit",Space,Str "amet"]
43+ ,Para [Cite [Citation {citationId = "Knu86", citationPrefix = [], citationSuffix = [Str "198"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] []]]
44+,Para [Str "consectetuer."]]
45+```
46+
47+```
48+% pandoc -f latex -t native
49+Lorem ipsum
50+\foreignblockquote{italian}{dolor sit amet}
51+consectetuer.
52+^D
53+[Para [Str "Lorem",Space,Str "ipsum"]
54+,BlockQuote
55+ [Div ("",[],[("lang","it")])
56+ [Para [Str "dolor",Space,Str "sit",Space,Str "amet"]]]
57+,Para [Str "consectetuer."]]
58+```
59+
test/command/4860.mdnew file+9
@@ -0,0 +1,9 @@
1+```
2+% pandoc -f rst -t native
3+This is broken_.
4+
5+.. ***** REFERENCES FOLLOW *****
6+.. _broken: http://google.com
7+^D
8+[Para [Str "This",Space,Str "is",Space,Link ("",[],[]) [Str "broken"] ("http://google.com",""),Str "."]]
9+```
test/command/4877.mdnew file+13
@@ -0,0 +1,13 @@
1+```
2+% pandoc -f html -t native
3+My <script type="math/tex">\mathcal{D}</script>
4+^D
5+[Plain [Str "My",Space,Math InlineMath "\\mathcal{D}"]]
6+```
7+
8+```
9+% pandoc -f html -t native
10+<script type="math/tex; mode=display">\mathcal{D}</script>
11+^D
12+[Plain [Math DisplayMath "\\mathcal{D}"]]
13+```
test/command/4885.mdnew file+8
@@ -0,0 +1,8 @@
1+```
2+% pandoc -f org -t markdown
3+This won't show the command.
4+src_maxima[:exports none :results raw]{tex('integrate(sin((e^x)/pi),x,0,inf));} $$\int_{0}^{\infty }{\sin \left({{e^{x}}\over{\pi}}\right)\;dx}$$
5+^D
6+This won\'t show the command.
7+$$\int_{0}^{\infty }{\sin \left({{e^{x}}\over{\pi}}\right)\;dx}$$
8+```
test/command/4908.mdnew file+16
@@ -0,0 +1,16 @@
1+```
2+% pandoc -f markdown_mmd+fancy_lists+example_lists -t native -t plain
3+(@) Example one
4+(@) Example two
5+
6+some text
7+
8+(@) Example three
9+^D
10+(1) Example one
11+(2) Example two
12+
13+some text
14+
15+(3) Example three
16+```
test/command/4913.mdnew file+34
@@ -0,0 +1,34 @@
1+```
2+% pandoc -f markdown -t html
3+[https://pandoc.org](https://pandoc.org)
4+^D
5+<p><a href="https://pandoc.org">https://pandoc.org</a></p>
6+```
7+
8+```
9+% pandoc -f markdown -t markdown
10+[https://pandoc.org](https://pandoc.org)
11+^D
12+<https://pandoc.org>
13+```
14+
15+```
16+% pandoc -f markdown -t html
17+<https://pandoc.org>
18+^D
19+<p><a href="https://pandoc.org" class="uri">https://pandoc.org</a></p>
20+```
21+
22+```
23+% pandoc -f markdown -t html
24+<https://pandoc.org>{.foo}
25+^D
26+<p><a href="https://pandoc.org" class="foo">https://pandoc.org</a></p>
27+```
28+
29+```
30+% pandoc -f markdown -t html
31+<me@example.com>
32+^D
33+<p><a href="mailto:me@example.com" class="email">me@example.com</a></p>
34+```
test/command/4919.mdnew file+14
@@ -0,0 +1,14 @@
1+```
2+% pandoc -f rst -t native
3+.. _`tgtmath`:
4+
5+ .. math::
6+ :name:
7+
8+ V = \frac{K}{r^2}
9+^D
10+[Div ("tgtmath",[],[])
11+ [BlockQuote
12+ [Para [Math DisplayMath "V = \\frac{K}{r^2}"]]]]
13+```
14+
test/command/4928.mdnew file+48
@@ -0,0 +1,48 @@
1+```
2+% pandoc -f latex -t native
3+\cites(Multiprenote)(multipostnote)[23][42]{Knu86}[65]{Nie72}
4+^D
5+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "Multiprenote",Space,Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65",Str ",",Space,Str "multipostnote"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites(Multiprenote)(multipostnote)[23][42]{Knu86}[65]{Nie72}"]]]
6+```
7+
8+```
9+% pandoc -f latex -t native
10+\cites(Multiprenote)()[23][42]{Knu86}[65]{Nie72}
11+^D
12+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "Multiprenote",Space,Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites(Multiprenote)()[23][42]{Knu86}[65]{Nie72}"]]]
13+```
14+
15+```
16+% pandoc -f latex -t native
17+\cites()(multipostnote)[23][42]{Knu86}[65]{Nie72}
18+^D
19+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65",Str ",",Space,Str "multipostnote"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites()(multipostnote)[23][42]{Knu86}[65]{Nie72}"]]]
20+```
21+
22+```
23+% pandoc -f latex -t native
24+\cites()()[23][42]{Knu86}[65]{Nie72}
25+^D
26+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites()()[23][42]{Knu86}[65]{Nie72}"]]]
27+```
28+
29+```
30+% pandoc -f latex -t native
31+\cites(multipostnote)[23][42]{Knu86}[65]{Nie72}
32+^D
33+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65",Str ",",Space,Str "multipostnote"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites(multipostnote)[23][42]{Knu86}[65]{Nie72}"]]]
34+```
35+
36+```
37+% pandoc -f latex -t native
38+\cites(Multiprenote)(multipostnote){Knu86}
39+^D
40+[Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "Multiprenote"], citationSuffix = [Str ",",Space,Str "multipostnote"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\cites(Multiprenote)(multipostnote){Knu86}"]]]
41+```
42+
43+```
44+% pandoc -f latex -t native
45+\footcites(Multiprenote)(multipostnote)[23][42]{Knu86}[65]{Nie72}
46+^D
47+[Para [Note [Para [Cite [Citation {citationId = "Knu86", citationPrefix = [Str "Multiprenote",Space,Str "23"], citationSuffix = [Str "42"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0},Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [Str "65",Str ",",Space,Str "multipostnote"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [RawInline (Format "latex") "\\footcites(Multiprenote)(multipostnote)[23][42]{Knu86}[65]{Nie72}"],Str "."]]]]
48+```
test/command/adjacent_latex_blocks.md+2−2
@@ -4,6 +4,6 @@
44
55\listoftables
66^D
7−[RawBlock (Format "latex") "\\listoffigures"
8−,RawBlock (Format "latex") "\\listoftables"]
7+[RawBlock (Format "tex") "\\listoffigures"
8+,RawBlock (Format "tex") "\\listoftables"]
99```
test/command/ascii.mdnew file+45
@@ -0,0 +1,45 @@
1+```
2+pandoc -t html --ascii
3+äéıå
4+^D
5+<p>&#228;&#233;&#305;&#229;</p>
6+```
7+
8+```
9+pandoc -t latex --ascii
10+äéıå
11+^D
12+\"{a}\'{e}\i \r{a}
13+```
14+
15+```
16+pandoc -t man --ascii
17+äéıå
18+^D
19+.PP
20+\[u00E4]\[u00E9]\[u0131]\[u00E5]
21+```
22+
23+```
24+pandoc -t ms --ascii
25+äéıå
26+^D
27+.LP
28+\[u00E4]\[u00E9]\[u0131]\[u00E5]
29+```
30+
31+```
32+pandoc -t docbook --ascii
33+äéıå
34+^D
35+<para>
36+ &#228;&#233;&#305;&#229;
37+</para>
38+```
39+
40+```
41+pandoc -t jats --ascii
42+äéıå
43+^D
44+<p>&#228;&#233;&#305;&#229;</p>
45+```
test/command/bar.texnew file+1
@@ -0,0 +1 @@
1+\emph{hi there}
test/command/emoji.mdnew file+27
@@ -0,0 +1,27 @@
1+```
2+% pandoc -t markdown+emoji -f markdown+emoji
3+:smile:
4+^D
5+:smile:
6+```
7+
8+```
9+% pandoc -t markdown-emoji -f markdown+emoji
10+:smile:
11+^D
12+😄
13+```
14+
15+```
16+% pandoc -t gfm -f markdown+emoji
17+:smile:
18+^D
19+:smile:
20+```
21+
22+```
23+% pandoc -t gfm-emoji -f markdown+emoji
24+:smile:
25+^D
26+😄
27+```
test/command/empty-inline-code.txtnew file+6
@@ -0,0 +1,6 @@
1+```
2+% pandoc -t native
3+` `
4+^D
5+[Code ("",[],[]) ""]
6+```
test/command/gfm.md+1−1
@@ -38,7 +38,7 @@ gfm tests:
3838% pandoc -f gfm -t native
3939My:thumbsup:emoji:heart:
4040^D
41−[Para [Str "My\128077emoji\10084\65039"]]
41+[Para [Str "My",Span ("",["emoji"],[("data-emoji","thumbsup")]) [Str "\128077"],Str "emoji",Span ("",["emoji"],[("data-emoji","heart")]) [Str "\10084\65039"]]]
4242```
4343
4444```
test/command/hspace.md+3−3
@@ -8,7 +8,7 @@ Here they need to be inline:
88\caption{lalune \hspace{2em} \vspace{1em} bloo}
99\end{figure}
1010^D
11−[RawBlock (Format "latex") "\\begin{figure}\n\\includegraphics{lalune.jpg}\n\\caption{lalune \\hspace{2em} \\vspace{1em} bloo}\n\\end{figure}"]
11+[RawBlock (Format "tex") "\\begin{figure}\n\\includegraphics{lalune.jpg}\n\\caption{lalune \\hspace{2em} \\vspace{1em} bloo}\n\\end{figure}"]
1212```
1313
1414Here block:
@@ -32,7 +32,7 @@ F & T &\\
3232F & F &\\
3333\end{tabular}
3434^D
35−[RawBlock (Format "latex") "\\begin{tabular}[t]{cc|c}\n\\(P\\) & \\(Q\\) & \\(P\\wedge Q\\)\\\\\n\\hline\nT & T &\\\\\nT & F &\\\\\nF & T &\\\\\nF & F &\\\\\n\\end{tabular}\n\\hspace{1em}\n\\begin{tabular}[t]{cc|c}\n\\(P\\) & \\(Q\\) & \\(P\\vee Q\\)\\\\\n\\hline\nT & T &\\\\\nT & F &\\\\\nF & T &\\\\\nF & F &\\\\\n\\end{tabular}"]
35+[RawBlock (Format "tex") "\\begin{tabular}[t]{cc|c}\n\\(P\\) & \\(Q\\) & \\(P\\wedge Q\\)\\\\\n\\hline\nT & T &\\\\\nT & F &\\\\\nF & T &\\\\\nF & F &\\\\\n\\end{tabular}\n\\hspace{1em}\n\\begin{tabular}[t]{cc|c}\n\\(P\\) & \\(Q\\) & \\(P\\vee Q\\)\\\\\n\\hline\nT & T &\\\\\nT & F &\\\\\nF & T &\\\\\nF & F &\\\\\n\\end{tabular}"]
3636```
3737
3838```
@@ -51,6 +51,6 @@ hi
5151there
5252^D
5353[Para [Str "hi"]
54−,RawBlock (Format "latex") "\\hspace{1em}"
54+,RawBlock (Format "tex") "\\hspace{1em}"
5555,Para [Str "there"]]
5656```
test/command/macros.md+4−4
@@ -24,18 +24,18 @@ expanded at point of use:
2424% pandoc -f latex -t latex
2525\let\a\b
2626\newcommand{\b}{\emph{ouk}}
27−\a
27+\a a
2828^D
29−\b
29+a̱
3030```
3131
3232```
3333% pandoc -f latex -t latex
3434\newcommand{\a}{\b}
3535\newcommand{\b}{\emph{ouk}}
36−\a
36+\a a
3737^D
38−\emph{ouk}
38+\emph{ouk}a
3939```
4040
4141```
test/command/refs.md+45−2
@@ -42,10 +42,53 @@ Accuracy~\eqref{eq:Accuracy} is the proportion, measuring true results among all
4242
4343Figure \ref{fig:Logo} illustrated the SVG logo
4444^D
45−[Para [Image ("",[],[]) [Str "Logo",Span ("",[],[("label","fig:Logo")]) []] ("command/SVG_logo.svg","fig:")]
46−,Para [Str "Figure",Space,Link ("",[],[("reference-type","ref"),("reference","fig:Logo")]) [Str "[fig:Logo]"] ("#fig:Logo",""),Space,Str "illustrated",Space,Str "the",Space,Str "SVG",Space,Str "logo"]]
45+[Para [Image ("fig:Logo",[],[]) [Str "Logo",Span ("",[],[("label","fig:Logo")]) []] ("command/SVG_logo.svg","fig:")]
46+,Para [Str "Figure",Space,Link ("",[],[("reference-type","ref"),("reference","fig:Logo")]) [Str "1"] ("#fig:Logo",""),Space,Str "illustrated",Space,Str "the",Space,Str "SVG",Space,Str "logo"]]
4747```
4848
49+```
50+% pandoc -f latex -t native
51+\chapter{One}
52+\begin{figure}
53+ \includegraphics{command/SVG_logo.svg}
54+ \caption{Logo}
55+ \label{fig:Logo}
56+\end{figure}
57+
58+\begin{figure}
59+ \includegraphics{command/SVG_logo2.svg}
60+ \caption{Logo2}
61+ \label{fig:Logo2}
62+\end{figure}
63+
64+\chapter{Two}
65+
66+\section{Subone}
67+
68+\begin{figure}
69+ \includegraphics{command/SVG_logo3.svg}
70+ \caption{Logo3}
71+ \label{fig:Logo3}
72+\end{figure}
73+
74+Figure \ref{fig:Logo} illustrated the SVG logo
75+
76+Figure \ref{fig:Logo2} illustrated the SVG logo
77+
78+Figure \ref{fig:Logo3} illustrated the SVG logo
79+^D
80+[Header 1 ("one",[],[]) [Str "One"]
81+,Para [Image ("fig:Logo",[],[]) [Str "Logo",Span ("",[],[("label","fig:Logo")]) []] ("command/SVG_logo.svg","fig:")]
82+,Para [Image ("fig:Logo2",[],[]) [Str "Logo2",Span ("",[],[("label","fig:Logo2")]) []] ("command/SVG_logo2.svg","fig:")]
83+,Header 1 ("two",[],[]) [Str "Two"]
84+,Header 2 ("subone",[],[]) [Str "Subone"]
85+,Para [Image ("fig:Logo3",[],[]) [Str "Logo3",Span ("",[],[("label","fig:Logo3")]) []] ("command/SVG_logo3.svg","fig:")]
86+,Para [Str "Figure",Space,Link ("",[],[("reference-type","ref"),("reference","fig:Logo")]) [Str "1.1"] ("#fig:Logo",""),Space,Str "illustrated",Space,Str "the",Space,Str "SVG",Space,Str "logo"]
87+,Para [Str "Figure",Space,Link ("",[],[("reference-type","ref"),("reference","fig:Logo2")]) [Str "1.2"] ("#fig:Logo2",""),Space,Str "illustrated",Space,Str "the",Space,Str "SVG",Space,Str "logo"]
88+,Para [Str "Figure",Space,Link ("",[],[("reference-type","ref"),("reference","fig:Logo3")]) [Str "2.1"] ("#fig:Logo3",""),Space,Str "illustrated",Space,Str "the",Space,Str "SVG",Space,Str "logo"]]
89+```
90+
91+
4992```
5093% pandoc -f latex -t native
5194\label{section} Section \ref{section}
test/command/write18.md+1−1
@@ -3,7 +3,7 @@ Handle \write18{..} as raw tex:
33% pandoc -t native
44\write18{git --version}
55^D
6−[RawBlock (Format "latex") "\\write18{git --version}"]
6+[RawBlock (Format "tex") "\\write18{git --version}"]
77```
88
99```
test/command/yaml-metadata-blocks.mdnew file+63
@@ -0,0 +1,63 @@
1+```
2+% pandoc -s -t native
3+---
4+foobar_: this should be ignored
5+foo:
6+ bar_: as should this
7+---
8+^D
9+Pandoc (Meta {unMeta = fromList [("foo",MetaMap (fromList []))]})
10+[]
11+```
12+```
13+% pandoc -s -t native
14+---
15+# For precedence, see multiple-metadata-blocks.md and vars-and-metadata.md
16+# For Bools, see also 4819.md
17+# For Multiline strings, see yaml-with-chomp.md
18+int: 7
19+float: 1.5
20+scientific: 3.7e-5
21+bool: true
22+more: False
23+nothing: null
24+emtpy: []
25+nested:
26+ int: 8
27+ float: 2.5
28+ bool: true
29+ more: False
30+ nothing: null
31+ emtpy: []
32+ scientific: 3.7e-5
33+---
34+^D
35+Pandoc (Meta {unMeta = fromList [("bool",MetaBool True),("emtpy",MetaList []),("float",MetaInlines [Str "1.5"]),("int",MetaInlines [Str "7"]),("more",MetaBool False),("nested",MetaMap (fromList [("bool",MetaBool True),("emtpy",MetaList []),("float",MetaInlines [Str "2.5"]),("int",MetaInlines [Str "8"]),("more",MetaBool False),("nothing",MetaInlines [Str "null"]),("scientific",MetaInlines [Str "3.7e-5"])])),("nothing",MetaInlines [Str "null"]),("scientific",MetaInlines [Str "3.7e-5"])]})
36+[]
37+```
38+```
39+% pandoc -s -t native
40+---
41+array:
42+ - foo: bar
43+ - bool: True
44+---
45+^D
46+Pandoc (Meta {unMeta = fromList [("array",MetaList [MetaMap (fromList [("foo",MetaInlines [Str "bar"])]),MetaMap (fromList [("bool",MetaBool True)])])]})
47+[]
48+```
49+```
50+% pandoc -s -t native --metadata-file command/yaml-metadata.yaml
51+---
52+title: document
53+---
54+^D
55+Pandoc (Meta {unMeta = fromList [("other",MetaInlines [Emph [Str "markdown"],Space,Str "value"]),("title",MetaInlines [Str "document"])]})
56+[]
57+```
58+```
59+% pandoc -s -t native --metadata-file command/yaml-metadata.yaml -M title=cmdline
60+^D
61+Pandoc (Meta {unMeta = fromList [("other",MetaInlines [Emph [Str "markdown"],Space,Str "value"]),("title",MetaString "cmdline")]})
62+[]
63+```
test/command/yaml-metadata.yamlnew file+4
@@ -0,0 +1,4 @@
1+---
2+title: file
3+other: _markdown_ value
4+---
test/docbook-xref.native+1−1
@@ -1,4 +1,4 @@
1−Pandoc (Meta {unMeta = fromList []})
1+Pandoc (Meta {unMeta = fromList [("title",MetaInlines [Str "An",Space,Str "Example",Space,Str "Book"])]})
22[Header 1 ("ch01",[],[]) [Str "XRef",Space,Str "Samples"]
33,Para [Str "This",Space,Str "paragraph",Space,Str "demonstrates",Space,Str "several",Space,Str "features",Space,Str "of",SoftBreak,Str "XRef."]
44,BulletList
test/fb2/meta.fb2+1−1
@@ -1,3 +1,3 @@
11<?xml version="1.0" encoding="UTF-8"?>
2−<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre><book-title>Book title</book-title><annotation><p>This is the abstract.</p>It consists of two paragraphs.</annotation></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p>Book title</p></title></body></FictionBook>
2+<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre><book-title>Book title</book-title><annotation><p>This is the abstract.</p><p>It consists of two paragraphs.</p></annotation></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p>Book title</p></title></body></FictionBook>
33
test/lhs-test.html+4−6
@@ -14,7 +14,7 @@
1414 <style type="text/css">
1515a.sourceLine { display: inline-block; line-height: 1.25; }
1616a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
17−a.sourceLine:empty { height: 1.2em; position: absolute; }
17+a.sourceLine:empty { height: 1.2em; }
1818.sourceCode { overflow: visible; }
1919code.sourceCode { white-space: pre; position: relative; }
2020div.sourceCode { margin: 1em 0; }
@@ -27,13 +27,11 @@ code.sourceCode { white-space: pre-wrap; }
2727a.sourceLine { text-indent: -1em; padding-left: 1em; }
2828}
2929pre.numberSource a.sourceLine
30− { position: relative; }
31−pre.numberSource a.sourceLine:empty
32− { position: absolute; }
30+ { position: relative; left: -4em; }
3331pre.numberSource a.sourceLine::before
3432 { content: attr(data-line-number);
35− position: absolute; left: -5em; text-align: right; vertical-align: baseline;
36− border: none; pointer-events: all;
33+ position: relative; left: -1em; text-align: right; vertical-align: baseline;
34+ border: none; pointer-events: all; display: inline-block;
3735 -webkit-touch-callout: none; -webkit-user-select: none;
3836 -khtml-user-select: none; -moz-user-select: none;
3937 -ms-user-select: none; user-select: none;
test/lhs-test.html+lhs+4−6
@@ -14,7 +14,7 @@
1414 <style type="text/css">
1515a.sourceLine { display: inline-block; line-height: 1.25; }
1616a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
17−a.sourceLine:empty { height: 1.2em; position: absolute; }
17+a.sourceLine:empty { height: 1.2em; }
1818.sourceCode { overflow: visible; }
1919code.sourceCode { white-space: pre; position: relative; }
2020div.sourceCode { margin: 1em 0; }
@@ -27,13 +27,11 @@ code.sourceCode { white-space: pre-wrap; }
2727a.sourceLine { text-indent: -1em; padding-left: 1em; }
2828}
2929pre.numberSource a.sourceLine
30− { position: relative; }
31−pre.numberSource a.sourceLine:empty
32− { position: absolute; }
30+ { position: relative; left: -4em; }
3331pre.numberSource a.sourceLine::before
3432 { content: attr(data-line-number);
35− position: absolute; left: -5em; text-align: right; vertical-align: baseline;
36− border: none; pointer-events: all;
33+ position: relative; left: -1em; text-align: right; vertical-align: baseline;
34+ border: none; pointer-events: all; display: inline-block;
3735 -webkit-touch-callout: none; -webkit-user-select: none;
3836 -khtml-user-select: none; -moz-user-select: none;
3937 -ms-user-select: none; user-select: none;
test/lua/test-pandoc-utils.lua+15
@@ -1,5 +1,19 @@
11utils = require 'pandoc.utils'
22
3+-- Squash blocks to inlines
4+------------------------------------------------------------------------
5+function test_blocks_to_inlines ()
6+ local blocks = {
7+ pandoc.Para{ pandoc.Str 'Paragraph1' },
8+ pandoc.Para{ pandoc.Emph 'Paragraph2' }
9+ }
10+ local inlines = utils.blocks_to_inlines(blocks, {pandoc.LineBreak()})
11+ return #inlines == 3
12+ and inlines[1].text == "Paragraph1"
13+ and inlines[2].t == 'LineBreak'
14+ and inlines[3].content[1].text == "Paragraph2"
15+end
16+
317-- hierarchicalize
418------------------------------------------------------------------------
519function test_hierarchicalize ()
@@ -110,6 +124,7 @@ end
110124
111125function Para (el)
112126 return {
127+ pandoc.Plain{pandoc.Str("blocks_to_inlines: " .. run(test_blocks_to_inlines))},
113128 pandoc.Plain{pandoc.Str("hierarchicalize: " .. run(test_hierarchicalize))},
114129 pandoc.Plain{pandoc.Str("normalize_date: " .. run(test_normalize_date))},
115130 pandoc.Plain{pandoc.Str("pipe: " .. run(test_pipe))},
test/markdown-reader-more.native+9−8
@@ -3,10 +3,11 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Author",S
33,Header 2 ("blank-line-before-url-in-link-reference",[],[]) [Str "Blank",Space,Str "line",Space,Str "before",Space,Str "URL",Space,Str "in",Space,Str "link",Space,Str "reference"]
44,Para [Link ("",[],[]) [Str "foo"] ("/url",""),Space,Str "and",Space,Link ("",[],[]) [Str "bar"] ("/url","title")]
55,Header 2 ("raw-context-environments",[],[]) [Str "Raw",Space,Str "ConTeXt",Space,Str "environments"]
6−,RawBlock (Format "context") "\\placeformula \\startformula\n L_{1} = L_{2}\n \\stopformula"
7−,RawBlock (Format "context") "\\start[a2]\n\\start[a2]\n\\stop[a2]\n\\stop[a2]"
6+,RawBlock (Format "tex") "\\placeformula \\startformula"
7+,Para [Str "L_{1}",Space,Str "=",Space,Str "L_{2}",SoftBreak,RawInline (Format "tex") "\\stopformula"]
8+,RawBlock (Format "tex") "\\start[a2]\n\\start[a2]\n\\stop[a2]\n\\stop[a2]"
89,Header 2 ("raw-latex-environments",[],[]) [Str "Raw",Space,Str "LaTeX",Space,Str "environments"]
9−,RawBlock (Format "latex") "\\begin{center}\n\\begin{tikzpicture}[baseline={([yshift=+-.5ex]current bounding box.center)}, level distance=24pt]\n\\Tree [.{S} [.NP John\\index{i} ] [.VP [.V likes ] [.NP himself\\index{i,*j} ]]]\n\\end{tikzpicture}\n\\end{center}"
10+,RawBlock (Format "tex") "\\begin{center}\n\\begin{tikzpicture}[baseline={([yshift=+-.5ex]current bounding box.center)}, level distance=24pt]\n\\Tree [.{S} [.NP John\\index{i} ] [.VP [.V likes ] [.NP himself\\index{i,*j} ]]]\n\\end{tikzpicture}\n\\end{center}"
1011,Header 2 ("urls-with-spaces-and-punctuation",[],[]) [Str "URLs",Space,Str "with",Space,Str "spaces",Space,Str "and",Space,Str "punctuation"]
1112,Para [Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("/bar%20and%20baz",""),SoftBreak,Link ("",[],[]) [Str "foo"] ("bar%20baz","title")]
1213,Para [Link ("",[],[]) [Str "baz"] ("/foo%20foo",""),Space,Link ("",[],[]) [Str "bam"] ("/foo%20fee",""),Space,Link ("",[],[]) [Str "bork"] ("/foo/zee%20zob","title")]
@@ -44,9 +45,9 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Author",S
4445,Para [Str "`hi"]
4546,Para [Str "there`"]
4647,Header 2 ("multilingual-urls",[],[]) [Str "Multilingual",Space,Str "URLs"]
47−,Para [Link ("",[],[]) [Str "http://\27979.com?\27979=\27979"] ("http://\27979.com?\27979=\27979","")]
48+,Para [Link ("",["uri"],[]) [Str "http://\27979.com?\27979=\27979"] ("http://\27979.com?\27979=\27979","")]
4849,Para [Link ("",[],[]) [Str "foo"] ("/bar/\27979?x=\27979","title")]
49−,Para [Link ("",[],[]) [Str "\27979@foo.\27979.baz"] ("mailto:\27979@foo.\27979.baz","")]
50+,Para [Link ("",["email"],[]) [Str "\27979@foo.\27979.baz"] ("mailto:\27979@foo.\27979.baz","")]
5051,Header 2 ("numbered-examples",[],[]) [Str "Numbered",Space,Str "examples"]
5152,OrderedList (1,Example,TwoParens)
5253 [[Plain [Str "First",Space,Str "example."]]
@@ -55,7 +56,7 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Author",S
5556,OrderedList (3,Example,TwoParens)
5657 [[Plain [Str "Third",Space,Str "example."]]]
5758,Header 2 ("macros",[],[]) [Str "Macros"]
58−,RawBlock (Format "latex") "\\newcommand{\\tuple}[1]{\\langle #1 \\rangle}"
59+,RawBlock (Format "tex") "\\newcommand{\\tuple}[1]{\\langle #1 \\rangle}"
5960,Para [Math InlineMath "\\langle x,y \\rangle"]
6061,Header 2 ("case-insensitive-references",[],[]) [Str "Case-insensitive",Space,Str "references"]
6162,Para [Link ("",[],[]) [Str "Fum"] ("/fum","")]
@@ -175,8 +176,8 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "Author",S
175176 ,[]]]
176177,Header 2 ("entities-in-links-and-titles",[],[]) [Str "Entities",Space,Str "in",Space,Str "links",Space,Str "and",Space,Str "titles"]
177178,Para [Link ("",[],[]) [Str "link"] ("/\252rl","\246\246!")]
178−,Para [Link ("",[],[]) [Str "http://g\246\246gle.com"] ("http://g\246\246gle.com","")]
179−,Para [Link ("",[],[]) [Str "me@ex\228mple.com"] ("mailto:me@ex\228mple.com","")]
179+,Para [Link ("",["uri"],[]) [Str "http://g\246\246gle.com"] ("http://g\246\246gle.com","")]
180+,Para [Link ("",["email"],[]) [Str "me@ex\228mple.com"] ("mailto:me@ex\228mple.com","")]
180181,Para [Link ("",[],[]) [Str "foobar"] ("/\252rl","\246\246!")]
181182,Header 2 ("parentheses-in-urls",[],[]) [Str "Parentheses",Space,Str "in",Space,Str "URLs"]
182183,Para [Link ("",[],[]) [Str "link"] ("/hi(there)","")]
test/pptx/lists.native+1−1
@@ -1,7 +1,7 @@
11[Header 1 ("lists",[],[]) [Str "Lists"]
22,BulletList
33 [[Para [Str "Bulleted",Space,Str "bulleted",Space,Str "lists."]]
4− ,[Para [Str "And",Space,Str "go",Space,Str "to",Space,Str "aribtrary",Space,Str "depth."]
4+ ,[Para [Str "And",Space,Str "go",Space,Str "to",Space,Str "arbitrary",Space,Str "depth."]
55 ,BulletList
66 [[Para [Str "Like",Space,Str "this"]
77 ,BulletList
test/pptx/lists.pptx

Binary file not shown.

test/pptx/lists_templated.pptx

Binary file not shown.

test/rst-reader.native+1−1
@@ -326,7 +326,7 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Spa
326326,Para [Math DisplayMath "\\alpha = beta",Math DisplayMath "E = mc^2"]
327327,Para [Str "Some",Space,Superscript [Str "of"],Space,Str "these",Space,Superscript [Str "words"],Space,Str "are",Space,Str "in",Space,Superscript [Str "superscript"],Str "."]
328328,Para [Str "Reset",Space,Str "default-role",Space,Str "to",Space,Str "the",Space,Str "default",Space,Str "default."]
329−,Para [Str "And",Space,Str "now",Space,Str "some-invalid-string-3231231",Space,Str "is",Space,Str "nonsense."]
329+,Para [Str "And",Space,Str "now",Space,Span ("",["title-ref"],[]) [Str "some-invalid-string-3231231"],Space,Str "is",Space,Str "nonsense."]
330330,Para [Str "And",Space,Str "now",Space,Str "with",Space,RawInline (Format "html") "<b>inline</b> <span id=\"test\">HTML</span>",Str "."]
331331,Para [Str "And",Space,Str "some",Space,Str "inline",Space,Str "haskell",Space,Code ("",["haskell","sourceCode"],[]) "fmap id [1,2..10]",Str "."]
332332,Para [Str "Indirect",Space,Str "python",Space,Str "role",Space,Code ("",["py","python","indirect","sourceCode"],[]) "[x*x for x in [1,2,3,4,5]]",Str "."]
test/tables-rstsubset.native+4−4
@@ -1,5 +1,5 @@
11[Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]
2−,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
2+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
33 [[Plain [Str "Right"]]
44 ,[Plain [Str "Left"]]
55 ,[Plain [Str "Center"]]
@@ -17,7 +17,7 @@
1717 ,[Plain [Str "1"]]
1818 ,[Plain [Str "1"]]]]
1919,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]
20−,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
20+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
2121 [[Plain [Str "Right"]]
2222 ,[Plain [Str "Left"]]
2323 ,[Plain [Str "Center"]]
@@ -35,7 +35,7 @@
3535 ,[Plain [Str "1"]]
3636 ,[Plain [Str "1"]]]]
3737,Para [Str "Simple",Space,Str "table",Space,Str "indented",Space,Str "two",Space,Str "spaces:"]
38−,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
38+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
3939 [[Plain [Str "Right"]]
4040 ,[Plain [Str "Left"]]
4141 ,[Plain [Str "Center"]]
@@ -81,7 +81,7 @@
8181 ,[Plain [Str "5.0"]]
8282 ,[Plain [Str "Here\8217s",Space,Str "another",Space,Str "one.",Space,Str "Note",SoftBreak,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",SoftBreak,Str "rows."]]]]
8383,Para [Str "Table",Space,Str "without",Space,Str "column",Space,Str "headers:"]
84−,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [7.5e-2,7.5e-2,7.5e-2,7.5e-2]
84+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
8585 [[]
8686 ,[]
8787 ,[]
test/tables.opendocument+98−96
@@ -6,64 +6,65 @@
66 <table:table-column table:style-name="Table1.D" />
77 <table:table-header-rows>
88 <table:table-row>
9− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
9+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
1010 <text:p text:style-name="P1">Right</text:p>
1111 </table:table-cell>
12− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
12+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
1313 <text:p text:style-name="Table_20_Heading">Left</text:p>
1414 </table:table-cell>
15− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
15+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
1616 <text:p text:style-name="P2">Center</text:p>
1717 </table:table-cell>
18− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
18+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
1919 <text:p text:style-name="Table_20_Heading">Default</text:p>
2020 </table:table-cell>
2121 </table:table-row>
2222 </table:table-header-rows>
2323 <table:table-row>
24− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
24+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
2525 <text:p text:style-name="P3">12</text:p>
2626 </table:table-cell>
27− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
27+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
2828 <text:p text:style-name="Table_20_Contents">12</text:p>
2929 </table:table-cell>
30− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
30+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
3131 <text:p text:style-name="P4">12</text:p>
3232 </table:table-cell>
33− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
33+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
3434 <text:p text:style-name="Table_20_Contents">12</text:p>
3535 </table:table-cell>
3636 </table:table-row>
3737 <table:table-row>
38− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
38+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
3939 <text:p text:style-name="P3">123</text:p>
4040 </table:table-cell>
41− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
41+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
4242 <text:p text:style-name="Table_20_Contents">123</text:p>
4343 </table:table-cell>
44− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
44+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
4545 <text:p text:style-name="P4">123</text:p>
4646 </table:table-cell>
47− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
47+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
4848 <text:p text:style-name="Table_20_Contents">123</text:p>
4949 </table:table-cell>
5050 </table:table-row>
5151 <table:table-row>
52− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
52+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
5353 <text:p text:style-name="P3">1</text:p>
5454 </table:table-cell>
55− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
55+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
5656 <text:p text:style-name="Table_20_Contents">1</text:p>
5757 </table:table-cell>
58− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
58+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
5959 <text:p text:style-name="P4">1</text:p>
6060 </table:table-cell>
61− <table:table-cell table:style-name="Table1.A1" office:value-type="string">
61+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
6262 <text:p text:style-name="Table_20_Contents">1</text:p>
6363 </table:table-cell>
6464 </table:table-row>
6565</table:table>
66−<text:p text:style-name="Table">Demonstration of simple table syntax.</text:p>
66+<text:p text:style-name="Table">Table <text:sequence text:ref-name="refTable0" text:name="Table" text:formula="ooow:Table+1" style:num-format="1">1</text:sequence>: Demonstration
67+of simple table syntax.</text:p>
6768<text:p text:style-name="First_20_paragraph">Simple table without
6869caption:</text:p>
6970<table:table table:name="Table2" table:style-name="Table2">
@@ -73,59 +74,59 @@ caption:</text:p>
7374 <table:table-column table:style-name="Table2.D" />
7475 <table:table-header-rows>
7576 <table:table-row>
76− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
77+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
7778 <text:p text:style-name="P5">Right</text:p>
7879 </table:table-cell>
79− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
80+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
8081 <text:p text:style-name="Table_20_Heading">Left</text:p>
8182 </table:table-cell>
82− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
83+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
8384 <text:p text:style-name="P6">Center</text:p>
8485 </table:table-cell>
85− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
86+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
8687 <text:p text:style-name="Table_20_Heading">Default</text:p>
8788 </table:table-cell>
8889 </table:table-row>
8990 </table:table-header-rows>
9091 <table:table-row>
91− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
92+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
9293 <text:p text:style-name="P7">12</text:p>
9394 </table:table-cell>
94− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
95+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
9596 <text:p text:style-name="Table_20_Contents">12</text:p>
9697 </table:table-cell>
97− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
98+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
9899 <text:p text:style-name="P8">12</text:p>
99100 </table:table-cell>
100− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
101+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
101102 <text:p text:style-name="Table_20_Contents">12</text:p>
102103 </table:table-cell>
103104 </table:table-row>
104105 <table:table-row>
105− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
106+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
106107 <text:p text:style-name="P7">123</text:p>
107108 </table:table-cell>
108− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
109+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
109110 <text:p text:style-name="Table_20_Contents">123</text:p>
110111 </table:table-cell>
111− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
112+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
112113 <text:p text:style-name="P8">123</text:p>
113114 </table:table-cell>
114− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
115+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
115116 <text:p text:style-name="Table_20_Contents">123</text:p>
116117 </table:table-cell>
117118 </table:table-row>
118119 <table:table-row>
119− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
120+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
120121 <text:p text:style-name="P7">1</text:p>
121122 </table:table-cell>
122− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
123+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
123124 <text:p text:style-name="Table_20_Contents">1</text:p>
124125 </table:table-cell>
125− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
126+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
126127 <text:p text:style-name="P8">1</text:p>
127128 </table:table-cell>
128− <table:table-cell table:style-name="Table2.A1" office:value-type="string">
129+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
129130 <text:p text:style-name="Table_20_Contents">1</text:p>
130131 </table:table-cell>
131132 </table:table-row>
@@ -139,64 +140,65 @@ spaces:</text:p>
139140 <table:table-column table:style-name="Table3.D" />
140141 <table:table-header-rows>
141142 <table:table-row>
142− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
143+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
143144 <text:p text:style-name="P9">Right</text:p>
144145 </table:table-cell>
145− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
146+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
146147 <text:p text:style-name="Table_20_Heading">Left</text:p>
147148 </table:table-cell>
148− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
149+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
149150 <text:p text:style-name="P10">Center</text:p>
150151 </table:table-cell>
151− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
152+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
152153 <text:p text:style-name="Table_20_Heading">Default</text:p>
153154 </table:table-cell>
154155 </table:table-row>
155156 </table:table-header-rows>
156157 <table:table-row>
157− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
158+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
158159 <text:p text:style-name="P11">12</text:p>
159160 </table:table-cell>
160− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
161+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
161162 <text:p text:style-name="Table_20_Contents">12</text:p>
162163 </table:table-cell>
163− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
164+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
164165 <text:p text:style-name="P12">12</text:p>
165166 </table:table-cell>
166− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
167+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
167168 <text:p text:style-name="Table_20_Contents">12</text:p>
168169 </table:table-cell>
169170 </table:table-row>
170171 <table:table-row>
171− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
172+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
172173 <text:p text:style-name="P11">123</text:p>
173174 </table:table-cell>
174− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
175+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
175176 <text:p text:style-name="Table_20_Contents">123</text:p>
176177 </table:table-cell>
177− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
178+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
178179 <text:p text:style-name="P12">123</text:p>
179180 </table:table-cell>
180− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
181+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
181182 <text:p text:style-name="Table_20_Contents">123</text:p>
182183 </table:table-cell>
183184 </table:table-row>
184185 <table:table-row>
185− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
186+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
186187 <text:p text:style-name="P11">1</text:p>
187188 </table:table-cell>
188− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
189+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
189190 <text:p text:style-name="Table_20_Contents">1</text:p>
190191 </table:table-cell>
191− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
192+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
192193 <text:p text:style-name="P12">1</text:p>
193194 </table:table-cell>
194− <table:table-cell table:style-name="Table3.A1" office:value-type="string">
195+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
195196 <text:p text:style-name="Table_20_Contents">1</text:p>
196197 </table:table-cell>
197198 </table:table-row>
198199</table:table>
199−<text:p text:style-name="Table">Demonstration of simple table syntax.</text:p>
200+<text:p text:style-name="Table">Table <text:sequence text:ref-name="refTable1" text:name="Table" text:formula="ooow:Table+1" style:num-format="1">2</text:sequence>: Demonstration
201+of simple table syntax.</text:p>
200202<text:p text:style-name="First_20_paragraph">Multiline table with
201203caption:</text:p>
202204<table:table table:name="Table4" table:style-name="Table4">
@@ -206,53 +208,53 @@ caption:</text:p>
206208 <table:table-column table:style-name="Table4.D" />
207209 <table:table-header-rows>
208210 <table:table-row>
209− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
211+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
210212 <text:p text:style-name="P13">Centered Header</text:p>
211213 </table:table-cell>
212− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
214+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
213215 <text:p text:style-name="Table_20_Heading">Left Aligned</text:p>
214216 </table:table-cell>
215− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
217+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
216218 <text:p text:style-name="P14">Right Aligned</text:p>
217219 </table:table-cell>
218− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
220+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
219221 <text:p text:style-name="Table_20_Heading">Default aligned</text:p>
220222 </table:table-cell>
221223 </table:table-row>
222224 </table:table-header-rows>
223225 <table:table-row>
224− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
226+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
225227 <text:p text:style-name="P15">First</text:p>
226228 </table:table-cell>
227− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
229+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
228230 <text:p text:style-name="Table_20_Contents">row</text:p>
229231 </table:table-cell>
230− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
232+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
231233 <text:p text:style-name="P16">12.0</text:p>
232234 </table:table-cell>
233− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
235+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
234236 <text:p text:style-name="Table_20_Contents">Example of a row that spans
235237 multiple lines.</text:p>
236238 </table:table-cell>
237239 </table:table-row>
238240 <table:table-row>
239− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
241+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
240242 <text:p text:style-name="P15">Second</text:p>
241243 </table:table-cell>
242− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
244+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
243245 <text:p text:style-name="Table_20_Contents">row</text:p>
244246 </table:table-cell>
245− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
247+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
246248 <text:p text:style-name="P16">5.0</text:p>
247249 </table:table-cell>
248− <table:table-cell table:style-name="Table4.A1" office:value-type="string">
250+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
249251 <text:p text:style-name="Table_20_Contents">Here’s another one. Note the
250252 blank line between rows.</text:p>
251253 </table:table-cell>
252254 </table:table-row>
253255</table:table>
254−<text:p text:style-name="Table">Here’s the caption. It may span multiple
255−lines.</text:p>
256+<text:p text:style-name="Table">Table <text:sequence text:ref-name="refTable2" text:name="Table" text:formula="ooow:Table+1" style:num-format="1">3</text:sequence>: Here’s
257+the caption. It may span multiple lines.</text:p>
256258<text:p text:style-name="First_20_paragraph">Multiline table without
257259caption:</text:p>
258260<table:table table:name="Table5" table:style-name="Table5">
@@ -262,46 +264,46 @@ caption:</text:p>
262264 <table:table-column table:style-name="Table5.D" />
263265 <table:table-header-rows>
264266 <table:table-row>
265− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
267+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
266268 <text:p text:style-name="P17">Centered Header</text:p>
267269 </table:table-cell>
268− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
270+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
269271 <text:p text:style-name="Table_20_Heading">Left Aligned</text:p>
270272 </table:table-cell>
271− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
273+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
272274 <text:p text:style-name="P18">Right Aligned</text:p>
273275 </table:table-cell>
274− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
276+ <table:table-cell table:style-name="TableHeaderRowCell" office:value-type="string">
275277 <text:p text:style-name="Table_20_Heading">Default aligned</text:p>
276278 </table:table-cell>
277279 </table:table-row>
278280 </table:table-header-rows>
279281 <table:table-row>
280− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
282+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
281283 <text:p text:style-name="P19">First</text:p>
282284 </table:table-cell>
283− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
285+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
284286 <text:p text:style-name="Table_20_Contents">row</text:p>
285287 </table:table-cell>
286− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
288+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
287289 <text:p text:style-name="P20">12.0</text:p>
288290 </table:table-cell>
289− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
291+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
290292 <text:p text:style-name="Table_20_Contents">Example of a row that spans
291293 multiple lines.</text:p>
292294 </table:table-cell>
293295 </table:table-row>
294296 <table:table-row>
295− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
297+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
296298 <text:p text:style-name="P19">Second</text:p>
297299 </table:table-cell>
298− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
300+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
299301 <text:p text:style-name="Table_20_Contents">row</text:p>
300302 </table:table-cell>
301− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
303+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
302304 <text:p text:style-name="P20">5.0</text:p>
303305 </table:table-cell>
304− <table:table-cell table:style-name="Table5.A1" office:value-type="string">
306+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
305307 <text:p text:style-name="Table_20_Contents">Here’s another one. Note the
306308 blank line between rows.</text:p>
307309 </table:table-cell>
@@ -315,44 +317,44 @@ headers:</text:p>
315317 <table:table-column table:style-name="Table6.C" />
316318 <table:table-column table:style-name="Table6.D" />
317319 <table:table-row>
318− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
320+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
319321 <text:p text:style-name="P24">12</text:p>
320322 </table:table-cell>
321− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
323+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
322324 <text:p text:style-name="Table_20_Contents">12</text:p>
323325 </table:table-cell>
324− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
326+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
325327 <text:p text:style-name="P25">12</text:p>
326328 </table:table-cell>
327− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
329+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
328330 <text:p text:style-name="P26">12</text:p>
329331 </table:table-cell>
330332 </table:table-row>
331333 <table:table-row>
332− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
334+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
333335 <text:p text:style-name="P24">123</text:p>
334336 </table:table-cell>
335− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
337+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
336338 <text:p text:style-name="Table_20_Contents">123</text:p>
337339 </table:table-cell>
338− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
340+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
339341 <text:p text:style-name="P25">123</text:p>
340342 </table:table-cell>
341− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
343+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
342344 <text:p text:style-name="P26">123</text:p>
343345 </table:table-cell>
344346 </table:table-row>
345347 <table:table-row>
346− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
348+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
347349 <text:p text:style-name="P24">1</text:p>
348350 </table:table-cell>
349− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
351+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
350352 <text:p text:style-name="Table_20_Contents">1</text:p>
351353 </table:table-cell>
352− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
354+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
353355 <text:p text:style-name="P25">1</text:p>
354356 </table:table-cell>
355− <table:table-cell table:style-name="Table6.A1" office:value-type="string">
357+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
356358 <text:p text:style-name="P26">1</text:p>
357359 </table:table-cell>
358360 </table:table-row>
@@ -365,31 +367,31 @@ headers:</text:p>
365367 <table:table-column table:style-name="Table7.C" />
366368 <table:table-column table:style-name="Table7.D" />
367369 <table:table-row>
368− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
370+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
369371 <text:p text:style-name="P29">First</text:p>
370372 </table:table-cell>
371− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
373+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
372374 <text:p text:style-name="Table_20_Contents">row</text:p>
373375 </table:table-cell>
374− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
376+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
375377 <text:p text:style-name="P30">12.0</text:p>
376378 </table:table-cell>
377− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
379+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
378380 <text:p text:style-name="Table_20_Contents">Example of a row that spans
379381 multiple lines.</text:p>
380382 </table:table-cell>
381383 </table:table-row>
382384 <table:table-row>
383− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
385+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
384386 <text:p text:style-name="P29">Second</text:p>
385387 </table:table-cell>
386− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
388+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
387389 <text:p text:style-name="Table_20_Contents">row</text:p>
388390 </table:table-cell>
389− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
391+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
390392 <text:p text:style-name="P30">5.0</text:p>
391393 </table:table-cell>
392− <table:table-cell table:style-name="Table7.A1" office:value-type="string">
394+ <table:table-cell table:style-name="TableRowCell" office:value-type="string">
393395 <text:p text:style-name="Table_20_Contents">Here’s another one. Note the
394396 blank line between rows.</text:p>
395397 </table:table-cell>
test/tables.rst+26−34
@@ -2,41 +2,35 @@ Simple table with caption:
22
33.. table:: Demonstration of simple table syntax.
44
5− +-------+------+--------+---------+
6− | Right | Left | Center | Default |
7− +=======+======+========+=========+
8− | 12 | 12 | 12 | 12 |
9− +-------+------+--------+---------+
10− | 123 | 123 | 123 | 123 |
11− +-------+------+--------+---------+
12− | 1 | 1 | 1 | 1 |
13− +-------+------+--------+---------+
5+ ===== ==== ====== =======
6+ Right Left Center Default
7+ ===== ==== ====== =======
8+ 12 12 12 12
9+ 123 123 123 123
10+ 1 1 1 1
11+ ===== ==== ====== =======
1412
1513Simple table without caption:
1614
17−+-------+------+--------+---------+
18−| Right | Left | Center | Default |
19−+=======+======+========+=========+
20−| 12 | 12 | 12 | 12 |
21−+-------+------+--------+---------+
22−| 123 | 123 | 123 | 123 |
23−+-------+------+--------+---------+
24−| 1 | 1 | 1 | 1 |
25−+-------+------+--------+---------+
15+===== ==== ====== =======
16+Right Left Center Default
17+===== ==== ====== =======
18+12 12 12 12
19+123 123 123 123
20+1 1 1 1
21+===== ==== ====== =======
2622
2723Simple table indented two spaces:
2824
2925.. table:: Demonstration of simple table syntax.
3026
31− +-------+------+--------+---------+
32− | Right | Left | Center | Default |
33− +=======+======+========+=========+
34− | 12 | 12 | 12 | 12 |
35− +-------+------+--------+---------+
36− | 123 | 123 | 123 | 123 |
37− +-------+------+--------+---------+
38− | 1 | 1 | 1 | 1 |
39− +-------+------+--------+---------+
27+ ===== ==== ====== =======
28+ Right Left Center Default
29+ ===== ==== ====== =======
30+ 12 12 12 12
31+ 123 123 123 123
32+ 1 1 1 1
33+ ===== ==== ====== =======
4034
4135Multiline table with caption:
4236
@@ -70,13 +64,11 @@ Multiline table without caption:
7064
7165Table without column headers:
7266
73−+-----+-----+-----+-----+
74−| 12 | 12 | 12 | 12 |
75−+-----+-----+-----+-----+
76−| 123 | 123 | 123 | 123 |
77−+-----+-----+-----+-----+
78−| 1 | 1 | 1 | 1 |
79−+-----+-----+-----+-----+
67+=== === === ===
68+12 12 12 12
69+123 123 123 123
70+1 1 1 1
71+=== === === ===
8072
8173Multiline table without column headers:
8274
test/testsuite.native+5−5
@@ -324,7 +324,7 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Spa
324324 ,[Plain [Str "Shoes",Space,Str "($20)",Space,Str "and",Space,Str "socks",Space,Str "($5)."]]
325325 ,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."]]]
326326,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
327−,RawBlock (Format "latex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
327+,RawBlock (Format "tex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
328328,HorizontalRule
329329,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"]
330330,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]
@@ -384,14 +384,14 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Spa
384384,Para [Str "Here\8217s",Space,Str "an",Space,Link ("",[],[]) [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
385385,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 "."]
386386,Header 2 ("autolinks",[],[]) [Str "Autolinks"]
387−,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link ("",[],[]) [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
387+,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link ("",["uri"],[]) [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
388388,BulletList
389389 [[Plain [Str "In",Space,Str "a",Space,Str "list?"]]
390− ,[Plain [Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
390+ ,[Plain [Link ("",["uri"],[]) [Str "http://example.com/"] ("http://example.com/","")]]
391391 ,[Plain [Str "It",Space,Str "should."]]]
392−,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link ("",[],[]) [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
392+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link ("",["email"],[]) [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
393393,BlockQuote
394− [Para [Str "Blockquoted:",Space,Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
394+ [Para [Str "Blockquoted:",Space,Link ("",["uri"],[]) [Str "http://example.com/"] ("http://example.com/","")]]
395395,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]
396396,CodeBlock ("",[],[]) "or here: <http://example.com/>"
397397,HorizontalRule
test/textile-reader.native+1−1
@@ -2,7 +2,7 @@ Pandoc (Meta {unMeta = fromList []})
22[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.",Space,Str "Part",Space,Str "of",Space,Str "it",Space,Str "comes",LineBreak,Str "from",Space,Str "John",Space,Str "Gruber\8217s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
33,HorizontalRule
44,Header 1 ("headers",[],[]) [Str "Headers"]
5−,Header 2 ("level-2-with-an-embeded-link",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link ("",[],[]) [Str "embeded",Space,Str "link"] ("http://www.example.com","")]
5+,Header 2 ("level-2-with-an-embedded-link",[],[]) [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link ("",[],[]) [Str "embedded",Space,Str "link"] ("http://www.example.com","")]
66,Header 3 ("level-3-with-emphasis",[],[]) [Str "Level",Space,Str "3",Space,Str "with",Space,Strong [Str "emphasis"]]
77,Header 4 ("level-4",[],[]) [Str "Level",Space,Str "4"]
88,Header 5 ("level-5",[],[]) [Str "Level",Space,Str "5"]
test/textile-reader.textile+1−1
@@ -5,7 +5,7 @@ from John Gruber's markdown test suite.
55
66h1. Headers
77
8−h2. Level 2 with an "embeded link":http://www.example.com
8+h2. Level 2 with an "embedded link":http://www.example.com
99
1010h3. Level 3 with *emphasis*
1111
test/tikiwiki-reader.native+29−29
@@ -43,52 +43,52 @@ Pandoc (Meta {unMeta = fromList []})
4343,Para [Str "info@example.org"]
4444,Header 1 ("lists",[],[]) [Str "lists"]
4545,BulletList
46− [[Plain [Str "Start",Space,Str "each",Space,Str "line",Space]]
47− ,[Plain [Str "with",Space,Str "an",Space,Str "asterisk",Space,Str "(*).",Space]
46+ [[Plain [Str "Start",Space,Str "each",Space,Str "line"]]
47+ ,[Plain [Str "with",Space,Str "an",Space,Str "asterisk",Space,Str "(*)."]
4848 ,BulletList
49− [[Plain [Str "More",Space,Str "asterisks",Space,Str "gives",Space,Str "deeper",Space]
49+ [[Plain [Str "More",Space,Str "asterisks",Space,Str "gives",Space,Str "deeper"]
5050 ,BulletList
51− [[Plain [Str "and",Space,Str "deeper",Space,Str "levels.",Space]]]]]]
52− ,[Plain [Str "Line",Space,Str "breaks",LineBreak,Str "don't",Space,Str "break",Space,Str "levels.",Space]]
53− ,[Plain [Str "Continuations",Space,Str "are",Space,Str "also",Space,Str "possible",Space]
51+ [[Plain [Str "and",Space,Str "deeper",Space,Str "levels."]]]]]]
52+ ,[Plain [Str "Line",Space,Str "breaks",LineBreak,Str "don't",Space,Str "break",Space,Str "levels."]]
53+ ,[Plain [Str "Continuations",Space,Str "are",Space,Str "also",Space,Str "possible"]
5454 ,BulletList
55− [[Plain [Str "and",Space,Str "do",Space,Str "not",Space,Str "break",Space,Str "the",Space,Str "list",Space,Str "flow",Space]]]]
56− ,[Plain [Str "Level",Space,Str "one",Space]]]
55+ [[Plain [Str "and",Space,Str "do",Space,Str "not",Space,Str "break",Space,Str "the",Space,Str "list",Space,Str "flow"]]]]
56+ ,[Plain [Str "Level",Space,Str "one"]]]
5757,Para [Str "Any",Space,Str "other",Space,Str "start",Space,Str "ends",Space,Str "the",Space,Str "list."]
5858,OrderedList (1,DefaultStyle,DefaultDelim)
59− [[Plain [Str "Start",Space,Str "each",Space,Str "line",Space]]
60− ,[Plain [Str "with",Space,Str "a",Space,Str "number",Space,Str "(1.).",Space]
59+ [[Plain [Str "Start",Space,Str "each",Space,Str "line"]]
60+ ,[Plain [Str "with",Space,Str "a",Space,Str "number",Space,Str "(1.)."]
6161 ,OrderedList (1,DefaultStyle,DefaultDelim)
62− [[Plain [Str "More",Space,Str "number",Space,Str "signs",Space,Str "gives",Space,Str "deeper",Space]
62+ [[Plain [Str "More",Space,Str "number",Space,Str "signs",Space,Str "gives",Space,Str "deeper"]
6363 ,OrderedList (1,DefaultStyle,DefaultDelim)
64− [[Plain [Str "and",Space,Str "deeper",Space]]
65− ,[Plain [Str "levels.",Space]]]]]]
66− ,[Plain [Str "Line",Space,Str "breaks",LineBreak,Str "don't",Space,Str "break",Space,Str "levels.",Space]]
67− ,[Plain [Str "Blank",Space,Str "lines",Space]]]
64+ [[Plain [Str "and",Space,Str "deeper"]]
65+ ,[Plain [Str "levels."]]]]]]
66+ ,[Plain [Str "Line",Space,Str "breaks",LineBreak,Str "don't",Space,Str "break",Space,Str "levels."]]
67+ ,[Plain [Str "Blank",Space,Str "lines"]]]
6868,OrderedList (1,DefaultStyle,DefaultDelim)
69− [[Plain [Str "end",Space,Str "the",Space,Str "list",Space,Str "and",Space,Str "start",Space,Str "another.",Space]]]
69+ [[Plain [Str "end",Space,Str "the",Space,Str "list",Space,Str "and",Space,Str "start",Space,Str "another."]]]
7070,Para [Str "Any",Space,Str "other",Space,Str "start",Space,Str "also",Space,Str "ends",Space,Str "the",Space,Str "list."]
7171,DefinitionList
7272 [([Str "item",Space,Str "1"],
73− [[Plain [Str "definition",Space,Str "1",Space]]])
73+ [[Plain [Str "definition",Space,Str "1"]]])
7474 ,([Str "item",Space,Str "2"],
75− [[Plain [Str "definition",Space,Str "2-1",Space,Str "definition",Space,Str "2-2",Space]]])
75+ [[Plain [Str "definition",Space,Str "2-1",Space,Str "definition",Space,Str "2-2"]]])
7676 ,([Str "item",Space,Emph [Str "3"]],
77− [[Plain [Str "definition",Space,Emph [Str "3"],Space]]])]
77+ [[Plain [Str "definition",Space,Emph [Str "3"]]]])]
7878,OrderedList (1,DefaultStyle,DefaultDelim)
79− [[Plain [Str "one",Space]]
80− ,[Plain [Str "two",Space]
79+ [[Plain [Str "one"]]
80+ ,[Plain [Str "two"]
8181 ,BulletList
82− [[Plain [Str "two",Space,Str "point",Space,Str "one",Space]]
83− ,[Plain [Str "two",Space,Str "point",Space,Str "two",Space]]]]
84− ,[Plain [Str "three",Space]]
85− ,[Plain [Str "four",Space]]
86− ,[Plain [Str "five",Space]
82+ [[Plain [Str "two",Space,Str "point",Space,Str "one"]]
83+ ,[Plain [Str "two",Space,Str "point",Space,Str "two"]]]]
84+ ,[Plain [Str "three"]]
85+ ,[Plain [Str "four"]]
86+ ,[Plain [Str "five"]
8787 ,OrderedList (1,DefaultStyle,DefaultDelim)
88− [[Plain [Str "five",Space,Str "sub",Space,Str "1",Space]
88+ [[Plain [Str "five",Space,Str "sub",Space,Str "1"]
8989 ,OrderedList (1,DefaultStyle,DefaultDelim)
90− [[Plain [Str "five",Space,Str "sub",Space,Str "1",Space,Str "sub",Space,Str "1",Space]]]]
91− ,[Plain [Str "five",Space,Str "sub",Space,Str "2",Space]]]]]
90+ [[Plain [Str "five",Space,Str "sub",Space,Str "1",Space,Str "sub",Space,Str "1"]]]]
91+ ,[Plain [Str "five",Space,Str "sub",Space,Str "2"]]]]]
9292,Header 1 ("tables",[],[]) [Str "tables"]
9393,Table [] [AlignDefault,AlignDefault] [0.0,0.0]
9494 [[Plain [Str ""]]
test/txt2tags.t2t+1−1
@@ -136,7 +136,7 @@ i) ***bold*** ///ital/// ___undr___ ---strk--- ```mono``` """raw"
136136%%% Syntax: Repetition is greedy
137137%% When the mark character is repeated many times,
138138%% the contents are expanded to the largest possible.
139−%% Thats why they are greedy, the outer marks are
139+%% That's why they are greedy, the outer marks are
140140%% the ones used.
141141
142142i) ***** ///// _____ ----- ````` """"" '''''
test/writer.context+6
@@ -706,6 +706,12 @@ These shouldn't be math:
706706
707707Here's a LaTeX table:
708708
709+\begin{tabular}{|l|l|}\hline
710+Animal & Number \\ \hline
711+Dog & 2 \\
712+Cat & 1 \\ \hline
713+\end{tabular}
714+
709715\thinrule
710716
711717\section[title={Special Characters},reference={special-characters}]
test/writer.docbook4+3−3
@@ -1298,7 +1298,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
12981298 <title>Autolinks</title>
12991299 <para>
13001300 With an ampersand:
1301− <ulink url="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</ulink>
1301+ <ulink url="http://example.com/?foo=1&amp;bar=2" role="uri">http://example.com/?foo=1&amp;bar=2</ulink>
13021302 </para>
13031303 <itemizedlist spacing="compact">
13041304 <listitem>
@@ -1308,7 +1308,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
13081308 </listitem>
13091309 <listitem>
13101310 <para>
1311− <ulink url="http://example.com/">http://example.com/</ulink>
1311+ <ulink url="http://example.com/" role="uri">http://example.com/</ulink>
13121312 </para>
13131313 </listitem>
13141314 <listitem>
@@ -1323,7 +1323,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
13231323 <blockquote>
13241324 <para>
13251325 Blockquoted:
1326− <ulink url="http://example.com/">http://example.com/</ulink>
1326+ <ulink url="http://example.com/" role="uri">http://example.com/</ulink>
13271327 </para>
13281328 </blockquote>
13291329 <para>
test/writer.docbook5+3−3
@@ -1273,7 +1273,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
12731273 <title>Autolinks</title>
12741274 <para>
12751275 With an ampersand:
1276− <link xlink:href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</link>
1276+ <link xlink:href="http://example.com/?foo=1&amp;bar=2" role="uri">http://example.com/?foo=1&amp;bar=2</link>
12771277 </para>
12781278 <itemizedlist spacing="compact">
12791279 <listitem>
@@ -1283,7 +1283,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
12831283 </listitem>
12841284 <listitem>
12851285 <para>
1286− <link xlink:href="http://example.com/">http://example.com/</link>
1286+ <link xlink:href="http://example.com/" role="uri">http://example.com/</link>
12871287 </para>
12881288 </listitem>
12891289 <listitem>
@@ -1298,7 +1298,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{
12981298 <blockquote>
12991299 <para>
13001300 Blockquoted:
1301− <link xlink:href="http://example.com/">http://example.com/</link>
1301+ <link xlink:href="http://example.com/" role="uri">http://example.com/</link>
13021302 </para>
13031303 </blockquote>
13041304 <para>
test/writer.fb2+1−1
@@ -3,7 +3,6 @@
33<description>
44<title-info>
55<genre>unrecognised</genre>
6−<book-title>Pandoc Test Suite</book-title>
76<author>
87<first-name>John</first-name>
98<last-name>MacFarlane</last-name>
@@ -11,6 +10,7 @@
1110<author>
1211<nickname>Anonymous</nickname>
1312</author>
13+<book-title>Pandoc Test Suite</book-title>
1414<date>July 17, 2006</date>
1515</title-info>
1616<document-info>
test/writer.haddock+7−7
@@ -455,14 +455,14 @@ ______________________________________________________________________________
455455#latex#
456456
457457-
458−- 2 + 2 = 4
459−- /x/ ∈ /y/
460−- /α/ ∧ /ω/
461−- 223
462−- /p/-Tree
458+- \(2+2=4\)
459+- \(x \in y\)
460+- \(\alpha \wedge \omega\)
461+- \(223\)
462+- \(p\)-Tree
463463- Here’s some display math:
464− $$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$$
465−- Here’s one that has a line break in it: /α/ + /ω/ × /x/2.
464+ \[\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}\]
465+- Here’s one that has a line break in it: \(\alpha + \omega \times x^2\).
466466
467467These shouldn’t be math:
468468
test/writer.html4+1−1
@@ -508,7 +508,7 @@ Blah
508508<li><a href="http://example.com/" class="uri">http://example.com/</a></li>
509509<li>It should.</li>
510510</ul>
511−<p>An e-mail address: <a href="mailto:nobody@nowhere.net">nobody@nowhere.net</a></p>
511+<p>An e-mail address: <a href="mailto:nobody@nowhere.net" class="email">nobody@nowhere.net</a></p>
512512<blockquote>
513513<p>Blockquoted: <a href="http://example.com/" class="uri">http://example.com/</a></p>
514514</blockquote>
test/writer.html5+2−2
@@ -19,7 +19,7 @@
1919 <![endif]-->
2020</head>
2121<body>
22−<header>
22+<header id="title-block-header">
2323<h1 class="title">Pandoc Test Suite</h1>
2424<p class="author">John MacFarlane</p>
2525<p class="author">Anonymous</p>
@@ -511,7 +511,7 @@ Blah
511511<li><a href="http://example.com/" class="uri">http://example.com/</a></li>
512512<li>It should.</li>
513513</ul>
514−<p>An e-mail address: <a href="mailto:nobody@nowhere.net">nobody@nowhere.net</a></p>
514+<p>An e-mail address: <a href="mailto:nobody@nowhere.net" class="email">nobody@nowhere.net</a></p>
515515<blockquote>
516516<p>Blockquoted: <a href="http://example.com/" class="uri">http://example.com/</a></p>
517517</blockquote>
test/writer.jats+6−7
@@ -583,7 +583,7 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
583583 </boxed-text>
584584 <p>Interpreted markdown in a table:</p>
585585 <p>This is <italic>emphasized</italic></p>
586− <p>And this is <bold role="strong">strong</bold></p>
586+ <p>And this is <bold>strong</bold></p>
587587 <p>Here’s a simple block:</p>
588588 <boxed-text>
589589 <p>foo</p>
@@ -614,14 +614,13 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
614614<sec id="inline-markup">
615615 <title>Inline Markup</title>
616616 <p>This is <italic>emphasized</italic>, and so <italic>is this</italic>.</p>
617− <p>This is <bold role="strong">strong</bold>, and so <bold role="strong">is
618− this</bold>.</p>
617+ <p>This is <bold>strong</bold>, and so <bold>is this</bold>.</p>
619618 <p>An <italic><ext-link ext-link-type="uri" xlink:href="/url">emphasized
620619 link</ext-link></italic>.</p>
621− <p><bold role="strong"><italic>This is strong and em.</italic></bold></p>
622− <p>So is <bold role="strong"><italic>this</italic></bold> word.</p>
623− <p><bold role="strong"><italic>This is strong and em.</italic></bold></p>
624− <p>So is <bold role="strong"><italic>this</italic></bold> word.</p>
620+ <p><bold><italic>This is strong and em.</italic></bold></p>
621+ <p>So is <bold><italic>this</italic></bold> word.</p>
622+ <p><bold><italic>This is strong and em.</italic></bold></p>
623+ <p>So is <bold><italic>this</italic></bold> word.</p>
625624 <p>This is code: <monospace>&gt;</monospace>, <monospace>$</monospace>,
626625 <monospace>\</monospace>, <monospace>\$</monospace>,
627626 <monospace>&lt;html&gt;</monospace>.</p>
test/writer.muse+37−40
@@ -11,7 +11,7 @@ markdown test suite.
1111
1212** Level 2 with an [[/url][embedded link]]
1313
14−*** Level 3 with <em>emphasis</em>
14+*** Level 3 with *emphasis*
1515
1616**** Level 4
1717
@@ -19,7 +19,7 @@ markdown test suite.
1919
2020* Level 1
2121
22−** Level 2 with <em>emphasis</em>
22+** Level 2 with *emphasis*
2323
2424*** Level 3
2525
@@ -271,18 +271,18 @@ Loose:
271271
272272Multiple blocks with italics:
273273
274− <em>apple</em> :: red fruit
274+ *apple* :: red fruit
275275
276− contains seeds, crisp, pleasant to taste
277− <em>orange</em> :: orange fruit
276+ contains seeds, crisp, pleasant to taste
277+ *orange* :: orange fruit
278278
279− <example>
280− { orange code block }
281− </example>
279+ <example>
280+ { orange code block }
281+ </example>
282282
283− <quote>
284− orange block quote
285− </quote>
283+ <quote>
284+ orange block quote
285+ </quote>
286286
287287Multiple definitions, tight:
288288
@@ -331,7 +331,7 @@ Interpreted markdown in a table:
331331<td>
332332</literal>
333333
334−This is <em>emphasized</em>
334+This is *emphasized*
335335
336336<literal style="html">
337337</td>
@@ -341,7 +341,7 @@ This is <em>emphasized</em>
341341<td>
342342</literal>
343343
344−And this is <strong>strong</strong>
344+And this is **strong**
345345
346346<literal style="html">
347347</td>
@@ -461,27 +461,25 @@ Hr’s:
461461
462462* Inline Markup
463463
464−This is <em>emphasized</em>, and so <em>is this</em>.
464+This is *emphasized*, and so *is this*.
465465
466−This is <strong>strong</strong>, and so <strong>is this</strong>.
466+This is **strong**, and so **is this**.
467467
468−An <em>[[/url][emphasized link]]</em>.
468+An *[[/url][emphasized link]]*.
469469
470−<strong><em>This is strong and em.</em></strong>
470+***This is strong and em.***
471471
472−So is <strong><em>this</em></strong> word.
472+So is ***this*** word.
473473
474−<strong><em>This is strong and em.</em></strong>
474+***This is strong and em.***
475475
476−So is <strong><em>this</em></strong> word.
476+So is ***this*** word.
477477
478−This is code: <code>></code>, <code>$</code>, <code>\</code>, <code>\$</code>,
479−<code><html></code>.
478+This is code: =>=, =$=, =\=, =\$=, =<html>=.
480479
481−<del>This is <em>strikeout</em>.</del>
480+<del>This is *strikeout*.</del>
482481
483−Superscripts: a<sup>bc</sup>d a<sup><em>hello</em></sup>
484−a<sup>hello there</sup>.
482+Superscripts: a<sup>bc</sup>d a<sup>*hello*</sup> a<sup>hello there</sup>.
485483
486484Subscripts: H<sub>2</sub>O, H<sub>23</sub>O, H<sub>many of them</sub>O.
487485
@@ -500,8 +498,8 @@ spaces: a^b c^d, a~b c~d.
500498
501499‘He said, “I want to go.”’ Were you alive in the 70’s?
502500
503−Here is some quoted ‘<code>code</code>’ and a
504−“[[http://example.com/?foo=1&bar=2][quoted link]]”.
501+Here is some quoted ‘=code=’ and a “[[http://example.com/?foo=1&bar=2][quoted
502+link]]”.
505503
506504Some dashes: one—two — three—four — five.
507505
@@ -515,26 +513,25 @@ Ellipses…and…and….
515513
516514 - <literal style="tex">\cite[22-23]{smith.1899}</literal>
517515 - <verbatim>2 + 2 = 4</verbatim>
518− - <em>x</em> ∈ <em>y</em>
519− - <em>α</em> ∧ <em>ω</em>
516+ - *x* ∈ *y*
517+ - *α* ∧ *ω*
520518 - 223
521− - <em>p</em>-Tree
519+ - *p*-Tree
522520 - Here’s some display math:
523521 <verbatim>$$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$</verbatim>
524− - Here’s one that has a line break in it:
525− <em>α</em> + <em>ω</em> × <em>x</em><sup>2</sup>.
522+ - Here’s one that has a line break in it: *α* + *ω* × *x*<sup>2</sup>.
526523
527524These shouldn’t be math:
528525
529526 - To get the famous equation, write <code>$e = mc^2$</code>.
530− - $22,000 is a <em>lot</em> of money. So is $34,000. (It worked if “lot” is
527+ - $22,000 is a *lot* of money. So is $34,000. (It worked if “lot” is
531528 emphasized.)
532529 - Shoes ($20) and socks ($5).
533− - Escaped <code>$</code>: $73 <em>this should be emphasized</em> 23$.
530+ - Escaped =$=: $73 *this should be emphasized* 23$.
534531
535532Here’s a LaTeX table:
536533
537−<literal style="latex">
534+<literal style="tex">
538535\begin{tabular}{|l|l|}\hline
539536Animal & Number \\ \hline
540537Dog & 2 \\
@@ -669,7 +666,7 @@ An e-mail address: [[mailto:nobody@nowhere.net][nobody@nowhere.net]]
669666Blockquoted: [[http://example.com/]]
670667</quote>
671668
672−Auto-links should not occur here: <code><http://example.com/></code>
669+Auto-links should not occur here: =<http://example.com/>=
673670
674671<example>
675672or here: <http://example.com/>
@@ -689,7 +686,7 @@ Here is a movie [[movie.jpg][movie]] icon.
689686
690687* Footnotes
691688
692−Here is a footnote reference,[1] and another.[2] This should <em>not</em> be a
689+Here is a footnote reference,[1] and another.[2] This should *not* be a
693690footnote reference, because it contains a space.[^my note] Here is an inline
694691note.[3]
695692
@@ -716,9 +713,9 @@ This paragraph should not be part of the note, as it is not indented.
716713 If you want, you can indent every line, but you can also be lazy and just
717714 indent the first line of each block.
718715
719−[3] This is <em>easier</em> to type. Inline notes may contain
720− [[http://google.com][links]] and <code>]</code> verbatim characters, as
721− well as [bracketed text].
716+[3] This is *easier* to type. Inline notes may contain
717+ [[http://google.com][links]] and =]= verbatim characters, as well as
718+ [bracketed text].
722719
723720[4] In quote.
724721
test/writer.native+5−5
@@ -324,7 +324,7 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Spa
324324 ,[Plain [Str "Shoes",Space,Str "($20)",Space,Str "and",Space,Str "socks",Space,Str "($5)."]]
325325 ,[Plain [Str "Escaped",Space,Code ("",[],[]) "$",Str ":",Space,Str "$73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23$."]]]
326326,Para [Str "Here\8217s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
327−,RawBlock (Format "latex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
327+,RawBlock (Format "tex") "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog & 2 \\\\\nCat & 1 \\\\ \\hline\n\\end{tabular}"
328328,HorizontalRule
329329,Header 1 ("special-characters",[],[]) [Str "Special",Space,Str "Characters"]
330330,Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]
@@ -384,14 +384,14 @@ Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "John",Spa
384384,Para [Str "Here\8217s",Space,Str "an",Space,Link ("",[],[]) [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
385385,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 "."]
386386,Header 2 ("autolinks",[],[]) [Str "Autolinks"]
387−,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link ("",[],[]) [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
387+,Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link ("",["uri"],[]) [Str "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
388388,BulletList
389389 [[Plain [Str "In",Space,Str "a",Space,Str "list?"]]
390− ,[Plain [Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
390+ ,[Plain [Link ("",["uri"],[]) [Str "http://example.com/"] ("http://example.com/","")]]
391391 ,[Plain [Str "It",Space,Str "should."]]]
392−,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link ("",[],[]) [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
392+,Para [Str "An",Space,Str "e-mail",Space,Str "address:",Space,Link ("",["email"],[]) [Str "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
393393,BlockQuote
394− [Para [Str "Blockquoted:",Space,Link ("",[],[]) [Str "http://example.com/"] ("http://example.com/","")]]
394+ [Para [Str "Blockquoted:",Space,Link ("",["uri"],[]) [Str "http://example.com/"] ("http://example.com/","")]]
395395,Para [Str "Auto-links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code ("",[],[]) "<http://example.com/>"]
396396,CodeBlock ("",[],[]) "or here: <http://example.com/>"
397397,HorizontalRule
test/writer.opendocument+621−234
@@ -6,629 +6,1007 @@
66 <office:automatic-styles>
77 <text:list-style style:name="L1">
88 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
9− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
9+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
10+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
11+ </style:list-level-properties>
1012 </text:list-level-style-number>
1113 </text:list-style>
1214 <text:list-style style:name="L2">
1315 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
14− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
16+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
17+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
18+ </style:list-level-properties>
1519 </text:list-level-style-bullet>
1620 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
17− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
21+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
22+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
23+ </style:list-level-properties>
1824 </text:list-level-style-bullet>
1925 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
20− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
26+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
27+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
28+ </style:list-level-properties>
2129 </text:list-level-style-bullet>
2230 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
23− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
31+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
32+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
33+ </style:list-level-properties>
2434 </text:list-level-style-bullet>
2535 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
26− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
36+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
37+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
38+ </style:list-level-properties>
2739 </text:list-level-style-bullet>
2840 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
29− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
41+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
42+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
43+ </style:list-level-properties>
3044 </text:list-level-style-bullet>
3145 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
32− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
46+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
47+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
48+ </style:list-level-properties>
3349 </text:list-level-style-bullet>
3450 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
35− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
51+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
52+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
53+ </style:list-level-properties>
3654 </text:list-level-style-bullet>
3755 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
38− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
56+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
57+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
58+ </style:list-level-properties>
3959 </text:list-level-style-bullet>
4060 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
41− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
61+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
62+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
63+ </style:list-level-properties>
4264 </text:list-level-style-bullet>
4365 </text:list-style>
4466 <text:list-style style:name="L3">
4567 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
46− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
68+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
69+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
70+ </style:list-level-properties>
4771 </text:list-level-style-bullet>
4872 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
49− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
73+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
74+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
75+ </style:list-level-properties>
5076 </text:list-level-style-bullet>
5177 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
52− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
78+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
79+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
80+ </style:list-level-properties>
5381 </text:list-level-style-bullet>
5482 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
55− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
83+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
84+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
85+ </style:list-level-properties>
5686 </text:list-level-style-bullet>
5787 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
58− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
88+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
89+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
90+ </style:list-level-properties>
5991 </text:list-level-style-bullet>
6092 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
61− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
93+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
94+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
95+ </style:list-level-properties>
6296 </text:list-level-style-bullet>
6397 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
64− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
98+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
99+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
100+ </style:list-level-properties>
65101 </text:list-level-style-bullet>
66102 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
67− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
103+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
104+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
105+ </style:list-level-properties>
68106 </text:list-level-style-bullet>
69107 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
70− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
108+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
109+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
110+ </style:list-level-properties>
71111 </text:list-level-style-bullet>
72112 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
73− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
113+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
114+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
115+ </style:list-level-properties>
74116 </text:list-level-style-bullet>
75117 </text:list-style>
76118 <text:list-style style:name="L4">
77119 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
78− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
120+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
121+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
122+ </style:list-level-properties>
79123 </text:list-level-style-bullet>
80124 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
81− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
125+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
126+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
127+ </style:list-level-properties>
82128 </text:list-level-style-bullet>
83129 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
84− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
130+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
131+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
132+ </style:list-level-properties>
85133 </text:list-level-style-bullet>
86134 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
87− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
135+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
136+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
137+ </style:list-level-properties>
88138 </text:list-level-style-bullet>
89139 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
90− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
140+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
141+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
142+ </style:list-level-properties>
91143 </text:list-level-style-bullet>
92144 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
93− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
145+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
146+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
147+ </style:list-level-properties>
94148 </text:list-level-style-bullet>
95149 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
96− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
150+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
151+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
152+ </style:list-level-properties>
97153 </text:list-level-style-bullet>
98154 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
99− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
155+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
156+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
157+ </style:list-level-properties>
100158 </text:list-level-style-bullet>
101159 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
102− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
160+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
161+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
162+ </style:list-level-properties>
103163 </text:list-level-style-bullet>
104164 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
105− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
165+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
166+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
167+ </style:list-level-properties>
106168 </text:list-level-style-bullet>
107169 </text:list-style>
108170 <text:list-style style:name="L5">
109171 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
110− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
172+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
173+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
174+ </style:list-level-properties>
111175 </text:list-level-style-bullet>
112176 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
113− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
177+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
178+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
179+ </style:list-level-properties>
114180 </text:list-level-style-bullet>
115181 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
116− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
182+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
183+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
184+ </style:list-level-properties>
117185 </text:list-level-style-bullet>
118186 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
119− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
187+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
188+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
189+ </style:list-level-properties>
120190 </text:list-level-style-bullet>
121191 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
122− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
192+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
193+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
194+ </style:list-level-properties>
123195 </text:list-level-style-bullet>
124196 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
125− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
197+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
198+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
199+ </style:list-level-properties>
126200 </text:list-level-style-bullet>
127201 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
128− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
202+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
203+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
204+ </style:list-level-properties>
129205 </text:list-level-style-bullet>
130206 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
131− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
207+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
208+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
209+ </style:list-level-properties>
132210 </text:list-level-style-bullet>
133211 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
134− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
212+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
213+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
214+ </style:list-level-properties>
135215 </text:list-level-style-bullet>
136216 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
137− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
217+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
218+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
219+ </style:list-level-properties>
138220 </text:list-level-style-bullet>
139221 </text:list-style>
140222 <text:list-style style:name="L6">
141223 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
142− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
224+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
225+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
226+ </style:list-level-properties>
143227 </text:list-level-style-bullet>
144228 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
145− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
229+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
230+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
231+ </style:list-level-properties>
146232 </text:list-level-style-bullet>
147233 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
148− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
234+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
235+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
236+ </style:list-level-properties>
149237 </text:list-level-style-bullet>
150238 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
151− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
239+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
240+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
241+ </style:list-level-properties>
152242 </text:list-level-style-bullet>
153243 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
154− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
244+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
245+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
246+ </style:list-level-properties>
155247 </text:list-level-style-bullet>
156248 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
157− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
249+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
250+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
251+ </style:list-level-properties>
158252 </text:list-level-style-bullet>
159253 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
160− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
254+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
255+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
256+ </style:list-level-properties>
161257 </text:list-level-style-bullet>
162258 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
163− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
259+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
260+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
261+ </style:list-level-properties>
164262 </text:list-level-style-bullet>
165263 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
166− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
264+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
265+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
266+ </style:list-level-properties>
167267 </text:list-level-style-bullet>
168268 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
169− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
269+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
270+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
271+ </style:list-level-properties>
170272 </text:list-level-style-bullet>
171273 </text:list-style>
172274 <text:list-style style:name="L7">
173275 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
174− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
276+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
277+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
278+ </style:list-level-properties>
175279 </text:list-level-style-bullet>
176280 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
177− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
281+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
282+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
283+ </style:list-level-properties>
178284 </text:list-level-style-bullet>
179285 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
180− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
286+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
287+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
288+ </style:list-level-properties>
181289 </text:list-level-style-bullet>
182290 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
183− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
291+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
292+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
293+ </style:list-level-properties>
184294 </text:list-level-style-bullet>
185295 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
186− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
296+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
297+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
298+ </style:list-level-properties>
187299 </text:list-level-style-bullet>
188300 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
189− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
301+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
302+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
303+ </style:list-level-properties>
190304 </text:list-level-style-bullet>
191305 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
192− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
306+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
307+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
308+ </style:list-level-properties>
193309 </text:list-level-style-bullet>
194310 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
195− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
311+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
312+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
313+ </style:list-level-properties>
196314 </text:list-level-style-bullet>
197315 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
198− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
316+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
317+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
318+ </style:list-level-properties>
199319 </text:list-level-style-bullet>
200320 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
201− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
321+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
322+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
323+ </style:list-level-properties>
202324 </text:list-level-style-bullet>
203325 </text:list-style>
204326 <text:list-style style:name="L8">
205327 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
206− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
328+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
329+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
330+ </style:list-level-properties>
207331 </text:list-level-style-number>
208332 </text:list-style>
209333 <text:list-style style:name="L9">
210334 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
211− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
335+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
336+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
337+ </style:list-level-properties>
212338 </text:list-level-style-number>
213339 </text:list-style>
214340 <text:list-style style:name="L10">
215341 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
216− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
342+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
343+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
344+ </style:list-level-properties>
217345 </text:list-level-style-number>
218346 </text:list-style>
219347 <text:list-style style:name="L11">
220348 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
221− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
349+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
350+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
351+ </style:list-level-properties>
222352 </text:list-level-style-number>
223353 </text:list-style>
224354 <text:list-style style:name="L12">
225355 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
226− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
356+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
357+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
358+ </style:list-level-properties>
227359 </text:list-level-style-number>
228360 </text:list-style>
229361 <text:list-style style:name="L13">
230362 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
231− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
363+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
364+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
365+ </style:list-level-properties>
232366 </text:list-level-style-bullet>
233367 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
234− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
368+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
369+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
370+ </style:list-level-properties>
235371 </text:list-level-style-bullet>
236372 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
237− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
373+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
374+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
375+ </style:list-level-properties>
238376 </text:list-level-style-bullet>
239377 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
240− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
378+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
379+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
380+ </style:list-level-properties>
241381 </text:list-level-style-bullet>
242382 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
243− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
383+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
384+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
385+ </style:list-level-properties>
244386 </text:list-level-style-bullet>
245387 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
246− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
388+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
389+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
390+ </style:list-level-properties>
247391 </text:list-level-style-bullet>
248392 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
249− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
393+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
394+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
395+ </style:list-level-properties>
250396 </text:list-level-style-bullet>
251397 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
252− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
398+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
399+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
400+ </style:list-level-properties>
253401 </text:list-level-style-bullet>
254402 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
255− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
403+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
404+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
405+ </style:list-level-properties>
256406 </text:list-level-style-bullet>
257407 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
258− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
408+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
409+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
410+ </style:list-level-properties>
259411 </text:list-level-style-bullet>
260412 </text:list-style>
261413 <text:list-style style:name="L14">
262414 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
263− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
415+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
416+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
417+ </style:list-level-properties>
264418 </text:list-level-style-bullet>
265419 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
266− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
420+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
421+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
422+ </style:list-level-properties>
267423 </text:list-level-style-bullet>
268424 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
269− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
425+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
426+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
427+ </style:list-level-properties>
270428 </text:list-level-style-bullet>
271429 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
272− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
430+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
431+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
432+ </style:list-level-properties>
273433 </text:list-level-style-bullet>
274434 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
275− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
435+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
436+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
437+ </style:list-level-properties>
276438 </text:list-level-style-bullet>
277439 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
278− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
440+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
441+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
442+ </style:list-level-properties>
279443 </text:list-level-style-bullet>
280444 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
281− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
445+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
446+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
447+ </style:list-level-properties>
282448 </text:list-level-style-bullet>
283449 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
284− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
450+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
451+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
452+ </style:list-level-properties>
285453 </text:list-level-style-bullet>
286454 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
287− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
455+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
456+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
457+ </style:list-level-properties>
288458 </text:list-level-style-bullet>
289459 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
290− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
460+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
461+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
462+ </style:list-level-properties>
291463 </text:list-level-style-bullet>
292464 </text:list-style>
293465 <text:list-style style:name="L15">
294466 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
295− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
467+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
468+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
469+ </style:list-level-properties>
296470 </text:list-level-style-bullet>
297471 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
298− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
472+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
473+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
474+ </style:list-level-properties>
299475 </text:list-level-style-bullet>
300476 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
301− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
477+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
478+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
479+ </style:list-level-properties>
302480 </text:list-level-style-bullet>
303481 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
304− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
482+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
483+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
484+ </style:list-level-properties>
305485 </text:list-level-style-bullet>
306486 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
307− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
487+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
488+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
489+ </style:list-level-properties>
308490 </text:list-level-style-bullet>
309491 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
310− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
492+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
493+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
494+ </style:list-level-properties>
311495 </text:list-level-style-bullet>
312496 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
313− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
497+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
498+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
499+ </style:list-level-properties>
314500 </text:list-level-style-bullet>
315501 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
316− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
502+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
503+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
504+ </style:list-level-properties>
317505 </text:list-level-style-bullet>
318506 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
319− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
507+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
508+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
509+ </style:list-level-properties>
320510 </text:list-level-style-bullet>
321511 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
322− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
512+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
513+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
514+ </style:list-level-properties>
323515 </text:list-level-style-bullet>
324516 </text:list-style>
325517 <text:list-style style:name="L16">
326518 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
327− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
519+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
520+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
521+ </style:list-level-properties>
328522 </text:list-level-style-number>
329523 </text:list-style>
330524 <text:list-style style:name="L17">
331525 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
332− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
526+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
527+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
528+ </style:list-level-properties>
333529 </text:list-level-style-bullet>
334530 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
335− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
531+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
532+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
533+ </style:list-level-properties>
336534 </text:list-level-style-bullet>
337535 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
338− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
536+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
537+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
538+ </style:list-level-properties>
339539 </text:list-level-style-bullet>
340540 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
341− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
541+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
542+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
543+ </style:list-level-properties>
342544 </text:list-level-style-bullet>
343545 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
344− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
546+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
547+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
548+ </style:list-level-properties>
345549 </text:list-level-style-bullet>
346550 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
347− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
551+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
552+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
553+ </style:list-level-properties>
348554 </text:list-level-style-bullet>
349555 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
350− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
556+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
557+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
558+ </style:list-level-properties>
351559 </text:list-level-style-bullet>
352560 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
353− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
561+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
562+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
563+ </style:list-level-properties>
354564 </text:list-level-style-bullet>
355565 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
356− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
566+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
567+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
568+ </style:list-level-properties>
357569 </text:list-level-style-bullet>
358570 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
359− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
571+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
572+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
573+ </style:list-level-properties>
360574 </text:list-level-style-bullet>
361575 </text:list-style>
362576 <text:list-style style:name="L18">
363577 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
364− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
578+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
579+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
580+ </style:list-level-properties>
365581 </text:list-level-style-number>
366582 </text:list-style>
367583 <text:list-style style:name="L19">
368584 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
369− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
585+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
586+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
587+ </style:list-level-properties>
370588 </text:list-level-style-bullet>
371589 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
372− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
590+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
591+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
592+ </style:list-level-properties>
373593 </text:list-level-style-bullet>
374594 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
375− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
595+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
596+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
597+ </style:list-level-properties>
376598 </text:list-level-style-bullet>
377599 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
378− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
600+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
601+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
602+ </style:list-level-properties>
379603 </text:list-level-style-bullet>
380604 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
381− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
605+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
606+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
607+ </style:list-level-properties>
382608 </text:list-level-style-bullet>
383609 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
384− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
610+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
611+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
612+ </style:list-level-properties>
385613 </text:list-level-style-bullet>
386614 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
387− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
615+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
616+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
617+ </style:list-level-properties>
388618 </text:list-level-style-bullet>
389619 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
390− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
620+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
621+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
622+ </style:list-level-properties>
391623 </text:list-level-style-bullet>
392624 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
393− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
625+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
626+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
627+ </style:list-level-properties>
394628 </text:list-level-style-bullet>
395629 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
396− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
630+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
631+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
632+ </style:list-level-properties>
397633 </text:list-level-style-bullet>
398634 </text:list-style>
399635 <text:list-style style:name="L20">
400636 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
401− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
637+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
638+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
639+ </style:list-level-properties>
402640 </text:list-level-style-bullet>
403641 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
404− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
642+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
643+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
644+ </style:list-level-properties>
405645 </text:list-level-style-bullet>
406646 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
407− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
647+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
648+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
649+ </style:list-level-properties>
408650 </text:list-level-style-bullet>
409651 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
410− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
652+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
653+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
654+ </style:list-level-properties>
411655 </text:list-level-style-bullet>
412656 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
413− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
657+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
658+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
659+ </style:list-level-properties>
414660 </text:list-level-style-bullet>
415661 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
416− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
662+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
663+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
664+ </style:list-level-properties>
417665 </text:list-level-style-bullet>
418666 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
419− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
667+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
668+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
669+ </style:list-level-properties>
420670 </text:list-level-style-bullet>
421671 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
422− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
672+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
673+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
674+ </style:list-level-properties>
423675 </text:list-level-style-bullet>
424676 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
425− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
677+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
678+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
679+ </style:list-level-properties>
426680 </text:list-level-style-bullet>
427681 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
428− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
682+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
683+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
684+ </style:list-level-properties>
429685 </text:list-level-style-bullet>
430686 </text:list-style>
431687 <text:list-style style:name="L21">
432688 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
433− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
689+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
690+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
691+ </style:list-level-properties>
434692 </text:list-level-style-bullet>
435693 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
436− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
694+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
695+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
696+ </style:list-level-properties>
437697 </text:list-level-style-bullet>
438698 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
439− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
699+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
700+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
701+ </style:list-level-properties>
440702 </text:list-level-style-bullet>
441703 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
442− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
704+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
705+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
706+ </style:list-level-properties>
443707 </text:list-level-style-bullet>
444708 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
445− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
709+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
710+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
711+ </style:list-level-properties>
446712 </text:list-level-style-bullet>
447713 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
448− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
714+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
715+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
716+ </style:list-level-properties>
449717 </text:list-level-style-bullet>
450718 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
451− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
719+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
720+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
721+ </style:list-level-properties>
452722 </text:list-level-style-bullet>
453723 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
454− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
724+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
725+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
726+ </style:list-level-properties>
455727 </text:list-level-style-bullet>
456728 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
457− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
729+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
730+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
731+ </style:list-level-properties>
458732 </text:list-level-style-bullet>
459733 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
460− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
734+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
735+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
736+ </style:list-level-properties>
461737 </text:list-level-style-bullet>
462738 </text:list-style>
463739 <text:list-style style:name="L22">
464740 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="2" style:num-prefix="(" style:num-suffix=")">
465− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
741+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
742+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
743+ </style:list-level-properties>
466744 </text:list-level-style-number>
467745 <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="i" text:start-value="4" style:num-suffix=".">
468− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
746+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
747+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
748+ </style:list-level-properties>
469749 </text:list-level-style-number>
470750 <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="A" text:start-value="1" style:num-prefix="(" style:num-suffix=")">
471− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
751+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
752+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
753+ </style:list-level-properties>
472754 </text:list-level-style-number>
473755 </text:list-style>
474756 <text:list-style style:name="L23">
475757 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="A" text:start-value="1" style:num-suffix=".">
476− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
758+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
759+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
760+ </style:list-level-properties>
477761 </text:list-level-style-number>
478762 <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="I" text:start-value="1" style:num-suffix=".">
479− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
763+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
764+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
765+ </style:list-level-properties>
480766 </text:list-level-style-number>
481767 <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="6" style:num-prefix="(" style:num-suffix=")">
482− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
768+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
769+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
770+ </style:list-level-properties>
483771 </text:list-level-style-number>
484772 <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="a" text:start-value="3" style:num-suffix=")">
485− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
773+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
774+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
775+ </style:list-level-properties>
486776 </text:list-level-style-number>
487777 </text:list-style>
488778 <text:list-style style:name="L24">
489779 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
490− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
780+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
781+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
782+ </style:list-level-properties>
491783 </text:list-level-style-number>
492784 <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
493− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
785+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
786+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
787+ </style:list-level-properties>
494788 </text:list-level-style-number>
495789 </text:list-style>
496790 <text:list-style style:name="L25">
497791 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
498− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
792+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
793+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
794+ </style:list-level-properties>
499795 </text:list-level-style-number>
500796 </text:list-style>
501797 <text:list-style style:name="L26">
502798 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
503− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
799+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
800+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
801+ </style:list-level-properties>
504802 </text:list-level-style-bullet>
505803 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
506− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
804+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
805+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
806+ </style:list-level-properties>
507807 </text:list-level-style-bullet>
508808 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
509− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
809+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
810+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
811+ </style:list-level-properties>
510812 </text:list-level-style-bullet>
511813 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
512− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
814+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
815+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
816+ </style:list-level-properties>
513817 </text:list-level-style-bullet>
514818 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
515− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
819+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
820+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
821+ </style:list-level-properties>
516822 </text:list-level-style-bullet>
517823 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
518− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
824+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
825+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
826+ </style:list-level-properties>
519827 </text:list-level-style-bullet>
520828 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
521− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
829+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
830+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
831+ </style:list-level-properties>
522832 </text:list-level-style-bullet>
523833 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
524− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
834+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
835+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
836+ </style:list-level-properties>
525837 </text:list-level-style-bullet>
526838 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
527− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
839+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
840+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
841+ </style:list-level-properties>
528842 </text:list-level-style-bullet>
529843 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
530− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
844+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
845+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
846+ </style:list-level-properties>
531847 </text:list-level-style-bullet>
532848 </text:list-style>
533849 <text:list-style style:name="L27">
534850 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
535− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
851+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
852+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
853+ </style:list-level-properties>
536854 </text:list-level-style-bullet>
537855 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
538− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
856+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
857+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
858+ </style:list-level-properties>
539859 </text:list-level-style-bullet>
540860 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
541− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
861+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
862+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
863+ </style:list-level-properties>
542864 </text:list-level-style-bullet>
543865 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
544− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
866+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
867+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
868+ </style:list-level-properties>
545869 </text:list-level-style-bullet>
546870 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
547− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
871+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
872+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
873+ </style:list-level-properties>
548874 </text:list-level-style-bullet>
549875 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
550− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
876+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
877+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
878+ </style:list-level-properties>
551879 </text:list-level-style-bullet>
552880 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
553− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
881+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
882+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
883+ </style:list-level-properties>
554884 </text:list-level-style-bullet>
555885 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
556− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
886+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
887+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
888+ </style:list-level-properties>
557889 </text:list-level-style-bullet>
558890 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
559− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
891+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
892+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
893+ </style:list-level-properties>
560894 </text:list-level-style-bullet>
561895 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
562− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
896+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
897+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
898+ </style:list-level-properties>
563899 </text:list-level-style-bullet>
564900 </text:list-style>
565901 <text:list-style style:name="L28">
566902 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
567− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
903+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
904+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
905+ </style:list-level-properties>
568906 </text:list-level-style-bullet>
569907 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
570− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
908+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
909+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
910+ </style:list-level-properties>
571911 </text:list-level-style-bullet>
572912 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
573− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
913+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
914+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
915+ </style:list-level-properties>
574916 </text:list-level-style-bullet>
575917 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
576− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
918+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
919+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
920+ </style:list-level-properties>
577921 </text:list-level-style-bullet>
578922 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
579− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
923+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
924+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
925+ </style:list-level-properties>
580926 </text:list-level-style-bullet>
581927 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
582− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
928+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
929+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
930+ </style:list-level-properties>
583931 </text:list-level-style-bullet>
584932 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
585− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
933+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
934+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
935+ </style:list-level-properties>
586936 </text:list-level-style-bullet>
587937 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
588− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
938+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
939+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
940+ </style:list-level-properties>
589941 </text:list-level-style-bullet>
590942 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
591− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
943+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
944+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
945+ </style:list-level-properties>
592946 </text:list-level-style-bullet>
593947 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
594− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
948+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
949+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
950+ </style:list-level-properties>
595951 </text:list-level-style-bullet>
596952 </text:list-style>
597953 <text:list-style style:name="L29">
598954 <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
599− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
955+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
956+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
957+ </style:list-level-properties>
600958 </text:list-level-style-bullet>
601959 <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
602− <style:list-level-properties text:space-before="0.4in" text:min-label-width="0.4in" />
960+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
961+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.1in" fo:margin-left="1.0in" />
962+ </style:list-level-properties>
603963 </text:list-level-style-bullet>
604964 <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
605− <style:list-level-properties text:space-before="0.8in" text:min-label-width="0.4in" />
965+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
966+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.1in" fo:margin-left="1.5in" />
967+ </style:list-level-properties>
606968 </text:list-level-style-bullet>
607969 <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
608− <style:list-level-properties text:space-before="1.2000000000000002in" text:min-label-width="0.4in" />
970+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
971+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.1in" fo:margin-left="2.0in" />
972+ </style:list-level-properties>
609973 </text:list-level-style-bullet>
610974 <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
611− <style:list-level-properties text:space-before="1.6in" text:min-label-width="0.4in" />
975+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
976+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.1in" fo:margin-left="2.5in" />
977+ </style:list-level-properties>
612978 </text:list-level-style-bullet>
613979 <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
614− <style:list-level-properties text:space-before="2.0in" text:min-label-width="0.4in" />
980+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
981+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.0in" fo:text-indent="-0.1in" fo:margin-left="3.0in" />
982+ </style:list-level-properties>
615983 </text:list-level-style-bullet>
616984 <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
617− <style:list-level-properties text:space-before="2.4000000000000004in" text:min-label-width="0.4in" />
985+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
986+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.5in" fo:text-indent="-0.1in" fo:margin-left="3.5in" />
987+ </style:list-level-properties>
618988 </text:list-level-style-bullet>
619989 <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">
620− <style:list-level-properties text:space-before="2.8000000000000003in" text:min-label-width="0.4in" />
990+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
991+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.0in" fo:text-indent="-0.1in" fo:margin-left="4.0in" />
992+ </style:list-level-properties>
621993 </text:list-level-style-bullet>
622994 <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">
623− <style:list-level-properties text:space-before="3.2in" text:min-label-width="0.4in" />
995+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
996+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.5in" fo:text-indent="-0.1in" fo:margin-left="4.5in" />
997+ </style:list-level-properties>
624998 </text:list-level-style-bullet>
625999 <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">
626− <style:list-level-properties text:space-before="3.6in" text:min-label-width="0.4in" />
1000+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
1001+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.0in" fo:text-indent="-0.1in" fo:margin-left="5.0in" />
1002+ </style:list-level-properties>
6271003 </text:list-level-style-bullet>
6281004 </text:list-style>
6291005 <text:list-style style:name="L30">
6301006 <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">
631− <style:list-level-properties text:space-before="0.0in" text:min-label-width="0.4in" />
1007+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">
1008+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.1in" fo:margin-left="0.5in" />
1009+ </style:list-level-properties>
6321010 </text:list-level-style-number>
6331011 </text:list-style>
6341012 <style:style style:name="T1" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
@@ -803,23 +1181,31 @@
8031181<text:p text:style-name="Text_20_body">This is a set of tests for pandoc. Most
8041182of them are adapted from John Gruber’s markdown test suite.</text:p>
8051183<text:p text:style-name="Horizontal_20_Line" />
806−<text:h text:style-name="Heading_20_1" text:outline-level="1">Headers</text:h>
807−<text:h text:style-name="Heading_20_2" text:outline-level="2">Level 2 with an
1184+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="headers" />Headers<text:bookmark-end text:name="headers" /></text:h>
1185+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-an-embedded-link" />Level
1186+2 with an
8081187<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">embedded
809−link</text:span></text:a></text:h>
810−<text:h text:style-name="Heading_20_3" text:outline-level="3">Level 3 with
811−<text:span text:style-name="T1">emphasis</text:span></text:h>
812−<text:h text:style-name="Heading_20_4" text:outline-level="4">Level 4</text:h>
813−<text:h text:style-name="Heading_20_5" text:outline-level="5">Level 5</text:h>
814−<text:h text:style-name="Heading_20_1" text:outline-level="1">Level 1</text:h>
815−<text:h text:style-name="Heading_20_2" text:outline-level="2">Level 2 with
816−<text:span text:style-name="T1">emphasis</text:span></text:h>
817−<text:h text:style-name="Heading_20_3" text:outline-level="3">Level 3</text:h>
1188+link</text:span></text:a><text:bookmark-end text:name="level-2-with-an-embedded-link" /></text:h>
1189+<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3-with-emphasis" />Level
1190+3 with
1191+<text:span text:style-name="T1">emphasis</text:span><text:bookmark-end text:name="level-3-with-emphasis" /></text:h>
1192+<text:h text:style-name="Heading_20_4" text:outline-level="4"><text:bookmark-start text:name="level-4" />Level
1193+4<text:bookmark-end text:name="level-4" /></text:h>
1194+<text:h text:style-name="Heading_20_5" text:outline-level="5"><text:bookmark-start text:name="level-5" />Level
1195+5<text:bookmark-end text:name="level-5" /></text:h>
1196+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="level-1" />Level
1197+1<text:bookmark-end text:name="level-1" /></text:h>
1198+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-emphasis" />Level
1199+2 with
1200+<text:span text:style-name="T1">emphasis</text:span><text:bookmark-end text:name="level-2-with-emphasis" /></text:h>
1201+<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3" />Level
1202+3<text:bookmark-end text:name="level-3" /></text:h>
8181203<text:p text:style-name="First_20_paragraph">with no blank line</text:p>
819−<text:h text:style-name="Heading_20_2" text:outline-level="2">Level 2</text:h>
1204+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2" />Level
1205+2<text:bookmark-end text:name="level-2" /></text:h>
8201206<text:p text:style-name="First_20_paragraph">with no blank line</text:p>
8211207<text:p text:style-name="Horizontal_20_Line" />
822−<text:h text:style-name="Heading_20_1" text:outline-level="1">Paragraphs</text:h>
1208+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="paragraphs" />Paragraphs<text:bookmark-end text:name="paragraphs" /></text:h>
8231209<text:p text:style-name="First_20_paragraph">Here’s a regular
8241210paragraph.</text:p>
8251211<text:p text:style-name="Text_20_body">In Markdown 1.0.0 and earlier. Version
@@ -830,8 +1216,8 @@ criminey.</text:p>
8301216<text:p text:style-name="Text_20_body">There should be a hard line
8311217break<text:line-break />here.</text:p>
8321218<text:p text:style-name="Horizontal_20_Line" />
833−<text:h text:style-name="Heading_20_1" text:outline-level="1">Block
834−Quotes</text:h>
1219+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="block-quotes" />Block
1220+Quotes<text:bookmark-end text:name="block-quotes" /></text:h>
8351221<text:p text:style-name="First_20_paragraph">E-mail style:</text:p>
8361222<text:p text:style-name="P1">This is a block quote. It is pretty
8371223short.</text:p>
@@ -855,8 +1241,8 @@ short.</text:p>
85512412 &gt; 1.</text:p>
8561242<text:p text:style-name="Text_20_body">And a following paragraph.</text:p>
8571243<text:p text:style-name="Horizontal_20_Line" />
858−<text:h text:style-name="Heading_20_1" text:outline-level="1">Code
859−Blocks</text:h>
1244+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="code-blocks" />Code
1245+Blocks<text:bookmark-end text:name="code-blocks" /></text:h>
8601246<text:p text:style-name="First_20_paragraph">Code:</text:p>
8611247<text:p text:style-name="P9">---- (should be four hyphens)</text:p>
8621248<text:p text:style-name="P10"></text:p>
@@ -870,8 +1256,8 @@ Blocks</text:h>
8701256<text:p text:style-name="P17"></text:p>
8711257<text:p text:style-name="P18">These should not be escaped: <text:s text:c="1" />\$ \\ \&gt; \[ \{</text:p>
8721258<text:p text:style-name="Horizontal_20_Line" />
873−<text:h text:style-name="Heading_20_1" text:outline-level="1">Lists</text:h>
874−<text:h text:style-name="Heading_20_2" text:outline-level="2">Unordered</text:h>
1259+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="lists" />Lists<text:bookmark-end text:name="lists" /></text:h>
1260+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="unordered" />Unordered<text:bookmark-end text:name="unordered" /></text:h>
8751261<text:p text:style-name="First_20_paragraph">Asterisks tight:</text:p>
8761262<text:list text:style-name="L2">
8771263 <text:list-item>
@@ -944,7 +1330,7 @@ Blocks</text:h>
9441330 <text:p text:style-name="P24">Minus 3</text:p>
9451331 </text:list-item>
9461332</text:list>
947−<text:h text:style-name="Heading_20_2" text:outline-level="2">Ordered</text:h>
1333+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="ordered" />Ordered<text:bookmark-end text:name="ordered" /></text:h>
9481334<text:p text:style-name="First_20_paragraph">Tight:</text:p>
9491335<text:list text:style-name="L8">
9501336 <text:list-item>
@@ -1007,7 +1393,7 @@ Blocks</text:h>
10071393 <text:p text:style-name="P29">Item 3.</text:p>
10081394 </text:list-item>
10091395</text:list>
1010−<text:h text:style-name="Heading_20_2" text:outline-level="2">Nested</text:h>
1396+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="nested" />Nested<text:bookmark-end text:name="nested" /></text:h>
10111397<text:list text:style-name="L13">
10121398 <text:list-item>
10131399 <text:p text:style-name="P30">Tab</text:p><text:list text:style-name="L14">
@@ -1068,8 +1454,8 @@ paragraphs:</text:p>
10681454 <text:p text:style-name="P35">Third</text:p>
10691455 </text:list-item>
10701456</text:list>
1071−<text:h text:style-name="Heading_20_2" text:outline-level="2">Tabs and
1072−spaces</text:h>
1457+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="tabs-and-spaces" />Tabs
1458+and spaces<text:bookmark-end text:name="tabs-and-spaces" /></text:h>
10731459<text:list text:style-name="L20">
10741460 <text:list-item>
10751461 <text:p text:style-name="P37">this is a list item indented with
@@ -1089,8 +1475,8 @@ spaces</text:h>
10891475 </text:list>
10901476 </text:list-item>
10911477</text:list>
1092−<text:h text:style-name="Heading_20_2" text:outline-level="2">Fancy list
1093−markers</text:h>
1478+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="fancy-list-markers" />Fancy
1479+list markers<text:bookmark-end text:name="fancy-list-markers" /></text:h>
10941480<text:list text:style-name="L22">
10951481 <text:list-item>
10961482 <text:p text:style-name="P39">begins with 2</text:p>
@@ -1157,8 +1543,8 @@ item:</text:p>
11571543<text:p text:style-name="Text_20_body">M.A. 2007</text:p>
11581544<text:p text:style-name="Text_20_body">B. Williams</text:p>
11591545<text:p text:style-name="Horizontal_20_Line" />
1160−<text:h text:style-name="Heading_20_1" text:outline-level="1">Definition
1161−Lists</text:h>
1546+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="definition-lists" />Definition
1547+Lists<text:bookmark-end text:name="definition-lists" /></text:h>
11621548<text:p text:style-name="First_20_paragraph">Tight using spaces:</text:p>
11631549<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>
11641550<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>
@@ -1225,8 +1611,8 @@ fruit</text:p><text:list text:style-name="L25">
12251611 <text:p text:style-name="P44">sublist</text:p>
12261612 </text:list-item>
12271613</text:list>
1228−<text:h text:style-name="Heading_20_1" text:outline-level="1">HTML
1229−Blocks</text:h>
1614+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="html-blocks" />HTML
1615+Blocks<text:bookmark-end text:name="html-blocks" /></text:h>
12301616<text:p text:style-name="First_20_paragraph">Simple block on one
12311617line:</text:p>
12321618<text:p text:style-name="Text_20_body">foo</text:p>
@@ -1262,8 +1648,8 @@ spaces on the line:</text:p>
12621648<text:p text:style-name="P50">&lt;hr /&gt;</text:p>
12631649<text:p text:style-name="First_20_paragraph">Hr’s:</text:p>
12641650<text:p text:style-name="Horizontal_20_Line" />
1265−<text:h text:style-name="Heading_20_1" text:outline-level="1">Inline
1266−Markup</text:h>
1651+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="inline-markup" />Inline
1652+Markup<text:bookmark-end text:name="inline-markup" /></text:h>
12671653<text:p text:style-name="First_20_paragraph">This is
12681654<text:span text:style-name="T1">emphasized</text:span>, and so
12691655<text:span text:style-name="T1">is this</text:span>.</text:p>
@@ -1300,8 +1686,9 @@ H<text:span text:style-name="T8">many of them</text:span>O.</text:p>
13001686<text:p text:style-name="Text_20_body">These should not be superscripts or
13011687subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</text:p>
13021688<text:p text:style-name="Horizontal_20_Line" />
1303−<text:h text:style-name="Heading_20_1" text:outline-level="1">Smart quotes,
1304−ellipses, dashes</text:h>
1689+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="smart-quotes-ellipses-dashes" />Smart
1690+quotes, ellipses,
1691+dashes<text:bookmark-end text:name="smart-quotes-ellipses-dashes" /></text:h>
13051692<text:p text:style-name="First_20_paragraph">“Hello,” said the spider.
13061693“‘Shelob’ is my name.”</text:p>
13071694<text:p text:style-name="Text_20_body">‘A’, ‘B’, and ‘C’ are letters.</text:p>
@@ -1319,7 +1706,7 @@ five.</text:p>
131917061987–1999.</text:p>
13201707<text:p text:style-name="Text_20_body">Ellipses…and…and….</text:p>
13211708<text:p text:style-name="Horizontal_20_Line" />
1322−<text:h text:style-name="Heading_20_1" text:outline-level="1">LaTeX</text:h>
1709+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="latex" />LaTeX<text:bookmark-end text:name="latex" /></text:h>
13231710<text:list text:style-name="L26">
13241711 <text:list-item>
13251712 <text:p text:style-name="P51"></text:p>
@@ -1371,8 +1758,8 @@ five.</text:p>
13711758</text:list>
13721759<text:p text:style-name="First_20_paragraph">Here’s a LaTeX table:</text:p>
13731760<text:p text:style-name="Horizontal_20_Line" />
1374−<text:h text:style-name="Heading_20_1" text:outline-level="1">Special
1375−Characters</text:h>
1761+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="special-characters" />Special
1762+Characters<text:bookmark-end text:name="special-characters" /></text:h>
13761763<text:p text:style-name="First_20_paragraph">Here is some unicode:</text:p>
13771764<text:list text:style-name="L28">
13781765 <text:list-item>
@@ -1415,8 +1802,8 @@ it.</text:p>
14151802<text:p text:style-name="Text_20_body">Plus: +</text:p>
14161803<text:p text:style-name="Text_20_body">Minus: -</text:p>
14171804<text:p text:style-name="Horizontal_20_Line" />
1418−<text:h text:style-name="Heading_20_1" text:outline-level="1">Links</text:h>
1419−<text:h text:style-name="Heading_20_2" text:outline-level="2">Explicit</text:h>
1805+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="links" />Links<text:bookmark-end text:name="links" /></text:h>
1806+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="explicit" />Explicit<text:bookmark-end text:name="explicit" /></text:h>
14201807<text:p text:style-name="First_20_paragraph">Just a
14211808<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">URL</text:span></text:a>.</text:p>
14221809<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title"><text:span text:style-name="Definition">URL
@@ -1433,7 +1820,7 @@ and title</text:span></text:a></text:p>
14331820<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="mailto:nobody@nowhere.net" office:name=""><text:span text:style-name="Definition">Email
14341821link</text:span></text:a></text:p>
14351822<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="" office:name=""><text:span text:style-name="Definition">Empty</text:span></text:a>.</text:p>
1436−<text:h text:style-name="Heading_20_2" text:outline-level="2">Reference</text:h>
1823+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="reference" />Reference<text:bookmark-end text:name="reference" /></text:h>
14371824<text:p text:style-name="First_20_paragraph">Foo
14381825<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>
14391826<text:p text:style-name="Text_20_body">With
@@ -1453,8 +1840,8 @@ by itself should be a link.</text:p>
14531840<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with &quot;quotes&quot; inside"><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>
14541841<text:p text:style-name="Text_20_body">Foo
14551842<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>
1456−<text:h text:style-name="Heading_20_2" text:outline-level="2">With
1457−ampersands</text:h>
1843+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="with-ampersands" />With
1844+ampersands<text:bookmark-end text:name="with-ampersands" /></text:h>
14581845<text:p text:style-name="First_20_paragraph">Here’s a
14591846<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">link
14601847with an ampersand in the URL</text:span></text:a>.</text:p>
@@ -1467,7 +1854,7 @@ link</text:span></text:a>.</text:p>
14671854<text:p text:style-name="Text_20_body">Here’s an
14681855<text:a xlink:type="simple" xlink:href="/script?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">inline
14691856link in pointy braces</text:span></text:a>.</text:p>
1470−<text:h text:style-name="Heading_20_2" text:outline-level="2">Autolinks</text:h>
1857+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="autolinks" />Autolinks<text:bookmark-end text:name="autolinks" /></text:h>
14711858<text:p text:style-name="First_20_paragraph">With an ampersand:
14721859<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&amp;bar=2" office:name=""><text:span text:style-name="Definition">http://example.com/?foo=1&amp;bar=2</text:span></text:a></text:p>
14731860<text:list text:style-name="L29">
@@ -1489,16 +1876,16 @@ link in pointy braces</text:span></text:a>.</text:p>
14891876<text:span text:style-name="Source_Text">&lt;http://example.com/&gt;</text:span></text:p>
14901877<text:p text:style-name="P57">or here: &lt;http://example.com/&gt;</text:p>
14911878<text:p text:style-name="Horizontal_20_Line" />
1492−<text:h text:style-name="Heading_20_1" text:outline-level="1">Images</text:h>
1879+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="images" />Images<text:bookmark-end text:name="images" /></text:h>
14931880<text:p text:style-name="First_20_paragraph">From “Voyage dans la Lune” by
14941881Georges Melies (1902):</text:p>
14951882<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>
1496−<text:p text:style-name="FigureCaption">lalune</text:p>
1883+<text:p text:style-name="FigureCaption">Figure <text:sequence text:ref-name="refIllustration0" text:name="Illustration" text:formula="ooow:Illustration+1" style:num-format="1">1</text:sequence>: lalune</text:p>
14971884<text:p text:style-name="Text_20_body">Here is a movie
14981885<draw:frame draw:name="img2"><draw:image xlink:href="movie.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame>
14991886icon.</text:p>
15001887<text:p text:style-name="Horizontal_20_Line" />
1501−<text:h text:style-name="Heading_20_1" text:outline-level="1">Footnotes</text:h>
1888+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="footnotes" />Footnotes<text:bookmark-end text:name="footnotes" /></text:h>
15021889<text:p text:style-name="First_20_paragraph">Here is a footnote
15031890reference,<text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here
15041891is the footnote. It can go anywhere after the footnote reference. It need not
test/writer.org+4−4
@@ -584,7 +584,7 @@ Superscripts: a^{bc}d a^{/hello/} a^{hello there}.
584584Subscripts: H_{2}O, H_{23}O, H_{many of them}O.
585585
586586These should not be superscripts or subscripts, because of the unescaped
587−spaces: a\^b c\^d, a~b c~d.
587+spaces: a^b c^d, a~b c~d.
588588
589589--------------
590590
@@ -674,7 +674,7 @@ Backtick: `
674674
675675Asterisk: *
676676
677−Underscore: \_
677+Underscore: _
678678
679679Left brace: {
680680
@@ -724,7 +724,7 @@ Just a [[/url/][URL]].
724724
725725[[/url/][URL and title]]
726726
727−[[/url/with_underscore][with\_underscore]]
727+[[/url/with_underscore][with_underscore]]
728728
729729[[mailto:nobody@nowhere.net][Email link]]
730730
@@ -816,7 +816,7 @@ Here is a movie [[file:movie.jpg]] icon.
816816 :END:
817817
818818Here is a footnote reference,[fn:1] and another.[fn:2] This should /not/ be a
819−footnote reference, because it contains a space.[\^my note] Here is an inline
819+footnote reference, because it contains a space.[^my note] Here is an inline
820820note.[fn:3]
821821
822822#+BEGIN_QUOTE
test/writer.rst+14−68
@@ -385,53 +385,23 @@ HTML Blocks
385385
386386Simple block on one line:
387387
388−.. raw:: html
389−
390− <div>
391−
392−foo
388+.. container::
393389
394−.. raw:: html
395−
396− </div>
390+ foo
397391
398392And nested without indentation:
399393
400−.. raw:: html
401−
402− <div>
403−
404−.. raw:: html
405−
406− <div>
407−
408−.. raw:: html
409−
410− <div>
411−
412−foo
413−
414−.. raw:: html
415−
416− </div>
417−
418−.. raw:: html
419−
420− </div>
394+.. container::
421395
422−.. raw:: html
396+ .. container::
423397
424− <div>
398+ .. container::
425399
426−bar
400+ foo
427401
428−.. raw:: html
402+ .. container::
429403
430− </div>
431−
432−.. raw:: html
433−
434− </div>
404+ bar
435405
436406Interpreted markdown in a table:
437407
@@ -477,15 +447,9 @@ And this is **strong**
477447
478448Here’s a simple block:
479449
480−.. raw:: html
481−
482− <div>
483−
484−foo
485−
486−.. raw:: html
450+.. container::
487451
488− </div>
452+ foo
489453
490454This should be a code block, though:
491455
@@ -503,31 +467,13 @@ As should this:
503467
504468Now, nested:
505469
506−.. raw:: html
507−
508− <div>
470+.. container::
509471
510−.. raw:: html
472+ .. container::
511473
512− <div>
474+ .. container::
513475
514−.. raw:: html
515−
516− <div>
517−
518−foo
519−
520−.. raw:: html
521−
522− </div>
523−
524−.. raw:: html
525−
526− </div>
527−
528−.. raw:: html
529−
530− </div>
476+ foo
531477
532478This should just be an HTML comment:
533479
test/writer.tei+2−2
@@ -8,8 +8,8 @@
88 <author>Anonymous</author>
99 </titleStmt>
1010 <publicationStmt>
11− <p></p>
12− </publicationStmt>
11+ <date>July 17, 2006</date>
12+ </publicationStmt>
1313 <sourceDesc>
1414 <p>Produced by pandoc.</p>
1515 </sourceDesc>
test/writer.texinfo+2−22
@@ -5,24 +5,6 @@
55~~\text\~~
66@end macro
77
8−@macro textsubscript{text}
9−@iftex
10−@textsubscript{\text\}
11−@end iftex
12−@ifnottex
13−_@{\text\@}
14−@end ifnottex
15−@end macro
16−
17−@macro textsuperscript{text}
18−@iftex
19−@textsuperscript{\text\}
20−@end iftex
21−@ifnottex
22−^@{\text\@}
23−@end ifnottex
24−@end macro
25−
268@ifnottex
279@paragraphindent 0
2810@end ifnottex
@@ -738,11 +720,9 @@ This is code: @code{>}, @code{$}, @code{\}, @code{\$}, @code{<html>}.
738720
739721@textstrikeout{This is @emph{strikeout}.}
740722
741−Superscripts: a@textsuperscript{bc}d a@textsuperscript{@emph{hello}}
742−a@textsuperscript{hello@ there}.
723+Superscripts: a@sup{bc}d a@sup{@emph{hello}} a@sup{hello@ there}.
743724
744−Subscripts: H@textsubscript{2}O, H@textsubscript{23}O,
745−H@textsubscript{many@ of@ them}O.
725+Subscripts: H@sub{2}O, H@sub{23}O, H@sub{many@ of@ them}O.
746726
747727These should not be superscripts or subscripts, because of the unescaped
748728spaces: a^b c^d, a~b c~d.
test/writer.textile+1−1
@@ -660,7 +660,7 @@ With an ampersand: "$":http://example.com/?foo=1&bar=2
660660* "$":http://example.com/
661661* It should.
662662
663−An e&#45;mail address: "nobody&#64;nowhere.net":mailto:nobody@nowhere.net
663+An e&#45;mail address: "(email)nobody&#64;nowhere.net":mailto:nobody@nowhere.net
664664
665665bq. Blockquoted: "$":http://example.com/
666666
tools/changelog-helper.shnew file+23
@@ -0,0 +1,23 @@
1+#!/bin/sh
2+# generate preliminary list of changes since changelog
3+# was last modified
4+
5+lastmod=`git log -n2 --format=oneline changelog | awk '{print $1;}'`
6+#git log --format=oneline $starthash..HEAD
7+files=`git ls-tree -r master --name-only`
8+for x in $files
9+do
10+ commits=`git log -n1 $lastmod..HEAD $x`
11+ if [[ ! -z $commits ]]
12+ then
13+ if echo $x | grep -q "src\/.*\.hs"
14+ then
15+ file=`echo $x | sed -e 's/src\///' | sed -e 's/\//\./g' | sed -e 's/\.hs$//'`
16+ else
17+ file=$x
18+ fi
19+ echo " * $file"
20+ GIT_PAGER=cat git log --pretty=format:'%n%w(78,4,6)+ %s (%an)%n%n%w(78,6,6)%b%n' $lastmod..HEAD $x
21+ fi
22+done
23+
trypandoc/trypandoc.hs+1−1
@@ -25,7 +25,7 @@ main = run app
2525app :: Application
2626app req respond = do
2727 let query = queryToQueryText $ queryString req
28− let getParam x = maybe (error $ T.unpack x ++ " paramater not set")
28+ let getParam x = maybe (error $ T.unpack x ++ " parameter not set")
2929 return $ lookup x query
3030 text <- getParam "text" >>= checkLength . fromMaybe T.empty
3131 fromFormat <- fromMaybe "" <$> getParam "from"