git.iko.soy/typeable/pandoc
on ffd487e help sign in
40 files changed+737−467
since splitsnapshots
unifiedsplit
.github/workflows/ci.yml+4−10 .github/workflows/release-candidate.yml+2−1 AUTHORS.md+1 CONTRIBUTING.md+9−3 MANUAL.txt+39−49 Makefile+2−2 README.md+2−2 benchmark/benchmark-pandoc.hs+35−25 changelog.md+58−2 data/templates/default.latex+3 doc/lua-filters.md+4−4 doc/org.md+15−11 man/pandoc.1+111−25 pandoc.cabal+1 src/Text/Pandoc/Readers/DocBook.hs+2−1 src/Text/Pandoc/Readers/Docx.hs+44−49 src/Text/Pandoc/Readers/Docx/Combine.hs+39−62 src/Text/Pandoc/Readers/Docx/Parse.hs+3 src/Text/Pandoc/Readers/Docx/Parse/Styles.hs+12−6 src/Text/Pandoc/Readers/Markdown.hs+2−5 src/Text/Pandoc/Readers/Metadata.hs+23−36 src/Text/Pandoc/Readers/Org/Blocks.hs+15−1 src/Text/Pandoc/Readers/Org/ExportSettings.hs+3−3 src/Text/Pandoc/Readers/Org/Inlines.hs+17−6 src/Text/Pandoc/Readers/Org/Meta.hs+67−70 src/Text/Pandoc/Readers/Org/ParserState.hs+6 src/Text/Pandoc/Readers/RST.hs+4−3 src/Text/Pandoc/Writers/Jira.hs+12−10 src/Text/Pandoc/Writers/Ms.hs+8−6 test/Tests/Readers/Org/Directive.hs+30 test/Tests/Readers/Org/Meta.hs+110−72 test/Tests/Writers/Ms.hs+37 test/docx/golden/inline_formatting.docx test/docx/inline_formatting.native+1−1 test/lhs-test.latex+3 test/lhs-test.latex+lhs+3 test/test-pandoc.hs+2 test/writer.jira+2−2 test/writer.latex+3 test/writers-lang-and-dir.latex+3
.github/workflows/ci.yml+4−10
@@ -61,16 +61,10 @@ jobs:
6161 # need to install older cabal/ghc versions from ppa repository
6262
6363 - name: Install recent cabal/ghc
64− run: |
65− if [[ ! -d /opt/ghc/${{ matrix.versions.ghc }} ]]
66− then
67− sudo add-apt-repository ppa:hvr/ghc
68− sudo apt-get update
69− sudo apt-get install ghc-${{ matrix.versions.ghc }} cabal-install-${{ matrix.versions.cabal }}
70− fi
71− # Use a GitHub workflow command to add folders to PATH.
72− echo "::add-path::/opt/ghc/${{ matrix.versions.ghc }}/bin"
73− echo "::add-path::/opt/cabal/${{ matrix.versions.cabal }}/bin"
64+ uses: actions/setup-haskell@v1.1
65+ with:
66+ ghc-version: ${{ matrix.versions.ghc }}
67+ cabal-version: ${{ matrix.versions.cabal }}
7468
7569 # declare/restore cached things
7670 # caching doesn't work for scheduled runs yet
.github/workflows/release-candidate.yml+2−1
@@ -35,8 +35,9 @@ jobs:
3535 stack_opts: "-j1"
3636 - osarch: "windows-i386"
3737 arch: "x86"
38− choco_opts: "--x86"
38+ choco_opts: "--x86 --version 2.1.3.20190715"
3939 stack_opts: "-j1 --flag hslua:lua_32bits"
40+ # we use stack 2.1.3 because 2.3.1 doesn't support i386
4041
4142 steps:
4243 - uses: actions/checkout@v1
AUTHORS.md+1
@@ -241,6 +241,7 @@
241241- Urs Liska
242242- Václav Zeman
243243- Václav Haisman
244+- Vaibhav Sagar
244245- Vanessa McHale
245246- Vasily Alferov
246247- Viktor Kronvall
CONTRIBUTING.md+9−3
@@ -17,8 +17,14 @@ Before you submit a bug report, search the [open issues] *and* [closed issues]
1717to make sure the issue hasn't come up before. Also, check the [User's Guide] and
1818[FAQs] for anything relevant.
1919
20−Make sure you can reproduce the bug with the [latest released version] of pandoc
21−(or, even better, the [development version]).
20+Make sure you can reproduce the bug with the [latest released
21+version] of pandoc---or, even better, the development version,
22+since the bug may have been fixed since the last release.
23+[Nightly builds] are available, so you don't need to compile
24+from source to test againt the development version.
25+(To fetch a nightly, visit the link, click the topmost "Nightly"
26+in the table, then choose your platform under "Artifacts." Note
27+that you must be logged in with a GitHub account.)
2228
2329Your report should give detailed, *reproducible* instructions, including
2430
@@ -346,7 +352,7 @@ you may want to consider submitting a pull request to the
346352[open issues]: https://github.com/jgm/pandoc/issues
347353[closed issues]: https://github.com/jgm/pandoc/issues?q=is%3Aissue+is%3Aclosed
348354[latest released version]: https://github.com/jgm/pandoc/releases/latest
349−[development version]: https://github.com/pandoc-extras/pandoc-nightly/releases/latest
355+[Nightly builds]: https://github.com/jgm/pandoc/actions?query=workflow%3ANightly
350356[pandoc-discuss]: http://groups.google.com/group/pandoc-discuss
351357[issue tracker]: https://github.com/jgm/pandoc/issues
352358[User's Guide]: http://pandoc.org/MANUAL.html
MANUAL.txt+39−49
@@ -1,7 +1,7 @@
11---
22title: Pandoc User's Guide
33author: John MacFarlane
4−date: March 23, 2020
4+date: June 29, 2020
55---
66
77# Synopsis
@@ -902,7 +902,7 @@ header when requesting a document from a URL:
902902 downloaded). If you're behind a proxy, you also need to set
903903 the environment variable `http_proxy` to `http://...`.
904904
905−`--no-check-certificate
905+`--no-check-certificate`
906906
907907: Disable the certificate verification to allow access to
908908 unsecure HTTP resources (for example when the certificate
@@ -2767,53 +2767,43 @@ reading web pages formatted using MathJax, for example.
27672767
27682768## Raw HTML/TeX
27692769
2770−The following extensions (especially how they affect Markdown
2771−input/output) are also described in more detail in their respective
2772−sections of [Pandoc's Markdown].
2773−
2774−#### Extension: `raw_html` {#raw_html}
2775−
2776−When converting from HTML, parse elements to raw HTML which are not
2777−representable in pandoc's AST.
2778−By default, this is disabled for HTML input.
2779−
2780−#### Extension: `raw_tex` {#raw_tex}
2781−
2782−Allows raw LaTeX, TeX, and ConTeXt to be included in a document.
2783−
2784−This extension can be enabled/disabled for the following formats
2785−(in addition to `markdown`):
2786−
2787−input formats
2788−: `latex`, `org`, `textile`, `html` (environments, `\ref`, and
2789− `\eqref` only), `ipynb`
2790−
2791−output formats
2792−: `textile`, `commonmark`
2793−
2794−Note: as applied to `ipynb`, `raw_html` and `raw_tex` affect not
2795−only raw TeX in markdown cells, but data with mime type
2796−`text/html` in output cells. Since the `ipynb` reader attempts
2797−to preserve the richest possible outputs when several options
2798−are given, you will get best results if you disable `raw_html`
2799−and `raw_tex` when converting to formats like `docx` which don't
2800−allow raw `html` or `tex`.
2801−
2802−#### Extension: `native_divs` {#native_divs}
2803−
2804−This extension is enabled by default for HTML input. This means that
2805−`div`s are parsed to pandoc native elements. (Alternatively, you
2806−can parse them to raw HTML using `-f html-native_divs+raw_html`.)
2807−
2808−When converting HTML to Markdown, for example, you may want to drop all
2809−`div`s and `span`s:
2810−
2811− pandoc -f html-native_divs-native_spans -t markdown
2812−
2813−#### Extension: `native_spans` {#native_spans}
2814−
2815−Analogous to `native_divs` above.
2816−
2770+The following extensions are described in more detail in
2771+their respective sections of [Pandoc's Markdown]:
2772+
2773+- [`raw_html`](#extension-raw_html) allows HTML elements which
2774+ are not representable in pandoc's AST to be parsed as raw HTML.
2775+ By default, this is disabled for HTML input.
2776+
2777+- [`raw_tex`](#extension-raw_tex) allows raw LaTeX, TeX, and ConTeXt
2778+ to be included in a document. This extension can be enabled/disabled
2779+ for the following formats (in addition to `markdown`):
2780+
2781+ input formats
2782+ : `latex`, `org`, `textile`, `html` (environments, `\ref`, and
2783+ `\eqref` only), `ipynb`
2784+
2785+ output formats
2786+ : `textile`, `commonmark`
2787+
2788+ Note: as applied to `ipynb`, `raw_html` and `raw_tex` affect not
2789+ only raw TeX in markdown cells, but data with mime type
2790+ `text/html` in output cells. Since the `ipynb` reader attempts
2791+ to preserve the richest possible outputs when several options
2792+ are given, you will get best results if you disable `raw_html`
2793+ and `raw_tex` when converting to formats like `docx` which don't
2794+ allow raw `html` or `tex`.
2795+
2796+- [`native_divs`](#extension-native_divs) causes HTML `div`
2797+ elements to be parsed as native pandoc Div blocks.
2798+ If you want them to be parsed as raw HTML, use
2799+ `-f html-native_divs+raw_html`.
2800+
2801+- [`native_spans`](#extension-native_spans) causes HTML `span`
2802+ elements to be parsed as native pandoc Span inlines.
2803+ If you want them to be parsed as raw HTML, use
2804+ `-f html-native_spans+raw_html`. If you want to drop all
2805+ `div`s and `span`s when converting HTML to Markdown, you
2806+ can use `pandoc -f html-native_divs-native_spans -t markdown`.
28172807
28182808## Literate Haskell support
28192809
Makefile+2−2
@@ -123,9 +123,9 @@ download_stats:
123123
124124pandoc-templates:
125125 rm ../pandoc-templates/default.* ; \
126− cp data/templates/default.* README.md styles.* ../pandoc-templates/ ; \
126+ cp data/templates/default.* data/templates/README.markdown data/templates/styles.* ../pandoc-templates/ ; \
127127 pushd ../pandoc-templates/ && \
128− git add default.* README.md styles.* && \
128+ git add default.* README.markdown styles.* && \
129129 git commit -m "Updated templates for pandoc $(version)" && \
130130 popd
131131
README.md+2−2
@@ -50,7 +50,7 @@ library. It can convert *from*
5050 notebook](https://nbformat.readthedocs.io/en/latest/))
5151 - `jats` ([JATS](https://jats.nlm.nih.gov) XML)
5252 - `jira`
53− ([Jira](https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all)
53+ ([Jira](https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all)/Confluence
5454 wiki markup)
5555 - `json` (JSON version of native AST)
5656 - `latex` ([LaTeX](https://www.latex-project.org/))
@@ -124,7 +124,7 @@ It can convert *to*
124124 Publishing Tag Set)
125125 - `jats` (alias for `jats_archiving`)
126126 - `jira`
127− ([Jira](https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all)
127+ ([Jira](https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all)/Confluence
128128 wiki markup)
129129 - `json` (JSON version of native AST)
130130 - `latex` ([LaTeX](https://www.latex-project.org/))
benchmark/benchmark-pandoc.hs+35−25
@@ -1,6 +1,5 @@
11{-# LANGUAGE NoImplicitPrelude #-}
22{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE TupleSections #-}
43{-
54Copyright (C) 2012-2019 John MacFarlane <jgm@berkeley.edu>
65
@@ -21,39 +20,49 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2120import Prelude
2221import Text.Pandoc
2322import Text.Pandoc.MIME
24−import Text.Pandoc.Error (PandocError(..))
25−import Control.Monad.Except (throwError)
23+import Control.Monad.Except (throwError, liftIO)
2624import qualified Text.Pandoc.UTF8 as UTF8
2725import qualified Data.ByteString as B
2826import qualified Data.Text as T
2927import Criterion.Main
3028import Criterion.Types (Config(..))
3129import Data.List (intersect)
32−import Data.Maybe (mapMaybe)
30+import Data.Maybe (mapMaybe, catMaybes)
3331import System.Environment (getArgs)
3432import qualified Data.ByteString.Lazy as BL
3533
34+data Input = InputText {unInputText :: T.Text}
35+ | InputBS {unInputBS :: BL.ByteString}
36+
3637readerBench :: Pandoc
3738 -> T.Text
38− -> Maybe Benchmark
39−readerBench doc name =
40− case res of
41− Right (readerFun, inp) ->
42− Just $ bench (T.unpack $ name <> " reader")
43− $ nf (\i -> either (error . show) id $ runPure (readerFun i))
44− inp
45− Left _ -> Nothing
46− where res = runPure $ do
47− (rdr, rexts) <- getReader name
39+ -> IO (Maybe Benchmark)
40+readerBench doc name = do
41+ let (rdr, rexts) = either (error . show) id . runPure $ getReader name
42+ res <- runIO $ do
4843 (wtr, wexts) <- getWriter name
4944 case (rdr, wtr) of
5045 (TextReader r, TextWriter w) -> do
51− setResourcePath ["../test"]
46+ setResourcePath ["./test"]
5247 inp <- w def{ writerWrapText = WrapAuto
5348 , writerExtensions = wexts } doc
54− return $ (r def{ readerExtensions = rexts }, inp)
55− _ -> throwError $ PandocSomeError $ "not a text format: "
49+ return (r def{ readerExtensions = rexts } . unInputText, InputText inp)
50+ (ByteStringReader r, ByteStringWriter w) -> do
51+ setResourcePath ["./test"]
52+ tmpl <- Just <$> compileDefaultTemplate name
53+ inp <- w def{ writerWrapText = WrapAuto
54+ , writerExtensions = wexts
55+ , writerTemplate = tmpl } doc
56+ liftIO $ BL.writeFile "/tmp/test.odt" inp
57+ return (r def{ readerExtensions = rexts } . unInputBS, InputBS inp)
58+ _ -> throwError $ PandocSomeError $ "text/bytestring format mismatch: "
5659 <> name
60+ return $ case res of
61+ Right (readerFun, inp) ->
62+ Just $ bench (T.unpack $ name <> " reader")
63+ $ nf (\i -> either (error . show) id $ runPure (readerFun i))
64+ inp
65+ Left _ -> Nothing
5766
5867getImages :: IO [(FilePath, MimeType, BL.ByteString)]
5968getImages = do
@@ -89,22 +98,23 @@ main :: IO ()
8998main = do
9099 args <- filter (\x -> T.take 1 x /= "-") . fmap T.pack <$> getArgs
91100 print args
92− let matchReader (n, TextReader _) =
101+ let matchReader (n, _) =
93102 null args || ("reader" `elem` args && n `elem` args)
94− matchReader _ = False
95− let matchWriter (n, TextWriter _) =
103+ matchWriter (n, TextWriter _) =
96104 null args || ("writer" `elem` args && n `elem` args)
97105 matchWriter _ = False
98− let matchedReaders = map fst $ (filter matchReader readers
106+ allWriters = map fst (writers :: [(T.Text, Writer PandocPure)])
107+ matchedReaders = map fst (filter matchReader readers
99108 :: [(T.Text, Reader PandocPure)])
100− let matchedWriters = map fst $ (filter matchWriter writers
109+ matchedWriters = map fst (filter matchWriter writers
101110 :: [(T.Text, Writer PandocPure)])
102111 inp <- UTF8.toText <$> B.readFile "test/testsuite.txt"
103112 let opts = def
104113 let doc = either (error . show) id $ runPure $ readMarkdown opts inp
105− let readerBs = mapMaybe (readerBench doc)
106− $ filter (/="haddock")
107− (matchedReaders `intersect` matchedWriters)
114+ readerBs <- fmap catMaybes
115+ $ mapM (readerBench doc)
116+ $ filter (/="haddock")
117+ (matchedReaders `intersect` allWriters)
108118 -- we need the corresponding writer to generate
109119 -- input for the reader
110120 let writerBs = mapMaybe (writerBench doc) matchedWriters
changelog.md+58−2
@@ -1,6 +1,6 @@
11# Revision history for pandoc
22
3−## pandoc 2.10 (YYYY-MM-DD)
3+## pandoc 2.10 (2020-06-29)
44
55 * Use pandoc-types 1.21. This adds two things:
66
@@ -31,6 +31,12 @@
3131 `--no-check-certificate`, which disables certificate checking when
3232 resources are fetched by HTTP.
3333
34+ * Unify defaults and markdown metadata parsers (#6328, Nikolay
35+ Yakimov). Clean up code in Text.Pandoc.Readers.Metadata and
36+ properly handle errors in `yamlToMeta`. This fixes parsing
37+ of Boolean fields in metadata withinin defaults files and reduces
38+ code duplication.
39+
3440 * Docbook reader:
3541
3642 + Implement `<procedure>` (#6442, Mathieu Boespflug).
@@ -39,7 +45,11 @@
3945 + Implement `<replaceable>` (#6437, Mathieu Boespflug)
4046 + Map `<simplesect>` to unnumbered section (#6436, Mathieu Boespflug).
4147
42− * JATS reader: handle "label" element in section title (#6288).
48+ * JATS reader:
49+
50+ + Handle "label" element in section title (#6288).
51+ + Parse abstract element into metadata field of same name
52+ (#6480, Albert Krewinkel).
4353
4454 * Jira reader (Albert Krewinkel):
4555
@@ -80,6 +90,9 @@
8090 + Fix inline code in lists (#6284, Nikolay Yakimov).
8191 Previously inline code containing list markers was sometimes
8292 parsed incorrectly.
93+ + Don't require blank line after grid table (#6481).
94+ This allows grid tables to be enclosed in fenced divs with no
95+ intervening blank lines.
8396
8497 * LaTeX reader:
8598
@@ -93,6 +106,41 @@
93106 * Org reader (Albert Krewinkel):
94107
95108 + Recognize images with uppercase extensions (#6472).
109+ + Keep unknown keyword lines as raw org. The lines of unknown
110+ keywords, like `#+SOMEWORD: value` are no longer read as metadata,
111+ but kept as raw `org` blocks. This ensures that more information
112+ is retained when round-tripping org-mode files; additionally,
113+ this change makes it possible to support non-standard org
114+ extensions via filters.
115+ + Unify keyword handling. Handling of export settings and other
116+ keywords (like `#+LINK`) has been combined and unified.
117+ + Support `LATEX_HEADER_EXTRA` and `HTML_HEAD_EXTRA`
118+ settings. These export settings are treated like their non-extra
119+ counterparts, i.e., the values are added to the `header-includes`
120+ metadata list.
121+ + Allow multiple `#+SUBTITLE` export settings. The values of all
122+ lines are read as inlines and collected in the `subtitle`
123+ metadata field.
124+ + Read `#+INSTITUTE` values as text with markup. The value is
125+ stored in the `institute` metadata field and used in the
126+ default beamer presentation template.
127+ + The behavior of the `#+AUTHOR` and `#+KEYWORD` export
128+ settings has changed: Org now allows multiple such lines
129+ and adds a space between the contents of each line. Pandoc
130+ now always parses these settings as meta inlines; setting
131+ values are no longer treated as comma-separated lists.
132+ Note that a Lua filter can be used to restore the previous
133+ behavior.
134+ + Read description lines as inlines (#6485). `#+DESCRIPTION` lines
135+ are now treated as text with markup. If multiple such
136+ lines are given, then all lines are read and separated by soft
137+ linebreaks.
138+ + Honor tex export option (#4070). The `tex` export option can be set
139+ with `#+OPTION: tex:nil` and allows three settings:
140+ `t` (the default) causes LaTeX fragments to be parsed as TeX or added
141+ as raw TeX. `nil` removes all LaTeX fragments from the document.
142+ `verbatim` treats LaTeX as text.
143+
96144
97145 * RST reader:
98146
@@ -244,6 +292,7 @@
244292 + Use `--enable-local-file-access` in invoking `wkhtmltopdf` (#6474).
245293 `wkhtmltopdf` changed in recent versions to require this for
246294 access to local files. This fixes PDF via HTML5 with `--css`.
295+ + Send verbose output to stderr, not stdout (#6483).
247296
248297 * Text.Pandoc.MIME: Fix MIME type for TrueType fonts in EPUBs
249298 (#6464, Michael Reed).
@@ -317,6 +366,8 @@
317366
318367 * Remove unnecessary hlint ignores (#6341, Joseph C. Sible).
319368
369+ * Remove obsolete RelaxedPolyRec extension (#6487, Nikolay Yakimov).
370+
320371 * trypandoc improvements (Mike Tzou):
321372
322373 + Add standalone option to the command text (#6210).
@@ -335,6 +386,11 @@
335386 + Update links to reveal.js documentation (#6386, Salim B).
336387 + Separate adjacent verbatim code blocks (#6307, tom-audm).
337388
389+ * org.md:
390+
391+ + Document behavior of `smart` extension (#4387, Albert Krewinkel).
392+ + Describe all supported export options in detail.
393+
338394 * lua-filters.md:
339395
340396 + Fix description of BulletList Lua type (Levi Gruspe).
data/templates/default.latex+3
@@ -339,6 +339,9 @@ $if(babel-newcommands)$
339339$endif$
340340\fi
341341$endif$
342+\ifluatex
343+ \usepackage{selnolig} % disable illegal ligatures
344+\fi
342345$if(dir)$
343346\ifxetex
344347 % Load bidi as late as possible as it modifies e.g. graphicx
doc/lua-filters.md+4−4
@@ -138,7 +138,7 @@ elements.
138138
139139## Filters on element sequences
140140
141−For some filtering tasks, the it is necessary to know the order
141+For some filtering tasks, it is necessary to know the order
142142in which elements occur in the document. It is not enough then to
143143inspect a single element at a time.
144144
@@ -1127,7 +1127,7 @@ A [table cell]{#type-table-cell} is a list of blocks.
11271127
11281128*[Alignment]{#type-alignment}* is a string value indicating the
11291129horizontal alignment of a table column. `AlignLeft`,
1130−`AlignRight`, and `AlignCenter` leads cell content tob be
1130+`AlignRight`, and `AlignCenter` leads cell content to be
11311131left-aligned, right-aligned, and centered, respectively. The
11321132default alignment is `AlignDefault` (often equivalent to
11331133centered).
@@ -3035,7 +3035,7 @@ methods and convenience functions.
30353035[`pandoc.List:insert ([pos], value)`]{#pandoc.list:insert}
30363036
30373037: Inserts element `value` at position `pos` in list, shifting
3038− elements to the next-greater indix if necessary.
3038+ elements to the next-greater index if necessary.
30393039
30403040 This function is identical to
30413041 [`table.insert`](https://www.lua.org/manual/5.3/manual.html#6.6).
@@ -3082,7 +3082,7 @@ methods and convenience functions.
30823082 Parameters:
30833083
30843084 `pos`:
3085− : position of the list value that will be remove; defaults
3085+ : position of the list value that will be removed; defaults
30863086 to the index of the last element
30873087
30883088 Returns: the removed element
doc/org.md+15−11
@@ -14,13 +14,13 @@ The following export keywords are supported:
1414
1515- AUTHOR: comma-separated list of author(s); fully supported.
1616
17−- CREATOR: output generator; passed as metadata entry, but
18− ignored by most output formats.
17+- CREATOR: output generator; passed as plain-text metadata entry
18+ `creator`, but not used by any default templates.
1919
2020- DATE: creation or publication date; well supported by pandoc.
2121
22−- EMAIL: author email address; passed as metadata entry, but not
23− included in most output formats.
22+- EMAIL: author email address; passed as plain-text metadata
23+ field `email`, but not used by any default templates.
2424
2525- LANGUAGE: currently unsupported; use `#+LANG:` instead.
2626
@@ -51,11 +51,12 @@ occur.
5151
5252 Pandoc follows the LaTeX exporter in that it allows markup in
5353 the description. In contrast, the Org-mode HTML exporter treats
54− reads the description as plain text.
54+ the description as plain text.
5555
56−- LATEX_HEADER: arbitrary lines to add to the document's preamble.
57− Contrary to Org-mode, these lines are not inserted before the
58− hyperref settings, but close to the end of the preamble.
56+- LATEX\_HEADER and LATEX_HEADER_EXTRA: arbitrary lines to add to
57+ the document's preamble. Contrary to Org-mode, these lines are
58+ not inserted before the hyperref settings, but close to the end
59+ of the preamble.
5960
6061 The contents of this option are stored as a list of raw LaTeX
6162 lines in the `header-includes` metadata field.
@@ -74,10 +75,13 @@ occur.
7475
7576- SUBTITLE: the document's subtitle; fully supported.
7677
77−- HTML_HEAD: arbitrary lines to add to the HTML document's head;
78− fully supported.
78+ The content of this option is stored as inlines in the
79+ `subtitle` metadata field.
80+
81+- HTML\_HEAD and HTML\_HEAD\_EXTRA: arbitrary lines to add to the
82+ HTML document's head; fully supported.
7983
80− The contents of this option are stored as a list of raw HTML
84+ The contents of these options are stored as a list of raw HTML
8185 lines in the `header-includes` metadata field.
8286
8387Pandoc-specific options
man/pandoc.1+111−25
@@ -1,7 +1,7 @@
11.\"t
2−.\" Automatically generated by Pandoc 2.9.2
2+.\" Automatically generated by Pandoc 2.10
33.\"
4−.TH "Pandoc User\[aq]s Guide" "" "March 23, 2020" "pandoc 2.9.2.1" ""
4+.TH "Pandoc User\[aq]s Guide" "" "June 29, 2020" "pandoc 2.10" ""
55.hy
66.SH NAME
77pandoc - general markup converter
@@ -255,7 +255,7 @@ if you need extensions not supported in \f[C]gfm\f[R].
255255.IP \[bu] 2
256256\f[C]jats\f[R] (JATS XML)
257257.IP \[bu] 2
258−\f[C]jira\f[R] (Jira wiki markup)
258+\f[C]jira\f[R] (Jira/Confluence wiki markup)
259259.IP \[bu] 2
260260\f[C]json\f[R] (JSON version of native AST)
261261.IP \[bu] 2
@@ -352,7 +352,7 @@ HTML5/XHTML polyglot markup)
352352.IP \[bu] 2
353353\f[C]jats\f[R] (alias for \f[C]jats_archiving\f[R])
354354.IP \[bu] 2
355−\f[C]jira\f[R] (Jira wiki markup)
355+\f[C]jira\f[R] (Jira/Confluence wiki markup)
356356.IP \[bu] 2
357357\f[C]json\f[R] (JSON version of native AST)
358358.IP \[bu] 2
@@ -481,7 +481,6 @@ eval \[dq]$(pandoc --bash-completion)\[dq]
481481.TP
482482\f[B]\f[CB]--verbose\f[B]\f[R]
483483Give verbose debugging output.
484−Currently this only has an effect with PDF output.
485484.TP
486485\f[B]\f[CB]--quiet\f[B]\f[R]
487486Suppress warning messages.
@@ -936,6 +935,11 @@ making HTTP requests (for example, when a URL is given on the command
936935line, or when resources used in a document must be downloaded).
937936If you\[aq]re behind a proxy, you also need to set the environment
938937variable \f[C]http_proxy\f[R] to \f[C]http://...\f[R].
938+.TP
939+\[ga]--no-check-certificate
940+Disable the certificate verification to allow access to unsecure HTTP
941+resources (for example when the certificate is no longer valid or self
942+signed).
939943.SS Options affecting specific writers
940944.TP
941945\f[B]\f[CB]--self-contained\f[B]\f[R]
@@ -1366,7 +1370,8 @@ depending on the output format specified using \f[C]-t/--to\f[R]:
13661370\f[C]-t context\f[R]: \f[C]context\f[R]
13671371.IP \[bu] 2
13681372\f[C]-t html\f[R]: \f[C]wkhtmltopdf\f[R] (other options:
1369−\f[C]prince\f[R], \f[C]weasyprint\f[R])
1373+\f[C]prince\f[R], \f[C]weasyprint\f[R]; see print-css.rocks for a good
1374+introduction to PDF generation from HTML/CSS.)
13701375.IP \[bu] 2
13711376\f[C]-t ms\f[R]: \f[C]pdfroff\f[R]
13721377.RE
@@ -2053,20 +2058,30 @@ ${ endfor }
20532058.fi
20542059.SS Partials
20552060.PP
2056−Partials (subtemplates stored in different files) may be included using
2057−the syntax
2061+Partials (subtemplates stored in different files) may be included by
2062+using the name of the partial, followed by \f[C]()\f[R], for example:
2063+.IP
2064+.nf
2065+\f[C]
2066+${ styles() }
2067+\f[R]
2068+.fi
2069+.PP
2070+Partials will be sought in the directory containing the main template.
2071+The file name will be assumed to have the same extension as the main
2072+template if it lacks an extension.
2073+When calling the partial, the full name including file extension can
2074+also be used:
20582075.IP
20592076.nf
20602077\f[C]
2061−${ boilerplate() }
2078+${ styles.html() }
20622079\f[R]
20632080.fi
20642081.PP
2065−Partials will be sought in the directory containing the main template,
2066−and will be assumed to have the same extension as the main template if
2067−they lack an explicit extension.
2068−(If the partials are not found here, they will also be sought in the
2069−\f[C]templates\f[R] subdirectory of the user data directory.)
2082+(If a partial is not found in the directory of the template, it will
2083+also be sought in the \f[C]templates\f[R] subdirectory of the user data
2084+directory.)
20702085.PP
20712086Partials may optionally be applied to variables using a colon:
20722087.IP
@@ -2232,6 +2247,18 @@ for a textual value, number of elements for a map or array.
22322247\f[C]reverse\f[R]: Reverses a textual value or array, and has no effect
22332248on other values.
22342249.IP \[bu] 2
2250+\f[C]first\f[R]: Returns the first value of an array, if applied to a
2251+non-empty array; otherwise returns the original value.
2252+.IP \[bu] 2
2253+\f[C]last\f[R]: Returns the last value of an array, if applied to a
2254+non-empty array; otherwise returns the original value.
2255+.IP \[bu] 2
2256+\f[C]rest\f[R]: Returns all but the first value of an array, if applied
2257+to a non-empty array; otherwise returns the original value.
2258+.IP \[bu] 2
2259+\f[C]allbutlast\f[R]: Returns all but the last value of an array, if
2260+applied to a non-empty array; otherwise returns the original value.
2261+.IP \[bu] 2
22352262\f[C]chomp\f[R]: Removes trailing newlines (and breakable space).
22362263.IP \[bu] 2
22372264\f[C]nowrap\f[R]: Disables line wrapping on breakable spaces.
@@ -2398,7 +2425,8 @@ To turn off boolean flags that default to true in reveal.js, use
23982425\f[C]0\f[R].
23992426.TP
24002427\f[B]\f[CB]revealjs-url\f[B]\f[R]
2401−base URL for reveal.js documents (defaults to \f[C]reveal.js\f[R])
2428+base URL for reveal.js documents (defaults to
2429+\f[C]https://unpkg.com/reveal.js\[at]\[ha]4/\f[R])
24022430.TP
24032431\f[B]\f[CB]s5-url\f[B]\f[R]
24042432base URL for S5 documents (defaults to \f[C]s5/default\f[R])
@@ -3247,7 +3275,7 @@ This extension can be enabled/disabled for the following formats:
32473275.TP
32483276output formats
32493277\f[C]odt\f[R], \f[C]opendocument\f[R]
3250−.SS Extension: \f[C]styles\f[R]
3278+.SS Extension: \f[C]styles\f[R] {#ext-styles}
32513279.PP
32523280When converting from docx, read all docx styles as divs (for paragraph
32533281styles) and spans (for character styles) regardless of whether pandoc
@@ -4404,7 +4432,7 @@ orange|3.09
44044432.PP
44054433The cells of pipe tables cannot contain block elements like paragraphs
44064434and lists, and cannot span multiple lines.
4407−If a pipe table contains a row whose printable content is wider than the
4435+If a pipe table contains a row whose Markdown content is wider than the
44084436column width (see \f[C]--columns\f[R]), then the table will take up the
44094437full text width and the cell contents will wrap, with the relative cell
44104438widths determined by the number of dashes in the line separating the
@@ -4454,7 +4482,11 @@ no author, you need a blank line:
44544482\f[C]
44554483%
44564484% Author
4457−
4485+\f[R]
4486+.fi
4487+.IP
4488+.nf
4489+\f[C]
44584490% My title
44594491%
44604492% June 15, 2006
@@ -4479,9 +4511,17 @@ So, all of the following are equivalent:
44794511\f[C]
44804512% Author One
44814513 Author Two
4482−
4514+\f[R]
4515+.fi
4516+.IP
4517+.nf
4518+\f[C]
44834519% Author One; Author Two
4484−
4520+\f[R]
4521+.fi
4522+.IP
4523+.nf
4524+\f[C]
44854525% Author One;
44864526 Author Two
44874527\f[R]
@@ -5398,11 +5438,12 @@ For example:
53985438\f[R]
53995439.fi
54005440.IP \[bu] 2
5401−Dimensions are converted to inches for output in page-based formats like
5402−LaTeX.
5403−Dimensions are converted to pixels for output in HTML-like formats.
5404−Use the \f[C]--dpi\f[R] option to specify the number of pixels per inch.
5405−The default is 96dpi.
5441+Dimensions may be converted to a form that is compatible with the output
5442+format (for example, dimensions given in pixels will be converted to
5443+inches when converting HTML to LaTeX).
5444+Conversion between pixels and physical measurements is affected by the
5445+\f[C]--dpi\f[R] option (by default, 96 dpi is assumed, unless the image
5446+itself contains dpi information).
54065447.IP \[bu] 2
54075448The \f[C]%\f[R] unit is generally relative to some available space.
54085449For example the above example will render to the following.
@@ -6371,6 +6412,51 @@ contents...
63716412::::::::::::::
63726413\f[R]
63736414.fi
6415+.SS Additional columns attributes in beamer
6416+.PP
6417+The div containers with classes \f[C]columns\f[R] and \f[C]column\f[R]
6418+can optionally have an \f[C]align\f[R] attribute.
6419+The class \f[C]columns\f[R] can optionally have a \f[C]totalwidth\f[R]
6420+attribute or an \f[C]onlytextwidth\f[R] class.
6421+.IP
6422+.nf
6423+\f[C]
6424+:::::::::::::: {.columns align=center totalwidth=8em}
6425+::: {.column width=\[dq]40%\[dq]}
6426+contents...
6427+:::
6428+::: {.column width=\[dq]60%\[dq] align=bottom}
6429+contents...
6430+:::
6431+::::::::::::::
6432+\f[R]
6433+.fi
6434+.PP
6435+The \f[C]align\f[R] attributes on \f[C]columns\f[R] and \f[C]column\f[R]
6436+can be used with the values \f[C]top\f[R], \f[C]top-baseline\f[R],
6437+\f[C]center\f[R] and \f[C]bottom\f[R] to vertically align the columns.
6438+It defaults to \f[C]top\f[R] in \f[C]columns\f[R].
6439+.PP
6440+The \f[C]totalwidth\f[R] attribute limits the width of the columns to
6441+the given value.
6442+.IP
6443+.nf
6444+\f[C]
6445+:::::::::::::: {.columns align=top .onlytextwidth}
6446+::: {.column width=\[dq]40%\[dq] align=center}
6447+contents...
6448+:::
6449+::: {.column width=\[dq]60%\[dq]}
6450+contents...
6451+:::
6452+::::::::::::::
6453+\f[R]
6454+.fi
6455+.PP
6456+The class \f[C]onlytextwidth\f[R] sets the \f[C]totalwidth\f[R] to
6457+\f[C]\[rs]textwidth\f[R].
6458+.PP
6459+See Section 12.7 of the Beamer User\[aq]s Guide for more details.
63746460.SS Frame attributes in beamer
63756461.PP
63766462Sometimes it is necessary to add the LaTeX \f[C][fragile]\f[R] option to
pandoc.cabal+1
@@ -816,6 +816,7 @@ test-suite test-pandoc
816816 Tests.Writers.FB2
817817 Tests.Writers.Powerpoint
818818 Tests.Writers.OOXML
819+ Tests.Writers.Ms
819820 if os(windows)
820821 cpp-options: -D_WINDOWS
821822 default-language: Haskell2010
src/Text/Pandoc/Readers/DocBook.hs+2−1
@@ -360,7 +360,7 @@ List of all DocBook tags, with [x] indicating implemented,
360360[x] refsectioninfo - Meta-information for a refsection
361361[ ] refsynopsisdiv - A syntactic synopsis of the subject of the reference page
362362[ ] refsynopsisdivinfo - Meta-information for a RefSynopsisDiv
363−[x] releaseinfo - Information about a particular release of a document
363+[ ] releaseinfo - Information about a particular release of a document
364364[ ] remark - A remark (or comment) intended for presentation in a draft
365365 manuscript
366366[x] replaceable - Content that may or must be replaced by the user
@@ -608,6 +608,7 @@ addMetadataFromElement e = do
608608 addMetaField "author" e
609609 addMetaField "date" e
610610 addMetaField "release" e
611+ addMetaField "releaseinfo" e
611612 return mempty
612613 where addMetaField fieldname elt =
613614 case filterChildren (named fieldname) elt of
src/Text/Pandoc/Readers/Docx.hs+44−49
@@ -261,46 +261,43 @@ resolveDependentRunStyle rPr
261261 | otherwise = return rPr
262262
263263runStyleToTransform :: PandocMonad m => RunStyle -> DocxContext m (Inlines -> Inlines)
264−runStyleToTransform rPr
265− | Just sn <- getStyleName <$> rParentStyle rPr
266− , sn `elem` spansToKeep = do
267− transform <- runStyleToTransform rPr{rParentStyle = Nothing}
268− return $ spanWith ("", [normalizeToClassName sn], []) . transform
269− | Just s <- rParentStyle rPr = do
270− ei <- extraInfo spanWith s
271− transform <- runStyleToTransform rPr{rParentStyle = Nothing}
272− return $ ei . transform
273− | Just True <- isItalic rPr = do
274− transform <- runStyleToTransform rPr{isItalic = Nothing}
275− return $ emph . transform
276− | Just True <- isBold rPr = do
277− transform <- runStyleToTransform rPr{isBold = Nothing}
278− return $ strong . transform
279− | Just True <- isSmallCaps rPr = do
280− transform <- runStyleToTransform rPr{isSmallCaps = Nothing}
281− return $ smallcaps . transform
282− | Just True <- isStrike rPr = do
283− transform <- runStyleToTransform rPr{isStrike = Nothing}
284− return $ strikeout . transform
285− | Just True <- isRTL rPr = do
286− transform <- runStyleToTransform rPr{isRTL = Nothing}
287− return $ spanWith ("",[],[("dir","rtl")]) . transform
288− | Just False <- isRTL rPr = do
289− transform <- runStyleToTransform rPr{isRTL = Nothing}
290− inBidi <- asks docxInBidi
291− return $ if inBidi
292− then spanWith ("",[],[("dir","ltr")]) . transform
293− else transform
294− | Just SupScrpt <- rVertAlign rPr = do
295− transform <- runStyleToTransform rPr{rVertAlign = Nothing}
296− return $ superscript . transform
297− | Just SubScrpt <- rVertAlign rPr = do
298− transform <- runStyleToTransform rPr{rVertAlign = Nothing}
299− return $ subscript . transform
300− | Just "single" <- rUnderline rPr = do
301− transform <- runStyleToTransform rPr{rUnderline = Nothing}
302− return $ Pandoc.underline . transform
303− | otherwise = return id
264+runStyleToTransform rPr' = do
265+ opts <- asks docxOptions
266+ inBidi <- asks docxInBidi
267+ let styles = isEnabled Ext_styles opts
268+ ctl = (Just True == isRTL rPr') || (Just True == isForceCTL rPr')
269+ italic rPr | ctl = isItalicCTL rPr
270+ | otherwise = isItalic rPr
271+ bold rPr | ctl = isBoldCTL rPr
272+ | otherwise = isBold rPr
273+ go rPr
274+ | Just sn <- getStyleName <$> rParentStyle rPr
275+ , sn `elem` spansToKeep =
276+ spanWith ("", [normalizeToClassName sn], [])
277+ . go rPr{rParentStyle = Nothing}
278+ | styles, Just s <- rParentStyle rPr =
279+ spanWith (extraAttr s) . go rPr{rParentStyle = Nothing}
280+ | Just True <- italic rPr =
281+ emph . go rPr{isItalic = Nothing, isItalicCTL = Nothing}
282+ | Just True <- bold rPr =
283+ strong . go rPr{isBold = Nothing, isBoldCTL = Nothing}
284+ | Just True <- isSmallCaps rPr =
285+ smallcaps . go rPr{isSmallCaps = Nothing}
286+ | Just True <- isStrike rPr =
287+ strikeout . go rPr{isStrike = Nothing}
288+ | Just True <- isRTL rPr =
289+ spanWith ("",[],[("dir","rtl")]) . go rPr{isRTL = Nothing}
290+ | inBidi, Just False <- isRTL rPr =
291+ spanWith ("",[],[("dir","ltr")]) . go rPr{isRTL = Nothing}
292+ | Just SupScrpt <- rVertAlign rPr =
293+ superscript . go rPr{rVertAlign = Nothing}
294+ | Just SubScrpt <- rVertAlign rPr = do
295+ subscript . go rPr{rVertAlign = Nothing}
296+ | Just "single" <- rUnderline rPr = do
297+ Pandoc.underline . go rPr{rUnderline = Nothing}
298+ | otherwise = id
299+ return $ go rPr'
300+
304301
305302runToInlines :: PandocMonad m => Run -> DocxContext m Inlines
306303runToInlines (Run rs runElems)
@@ -512,13 +509,8 @@ trimSps (Many ils) = Many $ Seq.dropWhileL isSp $Seq.dropWhileR isSp ils
512509 isSp LineBreak = True
513510 isSp _ = False
514511
515−extraInfo :: (Eq (StyleName a), PandocMonad m, HasStyleName a)
516− => (Attr -> i -> i) -> a -> DocxContext m (i -> i)
517−extraInfo f s = do
518− opts <- asks docxOptions
519− return $ if isEnabled Ext_styles opts
520− then f ("", [], [("custom-style", fromStyleName $ getStyleName s)])
521− else id
512+extraAttr :: (Eq (StyleName a), HasStyleName a) => a -> Attr
513+extraAttr s = ("", [], [("custom-style", fromStyleName $ getStyleName s)])
522514
523515parStyleToTransform :: PandocMonad m => ParagraphStyle -> DocxContext m (Blocks -> Blocks)
524516parStyleToTransform pPr = case pStyle pPr of
@@ -534,8 +526,11 @@ parStyleToTransform pPr = case pStyle pPr of
534526 | otherwise -> do
535527 let pPr' = pPr { pStyle = cs }
536528 transform <- parStyleToTransform pPr'
537− ei <- extraInfo divWith c
538− return $ ei . (if isBlockQuote c then blockQuote else id) . transform
529+ styles <- asks (isEnabled Ext_styles . docxOptions)
530+ return $
531+ (if styles then divWith (extraAttr c) else id)
532+ . (if isBlockQuote c then blockQuote else id)
533+ . transform
539534 []
540535 | Just left <- indentation pPr >>= leftParIndent -> do
541536 let pPr' = pPr { indentation = Nothing }
src/Text/Pandoc/Readers/Docx/Combine.hs+39−62
@@ -1,10 +1,9 @@
1−{-# LANGUAGE FlexibleInstances #-}
2−{-# LANGUAGE PatternGuards #-}
31{-# LANGUAGE OverloadedStrings #-}
42{- |
53 Module : Text.Pandoc.Readers.Docx.Combine
64 Copyright : © 2014-2020 Jesse Rosenthal <jrosenthal@jhu.edu>,
7− 2014-2020 John MacFarlane <jgm@berkeley.edu>
5+ 2014-2020 John MacFarlane <jgm@berkeley.edu>,
6+ 2020 Nikolay Yakimov <root@livid.pp.ru>
87 License : GNU GPL, version 2 or above
98
109 Maintainer : Jesse Rosenthal <jrosenthal@jhu.edu>
@@ -59,79 +58,61 @@ module Text.Pandoc.Readers.Docx.Combine ( smushInlines
5958 where
6059
6160import Data.List
62−import Data.Sequence (ViewL (..), ViewR (..), viewl, viewr, (><), (|>))
63−import qualified Data.Sequence as Seq (null)
61+import Data.Bifunctor
62+import Data.Sequence ( ViewL (..), ViewR (..), viewl, viewr, spanr, spanl
63+ , (><), (|>) )
6464import Text.Pandoc.Builder
6565
6666data Modifier a = Modifier (a -> a)
6767 | AttrModifier (Attr -> a -> a) Attr
68− | NullModifier
6968
7069spaceOutInlinesL :: Inlines -> (Inlines, Inlines)
7170spaceOutInlinesL ms = (l, stackInlines fs (m' <> r))
72− where (l, m, r) = spaceOutInlines ms
73− (fs, m') = unstackInlines m
71+ where (l, (fs, m'), r) = spaceOutInlines ms
7472
7573spaceOutInlinesR :: Inlines -> (Inlines, Inlines)
7674spaceOutInlinesR ms = (stackInlines fs (l <> m'), r)
77− where (l, m, r) = spaceOutInlines ms
78− (fs, m') = unstackInlines m
75+ where (l, (fs, m'), r) = spaceOutInlines ms
7976
80−spaceOutInlines :: Inlines -> (Inlines, Inlines, Inlines)
77+spaceOutInlines :: Inlines -> (Inlines, ([Modifier Inlines], Inlines), Inlines)
8178spaceOutInlines ils =
8279 let (fs, ils') = unstackInlines ils
83− contents = unMany ils'
84− left = case viewl contents of
85− (Space :< _) -> space
86− _ -> mempty
87− right = case viewr contents of
88− (_ :> Space) -> space
89− _ -> mempty in
90− (left, stackInlines fs $ trimInlines . Many $ contents, right)
80+ (left, (right, contents')) = second (spanr isSpace) $ spanl isSpace $ unMany ils'
81+ -- NOTE: spanr counterintuitively returns suffix as the FIRST tuple element
82+ in (Many left, (fs, Many contents'), Many right)
83+
84+isSpace :: Inline -> Bool
85+isSpace Space = True
86+isSpace SoftBreak = True
87+isSpace _ = False
9188
9289stackInlines :: [Modifier Inlines] -> Inlines -> Inlines
9390stackInlines [] ms = ms
94−stackInlines (NullModifier : fs) ms = stackInlines fs ms
9591stackInlines (Modifier f : fs) ms =
96− if isEmpty ms
92+ if null ms
9793 then stackInlines fs ms
9894 else f $ stackInlines fs ms
9995stackInlines (AttrModifier f attr : fs) ms = f attr $ stackInlines fs ms
10096
10197unstackInlines :: Inlines -> ([Modifier Inlines], Inlines)
102−unstackInlines ms = case ilModifier ms of
103− NullModifier -> ([], ms)
104− _ -> (f : fs, ms') where
105− f = ilModifier ms
106− (fs, ms') = unstackInlines $ ilInnards ms
107−
108−ilModifier :: Inlines -> Modifier Inlines
109−ilModifier ils = case viewl (unMany ils) of
110− (x :< xs) | Seq.null xs -> case x of
111− (Emph _) -> Modifier emph
112− (Strong _) -> Modifier strong
113− (SmallCaps _) -> Modifier smallcaps
114− (Strikeout _) -> Modifier strikeout
115− (Superscript _) -> Modifier superscript
116− (Subscript _) -> Modifier subscript
117− (Link attr _ tgt) -> Modifier $ linkWith attr (fst tgt) (snd tgt)
118− (Span attr _) -> AttrModifier spanWith attr
119− _ -> NullModifier
120− _ -> NullModifier
121−
122−ilInnards :: Inlines -> Inlines
123−ilInnards ils = case viewl (unMany ils) of
124− (x :< xs) | Seq.null xs -> case x of
125− (Emph lst) -> fromList lst
126− (Strong lst) -> fromList lst
127− (SmallCaps lst) -> fromList lst
128− (Strikeout lst) -> fromList lst
129− (Superscript lst) -> fromList lst
130− (Subscript lst) -> fromList lst
131− (Link _ lst _) -> fromList lst
132− (Span _ lst) -> fromList lst
133− _ -> ils
134− _ -> ils
98+unstackInlines ms = case ilModifierAndInnards ms of
99+ Nothing -> ([], ms)
100+ Just (f, inner) -> first (f :) $ unstackInlines inner
101+
102+ilModifierAndInnards :: Inlines -> Maybe (Modifier Inlines, Inlines)
103+ilModifierAndInnards ils = case viewl $ unMany ils of
104+ x :< xs | null xs -> second fromList <$> case x of
105+ Emph lst -> Just (Modifier emph, lst)
106+ Strong lst -> Just (Modifier strong, lst)
107+ SmallCaps lst -> Just (Modifier smallcaps, lst)
108+ Strikeout lst -> Just (Modifier strikeout, lst)
109+ Underline lst -> Just (Modifier underline, lst)
110+ Superscript lst -> Just (Modifier superscript, lst)
111+ Subscript lst -> Just (Modifier subscript, lst)
112+ Link attr lst tgt -> Just (Modifier $ linkWith attr (fst tgt) (snd tgt), lst)
113+ Span attr lst -> Just (AttrModifier spanWith attr, lst)
114+ _ -> Nothing
115+ _ -> Nothing
135116
136117inlinesL :: Inlines -> (Inlines, Inlines)
137118inlinesL ils = case viewl $ unMany ils of
@@ -161,12 +142,12 @@ combineSingletonInlines x y =
161142 y_rem_attr = filter isAttrModifier y_remaining
162143 in
163144 case null shared of
164− True | isEmpty xs && isEmpty ys ->
165− stackInlines (x_rem_attr ++ y_rem_attr) mempty
166− | isEmpty xs ->
145+ True | null xs && null ys ->
146+ stackInlines (x_rem_attr <> y_rem_attr) mempty
147+ | null xs ->
167148 let (sp, y') = spaceOutInlinesL y in
168149 stackInlines x_rem_attr mempty <> sp <> y'
169− | isEmpty ys ->
150+ | null ys ->
170151 let (x', sp) = spaceOutInlinesR x in
171152 x' <> sp <> stackInlines y_rem_attr mempty
172153 | otherwise ->
@@ -193,12 +174,8 @@ combineBlocks bs cs = bs <> cs
193174instance (Monoid a, Eq a) => Eq (Modifier a) where
194175 (Modifier f) == (Modifier g) = f mempty == g mempty
195176 (AttrModifier f attr) == (AttrModifier g attr') = f attr mempty == g attr' mempty
196− NullModifier == NullModifier = True
197177 _ == _ = False
198178
199−isEmpty :: (Monoid a, Eq a) => a -> Bool
200−isEmpty x = x == mempty
201−
202179isAttrModifier :: Modifier a -> Bool
203180isAttrModifier (AttrModifier _ _) = True
204181isAttrModifier _ = False
src/Text/Pandoc/Readers/Docx/Parse.hs+3
@@ -259,10 +259,13 @@ newtype Cell = Cell [BodyPart]
259259leftBiasedMergeRunStyle :: RunStyle -> RunStyle -> RunStyle
260260leftBiasedMergeRunStyle a b = RunStyle
261261 { isBold = isBold a <|> isBold b
262+ , isBoldCTL = isBoldCTL a <|> isBoldCTL b
262263 , isItalic = isItalic a <|> isItalic b
264+ , isItalicCTL = isItalicCTL a <|> isItalicCTL b
263265 , isSmallCaps = isSmallCaps a <|> isSmallCaps b
264266 , isStrike = isStrike a <|> isStrike b
265267 , isRTL = isRTL a <|> isRTL b
268+ , isForceCTL = isForceCTL a <|> isForceCTL b
266269 , rVertAlign = rVertAlign a <|> rVertAlign b
267270 , rUnderline = rUnderline a <|> rUnderline b
268271 , rParentStyle = rParentStyle a
src/Text/Pandoc/Readers/Docx/Parse/Styles.hs+12−6
@@ -44,7 +44,6 @@ module Text.Pandoc.Readers.Docx.Parse.Styles (
4444 ) where
4545import Codec.Archive.Zip
4646import Control.Applicative ((<|>))
47−import Control.Monad.Except
4847import Data.Function (on)
4948import Data.String (IsString(..))
5049import qualified Data.Map as M
@@ -101,10 +100,13 @@ data CharStyle = CharStyle { cStyleId :: CharStyleId
101100 } deriving (Show)
102101
103102data RunStyle = RunStyle { isBold :: Maybe Bool
103+ , isBoldCTL :: Maybe Bool
104104 , isItalic :: Maybe Bool
105+ , isItalicCTL :: Maybe Bool
105106 , isSmallCaps :: Maybe Bool
106107 , isStrike :: Maybe Bool
107108 , isRTL :: Maybe Bool
109+ , isForceCTL :: Maybe Bool
108110 , rVertAlign :: Maybe VertAlign
109111 , rUnderline :: Maybe String
110112 , rParentStyle :: Maybe CharStyle
@@ -121,10 +123,13 @@ data ParStyle = ParStyle { headingLev :: Maybe (ParaStyleName, Int)
121123
122124defaultRunStyle :: RunStyle
123125defaultRunStyle = RunStyle { isBold = Nothing
126+ , isBoldCTL = Nothing
124127 , isItalic = Nothing
128+ , isItalicCTL = Nothing
125129 , isSmallCaps = Nothing
126130 , isStrike = Nothing
127131 , isRTL = Nothing
132+ , isForceCTL = Nothing
128133 , rVertAlign = Nothing
129134 , rUnderline = Nothing
130135 , rParentStyle = Nothing
@@ -240,20 +245,21 @@ elemToCharStyle :: NameSpaces
240245elemToCharStyle ns element parentStyle
241246 = CharStyle <$> (CharStyleId <$> findAttrTextByName ns "w" "styleId" element)
242247 <*> getElementStyleName ns element
243− <*> (Just $ elemToRunStyle ns element parentStyle)
248+ <*> Just (elemToRunStyle ns element parentStyle)
244249
245250elemToRunStyle :: NameSpaces -> Element -> Maybe CharStyle -> RunStyle
246251elemToRunStyle ns element parentStyle
247252 | Just rPr <- findChildByName ns "w" "rPr" element =
248253 RunStyle
249254 {
250− isBold = checkOnOff ns rPr (elemName ns "w" "b") `mplus`
251− checkOnOff ns rPr (elemName ns "w" "bCs")
252− , isItalic = checkOnOff ns rPr (elemName ns "w" "i") `mplus`
253− checkOnOff ns rPr (elemName ns "w" "iCs")
255+ isBold = checkOnOff ns rPr (elemName ns "w" "b")
256+ , isBoldCTL = checkOnOff ns rPr (elemName ns "w" "bCs")
257+ , isItalic = checkOnOff ns rPr (elemName ns "w" "i")
258+ , isItalicCTL = checkOnOff ns rPr (elemName ns "w" "iCs")
254259 , isSmallCaps = checkOnOff ns rPr (elemName ns "w" "smallCaps")
255260 , isStrike = checkOnOff ns rPr (elemName ns "w" "strike")
256261 , isRTL = checkOnOff ns rPr (elemName ns "w" "rtl")
262+ , isForceCTL = checkOnOff ns rPr (elemName ns "w" "cs")
257263 , rVertAlign =
258264 findChildByName ns "w" "vertAlign" rPr >>=
259265 findAttrByName ns "w" "val" >>=
src/Text/Pandoc/Readers/Markdown.hs+2−5
@@ -67,16 +67,13 @@ yamlToMeta :: PandocMonad m
6767 -> m Meta
6868yamlToMeta opts bstr = do
6969 let parser = do
70− meta <- yamlBsToMeta (asBlocks <$> parseBlocks) bstr
70+ meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
7171 return $ runF meta defaultParserState
7272 parsed <- readWithM parser def{ stateOptions = opts } ""
7373 case parsed of
7474 Right result -> return result
7575 Left e -> throwError e
7676
77−asBlocks :: Functor f => f (B.Many Block) -> f MetaValue
78−asBlocks p = MetaBlocks . B.toList <$> p
79−
8077--
8178-- Constants and data structure definitions
8279--
@@ -241,7 +238,7 @@ yamlMetaBlock = try $ do
241238 -- by including --- and ..., we allow yaml blocks with just comments:
242239 let rawYaml = T.unlines ("---" : (rawYamlLines ++ ["..."]))
243240 optional blanklines
244− newMetaF <- yamlBsToMeta (asBlocks <$> parseBlocks)
241+ newMetaF <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks)
245242 $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
246243 -- Since `<>` is left-biased, existing values are not touched:
247244 updateState $ \st -> st{ stateMeta' = stateMeta' st <> newMetaF }
src/Text/Pandoc/Readers/Metadata.hs+23−36
@@ -1,4 +1,3 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
21{-# LANGUAGE OverloadedStrings #-}
32{- |
43 Module : Text.Pandoc.Readers.Metadata
@@ -21,7 +20,6 @@ import Data.Text (Text)
2120import qualified Data.Text as T
2221import qualified Data.YAML as YAML
2322import qualified Data.YAML.Event as YE
24−import qualified Text.Pandoc.Builder as B
2523import Text.Pandoc.Class.PandocMonad (PandocMonad (..))
2624import Text.Pandoc.Definition
2725import Text.Pandoc.Error
@@ -33,11 +31,11 @@ yamlBsToMeta :: PandocMonad m
3331 => ParserT Text ParserState m (F MetaValue)
3432 -> BL.ByteString
3533 -> ParserT Text ParserState m (F Meta)
36−yamlBsToMeta pBlocks bstr = do
34+yamlBsToMeta pMetaValue bstr = do
3735 pos <- getPosition
3836 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
3937 Right (YAML.Doc (YAML.Mapping _ _ o):_)
40− -> fmap Meta <$> yamlMap pBlocks o
38+ -> fmap Meta <$> yamlMap pMetaValue o
4139 Right [] -> return . return $ mempty
4240 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
4341 -> return . return $ mempty
@@ -57,30 +55,21 @@ nodeToKey (YAML.Scalar _ (YAML.SUnknown _ t)) = return t
5755nodeToKey _ = throwError $ PandocParseError
5856 "Non-string key in YAML mapping"
5957
60−toMetaValue :: PandocMonad m
61− => ParserT Text ParserState m (F MetaValue)
62− -> Text
63− -> ParserT Text ParserState m (F MetaValue)
64−toMetaValue pBlocks x =
58+normalizeMetaValue :: PandocMonad m
59+ => ParserT Text ParserState m (F MetaValue)
60+ -> Text
61+ -> ParserT Text ParserState m (F MetaValue)
62+normalizeMetaValue pMetaValue x =
6563 -- Note: a standard quoted or unquoted YAML value will
6664 -- not end in a newline, but a "block" set off with
6765 -- `|` or `>` will.
6866 if "\n" `T.isSuffixOf` x
69− then parseFromString' pBlocks (x <> "\n")
70− else parseFromString' pInlines x
71− where pInlines = do
72− bs <- pBlocks
73− return $ do
74− bs' <- bs
75− return $
76− case bs' of
77− MetaBlocks bs'' ->
78− case bs'' of
79− [Plain ils] -> MetaInlines ils
80− [Para ils] -> MetaInlines ils
81− xs -> MetaBlocks xs
82− _ -> bs'
83−
67+ then parseFromString' pMetaValue (x <> "\n")
68+ else parseFromString' asInlines x
69+ where asInlines = fmap b2i <$> pMetaValue
70+ b2i (MetaBlocks [Plain ils]) = MetaInlines ils
71+ b2i (MetaBlocks [Para ils]) = MetaInlines ils
72+ b2i bs = bs
8473
8574checkBoolean :: Text -> Maybe Bool
8675checkBoolean t
@@ -92,32 +81,30 @@ yamlToMetaValue :: PandocMonad m
9281 => ParserT Text ParserState m (F MetaValue)
9382 -> YAML.Node YE.Pos
9483 -> ParserT Text ParserState m (F MetaValue)
95−yamlToMetaValue pBlocks (YAML.Scalar _ x) =
84+yamlToMetaValue pMetaValue (YAML.Scalar _ x) =
9685 case x of
97− YAML.SStr t -> toMetaValue pBlocks t
86+ YAML.SStr t -> normalizeMetaValue pMetaValue t
9887 YAML.SBool b -> return $ return $ MetaBool b
9988 YAML.SFloat d -> return $ return $ MetaString $ tshow d
10089 YAML.SInt i -> return $ return $ MetaString $ tshow i
10190 YAML.SUnknown _ t ->
10291 case checkBoolean t of
10392 Just b -> return $ return $ MetaBool b
104− Nothing -> toMetaValue pBlocks t
93+ Nothing -> normalizeMetaValue pMetaValue t
10594 YAML.SNull -> return $ return $ MetaString ""
10695
107−yamlToMetaValue pBlocks (YAML.Sequence _ _ xs) = do
108− xs' <- mapM (yamlToMetaValue pBlocks) xs
109− return $ do
110− xs'' <- sequence xs'
111− return $ B.toMetaValue xs''
112−yamlToMetaValue pBlocks (YAML.Mapping _ _ o) =
113− fmap B.toMetaValue <$> yamlMap pBlocks o
96+yamlToMetaValue pMetaValue (YAML.Sequence _ _ xs) =
97+ fmap MetaList . sequence
98+ <$> mapM (yamlToMetaValue pMetaValue) xs
99+yamlToMetaValue pMetaValue (YAML.Mapping _ _ o) =
100+ fmap MetaMap <$> yamlMap pMetaValue o
114101yamlToMetaValue _ _ = return $ return $ MetaString ""
115102
116103yamlMap :: PandocMonad m
117104 => ParserT Text ParserState m (F MetaValue)
118105 -> M.Map (YAML.Node YE.Pos) (YAML.Node YE.Pos)
119106 -> ParserT Text ParserState m (F (M.Map Text MetaValue))
120−yamlMap pBlocks o = do
107+yamlMap pMetaValue o = do
121108 kvs <- forM (M.toList o) $ \(key, v) -> do
122109 k <- nodeToKey key
123110 return (k, v)
@@ -126,7 +113,7 @@ yamlMap pBlocks o = do
126113 where
127114 ignorable t = "_" `T.isSuffixOf` t
128115 toMeta (k, v) = do
129− fv <- yamlToMetaValue pBlocks v
116+ fv <- yamlToMetaValue pMetaValue v
130117 return $ do
131118 v' <- fv
132119 return (k, v')
src/Text/Pandoc/Readers/Org/Blocks.hs+15−1
@@ -76,6 +76,7 @@ block = choice [ mempty <$ blanklines
7676 , list
7777 , latexFragment
7878 , noteBlock
79+ , rawOrgLine
7980 , paraOrPlain
8081 ] <?> "block"
8182
@@ -559,6 +560,8 @@ include = try $ do
559560 | otherwise -> Para content
560561 _ -> blk
561562
563+-- | Parses a meta line which defines a raw block. Currently recognized:
564+-- @#+LATEX:@, @#+HTML:@, @#+TEXINFO:@, and @#+BEAMER@.
562565rawExportLine :: PandocMonad m => OrgParser m Blocks
563566rawExportLine = try $ do
564567 metaLineStart
@@ -567,6 +570,14 @@ rawExportLine = try $ do
567570 then B.rawBlock key <$> anyLine
568571 else mzero
569572
573+-- | Parses any meta line, i.e., a line starting with @#+@, into a raw
574+-- org block. This should be the last resort when trying to parse
575+-- keywords. Leading spaces are discarded.
576+rawOrgLine :: PandocMonad m => OrgParser m (F Blocks)
577+rawOrgLine = do
578+ line <- metaLineStart *> anyLine
579+ returnF $ B.rawBlock "org" $ ("#+" <> line)
580+
570581commentLine :: Monad m => OrgParser m Blocks
571582commentLine = commentLineStart *> anyLine *> pure mempty
572583
@@ -597,7 +608,10 @@ data OrgTable = OrgTable
597608 }
598609
599610table :: PandocMonad m => OrgParser m (F Blocks)
600−table = gridTableWith blocks True <|> orgTable
611+table = do
612+ withTables <- getExportSetting exportWithTables
613+ tbl <- gridTableWith blocks True <|> orgTable
614+ return $ if withTables then tbl else mempty
601615
602616-- | A normal org table
603617orgTable :: PandocMonad m => OrgParser m (F Blocks)
src/Text/Pandoc/Readers/Org/ExportSettings.hs+3−3
@@ -47,9 +47,9 @@ exportSetting = choice
4747 , booleanSetting "creator" (\val es -> es { exportWithCreator = val })
4848 , complementableListSetting "d" (\val es -> es { exportDrawers = val })
4949 , ignoredSetting "date"
50− , ignoredSetting "e"
50+ , booleanSetting "e" (\val es -> es { exportWithEntities = val })
5151 , booleanSetting "email" (\val es -> es { exportWithEmail = val })
52− , ignoredSetting "f"
52+ , booleanSetting "f" (\val es -> es { exportWithFootnotes = val })
5353 , integerSetting "H" (\val es -> es { exportHeadlineLevels = val })
5454 , ignoredSetting "inline"
5555 , ignoredSetting "num"
@@ -64,7 +64,7 @@ exportSetting = choice
6464 , ignoredSetting "title"
6565 , ignoredSetting "toc"
6666 , booleanSetting "todo" (\val es -> es { exportWithTodoKeywords = val })
67− , ignoredSetting "|"
67+ , booleanSetting "|" (\val es -> es { exportWithTables = val })
6868 , ignoreAndWarn
6969 ] <?> "export setting"
7070
src/Text/Pandoc/Readers/Org/Inlines.hs+17−6
@@ -378,7 +378,10 @@ citation = try $ do
378378 else rest
379379
380380footnote :: PandocMonad m => OrgParser m (F Inlines)
381−footnote = try $ inlineNote <|> referencedNote
381+footnote = try $ do
382+ note <- inlineNote <|> referencedNote
383+ withNote <- getExportSetting exportWithFootnotes
384+ return $ if withNote then note else mempty
382385
383386inlineNote :: PandocMonad m => OrgParser m (F Inlines)
384387inlineNote = try $ do
@@ -790,9 +793,12 @@ inlineLaTeX :: PandocMonad m => OrgParser m (F Inlines)
790793inlineLaTeX = try $ do
791794 cmd <- inlineLaTeXCommand
792795 texOpt <- getExportSetting exportWithLatex
796+ allowEntities <- getExportSetting exportWithEntities
793797 ils <- parseAsInlineLaTeX cmd texOpt
794798 maybe mzero returnF $
795− parseAsMathMLSym cmd `mplus` parseAsMath cmd texOpt `mplus` ils
799+ parseAsMathMLSym allowEntities cmd `mplus`
800+ parseAsMath cmd texOpt `mplus`
801+ ils
796802 where
797803 parseAsInlineLaTeX :: PandocMonad m
798804 => Text -> TeXExport -> OrgParser m (Maybe Inlines)
@@ -801,10 +807,15 @@ inlineLaTeX = try $ do
801807 TeXIgnore -> return (Just mempty)
802808 TeXVerbatim -> return (Just $ B.str cs)
803809
804− parseAsMathMLSym :: Text -> Maybe Inlines
805− parseAsMathMLSym cs = B.str <$> MathMLEntityMap.getUnicode (clean cs)
806− -- drop initial backslash and any trailing "{}"
807− where clean = T.dropWhileEnd (`elem` ("{}" :: String)) . T.drop 1
810+ parseAsMathMLSym :: Bool -> Text -> Maybe Inlines
811+ parseAsMathMLSym allowEntities cs = do
812+ -- drop initial backslash and any trailing "{}"
813+ let clean = T.dropWhileEnd (`elem` ("{}" :: String)) . T.drop 1
814+ -- If entities are disabled, then return the string as text, but
815+ -- only if this *is* a MathML entity.
816+ case B.str <$> MathMLEntityMap.getUnicode (clean cs) of
817+ Just _ | not allowEntities -> Just $ B.str cs
818+ x -> x
808819
809820 state :: ParserState
810821 state = def{ stateOptions = def{ readerExtensions =
src/Text/Pandoc/Readers/Org/Meta.hs+67−70
@@ -22,7 +22,7 @@ import Text.Pandoc.Readers.Org.Inlines
2222import Text.Pandoc.Readers.Org.ParserState
2323import Text.Pandoc.Readers.Org.Parsing
2424
25−import Text.Pandoc.Builder (Blocks, Inlines, ToMetaValue)
25+import Text.Pandoc.Builder (Blocks, Inlines)
2626import qualified Text.Pandoc.Builder as B
2727import Text.Pandoc.Class.PandocMonad (PandocMonad)
2828import Text.Pandoc.Definition
@@ -57,13 +57,13 @@ removeMeta key meta' =
5757-- The order, in which blocks are tried, makes sure that we're not looking at
5858-- the beginning of a block, so we don't need to check for it
5959metaLine :: PandocMonad m => OrgParser m Blocks
60−metaLine = mempty <$ metaLineStart <* (optionLine <|> declarationLine)
60+metaLine = try $ mempty <$ metaLineStart <* keywordLine
6161
62−declarationLine :: PandocMonad m => OrgParser m ()
63−declarationLine = try $ do
62+keywordLine :: PandocMonad m => OrgParser m ()
63+keywordLine = try $ do
6464 key <- T.toLower <$> metaKey
65− case Map.lookup key exportSettingHandlers of
66− Nothing -> () <$ anyLine
65+ case Map.lookup key keywordHandlers of
66+ Nothing -> fail $ "Unknown keyword: " ++ T.unpack key
6767 Just hd -> hd
6868
6969metaKey :: Monad m => OrgParser m Text
@@ -71,28 +71,55 @@ metaKey = T.toLower <$> many1Char (noneOf ": \n\r")
7171 <* char ':'
7272 <* skipSpaces
7373
74−exportSettingHandlers :: PandocMonad m => Map Text (OrgParser m ())
75−exportSettingHandlers = Map.fromList
76− [ ("result" , fmap pure anyLine `parseThen` discard)
77− -- Common settings
78− , ("author" , lineOfInlines `parseThen` collectLines "author")
79− , ("date" , lineOfInlines `parseThen` setField "date")
80− , ("description", lineOfInlines `parseThen` collectLines "description")
81− , ("keywords" , lineOfInlines `parseThen` collectLines "keywords")
82− , ("title" , lineOfInlines `parseThen` collectLines "title")
83− -- LaTeX
84− , ("latex_class", fmap pure anyLine `parseThen` setField "documentclass")
85− , ("latex_class_options", (pure . T.filter (`notElem` ("[]" :: String)) <$> anyLine)
86− `parseThen` setField "classoption")
87− , ("latex_header", metaExportSnippet "latex" `parseThen`
88− collectAsList "header-includes")
89− -- HTML
90− , ("html_head" , metaExportSnippet "html" `parseThen`
91− collectAsList "header-includes")
92− -- pandoc-specific
93− , ("nocite" , lineOfInlines `parseThen` collectLines "nocite")
94− , ("header-includes", lineOfInlines `parseThen` collectLines "header-includes")
95− , ("institute" , lineOfInlines `parseThen` collectLines "institute")
74+infix 0 ~~>
75+(~~>) :: a -> b -> (a, b)
76+a ~~> b = (a, b)
77+
78+keywordHandlers :: PandocMonad m => Map Text (OrgParser m ())
79+keywordHandlers = Map.fromList
80+ [ "author" ~~> lineOfInlines `parseThen` collectLines "author"
81+ , "creator" ~~> fmap pure anyLine `parseThen` B.setMeta "creator"
82+ , "date" ~~> lineOfInlines `parseThen` B.setMeta "date"
83+ , "description" ~~> lineOfInlines `parseThen` collectLines "description"
84+ , "email" ~~> fmap pure anyLine `parseThen` B.setMeta "email"
85+ , "exclude_tags" ~~> tagList >>= updateState . setExcludedTags
86+ , "header-includes" ~~>
87+ lineOfInlines `parseThen` collectLines "header-includes"
88+ -- HTML-specifix export settings
89+ , "html_head" ~~>
90+ metaExportSnippet "html" `parseThen` collectAsList "header-includes"
91+ , "html_head_extra" ~~>
92+ metaExportSnippet "html" `parseThen` collectAsList "header-includes"
93+ , "institute" ~~> lineOfInlines `parseThen` collectLines "institute"
94+ -- topic keywords
95+ , "keywords" ~~> lineOfInlines `parseThen` collectLines "keywords"
96+ -- LaTeX-specific export settings
97+ , "latex_class" ~~> fmap pure anyLine `parseThen` B.setMeta "documentclass"
98+ , "latex_class_options" ~~>
99+ (pure . T.filter (`notElem` ("[]" :: String)) <$> anyLine)
100+ `parseThen` B.setMeta "classoption"
101+ , "latex_header" ~~>
102+ metaExportSnippet "latex" `parseThen` collectAsList "header-includes"
103+ , "latex_header_extra" ~~>
104+ metaExportSnippet "latex" `parseThen` collectAsList "header-includes"
105+ -- link and macro
106+ , "link" ~~> addLinkFormatter
107+ , "macro" ~~> macroDefinition >>= updateState . registerMacro
108+ -- pandoc-specific way to include references in the bibliography
109+ , "nocite" ~~> lineOfInlines `parseThen` collectLines "nocite"
110+ -- compact way to set export settings
111+ , "options" ~~> exportSettings
112+ -- pandoc-specific way to configure emphasis recognition
113+ , "pandoc-emphasis-post" ~~> emphChars >>= updateState . setEmphasisPostChar
114+ , "pandoc-emphasis-pre" ~~> emphChars >>= updateState . setEmphasisPreChar
115+ -- result markers (ignored)
116+ , "result" ~~> void anyLine
117+ , "select_tags" ~~> tagList >>= updateState . setSelectedTags
118+ , "seq_todo" ~~> todoSequence >>= updateState . registerTodoSequence
119+ , "subtitle" ~~> lineOfInlines `parseThen` collectLines "subtitle"
120+ , "title" ~~> lineOfInlines `parseThen` collectLines "title"
121+ , "todo" ~~> todoSequence >>= updateState . registerTodoSequence
122+ , "typ_todo" ~~> todoSequence >>= updateState . registerTodoSequence
96123 ]
97124
98125parseThen :: PandocMonad m
@@ -104,9 +131,6 @@ parseThen p modMeta = do
104131 meta <- orgStateMeta <$> getState
105132 updateState (\st -> st { orgStateMeta = modMeta <$> value <*> meta })
106133
107−discard :: a -> Meta -> Meta
108−discard = const id
109−
110134collectLines :: Text -> Inlines -> Meta -> Meta
111135collectLines key value meta =
112136 let value' = appendValue meta (B.toList value)
@@ -141,51 +165,25 @@ collectAsList key value meta =
141165 Just x -> [x]
142166 _ -> []
143167
144−setField :: ToMetaValue a => Text -> a -> Meta -> Meta
145−setField field value meta = B.setMeta field (B.toMetaValue value) meta
146−
147168-- | Read an format specific meta definition
148169metaExportSnippet :: Monad m => Text -> OrgParser m (F Inlines)
149170metaExportSnippet format = pure . B.rawInline format <$> anyLine
150171
151−--
152−-- export options
153−--
154−optionLine :: PandocMonad m => OrgParser m ()
155−optionLine = try $ do
156− key <- metaKey
157− case key of
158− "link" -> parseLinkFormat >>= uncurry addLinkFormat
159− "options" -> exportSettings
160− "todo" -> todoSequence >>= updateState . registerTodoSequence
161− "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
162− "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
163− "macro" -> macroDefinition >>= updateState . registerMacro
164− "exclude_tags" -> tagList >>= updateState . setExcludedTags
165− "select_tags" -> tagList >>= updateState . setSelectedTags
166− "pandoc-emphasis-pre" -> emphChars >>= updateState . setEmphasisPreChar
167− "pandoc-emphasis-post" -> emphChars >>= updateState . setEmphasisPostChar
168− _ -> mzero
169−
170−addLinkFormat :: Monad m => Text
171− -> (Text -> Text)
172− -> OrgParser m ()
173−addLinkFormat key formatter = updateState $ \s ->
174− let fs = orgStateLinkFormatters s
175− in s{ orgStateLinkFormatters = Map.insert key formatter fs }
176−
177−parseLinkFormat :: Monad m => OrgParser m (Text, Text -> Text)
178−parseLinkFormat = try $ do
172+-- | Parse a link type definition (like @wp https://en.wikipedia.org/wiki/@).
173+addLinkFormatter :: Monad m => OrgParser m ()
174+addLinkFormatter = try $ do
179175 linkType <- T.cons <$> letter <*> manyChar (alphaNum <|> oneOf "-_") <* skipSpaces
180− linkSubst <- parseFormat
181− return (linkType, linkSubst)
176+ formatter <- parseFormat
177+ updateState $ \s ->
178+ let fs = orgStateLinkFormatters s
179+ in s{ orgStateLinkFormatters = Map.insert linkType formatter fs }
182180
183181-- | An ad-hoc, single-argument-only implementation of a printf-style format
184182-- parser.
185183parseFormat :: Monad m => OrgParser m (Text -> Text)
186184parseFormat = try $ replacePlain <|> replaceUrl <|> justAppend
187185 where
188− -- inefficient, but who cares
186+ -- inefficient
189187 replacePlain = try $ (\x -> T.concat . flip intersperse x)
190188 <$> sequence [tillSpecifier 's', rest]
191189 replaceUrl = try $ (\x -> T.concat . flip intersperse x . T.pack . urlEncode . T.unpack)
@@ -224,6 +222,7 @@ setEmphasisPostChar csMb st =
224222 let postChars = fromMaybe (orgStateEmphasisPostChars defaultOrgParserState) csMb
225223 in st { orgStateEmphasisPostChars = postChars }
226224
225+-- | Parses emphasis border character like @".,?!"@
227226emphChars :: Monad m => OrgParser m (Maybe [Char])
228227emphChars = do
229228 skipSpaces
@@ -234,16 +233,14 @@ lineOfInlines = do
234233 updateLastPreCharPos
235234 trimInlinesF . mconcat <$> manyTill inline newline
236235
237−--
238−-- ToDo Sequences and Keywords
239−--
236+-- | Parses ToDo sequences / keywords like @TODO DOING | DONE@.
240237todoSequence :: Monad m => OrgParser m TodoSequence
241238todoSequence = try $ do
242239 todoKws <- todoKeywords
243240 doneKws <- optionMaybe $ todoDoneSep *> todoKeywords
244241 newline
245− -- There must be at least one DONE keyword. The last TODO keyword is taken if
246− -- necessary.
242+ -- There must be at least one DONE keyword. The last TODO keyword is
243+ -- taken if necessary.
247244 case doneKws of
248245 Just done -> return $ keywordsToSequence todoKws done
249246 Nothing -> case reverse todoKws of
src/Text/Pandoc/Readers/Org/ParserState.hs+6
@@ -257,9 +257,12 @@ data ExportSettings = ExportSettings
257257 , exportWithAuthor :: Bool -- ^ Include author in final meta-data
258258 , exportWithCreator :: Bool -- ^ Include creator in final meta-data
259259 , exportWithEmail :: Bool -- ^ Include email in final meta-data
260+ , exportWithEntities :: Bool -- ^ Include MathML-like entities
261+ , exportWithFootnotes :: Bool -- ^ Include footnotes
260262 , exportWithLatex :: TeXExport -- ^ Handling of raw TeX commands
261263 , exportWithPlanning :: Bool -- ^ Keep planning info after headlines
262264 , exportWithTags :: Bool -- ^ Keep tags as part of headlines
265+ , exportWithTables :: Bool -- ^ Include tables
263266 , exportWithTodoKeywords :: Bool -- ^ Keep TODO keywords in headers
264267 }
265268
@@ -279,8 +282,11 @@ defaultExportSettings = ExportSettings
279282 , exportWithAuthor = True
280283 , exportWithCreator = True
281284 , exportWithEmail = True
285+ , exportWithEntities = True
286+ , exportWithFootnotes = True
282287 , exportWithLatex = TeXExport
283288 , exportWithPlanning = False
284289 , exportWithTags = True
290+ , exportWithTables = True
285291 , exportWithTodoKeywords = True
286292 }
src/Text/Pandoc/Readers/RST.hs+4−3
@@ -223,7 +223,8 @@ rawFieldListItem minIndent = try $ do
223223 first <- anyLine
224224 rest <- option "" $ try $ do lookAhead (count indent (char ' ') >> spaceChar)
225225 indentedBlock
226− let raw = (if T.null first then "" else first <> "\n") <> rest <> "\n"
226+ let raw = (if T.null first then "" else first <> "\n") <> rest <>
227+ (if T.null first && T.null rest then "" else "\n")
227228 return (name, raw)
228229
229230fieldListItem :: PandocMonad m => Int -> RSTParser m (Inlines, [Blocks])
@@ -484,7 +485,7 @@ includeDirective top fields body = do
484485 Just patt -> drop 1 .
485486 dropWhile (not . (patt `T.isInfixOf`))
486487 Nothing -> id) $ contentLines'
487− let contents' = T.unlines contentLines'' <> "\n"
488+ let contents' = T.unlines contentLines''
488489 case lookup "code" fields of
489490 Just lang -> do
490491 let classes = maybe [] T.words (lookup "class" fields)
@@ -494,7 +495,7 @@ includeDirective top fields body = do
494495 Just _ -> return $ B.rawBlock "rst" contents'
495496 Nothing -> do
496497 setPosition $ newPos (T.unpack f) 1 1
497− setInput contents'
498+ setInput $ contents' <> "\n"
498499 bs <- optional blanklines >>
499500 (mconcat <$> many block)
500501 setInput oldInput
src/Text/Pandoc/Writers/Jira.hs+12−10
@@ -194,7 +194,7 @@ toJiraInlines inlines = do
194194 Jira.Monospaced (escapeSpecialChars cs)
195195 Emph xs -> styled Jira.Emphasis xs
196196 Underline xs -> styled Jira.Insert xs
197− Image attr _ tgt -> imageToJira attr (fst tgt) (snd tgt)
197+ Image attr cap tgt -> imageToJira attr cap (fst tgt) (snd tgt)
198198 LineBreak -> pure . singleton $ Jira.Linebreak
199199 Link attr xs tgt -> toJiraLink attr tgt xs
200200 Math mtype cs -> mathToJira mtype cs
@@ -233,16 +233,18 @@ escapeSpecialChars t = case plainText t of
233233 Left _ -> singleton $ Jira.Str t
234234
235235imageToJira :: PandocMonad m
236− => Attr -> Text -> Text
236+ => Attr -> [Inline] -> Text -> Text
237237 -> JiraConverter m [Jira.Inline]
238−imageToJira (_, classes, kvs) src title =
239− let imgParams = if "thumbnail" `elem` classes
240− then [Jira.Parameter "thumbnail" ""]
241− else map (uncurry Jira.Parameter) kvs
242− imgParams' = if T.null title
243− then imgParams
244− else Jira.Parameter "title" title : imgParams
245− in pure . singleton $ Jira.Image imgParams' (Jira.URL src)
238+imageToJira (_, classes, kvs) caption src title =
239+ let imageWithParams ps = Jira.Image ps (Jira.URL src)
240+ alt = stringify caption
241+ in pure . singleton . imageWithParams $
242+ if "thumbnail" `elem` classes
243+ then [Jira.Parameter "thumbnail" ""]
244+ else map (uncurry Jira.Parameter)
245+ . (if T.null title then id else (("title", title):))
246+ . (if T.null alt then id else (("alt", alt):))
247+ $ kvs
246248
247249-- | Creates a Jira Link element.
248250toJiraLink :: PandocMonad m
src/Text/Pandoc/Writers/Ms.hs+8−6
@@ -204,7 +204,9 @@ blockToMs opts (CodeBlock attr str) = do
204204 literal ".IP" $$
205205 literal ".nf" $$
206206 literal "\\f[C]" $$
207− hlCode $$
207+ ((case T.uncons str of
208+ Just ('.',_) -> literal "\\&"
209+ _ -> mempty) <> hlCode) $$
208210 literal "\\f[]" $$
209211 literal ".fi"
210212blockToMs opts (LineBlock ls) = do
@@ -517,11 +519,11 @@ toMacro sty toktype =
517519
518520msFormatter :: WriterOptions -> FormatOptions -> [SourceLine] -> Doc Text
519521msFormatter opts _fmtopts =
520− vcat . map fmtLine
521− where fmtLine = hcat . map fmtToken
522− fmtToken (toktype, tok) = literal "\\*" <>
523− brackets (literal (tshow toktype) <> literal " \""
524− <> literal (escapeStr opts tok) <> literal "\"")
522+ literal . T.intercalate "\n" . map fmtLine
523+ where
524+ fmtLine = mconcat . map fmtToken
525+ fmtToken (toktype, tok) =
526+ "\\*[" <> (tshow toktype) <> " \"" <> (escapeStr opts tok) <> "\"]"
525527
526528highlightCode :: PandocMonad m => WriterOptions -> Attr -> Text -> MS m (Doc Text)
527529highlightCode opts attr str =
test/Tests/Readers/Org/Directive.hs+30
@@ -150,6 +150,28 @@ tests =
150150 ] =?>
151151 Pandoc nullMeta mempty
152152
153+ , "disable MathML-like entities" =:
154+ T.unlines [ "#+OPTIONS: e:nil"
155+ , "Icelandic letter: \\thorn"
156+ ] =?>
157+ para "Icelandic letter: \\thorn"
158+
159+ , testGroup "Option f"
160+ [ "disable inline footnotes" =:
161+ T.unlines [ "#+OPTIONS: f:nil"
162+ , "Funny![fn:funny:or not]"
163+ ] =?>
164+ para "Funny!"
165+
166+ , "disable reference footnotes" =:
167+ T.unlines [ "#+OPTIONS: f:nil"
168+ , "Burn everything[fn:1] down!"
169+ , ""
170+ , "[fn:2] Not quite everything."
171+ ] =?>
172+ para "Burn everything down!"
173+ ]
174+
153175 , "disable inclusion of todo keywords" =:
154176 T.unlines [ "#+OPTIONS: todo:nil"
155177 , "** DONE todo export"
@@ -258,6 +280,14 @@ tests =
258280 headerWith ("wichtig", mempty, mempty) 1 "Wichtig"
259281 ]
260282
283+ , testGroup "Option |"
284+ [ "disable export of tables" =:
285+ T.unlines [ "#+OPTIONS: |:nil"
286+ , "| chair |"
287+ ] =?>
288+ (mempty :: Blocks)
289+ ]
290+
261291 , testGroup "unknown options"
262292 [ "unknown options are ignored" =:
263293 T.unlines [ "#+OPTIONS: does-not-exist:t "] =?>
test/Tests/Readers/Org/Meta.hs+110−72
@@ -93,6 +93,13 @@ tests =
9393 in Pandoc meta mempty
9494 ]
9595
96+ , "Subtitle" =:
97+ T.unlines [ "#+SUBTITLE: Your Life in"
98+ , "#+SUBTITLE: /Plain/ Text"
99+ ] =?>
100+ let subtitle = "Your Life in" <> softbreak <> emph "Plain" <> " Text"
101+ in Pandoc (setMeta "subtitle" (toMetaValue subtitle) nullMeta) mempty
102+
96103 , "Keywords" =:
97104 T.unlines [ "#+KEYWORDS: pandoc, testing,"
98105 , "#+KEYWORDS: Org"
@@ -101,42 +108,117 @@ tests =
101108 meta = setMeta "keywords" (MetaInlines keywords) nullMeta
102109 in Pandoc meta mempty
103110
104− , "LaTeX_headers options are translated to header-includes" =:
105− "#+LaTeX_header: \\usepackage{tikz}" =?>
106− let latexInlines = rawInline "latex" "\\usepackage{tikz}"
107− inclList = MetaList [MetaInlines (toList latexInlines)]
108− meta = setMeta "header-includes" inclList nullMeta
109− in Pandoc meta mempty
111+ , "Institute" =:
112+ "#+INSTITUTE: ACME Inc." =?>
113+ Pandoc (setMeta "institute" ("ACME Inc." :: Inlines) nullMeta) mempty
110114
111− , testGroup "LaTeX_CLASS"
112− [ "LaTeX_class option is translated to documentclass" =:
113− "#+LATEX_CLASS: article" =?>
114− let meta = setMeta "documentclass" (MetaString "article") nullMeta
115+ , testGroup "LaTeX"
116+ [ "LATEX_HEADER" =:
117+ "#+LaTeX_header: \\usepackage{tikz}" =?>
118+ let latexInlines = rawInline "latex" "\\usepackage{tikz}"
119+ inclList = MetaList [MetaInlines (toList latexInlines)]
120+ meta = setMeta "header-includes" inclList nullMeta
115121 in Pandoc meta mempty
116122
117− , "last definition takes precedence" =:
118− T.unlines [ "#+LATEX_CLASS: this will not be used"
119− , "#+LATEX_CLASS: report"
120− ] =?>
121− let meta = setMeta "documentclass" (MetaString "report") nullMeta
123+ , "LATEX_HEADER_EXTRA" =:
124+ "#+LATEX_HEADER_EXTRA: \\usepackage{calc}" =?>
125+ let latexInlines = rawInline "latex" "\\usepackage{calc}"
126+ inclList = toMetaValue [latexInlines]
127+ in Pandoc (setMeta "header-includes" inclList nullMeta) mempty
128+
129+ , testGroup "LaTeX_CLASS"
130+ [ "stored as documentclass" =:
131+ "#+LATEX_CLASS: article" =?>
132+ let meta = setMeta "documentclass" (MetaString "article") nullMeta
133+ in Pandoc meta mempty
134+
135+ , "last definition takes precedence" =:
136+ T.unlines [ "#+LATEX_CLASS: this will not be used"
137+ , "#+LATEX_CLASS: report"
138+ ] =?>
139+ let meta = setMeta "documentclass" (MetaString "report") nullMeta
140+ in Pandoc meta mempty
141+ ]
142+
143+ , "LATEX_CLASS_OPTIONS as classoption" =:
144+ "#+LATEX_CLASS_OPTIONS: [a4paper]" =?>
145+ let meta = setMeta "classoption" (MetaString "a4paper") nullMeta
122146 in Pandoc meta mempty
123147 ]
124148
125− , "LaTeX_class_options is translated to classoption" =:
126− "#+LATEX_CLASS_OPTIONS: [a4paper]" =?>
127− let meta = setMeta "classoption" (MetaString "a4paper") nullMeta
128− in Pandoc meta mempty
149+ , testGroup "HTML"
150+ [ "HTML_HEAD values are added to header-includes" =:
151+ "#+html_head: <meta/>" =?>
152+ let html = rawInline "html" "<meta/>"
153+ inclList = MetaList [MetaInlines (toList html)]
154+ meta = setMeta "header-includes" inclList nullMeta
155+ in Pandoc meta mempty
129156
130− , "LaTeX_class_options is translated to classoption" =:
131− "#+html_head: <meta/>" =?>
132− let html = rawInline "html" "<meta/>"
133− inclList = MetaList [MetaInlines (toList html)]
134− meta = setMeta "header-includes" inclList nullMeta
135− in Pandoc meta mempty
157+ , "HTML_HEAD_EXTRA behaves like HTML_HEAD" =:
158+ T.unlines [ "#+HTML_HEAD: <meta name=\"generator\" content=\"pandoc\">"
159+ , "#+HTML_HEAD_EXTRA: <meta charset=\"utf-8\">"
160+ ] =?>
161+ let generator = rawInline "html"
162+ "<meta name=\"generator\" content=\"pandoc\">"
163+ charset = rawInline "html" "<meta charset=\"utf-8\">"
164+ inclList = toMetaValue [generator, charset]
165+ in Pandoc (setMeta "header-includes" inclList nullMeta) mempty
166+ ]
167+ ]
136168
137− , "Institute" =:
138− "#+INSTITUTE: ACME Inc." =?>
139− Pandoc (setMeta "institute" ("ACME Inc." :: Inlines) nullMeta) mempty
169+ , testGroup "Non-export keywords"
170+ [ testGroup "#+LINK"
171+ [ "Link abbreviation" =:
172+ T.unlines [ "#+LINK: wp https://en.wikipedia.org/wiki/%s"
173+ , "[[wp:Org_mode][Wikipedia on Org-mode]]"
174+ ] =?>
175+ para (link "https://en.wikipedia.org/wiki/Org_mode" ""
176+ ("Wikipedia" <> space <> "on" <> space <> "Org-mode"))
177+
178+ , "Link abbreviation, defined after first use" =:
179+ T.unlines [ "[[zl:non-sense][Non-sense articles]]"
180+ , "#+LINK: zl http://zeitlens.com/tags/%s.html"
181+ ] =?>
182+ para (link "http://zeitlens.com/tags/non-sense.html" ""
183+ ("Non-sense" <> space <> "articles"))
184+
185+ , "Link abbreviation, URL encoded arguments" =:
186+ T.unlines [ "#+link: expl http://example.com/%h/foo"
187+ , "[[expl:Hello, World!][Moin!]]"
188+ ] =?>
189+ para (link "http://example.com/Hello%2C%20World%21/foo" "" "Moin!")
190+
191+ , "Link abbreviation, append arguments" =:
192+ T.unlines [ "#+link: expl http://example.com/"
193+ , "[[expl:foo][bar]]"
194+ ] =?>
195+ para (link "http://example.com/foo" "" "bar")
196+ ]
197+
198+ , testGroup "emphasis config"
199+ [ "Changing pre and post chars for emphasis" =:
200+ T.unlines [ "#+pandoc-emphasis-pre: \"[)\""
201+ , "#+pandoc-emphasis-post: \"]\\n\""
202+ , "([/emph/])*foo*"
203+ ] =?>
204+ para ("([" <> emph "emph" <> "])" <> strong "foo")
205+
206+ , "setting an invalid value restores the default" =:
207+ T.unlines [ "#+pandoc-emphasis-pre: \"[\""
208+ , "#+pandoc-emphasis-post: \"]\""
209+ , "#+pandoc-emphasis-pre:"
210+ , "#+pandoc-emphasis-post:"
211+ , "[/noemph/]"
212+ ] =?>
213+ para "[/noemph/]"
214+ ]
215+
216+ , "Unknown keyword" =:
217+ T.unlines [ "#+UNKNOWN_KEYWORD: Chumbawamba"
218+ , "#+ANOTHER_UNKNOWN: Blur"
219+ ] =?>
220+ rawBlock "org" "#+UNKNOWN_KEYWORD: Chumbawamba" <>
221+ rawBlock "org" "#+ANOTHER_UNKNOWN: Blur"
140222 ]
141223
142224 , "Properties drawer" =:
@@ -193,48 +275,4 @@ tests =
193275 ] =?>
194276 (para (spanWith ("link-here", [], []) mempty <> "Target.") <>
195277 para (emph ("See" <> space <> "here!")))
196−
197− , "Link abbreviation" =:
198− T.unlines [ "#+LINK: wp https://en.wikipedia.org/wiki/%s"
199− , "[[wp:Org_mode][Wikipedia on Org-mode]]"
200− ] =?>
201− para (link "https://en.wikipedia.org/wiki/Org_mode" ""
202− ("Wikipedia" <> space <> "on" <> space <> "Org-mode"))
203−
204− , "Link abbreviation, defined after first use" =:
205− T.unlines [ "[[zl:non-sense][Non-sense articles]]"
206− , "#+LINK: zl http://zeitlens.com/tags/%s.html"
207− ] =?>
208− para (link "http://zeitlens.com/tags/non-sense.html" ""
209− ("Non-sense" <> space <> "articles"))
210−
211− , "Link abbreviation, URL encoded arguments" =:
212− T.unlines [ "#+link: expl http://example.com/%h/foo"
213− , "[[expl:Hello, World!][Moin!]]"
214− ] =?>
215− para (link "http://example.com/Hello%2C%20World%21/foo" "" "Moin!")
216−
217− , "Link abbreviation, append arguments" =:
218− T.unlines [ "#+link: expl http://example.com/"
219− , "[[expl:foo][bar]]"
220− ] =?>
221− para (link "http://example.com/foo" "" "bar")
222−
223− , testGroup "emphasis config"
224− [ "Changing pre and post chars for emphasis" =:
225− T.unlines [ "#+pandoc-emphasis-pre: \"[)\""
226− , "#+pandoc-emphasis-post: \"]\\n\""
227− , "([/emph/])*foo*"
228− ] =?>
229− para ("([" <> emph "emph" <> "])" <> strong "foo")
230−
231− , "setting an invalid value restores the default" =:
232− T.unlines [ "#+pandoc-emphasis-pre: \"[\""
233− , "#+pandoc-emphasis-post: \"]\""
234− , "#+pandoc-emphasis-pre:"
235− , "#+pandoc-emphasis-post:"
236− , "[/noemph/]"
237− ] =?>
238− para "[/noemph/]"
239− ]
240278 ]
test/Tests/Writers/Ms.hsnew file+37
@@ -0,0 +1,37 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+module Tests.Writers.Ms (tests) where
4+
5+import Prelude
6+import Test.Tasty
7+import Tests.Helpers
8+import Text.Pandoc
9+import Text.Pandoc.Builder
10+
11+infix 4 =:
12+(=:) :: (ToString a, ToPandoc a)
13+ => String -> (a, String) -> TestTree
14+(=:) = test (purely (writeMs def . toPandoc))
15+
16+tests :: [TestTree]
17+tests = [ testGroup "code blocks"
18+ [ "basic"
19+ =: codeBlock "hello"
20+ =?> unlines
21+ [ ".IP"
22+ , ".nf"
23+ , "\\f[C]"
24+ , "hello"
25+ , "\\f[]"
26+ , ".fi"]
27+ , "escape starting ."
28+ =: codeBlock ". hello"
29+ =?> unlines
30+ [ ".IP"
31+ , ".nf"
32+ , "\\f[C]"
33+ , "\\&. hello"
34+ , "\\f[]"
35+ , ".fi"]
36+ ]
37+ ]
test/docx/golden/inline_formatting.docx

Binary file not shown.

test/docx/inline_formatting.native+1−1
@@ -1,6 +1,6 @@
11Pandoc (Meta {unMeta = fromList []})
22[Para [Str "Regular",Space,Str "text",Space,Emph [Str "italics"],Space,Strong [Str "bold",Space,Emph [Str "bold",Space,Str "italics"]],Str "."]
33,Para [Str "This",Space,Str "is",Space,SmallCaps [Str "Small",Space,Str "Caps"],Str ",",Space,Str "and",Space,Str "this",Space,Str "is",Space,Strikeout [Str "strikethrough"],Str "."]
4−,Para [Str "Some",Space,Str "people",Space,Str "use",Space,Underline [Str "single",Space,Str "underlines",Space,Str "for",Space],Emph [Underline [Str "emphasis"]],Str "."]
4+,Para [Str "Some",Space,Str "people",Space,Str "use",Space,Underline [Str "single",Space,Str "underlines",Space,Str "for",Space,Emph [Str "emphasis"]],Str "."]
55,Para [Str "Above",Space,Str "the",Space,Str "line",Space,Str "is",Space,Superscript [Str "superscript"],Space,Str "and",Space,Str "below",Space,Str "the",Space,Str "line",Space,Str "is",Space,Subscript [Str "subscript"],Str "."]
66,Para [Str "A",Space,Str "line",LineBreak,Str "break."]]
test/lhs-test.latex+3
@@ -81,6 +81,9 @@
8181\providecommand{\tightlist}{%
8282 \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
8383\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
84+\ifluatex
85+ \usepackage{selnolig} % disable illegal ligatures
86+\fi
8487
8588\author{}
8689\date{}
test/lhs-test.latex+lhs+3
@@ -48,6 +48,9 @@
4848\providecommand{\tightlist}{%
4949 \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
5050\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
51+\ifluatex
52+ \usepackage{selnolig} % disable illegal ligatures
53+\fi
5154
5255\author{}
5356\date{}
test/test-pandoc.hs+2
@@ -37,6 +37,7 @@ import qualified Tests.Writers.JATS
3737import qualified Tests.Writers.Jira
3838import qualified Tests.Writers.LaTeX
3939import qualified Tests.Writers.Markdown
40+import qualified Tests.Writers.Ms
4041import qualified Tests.Writers.Muse
4142import qualified Tests.Writers.Native
4243import qualified Tests.Writers.Org
@@ -70,6 +71,7 @@ tests pandocPath = testGroup "pandoc tests"
7071 , testGroup "Muse" Tests.Writers.Muse.tests
7172 , testGroup "FB2" Tests.Writers.FB2.tests
7273 , testGroup "PowerPoint" Tests.Writers.Powerpoint.tests
74+ , testGroup "Ms" Tests.Writers.Ms.tests
7375 ]
7476 , testGroup "Readers"
7577 [ testGroup "LaTeX" Tests.Readers.LaTeX.tests
test/writer.jira+2−2
@@ -513,9 +513,9 @@ or here: <http://example.com/>
513513h1. {anchor:images}Images
514514From "Voyage dans la Lune" by Georges Melies \(1902):
515515
516−!lalune.jpg|title=fig:Voyage dans la Lune!
516+!lalune.jpg|title=fig:Voyage dans la Lune, alt=lalune!
517517
518−Here is a movie !movie.jpg! icon.
518+Here is a movie !movie.jpg|alt=movie! icon.
519519
520520----
521521h1. {anchor:footnotes}Footnotes
test/writer.latex+3
@@ -63,6 +63,9 @@
6363\providecommand{\tightlist}{%
6464 \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
6565\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
66+\ifluatex
67+ \usepackage{selnolig} % disable illegal ligatures
68+\fi
6669
6770\title{Pandoc Test Suite}
6871\author{John MacFarlane \and Anonymous}
test/writers-lang-and-dir.latex+3
@@ -66,6 +66,9 @@
6666 \newcommand{\textfrench}[2][]{\foreignlanguage{french}{#2}}
6767 \newenvironment{french}[2][]{\begin{otherlanguage}{french}}{\end{otherlanguage}}
6868\fi
69+\ifluatex
70+ \usepackage{selnolig} % disable illegal ligatures
71+\fi
6972\ifxetex
7073 % Load bidi as late as possible as it modifies e.g. graphicx
7174 \usepackage{bidi}