git.iko.soy/typeable/pandoc
on 2d60524 help sign in
.circleci/config.yml+1−1
since splitsnapshots
unifiedsplit
@@ -2,7 +2,7 @@ version: "2.1"
2jobs:
2jobs:
3 build:
3 build:
4 macos:
4 macos:
5− xcode: 11.1.0
5+ xcode: 9.4.1
6 environment:
6 environment:
7 HOMEBREW_NO_AUTO_UPDATE: 1
7 HOMEBREW_NO_AUTO_UPDATE: 1
8 steps:
8 steps:
.editorconfig−8
@@ -8,14 +8,6 @@ indent_size = 2
8insert_final_newline = true
8insert_final_newline = true
9trim_trailing_whitespace = true
9trim_trailing_whitespace = true
10
10
11−[*.{zip,docx}]
12−charset =
13−end_of_line =
14−indent_style =
15−indent_size =
16−insert_final_newline =
17−trim_trailing_whitespace =
18−
19[*.{markdown,md}]
11[*.{markdown,md}]
20trim_trailing_whitespace = false
12trim_trailing_whitespace = false
21
13
.github/ISSUE_TEMPLATEnew file+11
@@ -0,0 +1,11 @@
1+Asking a question?
2+Please use the pandoc-discuss mailing list instead:
3+https://groups.google.com/forum/#!forum/pandoc-discuss
4+This tracker is for bug reports and enhancement requests.
5+
6+Reporting a bug?
7+Please include your pandoc version and an example that allows us
8+to reproduce the problem (complete input, exact command line
9+used, expected and actual output). The smaller the example, the
10+better.
11+
.github/ISSUE_TEMPLATE/bug_report.mddeleted−25
@@ -1,25 +0,0 @@
1−---
2−name: Bug report
3−about: Create a report to help us improve
4−title: ''
5−labels: 'bug'
6−assignees: ''
7−
8−---
9−
10−<!--
11−Thank you for reporting an issue! Before you continue, please make sure that you have
12−
13−- searched the issue tracker for similar issues (including closed issues): https://github.com/jgm/pandoc/issues
14−- searched the pandoc-discuss mailing list for solutions: https://groups.google.com/forum/#!forum/pandoc-discuss
15−- reproduced your issue on the latest release of pandoc, or on https://pandoc.org/try
16−
17−Note that this bug tracker is for reporting bugs, not asking questions. For questions, use the pandoc-discuss mailing list.
18−-->
19−
20−**Explain the problem.**
21−Include the exact command line you used and all inputs necessary to reproduce the issue. Please create as minimal an example as possible, to help the maintainers isolate the problem. Explain the output you received and how it differs from what you expected.
22−
23−**Pandoc version?**
24−What version of pandoc are you using, on what OS?
25−
.github/ISSUE_TEMPLATE/config.ymldeleted−9
@@ -1,9 +0,0 @@
1−blank_issues_enabled: false
2−contact_links:
3− - name: Ask a question
4− url: https://groups.google.com/forum/#!forum/pandoc-discuss
5− about: "Discussion forum for pandoc (may be used as an email list)"
6− - name: Contributing Guidelines
7− url: https://pandoc.org/CONTRIBUTING.html
8− about: "Guidelines for submitting bug reports and code improvements"
9−
.github/ISSUE_TEMPLATE/feature_request.mddeleted−21
@@ -1,21 +0,0 @@
1−---
2−name: Feature request
3−about: Suggest an idea for this project
4−title: ''
5−labels: 'enhancement'
6−assignees: ''
7−
8−---
9−
10−<!--
11−Thank you for suggesting a feature! Before you continue, please make sure that you have
12−
13−- read the contributing guidelines: https://pandoc.org/CONTRIBUTING.html
14−- searched the issue tracker for similar issues (including closed issues): https://github.com/jgm/pandoc/issues
15−- searched the pandoc-discuss mailing list for relevant discussions: https://groups.google.com/forum/#!forum/pandoc-discuss
16−-->
17−
18−**Describe your proposed improvement and the problem it solves.**
19−
20−**Describe alternatives you've considered.**
21−
.github/workflows/ci.yml+3−12
@@ -44,8 +44,8 @@ jobs:
44 matrix:
44 matrix:
45 versions:
45 versions:
46 - ghc: '8.0.2'
46 - ghc: '8.0.2'
47− cabal: '2.4'
47+ cabal: '2.2'
48− prefix: 'v2-'
48+ prefix: 'new-'
49 cabalopts: ''
49 cabalopts: ''
50 testopts: ''
50 testopts: ''
51 - ghc: '8.2.2'
51 - ghc: '8.2.2'
@@ -68,23 +68,14 @@ jobs:
68 prefix: ''
68 prefix: ''
69 cabalopts: ''
69 cabalopts: ''
70 testopts: '--test-option=--hide-successes'
70 testopts: '--test-option=--hide-successes'
71− - ghc: '8.10.4'
71+ - ghc: '8.10.2'
72 cabal: '3.2'
72 cabal: '3.2'
73 prefix: ''
73 prefix: ''
74 cabalopts: '-ftrypandoc'
74 cabalopts: '-ftrypandoc'
75 testopts: '--test-option=--hide-successes'
75 testopts: '--test-option=--hide-successes'
76− - ghc: '9.0.1'
77− cabal: '3.4'
78− prefix: ''
79− cabalopts: ''
80− testopts: '--test-option=--hide-successes'
81 steps:
76 steps:
82 - uses: actions/checkout@v2
77 - uses: actions/checkout@v2
83
78
84− # needed by memory
85− - name: Install numa
86− run: sudo apt-get install libnuma-dev
87−
88 # need to install older cabal/ghc versions from ppa repository
79 # need to install older cabal/ghc versions from ppa repository
89
80
90 - name: Install recent cabal/ghc
81 - name: Install recent cabal/ghc
.github/workflows/nightly.yml+2−2
@@ -22,10 +22,10 @@ jobs:
22 ghc --version
22 ghc --version
23 cabal --version
23 cabal --version
24 cabal v2-update
24 cabal v2-update
25− cabal v2-build --dependencies-only
25+ cabal v2-build --dependencies-only all
26 - name: Build
26 - name: Build
27 run: |
27 run: |
28− cabal v2-install
28+ cabal v2-install all
29 strip $HOME/.cabal/bin/pandoc
29 strip $HOME/.cabal/bin/pandoc
30 - name: Install artifact
30 - name: Install artifact
31 run: |
31 run: |
.hlint.yaml−1
@@ -9,7 +9,6 @@
9# Ignore some builtin hints
9# Ignore some builtin hints
10#
10#
11- ignore: {name: "Avoid lambda"}
11- ignore: {name: "Avoid lambda"}
12−- ignore: {name: "Use bimap"}
13- ignore: {name: "Eta reduce"}
12- ignore: {name: "Eta reduce"}
14- ignore: {name: "Evaluate"}
13- ignore: {name: "Evaluate"}
15- ignore: {name: "Reduce duplication"} # TODO: could be more fine-grained
14- ignore: {name: "Reduce duplication"} # TODO: could be more fine-grained
AUTHORS.md−11
@@ -20,7 +20,6 @@
20- Andreas Lööw
20- Andreas Lööw
21- Andrew Dunning
21- Andrew Dunning
22- Andy Morris
22- Andy Morris
23−- Anti-Distinctlyminty
24- Antoine Latter
23- Antoine Latter
25- Antonio Terceiro
24- Antonio Terceiro
26- Arata Mizuki
25- Arata Mizuki
@@ -47,7 +46,6 @@
47- Carlos Sosa
46- Carlos Sosa
48- Cécile Chemin
47- Cécile Chemin
49- Cédric Couralet
48- Cédric Couralet
50−- Charanjit Singh
51- Chris Black
49- Chris Black
52- Christian Conkle
50- Christian Conkle
53- Christian Despres
51- Christian Despres
@@ -78,7 +76,6 @@
78- Eigil Rischel
76- Eigil Rischel
79- Emanuel Evans
77- Emanuel Evans
80- Emerson Harkin
78- Emerson Harkin
81−- Emily Bourke
82- Emily Eisenberg
79- Emily Eisenberg
83- Eric Kow
80- Eric Kow
84- Erik Rask
81- Erik Rask
@@ -152,7 +149,6 @@
152- Josef Svenningsson
149- Josef Svenningsson
153- Joseph C. Sible
150- Joseph C. Sible
154- Julien Cretel
151- Julien Cretel
155−- Julien Dutant
156- Juliette Fourcot
152- Juliette Fourcot
157- Juliusz Gonera
153- Juliusz Gonera
158- Justin Bogner
154- Justin Bogner
@@ -235,7 +231,6 @@
235- Raymond Ehlers
231- Raymond Ehlers
236- Recai Oktaş
232- Recai Oktaş
237- Roland Hieber
233- Roland Hieber
238−- Roman Beránek
239- RyanGlScott
234- RyanGlScott
240- Salim B
235- Salim B
241- Sascha Wilde
236- Sascha Wilde
@@ -253,7 +248,6 @@
253- Stefan Dresselhaus
248- Stefan Dresselhaus
254- Sumit Sahrawat
249- Sumit Sahrawat
255- Tarik Graba
250- Tarik Graba
256−- Tatiana Porras
257- Thenaesh Elango
251- Thenaesh Elango
258- Thomas Hodgson
252- Thomas Hodgson
259- Thomas Weißschuh
253- Thomas Weißschuh
@@ -287,7 +281,6 @@
287- a-vrma
281- a-vrma
288- andrebauer
282- andrebauer
289- argent0
283- argent0
290−- badumont
291- blmage
284- blmage
292- bucklereed
285- bucklereed
293- bumper314
286- bumper314
@@ -303,11 +296,8 @@
303- kaizshang91
296- kaizshang91
304- lux-lth
297- lux-lth
305- lwolfsonkin
298- lwolfsonkin
306−- mbrackeantidot
307- nkalvi
299- nkalvi
308- niszet
300- niszet
309−- nuew
310−- obcat
311- oltolm
301- oltolm
312- oquechy
302- oquechy
313- quasicomputational
303- quasicomputational
@@ -319,7 +309,6 @@
319- shreevatsa.public
309- shreevatsa.public
320- takahashim
310- takahashim
321- taotieren
311- taotieren
322−- tecosaur
323- TEC
312- TEC
324- tgkokk
313- tgkokk
325- the-solipsist
314- the-solipsist
CONTRIBUTING.md+5−6
@@ -406,11 +406,11 @@ The library is structured as follows:
406 tree automatically.
406 tree automatically.
407 - `Text.Pandoc.Readers.*` are the readers, and `Text.Pandoc.Writers.*`
407 - `Text.Pandoc.Readers.*` are the readers, and `Text.Pandoc.Writers.*`
408 are the writers.
408 are the writers.
409− - `Text.Pandoc.Citeproc.*` contain the code for citation handling,
409+ - `Text.Pandoc.Biblio` is a utility module for formatting citations
410− including an interface to the [citeproc] library.
410+ using citeproc-hs.
411 - `Text.Pandoc.Data` is used to embed data files when the `embed_data_files`
411 - `Text.Pandoc.Data` is used to embed data files when the `embed_data_files`
412− cabal flag is used.
412+ cabal flag is used. It is generated from `src/Text/Pandoc/Data.hsb` using
413− - `Text.Pandoc.Emoji` is a thin wrapper around [emojis].
413+ the preprocessor [hsb2hs].
414 - `Text.Pandoc.Highlighting` contains the interface to the
414 - `Text.Pandoc.Highlighting` contains the interface to the
415 skylighting library, which is used for code syntax highlighting.
415 skylighting library, which is used for code syntax highlighting.
416 - `Text.Pandoc.ImageSize` is a utility module containing functions for
416 - `Text.Pandoc.ImageSize` is a utility module containing functions for
@@ -421,6 +421,7 @@ The library is structured as follows:
421 - `Text.Pandoc.PDF` contains functions for producing a PDF from a
421 - `Text.Pandoc.PDF` contains functions for producing a PDF from a
422 LaTeX source.
422 LaTeX source.
423 - `Text.Pandoc.Parsing` contains parsing functions used in multiple readers.
423 - `Text.Pandoc.Parsing` contains parsing functions used in multiple readers.
424+ - `Text.Pandoc.Pretty` is a pretty-printing library specialized to
424 the needs of pandoc.
425 the needs of pandoc.
425 - `Text.Pandoc.SelfContained` contains functions for making an HTML
426 - `Text.Pandoc.SelfContained` contains functions for making an HTML
426 file "self-contained," by importing remotely linked images, CSS,
427 file "self-contained," by importing remotely linked images, CSS,
@@ -455,8 +456,6 @@ you may want to consider submitting a pull request to the
455[EditorConfig]: https://editorconfig.org/
456[EditorConfig]: https://editorconfig.org/
456[Haskell platform]: https://www.haskell.org/platform/
457[Haskell platform]: https://www.haskell.org/platform/
457[hlint]: https://hackage.haskell.org/package/hlint
458[hlint]: https://hackage.haskell.org/package/hlint
458−[citeproc]: https://hackage.haskell.org/package/citeproc
459−[emojis]: https://hackage.haskell.org/package/emojis
460[hsb2hs]: https://hackage.haskell.org/package/hsb2hs
459[hsb2hs]: https://hackage.haskell.org/package/hsb2hs
461[pre-commit hook]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
460[pre-commit hook]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
462[GitHub labels]: https://github.com/jgm/pandoc/labels
461[GitHub labels]: https://github.com/jgm/pandoc/labels
INSTALL.md−4
@@ -34,10 +34,6 @@ without SVG support), [Python] (to use Pandoc filters), and
34
34
35 choco install rsvg-convert python miktex
35 choco install rsvg-convert python miktex
36
36
37−Using multiple installation methods can result in two separate
38−installations of pandoc; it is recommended to properly uninstall
39−pandoc before switching to an alternative installation method.
40−
41By default, Pandoc creates PDFs using LaTeX.
37By default, Pandoc creates PDFs using LaTeX.
42We recommend installing it via [MiKTeX].
38We recommend installing it via [MiKTeX].
43
39
MANUAL.txt+62−160
@@ -1,7 +1,7 @@
1---
1---
2title: Pandoc User's Guide
2title: Pandoc User's Guide
3author: John MacFarlane
3author: John MacFarlane
4−date: June 20, 2021
4+date: March 20, 2021
5---
5---
6
6
7# Synopsis
7# Synopsis
@@ -675,12 +675,12 @@ header when requesting a document from a URL:
675: Extract images and other media contained in or linked from
675: Extract images and other media contained in or linked from
676 the source document to the path *DIR*, creating it if
676 the source document to the path *DIR*, creating it if
677 necessary, and adjust the images references in the document
677 necessary, and adjust the images references in the document
678− so they point to the extracted files. Media are downloaded,
678+ so they point to the extracted files. If the source format is
679− read from the file system, or extracted from a binary
679+ a binary container (docx, epub, or odt), the media is
680− container (e.g. docx), as needed. The original file paths
680+ extracted from the container and the original
681− are used if they are relative paths not containing `..`.
681+ filenames are used. Otherwise the media is read from the
682− Otherwise filenames are constructed from the SHA1 hash of
682+ file system or downloaded, and new filenames are constructed
683− the contents.
683+ based on SHA1 hashes of the contents.
684
684
685`--abbreviations=`*FILE*
685`--abbreviations=`*FILE*
686
686
@@ -1415,12 +1415,13 @@ results only for basic math, usually you will want to use
1415`--gladtex`
1415`--gladtex`
1416
1416
1417: Enclose TeX math in `<eq>` tags in HTML output. The resulting HTML
1417: Enclose TeX math in `<eq>` tags in HTML output. The resulting HTML
1418− can then be processed by [GladTeX] to produce SVG images of the typeset
1418+ can then be processed by [GladTeX] to produce images of the typeset
1419− formulas and an HTML file with these images embedded.
1419+ formulas and an HTML file with links to these images.
1420+ So, the procedure is:
1420
1421
1421 pandoc -s --gladtex input.md -o myfile.htex
1422 pandoc -s --gladtex input.md -o myfile.htex
1422− gladtex -d image_dir myfile.htex
1423+ gladtex -d myfile-images myfile.htex
1423− # produces myfile.html and images in image_dir
1424+ # produces myfile.html and images in myfile-images
1424
1425
1425[MathML]: https://www.w3.org/Math/
1426[MathML]: https://www.w3.org/Math/
1426[MathJax]: https://www.mathjax.org
1427[MathJax]: https://www.mathjax.org
@@ -2314,8 +2315,8 @@ math equations flush left using [YAML metadata](#layout) or with
2314
2315
2315These affect HTML output when [producing slide shows with pandoc].
2316These affect HTML output when [producing slide shows with pandoc].
2316
2317
2317−`institute`
2318+All [reveal.js configuration options] are available as variables.
2318−: author affiliations: can be a list when there are multiple authors
2319+To turn off boolean flags that default to true in reveal.js, use `0`.
2319
2320
2320`revealjs-url`
2321`revealjs-url`
2321: base URL for reveal.js documents (defaults to
2322: base URL for reveal.js documents (defaults to
@@ -2335,9 +2336,6 @@ These affect HTML output when [producing slide shows with pandoc].
2335: additional attributes for the title slide of reveal.js slide shows.
2336: additional attributes for the title slide of reveal.js slide shows.
2336 See [background in reveal.js and beamer] for an example.
2337 See [background in reveal.js and beamer] for an example.
2337
2338
2338−All [reveal.js configuration options] are available as variables.
2339−To turn off boolean flags that default to true in reveal.js, use `0`.
2340−
2341[reveal.js configuration options]: https://revealjs.com/config/
2339[reveal.js configuration options]: https://revealjs.com/config/
2342
2340
2343### Variables for Beamer slides
2341### Variables for Beamer slides
@@ -3754,7 +3752,7 @@ definition:
3754Note that space between items in a definition list is required.
3752Note that space between items in a definition list is required.
3755(A variant that loosens this requirement, but disallows "lazy"
3753(A variant that loosens this requirement, but disallows "lazy"
3756hard wrapping, can be activated with `compact_definition_lists`: see
3754hard wrapping, can be activated with `compact_definition_lists`: see
3757−[Non-default extensions], below.)
3755+[Non-pandoc extensions], below.)
3758
3756
3759[^3]: I have been influenced by the suggestions of [David
3757[^3]: I have been influenced by the suggestions of [David
3760 Wheeler](https://justatheory.com/2009/02/modest-markdown-proposal/).
3758 Wheeler](https://justatheory.com/2009/02/modest-markdown-proposal/).
@@ -4179,12 +4177,10 @@ option is used. All of the metadata will appear in a single block
4179at the beginning of the document.
4177at the beginning of the document.
4180
4178
4181Note that [YAML] escaping rules must be followed. Thus, for example,
4179Note that [YAML] escaping rules must be followed. Thus, for example,
4182−if a title contains a colon, it must be quoted, and if it contains a
4180+if a title contains a colon, it must be quoted. The pipe character
4183−backslash escape, then it must be ensured that it is not treated as a
4184−[YAML escape sequence]. The pipe character (`|`) can be used to begin
4185−an indented block that will be interpreted literally, without need for
4181+(`|`) can be used to begin an indented block that will be interpreted
4186−escaping. This form is necessary when the field contains blank lines
4182+literally, without need for escaping. This form is necessary
4187−or block-level formatting:
4183+when the field contains blank lines or block-level formatting:
4188
4184
4189 ---
4185 ---
4190 title: 'This is the title: it contains a colon'
4186 title: 'This is the title: it contains a colon'
@@ -4198,12 +4194,6 @@ or block-level formatting:
4198 It consists of two paragraphs.
4194 It consists of two paragraphs.
4199 ...
4195 ...
4200
4196
4201−The literal block after the `|` must be indented relative to the
4202−line containing the `|`. If it is not, the YAML will be invalid
4203−and pandoc will not interpret it as metadata. For an overview
4204−of the complex rules governing YAML, see the [Wikipedia entry on
4205−YAML syntax].
4206−
4207Template variables will be set automatically from the metadata. Thus, for
4197Template variables will be set automatically from the metadata. Thus, for
4208example, in writing HTML, the variable `abstract` will be set to the HTML
4198example, in writing HTML, the variable `abstract` will be set to the HTML
4209equivalent of the Markdown in the `abstract` field:
4199equivalent of the Markdown in the `abstract` field:
@@ -4265,8 +4255,6 @@ following restrictions apply:
4265 example, you can't use a reference link in these contexts
4255 example, you can't use a reference link in these contexts
4266 if the link definition is somewhere else in the document.
4256 if the link definition is somewhere else in the document.
4267
4257
4268−[YAML escape sequence]: https://yaml.org/spec/1.2/spec.html#id2776092
4269−[Wikipedia entry on YAML syntax]: https://en.m.wikipedia.org/wiki/YAML#Syntax
4270
4258
4271## Backslash escapes
4259## Backslash escapes
4272
4260
@@ -4960,68 +4948,37 @@ Inline and regular footnotes may be mixed freely.
4960
4948
4961#### Extension: `citations` ####
4949#### Extension: `citations` ####
4962
4950
4963−To cite a bibliographic item with an identifier foo, use the
4951+Markdown citations go inside square brackets and are separated
4964−syntax `@foo`. Normal citations should be included in square
4952+by semicolons. Each citation must have a key, composed of '@' +
4965−brackets, with semicolons separating distinct items:
4953+the citation identifier from the database, and may optionally
4966−
4954+have a prefix, a locator, and a suffix. The citation key must
4967− Blah blah [@doe99; @smith2000; @smith2004].
4968−
4969−How this is rendered depends on the citation style. In an
4970−author-date style, it might render as
4971−
4972− Blah blah (Doe 1999, Smith 2000, 2004).
4973−
4974−In a footnote style, it might render as
4975−
4976− Blah blah.[^1]
4977−
4978− [^1]: John Doe, "Frogs," *Journal of Amphibians* 44 (1999);
4979− Susan Smith, "Flies," *Journal of Insects* (2000);
4980− Susan Smith, "Bees," *Journal of Insects* (2004).
4981−
4982−See the [CSL user documentation] for more information about CSL
4983−styles and how they affect rendering.
4984−
4985−Unless a citation key start with a letter, digit, or `_`,
4955+begin with a letter, digit, or `_`, and may contain
4986−and contains only alphanumerics and internal punctuation
4956+alphanumerics, `_`, and internal punctuation characters
4987−characters (`:.#$%&-+?<>~/`), it must be surrounded
4957+(`:.#$%&-+?<>~/`). Here are some examples:
4988−by curly braces, which are not considered part of the key.
4958+
4989−In `@Foo_bar.baz.`, the key is `Foo_bar.baz`. The final
4959+ Blah blah [see @doe99, pp. 33-35; also @smith04, chap. 1].
4990−period is not *internal* punctuation, so it is not included in
4960+
4991−the key. In `@{Foo_bar.baz.}`, the key is `Foo_bar.baz.`, including
4961+ Blah blah [@doe99, pp. 33-35, 38-39 and *passim*].
4992−the final period. The curly braces are recommended if you use URLs as
4962+
4993−keys: `[@{https://example.com/bib?name=foobar&date=2000}, p. 33]`.
4963+ Blah blah [@smith04; @doe99].
4994−
4964+
4995−Citation items may optionally include a prefix, a locator, and
4996−a suffix. In
4997−
4998− Blah blah [see @doe99, pp. 33-35 and *passim*; @smith04, chap. 1].
4999−
5000−The first item (`doe99`) has prefix `see `, locator `pp. 33-35`,
5001−and suffix `and *passim*`. The second item (`smith04`) has
5002−locator `chap. 1` and no prefix or suffix.
5003−
5004−Pandoc uses some heuristics to separate the locator from the
5005−rest of the subject. It is sensitive to the locator terms
5006−defined in the [CSL locale files]. Either abbreviated or
4965+`pandoc` detects locator terms in the [CSL locale files].
5007−unabbreviated forms are accepted. In the `en-US` locale, locator
4966+Either abbreviated or unabbreviated forms are accepted. In the `en-US`
5008−terms can be written in either singular or plural forms, as
4967+locale, locator terms can be written in either singular or plural forms,
5009−`book`, `bk.`/`bks.`; `chapter`, `chap.`/`chaps.`; `column`,
4968+as `book`, `bk.`/`bks.`; `chapter`, `chap.`/`chaps.`; `column`,
5010−`col.`/`cols.`; `figure`, `fig.`/`figs.`; `folio`,
4969+`col.`/`cols.`; `figure`, `fig.`/`figs.`; `folio`, `fol.`/`fols.`;
5011−`fol.`/`fols.`; `number`, `no.`/`nos.`; `line`, `l.`/`ll.`;
4970+`number`, `no.`/`nos.`; `line`, `l.`/`ll.`; `note`, `n.`/`nn.`; `opus`,
5012−`note`, `n.`/`nn.`; `opus`, `op.`/`opp.`; `page`, `p.`/`pp.`;
5013−`paragraph`, `para.`/`paras.`; `part`, `pt.`/`pts.`; `section`,
4971+`op.`/`opp.`; `page`, `p.`/`pp.`; `paragraph`, `para.`/`paras.`; `part`,
5014−`sec.`/`secs.`; `sub verbo`, `s.v.`/`s.vv.`; `verse`,
4972+`pt.`/`pts.`; `section`, `sec.`/`secs.`; `sub verbo`, `s.v.`/`s.vv.`;
5015−`v.`/`vv.`; `volume`, `vol.`/`vols.`; `¶`/`¶¶`; `§`/`§§`. If no
4973+`verse`, `v.`/`vv.`; `volume`, `vol.`/`vols.`; `¶`/`¶¶`; `§`/`§§`. If no
5016locator term is used, "page" is assumed.
4974locator term is used, "page" is assumed.
5017
4975
5018−In complex cases, you can force something to be treated as
4976+`pandoc` will use heuristics to distinguish the locator
5019−a locator by enclosing it in curly braces or prevent parsing
4977+from the suffix. In complex cases, the locator can be enclosed
5020−the suffix as locator by prepending curly braces:
4978+in curly braces:
5021
4979
5022 [@smith{ii, A, D-Z}, with a suffix]
4980 [@smith{ii, A, D-Z}, with a suffix]
5023 [@smith, {pp. iv, vi-xi, (xv)-(xvii)} with suffix here]
4981 [@smith, {pp. iv, vi-xi, (xv)-(xvii)} with suffix here]
5024− [@smith{}, 99 years later]
5025
4982
5026A minus sign (`-`) before the `@` will suppress mention of
4983A minus sign (`-`) before the `@` will suppress mention of
5027the author in the citation. This can be useful when the
4984the author in the citation. This can be useful when the
@@ -5029,26 +4986,13 @@ author is already mentioned in the text:
5029
4986
5030 Smith says blah [-@smith04].
4987 Smith says blah [-@smith04].
5031
4988
5032−You can also write an author-in-text citation, by omitting the
4989+You can also write an in-text citation, as follows:
5033−square brackets:
5034
4990
5035 @smith04 says blah.
4991 @smith04 says blah.
5036
4992
5037 @smith04 [p. 33] says blah.
4993 @smith04 [p. 33] says blah.
5038
4994
5039−This will cause the author's name to be rendered, followed by
5040−the bibliographical details. Use this form when you want to
5041−make the citation the subject of a sentence.
5042
4995
5043−When you are using a note style, it is usually better to let
5044−citeproc create the footnotes from citations rather than writing
5045−an explicit note. If you do write an explicit note that
5046−contains a citation, note that normal citations will be put in
5047−parentheses, while author-in-text citations will not. For
5048−this reason, it is sometimes preferable to use the
5049−author-in-text style inside notes when using a note style.
5050−
5051−[CSL user documentation]: https://citationstyles.org/authors/
5052[CSL]: https://docs.citationstyles.org/en/stable/specification.html
4996[CSL]: https://docs.citationstyles.org/en/stable/specification.html
5053[CSL markup specs]: https://docs.citationstyles.org/en/1.0/release-notes.html#rich-text-markup-within-fields
4997[CSL markup specs]: https://docs.citationstyles.org/en/1.0/release-notes.html#rich-text-markup-within-fields
5054[Chicago Manual of Style]: https://chicagomanualofstyle.org
4998[Chicago Manual of Style]: https://chicagomanualofstyle.org
@@ -5057,44 +5001,13 @@ author-in-text style inside notes when using a note style.
5057[finding and editing styles]: https://citationstyles.org/authors/
5001[finding and editing styles]: https://citationstyles.org/authors/
5058[CSL locale files]: https://github.com/citation-style-language/locales
5002[CSL locale files]: https://github.com/citation-style-language/locales
5059
5003
5060−## Non-default extensions
5004+## Non-pandoc extensions
5061
5005
5062The following Markdown syntax extensions are not enabled by default
5006The following Markdown syntax extensions are not enabled by default
5063in pandoc, but may be enabled by adding `+EXTENSION` to the format
5007in pandoc, but may be enabled by adding `+EXTENSION` to the format
5064name, where `EXTENSION` is the name of the extension. Thus, for
5008name, where `EXTENSION` is the name of the extension. Thus, for
5065example, `markdown+hard_line_breaks` is Markdown with hard line breaks.
5009example, `markdown+hard_line_breaks` is Markdown with hard line breaks.
5066
5010
5067−#### Extension: `rebase_relative_paths` ####
5068−
5069−Rewrite relative paths for Markdown links and images, depending
5070−on the path of the file containing the link or image link. For
5071−each link or image, pandoc will compute the directory of the
5072−containing file, relative to the working directory, and prepend
5073−the resulting path to the link or image path.
5074−
5075−The use of this extension is best understood by example.
5076−Suppose you have a a subdirectory for each chapter of a book,
5077−`chap1`, `chap2`, `chap3`. Each contains a file `text.md` and a
5078−number of images used in the chapter. You would like to have
5079−`![image](spider.jpg)` in `chap1/text.md` refer to
5080−`chap1/spider.jpg` and `![image](spider.jpg)` in `chap2/text.md`
5081−refer to `chap2/spider.jpg`. To do this, use
5082−
5083− pandoc chap*/*.md -f markdown+rebase_relative_paths
5084−
5085−Without this extension, you would have to use
5086−`![image](chap1/spider.jpg)` in `chap1/text.md` and
5087−`![image](chap2/spider.jpg)` in `chap2/text.md`. Links with
5088−relative paths will be rewritten in the same way as images.
5089−
5090−Absolute paths and URLs are not changed. Neither are empty
5091−paths or paths consisting entirely of a fragment, e.g., `#foo`.
5092−
5093−Note that relative paths in reference links and images will
5094−be rewritten relative to the file containing the link
5095−reference definition, not the file containing the reference link
5096−or image itself, if these differ.
5097−
5098#### Extension: `attributes` ####
5011#### Extension: `attributes` ####
5099
5012
5100Allows attributes to be attached to any inline or block-level
5013Allows attributes to be attached to any inline or block-level
@@ -5628,23 +5541,10 @@ A few other metadata fields affect bibliography formatting:
5628
5541
5629`lang`
5542`lang`
5630: The `lang` field will affect how the style is localized,
5543: The `lang` field will affect how the style is localized,
5631− for example in the translation of labels, the use
5544+ for example in the translation of labels and the use
5632− of quotation marks, and the way items are sorted.
5633− (For backwards compatibility, `locale` may be used instead
5545+ of quotation marks. (For backwards compatibility,
5546+ `locale` may be used instead of `lang`, but this use
5634− of `lang`, but this use is deprecated.)
5547+ is deprecated.)
5635−
5636− A BCP 47 language tag is expected: for example, `en`,
5637− `de`, `en-US`, `fr-CA`, `ug-Cyrl`. The unicode extension
5638− syntax (after `-u-`) may be used to specify options for
5639− collation (sorting) more precisely. Here are some examples:
5640−
5641− - `zh-u-co-pinyin` -- Chinese with the Pinyin collation.
5642− - `es-u-co-trad` -- Spanish with the traditional collation
5643− (with `Ch` sorting after `C`).
5644− - `fr-u-kb` -- French with "backwards" accent sorting
5645− (with `coté` sorting after `côte`).
5646− - `en-US-u-kf-upper` -- English with uppercase letters sorting
5647− before lower (default is lower before upper).
5648
5548
5649`notes-after-punctuation`
5549`notes-after-punctuation`
5650: If true (the default), pandoc will put footnote citations
5550: If true (the default), pandoc will put footnote citations
@@ -5656,6 +5556,12 @@ A few other metadata fields affect bibliography formatting:
5656 punctuation.
5556 punctuation.
5657
5557
5658
5558
5559+
5560+
5561+
5562+
5563+
5564+
5659# Slide shows
5565# Slide shows
5660
5566
5661You can use pandoc to produce an HTML + JavaScript slide presentation
5567You can use pandoc to produce an HTML + JavaScript slide presentation
@@ -5748,11 +5654,7 @@ rules:
5748 * A heading at the slide level always starts a new slide.
5654 * A heading at the slide level always starts a new slide.
5749
5655
5750 * Headings *below* the slide level in the hierarchy create
5656 * Headings *below* the slide level in the hierarchy create
5751− headings *within* a slide. (In beamer, a "block" will be
5657+ headings *within* a slide.
5752− created. If the heading has the class `example`, an
5753− `exampleblock` environment will be used; if it has the class
5754− `alert`, an `alertblock` will be used; otherwise a regular
5755− `block` will be used.)
5756
5658
5757 * Headings *above* the slide level in the hierarchy create
5659 * Headings *above* the slide level in the hierarchy create
5758 "title slides," which just contain the section title
5660 "title slides," which just contain the section title
@@ -6330,7 +6232,7 @@ Then edit `my.theme` and use it like this:
6330If you are not satisfied with the built-in highlighting, or you
6232If you are not satisfied with the built-in highlighting, or you
6331want highlight a language that isn't supported, you can use the
6233want highlight a language that isn't supported, you can use the
6332`--syntax-definition` option to load a [KDE-style XML syntax definition
6234`--syntax-definition` option to load a [KDE-style XML syntax definition
6333−file](https://docs.kde.org/stable5/en/kate/katepart/highlight.html).
6235+file](https://docs.kde.org/stable5/en/applications/katepart/highlight.html).
6334Before writing your own, have a look at KDE's [repository of syntax
6236Before writing your own, have a look at KDE's [repository of syntax
6335definitions](https://github.com/KDE/syntax-highlighting/tree/master/data/syntax).
6237definitions](https://github.com/KDE/syntax-highlighting/tree/master/data/syntax).
6336
6238
@@ -6504,9 +6406,9 @@ application, here are some things to keep in mind:
65044. The HTML generated by pandoc is not guaranteed to be safe.
64064. The HTML generated by pandoc is not guaranteed to be safe.
6505 If `raw_html` is enabled for the Markdown input, users can
6407 If `raw_html` is enabled for the Markdown input, users can
6506 inject arbitrary HTML. Even if `raw_html` is disabled,
6408 inject arbitrary HTML. Even if `raw_html` is disabled,
6507− users can include dangerous content in URLs and attributes.
6409+ users can include dangerous content in attributes for
6410+ headings, spans, and code blocks. To be safe, you should
6508− To be safe, you should run all the generated HTML through
6411+ run all the generated HTML through an HTML sanitizer.
6509− an HTML sanitizer.
6510
6412
6511# Authors
6413# Authors
6512
6414
SECURITY.mddeleted−12
@@ -1,12 +0,0 @@
1−# Security Policy
2−
3−## Supported Versions
4−
5−Only the most recent version of pandoc is supported with security updates.
6−
7−## Reporting a Vulnerability
8−
9−To report a vulnerability, email the maintainer, jgm@berkeley.edu.
10−But first please read the section of the manual entitled
11−[A note on security](https://pandoc.org/MANUAL.html#a-note-on-security),
12−which describes some security guarantees pandoc does NOT make.
cabal.project+4−9
@@ -2,12 +2,7 @@ packages: pandoc.cabal
2tests: True
2tests: True
3flags: +embed_data_files
3flags: +embed_data_files
4
4
5−source-repository-package
6− type: git
7− location: https://github.com/jgm/doctemplates
8− tag: 428c26d5303cf7a2b1051fe1ffd9aafe9ba71c81
9−
10−source-repository-package
5+-- source-repository-package
11− type: git
6+-- type: git
12− location: https://github.com/jgm/citeproc
7+-- location: https://github.com/jgm/citeproc
13− tag: 4ce0501cd6f9c86eee087afcf878c256e49b9615
8+-- tag: d44e24696ab444090d0e63e321c3a573f68b2e74
changelog.md−590
@@ -1,595 +1,5 @@
1# Revision history for pandoc
1# Revision history for pandoc
2
2
3−## pandoc 2.14.0.3 (2021-06-22)
4−
5− * Text.Pandoc.MediaBag `insertMediaBag`: ensure we get a sane mediaPath
6− for URLs (#7391). In earlier 2.14.x versions, we'd get
7− incorrect paths for resources downloaded from URLs when the
8− media are extracted (including in PDF production).
9− * Text.Pandoc.Parsing: improve `emailAddress` (#7398).
10− Previously the parser would accept characters in domains
11− that are illegal in domains, and this sometimes caused it
12− to gobble bits of the following text.
13− * txt2tags reader: modify the email address parser so
14− it still includes form parameters, even after the change to
15− `emailAddress` in Text.Pandoc.Parsing.
16− * Text.Pandoc.Readers.Metadata: Fix regression with comment-only YAML
17− metadata blocks (#7400).
18− * reveal.js writer and template: better handling of options. Previously
19− it was impossible to specify false values for options that default to
20− true (e.g. `center`); setting the option to false just caused the portion
21− of the template setting the option to be omitted. Now we prepopulate
22− all the variables with their default values, including them all
23− unconditionally and allowing them to be overridden.
24− * Markdown writer: Fix regression in code blocks with attributes (#7397).
25− Code blocks with a single class but nonempty attributes
26− were having attributes drop as a result of #7242.
27− * LaTeX writer:
28− + Add strut at end of minipage if it contains line breaks.
29− Without them, the last line is not as tall as it should be in
30− some cases.
31− + Always use a minipage for cells with line breaks, when
32− width information is available (#7393). Otherwise the way we treat them
33− can lead to content that overflows a cell.
34− + Use `\strut` instead of `~` before `\\` in empty line.
35− * Use lts-18.0 stack resolver.
36− * Require skylighting 0.10.5.2 (adding support for Swift).
37− * Require commonmark 0.2.1.
38− * Rephrase section on unsafe HTML in manual.
39− * Create SECURITY.md
40−
41−## pandoc 2.14.0.2 (2021-06-13)
42−
43− * Fix MediaBag regressions (#7345). iIn the 2.14 release `--extract-media`
44− stopped working as before; there could be mismatches between the
45− paths in the rendered document and the extracted media.
46− This patch makes several changes that restore the earlier behavior
47− (while keeping the same API). The `mediaPath` in 2.14 was always
48− constructed from the SHA1 hash of the media contents. Now, we
49− preserve the original path unless it's an absolute path or contains
50− `..` segments (in that case we use a path based on the SHA1 hash of
51− the contents).
52−
53− In Text.Pandoc.MediaBag, `mediaDirectory` and `mediaItems` now use the
54− `mediaPath`, rather than the mediabag key, for the first component of the
55− tuple. This makes more sense, I think, and fits with the documentation of
56− these functions; eventually, though, we should rework the API so that
57− `mediaItems` returns both the keys and the MediaItems.
58−
59− In Text.Pandoc.Class.IO, rewriting of source paths in `extractMedia` has
60− been fixed.
61−
62− In Text.Pandoc.Class.PandocMonad, `fillMediaBag` has been modified so that
63− it doesn't modify image paths (that was part of the problem in #7345).
64−
65− We now do path normalization (e.g. `\` separators on Windows) in
66− writing the media.
67−
68− * Text.Pandoc.PDF:
69−
70− + Text.Pandoc.PDF: Fix regression in 2.14 for generation of PDFs with
71− SVGs (#7344).
72− + Only print relevant part of environment on `--verbose`. Since
73− `--verbose` output might be put in an issue, we want to avoid
74− spilling out secrets in environment variables.
75−
76− * Markdown reader: fix pipe table regression in 2.11.4 (#7343).
77− Previously pipe tables with empty headers (that is, a header
78− line with all empty cells) would be rendered as headerless
79− tables. This broke in 2.11.4. The fix here is to produce an
80− AST with an empty table head when a pipe table has all empty
81− header cells.
82−
83− * LaTeX reader: don't allow optional `*` on symbol control sequences
84− (#7340). Generally we allow optional starred variants of LaTeX commands
85− (since many allow them, and if we don't accept these explicitly,
86− ignoring the star usually gives acceptable results). But we
87− don't want to do this for `\(*\)` and similar cases.
88−
89− * Docx reader: handle absolute URIs in Relationship Target (#7374).
90−
91− * Docx writer: fix handling of empty table headers (Albert Krewinkel,
92− #7369). A table header which does not contain any cells is now treated as
93− an empty header.
94−
95− * LaTeX writer: Fix regression in table header position (#7347).
96− In recent versions the table headers were no longer bottom-aligned
97− (if more than one line). This patch fixes that by using minipages
98− for table headers in non-simple tables.
99−
100− * CommonMark writer:
101−
102− + Do not use simple class for fenced-divs (Jan Tojnar, amends #7242.)
103− + Do not throw away attributes when `Ext_attributes` is enabled.
104− `Ext_attributes` covers at least the following:
105− `Ext_fenced_code_attributes`, `Ext_header_attributes`,
106− `Ext_inline_code_attributes`, `Ext_link_attributes`.
107−
108− * Markdown writer:
109−
110− + Allow `pipe_tables` to be disabled for commonmark formats
111− (`commonmark_x`, `gfm`) (#7375).
112− + Re-use functions from Text.Pandoc.Markdown.Inline (Jan Tojnar).
113−
114− * DocBook writer: Remove non-existent admonitions (Jan Tojnar).
115− `attention`, `error` and `hint` are reStructuredText specific.
116−
117− * HTML writer: Don't omit width attribute on div (#7342).
118−
119− * Text.Pandoc.MIME, `extensionFromMimeType`: add a few special cases.
120− When we do a reverse lookup in the MIME table, we just get the
121− last match, so when the same mime type is associated with several
122− different extensions, we sometimes got weird results, e.g. `.vs`
123− for `text/plain`. These special cases help us get the most standard
124− extensions for mime types like `text/plain`.
125−
126− * Lua utils: fix handling of table headers in `from_simple_table` (Albert
127− Krewinkel, #7369). Passing an empty list of header cells now results
128− in an empty table header.
129−
130− * Text.Pandoc.Citeproc:
131−
132− + Avoid duplicate classes and attributes on references div.
133− + Fix regression in citeproc processing (#7376). If inline
134− references are used (in the metadata `references` field), we
135− should still only include in the bibliography items that are
136− actually cited (unless `nocite` is used).
137−
138− * Require citeproc 0.4.0.1. This fixes a bug which led to doubled
139− "et al." in some (rare) circumstances.
140−
141− * MANUAL.txt:
142−
143− + Mention GladTeX for EPUB export (Sebastian Humenda).
144− This updates the manual and the web site about the GladTeX usage.
145− + More details and a useful link for YAML syntax.
146−
147− * CONTRIBUTING.md: update modules overview (Albert Krewinkel).
148−
149− * using-the-pandoc-api.md: switch from String to Text (Albert Krewinkel).
150−
151−
152−## pandoc 2.14.0.1 (2021-06-01)
153−
154− * Commonmark reader: Fix regression in 2.14 with YAML metdata block parsing,
155− which could cause the document body to be omitted after metadata (#7339).
156−
157− * HTML reader: fix column width regression in 2.14 (#7334).
158− Column widths specified with a style attribute were off by a factor of 100.
159−
160− * Markdown reader: in `rebasePaths`, check for both Windows and Posix
161− absolute paths. Previously Windows pandoc was treating
162− `/foo/bar.jpg` as non-absolute.
163−
164− * Text.Pandoc.Logging: In rendering `LoadedResource`, use relative paths.
165−
166− * Docx writer: fix regression on captions (#7328). The "Table Caption"
167− style was no longer getting applied. (It was overwritten by "Compact.")
168−
169− * Use commonmark-extensions 0.2.1.2
170−
171−## pandoc 2.14 (2021-05-28)
172−
173− * Change reader types, allowing better tracking of source positions
174− [API change]. Previously, when multiple file arguments were provided,
175− pandoc simply concatenated them and passed the contents to the readers,
176− which took a Text argument. As a result, the readers had no way of knowing
177− which file was the source of any particular bit of text. This meant that
178− we couldn't report accurate source positions on errors or include accurate
179− source positions as attributes in the AST. More seriously, it meant that
180− we couldn't resolve resource paths relative to the files containing them
181− (see e.g. #5501, #6632, #6384, #3752).
182−
183− * Add `rebase_relative_paths` extension (#3752). When enabled, this
184− extension rewrites relative image and link paths by prepending
185− the (relative) directory of the containing file. This
186− behavior is useful when your input sources are split
187− into multiple files, across several directories, with files
188− referring to images stored in the same directory. The
189− extension can be enabled for all markdown and commonmark-based formats.
190−
191− * Add Text.Pandoc.Sources (exported module), with a `Sources` type and a
192− `ToSources` class. A `Sources` wraps a list of `(SourcePos, Text)` pairs
193− [API change]. A parsec `Stream` instance is provided for `Sources`. The
194− module also exports versions of parsec's `satisfy` and other Char parsers
195− that track source positions accurately from a `Sources` stream (or any
196− instance of the new `UpdateSourcePos` class).
197−
198− * Text.Pandoc.Parsing
199−
200− + Export the modified Char parsers defined in Text.Pandoc.Sources
201− instead of the ones parsec provides. Modified parsers to use a
202− `Sources` as stream [API change].
203− + Improve include file functions [API change]. Remove old
204− `insertIncludedFileF`. Give `insertIncludedFile` a more general type,
205− allowing it to be used where `insertIncludedFileF` was.
206− + Add parameter to the `citeKey` parser from
207− Text.Pandoc.Parsing, which controls whether the `@{..}`
208− syntax is allowed [API change].
209−
210− * Text.Pandoc.Error: Modified the constructor `PandocParsecError` to take a
211− `Sources` rather than a `Text` as first argument, so parse error locations
212− can be accurately reported.
213−
214− * Fix source position reporting for YAML bibliographies (#7273).
215−
216− * Issue error message when reader or writer format is malformed
217− (#7231). Previously we exited with an error status but (due to a bug)
218− no message.
219−
220− * Smarter smart quotes (#7216, #2103). Treat a leading `"` with no
221− closing `"` as a left curly quote. This supports the practice, in
222− fiction, of continuing paragraphs quoting the same speaker without an
223− end quote. It also helps with quotes that break over lines in line blocks.
224−
225− * Markdown reader:
226−
227− + Use MetaInlines not MetaBlocks for multimarkdown metadata fields.
228− This gives better results in converting to e.g. pandoc markdown.
229− + Implement curly-brace syntax for Markdown citation keys (#6026).
230− The change provides a way to use citation keys that contain
231− special characters not usable with the standard citation key syntax.
232− Example: `@{foo_bar{x}'}` for the key `foo_bar{x}`. It also allows
233− separating citation keys from immediately following text, e.g. `@{foo}A`.
234−
235− * RST reader:
236−
237− + Seek include files in the directory of the file
238− containing the include directive, as RST requires (#6632).
239− + Use `insertIncludedFile` from Text.Pandoc.Parsing
240− instead of reproducing much of its code.
241−
242− * Org reader: Resolve org includes relative to the directory containing the
243− file containing the INCLUDE directive (#5501).
244−
245− * ODT reader: Treat tabs as spaces (#7185, niszet).
246−
247− * Docx reader:
248−
249− + Add handling of vml image objects (#7257, mbrackeantidot).
250− + Support new table features (Emily Bourke, #6316): column
251− spans, row spans, multiple header rows, table description
252− (parsed as a simple caption), captions, column widths.
253−
254− * LaTeX reader:
255−
256− + Improved siunitx support (#6658, #6620).
257− + Better support for `\xspace` (#7299).
258− + Improve parsing of `\def` macros. We previously set "verbatim mode"
259− even for parsing the initial `\def`; this caused problems
260− for `\def` nested inside another `\def`.
261− + Implement `\newif`.
262−
263− * ConTeXt writer: improve ordered lists (#5016, Denis Maier).
264− Change ordered list from itemize to enumerate. Add new
265− itemgroup for ordered lists. Remove manual insertion of
266− width attributes. Use tabular figures in ordered list
267− enumerators.
268−
269− * HTML reader:
270−
271− + Don't fail on unmatched closing "script" tag (Albert Krenkel, #7282).
272− + Keep h1 tags as normal headers (#2293, Albert Krewinkel).
273− The tags `<title>` and `<h1 class="title">` often contain the same
274− information, so the latter was dropped from the document. However, as
275− this can lead to loss of information, the heading is now always
276− retained. Use `--shift-heading-level-by=-1` to turn the `<h1>`
277− into the document title, or a filter to restore the previous behavior.
278− + Handle relative lengths (e.g. `2*`) in HTML column widths (#4063).
279− See <https://www.w3.org/TR/html4/types.html#h-6.6>.
280−
281− * DocBook/JATS readers:
282−
283− + Fix mathml regression caused by the switch in XML libraries (#7173).
284− + Fix "phrase" in DocBook: take classes from "role" not "class" (#7195).
285−
286− * DocBook reader: ensure that first and last names are separated (#6541).
287−
288− * Jira reader (Albert Krewinkel, #7218):
289−
290− + Support "smart" links: `[alias|https://example.com|smart-card]` syntax.
291− + Allow spaces and most unicode characters in attachment links.
292− + No longer require a newline character after `{noformat}`.
293− + Only allow URI path segment characters in bare links.
294− + The `file:` schema is no longer allowed in bare links; these
295− rarely make sense.
296−
297− * Plain writer: handle superscript unicode minus (#7276).
298−
299− * LaTeX writer:
300−
301− + Better handling of line breaks in simple tables (#7272).
302− Now we also handle the case where they're embedded in other elements,
303− e.g. spans.
304− + For beamer output, support `exampleblock` and `alertblock` (#7278).
305− A block will be rendered as an `exampleblock` if the heading
306− has class `example` and an `alertblock` if it has class `alert`.
307− + Separate successive quote chars with thin space (#6958,
308− Albert Krewinkel). Successive quote characters are separated with
309− a thin space to improve readability and to prevent unwanted ligatures.
310− Detection of these quotes sometimes had failed if the second quote
311− was nested in a span element.
312− + Separate successive quote chars with thin space (#6958, Albert
313− Krewinkel).
314−
315− * EPUB Writer: Fix belongs-to-collection XML id choice (#7267, nuew).
316− The epub writer previously used the same XML id for both the book
317− identifier and the epub collection. This causes an error on epubcheck.
318−
319− * BibTeX/BibLaTeX writer: Handle `annote` field (#7266).
320−
321− * ZimWiki writer: allow links and emphasis in headers (#6605,
322− Albert Krewinkel).
323−
324− * ConTeXt writer:
325−
326− + Support blank lines in line blocks (#6564, Albert Krewinkel,
327− thanks to @denismaier).
328− + Use span identifiers as reference anchors (#7246, Albert Krewinkel).
329−
330− * HTML writer:
331−
332− + Keep attributes from code nested below `pre` tag (#7221,
333− Albert Krewinkel). If a code block is defined with `<pre><code
334− class="language-x">…</code></pre>`, where the `<pre>` element has no
335− attributes, then the attributes from the `<code>` element are used
336− instead. Any leading `language-` prefix is dropped in the code's
337− `class` attribute are dropped to improve syntax highlighting.
338− + Ensure headings only have valid attribs in HTML4 (#5944, Albert
339− Krewinkel).
340− + Parse `<header>` as a Div (Albert Krewinkel).
341−
342− * Org writer:
343−
344− + Inline latex envs need newlines (#7252, tecosaur).
345− As specified in https://orgmode.org/manual/LaTeX-fragments.html, an
346− inline \begin{}...\end{} LaTeX block must start on a new line.
347− + Use LaTeX style maths deliminators (#7196, tecosaur).
348−
349− * JATS writer (Albert Krewinkel):
350−
351− + Use either styled-content or named-content for spans (#7211).
352− If the element has a content-type attribute, or at least one class,
353− then that value is used as `content-type` and the span is put inside
354− a `<named-content>` element. Otherwise a `<styled-content>` element
355− is used instead.
356− + Reduce unnecessary use of `<p>` elements for wrapping (#7227).
357− The `<p>` element is used for wrapping in cases were the contents
358− would otherwise not be allowed in a certain context. Unnecessary
359− wrapping is avoided, especially around quotes (`<disp-quote>` elements).
360− + Convert spans to `<named-content>` elements (#7211). Spans with
361− attributes are converted to `<named-content>` elements instead of
362− being wrapped with `<milestone-start/>` and `<milestone-end>`
363− elements. Milestone elements are not allowed in documents using the
364− articleauthoring tag set, so this change ensures the creation of valid
365− documents.
366− + Add footnote number as label in backmatter (#7210). Footnotes in the
367− backmatter are given the footnote's number as a label. The
368− articleauthoring output is unaffected from this change, as footnotes
369− are placed inline there.
370− + Escape disallows chars in identifiers. XML identifiers must start
371− with an underscore or letter, and can contain only a limited set
372− of punctuation characters. Any IDs not adhering to these rules are
373− rewritten by writing the offending characters as `Uxxxx`,
374− where `xxxx` is the character's hex code.
375−
376− * Jira writer: use `{color}` when span has a color attribute
377− (Albert Krewinkel, tarleb/jira-wiki-markup#10).
378−
379− * Docx writer:
380−
381− + Autoset table width if no column has an explicit width (Albert
382− Krewinkel).
383− + Extract Table handling into separate module (Albert Krewinkel).
384− + Support colspans and rowspans in tables (Albert Krewinkel, #6315).
385− + Support multirow table headers (Albert Krewinkel).
386− + Improve integration of settings from reference.docx (#1209).
387− This change allows users to create a reference.docx that
388− sets `w:proofState` for spelling or grammar to `dirty`,
389− so that spell/grammar checking will be triggered on the
390− generated docx.
391− + Copy over more settings from reference.docx (#7240). From settings.xml
392− in the reference-doc, we now include: `zoom`, `embedSystemFonts`,
393− `doNotTrackMoves`, `defaultTabStop`, `drawingGridHorizontalSpacing`,
394− `drawingGridVerticalSpacing`, `displayHorizontalDrawingGridEvery`,
395− `displayVerticalDrawingGridEvery`, `characterSpacingControl`,
396− `savePreviewPicture`, `mathPr`, `themeFontLang`, `decimalSymbol`,
397− `listSeparator`, `autoHyphenation`, `compat`.
398− + Set zoom to 100% by default in settings.xml.
399− + Align math options more with current Word defaults (e.g. Cambria Math
400− font).
401− + Remove `rsid`s from default settings.xml. Word will add these
402− when revisions are made.
403−
404− * Ms writer: Handle tables with multiple paragraphs (#7288).
405− Previously they overflowed the table cell width. We now set line lengths
406− per-cell and restore them after the table has been written.
407−
408− * Markdown writer:
409−
410− + Use cleaner braceless syntax for code blocks with a
411− single class (#7242, Jan Tojnar).
412− + Add quotes properly in markdown YAML metadata fields (#7245).
413− This fixes a bug, which caused the writer to look at the *last*
414− rather than the *first* character in determining whether quotes
415− were needed. So we got spurious quotes in some cases and
416− didn't get necessary quotes in others.
417− + Use `@{..}` syntax for citations when needed.
418− + Use fewer unneeded escapes for `#` (see #6259).
419− + Improve escaping of `@`. We need to escape literal `@` before
420− `{` because of the new citation syntax.
421−
422− * Commonmark writer: Use backslash escapes for `<` and `|`...
423− instead of entities (#7208).
424−
425− * Powerpoint writer: allow `monofont` to be specified in metadata
426− (#7187).
427−
428− * LaTeX template:
429−
430− + Use non-starred names for xcolor color names (#6109).
431− This should make svgnames and x11names work properly.
432− + Fix bad vertical spacing after bibliography (#7234, badumont).
433− + List of figures before list of tables (#7235, Julien Dutant).
434− + Move CSL macro definitions before header-includes so they can be
435− overridden (#7286).
436− + Improve treatment of CSL `entry-spacing` (#7296).
437− Previously with the default template settings (`indent` variable
438− not set), we would get interparagraph spaces separating bib
439− entries even with `entry-spacing="0"`. On the other hand,
440− setting `entry-spacing="2"` gave ridiculously large spacing.
441− This change makes the spacing caused by `entry-spacing` a multiple
442− of `\parskip` by default, which gives aesthetically reasonable
443− output. Those who want a larger or smaller unit (e.g. because
444− they use `indent` which sets `\parskip` to 0) may
445− `\setlength{\cslentryspacingunit}{10pt}` in header-includes
446− to override the defaults.
447− + Move title, author, date up to top of preamble (#7295).
448− This allows header-includes to use them, and puts them
449− in a position where you can see them immediately.
450− + Define commands for zero width non-joiner character
451− (#6639, Albert Krewinkel). The zero-width non-joiner character
452− is used to avoid ligatures (e.g. in German).
453−
454− * ConTeXt template:
455−
456− + Define `enumerate` itemgroup (#5016, Denis Maier).
457− + List of figures before list of tables (#7235, Julien Dutant).
458−
459− * reveal.js template:
460−
461− + Support `toc-title` (#7171, Florian Kohrt).
462− + Use `hash: true` by default rather than `history: true` (#6968).
463−
464− * HTML-based slide shows: add support for `institute` (#7289, Thomas
465− Hodgson).
466−
467− * Text.Pandoc.Extensions: Add constructor `Ext_rebase_relative_paths` to
468− `Extensions` [API change].
469−
470− * Text.Pandoc.XML.Light: add Eq, Ord instances for Content,
471− Element, Attr, CDataKind [API change].
472−
473− * Text.Pandoc.MediaBag:
474−
475− + Change type to use a `Text` key instead of `[FilePath]`.
476− We normalize the path and use `/` separators for consistency.
477− + Export `MediaItem` type [API change].
478− + Change `MediaBag` type to a map from Text to MediaItem [API change].
479− + `lookupMedia` now returns a `MediaItem` [API change].
480− + Change `insertMedia` so it sets the `mediaPath` to a filename based on
481− the SHA1 hash of the contents. This will be used when contents
482− are extracted.
483−
484− * Text.Pandoc.Class.PandocMonad:
485−
486− + Remove `fetchMediaResource` [API change]. Use `fetchItem` to get
487− resources in `fillMediaBag`.
488− + Add informational message in `downloadOrRead` indicating what path
489− local resources have been loaded from.
490−
491− * Text.Pandoc.Logging:
492−
493− + Remove single quotes around paths in messages.
494− + Add LoadedResource constructor to LogMessage [API change].
495− This is for INFO-level messages telling where image data has been
496− loaded from. (This can vary because of the resource path.)
497−
498− * Text.Pandoc.Asciify: simplify code and export `toAsciiText` [API change].
499− Instead of encoding a giant (and incomplete) map, we now
500− just use unicode-transforms to normalize the text to
501− a canonical decomposition, and manipulate the result.
502−
503− * App: allow tabs expansion even if file-scope is used (Albert Krewinkel,
504− #6709). Tabs in plain-text inputs are now handled correctly, even if
505− the `--file-scope` flag is used.
506−
507− * Add new internal module Text.Pandoc.Writers.GridTable (Albert Krewinkel).
508−
509− * Text.Pandoc.Highlighting: Change type of `languagesByExtension`, adding
510− a parameter for a `SyntaxMap` [API change] (Jan Tojnar, #7241).
511− Languages defined using `--syntax-definition` were not recognized by
512− `languagesByExtension`. This patch corrects that, allowing the writers
513− to see all custom definitions. The LaTeX writer still uses the default
514− syntax map, but that's okay in that context, since
515− `--syntax-definition` won't create new listings styles.
516−
517− * Text.Pandoc.Citeproc:
518−
519− + Ensure that CSL-related attributes are passed on to a Div with id
520− 'refs'. Otherwise things like `entry-spacing` won't work when
521− such Divs are used.
522− + Use metadata's `lang` for the lang parameter of citeproc, overriding
523− `localeLanguage`.
524− + Recognize locators spelled with a capital letter (#7323).
525− + Add a comma and a space in front of the suffix if it doesn't start
526− with space or punctuation (#7324).
527− + Don't detect math elements as locators (#7321).
528−
529− * Remove Text.Pandoc.BCP47 module [API change]. Use types and functions
530− from UnicodeCollation.Lang instead. This is a richer implementation
531− of BCP 47.
532−
533− * Text.Pandoc.Shared:
534−
535− + Fix regression in grid tables for wide characters (#7214).
536− In the translation from String to Text, a char-width-sensitive
537− `splitAt'` was dropped. This commit reinstates it and uses it to make
538− `splitTextByInstances` char-width sensitive.
539− + Add `getLang` (formerly in the now-removed BCP47) [API change].
540−
541− * Text.Pandoc.SelfContained: use `application/octet-stream`
542− for unknown mime types instead of halting with an error (#7202).
543−
544− * Lua filters: respect Inlines/Blocks filter functions in `pandoc.walk_*`
545− (Albert Krewinkel).
546−
547− * Add text as build-depend for trypandoc (#7193, Roman Beránek).
548−
549− * Bump upper-bounds for network-uri, time, attoparsec.
550−
551− * Use citeproc 0.4.
552−
553− * Use texmath 0.12.3.
554−
555− * Use jira-wiki-markup 1.3.5 (Albert Krewinkel).
556−
557− * Require latest skylighting (fixes a bug in XML syntax highlighting).
558−
559− * Use latest xml-conduit.
560−
561− * Use latest commonmark, commonmark-extensions, commonmark-pandoc.
562−
563− * Use haddock-library-1.10.0 (Albert Krewinkel).
564−
565− * Allow compilation with base 4.15 (Albert Krewinkel).
566−
567− * MANUAL:
568−
569− + Add information about `lang` and bibliography sorting.
570− + Add info about YAML escape sequences, link to spec (#7152,
571− Albert Krewinkel).
572− + Note that `institute` variable works for HTML-based slides.
573− + Update documentation on citation syntax.
574− + Add citation example for locators and suffixes (Tristan Stenner)
575−
576− * Updated and fixed typos in documentation (Charanjit Singh,
577− Anti-Distinctlyminty, Tatiana Porras, obcat).
578−
579− * Add instructions for installing pandoc-types before compiling filter.
580−
581− * INSTALL: add note that parallel installations should be avoided
582− (#6865).
583−
584− * Remove `biblatex-nussbaum.md` test. It is basically the same
585− as `biblaetx-quotes.md`.
586−
587− * Command tests: fail if a file contains no tests---and fix a
588− test that failed in that way!
589−
590− * Use smaller images in tests, reducing the size of the source tarball by 8 MB.
591−
592−
593## pandoc 2.13 (2021-03-21)
3## pandoc 2.13 (2021-03-21)
594
4
595 * Support `yaml_metadata_block` extension for `commonmark`, `gfm` (#6537).
5 * Support `yaml_metadata_block` extension for `commonmark`, `gfm` (#6537).
data/docx/word/settings.xml+16−6
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
1<?xml version="1.0" encoding="UTF-8"?>
2<w:settings xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main">
2<w:settings xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main">
3− <w:zoom w:percent="100" />
3+ <w:zoom w:percent="90" />
4 <w:embedSystemFonts />
4 <w:embedSystemFonts />
5 <w:proofState w:spelling="clean" w:grammar="clean" />
5 <w:proofState w:spelling="clean" w:grammar="clean" />
6 <w:stylePaneFormatFilter w:val="0004" />
6 <w:stylePaneFormatFilter w:val="0004" />
@@ -17,21 +17,31 @@
17 <w:characterSpacingControl w:val="doNotCompress" />
17 <w:characterSpacingControl w:val="doNotCompress" />
18 <w:savePreviewPicture />
18 <w:savePreviewPicture />
19 <w:rsids>
19 <w:rsids>
20+ <w:rsidRoot w:val="00590D07" />
21+ <w:rsid w:val="00011C8B" />
22+ <w:rsid w:val="004E29B3" />
23+ <w:rsid w:val="00590D07" />
24+ <w:rsid w:val="00784D58" />
25+ <w:rsid w:val="008D6863" />
26+ <w:rsid w:val="00B86B75" />
27+ <w:rsid w:val="00BC48D5" />
28+ <w:rsid w:val="00C36279" />
29+ <w:rsid w:val="00E315A3" />
20 </w:rsids>
30 </w:rsids>
21 <m:mathPr>
31 <m:mathPr>
22− <m:mathFont m:val="Cambria Math" />
32+ <m:mathFont m:val="Lucida Grande" />
23 <m:brkBin m:val="before" />
33 <m:brkBin m:val="before" />
24 <m:brkBinSub m:val="--" />
34 <m:brkBinSub m:val="--" />
25− <m:smallFrac m:val="0" />
35+ <m:smallFrac m:val="false" />
26− <m:dispDef />
36+ <m:dispDef m:val="false" />
27 <m:lMargin m:val="0" />
37 <m:lMargin m:val="0" />
28 <m:rMargin m:val="0" />
38 <m:rMargin m:val="0" />
29 <m:wrapRight />
39 <m:wrapRight />
30 <m:intLim m:val="subSup" />
40 <m:intLim m:val="subSup" />
31− <m:naryLim m:val="undOvr" />
41+ <m:naryLim m:val="subSup" />
32 </m:mathPr>
42 </m:mathPr>
33 <w:themeFontLang w:val="en-US" />
43 <w:themeFontLang w:val="en-US" />
34 <w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink" />
44 <w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink" />
35 <w:decimalSymbol w:val="." />
45 <w:decimalSymbol w:val="." />
36 <w:listSeparator w:val="," />
46 <w:listSeparator w:val="," />
37−</w:settings>
47+</w:settings>
data/templates/default.context+3−7
@@ -51,7 +51,6 @@ $endif$
51
51
52% use microtypography
52% use microtypography
53\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
53\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
54−\definefontfeature[default:tnum][default][tnum=yes, pnum=no]
55\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
54\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
56\setupalign[hz,hanging]
55\setupalign[hz,hanging]
57\setupitaliccorrection[global, always]
56\setupitaliccorrection[global, always]
@@ -98,9 +97,6 @@ $endif$
98\setupitemize[autointro] % prevent orphan list intro
97\setupitemize[autointro] % prevent orphan list intro
99\setupitemize[indentnext=no]
98\setupitemize[indentnext=no]
100
99
101−\defineitemgroup[enumerate]
102−\setupenumerate[each][fit][itemalign=left,distance=.5em,style={\feature[+][default:tnum]}]
103−
104\setupfloat[figure][default={here,nonumber}]
100\setupfloat[figure][default={here,nonumber}]
105\setupfloat[table][default={here,nonumber}]
101\setupfloat[table][default={here,nonumber}]
106
102
@@ -164,12 +160,12 @@ $endfor$
164$if(toc)$
160$if(toc)$
165\completecontent
161\completecontent
166$endif$
162$endif$
167−$if(lof)$
168−\completelistoffigures
169−$endif$
170$if(lot)$
163$if(lot)$
171\completelistoftables
164\completelistoftables
172$endif$
165$endif$
166+$if(lof)$
167+\completelistoffigures
168+$endif$
173
169
174$body$
170$body$
175
171
data/templates/default.dzslides+1−1
@@ -171,7 +171,7 @@ $if(subtitle)$
171 <h1 class="subtitle">$subtitle$</h1>
171 <h1 class="subtitle">$subtitle$</h1>
172$endif$
172$endif$
173 <footer>
173 <footer>
174− $if(author)$<span class="author">$for(author)$$author$$sep$, $endfor$</span> · $endif$$if(institute)$<span class="institute">$for(institute)$$institute$$sep$, $endfor$</span> · $endif$$if(date)$<span class="date">$date$</span>$endif$
174+ $if(author)$<span class="author">$for(author)$$author$$sep$, $endfor$</span>$endif$ · $if(date)$<span class="date">$date$</span>$endif$
175 </footer>
175 </footer>
176</section>
176</section>
177$endif$
177$endif$
data/templates/default.latex+26−48
@@ -2,7 +2,7 @@
2\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
2\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
3\PassOptionsToPackage{hyphens}{url}
3\PassOptionsToPackage{hyphens}{url}
4$if(colorlinks)$
4$if(colorlinks)$
5−\PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor}
5+\PassOptionsToPackage{dvipsnames,svgnames*,x11names*}{xcolor}
6$endif$
6$endif$
7$if(dir)$
7$if(dir)$
8$if(latex-dir-rtl)$
8$if(latex-dir-rtl)$
@@ -156,25 +156,6 @@ $if(CJKmainfont)$
156 \fi
156 \fi
157$endif$
157$endif$
158\fi
158\fi
159−$if(zero-width-non-joiner)$
160−%% Support for zero-width non-joiner characters.
161−\makeatletter
162−\def\zerowidthnonjoiner{%
163− % Prevent ligatures and adjust kerning, but still support hyphenating.
164− \texorpdfstring{%
165− \textormath{\nobreak\discretionary{-}{}{\kern.03em}%
166− \ifvmode\else\nobreak\hskip\z@skip\fi}{}%
167− }{}%
168−}
169−\makeatother
170−\ifPDFTeX
171− \DeclareUnicodeCharacter{200C}{\zerowidthnonjoiner}
172−\else
173− \catcode`^^^^200c=\active
174− \protected\def ^^^^200c{\zerowidthnonjoiner}
175−\fi
176−%% End of ZWNJ support
177−$endif$
178$if(beamer)$
159$if(beamer)$
179$if(theme)$
160$if(theme)$
180\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$}
161\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$}
@@ -344,31 +325,6 @@ $endif$
344$if(pagestyle)$
325$if(pagestyle)$
345\pagestyle{$pagestyle$}
326\pagestyle{$pagestyle$}
346$endif$
327$endif$
347−$if(csl-refs)$
348−\newlength{\cslhangindent}
349−\setlength{\cslhangindent}{1.5em}
350−\newlength{\csllabelwidth}
351−\setlength{\csllabelwidth}{3em}
352−\newlength{\cslentryspacingunit} % times entry-spacing
353−\setlength{\cslentryspacingunit}{\parskip}
354−\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing
355− {% don't indent paragraphs
356− \setlength{\parindent}{0pt}
357− % turn on hanging indent if param 1 is 1
358− \ifodd #1
359− \let\oldpar\par
360− \def\par{\hangindent=\cslhangindent\oldpar}
361− \fi
362− % set entry spacing
363− \setlength{\parskip}{#2\cslentryspacingunit}
364− }%
365− {}
366−\usepackage{calc}
367−\newcommand{\CSLBlock}[1]{#1\hfill\break}
368−\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}}
369−\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break}
370−\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1}
371−$endif$
372$for(header-includes)$
328$for(header-includes)$
373$header-includes$
329$header-includes$
374$endfor$
330$endfor$
@@ -419,6 +375,28 @@ $endif$
419$if(nocite-ids)$
375$if(nocite-ids)$
420\nocite{$for(nocite-ids)$$it$$sep$, $endfor$}
376\nocite{$for(nocite-ids)$$it$$sep$, $endfor$}
421$endif$
377$endif$
378+$if(csl-refs)$
379+\newlength{\cslhangindent}
380+\setlength{\cslhangindent}{1.5em}
381+\newlength{\csllabelwidth}
382+\setlength{\csllabelwidth}{3em}
383+\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing
384+ {% don't indent paragraphs
385+ \setlength{\parindent}{0pt}
386+ % turn on hanging indent if param 1 is 1
387+ \ifodd #1 \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces\fi
388+ % set entry spacing
389+ \ifnum #2 > 0
390+ \setlength{\parskip}{#2\baselineskip}
391+ \fi
392+ }%
393+ {}
394+\usepackage{calc}
395+\newcommand{\CSLBlock}[1]{#1\hfill\break}
396+\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}}
397+\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break}
398+\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1}
399+$endif$
422$if(csquotes)$
400$if(csquotes)$
423\usepackage{csquotes}
401\usepackage{csquotes}
424$endif$
402$endif$
@@ -494,12 +472,12 @@ $endif$
494}
472}
495$endif$
473$endif$
496$endif$
474$endif$
497−$if(lof)$
498−\listoffigures
499−$endif$
500$if(lot)$
475$if(lot)$
501\listoftables
476\listoftables
502$endif$
477$endif$
478+$if(lof)$
479+\listoffigures
480+$endif$
503$if(linestretch)$
481$if(linestretch)$
504\setstretch{$linestretch$}
482\setstretch{$linestretch$}
505$endif$
483$endif$
data/templates/default.revealjs+128−78
@@ -52,9 +52,6 @@ $endif$
52$for(author)$
52$for(author)$
53 <p class="author">$author$</p>
53 <p class="author">$author$</p>
54$endfor$
54$endfor$
55−$for(institute)$
56− <p class="institute">$institute$</p>
57−$endfor$
58$if(date)$
55$if(date)$
59 <p class="date">$date$</p>
56 <p class="date">$date$</p>
60$endif$
57$endif$
@@ -62,12 +59,7 @@ $endif$
62$endif$
59$endif$
63$if(toc)$
60$if(toc)$
64<section id="$idprefix$TOC">
61<section id="$idprefix$TOC">
65−<nav role="doc-toc">
66−$if(toc-title)$
67−<h2 id="$idprefix$toc-title">$toc-title$</h2>
68−$endif$
69$table-of-contents$
62$table-of-contents$
70−</nav>
71</section>
63</section>
72$endif$
64$endif$
73
65
@@ -90,198 +82,256 @@ $endif$
90 // Full list of configuration options available at:
82 // Full list of configuration options available at:
91 // https://revealjs.com/config/
83 // https://revealjs.com/config/
92 Reveal.initialize({
84 Reveal.initialize({
85+$if(center)$
86+ // Determines whether slide content should be vertically centered
87+ center: $center$,
88+$endif$
89+$if(controls)$
93 // Display controls in the bottom right corner
90 // Display controls in the bottom right corner
94 controls: $controls$,
91 controls: $controls$,
95−
92+$endif$
93+$if(controlsTutorial)$
96 // Help the user learn the controls by providing hints, for example by
94 // Help the user learn the controls by providing hints, for example by
97 // bouncing the down arrow when they first encounter a vertical slide
95 // bouncing the down arrow when they first encounter a vertical slide
98 controlsTutorial: $controlsTutorial$,
96 controlsTutorial: $controlsTutorial$,
99−
97+$endif$
98+$if(controlsLayout)$
100 // Determines where controls appear, "edges" or "bottom-right"
99 // Determines where controls appear, "edges" or "bottom-right"
101 controlsLayout: '$controlsLayout$',
100 controlsLayout: '$controlsLayout$',
102−
101+$endif$
102+$if(controlsBackArrows)$
103 // Visibility rule for backwards navigation arrows; "faded", "hidden"
103 // Visibility rule for backwards navigation arrows; "faded", "hidden"
104 // or "visible"
104 // or "visible"
105 controlsBackArrows: '$controlsBackArrows$',
105 controlsBackArrows: '$controlsBackArrows$',
106−
106+$endif$
107+$if(progress)$
107 // Display a presentation progress bar
108 // Display a presentation progress bar
108 progress: $progress$,
109 progress: $progress$,
109−
110+$endif$
111+$if(slideNumber)$
110 // Display the page number of the current slide
112 // Display the page number of the current slide
111 slideNumber: $slideNumber$,
113 slideNumber: $slideNumber$,
112−
114+$endif$
115+$if(showSlideNumber)$
113 // 'all', 'print', or 'speaker'
116 // 'all', 'print', or 'speaker'
114 showSlideNumber: '$showSlideNumber$',
117 showSlideNumber: '$showSlideNumber$',
115−
118+$endif$
119+$if(hash)$
116 // Add the current slide number to the URL hash so that reloading the
120 // Add the current slide number to the URL hash so that reloading the
117 // page/copying the URL will return you to the same slide
121 // page/copying the URL will return you to the same slide
118 hash: $hash$,
122 hash: $hash$,
119−
123+$endif$
124+$if(hashOneBasedIndex)$
120 // Start with 1 for the hash rather than 0
125 // Start with 1 for the hash rather than 0
121 hashOneBasedIndex: $hashOneBasedIndex$,
126 hashOneBasedIndex: $hashOneBasedIndex$,
122−
127+$endif$
123− // Flags if we should monitor the hash and change slides accordingly
124− respondToHashChanges: $respondToHashChanges$,
125−
126 // Push each slide change to the browser history
128 // Push each slide change to the browser history
127− history: $history$,
129+ history: $if(history)$$history$$else$true$endif$,
128−
130+$if(keyboard)$
129 // Enable keyboard shortcuts for navigation
131 // Enable keyboard shortcuts for navigation
130 keyboard: $keyboard$,
132 keyboard: $keyboard$,
131−
133+$endif$
134+$if(overview)$
132 // Enable the slide overview mode
135 // Enable the slide overview mode
133 overview: $overview$,
136 overview: $overview$,
134−
137+$endif$
135− // Disables the default reveal.js slide layout (scaling and centering)
138+$if(center)$
136− // so that you can use custom CSS layout
137− disableLayout: false,
138−
139 // Vertical centering of slides
139 // Vertical centering of slides
140 center: $center$,
140 center: $center$,
141−
141+$endif$
142+$if(touch)$
142 // Enables touch navigation on devices with touch input
143 // Enables touch navigation on devices with touch input
143 touch: $touch$,
144 touch: $touch$,
144−
145+$endif$
146+$if(loop)$
145 // Loop the presentation
147 // Loop the presentation
146 loop: $loop$,
148 loop: $loop$,
147−
149+$endif$
150+$if(rtl)$
148 // Change the presentation direction to be RTL
151 // Change the presentation direction to be RTL
149 rtl: $rtl$,
152 rtl: $rtl$,
150−
153+$endif$
154+$if(navigationMode)$
151 // see https://revealjs.com/vertical-slides/#navigation-mode
155 // see https://revealjs.com/vertical-slides/#navigation-mode
152 navigationMode: '$navigationMode$',
156 navigationMode: '$navigationMode$',
153−
157+$endif$
158+$if(shuffle)$
154 // Randomizes the order of slides each time the presentation loads
159 // Randomizes the order of slides each time the presentation loads
155 shuffle: $shuffle$,
160 shuffle: $shuffle$,
156−
161+$endif$
162+$if(fragments)$
157 // Turns fragments on and off globally
163 // Turns fragments on and off globally
158 fragments: $fragments$,
164 fragments: $fragments$,
159−
165+$endif$
166+$if(fragmentInURL)$
160 // Flags whether to include the current fragment in the URL,
167 // Flags whether to include the current fragment in the URL,
161 // so that reloading brings you to the same fragment position
168 // so that reloading brings you to the same fragment position
162 fragmentInURL: $fragmentInURL$,
169 fragmentInURL: $fragmentInURL$,
163−
170+$endif$
171+$if(embedded)$
164 // Flags if the presentation is running in an embedded mode,
172 // Flags if the presentation is running in an embedded mode,
165 // i.e. contained within a limited portion of the screen
173 // i.e. contained within a limited portion of the screen
166 embedded: $embedded$,
174 embedded: $embedded$,
167−
175+$endif$
176+$if(help)$
168 // Flags if we should show a help overlay when the questionmark
177 // Flags if we should show a help overlay when the questionmark
169 // key is pressed
178 // key is pressed
170 help: $help$,
179 help: $help$,
171−
180+$endif$
181+$if(pause)$
172− // Flags if it should be possible to pause the presentation (blackout)
182+ // Flags if it should be possible to pause the presentation (blackout)
173− pause: $pause$,
183+ pause: $pause$,
174−
184+$endif$
185+$if(showNotes)$
175 // Flags if speaker notes should be visible to all viewers
186 // Flags if speaker notes should be visible to all viewers
176 showNotes: $showNotes$,
187 showNotes: $showNotes$,
177−
188+$endif$
189+$if(autoPlayMedia)$
178− // Global override for autoplaying embedded media (null/true/false)
190+ // Global override for autoplaying embedded media (video/audio/iframe)
191+ // - null: Media will only autoplay if data-autoplay is present
192+ // - true: All media will autoplay, regardless of individual setting
193+ // - false: No media will autoplay, regardless of individual setting
179 autoPlayMedia: $autoPlayMedia$,
194 autoPlayMedia: $autoPlayMedia$,
180−
195+$endif$
196+$if(preloadIframes)$
181− // Global override for preloading lazy-loaded iframes (null/true/false)
197+ // Global override for preloading lazy-loaded iframes
198+ // - null: Iframes with data-src AND data-preload will be loaded when within
199+ // the viewDistance, iframes with only data-src will be loaded when visible
200+ // - true: All iframes with data-src will be loaded when within the viewDistance
201+ // - false: All iframes with data-src will be loaded only when visible
182 preloadIframes: $preloadIframes$,
202 preloadIframes: $preloadIframes$,
183−
203+$endif$
204+$if(autoSlide)$
184 // Number of milliseconds between automatically proceeding to the
205 // Number of milliseconds between automatically proceeding to the
185 // next slide, disabled when set to 0, this value can be overwritten
206 // next slide, disabled when set to 0, this value can be overwritten
186 // by using a data-autoslide attribute on your slides
207 // by using a data-autoslide attribute on your slides
187 autoSlide: $autoSlide$,
208 autoSlide: $autoSlide$,
188−
209+$endif$
210+$if(autoSlideStoppable)$
189 // Stop auto-sliding after user input
211 // Stop auto-sliding after user input
190 autoSlideStoppable: $autoSlideStoppable$,
212 autoSlideStoppable: $autoSlideStoppable$,
191−
213+$endif$
214+$if(autoSlideMethod)$
192 // Use this method for navigation when auto-sliding
215 // Use this method for navigation when auto-sliding
193 autoSlideMethod: $autoSlideMethod$,
216 autoSlideMethod: $autoSlideMethod$,
194−
217+$endif$
218+$if(defaultTiming)$
195 // Specify the average time in seconds that you think you will spend
219 // Specify the average time in seconds that you think you will spend
196 // presenting each slide. This is used to show a pacing timer in the
220 // presenting each slide. This is used to show a pacing timer in the
197 // speaker view
221 // speaker view
198 defaultTiming: $defaultTiming$,
222 defaultTiming: $defaultTiming$,
199−
223+$endif$
224+$if(totalTime)$
225+ // Specify the total time in seconds that is available to
226+ // present. If this is set to a nonzero value, the pacing
227+ // timer will work out the time available for each slide,
228+ // instead of using the defaultTiming value
229+ totalTime: $totalTime$,
230+$endif$
231+$if(minimumTimePerSlide)$
232+ // Specify the minimum amount of time you want to allot to
233+ // each slide, if using the totalTime calculation method. If
234+ // the automated time allocation causes slide pacing to fall
235+ // below this threshold, then you will see an alert in the
236+ // speaker notes window
237+ minimumTimePerSlide: $minimumTimePerSlide$,
238+$endif$
239+$if(mouseWheel)$
200 // Enable slide navigation via mouse wheel
240 // Enable slide navigation via mouse wheel
201 mouseWheel: $mouseWheel$,
241 mouseWheel: $mouseWheel$,
202−
242+$endif$
203− // The display mode that will be used to show slides
243+$if(rollingLinks)$
204− display: '$display$',
244+ // Apply a 3D roll to links on hover
205−
245+ rollingLinks: $rollingLinks$,
246+$endif$
247+$if(hideInactiveCursor)$
206 // Hide cursor if inactive
248 // Hide cursor if inactive
207 hideInactiveCursor: $hideInactiveCursor$,
249 hideInactiveCursor: $hideInactiveCursor$,
208−
250+$endif$
251+$if(hideCursorTime)$
209 // Time before the cursor is hidden (in ms)
252 // Time before the cursor is hidden (in ms)
210 hideCursorTime: $hideCursorTime$,
253 hideCursorTime: $hideCursorTime$,
211−
254+$endif$
255+$if(hideAddressBar)$
256+ // Hides the address bar on mobile devices
257+ hideAddressBar: $hideAddressBar$,
258+$endif$
259+$if(previewLinks)$
212 // Opens links in an iframe preview overlay
260 // Opens links in an iframe preview overlay
213 previewLinks: $previewLinks$,
261 previewLinks: $previewLinks$,
214−
262+$endif$
263+$if(transition)$
264+ // Transition style
215− // Transition style (none/fade/slide/convex/concave/zoom)
265+ transition: '$transition$', // none/fade/slide/convex/concave/zoom
216− transition: '$transition$',
266+$endif$
217−
267+$if(transitionSpeed)$
218− // Transition speed (default/fast/slow)
268+ // Transition speed
219− transitionSpeed: '$transitionSpeed$',
269+ transitionSpeed: '$transitionSpeed$', // default/fast/slow
220−
270+$endif$
271+$if(backgroundTransition)$
221 // Transition style for full page slide backgrounds
272 // Transition style for full page slide backgrounds
222− // (none/fade/slide/convex/concave/zoom)
273+ backgroundTransition: '$backgroundTransition$', // none/fade/slide/convex/concave/zoom
223− backgroundTransition: '$backgroundTransition$',
274+$endif$
224−
275+$if(viewDistance)$
225 // Number of slides away from the current that are visible
276 // Number of slides away from the current that are visible
226 viewDistance: $viewDistance$,
277 viewDistance: $viewDistance$,
227−
278+$endif$
279+$if(mobileViewDistance)$
228 // Number of slides away from the current that are visible on mobile
280 // Number of slides away from the current that are visible on mobile
229 // devices. It is advisable to set this to a lower number than
281 // devices. It is advisable to set this to a lower number than
230 // viewDistance in order to save resources.
282 // viewDistance in order to save resources.
231 mobileViewDistance: $mobileViewDistance$,
283 mobileViewDistance: $mobileViewDistance$,
284+$endif$
232$if(parallaxBackgroundImage)$
285$if(parallaxBackgroundImage)$
233−
234 // Parallax background image
286 // Parallax background image
235 parallaxBackgroundImage: '$parallaxBackgroundImage$', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
287 parallaxBackgroundImage: '$parallaxBackgroundImage$', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
236$else$
288$else$
237$if(background-image)$
289$if(background-image)$
238−
239 // Parallax background image
290 // Parallax background image
240 parallaxBackgroundImage: '$background-image$', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
291 parallaxBackgroundImage: '$background-image$', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
241$endif$
292$endif$
242$endif$
293$endif$
243$if(parallaxBackgroundSize)$
294$if(parallaxBackgroundSize)$
244−
245 // Parallax background size
295 // Parallax background size
246 parallaxBackgroundSize: '$parallaxBackgroundSize$', // CSS syntax, e.g. "2100px 900px"
296 parallaxBackgroundSize: '$parallaxBackgroundSize$', // CSS syntax, e.g. "2100px 900px"
247$endif$
297$endif$
248$if(parallaxBackgroundHorizontal)$
298$if(parallaxBackgroundHorizontal)$
249−
250 // Amount to move parallax background (horizontal and vertical) on slide change
299 // Amount to move parallax background (horizontal and vertical) on slide change
251 // Number, e.g. 100
300 // Number, e.g. 100
252 parallaxBackgroundHorizontal: $parallaxBackgroundHorizontal$,
301 parallaxBackgroundHorizontal: $parallaxBackgroundHorizontal$,
253$endif$
302$endif$
254$if(parallaxBackgroundVertical)$
303$if(parallaxBackgroundVertical)$
255−
256 parallaxBackgroundVertical: $parallaxBackgroundVertical$,
304 parallaxBackgroundVertical: $parallaxBackgroundVertical$,
257$endif$
305$endif$
258$if(width)$
306$if(width)$
259−
260 // The "normal" size of the presentation, aspect ratio will be preserved
307 // The "normal" size of the presentation, aspect ratio will be preserved
261 // when the presentation is scaled to fit different resolutions. Can be
308 // when the presentation is scaled to fit different resolutions. Can be
262 // specified using percentage units.
309 // specified using percentage units.
263 width: $width$,
310 width: $width$,
264$endif$
311$endif$
265$if(height)$
312$if(height)$
266−
267 height: $height$,
313 height: $height$,
268$endif$
314$endif$
269$if(margin)$
315$if(margin)$
270−
271 // Factor of the display size that should remain empty around the content
316 // Factor of the display size that should remain empty around the content
272 margin: $margin$,
317 margin: $margin$,
273$endif$
318$endif$
274$if(minScale)$
319$if(minScale)$
275−
276 // Bounds for smallest/largest possible scale to apply to content
320 // Bounds for smallest/largest possible scale to apply to content
277 minScale: $minScale$,
321 minScale: $minScale$,
278$endif$
322$endif$
279$if(maxScale)$
323$if(maxScale)$
280−
281 maxScale: $maxScale$,
324 maxScale: $maxScale$,
282$endif$
325$endif$
326+$if(zoomKey)$
327+ // Modifier key used to click-zoom to part of the slide
328+ zoomKey: '$zoomKey$',
329+$endif$
330+$if(display)$
331+ // The display mode that will be used to show slides
332+ display: '$display$',
333+$endif$
283$if(mathjax)$
334$if(mathjax)$
284−
285 math: {
335 math: {
286 mathjax: '$mathjaxurl$',
336 mathjax: '$mathjaxurl$',
287 config: 'TeX-AMS_HTML-full',
337 config: 'TeX-AMS_HTML-full',
data/templates/default.s5−3
@@ -61,9 +61,6 @@ $endif$
61$if(author)$
61$if(author)$
62 <h3 class="author">$for(author)$$author$$sep$<br/>$endfor$</h3>
62 <h3 class="author">$for(author)$$author$$sep$<br/>$endfor$</h3>
63$endif$
63$endif$
64−$if(institute)$
65− <h3 class="institute">$for(institute)$$institute$$sep$<br/>$endfor$</h3>
66−$endif$
67$if(date)$
64$if(date)$
68 <h4 class="date">$date$</h4>
65 <h4 class="date">$date$</h4>
69$endif$
66$endif$
data/templates/default.slideous−7
@@ -63,16 +63,9 @@ $if(title)$
63$if(subtitle)$
63$if(subtitle)$
64 <h1 class="subtitle">$subtitle$</h1>
64 <h1 class="subtitle">$subtitle$</h1>
65$endif$
65$endif$
66−$if(author)$
67 <p class="author">
66 <p class="author">
68$for(author)$$author$$sep$<br/>$endfor$
67$for(author)$$author$$sep$<br/>$endfor$
69 </p>
68 </p>
70−$endif$
71−$if(institute)$
72− <p class="institute">
73−$for(institute)$$institute$$sep$<br/>$endfor$
74− </p>
75−$endif$
76$if(date)$
69$if(date)$
77 <p class="date">$date$</p>
70 <p class="date">$date$</p>
78$endif$
71$endif$
data/templates/default.slidy−5
@@ -52,11 +52,6 @@ $if(author)$
52$for(author)$$author$$sep$<br/>$endfor$
52$for(author)$$author$$sep$<br/>$endfor$
53 </p>
53 </p>
54$endif$
54$endif$
55−$if(institute)$
56− <p class="institute">
57−$for(institute)$$institute$$sep$<br/>$endfor$
58− </p>
59−$endif$
60$if(date)$
55$if(date)$
61 <p class="date">$date$</p>
56 <p class="date">$date$</p>
62$endif$
57$endif$
data/templates/styles.html+1−2
@@ -14,7 +14,7 @@ body {
14 padding-top: $if(margin-top)$$margin-top$$else$50px$endif$;
14 padding-top: $if(margin-top)$$margin-top$$else$50px$endif$;
15 padding-bottom: $if(margin-bottom)$$margin-bottom$$else$50px$endif$;
15 padding-bottom: $if(margin-bottom)$$margin-bottom$$else$50px$endif$;
16 hyphens: auto;
16 hyphens: auto;
17− overflow-wrap: break-word;
17+ word-wrap: break-word;
18 text-rendering: optimizeLegibility;
18 text-rendering: optimizeLegibility;
19 font-kerning: normal;
19 font-kerning: normal;
20}
20}
@@ -93,7 +93,6 @@ $endif$
93pre code {
93pre code {
94 padding: 0;
94 padding: 0;
95 overflow: visible;
95 overflow: visible;
96− overflow-wrap: normal;
97}
96}
98.sourceCode {
97.sourceCode {
99 background-color: transparent;
98 background-color: transparent;
doc/epub.md+2−9
@@ -141,15 +141,8 @@ Pandoc has an EPUB3 writer. It renders LaTeX math into MathML, which
141EPUB3 readers are supposed to support (but unfortunately few do).
141EPUB3 readers are supposed to support (but unfortunately few do).
142
142
143Of course, this isn't much help if you want EPUB2 output (`pandoc -t epub2`)
143Of course, this isn't much help if you want EPUB2 output (`pandoc -t epub2`)
144−or target readers that don't support MathML. Then you have two options:
144+or target readers that don't support MathML. Then you should try using the
145−
146−1. Use the [`--webtex`](https://pandoc.org/MANUAL.html#option--webtex) option,
147− which will use a web service to convert the TeX to an image.
145+`--webtex` option, which will use a web service to convert the TeX to an image.
148−2. Use the [`--gladtex`](https://pandoc.org/MANUAL.html#option--gladtex) option
149− to convert maths into SVG images on your local machine.
150−
151−Both GladTeX and WebTeX add the LaTeX source of the formula as alternative text
152−of the image, increasing accessibility for blind users.
153
146
154[KindleGen]: https://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211
147[KindleGen]: https://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211
155[EPUB]: https://en.wikipedia.org/wiki/EPUB
148[EPUB]: https://en.wikipedia.org/wiki/EPUB
doc/faqs.mddeleted−128
@@ -1,128 +0,0 @@
1−% FAQs
2−
3−::: faqs
4−
5−## How can I convert a whole directory of files from Markdown to RTF?
6−
7−On linux or OSX:
8−
9− for f in *.txt; do pandoc "$f" -s -o "${f%.txt}.rtf"; done
10−
11−
12−In Windows Powershell:
13−
14− gci -r -i *.txt |foreach{$rtf=$_.directoryname+"\"+$_.basename+".rtf";pandoc -f markdown -s $_.name -o $rtf}
15−
16−## I used pandoc to convert a document to ICML (or OPML or RTF), and when I try to open it I'm told it's invalid. What have I done wrong?
17−
18−Be sure to use the `-s` or `--standalone` flag, or you just get a
19−fragment, not a full document with the required header:
20−
21− pandoc -s -f markdown -t icml -o my.icml my.md
22−
23−## I get a blank document when I try to convert a markdown document in Chinese to PDF.
24−
25−By default, pandoc uses pdflatex to generate the PDF, and pdflatex
26−doesn't handle Chinese characters. But you can change the default to
27−use xelatex instead. You should also make sure you're using a font
28−with Chinese glyphs. For example:
29−
30− pandoc -o c.pdf --pdf-engine=xelatex -V mainfont='Adobe Ming Std'
31−
32−## The Windows installer does a single user install, rather than installing pandoc for all users. How can I install pandoc for all users?
33−
34−Run the following command as admin:
35−
36− msiexec /i pandoc-VERSION.msi ALLUSERS=1
37−
38−This will put pandoc in `C:\Program Files\Pandoc`.
39−You can install Pandoc to a different directory by setting APPLICATIONFOLDER parameter,
40−for example:
41−
42− msiexec /i pandoc-1.11.1.msi ALLUSERS=1 APPLICATIONFOLDER="C:\Pandoc"
43−
44−## How do I change the margins in PDF output?
45−
46−The option
47−
48− -V geometry:margin=1in
49−
50−will set the margins to one inch on each side. If you don't want uniform
51−margins, you can do something like
52−
53− -V geometry:"top=2cm, bottom=1.5cm, left=1cm, right=1cm"
54−
55−Or
56−
57− -V geometry:"left=3cm, width=10cm"
58−
59−For more options, see the documentation for the LaTeX [geometry
60−package](https://www.ctan.org/pkg/geometry).
61−
62−## How does pandoc compare to multimarkdown?
63−
64−Here is a [wiki
65−page](https://github.com/jgm/pandoc/wiki/Pandoc-vs-Multimarkdown)
66−comparing the two.
67−
68−## When I specify an image width of 50% and convert to LaTeX, pandoc sets the height to textheight and the aspect ratio isn't preserved. How can I prevent this?
69−
70−For example, if you convert an image with `{width="50%"}`, the LaTeX produced
71−will be `\includegraphics[width=0.5\textwidth,height=\textheight]`.
72−
73−This output presupposes the following code in pandoc's default latex
74−template:
75−
76−```
77−% Scale images if necessary, so that they will not overflow the page
78−% margins by default, and it is still possible to overwrite the defaults
79−% using explicit options in \includegraphics[width, height, ...]{}
80−\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
81−```
82−
83−If you don't have this in your custom template, you should
84−add it. If we didn't set the `height` explicitly in this way,
85−the image would not be resized correctly unless it was
86−being resized to smaller than its original size.
87−
88−## Pandoc sometimes uses too much memory. How can I limit the memory used by pandoc?
89−
90−`pandoc +RTS -M30m -RTS` will limit heap memory to 30MB.
91−When converting a document requires more than this, an out of
92−memory error will be issued.
93−
94−## When using `--include-in-header` with PDF or LaTeX output, how do I reference tex declarations coming after `$header-includes$` in the default template?
95−
96−For various reasons, the `$header-includes$` are not at the very
97−end of the LaTeX preamble. This poses a problem when the code
98−you are inserting depends on declarations in the preamble coming
99−after the `$header-includes$` location. For example, you might
100−want to reference the `\author` and `\title` metadata values
101−(set at the very bottom of the preamble) and present them in
102−margins. In that case you can wrap your code in `etoolbox`'s
103−`\AtEndPreamble`. The technique is demonstrated in [this
104−gist](https://gist.github.com/JohnLukeBentley/9dda6166b9ee5c4127afd2b8cd16b70a).
105−When using `\AtEndPreamble`, keep any `makeatletter` or
106−`makeatother` outside of the `\AtEndPreamble`, as shown in the
107−example.
108−
109−## How can I convert PDFs to other formats using pandoc?
110−
111−You can't. You can try opening the PDF in Word or Google Docs
112−and saving in a format from which pandoc can convert directly.
113−
114−## Do I really need to install a 1 GB TeX installation to produce a PDF using pandoc?
115−
116−No. You can get by with a relatively small TeX installation,
117−for example, by starting with MacTeX's Basic TeX distribution
118−and using the `tlmgr` tool to install a few packages required by pandoc
119−(see https://pandoc.org/MANUAL.html#creating-a-pdf).
120−
121−Or, you can produce PDFs via HTML and `wkhtmltopdf`,
122−or via groff ms and `pdfroff`. (These don't produce as nice
123−topography as TeX, particularly when it comes to math, but they
124−may be fine for many purposes.)
125−
126−
127−:::
128−
doc/filters.md−2
@@ -394,8 +394,6 @@ automatically assign it `Just` the target format or `Nothing`.
394
394
395We compile our script:
395We compile our script:
396
396
397− # first, make sure pandoc-types is installed:
398− cabal install --lib pandoc-types --package-env .
399 ghc --make handleRuby
397 ghc --make handleRuby
400
398
401Then run it:
399Then run it:
doc/libraries.md−4
@@ -15,9 +15,6 @@ pandoc:
15[texmath]
15[texmath]
16: Conversion of math between tex, Word equation, MathML, and GNU eqn.
16: Conversion of math between tex, Word equation, MathML, and GNU eqn.
17
17
18−[unicode-collation]
19−: Proper Unicode collation (sorting).
20−
21[doclayout]
18[doclayout]
22: Combinators for laying out a textual document, with support
19: Combinators for laying out a textual document, with support
23 for line wrapping, tabular layout, and more.
20 for line wrapping, tabular layout, and more.
@@ -59,5 +56,4 @@ pandoc:
59[rfc5051]: https://hackage.haskell.org/package/rfc5051
56[rfc5051]: https://hackage.haskell.org/package/rfc5051
60[emojis]: https://hackage.haskell.org/package/emojis
57[emojis]: https://hackage.haskell.org/package/emojis
61[jira-wiki-markup]: https://hackage.haskell.org/package/jira-wiki-markup
58[jira-wiki-markup]: https://hackage.haskell.org/package/jira-wiki-markup
62−[unicode-collation]: https://hackage.haskell.org/package/unicode-collation
63
59
doc/org.md−15
@@ -36,21 +36,6 @@ The following export keywords are supported:
36 defaults to stdout unless a target has to be given as a command
36 defaults to stdout unless a target has to be given as a command
37 line option.
37 line option.
38
38
39−::: {.alert .alert-info}
40−Pandoc tries to be compatible with org-mode when exporting an org document. If
41−you find some behavior confusing, please do refer to org-mode
42−[Export-Settings](https://orgmode.org/manual/Export-Settings.html)
43−documentation. For example, a common confusion
44−([#3214](https://github.com/jgm/pandoc/issues/3214 "Problem with headers lower
45−then 3 in org-mode reader"), [#5169](https://github.com/jgm/pandoc/issues/5169
46−"org mode headings past level three converted to numbered outline list"),
47−[#6145](https://github.com/jgm/pandoc/issues/6145 "Headers 4 levels deep render
48−differently"), [#7236](https://github.com/jgm/pandoc/issues/7236 "In Org mode,
49−Header with level > 3 are not recognized as headers")) is treatment of headers
50−with level > 3 differently because org-mode sets `org-export-headline-levels`
51−(configurable with `#+OPTIONS: H:3`) to 3 by default.
52−:::
53−
54[BCP47 language tag]: https://tools.ietf.org/html/bcp47
39[BCP47 language tag]: https://tools.ietf.org/html/bcp47
55
40
56Format-specific options
41Format-specific options
doc/using-the-pandoc-api.md+11−24
@@ -90,14 +90,8 @@ Some notes:
90Let's look at the types of `readMarkdown` and `writeRST`:
90Let's look at the types of `readMarkdown` and `writeRST`:
91
91
92```haskell
92```haskell
93−readMarkdown :: (PandocMonad m, ToSources a)
93+readMarkdown :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
94− => ReaderOptions
95− -> a
96− -> m Pandoc
97−writeRST :: PandocMonad m
94+writeRST :: PandocMonad m => WriterOptions -> Pandoc -> m Text
98− => WriterOptions
99− -> Pandoc
100− -> m Text
101```
95```
102
96
103The `PandocMonad m =>` part is a typeclass constraint.
97The `PandocMonad m =>` part is a typeclass constraint.
@@ -139,7 +133,7 @@ report :: PandocMonad m => LogMessage -> m ()
139-- | Fetch an image or other item from the local filesystem or the net.
133-- | Fetch an image or other item from the local filesystem or the net.
140-- Returns raw content and maybe mime type.
134-- Returns raw content and maybe mime type.
141fetchItem :: PandocMonad m
135fetchItem :: PandocMonad m
142− => Text
136+ => String
143 -> m (B.ByteString, Maybe MimeType)
137 -> m (B.ByteString, Maybe MimeType)
144
138
145-- Set the resource path searched by 'fetchItem'.
139-- Set the resource path searched by 'fetchItem'.
@@ -161,13 +155,6 @@ Note that `PandocIO` is an instance of `MonadIO`, so you can
161use `liftIO` to perform arbitrary IO operations inside a pandoc
155use `liftIO` to perform arbitrary IO operations inside a pandoc
162conversion chain.
156conversion chain.
163
157
164−`readMarkdown` is polymorphic in its second argument, which
165−can be any type that is an instance of the `ToSources`
166−typeclass. You can use `Text`, as in the example above.
167−But you can also use `[(FilePath, Text)]`, if the input comes
168−from multiple files and you want to track source positions
169−accurately.
170−
171# Options
158# Options
172
159
173The first argument of each reader or writer is for
160The first argument of each reader or writer is for
@@ -213,8 +200,8 @@ of the Monoid typeclass and can easily be concatenated:
213import Text.Pandoc.Builder
200import Text.Pandoc.Builder
214
201
215mydoc :: Pandoc
202mydoc :: Pandoc
216−mydoc = doc $ header 1 (text (T.pack "Hello!"))
203+mydoc = doc $ header 1 (text "Hello!")
217− <> para (emph (text (T.pack "hello world")) <> text (T.pack "."))
204+ <> para (emph (text "hello world") <> text ".")
218
205
219main :: IO ()
206main :: IO ()
220main = print mydoc
207main = print mydoc
@@ -261,16 +248,16 @@ import qualified Data.Text as T
261import Data.List (intersperse)
248import Data.List (intersperse)
262
249
263data Station = Station{
250data Station = Station{
264− address :: T.Text
251+ address :: String
265− , name :: T.Text
252+ , name :: String
266− , cardsAccepted :: [T.Text]
253+ , cardsAccepted :: [String]
267 } deriving Show
254 } deriving Show
268
255
269instance FromJSON Station where
256instance FromJSON Station where
270 parseJSON (Object v) = Station <$>
257 parseJSON (Object v) = Station <$>
271 v .: "street_address" <*>
258 v .: "street_address" <*>
272 v .: "station_name" <*>
259 v .: "station_name" <*>
273− (T.words <$> (v .:? "cards_accepted" .!= ""))
260+ (words <$> (v .:? "cards_accepted" .!= ""))
274 parseJSON _ = mzero
261 parseJSON _ = mzero
275
262
276createLetter :: [Station] -> Pandoc
263createLetter :: [Station] -> Pandoc
@@ -328,7 +315,7 @@ users to override the system defaults. If you want to disable
328this behavior, use `setUserDataDir Nothing`.
315this behavior, use `setUserDataDir Nothing`.
329
316
330To render a template, use `renderTemplate'`, which takes two
317To render a template, use `renderTemplate'`, which takes two
331−arguments, a template (Text) and a context (any instance
318+arguments, a template (String) and a context (any instance
332of ToJSON). If you want to create a context from the metadata
319of ToJSON). If you want to create a context from the metadata
333part of a Pandoc document, use `metaToJSON'` from
320part of a Pandoc document, use `metaToJSON'` from
334[Text.Pandoc.Writers.Shared]. If you also want to incorporate
321[Text.Pandoc.Writers.Shared]. If you also want to incorporate
@@ -426,7 +413,7 @@ concatenated together. Here's an example that returns a
426list of the URLs linked to in a document:
413list of the URLs linked to in a document:
427
414
428```haskell
415```haskell
429−listURLs :: Pandoc -> [Text]
416+listURLs :: Pandoc -> [String]
430listURLs = query urls
417listURLs = query urls
431 where urls (Link _ _ (src, _)) = [src]
418 where urls (Link _ _ (src, _)) = [src]
432 urls _ = []
419 urls _ = []
man/pandoc.1+39−187
@@ -1,7 +1,7 @@
1'\" t
1'\" t
2−.\" Automatically generated by Pandoc 2.14.0.1
2+.\" Automatically generated by Pandoc 2.12.1
3.\"
3.\"
4−.TH "Pandoc User\[cq]s Guide" "" "June 20, 2021" "pandoc 2.14.0.3" ""
4+.TH "Pandoc User\[cq]s Guide" "" "March 20, 2021" "pandoc 2.13" ""
5.hy
5.hy
6.SH NAME
6.SH NAME
7pandoc - general markup converter
7pandoc - general markup converter
@@ -716,11 +716,11 @@ Extract images and other media contained in or linked from the source
716document to the path \f[I]DIR\f[R], creating it if necessary, and adjust
716document to the path \f[I]DIR\f[R], creating it if necessary, and adjust
717the images references in the document so they point to the extracted
717the images references in the document so they point to the extracted
718files.
718files.
719−Media are downloaded, read from the file system, or extracted from a
720−binary container (e.g.\ docx), as needed.
719+If the source format is a binary container (docx, epub, or odt), the
721−The original file paths are used if they are relative paths not
720+media is extracted from the container and the original filenames are
722−containing \f[C]..\f[R].
721+used.
722+Otherwise the media is read from the file system or downloaded, and new
723−Otherwise filenames are constructed from the SHA1 hash of the contents.
723+filenames are constructed based on SHA1 hashes of the contents.
724.TP
724.TP
725\f[B]\f[CB]--abbreviations=\f[B]\f[R]\f[I]FILE\f[R]
725\f[B]\f[CB]--abbreviations=\f[B]\f[R]\f[I]FILE\f[R]
726Specifies a custom abbreviations file, with abbreviations one to a line.
726Specifies a custom abbreviations file, with abbreviations one to a line.
@@ -1504,16 +1504,16 @@ inserted.
1504.TP
1504.TP
1505\f[B]\f[CB]--gladtex\f[B]\f[R]
1505\f[B]\f[CB]--gladtex\f[B]\f[R]
1506Enclose TeX math in \f[C]<eq>\f[R] tags in HTML output.
1506Enclose TeX math in \f[C]<eq>\f[R] tags in HTML output.
1507−The resulting HTML can then be processed by GladTeX to produce SVG
1507+The resulting HTML can then be processed by GladTeX to produce images of
1508−images of the typeset formulas and an HTML file with these images
1508+the typeset formulas and an HTML file with links to these images.
1509−embedded.
1509+So, the procedure is:
1510.RS
1510.RS
1511.IP
1511.IP
1512.nf
1512.nf
1513\f[C]
1513\f[C]
1514pandoc -s --gladtex input.md -o myfile.htex
1514pandoc -s --gladtex input.md -o myfile.htex
1515−gladtex -d image_dir myfile.htex
1515+gladtex -d myfile-images myfile.htex
1516−# produces myfile.html and images in image_dir
1516+# produces myfile.html and images in myfile-images
1517\f[R]
1517\f[R]
1518.fi
1518.fi
1519.RE
1519.RE
@@ -2591,9 +2591,10 @@ YAML metadata or with \f[C]-M classoption=fleqn\f[R].
2591.SS Variables for HTML slides
2591.SS Variables for HTML slides
2592.PP
2592.PP
2593These affect HTML output when [producing slide shows with pandoc].
2593These affect HTML output when [producing slide shows with pandoc].
2594−.TP
2594+.PP
2595−\f[B]\f[CB]institute\f[B]\f[R]
2595+All reveal.js configuration options are available as variables.
2596−author affiliations: can be a list when there are multiple authors
2596+To turn off boolean flags that default to true in reveal.js, use
2597+\f[C]0\f[R].
2597.TP
2598.TP
2598\f[B]\f[CB]revealjs-url\f[B]\f[R]
2599\f[B]\f[CB]revealjs-url\f[B]\f[R]
2599base URL for reveal.js documents (defaults to
2600base URL for reveal.js documents (defaults to
@@ -2612,10 +2613,6 @@ base URL for Slideous documents (defaults to \f[C]slideous\f[R])
2612\f[B]\f[CB]title-slide-attributes\f[B]\f[R]
2613\f[B]\f[CB]title-slide-attributes\f[B]\f[R]
2613additional attributes for the title slide of reveal.js slide shows.
2614additional attributes for the title slide of reveal.js slide shows.
2614See background in reveal.js and beamer for an example.
2615See background in reveal.js and beamer for an example.
2615−.PP
2616−All reveal.js configuration options are available as variables.
2617−To turn off boolean flags that default to true in reveal.js, use
2618−\f[C]0\f[R].
2619.SS Variables for Beamer slides
2616.SS Variables for Beamer slides
2620.PP
2617.PP
2621These variables change the appearance of PDF slides using
2618These variables change the appearance of PDF slides using
@@ -4275,7 +4272,7 @@ Term 2
4275Note that space between items in a definition list is required.
4272Note that space between items in a definition list is required.
4276(A variant that loosens this requirement, but disallows \[lq]lazy\[rq]
4273(A variant that loosens this requirement, but disallows \[lq]lazy\[rq]
4277hard wrapping, can be activated with \f[C]compact_definition_lists\f[R]:
4274hard wrapping, can be activated with \f[C]compact_definition_lists\f[R]:
4278−see Non-default extensions, below.)
4275+see Non-pandoc extensions, below.)
4279.SS Numbered example lists
4276.SS Numbered example lists
4280.SS Extension: \f[C]example_lists\f[R]
4277.SS Extension: \f[C]example_lists\f[R]
4281.PP
4278.PP
@@ -4796,9 +4793,7 @@ All of the metadata will appear in a single block at the beginning of
4796the document.
4793the document.
4797.PP
4794.PP
4798Note that YAML escaping rules must be followed.
4795Note that YAML escaping rules must be followed.
4799−Thus, for example, if a title contains a colon, it must be quoted, and
4796+Thus, for example, if a title contains a colon, it must be quoted.
4800−if it contains a backslash escape, then it must be ensured that it is
4801−not treated as a YAML escape sequence.
4802The pipe character (\f[C]|\f[R]) can be used to begin an indented block
4797The pipe character (\f[C]|\f[R]) can be used to begin an indented block
4803that will be interpreted literally, without need for escaping.
4798that will be interpreted literally, without need for escaping.
4804This form is necessary when the field contains blank lines or
4799This form is necessary when the field contains blank lines or
@@ -4820,13 +4815,6 @@ abstract: |
4820\f[R]
4815\f[R]
4821.fi
4816.fi
4822.PP
4817.PP
4823−The literal block after the \f[C]|\f[R] must be indented relative to the
4824−line containing the \f[C]|\f[R].
4825−If it is not, the YAML will be invalid and pandoc will not interpret it
4826−as metadata.
4827−For an overview of the complex rules governing YAML, see the Wikipedia
4828−entry on YAML syntax.
4829−.PP
4830Template variables will be set automatically from the metadata.
4818Template variables will be set automatically from the metadata.
4831Thus, for example, in writing HTML, the variable \f[C]abstract\f[R] will
4819Thus, for example, in writing HTML, the variable \f[C]abstract\f[R] will
4832be set to the HTML equivalent of the Markdown in the \f[C]abstract\f[R]
4820be set to the HTML equivalent of the Markdown in the \f[C]abstract\f[R]
@@ -4892,21 +4880,6 @@ header-includes:
4892 \[ga]\[ga]\[ga]
4880 \[ga]\[ga]\[ga]
4893\f[R]
4881\f[R]
4894.fi
4882.fi
4895−.PP
4896−Note: the \f[C]yaml_metadata_block\f[R] extension works with
4897−\f[C]commonmark\f[R] as well as \f[C]markdown\f[R] (and it is enabled by
4898−default in \f[C]gfm\f[R] and \f[C]commonmark_x\f[R]).
4899−However, in these formats the following restrictions apply:
4900−.IP \[bu] 2
4901−The YAML metadata block must occur at the beginning of the document (and
4902−there can be only one).
4903−If multiple files are given as arguments to pandoc, only the first can
4904−be a YAML metadata block.
4905−.IP \[bu] 2
4906−The leaf nodes of the YAML structure are parsed in isolation from each
4907−other and from the rest of the document.
4908−So, for example, you can\[cq]t use a reference link in these contexts if
4909−the link definition is somewhere else in the document.
4910.SS Backslash escapes
4883.SS Backslash escapes
4911.SS Extension: \f[C]all_symbols_escapable\f[R]
4884.SS Extension: \f[C]all_symbols_escapable\f[R]
4912.PP
4885.PP
@@ -5787,70 +5760,27 @@ Inline and regular footnotes may be mixed freely.
5787.SS Citation syntax
5760.SS Citation syntax
5788.SS Extension: \f[C]citations\f[R]
5761.SS Extension: \f[C]citations\f[R]
5789.PP
5762.PP
5790−To cite a bibliographic item with an identifier foo, use the syntax
5763+Markdown citations go inside square brackets and are separated by
5791−\f[C]\[at]foo\f[R].
5764+semicolons.
5792−Normal citations should be included in square brackets, with semicolons
5765+Each citation must have a key, composed of `\[at]' + the citation
5793−separating distinct items:
5766+identifier from the database, and may optionally have a prefix, a
5794−.IP
5767+locator, and a suffix.
5795−.nf
5768+The citation key must begin with a letter, digit, or \f[C]_\f[R], and
5796−\f[C]
5769+may contain alphanumerics, \f[C]_\f[R], and internal punctuation
5797−Blah blah [\[at]doe99; \[at]smith2000; \[at]smith2004].
5770+characters (\f[C]:.#$%&-+?<>\[ti]/\f[R]).
5798−\f[R]
5771+Here are some examples:
5799−.fi
5800−.PP
5801−How this is rendered depends on the citation style.
5802−In an author-date style, it might render as
5803−.IP
5804−.nf
5805−\f[C]
5806−Blah blah (Doe 1999, Smith 2000, 2004).
5807−\f[R]
5808−.fi
5809−.PP
5810−In a footnote style, it might render as
5811.IP
5772.IP
5812.nf
5773.nf
5813\f[C]
5774\f[C]
5814−Blah blah.[\[ha]1]
5775+Blah blah [see \[at]doe99, pp. 33-35; also \[at]smith04, chap. 1].
5815
5776
5816−[\[ha]1]: John Doe, \[dq]Frogs,\[dq] *Journal of Amphibians* 44 (1999);
5817−Susan Smith, \[dq]Flies,\[dq] *Journal of Insects* (2000);
5818−Susan Smith, \[dq]Bees,\[dq] *Journal of Insects* (2004).
5819−\f[R]
5820−.fi
5821−.PP
5822−See the CSL user documentation for more information about CSL styles and
5823−how they affect rendering.
5824−.PP
5825−Unless a citation key start with a letter, digit, or \f[C]_\f[R], and
5826−contains only alphanumerics and internal punctuation characters
5827−(\f[C]:.#$%&-+?<>\[ti]/\f[R]), it must be surrounded by curly braces,
5828−which are not considered part of the key.
5829−In \f[C]\[at]Foo_bar.baz.\f[R], the key is \f[C]Foo_bar.baz\f[R].
5830−The final period is not \f[I]internal\f[R] punctuation, so it is not
5831−included in the key.
5832−In \f[C]\[at]{Foo_bar.baz.}\f[R], the key is \f[C]Foo_bar.baz.\f[R],
5833−including the final period.
5834−The curly braces are recommended if you use URLs as keys:
5835−\f[C][\[at]{https://example.com/bib?name=foobar&date=2000}, p. 33]\f[R].
5836−.PP
5837−Citation items may optionally include a prefix, a locator, and a suffix.
5838−In
5839−.IP
5840−.nf
5841−\f[C]
5842−Blah blah [see \[at]doe99, pp. 33-35 and *passim*; \[at]smith04, chap. 1].
5777+Blah blah [\[at]doe99, pp. 33-35, 38-39 and *passim*].
5778+
5779+Blah blah [\[at]smith04; \[at]doe99].
5843\f[R]
5780\f[R]
5844.fi
5781.fi
5845.PP
5782.PP
5846−The first item (\f[C]doe99\f[R]) has prefix \f[C]see\f[R], locator
5847−\f[C]pp. 33-35\f[R], and suffix \f[C]and *passim*\f[R].
5848−The second item (\f[C]smith04\f[R]) has locator \f[C]chap. 1\f[R] and no
5849−prefix or suffix.
5850−.PP
5851−Pandoc uses some heuristics to separate the locator from the rest of the
5852−subject.
5853−It is sensitive to the locator terms defined in the CSL locale files.
5783+\f[C]pandoc\f[R] detects locator terms in the CSL locale files.
5854Either abbreviated or unabbreviated forms are accepted.
5784Either abbreviated or unabbreviated forms are accepted.
5855In the \f[C]en-US\f[R] locale, locator terms can be written in either
5785In the \f[C]en-US\f[R] locale, locator terms can be written in either
5856singular or plural forms, as \f[C]book\f[R],
5786singular or plural forms, as \f[C]book\f[R],
@@ -5872,15 +5802,14 @@ singular or plural forms, as \f[C]book\f[R],
5872\f[C]\[sc]\f[R]/\f[C]\[sc]\[sc]\f[R].
5802\f[C]\[sc]\f[R]/\f[C]\[sc]\[sc]\f[R].
5873If no locator term is used, \[lq]page\[rq] is assumed.
5803If no locator term is used, \[lq]page\[rq] is assumed.
5874.PP
5804.PP
5875−In complex cases, you can force something to be treated as a locator by
5805+\f[C]pandoc\f[R] will use heuristics to distinguish the locator from the
5876−enclosing it in curly braces or prevent parsing the suffix as locator by
5806+suffix.
5877−prepending curly braces:
5807+In complex cases, the locator can be enclosed in curly braces:
5878.IP
5808.IP
5879.nf
5809.nf
5880\f[C]
5810\f[C]
5881[\[at]smith{ii, A, D-Z}, with a suffix]
5811[\[at]smith{ii, A, D-Z}, with a suffix]
5882[\[at]smith, {pp. iv, vi-xi, (xv)-(xvii)} with suffix here]
5812[\[at]smith, {pp. iv, vi-xi, (xv)-(xvii)} with suffix here]
5883−[\[at]smith{}, 99 years later]
5884\f[R]
5813\f[R]
5885.fi
5814.fi
5886.PP
5815.PP
@@ -5894,8 +5823,7 @@ Smith says blah [-\[at]smith04].
5894\f[R]
5823\f[R]
5895.fi
5824.fi
5896.PP
5825.PP
5897−You can also write an author-in-text citation, by omitting the square
5826+You can also write an in-text citation, as follows:
5898−brackets:
5899.IP
5827.IP
5900.nf
5828.nf
5901\f[C]
5829\f[C]
@@ -5904,64 +5832,13 @@ brackets:
5904\[at]smith04 [p. 33] says blah.
5832\[at]smith04 [p. 33] says blah.
5905\f[R]
5833\f[R]
5906.fi
5834.fi
5907−.PP
5908−This will cause the author\[cq]s name to be rendered, followed by the
5909−bibliographical details.
5910−Use this form when you want to make the citation the subject of a
5911−sentence.
5912−.PP
5913−When you are using a note style, it is usually better to let citeproc
5914−create the footnotes from citations rather than writing an explicit
5915−note.
5916−If you do write an explicit note that contains a citation, note that
5917−normal citations will be put in parentheses, while author-in-text
5918−citations will not.
5919−For this reason, it is sometimes preferable to use the author-in-text
5920−style inside notes when using a note style.
5921−.SS Non-default extensions
5835+.SS Non-pandoc extensions
5922.PP
5836.PP
5923The following Markdown syntax extensions are not enabled by default in
5837The following Markdown syntax extensions are not enabled by default in
5924pandoc, but may be enabled by adding \f[C]+EXTENSION\f[R] to the format
5838pandoc, but may be enabled by adding \f[C]+EXTENSION\f[R] to the format
5925name, where \f[C]EXTENSION\f[R] is the name of the extension.
5839name, where \f[C]EXTENSION\f[R] is the name of the extension.
5926Thus, for example, \f[C]markdown+hard_line_breaks\f[R] is Markdown with
5840Thus, for example, \f[C]markdown+hard_line_breaks\f[R] is Markdown with
5927hard line breaks.
5841hard line breaks.
5928−.SS Extension: \f[C]rebase_relative_paths\f[R]
5929−.PP
5930−Rewrite relative paths for Markdown links and images, depending on the
5931−path of the file containing the link or image link.
5932−For each link or image, pandoc will compute the directory of the
5933−containing file, relative to the working directory, and prepend the
5934−resulting path to the link or image path.
5935−.PP
5936−The use of this extension is best understood by example.
5937−Suppose you have a a subdirectory for each chapter of a book,
5938−\f[C]chap1\f[R], \f[C]chap2\f[R], \f[C]chap3\f[R].
5939−Each contains a file \f[C]text.md\f[R] and a number of images used in
5940−the chapter.
5941−You would like to have \f[C]![image](spider.jpg)\f[R] in
5942−\f[C]chap1/text.md\f[R] refer to \f[C]chap1/spider.jpg\f[R] and
5943−\f[C]![image](spider.jpg)\f[R] in \f[C]chap2/text.md\f[R] refer to
5944−\f[C]chap2/spider.jpg\f[R].
5945−To do this, use
5946−.IP
5947−.nf
5948−\f[C]
5949−pandoc chap*/*.md -f markdown+rebase_relative_paths
5950−\f[R]
5951−.fi
5952−.PP
5953−Without this extension, you would have to use
5954−\f[C]![image](chap1/spider.jpg)\f[R] in \f[C]chap1/text.md\f[R] and
5955−\f[C]![image](chap2/spider.jpg)\f[R] in \f[C]chap2/text.md\f[R].
5956−Links with relative paths will be rewritten in the same way as images.
5957−.PP
5958−Absolute paths and URLs are not changed.
5959−Neither are empty paths or paths consisting entirely of a fragment,
5960−e.g., \f[C]#foo\f[R].
5961−.PP
5962−Note that relative paths in reference links and images will be rewritten
5963−relative to the file containing the link reference definition, not the
5964−file containing the reference link or image itself, if these differ.
5965.SS Extension: \f[C]attributes\f[R]
5842.SS Extension: \f[C]attributes\f[R]
5966.PP
5843.PP
5967Allows attributes to be attached to any inline or block-level element.
5844Allows attributes to be attached to any inline or block-level element.
@@ -6591,29 +6468,9 @@ entries (for author-date and numerical styles only).
6591.TP
6468.TP
6592\f[B]\f[CB]lang\f[B]\f[R]
6469\f[B]\f[CB]lang\f[B]\f[R]
6593The \f[C]lang\f[R] field will affect how the style is localized, for
6470The \f[C]lang\f[R] field will affect how the style is localized, for
6594−example in the translation of labels, the use of quotation marks, and
6471+example in the translation of labels and the use of quotation marks.
6595−the way items are sorted.
6596(For backwards compatibility, \f[C]locale\f[R] may be used instead of
6472(For backwards compatibility, \f[C]locale\f[R] may be used instead of
6597\f[C]lang\f[R], but this use is deprecated.)
6473\f[C]lang\f[R], but this use is deprecated.)
6598−.RS
6599−.PP
6600−A BCP 47 language tag is expected: for example, \f[C]en\f[R],
6601−\f[C]de\f[R], \f[C]en-US\f[R], \f[C]fr-CA\f[R], \f[C]ug-Cyrl\f[R].
6602−The unicode extension syntax (after \f[C]-u-\f[R]) may be used to
6603−specify options for collation (sorting) more precisely.
6604−Here are some examples:
6605−.IP \[bu] 2
6606−\f[C]zh-u-co-pinyin\f[R] \[en] Chinese with the Pinyin collation.
6607−.IP \[bu] 2
6608−\f[C]es-u-co-trad\f[R] \[en] Spanish with the traditional collation
6609−(with \f[C]Ch\f[R] sorting after \f[C]C\f[R]).
6610−.IP \[bu] 2
6611−\f[C]fr-u-kb\f[R] \[en] French with \[lq]backwards\[rq] accent sorting
6612−(with \f[C]cot\['e]\f[R] sorting after \f[C]c\[^o]te\f[R]).
6613−.IP \[bu] 2
6614−\f[C]en-US-u-kf-upper\f[R] \[en] English with uppercase letters sorting
6615−before lower (default is lower before upper).
6616−.RE
6617.TP
6474.TP
6618\f[B]\f[CB]notes-after-punctuation\f[B]\f[R]
6475\f[B]\f[CB]notes-after-punctuation\f[B]\f[R]
6619If true (the default), pandoc will put footnote citations after
6476If true (the default), pandoc will put footnote citations after
@@ -6734,11 +6591,6 @@ A heading at the slide level always starts a new slide.
6734.IP \[bu] 2
6591.IP \[bu] 2
6735Headings \f[I]below\f[R] the slide level in the hierarchy create
6592Headings \f[I]below\f[R] the slide level in the hierarchy create
6736headings \f[I]within\f[R] a slide.
6593headings \f[I]within\f[R] a slide.
6737−(In beamer, a \[lq]block\[rq] will be created.
6738−If the heading has the class \f[C]example\f[R], an
6739−\f[C]exampleblock\f[R] environment will be used; if it has the class
6740−\f[C]alert\f[R], an \f[C]alertblock\f[R] will be used; otherwise a
6741−regular \f[C]block\f[R] will be used.)
6742.IP \[bu] 2
6594.IP \[bu] 2
6743Headings \f[I]above\f[R] the slide level in the hierarchy create
6595Headings \f[I]above\f[R] the slide level in the hierarchy create
6744\[lq]title slides,\[rq] which just contain the section title and help to
6596\[lq]title slides,\[rq] which just contain the section title and help to
@@ -7708,7 +7560,7 @@ The HTML generated by pandoc is not guaranteed to be safe.
7708If \f[C]raw_html\f[R] is enabled for the Markdown input, users can
7560If \f[C]raw_html\f[R] is enabled for the Markdown input, users can
7709inject arbitrary HTML.
7561inject arbitrary HTML.
7710Even if \f[C]raw_html\f[R] is disabled, users can include dangerous
7562Even if \f[C]raw_html\f[R] is disabled, users can include dangerous
7711−content in URLs and attributes.
7563+content in attributes for headings, spans, and code blocks.
7712To be safe, you should run all the generated HTML through an HTML
7564To be safe, you should run all the generated HTML through an HTML
7713sanitizer.
7565sanitizer.
7714.SH AUTHORS
7566.SH AUTHORS
pandoc.cabal+17−26
@@ -1,6 +1,6 @@
1cabal-version: 2.2
1cabal-version: 2.2
2name: pandoc
2name: pandoc
3−version: 2.14.0.3
3+version: 2.13
4build-type: Simple
4build-type: Simple
5license: GPL-2.0-or-later
5license: GPL-2.0-or-later
6license-file: COPYING.md
6license-file: COPYING.md
@@ -12,7 +12,7 @@ stability: alpha
12homepage: https://pandoc.org
12homepage: https://pandoc.org
13category: Text
13category: Text
14tested-with: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,
14tested-with: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,
15− GHC == 8.8.4, GHC == 8.10.2, GHC == 9.0.1
15+ GHC == 8.8.4, GHC == 8.10.2
16synopsis: Conversion between markup formats
16synopsis: Conversion between markup formats
17description: Pandoc is a Haskell library for converting from one markup
17description: Pandoc is a Haskell library for converting from one markup
18 format to another, and a command-line tool that uses
18 format to another, and a command-line tool that uses
@@ -208,16 +208,12 @@ extra-source-files:
208 test/command/*.md
208 test/command/*.md
209 test/command/*.csl
209 test/command/*.csl
210 test/command/biblio.bib
210 test/command/biblio.bib
211− test/command/averroes.bib
211+ test/command/biblatex-examples.bib
212 test/command/A.txt
212 test/command/A.txt
213 test/command/B.txt
213 test/command/B.txt
214 test/command/C.txt
214 test/command/C.txt
215 test/command/D.txt
215 test/command/D.txt
216 test/command/01.csv
216 test/command/01.csv
217− test/command/chap1/spider.png
218− test/command/chap2/spider.png
219− test/command/chap1/text.md
220− test/command/chap2/text.md
221 test/command/defaults1.yaml
217 test/command/defaults1.yaml
222 test/command/defaults2.yaml
218 test/command/defaults2.yaml
223 test/command/defaults3.yaml
219 test/command/defaults3.yaml
@@ -442,7 +438,6 @@ library
442 SHA >= 1.6 && < 1.7,
438 SHA >= 1.6 && < 1.7,
443 aeson >= 0.7 && < 1.6,
439 aeson >= 0.7 && < 1.6,
444 aeson-pretty >= 0.8.5 && < 0.9,
440 aeson-pretty >= 0.8.5 && < 0.9,
445− array >= 0.5 && < 0.6,
446 attoparsec >= 0.12 && < 0.15,
441 attoparsec >= 0.12 && < 0.15,
447 base64-bytestring >= 0.1 && < 1.3,
442 base64-bytestring >= 0.1 && < 1.3,
448 binary >= 0.7 && < 0.11,
443 binary >= 0.7 && < 0.11,
@@ -450,10 +445,10 @@ library
450 blaze-markup >= 0.8 && < 0.9,
445 blaze-markup >= 0.8 && < 0.9,
451 bytestring >= 0.9 && < 0.12,
446 bytestring >= 0.9 && < 0.12,
452 case-insensitive >= 1.2 && < 1.3,
447 case-insensitive >= 1.2 && < 1.3,
453− citeproc >= 0.4.0.1 && < 0.4.1,
448+ citeproc >= 0.3.0.9 && < 0.3.1,
454− commonmark >= 0.2.1 && < 0.3,
449+ commonmark >= 0.1.1.3 && < 0.2,
455− commonmark-extensions >= 0.2.1.2 && < 0.3,
450+ commonmark-extensions >= 0.2.0.4 && < 0.3,
456− commonmark-pandoc >= 0.2.1.1 && < 0.3,
451+ commonmark-pandoc >= 0.2 && < 0.3,
457 connection >= 0.3.1,
452 connection >= 0.3.1,
458 containers >= 0.4.2.1 && < 0.7,
453 containers >= 0.4.2.1 && < 0.7,
459 data-default >= 0.4 && < 0.8,
454 data-default >= 0.4 && < 0.8,
@@ -465,7 +460,7 @@ library
465 exceptions >= 0.8 && < 0.11,
460 exceptions >= 0.8 && < 0.11,
466 file-embed >= 0.0 && < 0.1,
461 file-embed >= 0.0 && < 0.1,
467 filepath >= 1.1 && < 1.5,
462 filepath >= 1.1 && < 1.5,
468− haddock-library >= 1.10 && < 1.11,
463+ haddock-library >= 1.8 && < 1.10,
469 hslua >= 1.1 && < 1.4,
464 hslua >= 1.1 && < 1.4,
470 hslua-module-path >= 0.1.0 && < 0.2.0,
465 hslua-module-path >= 0.1.0 && < 0.2.0,
471 hslua-module-system >= 0.2 && < 0.3,
466 hslua-module-system >= 0.2 && < 0.3,
@@ -474,31 +469,30 @@ library
474 http-client-tls >= 0.2.4 && < 0.4,
469 http-client-tls >= 0.2.4 && < 0.4,
475 http-types >= 0.8 && < 0.13,
470 http-types >= 0.8 && < 0.13,
476 ipynb >= 0.1 && < 0.2,
471 ipynb >= 0.1 && < 0.2,
477− jira-wiki-markup >= 1.4 && < 1.5,
472+ jira-wiki-markup >= 1.3.4 && < 1.4,
478 mtl >= 2.2 && < 2.3,
473 mtl >= 2.2 && < 2.3,
479 network >= 2.6,
474 network >= 2.6,
480− network-uri >= 2.6 && < 2.8,
475+ network-uri >= 2.6 && < 2.7,
481 pandoc-types >= 1.22 && < 1.23,
476 pandoc-types >= 1.22 && < 1.23,
482 parsec >= 3.1 && < 3.2,
477 parsec >= 3.1 && < 3.2,
483 process >= 1.2.3 && < 1.7,
478 process >= 1.2.3 && < 1.7,
484 random >= 1 && < 1.3,
479 random >= 1 && < 1.3,
485 safe >= 0.3.18 && < 0.4,
480 safe >= 0.3.18 && < 0.4,
486 scientific >= 0.3 && < 0.4,
481 scientific >= 0.3 && < 0.4,
487− skylighting >= 0.10.5.2 && < 0.10.6,
482+ skylighting >= 0.10.5.1 && < 0.10.6,
488− skylighting-core >= 0.10.5.2 && < 0.10.6,
483+ skylighting-core >= 0.10.5.1 && < 0.10.6,
489 split >= 0.2 && < 0.3,
484 split >= 0.2 && < 0.3,
490 syb >= 0.1 && < 0.8,
485 syb >= 0.1 && < 0.8,
491 tagsoup >= 0.14.6 && < 0.15,
486 tagsoup >= 0.14.6 && < 0.15,
492 temporary >= 1.1 && < 1.4,
487 temporary >= 1.1 && < 1.4,
493− texmath >= 0.12.3 && < 0.12.4,
488+ texmath >= 0.12.2 && < 0.12.3,
494 text >= 1.1.1.0 && < 1.3,
489 text >= 1.1.1.0 && < 1.3,
495 text-conversions >= 0.3 && < 0.4,
490 text-conversions >= 0.3 && < 0.4,
496− time >= 1.5 && < 1.12,
491+ time >= 1.5 && < 1.10,
497 unicode-transforms >= 0.3 && < 0.4,
492 unicode-transforms >= 0.3 && < 0.4,
498 unordered-containers >= 0.2 && < 0.3,
493 unordered-containers >= 0.2 && < 0.3,
499 xml >= 1.3.12 && < 1.4,
494 xml >= 1.3.12 && < 1.4,
500− xml-conduit >= 1.9.1.1 && < 1.10,
495+ xml-conduit >= 1.7 && < 1.10,
501− unicode-collation >= 0.1.1 && < 0.2,
502 zip-archive >= 0.2.3.4 && < 0.5,
496 zip-archive >= 0.2.3.4 && < 0.5,
503 zlib >= 0.5 && < 0.7
497 zlib >= 0.5 && < 0.7
504 if os(windows) && arch(i386)
498 if os(windows) && arch(i386)
@@ -517,7 +511,6 @@ library
517 Text.Pandoc.Options,
511 Text.Pandoc.Options,
518 Text.Pandoc.Extensions,
512 Text.Pandoc.Extensions,
519 Text.Pandoc.Shared,
513 Text.Pandoc.Shared,
520− Text.Pandoc.Sources,
521 Text.Pandoc.MediaBag,
514 Text.Pandoc.MediaBag,
522 Text.Pandoc.Error,
515 Text.Pandoc.Error,
523 Text.Pandoc.Filter,
516 Text.Pandoc.Filter,
@@ -607,6 +600,7 @@ library
607 Text.Pandoc.Asciify,
600 Text.Pandoc.Asciify,
608 Text.Pandoc.Emoji,
601 Text.Pandoc.Emoji,
609 Text.Pandoc.ImageSize,
602 Text.Pandoc.ImageSize,
603+ Text.Pandoc.BCP47,
610 Text.Pandoc.Class,
604 Text.Pandoc.Class,
611 Text.Pandoc.Citeproc
605 Text.Pandoc.Citeproc
612 other-modules: Text.Pandoc.App.CommandLineOptions,
606 other-modules: Text.Pandoc.App.CommandLineOptions,
@@ -663,9 +657,6 @@ library
663 Text.Pandoc.Readers.Metadata,
657 Text.Pandoc.Readers.Metadata,
664 Text.Pandoc.Readers.Roff,
658 Text.Pandoc.Readers.Roff,
665 Text.Pandoc.Writers.Docx.StyleMap,
659 Text.Pandoc.Writers.Docx.StyleMap,
666− Text.Pandoc.Writers.Docx.Table,
667− Text.Pandoc.Writers.Docx.Types,
668− Text.Pandoc.Writers.GridTable
669 Text.Pandoc.Writers.JATS.References,
660 Text.Pandoc.Writers.JATS.References,
670 Text.Pandoc.Writers.JATS.Table,
661 Text.Pandoc.Writers.JATS.Table,
671 Text.Pandoc.Writers.JATS.Types,
662 Text.Pandoc.Writers.JATS.Types,
@@ -768,7 +759,7 @@ test-suite test-pandoc
768 tasty-lua >= 0.2 && < 0.3,
759 tasty-lua >= 0.2 && < 0.3,
769 tasty-quickcheck >= 0.8 && < 0.11,
760 tasty-quickcheck >= 0.8 && < 0.11,
770 text >= 1.1.1.0 && < 1.3,
761 text >= 1.1.1.0 && < 1.3,
771− time >= 1.5 && < 1.12,
762+ time >= 1.5 && < 1.10,
772 xml >= 1.3.12 && < 1.4,
763 xml >= 1.3.12 && < 1.4,
773 zip-archive >= 0.2.3.4 && < 0.5
764 zip-archive >= 0.2.3.4 && < 0.5
774 other-modules: Tests.Old
765 other-modules: Tests.Old
src/Text/Pandoc/App.hs+13−19
@@ -55,7 +55,7 @@ import Text.Pandoc.App.Opt (Opt (..), LineEnding (..), defaultOpts,
55import Text.Pandoc.App.CommandLineOptions (parseOptions, parseOptionsFromArgs,
55import Text.Pandoc.App.CommandLineOptions (parseOptions, parseOptionsFromArgs,
56 options)
56 options)
57import Text.Pandoc.App.OutputSettings (OutputSettings (..), optToOutputSettings)
57import Text.Pandoc.App.OutputSettings (OutputSettings (..), optToOutputSettings)
58−import Text.Collate.Lang (Lang (..), parseLang)
58+import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
59import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
59import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
60import Text.Pandoc.PDF (makePDF)
60import Text.Pandoc.PDF (makePDF)
61import Text.Pandoc.SelfContained (makeSelfContained)
61import Text.Pandoc.SelfContained (makeSelfContained)
@@ -160,11 +160,9 @@ convertWithOpts opts = do
160 else optTabStop opts)
160 else optTabStop opts)
161
161
162
162
163− let readSources :: [FilePath] -> PandocIO [(FilePath, Text)]
163+ let readSources :: [FilePath] -> PandocIO Text
164− readSources srcs =
164+ readSources srcs = convertTabs . T.intercalate (T.pack "\n") <$>
165− mapM (\fp -> do
166− t <- readSource fp
165+ mapM readSource srcs
167− return (if fp == "-" then "" else fp, convertTabs t)) srcs
168
166
169
167
170 outputSettings <- optToOutputSettings opts
168 outputSettings <- optToOutputSettings opts
@@ -202,8 +200,8 @@ convertWithOpts opts = do
202 Just f -> readFileStrict f
200 Just f -> readFileStrict f
203
201
204 case lookupMetaString "lang" (optMetadata opts) of
202 case lookupMetaString "lang" (optMetadata opts) of
205− "" -> setTranslations $ Lang "en" Nothing (Just "US") [] [] []
203+ "" -> setTranslations $ Lang "en" "" "US" []
206− l -> case parseLang l of
204+ l -> case parseBCP47 l of
207 Left _ -> report $ InvalidLang l
205 Left _ -> report $ InvalidLang l
208 Right l' -> setTranslations l'
206 Right l' -> setTranslations l'
209
207
@@ -257,17 +255,13 @@ convertWithOpts opts = do
257 let sourceToDoc :: [FilePath] -> PandocIO Pandoc
255 let sourceToDoc :: [FilePath] -> PandocIO Pandoc
258 sourceToDoc sources' =
256 sourceToDoc sources' =
259 case reader of
257 case reader of
260− TextReader r
258+ TextReader r
261− | readerNameBase == "json" ->
259+ | optFileScope opts || readerNameBase == "json" ->
262− mconcat <$> mapM (readSource >=> r readerOpts) sources'
260+ mconcat <$> mapM (readSource >=> r readerOpts) sources'
263− | optFileScope opts ->
264− -- Read source and convert tabs (see #6709)
265− let readSource' = fmap convertTabs . readSource
266− in mconcat <$> mapM (readSource' >=> r readerOpts) sources'
267− | otherwise ->
261+ | otherwise ->
268− readSources sources' >>= r readerOpts
262+ readSources sources' >>= r readerOpts
269− ByteStringReader r ->
263+ ByteStringReader r ->
270− mconcat <$> mapM (readFile' >=> r readerOpts) sources'
264+ mconcat <$> mapM (readFile' >=> r readerOpts) sources'
271
265
272
266
273 when (readerNameBase == "markdown_github" ||
267 when (readerNameBase == "markdown_github" ||
src/Text/Pandoc/App/Opt.hs+1−1
@@ -687,7 +687,7 @@ yamlToMeta (Mapping _ _ m) =
687 where
687 where
688 pMetaString = pure . MetaString <$> P.manyChar P.anyChar
688 pMetaString = pure . MetaString <$> P.manyChar P.anyChar
689 runEverything p =
689 runEverything p =
690− runPure (P.readWithM p (def :: P.ParserState) ("" :: Text))
690+ runPure (P.readWithM p (def :: P.ParserState) "")
691 >>= fmap (Meta . flip P.runF def)
691 >>= fmap (Meta . flip P.runF def)
692yamlToMeta _ = return mempty
692yamlToMeta _ = return mempty
693
693
src/Text/Pandoc/BCP47.hsnew file+112
@@ -0,0 +1,112 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{- |
3+ Module : Text.Pandoc.BCP47
4+ Copyright : Copyright (C) 2017-2021 John MacFarlane
5+ License : GNU GPL, version 2 or above
6+
7+ Maintainer : John MacFarlane <jgm@berkeley.edu>
8+ Stability : alpha
9+ Portability : portable
10+
11+Functions for parsing and rendering BCP47 language identifiers.
12+-}
13+module Text.Pandoc.BCP47 (
14+ getLang
15+ , parseBCP47
16+ , Lang(..)
17+ , renderLang
18+ )
19+where
20+import Control.Monad (guard)
21+import Data.Char (isAlphaNum, isAscii, isLetter, isLower, isUpper)
22+import Text.Pandoc.Definition
23+import Text.Pandoc.Options
24+import Text.DocTemplates (FromContext(..))
25+import qualified Data.Text as T
26+import qualified Text.Parsec as P
27+
28+-- | Represents BCP 47 language/country code.
29+data Lang = Lang{ langLanguage :: T.Text
30+ , langScript :: T.Text
31+ , langRegion :: T.Text
32+ , langVariants :: [T.Text] }
33+ deriving (Eq, Ord, Show)
34+
35+-- | Render a Lang as BCP 47.
36+renderLang :: Lang -> T.Text
37+renderLang lang = T.intercalate "-" (langLanguage lang : filter (not . T.null)
38+ ([langScript lang, langRegion lang] ++ langVariants lang))
39+
40+-- | Get the contents of the `lang` metadata field or variable.
41+getLang :: WriterOptions -> Meta -> Maybe T.Text
42+getLang opts meta =
43+ case lookupContext "lang" (writerVariables opts) of
44+ Just s -> Just s
45+ _ ->
46+ case lookupMeta "lang" meta of
47+ Just (MetaBlocks [Para [Str s]]) -> Just s
48+ Just (MetaBlocks [Plain [Str s]]) -> Just s
49+ Just (MetaInlines [Str s]) -> Just s
50+ Just (MetaString s) -> Just s
51+ _ -> Nothing
52+
53+-- | Parse a BCP 47 string as a Lang. Currently we parse
54+-- extensions and private-use fields as "variants," even
55+-- though officially they aren't.
56+parseBCP47 :: T.Text -> Either T.Text Lang
57+parseBCP47 lang =
58+ case P.parse bcp47 "lang" lang of
59+ Right r -> Right r
60+ Left e -> Left $ T.pack $ show e
61+ where bcp47 = do
62+ language <- pLanguage
63+ script <- P.option "" pScript
64+ region <- P.option "" pRegion
65+ variants <- P.many (pVariant P.<|> pExtension P.<|> pPrivateUse)
66+ P.eof
67+ return Lang{ langLanguage = language
68+ , langScript = script
69+ , langRegion = region
70+ , langVariants = variants }
71+ asciiLetter = P.satisfy (\c -> isAscii c && isLetter c)
72+ pLanguage = do
73+ cs <- P.many1 asciiLetter
74+ let lcs = length cs
75+ guard $ lcs == 2 || lcs == 3
76+ return $ T.toLower $ T.pack cs
77+ pScript = P.try $ do
78+ P.char '-'
79+ x <- P.satisfy (\c -> isAscii c && isLetter c && isUpper c)
80+ xs <- P.count 3
81+ (P.satisfy (\c -> isAscii c && isLetter c && isLower c))
82+ return $ T.toLower $ T.pack (x:xs)
83+ pRegion = P.try $ do
84+ P.char '-'
85+ cs <- P.many1 asciiLetter
86+ let lcs = length cs
87+ guard $ lcs == 2 || lcs == 3
88+ return $ T.toUpper $ T.pack cs
89+ pVariant = P.try $ do
90+ P.char '-'
91+ ds <- P.option "" (P.count 1 P.digit)
92+ cs <- P.many1 asciiLetter
93+ let var = ds ++ cs
94+ lv = length var
95+ guard $ if null ds
96+ then lv >= 5 && lv <= 8
97+ else lv == 4
98+ return $ T.toLower $ T.pack var
99+ pExtension = P.try $ do
100+ P.char '-'
101+ cs <- P.many1 $ P.satisfy (\c -> isAscii c && isAlphaNum c)
102+ let lcs = length cs
103+ guard $ lcs >= 2 && lcs <= 8
104+ return $ T.toLower $ T.pack cs
105+ pPrivateUse = P.try $ do
106+ P.char '-'
107+ P.char 'x'
108+ P.char '-'
109+ cs <- P.many1 $ P.satisfy (\c -> isAscii c && isAlphaNum c)
110+ guard $ not (null cs) && length cs <= 8
111+ let var = "x-" ++ cs
112+ return $ T.toLower $ T.pack var
src/Text/Pandoc/Citeproc.hs+51−70
@@ -18,6 +18,7 @@ import Text.Pandoc.Citeproc.CslJson (cslJsonToReferences)
18import Text.Pandoc.Citeproc.BibTeX (readBibtexString, Variant(..))
18import Text.Pandoc.Citeproc.BibTeX (readBibtexString, Variant(..))
19import Text.Pandoc.Citeproc.MetaValue (metaValueToReference, metaValueToText)
19import Text.Pandoc.Citeproc.MetaValue (metaValueToReference, metaValueToText)
20import Text.Pandoc.Readers.Markdown (yamlToRefs)
20import Text.Pandoc.Readers.Markdown (yamlToRefs)
21+import qualified Text.Pandoc.BCP47 as BCP47
21import Text.Pandoc.Builder (Inlines, Many(..), deleteMeta, setMeta)
22import Text.Pandoc.Builder (Inlines, Many(..), deleteMeta, setMeta)
22import qualified Text.Pandoc.Builder as B
23import qualified Text.Pandoc.Builder as B
23import Text.Pandoc.Definition as Pandoc
24import Text.Pandoc.Definition as Pandoc
@@ -27,7 +28,7 @@ import Text.Pandoc.Error (PandocError(..))
27import Text.Pandoc.Extensions (pandocExtensions)
28import Text.Pandoc.Extensions (pandocExtensions)
28import Text.Pandoc.Logging (LogMessage(..))
29import Text.Pandoc.Logging (LogMessage(..))
29import Text.Pandoc.Options (ReaderOptions(..))
30import Text.Pandoc.Options (ReaderOptions(..))
30−import Text.Pandoc.Shared (stringify, ordNub, tshow)
31+import Text.Pandoc.Shared (stringify, ordNub, blocksToInlines, tshow)
31import qualified Text.Pandoc.UTF8 as UTF8
32import qualified Text.Pandoc.UTF8 as UTF8
32import Text.Pandoc.Walk (query, walk, walkM)
33import Text.Pandoc.Walk (query, walk, walkM)
33import Control.Applicative ((<|>))
34import Control.Applicative ((<|>))
@@ -74,7 +75,8 @@ processCitations (Pandoc meta bs) = do
74
75
75 let linkCites = maybe False truish $ lookupMeta "link-citations" meta
76 let linkCites = maybe False truish $ lookupMeta "link-citations" meta
76 let opts = defaultCiteprocOptions{ linkCitations = linkCites }
77 let opts = defaultCiteprocOptions{ linkCitations = linkCites }
77− let result = Citeproc.citeproc opts style mblang refs citations
78+ let result = Citeproc.citeproc opts style (localeLanguage locale)
79+ refs citations
78 mapM_ (report . CiteprocWarning) (resultWarnings result)
80 mapM_ (report . CiteprocWarning) (resultWarnings result)
79 let sopts = styleOptions style
81 let sopts = styleOptions style
80 let classes = "references" : -- TODO remove this or keep for compatibility?
82 let classes = "references" : -- TODO remove this or keep for compatibility?
@@ -91,18 +93,22 @@ processCitations (Pandoc meta bs) = do
91 walk (convertQuotes locale) .
93 walk (convertQuotes locale) .
92 insertSpace $ out)
94 insertSpace $ out)
93 (resultBibliography result)
95 (resultBibliography result)
94− let moveNotes = styleIsNoteStyle sopts &&
96+ let moveNotes = maybe True truish $
95− maybe True truish (lookupMeta "notes-after-punctuation" meta)
97+ lookupMeta "notes-after-punctuation" meta
96 let cits = map (walk (convertQuotes locale)) $
98 let cits = map (walk (convertQuotes locale)) $
97 resultCitations result
99 resultCitations result
98
100
101+ let fixQuotes = case localePunctuationInQuote locale of
102+ Just True ->
103+ B.toList . movePunctuationInsideQuotes . B.fromList
104+ _ -> id
105+
99 let metanocites = lookupMeta "nocite" meta
106 let metanocites = lookupMeta "nocite" meta
100 let Pandoc meta'' bs' =
107 let Pandoc meta'' bs' =
101 maybe id (setMeta "nocite") metanocites .
108 maybe id (setMeta "nocite") metanocites .
109+ walk (map capitalizeNoteCitation .
102− walk (mvPunct moveNotes locale) .
110+ fixQuotes . mvPunct moveNotes locale) .
103− (if styleIsNoteStyle sopts
104− then walk addNote . walk deNote
111+ walk deNote .
105− else id) .
106 evalState (walkM insertResolvedCitations $ Pandoc meta' bs)
112 evalState (walkM insertResolvedCitations $ Pandoc meta' bs)
107 $ cits
113 $ cits
108 return $ Pandoc meta''
114 return $ Pandoc meta''
@@ -191,9 +197,7 @@ getReferences mblocale (Pandoc meta bs) = do
191 then const True
197 then const True
192 else (`Set.member` citeIds)
198 else (`Set.member` citeIds)
193 let inlineRefs = case lookupMeta "references" meta of
199 let inlineRefs = case lookupMeta "references" meta of
194− Just (MetaList rs) ->
195− filter (idpred . unItemId . referenceId)
196− $ mapMaybe metaValueToReference rs
200+ Just (MetaList rs) -> mapMaybe metaValueToReference rs
197 _ -> []
201 _ -> []
198 externalRefs <- case lookupMeta "bibliography" meta of
202 externalRefs <- case lookupMeta "bibliography" meta of
199 Just (MetaList xs) ->
203 Just (MetaList xs) ->
@@ -372,6 +376,7 @@ formatFromExtension fp = case dropWhile (== '.') $ takeExtension fp of
372
376
373
377
374isNote :: Inline -> Bool
378isNote :: Inline -> Bool
379+isNote (Note _) = True
375isNote (Cite _ [Note _]) = True
380isNote (Cite _ [Note _]) = True
376 -- the following allows citation styles that are "in-text" but use superscript
381 -- the following allows citation styles that are "in-text" but use superscript
377 -- references to be treated as if they are "notes" for the purposes of moving
382 -- references to be treated as if they are "notes" for the purposes of moving
@@ -384,12 +389,6 @@ isSpacy Space = True
384isSpacy SoftBreak = True
389isSpacy SoftBreak = True
385isSpacy _ = False
390isSpacy _ = False
386
391
387−movePunctInsideQuotes :: Locale -> [Inline] -> [Inline]
388−movePunctInsideQuotes locale
389− | localePunctuationInQuote locale == Just True
390− = B.toList . movePunctuationInsideQuotes . B.fromList
391− | otherwise
392− = id
393
392
394mvPunct :: Bool -> Locale -> [Inline] -> [Inline]
393mvPunct :: Bool -> Locale -> [Inline] -> [Inline]
395mvPunct moveNotes locale (x : xs)
394mvPunct moveNotes locale (x : xs)
@@ -402,8 +401,7 @@ mvPunct moveNotes locale (q : s : x : ys)
402 in if moveNotes
401 in if moveNotes
403 then if T.null spunct
402 then if T.null spunct
404 then q : x : mvPunct moveNotes locale ys
403 then q : x : mvPunct moveNotes locale ys
405− else movePunctInsideQuotes locale
406− [q , Str spunct , x] ++ mvPunct moveNotes locale
404+ else q : Str spunct : x : mvPunct moveNotes locale
407 (B.toList
405 (B.toList
408 (dropTextWhile isPunctuation (B.fromList ys)))
406 (dropTextWhile isPunctuation (B.fromList ys)))
409 else q : x : mvPunct moveNotes locale ys
407 else q : x : mvPunct moveNotes locale ys
@@ -415,10 +413,9 @@ mvPunct moveNotes locale (Cite cs ils : ys)
415 , moveNotes
413 , moveNotes
416 = let s = stringify ys
414 = let s = stringify ys
417 spunct = T.takeWhile isPunctuation s
415 spunct = T.takeWhile isPunctuation s
418− in Cite cs (movePunctInsideQuotes locale $
419− init ils
416+ in Cite cs (init ils
420− ++ [Str spunct | not (endWithPunct False (init ils))]
417+ ++ [Str spunct | not (endWithPunct False (init ils))]
421− ++ [last ils]) :
418+ ++ [last ils]) :
422 mvPunct moveNotes locale
419 mvPunct moveNotes locale
423 (B.toList (dropTextWhile isPunctuation (B.fromList ys)))
420 (B.toList (dropTextWhile isPunctuation (B.fromList ys)))
424mvPunct moveNotes locale (s : x : ys) | isSpacy s, isNote x =
421mvPunct moveNotes locale (s : x : ys) | isSpacy s, isNote x =
@@ -504,8 +501,7 @@ insertRefs refkvs refclasses meta refs bs =
504 put True
501 put True
505 -- refHeader isn't used if you have an explicit references div
502 -- refHeader isn't used if you have an explicit references div
506 let cs' = ordNub $ cs ++ refclasses
503 let cs' = ordNub $ cs ++ refclasses
507− let kvs' = ordNub $ kvs ++ refkvs
508− return $ Div ("refs",cs',kvs') (xs ++ refs)
504+ return $ Div ("refs",cs',kvs) (xs ++ refs)
509 go x = return x
505 go x = return x
510
506
511refTitle :: Meta -> Maybe [Inline]
507refTitle :: Meta -> Maybe [Inline]
@@ -564,62 +560,42 @@ extractText (FancyVal x) = toText x
564extractText (NumVal n) = T.pack (show n)
560extractText (NumVal n) = T.pack (show n)
565extractText _ = mempty
561extractText _ = mempty
566
562
567−-- Here we take the Spans with class csl-note that are left
568−-- after deNote has removed nested ones, and convert them
569−-- into real notes.
570−addNote :: Inline -> Inline
563+capitalizeNoteCitation :: Inline -> Inline
571−addNote (Span ("",["csl-note"],[]) ils) =
564+capitalizeNoteCitation (Cite cs [Note [Para ils]]) =
572− Note [Para $
565+ Cite cs
573− B.toList . addTextCase Nothing CapitalizeFirst . B.fromList $ ils]
566+ [Note [Para $ B.toList $ addTextCase Nothing CapitalizeFirst
574−addNote x = x
567+ $ B.fromList ils]]
575−
568+capitalizeNoteCitation x = x
576−-- Here we handle citation notes that occur inside footnotes
569+
577−-- or other citation notes, in a note style. We don't want
578−-- notes inside notes, so we convert these to parenthesized
579−-- or comma-separated citations.
580−deNote :: Inline -> Inline
570+deNote :: [Inline] -> [Inline]
581−deNote (Note bs) =
571+deNote [] = []
582− case bs of
572+deNote (Note bs:rest) =
583− [Para (cit@(Cite (c:_) _) : ils)]
573+ Note (walk go bs) : deNote rest
584− | citationMode c /= AuthorInText ->
585− -- if citation is first in note, no need to parenthesize.
586− Note [Para (walk removeNotes $ cit : walk addParens ils)]
587− _ -> Note (walk removeNotes . walk addParens $ bs)
588−
589 where
574 where
590− addParens [] = []
575+ go [] = []
591− addParens (Cite (c:cs) ils : zs)
576+ go (Cite (c:cs) ils : zs)
592 | citationMode c == AuthorInText
577 | citationMode c == AuthorInText
593− = Cite (c:cs) (concatMap (noteAfterComma (needsPeriod zs)) ils) :
578+ = Cite (c:cs) (concatMap (noteAfterComma (needsPeriod zs)) ils) : go zs
594− addParens zs
595 | otherwise
579 | otherwise
596− = Cite (c:cs) (concatMap noteInParens ils) : addParens zs
580+ = Cite (c:cs) (concatMap noteInParens ils) : go zs
597− addParens (x:xs) = x : addParens xs
581+ go (x:xs) = x : go xs
598−
599− removeNotes (Span ("",["csl-note"],[]) ils) = Span ("",[],[]) ils
600− removeNotes x = x
601−
602 needsPeriod [] = True
582 needsPeriod [] = True
603 needsPeriod (Str t:_) = case T.uncons t of
583 needsPeriod (Str t:_) = case T.uncons t of
604 Nothing -> False
584 Nothing -> False
605 Just (c,_) -> isUpper c
585 Just (c,_) -> isUpper c
606 needsPeriod (Space:zs) = needsPeriod zs
586 needsPeriod (Space:zs) = needsPeriod zs
607 needsPeriod _ = False
587 needsPeriod _ = False
608−
609− noteInParens (Span ("",["csl-note"],[]) ils)
588+ noteInParens (Note bs')
610 = Space : Str "(" :
589 = Space : Str "(" :
611− removeFinalPeriod ils ++ [Str ")"]
590+ removeFinalPeriod (blocksToInlines bs') ++ [Str ")"]
612 noteInParens x = [x]
591 noteInParens x = [x]
613−
614− noteAfterComma needsPer (Span ("",["csl-note"],[]) ils)
592+ noteAfterComma needsPer (Note bs')
615− | not (null ils)
616 = Str "," : Space :
593 = Str "," : Space :
617− if needsPer
594+ (if needsPer
618− then ils
595+ then id
619− else removeFinalPeriod ils
596+ else removeFinalPeriod) (blocksToInlines bs')
620 noteAfterComma _ x = [x]
597 noteAfterComma _ x = [x]
621−
622−deNote x = x
598+deNote (x:xs) = x : deNote xs
623
599
624-- Note: we can't use dropTextWhileEnd indiscriminately,
600-- Note: we can't use dropTextWhileEnd indiscriminately,
625-- because this would remove the final period on abbreviations like Ibid.
601-- because this would remove the final period on abbreviations like Ibid.
@@ -654,8 +630,13 @@ removeFinalPeriod ils =
654
630
655bcp47LangToIETF :: PandocMonad m => Text -> m (Maybe Lang)
631bcp47LangToIETF :: PandocMonad m => Text -> m (Maybe Lang)
656bcp47LangToIETF bcplang =
632bcp47LangToIETF bcplang =
657− case parseLang bcplang of
633+ case BCP47.parseBCP47 bcplang of
658 Left _ -> do
634 Left _ -> do
659 report $ InvalidLang bcplang
635 report $ InvalidLang bcplang
660 return Nothing
636 return Nothing
637+ Right lang ->
661− Right lang -> return $ Just lang
638+ return $ Just
639+ $ Lang (BCP47.langLanguage lang)
640+ (if T.null (BCP47.langRegion lang)
641+ then Nothing
642+ else Just (BCP47.langRegion lang))
src/Text/Pandoc/Citeproc/BibTeX.hs+15−25
@@ -59,11 +59,10 @@ data Variant = Bibtex | Biblatex
59 deriving (Show, Eq, Ord)
59 deriving (Show, Eq, Ord)
60
60
61-- | Parse BibTeX or BibLaTeX into a list of 'Reference's.
61-- | Parse BibTeX or BibLaTeX into a list of 'Reference's.
62−readBibtexString :: ToSources a
63− => Variant -- ^ bibtex or biblatex
62+readBibtexString :: Variant -- ^ bibtex or biblatex
64 -> Locale -- ^ Locale
63 -> Locale -- ^ Locale
65 -> (Text -> Bool) -- ^ Filter on citation ids
64 -> (Text -> Bool) -- ^ Filter on citation ids
66− -> a -- ^ bibtex/biblatex text
65+ -> Text -- ^ bibtex/biblatex text
67 -> Either ParseError [Reference Inlines]
66 -> Either ParseError [Reference Inlines]
68readBibtexString variant locale idpred contents = do
67readBibtexString variant locale idpred contents = do
69 case runParser (((resolveCrossRefs variant <$> bibEntries) <* eof) >>=
68 case runParser (((resolveCrossRefs variant <$> bibEntries) <* eof) >>=
@@ -71,11 +70,9 @@ readBibtexString variant locale idpred contents = do
71 filter (\item -> idpred (identifier item) &&
70 filter (\item -> idpred (identifier item) &&
72 entryType item /= "xdata"))
71 entryType item /= "xdata"))
73 (fromMaybe defaultLang $ localeLanguage locale, Map.empty)
72 (fromMaybe defaultLang $ localeLanguage locale, Map.empty)
74− (initialSourceName sources) sources of
73+ "" contents of
75 Left err -> Left err
74 Left err -> Left err
76 Right xs -> return xs
75 Right xs -> return xs
77− where
78− sources = toSources contents
79
76
80-- | Write BibTeX or BibLaTeX given given a 'Reference'.
77-- | Write BibTeX or BibLaTeX given given a 'Reference'.
81writeBibtexString :: WriterOptions -- ^ options (for writing LaTex)
78writeBibtexString :: WriterOptions -- ^ options (for writing LaTex)
@@ -158,7 +155,6 @@ writeBibtexString opts variant mblang ref =
158 , "langid"
155 , "langid"
159 , "abstract"
156 , "abstract"
160 , "keywords"
157 , "keywords"
161− , "annote"
162 ]
158 ]
163 Bibtex ->
159 Bibtex ->
164 [ "author"
160 [ "author"
@@ -178,7 +174,6 @@ writeBibtexString opts variant mblang ref =
178 , "address"
174 , "address"
179 , "type"
175 , "type"
180 , "note"
176 , "note"
181− , "annote"
182 ]
177 ]
183
178
184 valToInlines (TextVal t) = B.text t
179 valToInlines (TextVal t) = B.text t
@@ -210,13 +205,10 @@ writeBibtexString opts variant mblang ref =
210 [ (", " <>) <$> nameGiven name,
205 [ (", " <>) <$> nameGiven name,
211 nameDroppingParticle name ]
206 nameDroppingParticle name ]
212
207
213− mblang' = case getVariableAsText "language" of
208+ mblang' = (parseLang <$> getVariableAsText "language") <|> mblang
214− Just l -> either (const Nothing) Just $ parseLang l
215− Nothing -> mblang
216
209
217 titlecase = case mblang' of
210 titlecase = case mblang' of
218− Just lang | langLanguage lang == "en"
219− -> titlecase'
211+ Just (Lang "en" _) -> titlecase'
220 Nothing -> titlecase'
212 Nothing -> titlecase'
221 _ ->
213 _ ->
222 case variant of
214 case variant of
@@ -339,12 +331,12 @@ writeBibtexString opts variant mblang ref =
339 renderFields = mconcat . intersperse ("," <> cr) . mapMaybe renderField
331 renderFields = mconcat . intersperse ("," <> cr) . mapMaybe renderField
340
332
341defaultLang :: Lang
333defaultLang :: Lang
342−defaultLang = Lang "en" Nothing (Just "US") [] [] []
334+defaultLang = Lang "en" (Just "US")
343
335
344-- a map of bibtex "string" macros
336-- a map of bibtex "string" macros
345type StringMap = Map.Map Text Text
337type StringMap = Map.Map Text Text
346
338
347−type BibParser = Parser Sources (Lang, StringMap)
339+type BibParser = Parser Text (Lang, StringMap)
348
340
349data Item = Item{ identifier :: Text
341data Item = Item{ identifier :: Text
350 , sourcePos :: SourcePos
342 , sourcePos :: SourcePos
@@ -359,7 +351,9 @@ itemToReference locale variant item = do
359 bib item $ do
351 bib item $ do
360 let lang = fromMaybe defaultLang $ localeLanguage locale
352 let lang = fromMaybe defaultLang $ localeLanguage locale
361 modify $ \st -> st{ localeLang = lang,
353 modify $ \st -> st{ localeLang = lang,
362− untitlecase = langLanguage lang == "en" }
354+ untitlecase = case lang of
355+ (Lang "en" _) -> True
356+ _ -> False }
363
357
364 id' <- asks identifier
358 id' <- asks identifier
365 otherIds <- (Just <$> getRawField "ids")
359 otherIds <- (Just <$> getRawField "ids")
@@ -717,7 +711,7 @@ itemToReference locale variant item = do
717
711
718
712
719bib :: Item -> Bib a -> BibParser a
713bib :: Item -> Bib a -> BibParser a
720−bib entry m = fst <$> evalRWST m entry (BibState True defaultLang)
714+bib entry m = fst <$> evalRWST m entry (BibState True (Lang "en" (Just "US")))
721
715
722resolveCrossRefs :: Variant -> [Item] -> [Item]
716resolveCrossRefs :: Variant -> [Item] -> [Item]
723resolveCrossRefs variant entries =
717resolveCrossRefs variant entries =
@@ -809,7 +803,7 @@ bibEntries = do
809 (bibComment <|> bibPreamble <|> bibString))
803 (bibComment <|> bibPreamble <|> bibString))
810
804
811bibSkip :: BibParser ()
805bibSkip :: BibParser ()
812−bibSkip = skipMany1 (satisfy (/='@'))
806+bibSkip = () <$ take1WhileP (/='@')
813
807
814bibComment :: BibParser ()
808bibComment :: BibParser ()
815bibComment = do
809bibComment = do
@@ -834,9 +828,6 @@ bibString = do
834 updateState (\(l,m) -> (l, Map.insert k v m))
828 updateState (\(l,m) -> (l, Map.insert k v m))
835 return ()
829 return ()
836
830
837−take1WhileP :: Monad m => (Char -> Bool) -> ParserT Sources u m Text
838−take1WhileP f = T.pack <$> many1 (satisfy f)
839−
840inBraces :: BibParser Text
831inBraces :: BibParser Text
841inBraces = do
832inBraces = do
842 char '{'
833 char '{'
@@ -868,7 +859,7 @@ fieldName = resolveAlias . T.toLower
868
859
869isBibtexKeyChar :: Char -> Bool
860isBibtexKeyChar :: Char -> Bool
870isBibtexKeyChar c =
861isBibtexKeyChar c =
871− isAlphaNum c || c `elem` (".:;?!`'()$/*@_+=-[]*&" :: [Char])
862+ isAlphaNum c || c `elem` (".:;?!`'()/*@_+=-[]*&" :: [Char])
872
863
873bibItem :: BibParser Item
864bibItem :: BibParser Item
874bibItem = do
865bibItem = do
@@ -1465,9 +1456,8 @@ resolveKey lang ils = Walk.walk go ils
1465 go x = x
1456 go x = x
1466
1457
1467resolveKey' :: Lang -> Text -> Text
1458resolveKey' :: Lang -> Text -> Text
1468−resolveKey' lang k =
1459+resolveKey' lang@(Lang l _) k =
1469− case Map.lookup (langLanguage lang) biblatexStringMap >>=
1460+ case Map.lookup l biblatexStringMap >>= Map.lookup (T.toLower k) of
1470− Map.lookup (T.toLower k) of
1471 Nothing -> k
1461 Nothing -> k
1472 Just (x, _) -> either (const k) stringify $ parseLaTeX lang x
1462 Just (x, _) -> either (const k) stringify $ parseLaTeX lang x
1473
1463
src/Text/Pandoc/Citeproc/Data.hs+6−7
@@ -10,7 +10,7 @@ import qualified Data.Text.Encoding as TE
10import qualified Data.Text as T
10import qualified Data.Text as T
11import Data.Text (Text)
11import Data.Text (Text)
12import Text.Pandoc.Citeproc.Util (toIETF)
12import Text.Pandoc.Citeproc.Util (toIETF)
13−import Text.Collate.Lang (Lang(..), parseLang)
13+import Citeproc (Lang(..), parseLang)
14
14
15biblatexLocalizations :: [(FilePath, ByteString)]
15biblatexLocalizations :: [(FilePath, ByteString)]
16biblatexLocalizations = $(embedDir "citeproc/biblatex-localization")
16biblatexLocalizations = $(embedDir "citeproc/biblatex-localization")
@@ -21,12 +21,11 @@ biblatexStringMap :: M.Map Text (M.Map Text (Text, Text))
21biblatexStringMap = foldr go mempty biblatexLocalizations
21biblatexStringMap = foldr go mempty biblatexLocalizations
22 where
22 where
23 go (fp, bs) =
23 go (fp, bs) =
24− let ls = T.lines $ TE.decodeUtf8 bs
25− in case parseLang (toIETF $ T.takeWhile (/= '.') $ T.pack fp) of
24+ let Lang lang _ = parseLang (toIETF $ T.takeWhile (/= '.') $ T.pack fp)
25+ ls = T.lines $ TE.decodeUtf8 bs
26− Right lang | length ls > 4
26+ in if length ls > 4
27− -> M.insert (langLanguage lang)
28− (toStringMap $ map (T.splitOn "|") ls)
27+ then M.insert lang (toStringMap $ map (T.splitOn "|") ls)
29− _ -> id
28+ else id
30 toStringMap = foldr go' mempty
29 toStringMap = foldr go' mempty
31 go' [term, x, y] = M.insert term (x, y)
30 go' [term, x, y] = M.insert term (x, y)
32 go' _ = id
31 go' _ = id
src/Text/Pandoc/Citeproc/Locator.hs+3−18
@@ -20,7 +20,7 @@ parseLocator :: Locale -> [Inline] -> (Maybe (Text, Text), [Inline])
20parseLocator locale inp =
20parseLocator locale inp =
21 case parse (pLocatorWords (toLocatorMap locale)) "suffix" $ splitInp inp of
21 case parse (pLocatorWords (toLocatorMap locale)) "suffix" $ splitInp inp of
22 Right r -> r
22 Right r -> r
23− Left _ -> (Nothing, maybeAddComma inp)
23+ Left _ -> (Nothing, inp)
24
24
25splitInp :: [Inline] -> [Inline]
25splitInp :: [Inline] -> [Inline]
26splitInp = splitStrWhen (\c -> isSpace c || (isPunctuation c && c /= ':'))
26splitInp = splitStrWhen (\c -> isSpace c || (isPunctuation c && c /= ':'))
@@ -42,17 +42,9 @@ pLocatorWords locMap = do
42 -- i.e. the first one will be " 9"
42 -- i.e. the first one will be " 9"
43 return $
43 return $
44 if T.null la && T.null lo
44 if T.null la && T.null lo
45− then (Nothing, maybeAddComma s)
45+ then (Nothing, s)
46 else (Just (la, T.strip lo), s)
46 else (Just (la, T.strip lo), s)
47
47
48−maybeAddComma :: [Inline] -> [Inline]
49−maybeAddComma [] = []
50−maybeAddComma ils@(Space : _) = ils
51−maybeAddComma ils@(Str t : _)
52− | Just (c, _) <- T.uncons t
53− , isPunctuation c = ils
54−maybeAddComma ils = Str "," : Space : ils
55−
56pLocatorDelimited :: LocatorMap -> LocatorParser (Text, Text)
48pLocatorDelimited :: LocatorMap -> LocatorParser (Text, Text)
57pLocatorDelimited locMap = try $ do
49pLocatorDelimited locMap = try $ do
58 _ <- pMatchChar "{" (== '{')
50 _ <- pMatchChar "{" (== '{')
@@ -105,7 +97,7 @@ pLocatorLabel' locMap lim = go ""
105 t <- anyToken
97 t <- anyToken
106 ts <- manyTill anyToken (try $ lookAhead lim)
98 ts <- manyTill anyToken (try $ lookAhead lim)
107 let s = acc <> stringify (t:ts)
99 let s = acc <> stringify (t:ts)
108− case M.lookup (T.toCaseFold $ T.strip s) locMap of
100+ case M.lookup (T.strip s) locMap of
109 -- try to find a longer one, or return this one
101 -- try to find a longer one, or return this one
110 Just l -> go s <|> return (l, False)
102 Just l -> go s <|> return (l, False)
111 Nothing -> go s
103 Nothing -> go s
@@ -189,7 +181,6 @@ pPageUnit = roman <|> plainUnit
189 plainUnit = do
181 plainUnit = do
190 ts <- many1 (notFollowedBy pSpace >>
182 ts <- many1 (notFollowedBy pSpace >>
191 notFollowedBy pLocatorPunct >>
183 notFollowedBy pLocatorPunct >>
192− notFollowedBy pMath >>
193 anyToken)
184 anyToken)
194 let s = stringify ts
185 let s = stringify ts
195 -- otherwise look for actual digits or -s
186 -- otherwise look for actual digits or -s
@@ -220,12 +211,6 @@ pMatchChar msg f = satisfyTok f' <?> msg
220pSpace :: LocatorParser Inline
211pSpace :: LocatorParser Inline
221pSpace = satisfyTok (\t -> isSpacey t || t == Str "\160") <?> "space"
212pSpace = satisfyTok (\t -> isSpacey t || t == Str "\160") <?> "space"
222
213
223−pMath :: LocatorParser Inline
224−pMath = satisfyTok isMath
225− where
226− isMath (Math{}) = True
227− isMath _ = False
228−
229satisfyTok :: (Inline -> Bool) -> LocatorParser Inline
214satisfyTok :: (Inline -> Bool) -> LocatorParser Inline
230satisfyTok f = tokenPrim show (\sp _ _ -> sp) (\tok -> if f tok
215satisfyTok f = tokenPrim show (\sp _ _ -> sp) (\tok -> if f tok
231 then Just tok
216 then Just tok
src/Text/Pandoc/Class/CommonState.hs+1−1
@@ -19,7 +19,7 @@ where
19
19
20import Data.Default (Default (def))
20import Data.Default (Default (def))
21import Data.Text (Text)
21import Data.Text (Text)
22−import Text.Collate.Lang (Lang)
22+import Text.Pandoc.BCP47 (Lang)
23import Text.Pandoc.MediaBag (MediaBag)
23import Text.Pandoc.MediaBag (MediaBag)
24import Text.Pandoc.Logging (LogMessage, Verbosity (WARNING))
24import Text.Pandoc.Logging (LogMessage, Verbosity (WARNING))
25import Text.Pandoc.Translations (Translations)
25import Text.Pandoc.Translations (Translations)
src/Text/Pandoc/Class/IO.hs+22−21
@@ -62,7 +62,7 @@ import Text.Pandoc.Definition (Pandoc, Inline (Image))
62import Text.Pandoc.Error (PandocError (..))
62import Text.Pandoc.Error (PandocError (..))
63import Text.Pandoc.Logging (LogMessage (..), messageVerbosity, showLogMessage)
63import Text.Pandoc.Logging (LogMessage (..), messageVerbosity, showLogMessage)
64import Text.Pandoc.MIME (MimeType)
64import Text.Pandoc.MIME (MimeType)
65−import Text.Pandoc.MediaBag (MediaBag, MediaItem(..), lookupMedia, mediaItems)
65+import Text.Pandoc.MediaBag (MediaBag, lookupMedia, mediaDirectory)
66import Text.Pandoc.Walk (walk)
66import Text.Pandoc.Walk (walk)
67import qualified Control.Exception as E
67import qualified Control.Exception as E
68import qualified Data.ByteString as B
68import qualified Data.ByteString as B
@@ -200,32 +200,33 @@ alertIndent (l:ls) = do
200extractMedia :: (PandocMonad m, MonadIO m) => FilePath -> Pandoc -> m Pandoc
200extractMedia :: (PandocMonad m, MonadIO m) => FilePath -> Pandoc -> m Pandoc
201extractMedia dir d = do
201extractMedia dir d = do
202 media <- getMediaBag
202 media <- getMediaBag
203− let items = mediaItems media
203+ case [fp | (fp, _, _) <- mediaDirectory media] of
204− if null items
205− then return d
204+ [] -> return d
206− else do
205+ fps -> do
207− mapM_ (writeMedia dir) items
206+ mapM_ (writeMedia dir media) fps
208− return $ walk (adjustImagePath dir media) d
207+ return $ walk (adjustImagePath dir fps) d
209
208
210-- | Write the contents of a media bag to a path.
209-- | Write the contents of a media bag to a path.
211writeMedia :: (PandocMonad m, MonadIO m)
210writeMedia :: (PandocMonad m, MonadIO m)
212− => FilePath
211+ => FilePath -> MediaBag -> FilePath
213− -> (FilePath, MimeType, BL.ByteString)
214 -> m ()
212 -> m ()
215−writeMedia dir (fp, _mt, bs) = do
213+writeMedia dir mediabag subpath = do
216− -- we normalize to get proper path separators for the platform
214+ -- we join and split to convert a/b/c to a\b\c on Windows;
215+ -- in zip containers all paths use /
217− let fullpath = normalise $ dir </> fp
216+ let fullpath = dir </> unEscapeString (normalise subpath)
217+ let mbcontents = lookupMedia subpath mediabag
218+ case mbcontents of
219+ Nothing -> throwError $ PandocResourceNotFound $ pack subpath
220+ Just (_, bs) -> do
221+ report $ Extracting $ pack fullpath
218− liftIOError (createDirectoryIfMissing True) (takeDirectory fullpath)
222+ liftIOError (createDirectoryIfMissing True) (takeDirectory fullpath)
219− logIOError $ BL.writeFile fullpath bs
223+ logIOError $ BL.writeFile fullpath bs
220
224
221-- | If the given Inline element is an image with a @src@ path equal to
225-- | If the given Inline element is an image with a @src@ path equal to
222-- one in the list of @paths@, then prepends @dir@ to the image source;
226-- one in the list of @paths@, then prepends @dir@ to the image source;
223-- returns the element unchanged otherwise.
227-- returns the element unchanged otherwise.
224−adjustImagePath :: FilePath -> MediaBag -> Inline -> Inline
228+adjustImagePath :: FilePath -> [FilePath] -> Inline -> Inline
225−adjustImagePath dir mediabag (Image attr lab (src, tit)) =
229+adjustImagePath dir paths (Image attr lab (src, tit))
226− case lookupMedia (T.unpack src) mediabag of
230+ | unpack src `elem` paths
227− Nothing -> Image attr lab (src, tit)
231+ = Image attr lab (pack (normalise $ dir </> unpack src), tit)
228− Just item ->
229− let fullpath = dir </> mediaPath item
230− in Image attr lab (T.pack fullpath, tit)
231adjustImagePath _ _ x = x
232adjustImagePath _ _ x = x
src/Text/Pandoc/Class/PandocMonad.hs+33−22
@@ -1,5 +1,4 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2−{-# LANGUAGE TupleSections #-}
3{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
@@ -38,6 +37,7 @@ module Text.Pandoc.Class.PandocMonad
38 , setUserDataDir
37 , setUserDataDir
39 , getUserDataDir
38 , getUserDataDir
40 , fetchItem
39 , fetchItem
40+ , fetchMediaResource
41 , getInputFiles
41 , getInputFiles
42 , setInputFiles
42 , setInputFiles
43 , getOutputFile
43 , getOutputFile
@@ -57,6 +57,8 @@ module Text.Pandoc.Class.PandocMonad
57import Codec.Archive.Zip
57import Codec.Archive.Zip
58import Control.Monad.Except (MonadError (catchError, throwError),
58import Control.Monad.Except (MonadError (catchError, throwError),
59 MonadTrans, lift, when)
59 MonadTrans, lift, when)
60+import Data.Digest.Pure.SHA (sha1, showDigest)
61+import Data.Maybe (fromMaybe)
60import Data.List (foldl')
62import Data.List (foldl')
61import Data.Time (UTCTime)
63import Data.Time (UTCTime)
62import Data.Time.Clock.POSIX (POSIXTime, utcTimeToPOSIXSeconds,
64import Data.Time.Clock.POSIX (POSIXTime, utcTimeToPOSIXSeconds,
@@ -65,16 +67,16 @@ import Data.Time.LocalTime (TimeZone, ZonedTime, utcToZonedTime)
65import Network.URI ( escapeURIString, nonStrictRelativeTo,
67import Network.URI ( escapeURIString, nonStrictRelativeTo,
66 unEscapeString, parseURIReference, isAllowedInURI,
68 unEscapeString, parseURIReference, isAllowedInURI,
67 parseURI, URI(..) )
69 parseURI, URI(..) )
68−import System.FilePath ((</>), takeExtension, dropExtension,
70+import System.FilePath ((</>), (<.>), takeExtension, dropExtension,
69− isRelative, splitDirectories, makeRelative)
71+ isRelative, splitDirectories)
70import System.Random (StdGen)
72import System.Random (StdGen)
71−import Text.Collate.Lang (Lang(..), parseLang, renderLang)
73+import Text.Pandoc.BCP47 (Lang(..), parseBCP47, renderLang)
72import Text.Pandoc.Class.CommonState (CommonState (..))
74import Text.Pandoc.Class.CommonState (CommonState (..))
73import Text.Pandoc.Definition
75import Text.Pandoc.Definition
74import Text.Pandoc.Error
76import Text.Pandoc.Error
75import Text.Pandoc.Logging
77import Text.Pandoc.Logging
76−import Text.Pandoc.MIME (MimeType, getMimeType)
78+import Text.Pandoc.MIME (MimeType, getMimeType, extensionFromMimeType)
77−import Text.Pandoc.MediaBag (MediaBag, lookupMedia, MediaItem(..))
79+import Text.Pandoc.MediaBag (MediaBag, lookupMedia)
78import Text.Pandoc.Shared (uriPathToPath, safeRead)
80import Text.Pandoc.Shared (uriPathToPath, safeRead)
79import Text.Pandoc.Translations (Term(..), Translations, lookupTerm,
81import Text.Pandoc.Translations (Term(..), Translations, lookupTerm,
80 readTranslations)
82 readTranslations)
@@ -283,7 +285,7 @@ readFileFromDirs (d:ds) f = catchError
283toLang :: PandocMonad m => Maybe T.Text -> m (Maybe Lang)
285toLang :: PandocMonad m => Maybe T.Text -> m (Maybe Lang)
284toLang Nothing = return Nothing
286toLang Nothing = return Nothing
285toLang (Just s) =
287toLang (Just s) =
286− case parseLang s of
288+ case parseBCP47 s of
287 Left _ -> do
289 Left _ -> do
288 report $ InvalidLang s
290 report $ InvalidLang s
289 return Nothing
291 return Nothing
@@ -374,8 +376,7 @@ fetchItem :: PandocMonad m
374fetchItem s = do
376fetchItem s = do
375 mediabag <- getMediaBag
377 mediabag <- getMediaBag
376 case lookupMedia (T.unpack s) mediabag of
378 case lookupMedia (T.unpack s) mediabag of
377− Just item -> return (BL.toStrict (mediaContents item),
379+ Just (mime, bs) -> return (BL.toStrict bs, Just mime)
378− Just (mediaMimeType item))
379 Nothing -> downloadOrRead s
380 Nothing -> downloadOrRead s
380
381
381-- | Returns the content and, if available, the MIME type of a resource.
382-- | Returns the content and, if available, the MIME type of a resource.
@@ -410,10 +411,9 @@ downloadOrRead s = do
410 _ -> readLocalFile fp -- get from local file system
411 _ -> readLocalFile fp -- get from local file system
411 where readLocalFile f = do
412 where readLocalFile f = do
412 resourcePath <- getResourcePath
413 resourcePath <- getResourcePath
413− (fp', cont) <- if isRelative f
414+ cont <- if isRelative f
414− then withPaths resourcePath readFileStrict f
415+ then withPaths resourcePath readFileStrict f
415− else (f,) <$> readFileStrict f
416+ else readFileStrict f
416− report $ LoadedResource f (makeRelative "." fp')
417 return (cont, mime)
417 return (cont, mime)
418 httpcolon = URI{ uriScheme = "http:",
418 httpcolon = URI{ uriScheme = "http:",
419 uriAuthority = Nothing,
419 uriAuthority = Nothing,
@@ -623,13 +623,25 @@ makeCanonical = Posix.joinPath . transformPathParts . splitDirectories
623-- that filepath. Returns the result of the first successful execution
623-- that filepath. Returns the result of the first successful execution
624-- of the action, or throws a @PandocResourceNotFound@ exception if the
624-- of the action, or throws a @PandocResourceNotFound@ exception if the
625-- action errors for all filepaths.
625-- action errors for all filepaths.
626−withPaths :: PandocMonad m
627− => [FilePath] -> (FilePath -> m a) -> FilePath -> m (FilePath, a)
626+withPaths :: PandocMonad m => [FilePath] -> (FilePath -> m a) -> FilePath -> m a
628withPaths [] _ fp = throwError $ PandocResourceNotFound $ T.pack fp
627withPaths [] _ fp = throwError $ PandocResourceNotFound $ T.pack fp
629withPaths (p:ps) action fp =
628withPaths (p:ps) action fp =
630− catchError ((p </> fp,) <$> action (p </> fp))
629+ catchError (action (p </> fp))
631 (\_ -> withPaths ps action fp)
630 (\_ -> withPaths ps action fp)
632
631
632+-- | Fetch local or remote resource (like an image) and provide data suitable
633+-- for adding it to the MediaBag.
634+fetchMediaResource :: PandocMonad m
635+ => T.Text -> m (FilePath, Maybe MimeType, BL.ByteString)
636+fetchMediaResource src = do
637+ (bs, mt) <- downloadOrRead src
638+ let ext = fromMaybe (T.pack $ takeExtension $ T.unpack src)
639+ (mt >>= extensionFromMimeType)
640+ let bs' = BL.fromChunks [bs]
641+ let basename = showDigest $ sha1 bs'
642+ let fname = basename <.> T.unpack ext
643+ return (fname, mt, bs')
644+
633-- | Traverse tree, filling media bag for any images that
645-- | Traverse tree, filling media bag for any images that
634-- aren't already in the media bag.
646-- aren't already in the media bag.
635fillMediaBag :: PandocMonad m => Pandoc -> m Pandoc
647fillMediaBag :: PandocMonad m => Pandoc -> m Pandoc
@@ -637,13 +649,12 @@ fillMediaBag d = walkM handleImage d
637 where handleImage :: PandocMonad m => Inline -> m Inline
649 where handleImage :: PandocMonad m => Inline -> m Inline
638 handleImage (Image attr lab (src, tit)) = catchError
650 handleImage (Image attr lab (src, tit)) = catchError
639 (do mediabag <- getMediaBag
651 (do mediabag <- getMediaBag
640− let fp = T.unpack src
652+ case lookupMedia (T.unpack src) mediabag of
641− case lookupMedia fp mediabag of
642− Just _ -> return ()
653+ Just (_, _) -> return $ Image attr lab (src, tit)
643 Nothing -> do
654 Nothing -> do
644− (bs, mt) <- fetchItem src
655+ (fname, mt, bs) <- fetchMediaResource src
645− insertMedia fp mt (BL.fromStrict bs)
656+ insertMedia fname mt bs
646− return $ Image attr lab (src, tit))
657+ return $ Image attr lab (T.pack fname, tit))
647 (\e ->
658 (\e ->
648 case e of
659 case e of
649 PandocResourceNotFound _ -> do
660 PandocResourceNotFound _ -> do
src/Text/Pandoc/Error.hs+16−23
@@ -23,27 +23,26 @@ import Control.Exception (Exception, displayException)
23import Data.Typeable (Typeable)
23import Data.Typeable (Typeable)
24import Data.Word (Word8)
24import Data.Word (Word8)
25import Data.Text (Text)
25import Data.Text (Text)
26−import Data.List (sortOn)
27import qualified Data.Text as T
26import qualified Data.Text as T
28−import Data.Ord (Down(..))
29import GHC.Generics (Generic)
27import GHC.Generics (Generic)
30import Network.HTTP.Client (HttpException)
28import Network.HTTP.Client (HttpException)
31import System.Exit (ExitCode (..), exitWith)
29import System.Exit (ExitCode (..), exitWith)
32import System.IO (stderr)
30import System.IO (stderr)
33import qualified Text.Pandoc.UTF8 as UTF8
31import qualified Text.Pandoc.UTF8 as UTF8
34−import Text.Pandoc.Sources (Sources(..))
35import Text.Printf (printf)
32import Text.Printf (printf)
36import Text.Parsec.Error
33import Text.Parsec.Error
37import Text.Parsec.Pos hiding (Line)
34import Text.Parsec.Pos hiding (Line)
38import Text.Pandoc.Shared (tshow)
35import Text.Pandoc.Shared (tshow)
39import Citeproc (CiteprocError, prettyCiteprocError)
36import Citeproc (CiteprocError, prettyCiteprocError)
40
37
38+type Input = Text
39+
41data PandocError = PandocIOError Text IOError
40data PandocError = PandocIOError Text IOError
42 | PandocHttpError Text HttpException
41 | PandocHttpError Text HttpException
43 | PandocShouldNeverHappenError Text
42 | PandocShouldNeverHappenError Text
44 | PandocSomeError Text
43 | PandocSomeError Text
45 | PandocParseError Text
44 | PandocParseError Text
46− | PandocParsecError Sources ParseError
45+ | PandocParsecError Input ParseError
47 | PandocMakePDFError Text
46 | PandocMakePDFError Text
48 | PandocOptionError Text
47 | PandocOptionError Text
49 | PandocSyntaxMapError Text
48 | PandocSyntaxMapError Text
@@ -82,28 +81,22 @@ renderError e =
82 "Please report this to pandoc's developers: " <> s
81 "Please report this to pandoc's developers: " <> s
83 PandocSomeError s -> s
82 PandocSomeError s -> s
84 PandocParseError s -> s
83 PandocParseError s -> s
85− PandocParsecError (Sources inputs) err' ->
84+ PandocParsecError input err' ->
86 let errPos = errorPos err'
85 let errPos = errorPos err'
87 errLine = sourceLine errPos
86 errLine = sourceLine errPos
88 errColumn = sourceColumn errPos
87 errColumn = sourceColumn errPos
89− errFile = sourceName errPos
90− errorInFile =
91− case sortOn (Down . sourceLine . fst)
92− [ (pos,t)
93− | (pos,t) <- inputs
94− , sourceName pos == errFile
95− , sourceLine pos <= errLine
96− ] of
97− [] -> ""
98− ((pos,txt):_) ->
99− let ls = T.lines txt <> [""]
88+ ls = T.lines input <> [""]
100− ln = (errLine - sourceLine pos) + 1
101− in if length ls > ln && ln >= 1
89+ errorInFile = if length ls > errLine - 1
102− then T.concat ["\n", ls !! (ln - 1)
90+ then T.concat ["\n", ls !! (errLine - 1)
103− ,"\n", T.replicate (errColumn - 1) " "
91+ ,"\n", T.replicate (errColumn - 1) " "
104− ,"^"]
92+ ,"^"]
105− else ""
93+ else ""
106− in "Error at " <> tshow err' <> errorInFile
94+ in "\nError at " <> tshow err' <>
95+ -- if error comes from a chunk or included file,
96+ -- then we won't get the right text this way:
97+ if sourceName errPos == "source"
98+ then errorInFile
99+ else ""
107 PandocMakePDFError s -> s
100 PandocMakePDFError s -> s
108 PandocOptionError s -> s
101 PandocOptionError s -> s
109 PandocSyntaxMapError s -> s
102 PandocSyntaxMapError s -> s
src/Text/Pandoc/Extensions.hs−4
@@ -136,8 +136,6 @@ data Extension =
136 | Ext_raw_html -- ^ Allow raw HTML
136 | Ext_raw_html -- ^ Allow raw HTML
137 | Ext_raw_tex -- ^ Allow raw TeX (other than math)
137 | Ext_raw_tex -- ^ Allow raw TeX (other than math)
138 | Ext_raw_markdown -- ^ Parse markdown in ipynb as raw markdown
138 | Ext_raw_markdown -- ^ Parse markdown in ipynb as raw markdown
139− | Ext_rebase_relative_paths -- ^ Rebase relative image and link paths,
140− -- relative to directory of containing file
141 | Ext_shortcut_reference_links -- ^ Shortcut reference links
139 | Ext_shortcut_reference_links -- ^ Shortcut reference links
142 | Ext_simple_tables -- ^ Pandoc-style simple tables
140 | Ext_simple_tables -- ^ Pandoc-style simple tables
143 | Ext_smart -- ^ "Smart" quotes, apostrophes, ellipses, dashes
141 | Ext_smart -- ^ "Smart" quotes, apostrophes, ellipses, dashes
@@ -464,7 +462,6 @@ getAllExtensions f = universalExtensions <> getAll f
464 , Ext_gutenberg
462 , Ext_gutenberg
465 , Ext_smart
463 , Ext_smart
466 , Ext_literate_haskell
464 , Ext_literate_haskell
467− , Ext_rebase_relative_paths
468 ]
465 ]
469 getAll "markdown_strict" = allMarkdownExtensions
466 getAll "markdown_strict" = allMarkdownExtensions
470 getAll "markdown_phpextra" = allMarkdownExtensions
467 getAll "markdown_phpextra" = allMarkdownExtensions
@@ -517,7 +514,6 @@ getAllExtensions f = universalExtensions <> getAll f
517 , Ext_attributes
514 , Ext_attributes
518 , Ext_sourcepos
515 , Ext_sourcepos
519 , Ext_yaml_metadata_block
516 , Ext_yaml_metadata_block
520− , Ext_rebase_relative_paths
521 ]
517 ]
522 getAll "commonmark_x" = getAll "commonmark"
518 getAll "commonmark_x" = getAll "commonmark"
523 getAll "org" = autoIdExtensions <>
519 getAll "org" = autoIdExtensions <>
src/Text/Pandoc/Highlighting.hs+5−5
@@ -52,12 +52,12 @@ highlightingStyles =
52 ("breezedark", breezeDark),
52 ("breezedark", breezeDark),
53 ("haddock", haddock)]
53 ("haddock", haddock)]
54
54
55−languages :: SyntaxMap -> [T.Text]
55+languages :: [T.Text]
56−languages syntaxmap = [T.toLower (sName s) | s <- M.elems syntaxmap]
56+languages = [T.toLower (sName s) | s <- M.elems defaultSyntaxMap]
57
57
58−languagesByExtension :: SyntaxMap -> T.Text -> [T.Text]
58+languagesByExtension :: T.Text -> [T.Text]
59−languagesByExtension syntaxmap ext =
59+languagesByExtension ext =
60− [T.toLower (sName s) | s <- syntaxesByExtension syntaxmap (T.unpack ext)]
60+ [T.toLower (sName s) | s <- syntaxesByExtension defaultSyntaxMap (T.unpack ext)]
61
61
62highlight :: SyntaxMap
62highlight :: SyntaxMap
63 -> (FormatOptions -> [SourceLine] -> a) -- ^ Formatter
63 -> (FormatOptions -> [SourceLine] -> a) -- ^ Formatter
src/Text/Pandoc/ImageSize.hs+1−5
@@ -57,8 +57,7 @@ import Codec.Picture (decodeImageWithMetadata)
57-- quick and dirty functions to get image sizes
57-- quick and dirty functions to get image sizes
58-- algorithms borrowed from wwwis.pl
58-- algorithms borrowed from wwwis.pl
59
59
60−data ImageType = Png | Gif | Jpeg | Svg | Pdf | Eps | Emf | Tiff
60+data ImageType = Png | Gif | Jpeg | Svg | Pdf | Eps | Emf deriving Show
61− deriving Show
62data Direction = Width | Height
61data Direction = Width | Height
63instance Show Direction where
62instance Show Direction where
64 show Width = "width"
63 show Width = "width"
@@ -101,8 +100,6 @@ imageType :: ByteString -> Maybe ImageType
101imageType img = case B.take 4 img of
100imageType img = case B.take 4 img of
102 "\x89\x50\x4e\x47" -> return Png
101 "\x89\x50\x4e\x47" -> return Png
103 "\x47\x49\x46\x38" -> return Gif
102 "\x47\x49\x46\x38" -> return Gif
104− "\x49\x49\x2a\x00" -> return Tiff
105− "\x4D\x4D\x00\x2a" -> return Tiff
106 "\xff\xd8\xff\xe0" -> return Jpeg -- JFIF
103 "\xff\xd8\xff\xe0" -> return Jpeg -- JFIF
107 "\xff\xd8\xff\xe1" -> return Jpeg -- Exif
104 "\xff\xd8\xff\xe1" -> return Jpeg -- Exif
108 "%PDF" -> return Pdf
105 "%PDF" -> return Pdf
@@ -127,7 +124,6 @@ imageSize opts img = checkDpi <$>
127 Just Png -> getSize img
124 Just Png -> getSize img
128 Just Gif -> getSize img
125 Just Gif -> getSize img
129 Just Jpeg -> getSize img
126 Just Jpeg -> getSize img
130− Just Tiff -> getSize img
131 Just Svg -> mbToEither "could not determine SVG size" $ svgSize opts img
127 Just Svg -> mbToEither "could not determine SVG size" $ svgSize opts img
132 Just Eps -> mbToEither "could not determine EPS size" $ epsSize img
128 Just Eps -> mbToEither "could not determine EPS size" $ epsSize img
133 Just Pdf -> mbToEither "could not determine PDF size" $ pdfSize img
129 Just Pdf -> mbToEither "could not determine PDF size" $ pdfSize img
src/Text/Pandoc/Logging.hs+9−18
@@ -85,7 +85,6 @@ data LogMessage =
85 | CouldNotParseCSS Text
85 | CouldNotParseCSS Text
86 | Fetching Text
86 | Fetching Text
87 | Extracting Text
87 | Extracting Text
88− | LoadedResource FilePath FilePath
89 | NoTitleElement Text
88 | NoTitleElement Text
90 | NoLangSpecified
89 | NoLangSpecified
91 | InvalidLang Text
90 | InvalidLang Text
@@ -196,9 +195,6 @@ instance ToJSON LogMessage where
196 ["path" .= fp]
195 ["path" .= fp]
197 Extracting fp ->
196 Extracting fp ->
198 ["path" .= fp]
197 ["path" .= fp]
199− LoadedResource orig found ->
200− ["for" .= orig
201− ,"from" .= found]
202 NoTitleElement fallback ->
198 NoTitleElement fallback ->
203 ["fallback" .= fallback]
199 ["fallback" .= fallback]
204 NoLangSpecified -> []
200 NoLangSpecified -> []
@@ -245,11 +241,9 @@ instance ToJSON LogMessage where
245showPos :: SourcePos -> Text
241showPos :: SourcePos -> Text
246showPos pos = Text.pack $ sn ++ "line " ++
242showPos pos = Text.pack $ sn ++ "line " ++
247 show (sourceLine pos) ++ " column " ++ show (sourceColumn pos)
243 show (sourceLine pos) ++ " column " ++ show (sourceColumn pos)
248− where
244+ where sn = if sourceName pos == "source" || sourceName pos == ""
249− sn' = sourceName pos
250− sn = if sn' == "source" || sn' == "" || sn' == "-"
251− then ""
245+ then ""
252− else sn' ++ " "
246+ else sourceName pos ++ " "
253
247
254encodeLogMessages :: [LogMessage] -> BL.ByteString
248encodeLogMessages :: [LogMessage] -> BL.ByteString
255encodeLogMessages ms =
249encodeLogMessages ms =
@@ -282,7 +276,7 @@ showLogMessage msg =
282 ParsingUnescaped s pos ->
276 ParsingUnescaped s pos ->
283 "Parsing unescaped '" <> s <> "' at " <> showPos pos
277 "Parsing unescaped '" <> s <> "' at " <> showPos pos
284 CouldNotLoadIncludeFile fp pos ->
278 CouldNotLoadIncludeFile fp pos ->
285− "Could not load include file " <> fp <> " at " <> showPos pos
279+ "Could not load include file '" <> fp <> "' at " <> showPos pos
286 MacroAlreadyDefined name pos ->
280 MacroAlreadyDefined name pos ->
287 "Macro '" <> name <> "' already defined, ignoring at " <> showPos pos
281 "Macro '" <> name <> "' already defined, ignoring at " <> showPos pos
288 InlineNotRendered il ->
282 InlineNotRendered il ->
@@ -294,18 +288,18 @@ showLogMessage msg =
294 IgnoredIOError s ->
288 IgnoredIOError s ->
295 "IO Error (ignored): " <> s
289 "IO Error (ignored): " <> s
296 CouldNotFetchResource fp s ->
290 CouldNotFetchResource fp s ->
297− "Could not fetch resource " <> fp <>
291+ "Could not fetch resource '" <> fp <> "'" <>
298 if Text.null s then "" else ": " <> s
292 if Text.null s then "" else ": " <> s
299 CouldNotDetermineImageSize fp s ->
293 CouldNotDetermineImageSize fp s ->
300− "Could not determine image size for " <> fp <>
294+ "Could not determine image size for '" <> fp <> "'" <>
301 if Text.null s then "" else ": " <> s
295 if Text.null s then "" else ": " <> s
302 CouldNotConvertImage fp s ->
296 CouldNotConvertImage fp s ->
303− "Could not convert image " <> fp <>
297+ "Could not convert image '" <> fp <> "'" <>
304 if Text.null s then "" else ": " <> s
298 if Text.null s then "" else ": " <> s
305 CouldNotDetermineMimeType fp ->
299 CouldNotDetermineMimeType fp ->
306− "Could not determine mime type for " <> fp
300+ "Could not determine mime type for '" <> fp <> "'"
307 CouldNotConvertTeXMath s m ->
301 CouldNotConvertTeXMath s m ->
308− "Could not convert TeX math " <> s <> ", rendering as TeX" <>
302+ "Could not convert TeX math '" <> s <> "', rendering as TeX" <>
309 if Text.null m then "" else ":\n" <> m
303 if Text.null m then "" else ":\n" <> m
310 CouldNotParseCSS m ->
304 CouldNotParseCSS m ->
311 "Could not parse CSS" <> if Text.null m then "" else ":\n" <> m
305 "Could not parse CSS" <> if Text.null m then "" else ":\n" <> m
@@ -313,8 +307,6 @@ showLogMessage msg =
313 "Fetching " <> fp <> "..."
307 "Fetching " <> fp <> "..."
314 Extracting fp ->
308 Extracting fp ->
315 "Extracting " <> fp <> "..."
309 "Extracting " <> fp <> "..."
316− LoadedResource orig found ->
317− "Loaded " <> Text.pack orig <> " from " <> Text.pack found
318 NoTitleElement fallback ->
310 NoTitleElement fallback ->
319 "This document format requires a nonempty <title> element.\n" <>
311 "This document format requires a nonempty <title> element.\n" <>
320 "Defaulting to '" <> fallback <> "' as the title.\n" <>
312 "Defaulting to '" <> fallback <> "' as the title.\n" <>
@@ -395,7 +387,6 @@ messageVerbosity msg =
395 CouldNotParseCSS{} -> WARNING
387 CouldNotParseCSS{} -> WARNING
396 Fetching{} -> INFO
388 Fetching{} -> INFO
397 Extracting{} -> INFO
389 Extracting{} -> INFO
398− LoadedResource{} -> INFO
399 NoTitleElement{} -> WARNING
390 NoTitleElement{} -> WARNING
400 NoLangSpecified -> INFO
391 NoLangSpecified -> INFO
401 InvalidLang{} -> WARNING
392 InvalidLang{} -> WARNING
src/Text/Pandoc/Lua/Module/MediaBag.hs+3−3
@@ -73,9 +73,9 @@ lookup fp = do
73 res <- MB.lookupMedia fp <$> getMediaBag
73 res <- MB.lookupMedia fp <$> getMediaBag
74 liftPandocLua $ case res of
74 liftPandocLua $ case res of
75 Nothing -> 1 <$ Lua.pushnil
75 Nothing -> 1 <$ Lua.pushnil
76− Just item -> do
76+ Just (mimeType, contents) -> do
77− Lua.push $ MB.mediaMimeType item
77+ Lua.push mimeType
78− Lua.push $ MB.mediaContents item
78+ Lua.push contents
79 return 2
79 return 2
80
80
81list :: PandocLua NumResults
81list :: PandocLua NumResults
src/Text/Pandoc/Lua/Module/Utils.hs+1−1
@@ -146,7 +146,7 @@ from_simple_table (SimpleTable capt aligns widths head' body) = do
146 nullAttr
146 nullAttr
147 (Caption Nothing [Plain capt])
147 (Caption Nothing [Plain capt])
148 (zipWith (\a w -> (a, toColWidth w)) aligns widths)
148 (zipWith (\a w -> (a, toColWidth w)) aligns widths)
149− (TableHead nullAttr [blockListToRow head' | not (null head') ])
149+ (TableHead nullAttr [blockListToRow head'])
150 [TableBody nullAttr 0 [] $ map blockListToRow body]
150 [TableBody nullAttr 0 [] $ map blockListToRow body]
151 (TableFoot nullAttr [])
151 (TableFoot nullAttr [])
152 return (NumResults 1)
152 return (NumResults 1)
src/Text/Pandoc/MIME.hs−10
@@ -43,16 +43,6 @@ getMimeTypeDef :: FilePath -> MimeType
43getMimeTypeDef = fromMaybe "application/octet-stream" . getMimeType
43getMimeTypeDef = fromMaybe "application/octet-stream" . getMimeType
44
44
45extensionFromMimeType :: MimeType -> Maybe T.Text
45extensionFromMimeType :: MimeType -> Maybe T.Text
46−-- few special cases, where there are multiple options:
47−extensionFromMimeType "text/plain" = Just "txt"
48−extensionFromMimeType "video/quicktime" = Just "mov"
49−extensionFromMimeType "video/mpeg" = Just "mpeg"
50−extensionFromMimeType "video/dv" = Just "dv"
51−extensionFromMimeType "image/vnd.djvu" = Just "djvu"
52−extensionFromMimeType "image/tiff" = Just "tiff"
53−extensionFromMimeType "image/jpeg" = Just "jpg"
54−extensionFromMimeType "application/xml" = Just "xml"
55−extensionFromMimeType "application/ogg" = Just "ogg"
56extensionFromMimeType mimetype =
46extensionFromMimeType mimetype =
57 M.lookup (T.takeWhile (/=';') mimetype) reverseMimeTypes
47 M.lookup (T.takeWhile (/=';') mimetype) reverseMimeTypes
58 -- note: we just look up the basic mime type, dropping the content-encoding etc.
48 -- note: we just look up the basic mime type, dropping the content-encoding etc.
src/Text/Pandoc/MediaBag.hs+14−45
@@ -1,5 +1,4 @@
1{-# LANGUAGE CPP #-}
1{-# LANGUAGE CPP #-}
2−{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{- |
4{- |
@@ -15,7 +14,6 @@ Definition of a MediaBag object to hold binary resources, and an
15interface for interacting with it.
14interface for interacting with it.
16-}
15-}
17module Text.Pandoc.MediaBag (
16module Text.Pandoc.MediaBag (
18− MediaItem(..),
19 MediaBag,
17 MediaBag,
20 deleteMedia,
18 deleteMedia,
21 lookupMedia,
19 lookupMedia,
@@ -26,43 +24,29 @@ module Text.Pandoc.MediaBag (
26import qualified Data.ByteString.Lazy as BL
24import qualified Data.ByteString.Lazy as BL
27import Data.Data (Data)
25import Data.Data (Data)
28import qualified Data.Map as M
26import qualified Data.Map as M
29−import Data.Maybe (fromMaybe, isNothing)
27+import Data.Maybe (fromMaybe)
30import Data.Typeable (Typeable)
28import Data.Typeable (Typeable)
31import System.FilePath
29import System.FilePath
30+import qualified System.FilePath.Posix as Posix
32−import Text.Pandoc.MIME (MimeType, getMimeTypeDef, extensionFromMimeType)
31+import Text.Pandoc.MIME (MimeType, getMimeTypeDef)
33−import Data.Text (Text)
34−import qualified Data.Text as T
35−import Data.Digest.Pure.SHA (sha1, showDigest)
36−import Network.URI (URI (..), parseURI)
37−
38−data MediaItem =
39− MediaItem
40− { mediaMimeType :: MimeType
41− , mediaPath :: FilePath
42− , mediaContents :: BL.ByteString
43− } deriving (Eq, Ord, Show, Data, Typeable)
44
32
45-- | A container for a collection of binary resources, with names and
33-- | A container for a collection of binary resources, with names and
46-- mime types. Note that a 'MediaBag' is a Monoid, so 'mempty'
34-- mime types. Note that a 'MediaBag' is a Monoid, so 'mempty'
47-- can be used for an empty 'MediaBag', and '<>' can be used to append
35-- can be used for an empty 'MediaBag', and '<>' can be used to append
48-- two 'MediaBag's.
36-- two 'MediaBag's.
49−newtype MediaBag = MediaBag (M.Map Text MediaItem)
37+newtype MediaBag = MediaBag (M.Map [FilePath] (MimeType, BL.ByteString))
50 deriving (Semigroup, Monoid, Data, Typeable)
38 deriving (Semigroup, Monoid, Data, Typeable)
51
39
52instance Show MediaBag where
40instance Show MediaBag where
53 show bag = "MediaBag " ++ show (mediaDirectory bag)
41 show bag = "MediaBag " ++ show (mediaDirectory bag)
54
42
55−-- | We represent paths with /, in normalized form.
56−canonicalize :: FilePath -> Text
57−canonicalize = T.replace "\\" "/" . T.pack . normalise
58−
59-- | Delete a media item from a 'MediaBag', or do nothing if no item corresponds
43-- | Delete a media item from a 'MediaBag', or do nothing if no item corresponds
60-- to the given path.
44-- to the given path.
61deleteMedia :: FilePath -- ^ relative path and canonical name of resource
45deleteMedia :: FilePath -- ^ relative path and canonical name of resource
62 -> MediaBag
46 -> MediaBag
63 -> MediaBag
47 -> MediaBag
64deleteMedia fp (MediaBag mediamap) =
48deleteMedia fp (MediaBag mediamap) =
65− MediaBag $ M.delete (canonicalize fp) mediamap
49+ MediaBag $ M.delete (splitDirectories fp) mediamap
66
50
67-- | Insert a media item into a 'MediaBag', replacing any existing
51-- | Insert a media item into a 'MediaBag', replacing any existing
68-- value with the same name.
52-- value with the same name.
@@ -72,41 +56,26 @@ insertMedia :: FilePath -- ^ relative path and canonical name of resource
72 -> MediaBag
56 -> MediaBag
73 -> MediaBag
57 -> MediaBag
74insertMedia fp mbMime contents (MediaBag mediamap) =
58insertMedia fp mbMime contents (MediaBag mediamap) =
75− MediaBag (M.insert fp' mediaItem mediamap)
59+ MediaBag (M.insert (splitDirectories fp) (mime, contents) mediamap)
76− where mediaItem = MediaItem{ mediaPath = newpath
60+ where mime = fromMaybe fallback mbMime
77− , mediaContents = contents
78− , mediaMimeType = mt }
79− fp' = canonicalize fp
80− uri = parseURI fp
81− newpath = if isRelative fp
82− && isNothing uri
83− && ".." `notElem` splitPath fp
84− then T.unpack fp'
85− else showDigest (sha1 contents) <> "." <> ext
86 fallback = case takeExtension fp of
61 fallback = case takeExtension fp of
87 ".gz" -> getMimeTypeDef $ dropExtension fp
62 ".gz" -> getMimeTypeDef $ dropExtension fp
88 _ -> getMimeTypeDef fp
63 _ -> getMimeTypeDef fp
89− mt = fromMaybe fallback mbMime
90− path = maybe fp uriPath uri
91− ext = case takeExtension path of
92− '.':e -> e
93− _ -> maybe "" T.unpack $ extensionFromMimeType mt
94−
95
64
96-- | Lookup a media item in a 'MediaBag', returning mime type and contents.
65-- | Lookup a media item in a 'MediaBag', returning mime type and contents.
97lookupMedia :: FilePath
66lookupMedia :: FilePath
98 -> MediaBag
67 -> MediaBag
99− -> Maybe MediaItem
68+ -> Maybe (MimeType, BL.ByteString)
100−lookupMedia fp (MediaBag mediamap) = M.lookup (canonicalize fp) mediamap
69+lookupMedia fp (MediaBag mediamap) = M.lookup (splitDirectories fp) mediamap
101
70
102-- | Get a list of the file paths stored in a 'MediaBag', with
71-- | Get a list of the file paths stored in a 'MediaBag', with
103-- their corresponding mime types and the lengths in bytes of the contents.
72-- their corresponding mime types and the lengths in bytes of the contents.
104mediaDirectory :: MediaBag -> [(FilePath, MimeType, Int)]
73mediaDirectory :: MediaBag -> [(FilePath, MimeType, Int)]
105−mediaDirectory mediabag =
74+mediaDirectory (MediaBag mediamap) =
75+ M.foldrWithKey (\fp (mime,contents) ->
106− map (\(fp, mt, bs) -> (fp, mt, fromIntegral (BL.length bs)))
76+ ((Posix.joinPath fp, mime, fromIntegral $ BL.length contents):)) [] mediamap
107− (mediaItems mediabag)
108
77
109mediaItems :: MediaBag -> [(FilePath, MimeType, BL.ByteString)]
78mediaItems :: MediaBag -> [(FilePath, MimeType, BL.ByteString)]
110mediaItems (MediaBag mediamap) =
79mediaItems (MediaBag mediamap) =
111− map (\item -> (mediaPath item, mediaMimeType item, mediaContents item))
80+ M.foldrWithKey (\fp (mime,contents) ->
112− (M.elems mediamap)
81+ ((Posix.joinPath fp, mime, contents):)) [] mediamap
src/Text/Pandoc/Options.hs+17−17
@@ -315,23 +315,6 @@ defaultMathJaxURL = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.j
315defaultKaTeXURL :: Text
315defaultKaTeXURL :: Text
316defaultKaTeXURL = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/"
316defaultKaTeXURL = "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/"
317
317
318−-- Update documentation in doc/filters.md if this is changed.
319−$(deriveJSON defaultOptions{ constructorTagModifier =
320− camelCaseStrToHyphenated
321− } ''TrackChanges)
322−
323−$(deriveJSON defaultOptions{ constructorTagModifier =
324− camelCaseStrToHyphenated
325− } ''WrapOption)
326−
327−$(deriveJSON defaultOptions{ constructorTagModifier =
328− camelCaseStrToHyphenated . drop 8
329− } ''TopLevelDivision)
330−
331−$(deriveJSON defaultOptions{ constructorTagModifier =
332− camelCaseStrToHyphenated
333− } ''ReferenceLocation)
334−
335-- Update documentation in doc/filters.md if this is changed.
318-- Update documentation in doc/filters.md if this is changed.
336$(deriveJSON defaultOptions ''ReaderOptions)
319$(deriveJSON defaultOptions ''ReaderOptions)
337
320
@@ -355,3 +338,20 @@ $(deriveJSON defaultOptions{ constructorTagModifier =
355 } ''ObfuscationMethod)
338 } ''ObfuscationMethod)
356
339
357$(deriveJSON defaultOptions ''HTMLSlideVariant)
340$(deriveJSON defaultOptions ''HTMLSlideVariant)
341+
342+-- Update documentation in doc/filters.md if this is changed.
343+$(deriveJSON defaultOptions{ constructorTagModifier =
344+ camelCaseStrToHyphenated
345+ } ''TrackChanges)
346+
347+$(deriveJSON defaultOptions{ constructorTagModifier =
348+ camelCaseStrToHyphenated
349+ } ''WrapOption)
350+
351+$(deriveJSON defaultOptions{ constructorTagModifier =
352+ camelCaseStrToHyphenated . drop 8
353+ } ''TopLevelDivision)
354+
355+$(deriveJSON defaultOptions{ constructorTagModifier =
356+ camelCaseStrToHyphenated
357+ } ''ReferenceLocation)
src/Text/Pandoc/PDF.hs+3−16
@@ -202,7 +202,7 @@ convertImage opts tmpdir fname = do
202 Just "image/svg+xml" -> E.catch (do
202 Just "image/svg+xml" -> E.catch (do
203 (exit, _) <- pipeProcess Nothing "rsvg-convert"
203 (exit, _) <- pipeProcess Nothing "rsvg-convert"
204 ["-f","pdf","-a","--dpi-x",dpi,"--dpi-y",dpi,
204 ["-f","pdf","-a","--dpi-x",dpi,"--dpi-y",dpi,
205− "-o",pdfOut,svgIn] BL.empty
205+ "-o",pdfOut,fname] BL.empty
206 if exit == ExitSuccess
206 if exit == ExitSuccess
207 then return $ Right pdfOut
207 then return $ Right pdfOut
208 else return $ Left "conversion from SVG failed")
208 else return $ Left "conversion from SVG failed")
@@ -217,7 +217,6 @@ convertImage opts tmpdir fname = do
217 where
217 where
218 pngOut = replaceDirectory (replaceExtension fname ".png") tmpdir
218 pngOut = replaceDirectory (replaceExtension fname ".png") tmpdir
219 pdfOut = replaceDirectory (replaceExtension fname ".pdf") tmpdir
219 pdfOut = replaceDirectory (replaceExtension fname ".pdf") tmpdir
220− svgIn = tmpdir </> fname
221 mime = getMimeType fname
220 mime = getMimeType fname
222 doNothing = return (Right fname)
221 doNothing = return (Right fname)
223
222
@@ -507,20 +506,8 @@ showVerboseInfo mbTmpDir program programArgs env source = do
507 UTF8.hPutStrLn stderr $
506 UTF8.hPutStrLn stderr $
508 T.pack program <> " " <> T.pack (unwords (map show programArgs))
507 T.pack program <> " " <> T.pack (unwords (map show programArgs))
509 UTF8.hPutStr stderr "\n"
508 UTF8.hPutStr stderr "\n"
510− UTF8.hPutStrLn stderr "[makePDF] Relevant environment variables:"
509+ UTF8.hPutStrLn stderr "[makePDF] Environment:"
511− -- we filter out irrelevant stuff to avoid leaking passwords and keys!
512− let isRelevant ("PATH",_) = True
513− isRelevant ("TMPDIR",_) = True
514− isRelevant ("PWD",_) = True
515− isRelevant ("LANG",_) = True
516− isRelevant ("HOME",_) = True
517− isRelevant ("LUA_PATH",_) = True
518− isRelevant ("LUA_CPATH",_) = True
519− isRelevant ("SHELL",_) = True
520− isRelevant ("TEXINPUTS",_) = True
521− isRelevant ("TEXMFOUTPUT",_) = True
522− isRelevant _ = False
523− mapM_ (UTF8.hPutStrLn stderr . tshow) (filter isRelevant env)
510+ mapM_ (UTF8.hPutStrLn stderr . tshow) env
524 UTF8.hPutStr stderr "\n"
511 UTF8.hPutStr stderr "\n"
525 UTF8.hPutStrLn stderr "[makePDF] Source:"
512 UTF8.hPutStrLn stderr "[makePDF] Source:"
526 UTF8.hPutStrLn stderr source
513 UTF8.hPutStrLn stderr source
src/Text/Pandoc/Parsing.hs+235−356
@@ -5,6 +5,7 @@
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE IncoherentInstances #-}
6{-# LANGUAGE IncoherentInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8+{-# LANGUAGE ViewPatterns #-}
8{-# LANGUAGE OverloadedStrings #-}
9{-# LANGUAGE OverloadedStrings #-}
9{- |
10{- |
10 Module : Text.Pandoc.Parsing
11 Module : Text.Pandoc.Parsing
@@ -18,7 +19,8 @@
18A utility library with parsers used in pandoc readers.
19A utility library with parsers used in pandoc readers.
19-}
20-}
20
21
21−module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
22+module Text.Pandoc.Parsing ( take1WhileP,
23+ takeP,
22 countChar,
24 countChar,
23 textStr,
25 textStr,
24 anyLine,
26 anyLine,
@@ -103,9 +105,8 @@ module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
103 singleQuoteEnd,
105 singleQuoteEnd,
104 doubleQuoteStart,
106 doubleQuoteStart,
105 doubleQuoteEnd,
107 doubleQuoteEnd,
106− apostrophe,
107− doubleCloseQuote,
108 ellipses,
108 ellipses,
109+ apostrophe,
109 dash,
110 dash,
110 nested,
111 nested,
111 citeKey,
112 citeKey,
@@ -121,6 +122,7 @@ module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
121 (<+?>),
122 (<+?>),
122 extractIdClass,
123 extractIdClass,
123 insertIncludedFile,
124 insertIncludedFile,
125+ insertIncludedFileF,
124 -- * Re-exports from Text.Parsec
126 -- * Re-exports from Text.Parsec
125 Stream,
127 Stream,
126 runParser,
128 runParser,
@@ -131,10 +133,22 @@ module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
131 getInput,
133 getInput,
132 setInput,
134 setInput,
133 unexpected,
135 unexpected,
136+ char,
137+ letter,
138+ digit,
139+ alphaNum,
134 skipMany,
140 skipMany,
135 skipMany1,
141 skipMany1,
142+ spaces,
143+ space,
144+ anyChar,
145+ satisfy,
146+ newline,
147+ string,
136 count,
148 count,
137 eof,
149 eof,
150+ noneOf,
151+ oneOf,
138 lookAhead,
152 lookAhead,
139 notFollowedBy,
153 notFollowedBy,
140 many,
154 many,
@@ -159,8 +173,6 @@ module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
159 SourcePos,
173 SourcePos,
160 getPosition,
174 getPosition,
161 setPosition,
175 setPosition,
162− sourceName,
163− setSourceName,
164 sourceColumn,
176 sourceColumn,
165 sourceLine,
177 sourceLine,
166 setSourceColumn,
178 setSourceColumn,
@@ -176,25 +188,16 @@ module Text.Pandoc.Parsing ( module Text.Pandoc.Sources,
176where
188where
177
189
178import Control.Monad.Identity
190import Control.Monad.Identity
179− ( guard,
180− join,
181− unless,
182− when,
183− void,
184− liftM2,
185− liftM,
186− Identity(..),
187− MonadPlus(mzero) )
188import Control.Monad.Reader
191import Control.Monad.Reader
189− ( asks, runReader, MonadReader(ask), Reader, ReaderT(ReaderT) )
190import Data.Char (chr, isAlphaNum, isAscii, isAsciiUpper, isAsciiLower,
192import Data.Char (chr, isAlphaNum, isAscii, isAsciiUpper, isAsciiLower,
191− isSpace, ord, toLower, toUpper)
193+ isPunctuation, isSpace, ord, toLower, toUpper)
192−import Data.Default ( Default(..) )
194+import Data.Default
193import Data.Functor (($>))
195import Data.Functor (($>))
194import Data.List (intercalate, transpose)
196import Data.List (intercalate, transpose)
195import qualified Data.Map as M
197import qualified Data.Map as M
196import Data.Maybe (fromMaybe)
198import Data.Maybe (fromMaybe)
197import qualified Data.Set as Set
199import qualified Data.Set as Set
200+import Data.String
198import Data.Text (Text)
201import Data.Text (Text)
199import qualified Data.Text as T
202import qualified Data.Text as T
200import Text.HTML.TagSoup.Entity (lookupEntity)
203import Text.HTML.TagSoup.Entity (lookupEntity)
@@ -203,108 +206,22 @@ import Text.Pandoc.Builder (Blocks, HasMeta (..), Inlines, trimInlines)
203import qualified Text.Pandoc.Builder as B
206import qualified Text.Pandoc.Builder as B
204import Text.Pandoc.Class.PandocMonad (PandocMonad, readFileFromDirs, report)
207import Text.Pandoc.Class.PandocMonad (PandocMonad, readFileFromDirs, report)
205import Text.Pandoc.Definition
208import Text.Pandoc.Definition
206− ( Target,
207− nullMeta,
208− nullAttr,
209− Meta,
210− ColWidth(ColWidthDefault, ColWidth),
211− TableFoot(TableFoot),
212− TableBody(TableBody),
213− Attr,
214− TableHead(TableHead),
215− Row(..),
216− Alignment(..),
217− Inline(Str),
218− ListNumberDelim(..),
219− ListAttributes,
220− ListNumberStyle(..) )
221import Text.Pandoc.Logging
209import Text.Pandoc.Logging
222− ( LogMessage(CouldNotLoadIncludeFile, DuplicateIdentifier) )
223import Text.Pandoc.Options
210import Text.Pandoc.Options
224− ( extensionEnabled,
225− Extension(Ext_old_dashes, Ext_tex_math_dollars,
226− Ext_tex_math_single_backslash, Ext_tex_math_double_backslash,
227− Ext_auto_identifiers, Ext_ascii_identifiers, Ext_smart),
228− ReaderOptions(readerTabStop, readerColumns, readerExtensions) )
229import Text.Pandoc.Readers.LaTeX.Types (Macro)
211import Text.Pandoc.Readers.LaTeX.Types (Macro)
230import Text.Pandoc.Shared
212import Text.Pandoc.Shared
231− ( uniqueIdent,
232− tshow,
233− mapLeft,
234− compactify,
235− trim,
236− trimr,
237− splitTextByIndices,
238− safeRead,
239− trimMath,
240− schemes,
241− escapeURI )
242−import Text.Pandoc.Sources
243import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
213import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
244import Text.Pandoc.XML (fromEntities)
214import Text.Pandoc.XML (fromEntities)
245−import Text.Parsec
215+import Text.Parsec hiding (token)
246− ( between,
247− setSourceName,
248− Parsec,
249− Column,
250− Line,
251− incSourceLine,
252− incSourceColumn,
253− setSourceLine,
254− setSourceColumn,
255− sourceLine,
256− sourceColumn,
257− sourceName,
258− setSourceName,
259− setPosition,
260− getPosition,
261− updateState,
262− setState,
263− getState,
264− optionMaybe,
265− optional,
266− option,
267− endBy1,
268− endBy,
269− sepEndBy1,
270− sepEndBy,
271− sepBy1,
272− sepBy,
273− try,
274− choice,
275− (<?>),
276− (<|>),
277− manyTill,
278− many1,
279− many,
280− notFollowedBy,
281− lookAhead,
282− eof,
283− count,
284− skipMany1,
285− skipMany,
286− unexpected,
287− setInput,
288− getInput,
289− anyToken,
290− tokenPrim,
291− parse,
292− runParserT,
293− runParser,
294− ParseError,
295− ParsecT,
296− SourcePos,
297− Stream(..) )
298−import Text.Parsec.Pos (initialPos, newPos)
216+import Text.Parsec.Pos (initialPos, newPos, updatePosString)
217+
299−import Control.Monad.Except ( MonadError(throwError) )
218+import Control.Monad.Except
300import Text.Pandoc.Error
219import Text.Pandoc.Error
301− ( PandocError(PandocParseError, PandocParsecError) )
302
220
303type Parser t s = Parsec t s
221type Parser t s = Parsec t s
304
222
305type ParserT = ParsecT
223type ParserT = ParsecT
306
224
307−
308-- | Reader monad wrapping the parser state. This is used to possibly delay
225-- | Reader monad wrapping the parser state. This is used to possibly delay
309-- evaluation until all relevant information has been parsed and made available
226-- evaluation until all relevant information has been parsed and made available
310-- in the parser state.
227-- in the parser state.
@@ -333,48 +250,70 @@ instance (Semigroup a, Monoid a) => Monoid (Future s a) where
333 mappend = (<>)
250 mappend = (<>)
334
251
335-- | Like @count@, but packs its result
252-- | Like @count@, but packs its result
336−countChar :: (Stream s m Char, UpdateSourcePos s Char, Monad m)
253+countChar :: (Stream s m Char, Monad m)
337 => Int
254 => Int
338 -> ParsecT s st m Char
255 -> ParsecT s st m Char
339 -> ParsecT s st m Text
256 -> ParsecT s st m Text
340countChar n = fmap T.pack . count n
257countChar n = fmap T.pack . count n
341
258
342-- | Like @string@, but uses @Text@.
259-- | Like @string@, but uses @Text@.
343−textStr :: (Stream s m Char, UpdateSourcePos s Char)
344− => Text -> ParsecT s u m Text
260+textStr :: Stream s m Char => Text -> ParsecT s u m Text
345textStr t = string (T.unpack t) $> t
261textStr t = string (T.unpack t) $> t
346
262
347−
263+-- | Parse characters while a predicate is true.
264+take1WhileP :: Monad m
265+ => (Char -> Bool)
266+ -> ParserT Text st m Text
267+take1WhileP f = do
268+ -- needed to persuade parsec that this won't match an empty string:
269+ c <- satisfy f
270+ inp <- getInput
271+ pos <- getPosition
272+ let (t, rest) = T.span f inp
273+ setInput rest
274+ setPosition $
275+ if f '\t' || f '\n'
276+ then updatePosString pos $ T.unpack t
277+ else incSourceColumn pos (T.length t)
278+ return $ T.singleton c <> t
279+
280+-- Parse n characters of input (or the rest of the input if
281+-- there aren't n characters).
282+takeP :: Monad m => Int -> ParserT Text st m Text
283+takeP n = do
284+ guard (n > 0)
285+ -- faster than 'count n anyChar'
286+ inp <- getInput
287+ pos <- getPosition
288+ let (xs, rest) = T.splitAt n inp
289+ -- needed to persuade parsec that this won't match an empty string:
290+ anyChar
291+ setInput rest
292+ setPosition $ updatePosString pos $ T.unpack xs
293+ return xs
294+
348−-- | Parse any line of text, returning the contents without the
295+-- | Parse any line of text
349−-- final newline.
350−anyLine :: Monad m => ParserT Sources st m Text
296+anyLine :: Monad m => ParserT Text st m Text
351anyLine = do
297anyLine = do
352 -- This is much faster than:
298 -- This is much faster than:
353 -- manyTill anyChar newline
299 -- manyTill anyChar newline
354 inp <- getInput
300 inp <- getInput
355− case inp of
301+ pos <- getPosition
356− Sources [] -> mzero
357− Sources ((fp,t):inps) ->
358− -- we assume that lines don't span different input files
359− case T.break (=='\n') t of
302+ case T.break (=='\n') inp of
360− (this, rest)
303+ (this, T.uncons -> Just ('\n', rest)) -> do
361− | T.null rest
362− , not (null inps) ->
363− -- line may span different input files, so do it
364− -- character by character
365− T.pack <$> manyTill anyChar newline
366− | otherwise -> do -- either end of inputs or newline in rest
367− setInput $ Sources ((fp, rest):inps)
368− char '\n' -- needed so parsec knows we won't match empty string
304+ -- needed to persuade parsec that this won't match an empty string:
369− -- and so source pos is updated
305+ anyChar
306+ setInput rest
307+ setPosition $ incSourceLine (setSourceColumn pos 1) 1
370− return this
308+ return this
309+ _ -> mzero
371
310
372-- | Parse any line, include the final newline in the output
311-- | Parse any line, include the final newline in the output
373−anyLineNewline :: Monad m => ParserT Sources st m Text
312+anyLineNewline :: Monad m => ParserT Text st m Text
374anyLineNewline = (<> "\n") <$> anyLine
313anyLineNewline = (<> "\n") <$> anyLine
375
314
376-- | Parse indent by specified number of spaces (or equiv. tabs)
315-- | Parse indent by specified number of spaces (or equiv. tabs)
377−indentWith :: (Stream s m Char, UpdateSourcePos s Char)
316+indentWith :: Stream s m Char
378 => HasReaderOptions st
317 => HasReaderOptions st
379 => Int -> ParserT s st m Text
318 => Int -> ParserT s st m Text
380indentWith num = do
319indentWith num = do
@@ -459,13 +398,11 @@ notFollowedBy' p = try $ join $ do a <- try p
459 return (return ())
398 return (return ())
460-- (This version due to Andrew Pimlott on the Haskell mailing list.)
399-- (This version due to Andrew Pimlott on the Haskell mailing list.)
461
400
462−oneOfStrings' :: (Stream s m Char, UpdateSourcePos s Char)
463− => (Char -> Char -> Bool) -> [Text] -> ParserT s st m Text
401+oneOfStrings' :: Stream s m Char => (Char -> Char -> Bool) -> [Text] -> ParserT s st m Text
464oneOfStrings' f = fmap T.pack . oneOfStrings'' f . fmap T.unpack
402oneOfStrings' f = fmap T.pack . oneOfStrings'' f . fmap T.unpack
465
403
466-- TODO: This should be re-implemented in a Text-aware way
404-- TODO: This should be re-implemented in a Text-aware way
467−oneOfStrings'' :: (Stream s m Char, UpdateSourcePos s Char)
468− => (Char -> Char -> Bool) -> [String] -> ParserT s st m String
405+oneOfStrings'' :: Stream s m Char => (Char -> Char -> Bool) -> [String] -> ParserT s st m String
469oneOfStrings'' _ [] = Prelude.fail "no strings"
406oneOfStrings'' _ [] = Prelude.fail "no strings"
470oneOfStrings'' matches strs = try $ do
407oneOfStrings'' matches strs = try $ do
471 c <- anyChar
408 c <- anyChar
@@ -480,16 +417,14 @@ oneOfStrings'' matches strs = try $ do
480-- | Parses one of a list of strings. If the list contains
417-- | Parses one of a list of strings. If the list contains
481-- two strings one of which is a prefix of the other, the longer
418-- two strings one of which is a prefix of the other, the longer
482-- string will be matched if possible.
419-- string will be matched if possible.
483−oneOfStrings :: (Stream s m Char, UpdateSourcePos s Char)
484− => [Text] -> ParserT s st m Text
420+oneOfStrings :: Stream s m Char => [Text] -> ParserT s st m Text
485oneOfStrings = oneOfStrings' (==)
421oneOfStrings = oneOfStrings' (==)
486
422
487-- | Parses one of a list of strings (tried in order), case insensitive.
423-- | Parses one of a list of strings (tried in order), case insensitive.
488
424
489-- TODO: This will not be accurate with general Unicode (neither
425-- TODO: This will not be accurate with general Unicode (neither
490-- Text.toLower nor Text.toCaseFold can be implemented with a map)
426-- Text.toLower nor Text.toCaseFold can be implemented with a map)
491−oneOfStringsCI :: (Stream s m Char, UpdateSourcePos s Char)
492− => [Text] -> ParserT s st m Text
427+oneOfStringsCI :: Stream s m Char => [Text] -> ParserT s st m Text
493oneOfStringsCI = oneOfStrings' ciMatch
428oneOfStringsCI = oneOfStrings' ciMatch
494 where ciMatch x y = toLower' x == toLower' y
429 where ciMatch x y = toLower' x == toLower' y
495 -- this optimizes toLower by checking common ASCII case
430 -- this optimizes toLower by checking common ASCII case
@@ -500,13 +435,11 @@ oneOfStringsCI = oneOfStrings' ciMatch
500 | otherwise = toLower c
435 | otherwise = toLower c
501
436
502-- | Parses a space or tab.
437-- | Parses a space or tab.
503−spaceChar :: (Stream s m Char, UpdateSourcePos s Char)
504− => ParserT s st m Char
438+spaceChar :: Stream s m Char => ParserT s st m Char
505spaceChar = satisfy $ \c -> c == ' ' || c == '\t'
439spaceChar = satisfy $ \c -> c == ' ' || c == '\t'
506
440
507-- | Parses a nonspace, nonnewline character.
441-- | Parses a nonspace, nonnewline character.
508−nonspaceChar :: (Stream s m Char, UpdateSourcePos s Char)
442+nonspaceChar :: Stream s m Char => ParserT s st m Char
509− => ParserT s st m Char
510nonspaceChar = satisfy (not . isSpaceChar)
443nonspaceChar = satisfy (not . isSpaceChar)
511
444
512isSpaceChar :: Char -> Bool
445isSpaceChar :: Char -> Bool
@@ -517,24 +450,21 @@ isSpaceChar '\r' = True
517isSpaceChar _ = False
450isSpaceChar _ = False
518
451
519-- | Skips zero or more spaces or tabs.
452-- | Skips zero or more spaces or tabs.
520−skipSpaces :: (Stream s m Char, UpdateSourcePos s Char)
453+skipSpaces :: Stream s m Char => ParserT s st m ()
521− => ParserT s st m ()
522skipSpaces = skipMany spaceChar
454skipSpaces = skipMany spaceChar
523
455
524-- | Skips zero or more spaces or tabs, then reads a newline.
456-- | Skips zero or more spaces or tabs, then reads a newline.
525−blankline :: (Stream s m Char, UpdateSourcePos s Char)
526− => ParserT s st m Char
457+blankline :: Stream s m Char => ParserT s st m Char
527blankline = try $ skipSpaces >> newline
458blankline = try $ skipSpaces >> newline
528
459
529-- | Parses one or more blank lines and returns a string of newlines.
460-- | Parses one or more blank lines and returns a string of newlines.
530−blanklines :: (Stream s m Char, UpdateSourcePos s Char)
531− => ParserT s st m Text
461+blanklines :: Stream s m Char => ParserT s st m Text
532blanklines = T.pack <$> many1 blankline
462blanklines = T.pack <$> many1 blankline
533
463
534-- | Gobble n spaces; if tabs are encountered, expand them
464-- | Gobble n spaces; if tabs are encountered, expand them
535-- and gobble some or all of their spaces, leaving the rest.
465-- and gobble some or all of their spaces, leaving the rest.
536gobbleSpaces :: (HasReaderOptions st, Monad m)
466gobbleSpaces :: (HasReaderOptions st, Monad m)
537− => Int -> ParserT Sources st m ()
467+ => Int -> ParserT Text st m ()
538gobbleSpaces 0 = return ()
468gobbleSpaces 0 = return ()
539gobbleSpaces n
469gobbleSpaces n
540 | n < 0 = error "gobbleSpaces called with negative number"
470 | n < 0 = error "gobbleSpaces called with negative number"
@@ -542,26 +472,18 @@ gobbleSpaces n
542 char ' ' <|> eatOneSpaceOfTab
472 char ' ' <|> eatOneSpaceOfTab
543 gobbleSpaces (n - 1)
473 gobbleSpaces (n - 1)
544
474
545−eatOneSpaceOfTab :: (HasReaderOptions st, Monad m) => ParserT Sources st m Char
475+eatOneSpaceOfTab :: (HasReaderOptions st, Monad m) => ParserT Text st m Char
546eatOneSpaceOfTab = do
476eatOneSpaceOfTab = do
547− lookAhead (char '\t')
477+ char '\t'
548− pos <- getPosition
549 tabstop <- getOption readerTabStop
478 tabstop <- getOption readerTabStop
550− -- replace the tab on the input stream with spaces
551− let numSpaces = tabstop - ((sourceColumn pos - 1) `mod` tabstop)
552 inp <- getInput
479 inp <- getInput
553− setInput $
480+ setInput $ T.replicate (tabstop - 1) " " <> inp
554− case inp of
481+ return ' '
555− Sources [] -> error "eatOneSpaceOfTab - empty Sources list"
556− Sources ((fp,t):rest) ->
557− -- drop the tab and add spaces
558− Sources ((fp, T.replicate numSpaces " " <> T.drop 1 t):rest)
559− char ' '
560
482
561-- | Gobble up to n spaces; if tabs are encountered, expand them
483-- | Gobble up to n spaces; if tabs are encountered, expand them
562-- and gobble some or all of their spaces, leaving the rest.
484-- and gobble some or all of their spaces, leaving the rest.
563gobbleAtMostSpaces :: (HasReaderOptions st, Monad m)
485gobbleAtMostSpaces :: (HasReaderOptions st, Monad m)
564− => Int -> ParserT Sources st m Int
486+ => Int -> ParserT Text st m Int
565gobbleAtMostSpaces 0 = return 0
487gobbleAtMostSpaces 0 = return 0
566gobbleAtMostSpaces n
488gobbleAtMostSpaces n
567 | n < 0 = error "gobbleAtMostSpaces called with negative number"
489 | n < 0 = error "gobbleAtMostSpaces called with negative number"
@@ -570,8 +492,7 @@ gobbleAtMostSpaces n
570 (+ 1) <$> gobbleAtMostSpaces (n - 1)
492 (+ 1) <$> gobbleAtMostSpaces (n - 1)
571
493
572-- | Parses material enclosed between start and end parsers.
494-- | Parses material enclosed between start and end parsers.
573−enclosed :: (Show end, Stream s m Char, UpdateSourcePos s Char)
574− => ParserT s st m t -- ^ start parser
495+enclosed :: (Show end, Stream s m Char) => ParserT s st m t -- ^ start parser
575 -> ParserT s st m end -- ^ end parser
496 -> ParserT s st m end -- ^ end parser
576 -> ParserT s st m a -- ^ content parser (to be used repeatedly)
497 -> ParserT s st m a -- ^ content parser (to be used repeatedly)
577 -> ParserT s st m [a]
498 -> ParserT s st m [a]
@@ -579,41 +500,39 @@ enclosed start end parser = try $
579 start >> notFollowedBy space >> many1Till parser end
500 start >> notFollowedBy space >> many1Till parser end
580
501
581-- | Parse string, case insensitive.
502-- | Parse string, case insensitive.
582−stringAnyCase :: (Stream s m Char, UpdateSourcePos s Char)
583− => Text -> ParserT s st m Text
503+stringAnyCase :: Stream s m Char => Text -> ParserT s st m Text
584stringAnyCase = fmap T.pack . stringAnyCase' . T.unpack
504stringAnyCase = fmap T.pack . stringAnyCase' . T.unpack
585
505
586−stringAnyCase' :: (Stream s m Char, UpdateSourcePos s Char)
587− => String -> ParserT s st m String
506+stringAnyCase' :: Stream s m Char => String -> ParserT s st m String
588stringAnyCase' [] = string ""
507stringAnyCase' [] = string ""
589stringAnyCase' (x:xs) = do
508stringAnyCase' (x:xs) = do
590 firstChar <- char (toUpper x) <|> char (toLower x)
509 firstChar <- char (toUpper x) <|> char (toLower x)
591 rest <- stringAnyCase' xs
510 rest <- stringAnyCase' xs
592 return (firstChar:rest)
511 return (firstChar:rest)
593
512
594−-- TODO rewrite by just adding to Sources stream?
595-- | Parse contents of 'str' using 'parser' and return result.
513-- | Parse contents of 'str' using 'parser' and return result.
596−parseFromString :: Monad m
514+parseFromString :: (Stream s m Char, IsString s)
597− => ParserT Sources st m r
515+ => ParserT s st m r
598 -> Text
516 -> Text
599− -> ParserT Sources st m r
517+ -> ParserT s st m r
600parseFromString parser str = do
518parseFromString parser str = do
601 oldPos <- getPosition
519 oldPos <- getPosition
602− setPosition $ initialPos "chunk"
520+ setPosition $ initialPos " chunk"
603 oldInput <- getInput
521 oldInput <- getInput
604− setInput $ toSources str
522+ setInput $ fromString $ T.unpack str
605 result <- parser
523 result <- parser
606 spaces
524 spaces
525+ eof
607 setInput oldInput
526 setInput oldInput
608 setPosition oldPos
527 setPosition oldPos
609 return result
528 return result
610
529
611-- | Like 'parseFromString' but specialized for 'ParserState'.
530-- | Like 'parseFromString' but specialized for 'ParserState'.
612-- This resets 'stateLastStrPos', which is almost always what we want.
531-- This resets 'stateLastStrPos', which is almost always what we want.
613−parseFromString' :: (Monad m, HasLastStrPosition u)
532+parseFromString' :: (Stream s m Char, IsString s, HasLastStrPosition u)
614− => ParserT Sources u m a
533+ => ParserT s u m a
615 -> Text
534 -> Text
616− -> ParserT Sources u m a
535+ -> ParserT s u m a
617parseFromString' parser str = do
536parseFromString' parser str = do
618 oldLastStrPos <- getLastStrPos <$> getState
537 oldLastStrPos <- getLastStrPos <$> getState
619 updateState $ setLastStrPos Nothing
538 updateState $ setLastStrPos Nothing
@@ -622,7 +541,7 @@ parseFromString' parser str = do
622 return res
541 return res
623
542
624-- | Parse raw line block up to and including blank lines.
543-- | Parse raw line block up to and including blank lines.
625−lineClump :: Monad m => ParserT Sources st m Text
544+lineClump :: Monad m => ParserT Text st m Text
626lineClump = blanklines
545lineClump = blanklines
627 <|> (T.unlines <$> many1 (notFollowedBy blankline >> anyLine))
546 <|> (T.unlines <$> many1 (notFollowedBy blankline >> anyLine))
628
547
@@ -631,7 +550,7 @@ lineClump = blanklines
631-- pairs of open and close, which must be different. For example,
550-- pairs of open and close, which must be different. For example,
632-- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"
551-- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"
633-- and return "hello (there)".
552-- and return "hello (there)".
634−charsInBalanced :: (Stream s m Char, UpdateSourcePos s Char) => Char -> Char -> ParserT s st m Char
553+charsInBalanced :: Stream s m Char => Char -> Char -> ParserT s st m Char
635 -> ParserT s st m Text
554 -> ParserT s st m Text
636charsInBalanced open close parser = try $ do
555charsInBalanced open close parser = try $ do
637 char open
556 char open
@@ -650,7 +569,7 @@ charsInBalanced open close parser = try $ do
650-- Auxiliary functions for romanNumeral:
569-- Auxiliary functions for romanNumeral:
651
570
652-- | Parses a roman numeral (uppercase or lowercase), returns number.
571-- | Parses a roman numeral (uppercase or lowercase), returns number.
653−romanNumeral :: (Stream s m Char, UpdateSourcePos s Char) => Bool -- ^ Uppercase if true
572+romanNumeral :: Stream s m Char => Bool -- ^ Uppercase if true
654 -> ParserT s st m Int
573 -> ParserT s st m Int
655romanNumeral upperCase = do
574romanNumeral upperCase = do
656 let rchar uc = char $ if upperCase then uc else toLower uc
575 let rchar uc = char $ if upperCase then uc else toLower uc
@@ -686,19 +605,20 @@ romanNumeral upperCase = do
686
605
687-- | Parses an email address; returns original and corresponding
606-- | Parses an email address; returns original and corresponding
688-- escaped mailto: URI.
607-- escaped mailto: URI.
689−emailAddress :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (Text, Text)
608+emailAddress :: Stream s m Char => ParserT s st m (Text, Text)
690emailAddress = try $ toResult <$> mailbox <*> (char '@' *> domain)
609emailAddress = try $ toResult <$> mailbox <*> (char '@' *> domain)
691 where toResult mbox dom = let full = fromEntities $ T.pack $ mbox ++ '@':dom
610 where toResult mbox dom = let full = fromEntities $ T.pack $ mbox ++ '@':dom
692 in (full, escapeURI $ "mailto:" <> full)
611 in (full, escapeURI $ "mailto:" <> full)
693 mailbox = intercalate "." <$> (emailWord `sepBy1'` dot)
612 mailbox = intercalate "." <$> (emailWord `sepBy1'` dot)
694 domain = intercalate "." <$> (subdomain `sepBy1'` dot)
613 domain = intercalate "." <$> (subdomain `sepBy1'` dot)
695 dot = char '.'
614 dot = char '.'
696− subdomain = many1 $ alphaNum <|> innerPunct (=='-')
615+ subdomain = many1 $ alphaNum <|> innerPunct
697 -- this excludes some valid email addresses, since an
616 -- this excludes some valid email addresses, since an
698 -- email could contain e.g. '__', but gives better results
617 -- email could contain e.g. '__', but gives better results
699 -- for our purposes, when combined with markdown parsing:
618 -- for our purposes, when combined with markdown parsing:
700− innerPunct f = try (satisfy f
619+ innerPunct = try (satisfy (\c -> isEmailPunct c || c == '@')
620+ <* notFollowedBy space
701− <* notFollowedBy (satisfy (not . isAlphaNum)))
621+ <* notFollowedBy (satisfy isPunctuation))
702 -- technically an email address could begin with a symbol,
622 -- technically an email address could begin with a symbol,
703 -- but allowing this creates too many problems.
623 -- but allowing this creates too many problems.
704 -- See e.g. https://github.com/jgm/pandoc/issues/2940
624 -- See e.g. https://github.com/jgm/pandoc/issues/2940
@@ -709,11 +629,11 @@ emailAddress = try $ toResult <$> mailbox <*> (char '@' *> domain)
709 isEmailPunct c = T.any (== c) "!\"#$%&'*+-/=?^_{|}~;"
629 isEmailPunct c = T.any (== c) "!\"#$%&'*+-/=?^_{|}~;"
710
630
711
631
712−uriScheme :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Text
632+uriScheme :: Stream s m Char => ParserT s st m Text
713uriScheme = oneOfStringsCI (Set.toList schemes)
633uriScheme = oneOfStringsCI (Set.toList schemes)
714
634
715-- | Parses a URI. Returns pair of original and URI-escaped version.
635-- | Parses a URI. Returns pair of original and URI-escaped version.
716−uri :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (Text, Text)
636+uri :: Stream s m Char => ParserT s st m (Text, Text)
717uri = try $ do
637uri = try $ do
718 scheme <- uriScheme
638 scheme <- uriScheme
719 char ':'
639 char ':'
@@ -756,7 +676,7 @@ uri = try $ do
756 uriChunkBetween l r = try $ do chunk <- between (char l) (char r) uriChunk
676 uriChunkBetween l r = try $ do chunk <- between (char l) (char r) uriChunk
757 return (T.pack $ [l] ++ chunk ++ [r])
677 return (T.pack $ [l] ++ chunk ++ [r])
758
678
759−mathInlineWith :: (Stream s m Char, UpdateSourcePos s Char) => Text -> Text -> ParserT s st m Text
679+mathInlineWith :: Stream s m Char => Text -> Text -> ParserT s st m Text
760mathInlineWith op cl = try $ do
680mathInlineWith op cl = try $ do
761 textStr op
681 textStr op
762 when (op == "$") $ notFollowedBy space
682 when (op == "$") $ notFollowedBy space
@@ -777,10 +697,10 @@ mathInlineWith op cl = try $ do
777 notFollowedBy digit -- to prevent capture of $5
697 notFollowedBy digit -- to prevent capture of $5
778 return $ trimMath $ T.concat words'
698 return $ trimMath $ T.concat words'
779 where
699 where
780− inBalancedBraces :: (Stream s m Char, UpdateSourcePos s Char) => Int -> Text -> ParserT s st m Text
700+ inBalancedBraces :: Stream s m Char => Int -> Text -> ParserT s st m Text
781 inBalancedBraces n = fmap T.pack . inBalancedBraces' n . T.unpack
701 inBalancedBraces n = fmap T.pack . inBalancedBraces' n . T.unpack
782
702
783− inBalancedBraces' :: (Stream s m Char, UpdateSourcePos s Char) => Int -> String -> ParserT s st m String
703+ inBalancedBraces' :: Stream s m Char => Int -> String -> ParserT s st m String
784 inBalancedBraces' 0 "" = do
704 inBalancedBraces' 0 "" = do
785 c <- anyChar
705 c <- anyChar
786 if c == '{'
706 if c == '{'
@@ -797,13 +717,13 @@ mathInlineWith op cl = try $ do
797 '{' -> inBalancedBraces' (numOpen + 1) (c:xs)
717 '{' -> inBalancedBraces' (numOpen + 1) (c:xs)
798 _ -> inBalancedBraces' numOpen (c:xs)
718 _ -> inBalancedBraces' numOpen (c:xs)
799
719
800−mathDisplayWith :: (Stream s m Char, UpdateSourcePos s Char) => Text -> Text -> ParserT s st m Text
720+mathDisplayWith :: Stream s m Char => Text -> Text -> ParserT s st m Text
801mathDisplayWith op cl = try $ fmap T.pack $ do
721mathDisplayWith op cl = try $ fmap T.pack $ do
802 textStr op
722 textStr op
803 many1Till (satisfy (/= '\n') <|> (newline <* notFollowedBy' blankline))
723 many1Till (satisfy (/= '\n') <|> (newline <* notFollowedBy' blankline))
804 (try $ textStr cl)
724 (try $ textStr cl)
805
725
806−mathDisplay :: (HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char)
726+mathDisplay :: (HasReaderOptions st, Stream s m Char)
807 => ParserT s st m Text
727 => ParserT s st m Text
808mathDisplay =
728mathDisplay =
809 (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")
729 (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")
@@ -812,7 +732,7 @@ mathDisplay =
812 <|> (guardEnabled Ext_tex_math_double_backslash >>
732 <|> (guardEnabled Ext_tex_math_double_backslash >>
813 mathDisplayWith "\\\\[" "\\\\]")
733 mathDisplayWith "\\\\[" "\\\\]")
814
734
815−mathInline :: (HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char)
735+mathInline :: (HasReaderOptions st , Stream s m Char)
816 => ParserT s st m Text
736 => ParserT s st m Text
817mathInline =
737mathInline =
818 (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")
738 (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")
@@ -825,7 +745,7 @@ mathInline =
825-- displacement (the difference between the source column at the end
745-- displacement (the difference between the source column at the end
826-- and the source column at the beginning). Vertical displacement
746-- and the source column at the beginning). Vertical displacement
827-- (source row) is ignored.
747-- (source row) is ignored.
828−withHorizDisplacement :: (Stream s m Char, UpdateSourcePos s Char)
748+withHorizDisplacement :: Stream s m Char
829 => ParserT s st m a -- ^ Parser to apply
749 => ParserT s st m a -- ^ Parser to apply
830 -> ParserT s st m (a, Int) -- ^ (result, displacement)
750 -> ParserT s st m (a, Int) -- ^ (result, displacement)
831withHorizDisplacement parser = do
751withHorizDisplacement parser = do
@@ -837,37 +757,30 @@ withHorizDisplacement parser = do
837-- | Applies a parser and returns the raw string that was parsed,
757-- | Applies a parser and returns the raw string that was parsed,
838-- along with the value produced by the parser.
758-- along with the value produced by the parser.
839withRaw :: Monad m
759withRaw :: Monad m
840− => ParsecT Sources st m a
760+ => ParsecT Text st m a
841− -> ParsecT Sources st m (a, Text)
761+ -> ParsecT Text st m (a, Text)
842withRaw parser = do
762withRaw parser = do
763+ pos1 <- getPosition
843− inps1 <- getInput
764+ inp <- getInput
844 result <- parser
765 result <- parser
845− inps2 <- getInput
766+ pos2 <- getPosition
846− -- 'raw' is the difference between inps1 and inps2
767+ let (l1,c1) = (sourceLine pos1, sourceColumn pos1)
847− return (result, sourcesDifference inps1 inps2)
768+ let (l2,c2) = (sourceLine pos2, sourceColumn pos2)
848−
769+ let inplines = take ((l2 - l1) + 1) $ T.lines inp
849−sourcesDifference :: Sources -> Sources -> Text
770+ let raw = case inplines of
850−sourcesDifference (Sources is1) (Sources is2) = go is1 is2
851− where
852− go inps1 inps2 =
853− case (inps1, inps2) of
854− ([], _) -> mempty
771+ [] -> ""
855− (_, []) -> mconcat $ map snd inps1
772+ [l] -> T.take (c2 - c1) l
856− ((p1,t1):rest1, (p2, t2):rest2)
773+ ls -> T.unlines (init ls) <> T.take (c2 - 1) (last ls)
857− | p1 == p2
774+ return (result, raw)
858− , t1 == t2 -> go rest1 rest2
859− | p1 == p2
860− , t1 /= t2 -> fromMaybe mempty $ T.stripSuffix t2 t1
861− | otherwise -> t1 <> go rest1 inps2
862
775
863-- | Parses backslash, then applies character parser.
776-- | Parses backslash, then applies character parser.
864−escaped :: (Stream s m Char, UpdateSourcePos s Char)
777+escaped :: Stream s m Char
865 => ParserT s st m Char -- ^ Parser for character to escape
778 => ParserT s st m Char -- ^ Parser for character to escape
866 -> ParserT s st m Char
779 -> ParserT s st m Char
867escaped parser = try $ char '\\' >> parser
780escaped parser = try $ char '\\' >> parser
868
781
869-- | Parse character entity.
782-- | Parse character entity.
870−characterReference :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Char
783+characterReference :: Stream s m Char => ParserT s st m Char
871characterReference = try $ do
784characterReference = try $ do
872 char '&'
785 char '&'
873 ent <- many1Till nonspaceChar (char ';')
786 ent <- many1Till nonspaceChar (char ';')
@@ -880,19 +793,19 @@ characterReference = try $ do
880 _ -> Prelude.fail "entity not found"
793 _ -> Prelude.fail "entity not found"
881
794
882-- | Parses an uppercase roman numeral and returns (UpperRoman, number).
795-- | Parses an uppercase roman numeral and returns (UpperRoman, number).
883−upperRoman :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
796+upperRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
884upperRoman = do
797upperRoman = do
885 num <- romanNumeral True
798 num <- romanNumeral True
886 return (UpperRoman, num)
799 return (UpperRoman, num)
887
800
888-- | Parses a lowercase roman numeral and returns (LowerRoman, number).
801-- | Parses a lowercase roman numeral and returns (LowerRoman, number).
889−lowerRoman :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
802+lowerRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
890lowerRoman = do
803lowerRoman = do
891 num <- romanNumeral False
804 num <- romanNumeral False
892 return (LowerRoman, num)
805 return (LowerRoman, num)
893
806
894-- | Parses a decimal numeral and returns (Decimal, number).
807-- | Parses a decimal numeral and returns (Decimal, number).
895−decimal :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
808+decimal :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
896decimal = do
809decimal = do
897 num <- many1 digit
810 num <- many1 digit
898 return (Decimal, fromMaybe 1 $ safeRead $ T.pack num)
811 return (Decimal, fromMaybe 1 $ safeRead $ T.pack num)
@@ -901,7 +814,7 @@ decimal = do
901-- returns (DefaultStyle, [next example number]). The next
814-- returns (DefaultStyle, [next example number]). The next
902-- example number is incremented in parser state, and the label
815-- example number is incremented in parser state, and the label
903-- (if present) is added to the label table.
816-- (if present) is added to the label table.
904−exampleNum :: (Stream s m Char, UpdateSourcePos s Char)
817+exampleNum :: Stream s m Char
905 => ParserT s ParserState m (ListNumberStyle, Int)
818 => ParserT s ParserState m (ListNumberStyle, Int)
906exampleNum = do
819exampleNum = do
907 char '@'
820 char '@'
@@ -920,37 +833,37 @@ exampleNum = do
920 return (Example, num)
833 return (Example, num)
921
834
922-- | Parses a '#' returns (DefaultStyle, 1).
835-- | Parses a '#' returns (DefaultStyle, 1).
923−defaultNum :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
836+defaultNum :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
924defaultNum = do
837defaultNum = do
925 char '#'
838 char '#'
926 return (DefaultStyle, 1)
839 return (DefaultStyle, 1)
927
840
928-- | Parses a lowercase letter and returns (LowerAlpha, number).
841-- | Parses a lowercase letter and returns (LowerAlpha, number).
929−lowerAlpha :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
842+lowerAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
930lowerAlpha = do
843lowerAlpha = do
931 ch <- satisfy isAsciiLower
844 ch <- satisfy isAsciiLower
932 return (LowerAlpha, ord ch - ord 'a' + 1)
845 return (LowerAlpha, ord ch - ord 'a' + 1)
933
846
934-- | Parses an uppercase letter and returns (UpperAlpha, number).
847-- | Parses an uppercase letter and returns (UpperAlpha, number).
935−upperAlpha :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
848+upperAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
936upperAlpha = do
849upperAlpha = do
937 ch <- satisfy isAsciiUpper
850 ch <- satisfy isAsciiUpper
938 return (UpperAlpha, ord ch - ord 'A' + 1)
851 return (UpperAlpha, ord ch - ord 'A' + 1)
939
852
940-- | Parses a roman numeral i or I
853-- | Parses a roman numeral i or I
941−romanOne :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m (ListNumberStyle, Int)
854+romanOne :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
942romanOne = (char 'i' >> return (LowerRoman, 1)) <|>
855romanOne = (char 'i' >> return (LowerRoman, 1)) <|>
943 (char 'I' >> return (UpperRoman, 1))
856 (char 'I' >> return (UpperRoman, 1))
944
857
945-- | Parses an ordered list marker and returns list attributes.
858-- | Parses an ordered list marker and returns list attributes.
946−anyOrderedListMarker :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s ParserState m ListAttributes
859+anyOrderedListMarker :: Stream s m Char => ParserT s ParserState m ListAttributes
947anyOrderedListMarker = choice
860anyOrderedListMarker = choice
948 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
861 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
949 numParser <- [decimal, exampleNum, defaultNum, romanOne,
862 numParser <- [decimal, exampleNum, defaultNum, romanOne,
950 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
863 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
951
864
952-- | Parses a list number (num) followed by a period, returns list attributes.
865-- | Parses a list number (num) followed by a period, returns list attributes.
953−inPeriod :: (Stream s m Char, UpdateSourcePos s Char)
866+inPeriod :: Stream s m Char
954 => ParserT s st m (ListNumberStyle, Int)
867 => ParserT s st m (ListNumberStyle, Int)
955 -> ParserT s st m ListAttributes
868 -> ParserT s st m ListAttributes
956inPeriod num = try $ do
869inPeriod num = try $ do
@@ -962,7 +875,7 @@ inPeriod num = try $ do
962 return (start, style, delim)
875 return (start, style, delim)
963
876
964-- | Parses a list number (num) followed by a paren, returns list attributes.
877-- | Parses a list number (num) followed by a paren, returns list attributes.
965−inOneParen :: (Stream s m Char, UpdateSourcePos s Char)
878+inOneParen :: Stream s m Char
966 => ParserT s st m (ListNumberStyle, Int)
879 => ParserT s st m (ListNumberStyle, Int)
967 -> ParserT s st m ListAttributes
880 -> ParserT s st m ListAttributes
968inOneParen num = try $ do
881inOneParen num = try $ do
@@ -971,7 +884,7 @@ inOneParen num = try $ do
971 return (start, style, OneParen)
884 return (start, style, OneParen)
972
885
973-- | Parses a list number (num) enclosed in parens, returns list attributes.
886-- | Parses a list number (num) enclosed in parens, returns list attributes.
974−inTwoParens :: (Stream s m Char, UpdateSourcePos s Char)
887+inTwoParens :: Stream s m Char
975 => ParserT s st m (ListNumberStyle, Int)
888 => ParserT s st m (ListNumberStyle, Int)
976 -> ParserT s st m ListAttributes
889 -> ParserT s st m ListAttributes
977inTwoParens num = try $ do
890inTwoParens num = try $ do
@@ -982,7 +895,7 @@ inTwoParens num = try $ do
982
895
983-- | Parses an ordered list marker with a given style and delimiter,
896-- | Parses an ordered list marker with a given style and delimiter,
984-- returns number.
897-- returns number.
985−orderedListMarker :: (Stream s m Char, UpdateSourcePos s Char)
898+orderedListMarker :: Stream s m Char
986 => ListNumberStyle
899 => ListNumberStyle
987 -> ListNumberDelim
900 -> ListNumberDelim
988 -> ParserT s ParserState m Int
901 -> ParserT s ParserState m Int
@@ -1005,10 +918,10 @@ orderedListMarker style delim = do
1005 return start
918 return start
1006
919
1007-- | Parses a character reference and returns a Str element.
920-- | Parses a character reference and returns a Str element.
1008−charRef :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Inline
921+charRef :: Stream s m Char => ParserT s st m Inline
1009charRef = Str . T.singleton <$> characterReference
922charRef = Str . T.singleton <$> characterReference
1010
923
1011−lineBlockLine :: Monad m => ParserT Sources st m Text
924+lineBlockLine :: Monad m => ParserT Text st m Text
1012lineBlockLine = try $ do
925lineBlockLine = try $ do
1013 char '|'
926 char '|'
1014 char ' '
927 char ' '
@@ -1018,11 +931,11 @@ lineBlockLine = try $ do
1018 continuations <- many (try $ char ' ' >> anyLine)
931 continuations <- many (try $ char ' ' >> anyLine)
1019 return $ white <> T.unwords (line : continuations)
932 return $ white <> T.unwords (line : continuations)
1020
933
1021−blankLineBlockLine :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Char
934+blankLineBlockLine :: Stream s m Char => ParserT s st m Char
1022blankLineBlockLine = try (char '|' >> blankline)
935blankLineBlockLine = try (char '|' >> blankline)
1023
936
1024-- | Parses an RST-style line block and returns a list of strings.
937-- | Parses an RST-style line block and returns a list of strings.
1025−lineBlockLines :: Monad m => ParserT Sources st m [Text]
938+lineBlockLines :: Monad m => ParserT Text st m [Text]
1026lineBlockLines = try $ do
939lineBlockLines = try $ do
1027 lines' <- many1 (lineBlockLine <|> (T.singleton <$> blankLineBlockLine))
940 lines' <- many1 (lineBlockLine <|> (T.singleton <$> blankLineBlockLine))
1028 skipMany blankline
941 skipMany blankline
@@ -1030,8 +943,7 @@ lineBlockLines = try $ do
1030
943
1031-- | Parse a table using 'headerParser', 'rowParser',
944-- | Parse a table using 'headerParser', 'rowParser',
1032-- 'lineParser', and 'footerParser'.
945-- 'lineParser', and 'footerParser'.
1033−tableWith :: (Stream s m Char, UpdateSourcePos s Char,
1034− HasReaderOptions st, Monad mf)
946+tableWith :: (Stream s m Char, HasReaderOptions st, Monad mf)
1035 => ParserT s st m (mf [Blocks], [Alignment], [Int])
947 => ParserT s st m (mf [Blocks], [Alignment], [Int])
1036 -> ([Int] -> ParserT s st m (mf [Blocks]))
948 -> ([Int] -> ParserT s st m (mf [Blocks]))
1037 -> ParserT s st m sep
949 -> ParserT s st m sep
@@ -1051,8 +963,7 @@ tableWith headerParser rowParser lineParser footerParser = try $ do
1051
963
1052type TableComponents mf = ([Alignment], [Double], mf [Row], mf [Row])
964type TableComponents mf = ([Alignment], [Double], mf [Row], mf [Row])
1053
965
1054−tableWith' :: (Stream s m Char, UpdateSourcePos s Char,
1055− HasReaderOptions st, Monad mf)
966+tableWith' :: (Stream s m Char, HasReaderOptions st, Monad mf)
1056 => ParserT s st m (mf [Blocks], [Alignment], [Int])
967 => ParserT s st m (mf [Blocks], [Alignment], [Int])
1057 -> ([Int] -> ParserT s st m (mf [Blocks]))
968 -> ([Int] -> ParserT s st m (mf [Blocks]))
1058 -> ParserT s st m sep
969 -> ParserT s st m sep
@@ -1101,19 +1012,20 @@ widthsFromIndices numColumns' indices =
1101-- (which may be grid), then the rows,
1012-- (which may be grid), then the rows,
1102-- which may be grid, separated by blank lines, and
1013-- which may be grid, separated by blank lines, and
1103-- ending with a footer (dashed line followed by blank line).
1014-- ending with a footer (dashed line followed by blank line).
1104−gridTableWith :: (Monad m, HasReaderOptions st, HasLastStrPosition st, Monad mf)
1015+gridTableWith :: (Stream s m Char, HasReaderOptions st, HasLastStrPosition st,
1016+ Monad mf, IsString s)
1105− => ParserT Sources st m (mf Blocks) -- ^ Block list parser
1017+ => ParserT s st m (mf Blocks) -- ^ Block list parser
1106 -> Bool -- ^ Headerless table
1018 -> Bool -- ^ Headerless table
1107− -> ParserT Sources st m (mf Blocks)
1019+ -> ParserT s st m (mf Blocks)
1108gridTableWith blocks headless =
1020gridTableWith blocks headless =
1109 tableWith (gridTableHeader headless blocks) (gridTableRow blocks)
1021 tableWith (gridTableHeader headless blocks) (gridTableRow blocks)
1110 (gridTableSep '-') gridTableFooter
1022 (gridTableSep '-') gridTableFooter
1111
1023
1112−gridTableWith' :: (Monad m, HasReaderOptions st, HasLastStrPosition st,
1024+gridTableWith' :: (Stream s m Char, HasReaderOptions st, HasLastStrPosition st,
1113− Monad mf)
1025+ Monad mf, IsString s)
1114− => ParserT Sources st m (mf Blocks) -- ^ Block list parser
1026+ => ParserT s st m (mf Blocks) -- ^ Block list parser
1115 -> Bool -- ^ Headerless table
1027 -> Bool -- ^ Headerless table
1116− -> ParserT Sources st m (TableComponents mf)
1028+ -> ParserT s st m (TableComponents mf)
1117gridTableWith' blocks headless =
1029gridTableWith' blocks headless =
1118 tableWith' (gridTableHeader headless blocks) (gridTableRow blocks)
1030 tableWith' (gridTableHeader headless blocks) (gridTableRow blocks)
1119 (gridTableSep '-') gridTableFooter
1031 (gridTableSep '-') gridTableFooter
@@ -1122,7 +1034,7 @@ gridTableSplitLine :: [Int] -> Text -> [Text]
1122gridTableSplitLine indices line = map removeFinalBar $ tail $
1034gridTableSplitLine indices line = map removeFinalBar $ tail $
1123 splitTextByIndices (init indices) $ trimr line
1035 splitTextByIndices (init indices) $ trimr line
1124
1036
1125−gridPart :: Monad m => Char -> ParserT Sources st m ((Int, Int), Alignment)
1037+gridPart :: Stream s m Char => Char -> ParserT s st m ((Int, Int), Alignment)
1126gridPart ch = do
1038gridPart ch = do
1127 leftColon <- option False (True <$ char ':')
1039 leftColon <- option False (True <$ char ':')
1128 dashes <- many1 (char ch)
1040 dashes <- many1 (char ch)
@@ -1137,7 +1049,7 @@ gridPart ch = do
1137 (False, False) -> AlignDefault
1049 (False, False) -> AlignDefault
1138 return ((lengthDashes, lengthDashes + 1), alignment)
1050 return ((lengthDashes, lengthDashes + 1), alignment)
1139
1051
1140−gridDashedLines :: Monad m => Char -> ParserT Sources st m [((Int, Int), Alignment)]
1052+gridDashedLines :: Stream s m Char => Char -> ParserT s st m [((Int, Int), Alignment)]
1141gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline
1053gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline
1142
1054
1143removeFinalBar :: Text -> Text
1055removeFinalBar :: Text -> Text
@@ -1146,14 +1058,14 @@ removeFinalBar = T.dropWhileEnd go . T.dropWhileEnd (=='|')
1146 go c = T.any (== c) " \t"
1058 go c = T.any (== c) " \t"
1147
1059
1148-- | Separator between rows of grid table.
1060-- | Separator between rows of grid table.
1149−gridTableSep :: Monad m => Char -> ParserT Sources st m Char
1061+gridTableSep :: Stream s m Char => Char -> ParserT s st m Char
1150gridTableSep ch = try $ gridDashedLines ch >> return '\n'
1062gridTableSep ch = try $ gridDashedLines ch >> return '\n'
1151
1063
1152-- | Parse header for a grid table.
1064-- | Parse header for a grid table.
1153−gridTableHeader :: (Monad m, Monad mf, HasLastStrPosition st)
1065+gridTableHeader :: (Stream s m Char, Monad mf, IsString s, HasLastStrPosition st)
1154 => Bool -- ^ Headerless table
1066 => Bool -- ^ Headerless table
1155− -> ParserT Sources st m (mf Blocks)
1067+ -> ParserT s st m (mf Blocks)
1156− -> ParserT Sources st m (mf [Blocks], [Alignment], [Int])
1068+ -> ParserT s st m (mf [Blocks], [Alignment], [Int])
1157gridTableHeader True _ = do
1069gridTableHeader True _ = do
1158 optional blanklines
1070 optional blanklines
1159 dashes <- gridDashedLines '-'
1071 dashes <- gridDashedLines '-'
@@ -1176,17 +1088,17 @@ gridTableHeader False blocks = try $ do
1176 heads <- sequence <$> mapM (parseFromString' blocks . trim) rawHeads
1088 heads <- sequence <$> mapM (parseFromString' blocks . trim) rawHeads
1177 return (heads, aligns, indices)
1089 return (heads, aligns, indices)
1178
1090
1179−gridTableRawLine :: (Stream s m Char, UpdateSourcePos s Char) => [Int] -> ParserT s st m [Text]
1091+gridTableRawLine :: Stream s m Char => [Int] -> ParserT s st m [Text]
1180gridTableRawLine indices = do
1092gridTableRawLine indices = do
1181 char '|'
1093 char '|'
1182 line <- many1Till anyChar newline
1094 line <- many1Till anyChar newline
1183 return (gridTableSplitLine indices $ T.pack line)
1095 return (gridTableSplitLine indices $ T.pack line)
1184
1096
1185-- | Parse row of grid table.
1097-- | Parse row of grid table.
1186−gridTableRow :: (Monad m, Monad mf, HasLastStrPosition st)
1098+gridTableRow :: (Stream s m Char, Monad mf, IsString s, HasLastStrPosition st)
1187− => ParserT Sources st m (mf Blocks)
1099+ => ParserT s st m (mf Blocks)
1188 -> [Int]
1100 -> [Int]
1189− -> ParserT Sources st m (mf [Blocks])
1101+ -> ParserT s st m (mf [Blocks])
1190gridTableRow blocks indices = do
1102gridTableRow blocks indices = do
1191 colLines <- many1 (gridTableRawLine indices)
1103 colLines <- many1 (gridTableRawLine indices)
1192 let cols = map ((<> "\n") . T.unlines . removeOneLeadingSpace) $
1104 let cols = map ((<> "\n") . T.unlines . removeOneLeadingSpace) $
@@ -1207,38 +1119,34 @@ removeOneLeadingSpace xs =
1207 Just (c, _) -> c == ' '
1119 Just (c, _) -> c == ' '
1208
1120
1209-- | Parse footer for a grid table.
1121-- | Parse footer for a grid table.
1210−gridTableFooter :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m ()
1122+gridTableFooter :: Stream s m Char => ParserT s st m ()
1211gridTableFooter = optional blanklines
1123gridTableFooter = optional blanklines
1212
1124
1213---
1125---
1214
1126
1215-- | Removes the ParsecT layer from the monad transformer stack
1127-- | Removes the ParsecT layer from the monad transformer stack
1216−readWithM :: (Monad m, ToSources t)
1128+readWithM :: Monad m
1217− => ParserT Sources st m a -- ^ parser
1129+ => ParserT Text st m a -- ^ parser
1218− -> st -- ^ initial state
1130+ -> st -- ^ initial state
1219− -> t -- ^ input
1131+ -> Text -- ^ input
1220 -> m (Either PandocError a)
1132 -> m (Either PandocError a)
1221readWithM parser state input =
1133readWithM parser state input =
1222− mapLeft (PandocParsecError sources)
1134+ mapLeft (PandocParsecError input) <$> runParserT parser state "source" input
1223− <$> runParserT parser state (initialSourceName sources) sources
1224− where
1225− sources = toSources input
1226
1135
1227-- | Parse a string with a given parser and state
1136-- | Parse a string with a given parser and state
1228−readWith :: ToSources t
1229− => Parser Sources st a
1137+readWith :: Parser Text st a
1230 -> st
1138 -> st
1231− -> t
1139+ -> Text
1232 -> Either PandocError a
1140 -> Either PandocError a
1233readWith p t inp = runIdentity $ readWithM p t inp
1141readWith p t inp = runIdentity $ readWithM p t inp
1234
1142
1235-- | Parse a string with @parser@ (for testing).
1143-- | Parse a string with @parser@ (for testing).
1236testStringWith :: Show a
1144testStringWith :: Show a
1237− => ParserT Sources ParserState Identity a
1145+ => ParserT Text ParserState Identity a
1238 -> Text
1146 -> Text
1239 -> IO ()
1147 -> IO ()
1240testStringWith parser str = UTF8.putStrLn $ tshow $
1148testStringWith parser str = UTF8.putStrLn $ tshow $
1241− readWith parser defaultParserState (toSources str)
1149+ readWith parser defaultParserState str
1242
1150
1243-- | Parsing options.
1151-- | Parsing options.
1244data ParserState = ParserState
1152data ParserState = ParserState
@@ -1485,42 +1393,34 @@ registerHeader (ident,classes,kvs) header' = do
1485 updateState $ updateIdentifierList $ Set.insert ident
1393 updateState $ updateIdentifierList $ Set.insert ident
1486 return (ident,classes,kvs)
1394 return (ident,classes,kvs)
1487
1395
1488−smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st,
1396+smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1489− HasQuoteContext st m,
1490− Stream s m Char, UpdateSourcePos s Char)
1491 => ParserT s st m Inlines
1397 => ParserT s st m Inlines
1492 -> ParserT s st m Inlines
1398 -> ParserT s st m Inlines
1493smartPunctuation inlineParser = do
1399smartPunctuation inlineParser = do
1494 guardEnabled Ext_smart
1400 guardEnabled Ext_smart
1495− choice [ quoted inlineParser, apostrophe, doubleCloseQuote, dash, ellipses ]
1401+ choice [ quoted inlineParser, apostrophe, dash, ellipses ]
1496
1402
1403+apostrophe :: Stream s m Char => ParserT s st m Inlines
1404+apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\x2019")
1405+
1497−quoted :: (HasLastStrPosition st, HasQuoteContext st m,
1406+quoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1498− Stream s m Char, UpdateSourcePos s Char)
1499 => ParserT s st m Inlines
1407 => ParserT s st m Inlines
1500 -> ParserT s st m Inlines
1408 -> ParserT s st m Inlines
1501quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser
1409quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser
1502
1410
1503−singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m,
1411+singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1504− Stream s m Char, UpdateSourcePos s Char)
1505 => ParserT s st m Inlines
1412 => ParserT s st m Inlines
1506 -> ParserT s st m Inlines
1413 -> ParserT s st m Inlines
1507−singleQuoted inlineParser = do
1414+singleQuoted inlineParser = try $ B.singleQuoted . mconcat
1508− singleQuoteStart
1415+ <$ singleQuoteStart
1509− (B.singleQuoted . mconcat <$>
1510− try
1511− (withQuoteContext InSingleQuote (many1Till inlineParser singleQuoteEnd)))
1416+ <*> withQuoteContext InSingleQuote (many1Till inlineParser singleQuoteEnd)
1512− <|> pure "\8217"
1417+
1513−
1514−doubleQuoted :: (HasQuoteContext st m, HasLastStrPosition st,
1418+doubleQuoted :: (HasQuoteContext st m, Stream s m Char)
1515− Stream s m Char, UpdateSourcePos s Char)
1516 => ParserT s st m Inlines
1419 => ParserT s st m Inlines
1517 -> ParserT s st m Inlines
1420 -> ParserT s st m Inlines
1518−doubleQuoted inlineParser = do
1421+doubleQuoted inlineParser = try $ B.doubleQuoted . mconcat
1519− doubleQuoteStart
1422+ <$ doubleQuoteStart
1520− (B.doubleQuoted . mconcat <$>
1521− try
1522− (withQuoteContext InDoubleQuote (manyTill inlineParser doubleQuoteEnd)))
1423+ <*> withQuoteContext InDoubleQuote (manyTill inlineParser doubleQuoteEnd)
1523− <|> pure (B.str "\8220")
1524
1424
1525failIfInQuoteContext :: (HasQuoteContext st m, Stream s m t)
1425failIfInQuoteContext :: (HasQuoteContext st m, Stream s m t)
1526 => QuoteContext
1426 => QuoteContext
@@ -1529,14 +1429,13 @@ failIfInQuoteContext context = do
1529 context' <- getQuoteContext
1429 context' <- getQuoteContext
1530 when (context' == context) $ Prelude.fail "already inside quotes"
1430 when (context' == context) $ Prelude.fail "already inside quotes"
1531
1431
1532−charOrRef :: (Stream s m Char, UpdateSourcePos s Char) => [Char] -> ParserT s st m Char
1432+charOrRef :: Stream s m Char => [Char] -> ParserT s st m Char
1533charOrRef cs =
1433charOrRef cs =
1534 oneOf cs <|> try (do c <- characterReference
1434 oneOf cs <|> try (do c <- characterReference
1535 guard (c `elem` cs)
1435 guard (c `elem` cs)
1536 return c)
1436 return c)
1537
1437
1538−singleQuoteStart :: (HasLastStrPosition st, HasQuoteContext st m,
1438+singleQuoteStart :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1539− Stream s m Char, UpdateSourcePos s Char)
1540 => ParserT s st m ()
1439 => ParserT s st m ()
1541singleQuoteStart = do
1440singleQuoteStart = do
1542 failIfInQuoteContext InSingleQuote
1441 failIfInQuoteContext InSingleQuote
@@ -1544,39 +1443,30 @@ singleQuoteStart = do
1544 guard =<< notAfterString
1443 guard =<< notAfterString
1545 try $ do
1444 try $ do
1546 charOrRef "'\8216\145"
1445 charOrRef "'\8216\145"
1547− void $ lookAhead (satisfy (not . isSpaceChar))
1446+ notFollowedBy (oneOf [' ', '\t', '\n'])
1548
1447
1549−singleQuoteEnd :: (Stream s m Char, UpdateSourcePos s Char)
1448+singleQuoteEnd :: Stream s m Char
1550 => ParserT s st m ()
1449 => ParserT s st m ()
1551singleQuoteEnd = try $ do
1450singleQuoteEnd = try $ do
1552 charOrRef "'\8217\146"
1451 charOrRef "'\8217\146"
1553 notFollowedBy alphaNum
1452 notFollowedBy alphaNum
1554
1453
1555−doubleQuoteStart :: (HasLastStrPosition st,
1556− HasQuoteContext st m,
1454+doubleQuoteStart :: (HasQuoteContext st m, Stream s m Char)
1557− Stream s m Char, UpdateSourcePos s Char)
1558 => ParserT s st m ()
1455 => ParserT s st m ()
1559doubleQuoteStart = do
1456doubleQuoteStart = do
1560 failIfInQuoteContext InDoubleQuote
1457 failIfInQuoteContext InDoubleQuote
1561− guard =<< notAfterString
1562 try $ do charOrRef "\"\8220\147"
1458 try $ do charOrRef "\"\8220\147"
1563− void $ lookAhead (satisfy (not . isSpaceChar))
1459+ notFollowedBy (oneOf [' ', '\t', '\n'])
1564
1460
1565−doubleQuoteEnd :: (Stream s m Char, UpdateSourcePos s Char)
1461+doubleQuoteEnd :: Stream s m Char
1566 => ParserT s st m ()
1462 => ParserT s st m ()
1567doubleQuoteEnd = void (charOrRef "\"\8221\148")
1463doubleQuoteEnd = void (charOrRef "\"\8221\148")
1568
1464
1569−apostrophe :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Inlines
1570−apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\8217")
1571−
1572−doubleCloseQuote :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m Inlines
1573−doubleCloseQuote = B.str "\8221" <$ char '"'
1574−
1575−ellipses :: (Stream s m Char, UpdateSourcePos s Char)
1465+ellipses :: Stream s m Char
1576 => ParserT s st m Inlines
1466 => ParserT s st m Inlines
1577ellipses = try (string "..." >> return (B.str "\8230"))
1467ellipses = try (string "..." >> return (B.str "\8230"))
1578
1468
1579−dash :: (HasReaderOptions st, Stream s m Char, UpdateSourcePos s Char)
1469+dash :: (HasReaderOptions st, Stream s m Char)
1580 => ParserT s st m Inlines
1470 => ParserT s st m Inlines
1581dash = try $ do
1471dash = try $ do
1582 oldDashes <- extensionEnabled Ext_old_dashes <$> getOption readerExtensions
1472 oldDashes <- extensionEnabled Ext_old_dashes <$> getOption readerExtensions
@@ -1603,28 +1493,20 @@ nested p = do
1603 updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }
1493 updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }
1604 return res
1494 return res
1605
1495
1606−citeKey :: (Stream s m Char, UpdateSourcePos s Char, HasLastStrPosition st)
1496+citeKey :: (Stream s m Char, HasLastStrPosition st)
1607− => Bool -- ^ If True, allow expanded @{..} syntax.
1608− -> ParserT s st m (Bool, Text)
1497+ => ParserT s st m (Bool, Text)
1609−citeKey allowBraced = try $ do
1498+citeKey = try $ do
1610 guard =<< notAfterString
1499 guard =<< notAfterString
1611 suppress_author <- option False (True <$ char '-')
1500 suppress_author <- option False (True <$ char '-')
1612 char '@'
1501 char '@'
1613− key <- simpleCiteIdentifier
1614− <|> if allowBraced
1615− then charsInBalanced '{' '}' (satisfy (not . isSpace))
1616− else mzero
1617− return (suppress_author, key)
1618−
1619−simpleCiteIdentifier :: (Stream s m Char, UpdateSourcePos s Char)
1620− => ParserT s st m Text
1621−simpleCiteIdentifier = do
1622 firstChar <- alphaNum <|> char '_' <|> char '*' -- @* for wildcard in nocite
1502 firstChar <- alphaNum <|> char '_' <|> char '*' -- @* for wildcard in nocite
1623 let regchar = satisfy (\c -> isAlphaNum c || c == '_')
1503 let regchar = satisfy (\c -> isAlphaNum c || c == '_')
1624 let internal p = try $ p <* lookAhead regchar
1504 let internal p = try $ p <* lookAhead regchar
1625 rest <- many $ regchar <|> internal (oneOf ":.#$%&-+?<>~/") <|>
1505 rest <- many $ regchar <|> internal (oneOf ":.#$%&-+?<>~/") <|>
1626 try (oneOf ":/" <* lookAhead (char '/'))
1506 try (oneOf ":/" <* lookAhead (char '/'))
1507+ let key = firstChar:rest
1627− return $ T.pack $ firstChar:rest
1508+ return (suppress_author, T.pack key)
1509+
1628
1510
1629token :: (Stream s m t)
1511token :: (Stream s m t)
1630 => (t -> Text)
1512 => (t -> Text)
@@ -1644,15 +1526,12 @@ extractIdClass (ident, cls, kvs) = (ident', cls', kvs')
1644 cls' = maybe cls T.words $ lookup "class" kvs
1526 cls' = maybe cls T.words $ lookup "class" kvs
1645 kvs' = filter (\(k,_) -> k /= "id" || k /= "class") kvs
1527 kvs' = filter (\(k,_) -> k /= "id" || k /= "class") kvs
1646
1528
1647−insertIncludedFile :: (PandocMonad m, HasIncludeFiles st)
1529+insertIncludedFile' :: (PandocMonad m, HasIncludeFiles st)
1648− => ParserT a st m b -- ^ parser to apply
1530+ => ParserT a st m (mf Blocks)
1649− -> (Text -> a) -- ^ convert Text to stream type
1531+ -> (Text -> a)
1650− -> [FilePath] -- ^ search path (directories)
1532+ -> [FilePath] -> FilePath
1651− -> FilePath -- ^ path of file to include
1652− -> Maybe Int -- ^ start line (negative counts from end)
1653− -> Maybe Int -- ^ end line (negative counts from end)
1654− -> ParserT a st m b
1533+ -> ParserT a st m (mf Blocks)
1655−insertIncludedFile parser toStream dirs f mbstartline mbendline = do
1534+insertIncludedFile' blocks totoks dirs f = do
1656 oldPos <- getPosition
1535 oldPos <- getPosition
1657 oldInput <- getInput
1536 oldInput <- getInput
1658 containers <- getIncludeFiles <$> getState
1537 containers <- getIncludeFiles <$> getState
@@ -1661,32 +1540,32 @@ insertIncludedFile parser toStream dirs f mbstartline mbendline = do
1661 updateState $ addIncludeFile $ T.pack f
1540 updateState $ addIncludeFile $ T.pack f
1662 mbcontents <- readFileFromDirs dirs f
1541 mbcontents <- readFileFromDirs dirs f
1663 contents <- case mbcontents of
1542 contents <- case mbcontents of
1664− Just s -> return $ exciseLines mbstartline mbendline s
1543+ Just s -> return s
1665 Nothing -> do
1544 Nothing -> do
1666 report $ CouldNotLoadIncludeFile (T.pack f) oldPos
1545 report $ CouldNotLoadIncludeFile (T.pack f) oldPos
1667 return ""
1546 return ""
1668− setInput $ toStream contents
1669− setPosition $ newPos f (fromMaybe 1 mbstartline) 1
1547+ setPosition $ newPos f 1 1
1670− result <- parser
1548+ setInput $ totoks contents
1549+ bs <- blocks
1671 setInput oldInput
1550 setInput oldInput
1672 setPosition oldPos
1551 setPosition oldPos
1673 updateState dropLatestIncludeFile
1552 updateState dropLatestIncludeFile
1674− return result
1553+ return bs
1675−
1676−exciseLines :: Maybe Int -> Maybe Int -> Text -> Text
1677−exciseLines Nothing Nothing t = t
1678−exciseLines mbstartline mbendline t =
1679− T.unlines $ take (endline' - (startline' - 1))
1680− $ drop (startline' - 1) contentLines
1681− where
1682− contentLines = T.lines t
1683− numLines = length contentLines
1684− startline' = case mbstartline of
1685− Nothing -> 1
1686− Just x | x >= 0 -> x
1687− | otherwise -> numLines + x -- negative from end
1688− endline' = case mbendline of
1689− Nothing -> numLines
1690− Just x | x >= 0 -> x
1691− | otherwise -> numLines + x -- negative from end
1692
1554
1555+-- | Parse content of include file as blocks. Circular includes result in an
1556+-- @PandocParseError@.
1557+insertIncludedFile :: (PandocMonad m, HasIncludeFiles st)
1558+ => ParserT [a] st m Blocks
1559+ -> (Text -> [a])
1560+ -> [FilePath] -> FilePath
1561+ -> ParserT [a] st m Blocks
1562+insertIncludedFile blocks totoks dirs f =
1563+ runIdentity <$> insertIncludedFile' (Identity <$> blocks) totoks dirs f
1564+
1565+-- | Parse content of include file as future blocks. Circular includes result in
1566+-- an @PandocParseError@.
1567+insertIncludedFileF :: (PandocMonad m, HasIncludeFiles st)
1568+ => ParserT Text st m (Future st Blocks)
1569+ -> [FilePath] -> FilePath
1570+ -> ParserT Text st m (Future st Blocks)
1571+insertIncludedFileF p = insertIncludedFile' p id
src/Text/Pandoc/Readers.hs+48−55
@@ -1,5 +1,4 @@
1{-# LANGUAGE MonoLocalBinds #-}
1{-# LANGUAGE MonoLocalBinds #-}
2−{-# LANGUAGE RankNTypes #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
5{- |
4{- |
@@ -66,14 +65,12 @@ import Data.Aeson
66import qualified Data.ByteString.Lazy as BL
65import qualified Data.ByteString.Lazy as BL
67import Data.Text (Text)
66import Data.Text (Text)
68import qualified Data.Text as T
67import qualified Data.Text as T
69−import Text.Pandoc.Shared (tshow)
70import Text.Pandoc.Class
68import Text.Pandoc.Class
71import Text.Pandoc.Definition
69import Text.Pandoc.Definition
72import Text.Pandoc.Error
70import Text.Pandoc.Error
73import Text.Pandoc.Extensions
71import Text.Pandoc.Extensions
74import Text.Pandoc.Options
72import Text.Pandoc.Options
75import Text.Pandoc.Readers.CommonMark
73import Text.Pandoc.Readers.CommonMark
76−import Text.Pandoc.Readers.Markdown
77import Text.Pandoc.Readers.Creole
74import Text.Pandoc.Readers.Creole
78import Text.Pandoc.Readers.DocBook
75import Text.Pandoc.Readers.DocBook
79import Text.Pandoc.Readers.Docx
76import Text.Pandoc.Readers.Docx
@@ -86,6 +83,7 @@ import Text.Pandoc.Readers.HTML (readHtml)
86import Text.Pandoc.Readers.JATS (readJATS)
83import Text.Pandoc.Readers.JATS (readJATS)
87import Text.Pandoc.Readers.Jira (readJira)
84import Text.Pandoc.Readers.Jira (readJira)
88import Text.Pandoc.Readers.LaTeX
85import Text.Pandoc.Readers.LaTeX
86+import Text.Pandoc.Readers.Markdown
89import Text.Pandoc.Readers.MediaWiki
87import Text.Pandoc.Readers.MediaWiki
90import Text.Pandoc.Readers.Muse
88import Text.Pandoc.Readers.Muse
91import Text.Pandoc.Readers.Native
89import Text.Pandoc.Readers.Native
@@ -103,60 +101,59 @@ import Text.Pandoc.Readers.CSV
103import Text.Pandoc.Readers.CslJson
101import Text.Pandoc.Readers.CslJson
104import Text.Pandoc.Readers.BibTeX
102import Text.Pandoc.Readers.BibTeX
105import qualified Text.Pandoc.UTF8 as UTF8
103import qualified Text.Pandoc.UTF8 as UTF8
106−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
104+import Text.Parsec.Error
107
105
108−data Reader m = TextReader (forall a . ToSources a =>
109− ReaderOptions -> a -> m Pandoc)
106+data Reader m = TextReader (ReaderOptions -> Text -> m Pandoc)
110 | ByteStringReader (ReaderOptions -> BL.ByteString -> m Pandoc)
107 | ByteStringReader (ReaderOptions -> BL.ByteString -> m Pandoc)
111
108
112-- | Association list of formats and readers.
109-- | Association list of formats and readers.
113readers :: PandocMonad m => [(Text, Reader m)]
110readers :: PandocMonad m => [(Text, Reader m)]
114−readers = [("native" , TextReader readNative)
111+readers = [ ("native" , TextReader readNative)
115− ,("json" , TextReader readJSON)
112+ ,("json" , TextReader readJSON)
116− ,("markdown" , TextReader readMarkdown)
113+ ,("markdown" , TextReader readMarkdown)
117− ,("markdown_strict" , TextReader readMarkdown)
114+ ,("markdown_strict" , TextReader readMarkdown)
118− ,("markdown_phpextra" , TextReader readMarkdown)
115+ ,("markdown_phpextra" , TextReader readMarkdown)
119− ,("markdown_github" , TextReader readMarkdown)
116+ ,("markdown_github" , TextReader readMarkdown)
120− ,("markdown_mmd", TextReader readMarkdown)
117+ ,("markdown_mmd", TextReader readMarkdown)
121− ,("commonmark" , TextReader readCommonMark)
118+ ,("commonmark" , TextReader readCommonMark)
122− ,("commonmark_x" , TextReader readCommonMark)
119+ ,("commonmark_x" , TextReader readCommonMark)
123− ,("creole" , TextReader readCreole)
120+ ,("creole" , TextReader readCreole)
124− ,("dokuwiki" , TextReader readDokuWiki)
121+ ,("dokuwiki" , TextReader readDokuWiki)
125− ,("gfm" , TextReader readCommonMark)
122+ ,("gfm" , TextReader readCommonMark)
126− ,("rst" , TextReader readRST)
123+ ,("rst" , TextReader readRST)
127− ,("mediawiki" , TextReader readMediaWiki)
124+ ,("mediawiki" , TextReader readMediaWiki)
128− ,("vimwiki" , TextReader readVimwiki)
125+ ,("vimwiki" , TextReader readVimwiki)
129− ,("docbook" , TextReader readDocBook)
126+ ,("docbook" , TextReader readDocBook)
130− ,("opml" , TextReader readOPML)
127+ ,("opml" , TextReader readOPML)
131− ,("org" , TextReader readOrg)
128+ ,("org" , TextReader readOrg)
132− ,("textile" , TextReader readTextile) -- TODO : textile+lhs
129+ ,("textile" , TextReader readTextile) -- TODO : textile+lhs
133− ,("html" , TextReader readHtml)
130+ ,("html" , TextReader readHtml)
134− ,("jats" , TextReader readJATS)
131+ ,("jats" , TextReader readJATS)
135− ,("jira" , TextReader readJira)
132+ ,("jira" , TextReader readJira)
136− ,("latex" , TextReader readLaTeX)
133+ ,("latex" , TextReader readLaTeX)
137− ,("haddock" , TextReader readHaddock)
134+ ,("haddock" , TextReader readHaddock)
138− ,("twiki" , TextReader readTWiki)
135+ ,("twiki" , TextReader readTWiki)
139− ,("tikiwiki" , TextReader readTikiWiki)
136+ ,("tikiwiki" , TextReader readTikiWiki)
140− ,("docx" , ByteStringReader readDocx)
137+ ,("docx" , ByteStringReader readDocx)
141− ,("odt" , ByteStringReader readOdt)
138+ ,("odt" , ByteStringReader readOdt)
142− ,("t2t" , TextReader readTxt2Tags)
139+ ,("t2t" , TextReader readTxt2Tags)
143− ,("epub" , ByteStringReader readEPUB)
140+ ,("epub" , ByteStringReader readEPUB)
144− ,("muse" , TextReader readMuse)
141+ ,("muse" , TextReader readMuse)
145− ,("man" , TextReader readMan)
142+ ,("man" , TextReader readMan)
146− ,("fb2" , TextReader readFB2)
143+ ,("fb2" , TextReader readFB2)
147− ,("ipynb" , TextReader readIpynb)
144+ ,("ipynb" , TextReader readIpynb)
148− ,("csv" , TextReader readCSV)
145+ ,("csv" , TextReader readCSV)
149− ,("csljson" , TextReader readCslJson)
146+ ,("csljson" , TextReader readCslJson)
150− ,("bibtex" , TextReader readBibTeX)
147+ ,("bibtex" , TextReader readBibTeX)
151− ,("biblatex" , TextReader readBibLaTeX)
148+ ,("biblatex" , TextReader readBibLaTeX)
152 ]
149 ]
153
150
154-- | Retrieve reader, extensions based on formatSpec (format+extensions).
151-- | Retrieve reader, extensions based on formatSpec (format+extensions).
155getReader :: PandocMonad m => Text -> m (Reader m, Extensions)
152getReader :: PandocMonad m => Text -> m (Reader m, Extensions)
156getReader s =
153getReader s =
157 case parseFormatSpec s of
154 case parseFormatSpec s of
158− Left e -> throwError $ PandocAppError $
155+ Left e -> throwError $ PandocAppError
159− "Error parsing reader format " <> tshow s <> ": " <> tshow e
156+ $ T.intercalate "\n" [T.pack m | Message m <- errorMessages e]
160 Right (readerName, extsToEnable, extsToDisable) ->
157 Right (readerName, extsToEnable, extsToDisable) ->
161 case lookup readerName readers of
158 case lookup readerName readers of
162 Nothing -> throwError $ PandocUnknownReaderError
159 Nothing -> throwError $ PandocUnknownReaderError
@@ -176,13 +173,9 @@ getReader s =
176 return (r, exts)
173 return (r, exts)
177
174
178-- | Read pandoc document from JSON format.
175-- | Read pandoc document from JSON format.
179−readJSON :: (PandocMonad m, ToSources a)
176+readJSON :: PandocMonad m
180− => ReaderOptions
177+ => ReaderOptions -> Text -> m Pandoc
181− -> a
182− -> m Pandoc
183−readJSON _ s =
178+readJSON _ t =
184− case eitherDecode' . BL.fromStrict . UTF8.fromText
179+ case eitherDecode' . BL.fromStrict . UTF8.fromText $ t of
185− . sourcesToText . toSources $ s of
186 Right doc -> return doc
180 Right doc -> return doc
187− Left e -> throwError $ PandocParseError ("JSON parse error: "
181+ Left e -> throwError $ PandocParseError ("JSON parse error: " <> T.pack e)
188− <> T.pack e)
src/Text/Pandoc/Readers/BibTeX.hs+8−14
@@ -23,47 +23,41 @@ where
23import Text.Pandoc.Options
23import Text.Pandoc.Options
24import Text.Pandoc.Definition
24import Text.Pandoc.Definition
25import Text.Pandoc.Builder (setMeta, cite, str)
25import Text.Pandoc.Builder (setMeta, cite, str)
26+import Data.Text (Text)
26import Citeproc (Lang(..), parseLang)
27import Citeproc (Lang(..), parseLang)
27import Citeproc.Locale (getLocale)
28import Citeproc.Locale (getLocale)
28import Text.Pandoc.Error (PandocError(..))
29import Text.Pandoc.Error (PandocError(..))
29import Text.Pandoc.Class (PandocMonad, lookupEnv)
30import Text.Pandoc.Class (PandocMonad, lookupEnv)
30import Text.Pandoc.Citeproc.BibTeX as BibTeX
31import Text.Pandoc.Citeproc.BibTeX as BibTeX
31import Text.Pandoc.Citeproc.MetaValue (referenceToMetaValue)
32import Text.Pandoc.Citeproc.MetaValue (referenceToMetaValue)
32−import Text.Pandoc.Sources (ToSources(..))
33import Control.Monad.Except (throwError)
33import Control.Monad.Except (throwError)
34
34
35-- | Read BibTeX from an input string and return a Pandoc document.
35-- | Read BibTeX from an input string and return a Pandoc document.
36-- The document will have only metadata, with an empty body.
36-- The document will have only metadata, with an empty body.
37-- The metadata will contain a `references` field with the
37-- The metadata will contain a `references` field with the
38-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
38-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
39−readBibTeX :: (PandocMonad m, ToSources a)
40− => ReaderOptions -> a -> m Pandoc
39+readBibTeX :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
41readBibTeX = readBibTeX' BibTeX.Bibtex
40readBibTeX = readBibTeX' BibTeX.Bibtex
42
41
43-- | Read BibLaTeX from an input string and return a Pandoc document.
42-- | Read BibLaTeX from an input string and return a Pandoc document.
44-- The document will have only metadata, with an empty body.
43-- The document will have only metadata, with an empty body.
45-- The metadata will contain a `references` field with the
44-- The metadata will contain a `references` field with the
46-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
45-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
47−readBibLaTeX :: (PandocMonad m, ToSources a)
46+readBibLaTeX :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
48− => ReaderOptions -> a -> m Pandoc
49readBibLaTeX = readBibTeX' BibTeX.Biblatex
47readBibLaTeX = readBibTeX' BibTeX.Biblatex
50
48
51−readBibTeX' :: (PandocMonad m, ToSources a)
52− => Variant -> ReaderOptions -> a -> m Pandoc
49+readBibTeX' :: PandocMonad m => Variant -> ReaderOptions -> Text -> m Pandoc
53readBibTeX' variant _opts t = do
50readBibTeX' variant _opts t = do
54− mblangEnv <- lookupEnv "LANG"
51+ lang <- maybe (Lang "en" (Just "US")) parseLang
55− let defaultLang = Lang "en" Nothing (Just "US") [] [] []
52+ <$> lookupEnv "LANG"
56− let lang = case mblangEnv of
57− Nothing -> defaultLang
58− Just l -> either (const defaultLang) id $ parseLang l
59 locale <- case getLocale lang of
53 locale <- case getLocale lang of
60 Left e ->
54 Left e ->
61− case getLocale (Lang "en" Nothing (Just "US") [] [] []) of
55+ case getLocale (Lang "en" (Just "US")) of
62 Right l -> return l
56 Right l -> return l
63 Left _ -> throwError $ PandocCiteprocError e
57 Left _ -> throwError $ PandocCiteprocError e
64 Right l -> return l
58 Right l -> return l
65 case BibTeX.readBibtexString variant locale (const True) t of
59 case BibTeX.readBibtexString variant locale (const True) t of
66− Left e -> throwError $ PandocParsecError (toSources t) e
60+ Left e -> throwError $ PandocParsecError t e
67 Right refs -> return $ setMeta "references"
61 Right refs -> return $ setMeta "references"
68 (map referenceToMetaValue refs)
62 (map referenceToMetaValue refs)
69 . setMeta "nocite"
63 . setMeta "nocite"
src/Text/Pandoc/Readers/CSV.hs+7−7
@@ -13,23 +13,23 @@
13Conversion from CSV to a 'Pandoc' table.
13Conversion from CSV to a 'Pandoc' table.
14-}
14-}
15module Text.Pandoc.Readers.CSV ( readCSV ) where
15module Text.Pandoc.Readers.CSV ( readCSV ) where
16+import Data.Text (Text)
16import qualified Data.Text as T
17import qualified Data.Text as T
17import Text.Pandoc.CSV (parseCSV, defaultCSVOptions)
18import Text.Pandoc.CSV (parseCSV, defaultCSVOptions)
18import Text.Pandoc.Definition
19import Text.Pandoc.Definition
19import qualified Text.Pandoc.Builder as B
20import qualified Text.Pandoc.Builder as B
20import Text.Pandoc.Class (PandocMonad)
21import Text.Pandoc.Class (PandocMonad)
22+import Text.Pandoc.Shared (crFilter)
21import Text.Pandoc.Error
23import Text.Pandoc.Error
22−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
23import Text.Pandoc.Options (ReaderOptions)
24import Text.Pandoc.Options (ReaderOptions)
24import Control.Monad.Except (throwError)
25import Control.Monad.Except (throwError)
25
26
26−readCSV :: (PandocMonad m, ToSources a)
27+readCSV :: PandocMonad m
27 => ReaderOptions -- ^ Reader options
28 => ReaderOptions -- ^ Reader options
28− -> a
29+ -> Text -- ^ Text to parse (assuming @'\n'@ line endings)
29 -> m Pandoc
30 -> m Pandoc
30−readCSV _opts s = do
31+readCSV _opts s =
31− let txt = sourcesToText $ toSources s
32− case parseCSV defaultCSVOptions txt of
32+ case parseCSV defaultCSVOptions (crFilter s) of
33 Right (r:rs) -> return $ B.doc $ B.table capt
33 Right (r:rs) -> return $ B.doc $ B.table capt
34 (zip aligns widths)
34 (zip aligns widths)
35 (TableHead nullAttr hdrs)
35 (TableHead nullAttr hdrs)
@@ -45,4 +45,4 @@ readCSV _opts s = do
45 aligns = replicate numcols AlignDefault
45 aligns = replicate numcols AlignDefault
46 widths = replicate numcols ColWidthDefault
46 widths = replicate numcols ColWidthDefault
47 Right [] -> return $ B.doc mempty
47 Right [] -> return $ B.doc mempty
48− Left e -> throwError $ PandocParsecError (toSources [("",txt)]) e
48+ Left e -> throwError $ PandocParsecError s e
src/Text/Pandoc/Readers/CommonMark.hs+31−43
@@ -30,55 +30,45 @@ import Text.Pandoc.Readers.Metadata (yamlMetaBlock)
30import Control.Monad.Except
30import Control.Monad.Except
31import Data.Functor.Identity (runIdentity)
31import Data.Functor.Identity (runIdentity)
32import Data.Typeable
32import Data.Typeable
33−import Text.Pandoc.Parsing (runParserT, getInput,
33+import Text.Pandoc.Parsing (runParserT, getPosition, sourceLine,
34− runF, defaultParserState, option, many1, anyChar,
34+ runF, defaultParserState, take1WhileP, option)
35− Sources(..), ToSources(..), ParserT, Future,
36− sourceName)
37import qualified Data.Text as T
35import qualified Data.Text as T
38
36
39-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
37-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
40−readCommonMark :: (PandocMonad m, ToSources a)
38+readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
41− => ReaderOptions -> a -> m Pandoc
42readCommonMark opts s
39readCommonMark opts s
43− | isEnabled Ext_yaml_metadata_block opts = do
40+ | isEnabled Ext_yaml_metadata_block opts
44− let sources = toSources s
41+ , "---" `T.isPrefixOf` s = do
45− let toks = concatMap sourceToToks (unSources sources)
42+ let metaValueParser = do
43+ inp <- option "" $ take1WhileP (const True)
44+ case runIdentity
45+ (commonmarkWith (specFor opts) "metadata value" inp) of
46+ Left _ -> mzero
47+ Right (Cm bls :: Cm () Blocks)
48+ -> return $ return $ B.toMetaValue bls
46− res <- runParserT (do meta <- yamlMetaBlock (metaValueParser opts)
49+ res <- runParserT (do meta <- yamlMetaBlock metaValueParser
47− rest <- getInput
50+ pos <- getPosition
48− return (meta, rest))
51+ return (meta, pos))
49− defaultParserState "YAML metadata" (toSources s)
52+ defaultParserState "YAML metadata" s
50− case res of
53+ case res of
51− Left _ -> readCommonMarkBody opts sources toks
54+ Left _ -> readCommonMarkBody opts s
52− Right (meta, rest) -> do
55+ Right (meta, pos) -> do
53− -- strip off metadata section and parse body
56+ let dropLines 0 = id
54− let body = concatMap sourceToToks (unSources rest)
57+ dropLines n = dropLines (n - 1) . T.drop 1 . T.dropWhile (/='\n')
58+ let metaLines = sourceLine pos - 1
59+ let body = T.replicate metaLines "\n" <> dropLines metaLines s
55− Pandoc _ bs <- readCommonMarkBody opts sources body
60+ Pandoc _ bs <- readCommonMarkBody opts body
56− return $ Pandoc (runF meta defaultParserState) bs
61+ return $ Pandoc (runF meta defaultParserState) bs
57− | otherwise = do
58− let sources = toSources s
59− let toks = concatMap sourceToToks (unSources sources)
60− readCommonMarkBody opts sources toks
62+ | otherwise = readCommonMarkBody opts s
61
63
62−sourceToToks :: (SourcePos, Text) -> [Tok]
63−sourceToToks (pos, s) = tokenize (sourceName pos) s
64−
65−metaValueParser :: Monad m
66− => ReaderOptions -> ParserT Sources st m (Future st MetaValue)
67−metaValueParser opts = do
68− inp <- option "" $ T.pack <$> many1 anyChar
69− let toks = concatMap sourceToToks (unSources (toSources inp))
70− case runIdentity (parseCommonmarkWith (specFor opts) toks) of
71− Left _ -> mzero
72− Right (Cm bls :: Cm () Blocks) -> return $ return $ B.toMetaValue bls
73−
74−readCommonMarkBody :: PandocMonad m => ReaderOptions -> Sources -> [Tok] -> m Pandoc
64+readCommonMarkBody :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
75−readCommonMarkBody opts s toks
65+readCommonMarkBody opts s
76 | isEnabled Ext_sourcepos opts =
66 | isEnabled Ext_sourcepos opts =
77− case runIdentity (parseCommonmarkWith (specFor opts) toks) of
67+ case runIdentity (commonmarkWith (specFor opts) "" s) of
78 Left err -> throwError $ PandocParsecError s err
68 Left err -> throwError $ PandocParsecError s err
79 Right (Cm bls :: Cm SourceRange Blocks) -> return $ B.doc bls
69 Right (Cm bls :: Cm SourceRange Blocks) -> return $ B.doc bls
80 | otherwise =
70 | otherwise =
81− case runIdentity (parseCommonmarkWith (specFor opts) toks) of
71+ case runIdentity (commonmarkWith (specFor opts) "" s) of
82 Left err -> throwError $ PandocParsecError s err
72 Left err -> throwError $ PandocParsecError s err
83 Right (Cm bls :: Cm () Blocks) -> return $ B.doc bls
73 Right (Cm bls :: Cm () Blocks) -> return $ B.doc bls
84
74
@@ -112,7 +102,5 @@ specFor opts = foldr ($) defaultSyntaxSpec exts
112 | isEnabled Ext_implicit_header_references opts ] ++
102 | isEnabled Ext_implicit_header_references opts ] ++
113 [ (footnoteSpec <>) | isEnabled Ext_footnotes opts ] ++
103 [ (footnoteSpec <>) | isEnabled Ext_footnotes opts ] ++
114 [ (definitionListSpec <>) | isEnabled Ext_definition_lists opts ] ++
104 [ (definitionListSpec <>) | isEnabled Ext_definition_lists opts ] ++
115− [ (taskListSpec <>) | isEnabled Ext_task_lists opts ] ++
105+ [ (taskListSpec <>) | isEnabled Ext_task_lists opts ]
116− [ (rebaseRelativePathsSpec <>)
117− | isEnabled Ext_rebase_relative_paths opts ]
118
106
src/Text/Pandoc/Readers/Creole.hs+6−5
@@ -23,20 +23,21 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad (..))
23import Text.Pandoc.Definition
23import Text.Pandoc.Definition
24import Text.Pandoc.Options
24import Text.Pandoc.Options
25import Text.Pandoc.Parsing hiding (enclosed)
25import Text.Pandoc.Parsing hiding (enclosed)
26+import Text.Pandoc.Shared (crFilter)
27+
26
28
27-- | Read creole from an input string and return a Pandoc document.
29-- | Read creole from an input string and return a Pandoc document.
28−readCreole :: (PandocMonad m, ToSources a)
30+readCreole :: PandocMonad m
29 => ReaderOptions
31 => ReaderOptions
30− -> a
32+ -> Text
31 -> m Pandoc
33 -> m Pandoc
32readCreole opts s = do
34readCreole opts s = do
33− let sources = ensureFinalNewlines 2 (toSources s)
34− res <- readWithM parseCreole def{ stateOptions = opts } sources
35+ res <- readWithM parseCreole def{ stateOptions = opts } $ crFilter s <> "\n\n"
35 case res of
36 case res of
36 Left e -> throwError e
37 Left e -> throwError e
37 Right d -> return d
38 Right d -> return d
38
39
39−type CRLParser = ParserT Sources ParserState
40+type CRLParser = ParserT Text ParserState
40
41
41--
42--
42-- Utility functions
43-- Utility functions
src/Text/Pandoc/Readers/CslJson.hs+4−5
@@ -24,22 +24,21 @@ import Text.Pandoc.Options
24import Text.Pandoc.Definition
24import Text.Pandoc.Definition
25import Text.Pandoc.Builder (setMeta, cite, str)
25import Text.Pandoc.Builder (setMeta, cite, str)
26import qualified Text.Pandoc.UTF8 as UTF8
26import qualified Text.Pandoc.UTF8 as UTF8
27+import Data.Text (Text)
27import qualified Data.Text as T
28import qualified Data.Text as T
28import Text.Pandoc.Error (PandocError(..))
29import Text.Pandoc.Error (PandocError(..))
29import Text.Pandoc.Class (PandocMonad)
30import Text.Pandoc.Class (PandocMonad)
30import Text.Pandoc.Citeproc.CslJson (cslJsonToReferences)
31import Text.Pandoc.Citeproc.CslJson (cslJsonToReferences)
31import Text.Pandoc.Citeproc.MetaValue (referenceToMetaValue)
32import Text.Pandoc.Citeproc.MetaValue (referenceToMetaValue)
32import Control.Monad.Except (throwError)
33import Control.Monad.Except (throwError)
33−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
34
34
35-- | Read CSL JSON from an input string and return a Pandoc document.
35-- | Read CSL JSON from an input string and return a Pandoc document.
36-- The document will have only metadata, with an empty body.
36-- The document will have only metadata, with an empty body.
37-- The metadata will contain a `references` field with the
37-- The metadata will contain a `references` field with the
38-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
38-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
39−readCslJson :: (PandocMonad m, ToSources a)
40− => ReaderOptions -> a -> m Pandoc
39+readCslJson :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
41−readCslJson _opts x =
40+readCslJson _opts t =
42− case cslJsonToReferences (UTF8.fromText $ sourcesToText $ toSources x) of
41+ case cslJsonToReferences (UTF8.fromText t) of
43 Left e -> throwError $ PandocParseError $ T.pack e
42 Left e -> throwError $ PandocParseError $ T.pack e
44 Right refs -> return $ setMeta "references"
43 Right refs -> return $ setMeta "references"
45 (map referenceToMetaValue refs)
44 (map referenceToMetaValue refs)
src/Text/Pandoc/Readers/DocBook.hs+10−24
@@ -30,8 +30,7 @@ import Text.Pandoc.Builder
30import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
30import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
31import Text.Pandoc.Options
31import Text.Pandoc.Options
32import Text.Pandoc.Logging (LogMessage(..))
32import Text.Pandoc.Logging (LogMessage(..))
33−import Text.Pandoc.Shared (safeRead, extractSpaces)
33+import Text.Pandoc.Shared (crFilter, safeRead, extractSpaces)
34−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
35import Text.TeXMath (readMathML, writeTeX)
34import Text.TeXMath (readMathML, writeTeX)
36import Text.Pandoc.XML.Light
35import Text.Pandoc.XML.Light
37
36
@@ -134,7 +133,6 @@ List of all DocBook tags, with [x] indicating implemented,
134[ ] corpcredit - A corporation or organization credited in a document
133[ ] corpcredit - A corporation or organization credited in a document
135[ ] corpname - The name of a corporation
134[ ] corpname - The name of a corporation
136[ ] country - The name of a country
135[ ] country - The name of a country
137−[x] danger - An admonition set off from the text indicating hazardous situation
138[ ] database - The name of a database, or part of a database
136[ ] database - The name of a database, or part of a database
139[x] date - The date of publication or revision of a document
137[x] date - The date of publication or revision of a document
140[ ] dedication - A wrapper for the dedication section of a book
138[ ] dedication - A wrapper for the dedication section of a book
@@ -541,15 +539,11 @@ instance Default DBState where
541 , dbContent = [] }
539 , dbContent = [] }
542
540
543
541
544−readDocBook :: (PandocMonad m, ToSources a)
542+readDocBook :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
545− => ReaderOptions
546− -> a
547− -> m Pandoc
548readDocBook _ inp = do
543readDocBook _ inp = do
549− let sources = toSources inp
550 tree <- either (throwError . PandocXMLError "") return $
544 tree <- either (throwError . PandocXMLError "") return $
551 parseXMLContents
545 parseXMLContents
552− (TL.fromStrict . handleInstructions . sourcesToText $ sources)
546+ (TL.fromStrict . handleInstructions $ crFilter inp)
553 (bs, st') <- flip runStateT (def{ dbContent = tree }) $ mapM parseBlock tree
547 (bs, st') <- flip runStateT (def{ dbContent = tree }) $ mapM parseBlock tree
554 return $ Pandoc (dbMeta st') (toList . mconcat $ bs)
548 return $ Pandoc (dbMeta st') (toList . mconcat $ bs)
555
549
@@ -601,24 +595,16 @@ addMetadataFromElement e = do
601 Nothing -> return ()
595 Nothing -> return ()
602 Just z -> addMetaField "author" z
596 Just z -> addMetaField "author" z
603 addMetaField "subtitle" e
597 addMetaField "subtitle" e
604− addAuthor e
598+ addMetaField "author" e
605 addMetaField "date" e
599 addMetaField "date" e
606 addMetaField "release" e
600 addMetaField "release" e
607 addMetaField "releaseinfo" e
601 addMetaField "releaseinfo" e
608 return mempty
602 return mempty
609− where
610− addAuthor elt =
611− case filterChildren (named "author") elt of
612− [] -> return ()
613− [z] -> fromAuthor z >>= addMeta "author"
614− zs -> mapM fromAuthor zs >>= addMeta "author"
615− fromAuthor elt =
616− mconcat . intersperse space <$> mapM getInlines (elChildren elt)
617− addMetaField fieldname elt =
603+ where addMetaField fieldname elt =
618− case filterChildren (named fieldname) elt of
604+ case filterChildren (named fieldname) elt of
619− [] -> return ()
605+ [] -> return ()
620− [z] -> getInlines z >>= addMeta fieldname
606+ [z] -> getInlines z >>= addMeta fieldname
621− zs -> mapM getInlines zs >>= addMeta fieldname
607+ zs -> mapM getInlines zs >>= addMeta fieldname
622
608
623addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> DB m ()
609addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> DB m ()
624addMeta field val = modify (setMeta field val)
610addMeta field val = modify (setMeta field val)
@@ -719,7 +705,7 @@ blockTags =
719 ] ++ admonitionTags
705 ] ++ admonitionTags
720
706
721admonitionTags :: [Text]
707admonitionTags :: [Text]
722−admonitionTags = ["caution","danger","important","note","tip","warning"]
708+admonitionTags = ["important","caution","note","tip","warning"]
723
709
724-- Trim leading and trailing newline characters
710-- Trim leading and trailing newline characters
725trimNl :: Text -> Text
711trimNl :: Text -> Text
src/Text/Pandoc/Readers/Docx.hs+37−58
@@ -61,14 +61,13 @@ module Text.Pandoc.Readers.Docx
61import Codec.Archive.Zip
61import Codec.Archive.Zip
62import Control.Monad.Reader
62import Control.Monad.Reader
63import Control.Monad.State.Strict
63import Control.Monad.State.Strict
64−import Data.Bifunctor (bimap, first)
65import qualified Data.ByteString.Lazy as B
64import qualified Data.ByteString.Lazy as B
66import Data.Default (Default)
65import Data.Default (Default)
67−import Data.List (delete, intersect, foldl')
66+import Data.List (delete, intersect)
68import Data.Char (isSpace)
67import Data.Char (isSpace)
69import qualified Data.Map as M
68import qualified Data.Map as M
70import qualified Data.Text as T
69import qualified Data.Text as T
71−import Data.Maybe (catMaybes, isJust, fromMaybe)
70+import Data.Maybe (isJust, fromMaybe)
72import Data.Sequence (ViewL (..), viewl)
71import Data.Sequence (ViewL (..), viewl)
73import qualified Data.Sequence as Seq
72import qualified Data.Sequence as Seq
74import qualified Data.Set as Set
73import qualified Data.Set as Set
@@ -114,7 +113,6 @@ data DState = DState { docxAnchorMap :: M.Map T.Text T.Text
114 -- restarting
113 -- restarting
115 , docxListState :: M.Map (T.Text, T.Text) Integer
114 , docxListState :: M.Map (T.Text, T.Text) Integer
116 , docxPrevPara :: Inlines
115 , docxPrevPara :: Inlines
117− , docxTableCaptions :: [Blocks]
118 }
116 }
119
117
120instance Default DState where
118instance Default DState where
@@ -125,7 +123,6 @@ instance Default DState where
125 , docxDropCap = mempty
123 , docxDropCap = mempty
126 , docxListState = M.empty
124 , docxListState = M.empty
127 , docxPrevPara = mempty
125 , docxPrevPara = mempty
128− , docxTableCaptions = []
129 }
126 }
130
127
131data DEnv = DEnv { docxOptions :: ReaderOptions
128data DEnv = DEnv { docxOptions :: ReaderOptions
@@ -494,32 +491,15 @@ singleParaToPlain blks
494 singleton $ Plain ils
491 singleton $ Plain ils
495singleParaToPlain blks = blks
492singleParaToPlain blks = blks
496
493
497−cellToCell :: PandocMonad m => RowSpan -> Docx.Cell -> DocxContext m Pandoc.Cell
494+cellToBlocks :: PandocMonad m => Docx.Cell -> DocxContext m Blocks
498−cellToCell rowSpan (Docx.Cell gridSpan _ bps) = do
495+cellToBlocks (Docx.Cell bps) = do
499 blks <- smushBlocks <$> mapM bodyPartToBlocks bps
496 blks <- smushBlocks <$> mapM bodyPartToBlocks bps
500− let blks' = singleParaToPlain $ fromList $ blocksToDefinitions $ blocksToBullets $ toList blks
497+ return $ fromList $ blocksToDefinitions $ blocksToBullets $ toList blks
501− return (cell AlignDefault rowSpan (ColSpan (fromIntegral gridSpan)) blks')
502−
503−rowsToRows :: PandocMonad m => [Docx.Row] -> DocxContext m [Pandoc.Row]
504−rowsToRows rows = do
505− let rowspans = (fmap . fmap) (first RowSpan) (Docx.rowsToRowspans rows)
506− cells <- traverse (traverse (uncurry cellToCell)) rowspans
507− return (fmap (Pandoc.Row nullAttr) cells)
508−
509−splitHeaderRows :: Bool -> [Docx.Row] -> ([Docx.Row], [Docx.Row])
510−splitHeaderRows hasFirstRowFormatting rs = bimap reverse reverse $ fst
511− $ if hasFirstRowFormatting
512− then foldl' f ((take 1 rs, []), True) (drop 1 rs)
513− else foldl' f (([], []), False) rs
514− where
515− f ((headerRows, bodyRows), previousRowWasHeader) r@(Docx.Row h cs)
516− | h == HasTblHeader || (previousRowWasHeader && any isContinuationCell cs)
517− = ((r : headerRows, bodyRows), True)
518− | otherwise
519− = ((headerRows, r : bodyRows), False)
520−
521− isContinuationCell (Docx.Cell _ vm _) = vm == Docx.Continue
522
498
499+rowToBlocksList :: PandocMonad m => Docx.Row -> DocxContext m [Blocks]
500+rowToBlocksList (Docx.Row cells) = do
501+ blksList <- mapM cellToBlocks cells
502+ return $ map singleParaToPlain blksList
523
503
524-- like trimInlines, but also take out linebreaks
504-- like trimInlines, but also take out linebreaks
525trimSps :: Inlines -> Inlines
505trimSps :: Inlines -> Inlines
@@ -566,11 +546,6 @@ normalizeToClassName = T.map go . fromStyleName
566 where go c | isSpace c = '-'
546 where go c | isSpace c = '-'
567 | otherwise = c
547 | otherwise = c
568
548
569−bodyPartToTableCaption :: PandocMonad m => BodyPart -> DocxContext m (Maybe Blocks)
570−bodyPartToTableCaption (TblCaption pPr parparts) =
571− Just <$> bodyPartToBlocks (Paragraph pPr parparts)
572−bodyPartToTableCaption _ = pure Nothing
573−
574bodyPartToBlocks :: PandocMonad m => BodyPart -> DocxContext m Blocks
549bodyPartToBlocks :: PandocMonad m => BodyPart -> DocxContext m Blocks
575bodyPartToBlocks (Paragraph pPr parparts)
550bodyPartToBlocks (Paragraph pPr parparts)
576 | Just True <- pBidi pPr = do
551 | Just True <- pBidi pPr = do
@@ -662,43 +637,49 @@ bodyPartToBlocks (ListItem pPr _ _ _ parparts) =
662 let pPr' = pPr {pStyle = constructBogusParStyleData "list-paragraph": pStyle pPr}
637 let pPr' = pPr {pStyle = constructBogusParStyleData "list-paragraph": pStyle pPr}
663 in
638 in
664 bodyPartToBlocks $ Paragraph pPr' parparts
639 bodyPartToBlocks $ Paragraph pPr' parparts
665−bodyPartToBlocks (TblCaption _ _) =
666− return $ para mempty -- collected separately
667bodyPartToBlocks (Tbl _ _ _ []) =
640bodyPartToBlocks (Tbl _ _ _ []) =
668 return $ para mempty
641 return $ para mempty
669−bodyPartToBlocks (Tbl cap grid look parts) = do
642+bodyPartToBlocks (Tbl cap _ look parts@(r:rs)) = do
670− captions <- gets docxTableCaptions
643+ let cap' = simpleCaption $ plain $ text cap
671− fullCaption <- case captions of
644+ (hdr, rows) = case firstRowFormatting look of
672− c : cs -> do
645+ True | null rs -> (Nothing, [r])
673− modify (\s -> s { docxTableCaptions = cs })
646+ | otherwise -> (Just r, rs)
674− return c
647+ False -> (Nothing, r:rs)
675− [] -> return $ if T.null cap then mempty else plain (text cap)
648+
676− let shortCaption = if T.null cap then Nothing else Just (toList (text cap))
649+ cells <- mapM rowToBlocksList rows
677− cap' = caption shortCaption fullCaption
678− (hdr, rows) = splitHeaderRows (firstRowFormatting look) parts
679
650
680 let width = maybe 0 maximum $ nonEmpty $ map rowLength parts
651 let width = maybe 0 maximum $ nonEmpty $ map rowLength parts
681 rowLength :: Docx.Row -> Int
652 rowLength :: Docx.Row -> Int
682− rowLength (Docx.Row _ c) = sum (fmap (\(Docx.Cell gridSpan _ _) -> fromIntegral gridSpan) c)
653+ rowLength (Docx.Row c) = length c
683
654
684− headerCells <- rowsToRows hdr
655+ let toRow = Pandoc.Row nullAttr . map simpleCell
685− bodyCells <- rowsToRows rows
656+ toHeaderRow l = [toRow l | not (null l)]
686
657
687− -- Horizontal column alignment goes to the default at the moment. Getting
658+ -- pad cells. New Text.Pandoc.Builder will do that for us,
659+ -- so this is for compatibility while we switch over.
660+ let cells' = map (\row -> toRow $ take width (row ++ repeat mempty)) cells
661+
662+ hdrCells <- case hdr of
663+ Just r' -> toHeaderRow <$> rowToBlocksList r'
664+ Nothing -> return []
665+
666+ -- The two following variables (horizontal column alignment and
667+ -- relative column widths) go to the default at the
668+ -- moment. Width information is in the TblGrid field of the Tbl,
669+ -- so should be possible. Alignment might be more difficult,
688− -- it might be difficult, since there doesn't seem to be a column entity
670+ -- since there doesn't seem to be a column entity in docx.
689− -- in docx.
690 let alignments = replicate width AlignDefault
671 let alignments = replicate width AlignDefault
691− totalWidth = sum grid
672+ widths = replicate width ColWidthDefault
692− widths = (\w -> ColWidth (fromInteger w / fromInteger totalWidth)) <$> grid
693
673
694 return $ table cap'
674 return $ table cap'
695 (zip alignments widths)
675 (zip alignments widths)
696− (TableHead nullAttr headerCells)
676+ (TableHead nullAttr hdrCells)
697− [TableBody nullAttr 0 [] bodyCells]
677+ [TableBody nullAttr 0 [] cells']
698 (TableFoot nullAttr [])
678 (TableFoot nullAttr [])
699bodyPartToBlocks (OMathPara e) =
679bodyPartToBlocks (OMathPara e) =
700 return $ para $ displayMath (writeTeX e)
680 return $ para $ displayMath (writeTeX e)
701
681
682+
702-- replace targets with generated anchors.
683-- replace targets with generated anchors.
703rewriteLink' :: PandocMonad m => Inline -> DocxContext m Inline
684rewriteLink' :: PandocMonad m => Inline -> DocxContext m Inline
704rewriteLink' l@(Link attr ils (T.uncons -> Just ('#',target), title)) = do
685rewriteLink' l@(Link attr ils (T.uncons -> Just ('#',target), title)) = do
@@ -734,8 +715,6 @@ bodyToOutput :: PandocMonad m => Body -> DocxContext m (Meta, [Block])
734bodyToOutput (Body bps) = do
715bodyToOutput (Body bps) = do
735 let (metabps, blkbps) = sepBodyParts bps
716 let (metabps, blkbps) = sepBodyParts bps
736 meta <- bodyPartsToMeta metabps
717 meta <- bodyPartsToMeta metabps
737− captions <- catMaybes <$> mapM bodyPartToTableCaption blkbps
738− modify (\s -> s { docxTableCaptions = captions })
739 blks <- smushBlocks <$> mapM bodyPartToBlocks blkbps
718 blks <- smushBlocks <$> mapM bodyPartToBlocks blkbps
740 blks' <- rewriteLinks $ blocksToDefinitions $ blocksToBullets $ toList blks
719 blks' <- rewriteLinks $ blocksToDefinitions $ blocksToBullets $ toList blks
741 blks'' <- removeOrphanAnchors blks'
720 blks'' <- removeOrphanAnchors blks'
src/Text/Pandoc/Readers/Docx/Combine.hs+3−3
@@ -61,7 +61,7 @@ import Data.List
61import Data.Bifunctor
61import Data.Bifunctor
62import Data.Sequence ( ViewL (..), ViewR (..), viewl, viewr, spanr, spanl
62import Data.Sequence ( ViewL (..), ViewR (..), viewl, viewr, spanr, spanl
63 , (><), (|>) )
63 , (><), (|>) )
64−import Text.Pandoc.Builder as B
64+import Text.Pandoc.Builder
65
65
66data Modifier a = Modifier (a -> a)
66data Modifier a = Modifier (a -> a)
67 | AttrModifier (Attr -> a -> a) Attr
67 | AttrModifier (Attr -> a -> a) Attr
@@ -116,12 +116,12 @@ ilModifierAndInnards ils = case viewl $ unMany ils of
116
116
117inlinesL :: Inlines -> (Inlines, Inlines)
117inlinesL :: Inlines -> (Inlines, Inlines)
118inlinesL ils = case viewl $ unMany ils of
118inlinesL ils = case viewl $ unMany ils of
119− (s :< sq) -> (B.singleton s, Many sq)
119+ (s :< sq) -> (singleton s, Many sq)
120 _ -> (mempty, ils)
120 _ -> (mempty, ils)
121
121
122inlinesR :: Inlines -> (Inlines, Inlines)
122inlinesR :: Inlines -> (Inlines, Inlines)
123inlinesR ils = case viewr $ unMany ils of
123inlinesR ils = case viewr $ unMany ils of
124− (sq :> s) -> (Many sq, B.singleton s)
124+ (sq :> s) -> (Many sq, singleton s)
125 _ -> (ils, mempty)
125 _ -> (ils, mempty)
126
126
127combineInlines :: Inlines -> Inlines -> Inlines
127combineInlines :: Inlines -> Inlines -> Inlines
src/Text/Pandoc/Readers/Docx/Parse.hs+21−121
@@ -33,9 +33,7 @@ module Text.Pandoc.Readers.Docx.Parse ( Docx(..)
33 , ParStyle
33 , ParStyle
34 , CharStyle(cStyleData)
34 , CharStyle(cStyleData)
35 , Row(..)
35 , Row(..)
36− , TblHeader(..)
37 , Cell(..)
36 , Cell(..)
38− , VMerge(..)
39 , TrackedChange(..)
37 , TrackedChange(..)
40 , ChangeType(..)
38 , ChangeType(..)
41 , ChangeInfo(..)
39 , ChangeInfo(..)
@@ -52,7 +50,6 @@ module Text.Pandoc.Readers.Docx.Parse ( Docx(..)
52 , pHeading
50 , pHeading
53 , constructBogusParStyleData
51 , constructBogusParStyleData
54 , leftBiasedMergeRunStyle
52 , leftBiasedMergeRunStyle
55− , rowsToRowspans
56 ) where
53 ) where
57import Text.Pandoc.Readers.Docx.Parse.Styles
54import Text.Pandoc.Readers.Docx.Parse.Styles
58import Codec.Archive.Zip
55import Codec.Archive.Zip
@@ -228,7 +225,6 @@ defaultParagraphStyle = ParagraphStyle { pStyle = []
228data BodyPart = Paragraph ParagraphStyle [ParPart]
225data BodyPart = Paragraph ParagraphStyle [ParPart]
229 | ListItem ParagraphStyle T.Text T.Text (Maybe Level) [ParPart]
226 | ListItem ParagraphStyle T.Text T.Text (Maybe Level) [ParPart]
230 | Tbl T.Text TblGrid TblLook [Row]
227 | Tbl T.Text TblGrid TblLook [Row]
231− | TblCaption ParagraphStyle [ParPart]
232 | OMathPara [Exp]
228 | OMathPara [Exp]
233 deriving Show
229 deriving Show
234
230
@@ -240,61 +236,12 @@ newtype TblLook = TblLook {firstRowFormatting::Bool}
240defaultTblLook :: TblLook
236defaultTblLook :: TblLook
241defaultTblLook = TblLook{firstRowFormatting = False}
237defaultTblLook = TblLook{firstRowFormatting = False}
242
238
243−data Row = Row TblHeader [Cell] deriving Show
239+newtype Row = Row [Cell]
244−
240+ deriving Show
245−data TblHeader = HasTblHeader | NoTblHeader deriving (Show, Eq)
246
241
247−data Cell = Cell GridSpan VMerge [BodyPart]
242+newtype Cell = Cell [BodyPart]
248 deriving Show
243 deriving Show
249
244
250−type GridSpan = Integer
251−
252−data VMerge = Continue
253− -- ^ This cell should be merged with the one above it
254− | Restart
255− -- ^ This cell should not be merged with the one above it
256− deriving (Show, Eq)
257−
258−rowsToRowspans :: [Row] -> [[(Int, Cell)]]
259−rowsToRowspans rows = let
260− removeMergedCells = fmap (filter (\(_, Cell _ vmerge _) -> vmerge == Restart))
261− in removeMergedCells (foldr f [] rows)
262− where
263− f :: Row -> [[(Int, Cell)]] -> [[(Int, Cell)]]
264− f (Row _ cells) acc = let
265− spans = g cells Nothing (listToMaybe acc)
266− in spans : acc
267−
268− g ::
269− -- | The current row
270− [Cell] ->
271− -- | Number of columns left below
272− Maybe Integer ->
273− -- | (rowspan so far, cell) for the row below this one
274− Maybe [(Int, Cell)] ->
275− -- | (rowspan so far, cell) for this row
276− [(Int, Cell)]
277− g cells _ Nothing = zip (repeat 1) cells
278− g cells columnsLeftBelow (Just rowBelow) =
279− case cells of
280− [] -> []
281− thisCell@(Cell thisGridSpan _ _) : restOfRow -> case rowBelow of
282− [] -> zip (repeat 1) cells
283− (spanSoFarBelow, Cell gridSpanBelow vmerge _) : _ ->
284− let spanSoFar = case vmerge of
285− Restart -> 1
286− Continue -> 1 + spanSoFarBelow
287− columnsToDrop = thisGridSpan + (gridSpanBelow - fromMaybe gridSpanBelow columnsLeftBelow)
288− (newColumnsLeftBelow, restOfRowBelow) = dropColumns columnsToDrop rowBelow
289− in (spanSoFar, thisCell) : g restOfRow (Just newColumnsLeftBelow) (Just restOfRowBelow)
290−
291− dropColumns :: Integer -> [(a, Cell)] -> (Integer, [(a, Cell)])
292− dropColumns n [] = (n, [])
293− dropColumns n cells@((_, Cell gridSpan _ _) : otherCells) =
294− if n < gridSpan
295− then (gridSpan - n, cells)
296− else dropColumns (n - gridSpan) otherCells
297−
298leftBiasedMergeRunStyle :: RunStyle -> RunStyle -> RunStyle
245leftBiasedMergeRunStyle :: RunStyle -> RunStyle -> RunStyle
299leftBiasedMergeRunStyle a b = RunStyle
246leftBiasedMergeRunStyle a b = RunStyle
300 { isBold = isBold a <|> isBold b
247 { isBold = isBold a <|> isBold b
@@ -479,26 +426,20 @@ filePathToRelType path docXmlPath =
479 then Just InDocument
426 then Just InDocument
480 else Nothing
427 else Nothing
481
428
482−relElemToRelationship :: FilePath -> DocumentLocation -> Element
429+relElemToRelationship :: DocumentLocation -> Element -> Maybe Relationship
483− -> Maybe Relationship
484−relElemToRelationship fp relType element | qName (elName element) == "Relationship" =
430+relElemToRelationship relType element | qName (elName element) == "Relationship" =
485 do
431 do
486 relId <- findAttr (QName "Id" Nothing Nothing) element
432 relId <- findAttr (QName "Id" Nothing Nothing) element
487 target <- findAttr (QName "Target" Nothing Nothing) element
433 target <- findAttr (QName "Target" Nothing Nothing) element
488− -- target may be relative (media/image1.jpeg) or absolute
489− -- (/word/media/image1.jpeg); we need to relativize it (see #7374)
490− let frontOfFp = T.pack $ takeWhile (/= '_') fp
491− let target' = fromMaybe target $
492− T.stripPrefix frontOfFp $ T.dropWhile (== '/') target
493− return $ Relationship relType relId target'
434+ return $ Relationship relType relId target
494−relElemToRelationship _ _ _ = Nothing
435+relElemToRelationship _ _ = Nothing
495
436
496filePathToRelationships :: Archive -> FilePath -> FilePath -> [Relationship]
437filePathToRelationships :: Archive -> FilePath -> FilePath -> [Relationship]
497filePathToRelationships ar docXmlPath fp
438filePathToRelationships ar docXmlPath fp
498 | Just relType <- filePathToRelType fp docXmlPath
439 | Just relType <- filePathToRelType fp docXmlPath
499 , Just entry <- findEntryByPath fp ar
440 , Just entry <- findEntryByPath fp ar
500 , Just relElems <- parseXMLFromEntry entry =
441 , Just relElems <- parseXMLFromEntry entry =
501− mapMaybe (relElemToRelationship fp relType) $ elChildren relElems
442+ mapMaybe (relElemToRelationship relType) $ elChildren relElems
502filePathToRelationships _ _ _ = []
443filePathToRelationships _ _ _ = []
503
444
504archiveToRelationships :: Archive -> FilePath -> [Relationship]
445archiveToRelationships :: Archive -> FilePath -> [Relationship]
@@ -622,7 +563,7 @@ elemToTblGrid :: NameSpaces -> Element -> D TblGrid
622elemToTblGrid ns element | isElem ns "w" "tblGrid" element =
563elemToTblGrid ns element | isElem ns "w" "tblGrid" element =
623 let cols = findChildrenByName ns "w" "gridCol" element
564 let cols = findChildrenByName ns "w" "gridCol" element
624 in
565 in
625− mapD (\e -> maybeToD (findAttrByName ns "w" "w" e >>= stringToInteger))
566+ mapD (\e -> maybeToD (findAttrByName ns "w" "val" e >>= stringToInteger))
626 cols
567 cols
627elemToTblGrid _ _ = throwError WrongElem
568elemToTblGrid _ _ = throwError WrongElem
628
569
@@ -646,31 +587,14 @@ elemToRow ns element | isElem ns "w" "tr" element =
646 do
587 do
647 let cellElems = findChildrenByName ns "w" "tc" element
588 let cellElems = findChildrenByName ns "w" "tc" element
648 cells <- mapD (elemToCell ns) cellElems
589 cells <- mapD (elemToCell ns) cellElems
649− let hasTblHeader = maybe NoTblHeader (const HasTblHeader)
650− (findChildByName ns "w" "trPr" element
651− >>= findChildByName ns "w" "tblHeader")
652− return $ Row hasTblHeader cells
590+ return $ Row cells
653elemToRow _ _ = throwError WrongElem
591elemToRow _ _ = throwError WrongElem
654
592
655elemToCell :: NameSpaces -> Element -> D Cell
593elemToCell :: NameSpaces -> Element -> D Cell
656elemToCell ns element | isElem ns "w" "tc" element =
594elemToCell ns element | isElem ns "w" "tc" element =
657 do
595 do
658− let properties = findChildByName ns "w" "tcPr" element
659− let gridSpan = properties
660− >>= findChildByName ns "w" "gridSpan"
661− >>= findAttrByName ns "w" "val"
662− >>= stringToInteger
663− let vMerge = case properties >>= findChildByName ns "w" "vMerge" of
664− Nothing -> Restart
665− Just e ->
666− fromMaybe Continue $ do
667− s <- findAttrByName ns "w" "val" e
668− case s of
669− "continue" -> Just Continue
670− "restart" -> Just Restart
671− _ -> Nothing
672 cellContents <- mapD (elemToBodyPart ns) (elChildren element)
596 cellContents <- mapD (elemToBodyPart ns) (elChildren element)
673− return $ Cell (fromMaybe 1 gridSpan) vMerge cellContents
597+ return $ Cell cellContents
674elemToCell _ _ = throwError WrongElem
598elemToCell _ _ = throwError WrongElem
675
599
676elemToParIndentation :: NameSpaces -> Element -> Maybe ParIndentation
600elemToParIndentation :: NameSpaces -> Element -> Maybe ParIndentation
@@ -702,9 +626,10 @@ pNumInfo = getParStyleField numInfo . pStyle
702elemToBodyPart :: NameSpaces -> Element -> D BodyPart
626elemToBodyPart :: NameSpaces -> Element -> D BodyPart
703elemToBodyPart ns element
627elemToBodyPart ns element
704 | isElem ns "w" "p" element
628 | isElem ns "w" "p" element
705− , (c:_) <- findChildrenByName ns "m" "oMathPara" element = do
629+ , (c:_) <- findChildrenByName ns "m" "oMathPara" element =
630+ do
706− expsLst <- eitherToD $ readOMML $ showElement c
631+ expsLst <- eitherToD $ readOMML $ showElement c
707− return $ OMathPara expsLst
632+ return $ OMathPara expsLst
708elemToBodyPart ns element
633elemToBodyPart ns element
709 | isElem ns "w" "p" element
634 | isElem ns "w" "p" element
710 , Just (numId, lvl) <- getNumInfo ns element = do
635 , Just (numId, lvl) <- getNumInfo ns element = do
@@ -722,31 +647,13 @@ elemToBodyPart ns element
722 Nothing | Just (numId, lvl) <- pNumInfo parstyle -> do
647 Nothing | Just (numId, lvl) <- pNumInfo parstyle -> do
723 levelInfo <- lookupLevel numId lvl <$> asks envNumbering
648 levelInfo <- lookupLevel numId lvl <$> asks envNumbering
724 return $ ListItem parstyle numId lvl levelInfo parparts
649 return $ ListItem parstyle numId lvl levelInfo parparts
725− _ -> let
726− hasCaptionStyle = elem "Caption" (pStyleId <$> pStyle parstyle)
727−
728− hasSimpleTableField = fromMaybe False $ do
729− fldSimple <- findChildByName ns "w" "fldSimple" element
730− instr <- findAttrByName ns "w" "instr" fldSimple
731− pure ("Table" `elem` T.words instr)
732−
733− hasComplexTableField = fromMaybe False $ do
734− instrText <- findElementByName ns "w" "instrText" element
735− pure ("Table" `elem` T.words (strContent instrText))
736−
737− in if hasCaptionStyle && (hasSimpleTableField || hasComplexTableField)
738− then return $ TblCaption parstyle parparts
739− else return $ Paragraph parstyle parparts
650+ _ -> return $ Paragraph parstyle parparts
740−
741elemToBodyPart ns element
651elemToBodyPart ns element
742 | isElem ns "w" "tbl" element = do
652 | isElem ns "w" "tbl" element = do
743− let tblProperties = findChildByName ns "w" "tblPr" element
653+ let caption' = findChildByName ns "w" "tblPr" element
744− caption = fromMaybe "" $ tblProperties
745 >>= findChildByName ns "w" "tblCaption"
654 >>= findChildByName ns "w" "tblCaption"
746 >>= findAttrByName ns "w" "val"
655 >>= findAttrByName ns "w" "val"
747− description = fromMaybe "" $ tblProperties
656+ caption = fromMaybe "" caption'
748− >>= findChildByName ns "w" "tblDescription"
749− >>= findAttrByName ns "w" "val"
750 grid' = case findChildByName ns "w" "tblGrid" element of
657 grid' = case findChildByName ns "w" "tblGrid" element of
751 Just g -> elemToTblGrid ns g
658 Just g -> elemToTblGrid ns g
752 Nothing -> return []
659 Nothing -> return []
@@ -759,7 +666,7 @@ elemToBodyPart ns element
759 grid <- grid'
666 grid <- grid'
760 tblLook <- tblLook'
667 tblLook <- tblLook'
761 rows <- mapD (elemToRow ns) (elChildren element)
668 rows <- mapD (elemToRow ns) (elChildren element)
762− return $ Tbl (caption <> description) grid tblLook rows
669+ return $ Tbl caption grid tblLook rows
763elemToBodyPart _ _ = throwError WrongElem
670elemToBodyPart _ _ = throwError WrongElem
764
671
765lookupRelationship :: DocumentLocation -> RelId -> [Relationship] -> Maybe Target
672lookupRelationship :: DocumentLocation -> RelId -> [Relationship] -> Maybe Target
@@ -802,8 +709,7 @@ elemToParPart ns element
802 case drawing of
709 case drawing of
803 Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp title alt bs $ elemToExtent drawingElem)
710 Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp title alt bs $ elemToExtent drawingElem)
804 Nothing -> throwError WrongElem
711 Nothing -> throwError WrongElem
805−-- The two cases below are an attempt to deal with images in deprecated vml format.
712+-- The below is an attempt to deal with images in deprecated vml format.
806−-- Todo: check out title and attr for deprecated format.
807elemToParPart ns element
713elemToParPart ns element
808 | isElem ns "w" "r" element
714 | isElem ns "w" "r" element
809 , Just _ <- findChildByName ns "w" "pict" element =
715 , Just _ <- findChildByName ns "w" "pict" element =
@@ -811,15 +717,9 @@ elemToParPart ns element
811 >>= findAttrByName ns "r" "id"
717 >>= findAttrByName ns "r" "id"
812 in
718 in
813 case drawing of
719 case drawing of
720+ -- Todo: check out title and attr for deprecated format.
814 Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
721 Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
815 Nothing -> throwError WrongElem
722 Nothing -> throwError WrongElem
816−elemToParPart ns element
817− | isElem ns "w" "r" element
818− , Just objectElem <- findChildByName ns "w" "object" element
819− , Just shapeElem <- findChildByName ns "v" "shape" objectElem
820− , Just imagedataElem <- findChildByName ns "v" "imagedata" shapeElem
821− , Just drawingId <- findAttrByName ns "r" "id" imagedataElem
822− = expandDrawingId drawingId >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
823-- Chart
723-- Chart
824elemToParPart ns element
724elemToParPart ns element
825 | isElem ns "w" "r" element
725 | isElem ns "w" "r" element
src/Text/Pandoc/Readers/Docx/Util.hs−7
@@ -19,7 +19,6 @@ module Text.Pandoc.Readers.Docx.Util (
19 , elemToNameSpaces
19 , elemToNameSpaces
20 , findChildByName
20 , findChildByName
21 , findChildrenByName
21 , findChildrenByName
22− , findElementByName
23 , findAttrByName
22 , findAttrByName
24 ) where
23 ) where
25
24
@@ -57,12 +56,6 @@ findChildrenByName ns pref name el =
57 let ns' = ns <> elemToNameSpaces el
56 let ns' = ns <> elemToNameSpaces el
58 in findChildren (elemName ns' pref name) el
57 in findChildren (elemName ns' pref name) el
59
58
60−-- | Like 'findChildrenByName', but searches descendants.
61−findElementByName :: NameSpaces -> Text -> Text -> Element -> Maybe Element
62−findElementByName ns pref name el =
63− let ns' = ns <> elemToNameSpaces el
64− in findElement (elemName ns' pref name) el
65−
66findAttrByName :: NameSpaces -> Text -> Text -> Element -> Maybe Text
59findAttrByName :: NameSpaces -> Text -> Text -> Element -> Maybe Text
67findAttrByName ns pref name el =
60findAttrByName ns pref name el =
68 let ns' = ns <> elemToNameSpaces el
61 let ns' = ns <> elemToNameSpaces el
src/Text/Pandoc/Readers/DokuWiki.hs+8−9
@@ -29,27 +29,26 @@ import Text.Pandoc.Definition
29import Text.Pandoc.Error (PandocError (PandocParsecError))
29import Text.Pandoc.Error (PandocError (PandocParsecError))
30import Text.Pandoc.Options
30import Text.Pandoc.Options
31import Text.Pandoc.Parsing hiding (enclosed, nested)
31import Text.Pandoc.Parsing hiding (enclosed, nested)
32−import Text.Pandoc.Shared (trim, stringify, tshow)
32+import Text.Pandoc.Shared (crFilter, trim, stringify, tshow)
33
33
34-- | Read DokuWiki from an input string and return a Pandoc document.
34-- | Read DokuWiki from an input string and return a Pandoc document.
35−readDokuWiki :: (PandocMonad m, ToSources a)
35+readDokuWiki :: PandocMonad m
36 => ReaderOptions
36 => ReaderOptions
37− -> a
37+ -> Text
38 -> m Pandoc
38 -> m Pandoc
39readDokuWiki opts s = do
39readDokuWiki opts s = do
40− let sources = toSources s
40+ let input = crFilter s
41− res <- runParserT parseDokuWiki def {stateOptions = opts }
41+ res <- runParserT parseDokuWiki def {stateOptions = opts } "source" input
42− (initialSourceName sources) sources
43 case res of
42 case res of
44− Left e -> throwError $ PandocParsecError sources e
43+ Left e -> throwError $ PandocParsecError input e
45 Right d -> return d
44 Right d -> return d
46
45
47−type DWParser = ParserT Sources ParserState
46+type DWParser = ParserT Text ParserState
48
47
49-- * Utility functions
48-- * Utility functions
50
49
51-- | Parse end-of-line, which can be either a newline or end-of-file.
50-- | Parse end-of-line, which can be either a newline or end-of-file.
52−eol :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m ()
51+eol :: Stream s m Char => ParserT s st m ()
53eol = void newline <|> eof
52eol = void newline <|> eof
54
53
55nested :: PandocMonad m => DWParser m a -> DWParser m a
54nested :: PandocMonad m => DWParser m a -> DWParser m a
src/Text/Pandoc/Readers/FB2.hs+3−6
@@ -40,9 +40,9 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad, insertMedia, report)
40import Text.Pandoc.Error
40import Text.Pandoc.Error
41import Text.Pandoc.Logging
41import Text.Pandoc.Logging
42import Text.Pandoc.Options
42import Text.Pandoc.Options
43+import Text.Pandoc.Shared (crFilter)
43import Text.Pandoc.XML.Light
44import Text.Pandoc.XML.Light
44import qualified Text.Pandoc.UTF8 as UTF8
45import qualified Text.Pandoc.UTF8 as UTF8
45−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
46
46
47type FB2 m = StateT FB2State m
47type FB2 m = StateT FB2State m
48
48
@@ -63,12 +63,9 @@ instance HasMeta FB2State where
63 setMeta field v s = s {fb2Meta = setMeta field v (fb2Meta s)}
63 setMeta field v s = s {fb2Meta = setMeta field v (fb2Meta s)}
64 deleteMeta field s = s {fb2Meta = deleteMeta field (fb2Meta s)}
64 deleteMeta field s = s {fb2Meta = deleteMeta field (fb2Meta s)}
65
65
66−readFB2 :: (PandocMonad m, ToSources a)
66+readFB2 :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
67− => ReaderOptions
68− -> a
69− -> m Pandoc
70readFB2 _ inp =
67readFB2 _ inp =
71− case parseXMLElement $ TL.fromStrict $ sourcesToText $ toSources inp of
68+ case parseXMLElement $ TL.fromStrict $ crFilter inp of
72 Left msg -> throwError $ PandocXMLError "" msg
69 Left msg -> throwError $ PandocXMLError "" msg
73 Right el -> do
70 Right el -> do
74 (bs, st) <- runStateT (parseRootElement el) def
71 (bs, st) <- runStateT (parseRootElement el) def
src/Text/Pandoc/Readers/HTML.hs+27−43
@@ -62,21 +62,21 @@ import Text.Pandoc.Options (
62 extensionEnabled)
62 extensionEnabled)
63import Text.Pandoc.Parsing hiding ((<|>))
63import Text.Pandoc.Parsing hiding ((<|>))
64import Text.Pandoc.Shared (
64import Text.Pandoc.Shared (
65− addMetaField, blocksToInlines', escapeURI, extractSpaces,
65+ addMetaField, blocksToInlines', crFilter, escapeURI, extractSpaces,
66 htmlSpanLikeElements, renderTags', safeRead, tshow)
66 htmlSpanLikeElements, renderTags', safeRead, tshow)
67import Text.Pandoc.Walk
67import Text.Pandoc.Walk
68import Text.Parsec.Error
68import Text.Parsec.Error
69import Text.TeXMath (readMathML, writeTeX)
69import Text.TeXMath (readMathML, writeTeX)
70
70
71-- | Convert HTML-formatted string to 'Pandoc' document.
71-- | Convert HTML-formatted string to 'Pandoc' document.
72−readHtml :: (PandocMonad m, ToSources a)
72+readHtml :: PandocMonad m
73 => ReaderOptions -- ^ Reader options
73 => ReaderOptions -- ^ Reader options
74− -> a -- ^ Input to parse
74+ -> Text -- ^ String to parse (assumes @'\n'@ line endings)
75 -> m Pandoc
75 -> m Pandoc
76readHtml opts inp = do
76readHtml opts inp = do
77 let tags = stripPrefixes $ canonicalizeTags $
77 let tags = stripPrefixes $ canonicalizeTags $
78 parseTagsOptions parseOptions{ optTagPosition = True }
78 parseTagsOptions parseOptions{ optTagPosition = True }
79− (sourcesToText $ toSources inp)
79+ (crFilter inp)
80 parseDoc = do
80 parseDoc = do
81 blocks <- fixPlains False . mconcat <$> manyTill block eof
81 blocks <- fixPlains False . mconcat <$> manyTill block eof
82 meta <- stateMeta . parserState <$> getState
82 meta <- stateMeta . parserState <$> getState
@@ -205,7 +205,6 @@ block = ((do
205 | otherwise
205 | otherwise
206 -> pDiv
206 -> pDiv
207 "section" -> pDiv
207 "section" -> pDiv
208− "header" -> pDiv
209 "main" -> pDiv
208 "main" -> pDiv
210 "figure" -> pFigure
209 "figure" -> pFigure
211 "iframe" -> pIframe
210 "iframe" -> pIframe
@@ -405,7 +404,6 @@ pLineBlock = try $ do
405isDivLike :: Text -> Bool
404isDivLike :: Text -> Bool
406isDivLike "div" = True
405isDivLike "div" = True
407isDivLike "section" = True
406isDivLike "section" = True
408−isDivLike "header" = True
409isDivLike "main" = True
407isDivLike "main" = True
410isDivLike _ = False
408isDivLike _ = False
411
409
@@ -501,13 +499,17 @@ pHeader = try $ do
501 tagOpen (`elem` ["h1","h2","h3","h4","h5","h6"])
499 tagOpen (`elem` ["h1","h2","h3","h4","h5","h6"])
502 (const True)
500 (const True)
503 let attr = toStringAttr attr'
501 let attr = toStringAttr attr'
502+ let bodyTitle = TagOpen tagtype attr' ~== TagOpen ("h1" :: Text)
503+ [("class","title")]
504 level <- headerLevel tagtype
504 level <- headerLevel tagtype
505 contents <- trimInlines . mconcat <$> manyTill inline (pCloses tagtype <|> eof)
505 contents <- trimInlines . mconcat <$> manyTill inline (pCloses tagtype <|> eof)
506 let ident = fromMaybe "" $ lookup "id" attr
506 let ident = fromMaybe "" $ lookup "id" attr
507 let classes = maybe [] T.words $ lookup "class" attr
507 let classes = maybe [] T.words $ lookup "class" attr
508 let keyvals = [(k,v) | (k,v) <- attr, k /= "class", k /= "id"]
508 let keyvals = [(k,v) | (k,v) <- attr, k /= "class", k /= "id"]
509 attr'' <- registerHeader (ident, classes, keyvals) contents
509 attr'' <- registerHeader (ident, classes, keyvals) contents
510+ return $ if bodyTitle
511+ then mempty -- skip a representation of the title in the body
510− return $ B.headerWith attr'' level contents
512+ else B.headerWith attr'' level contents
511
513
512pHrule :: PandocMonad m => TagParser m Blocks
514pHrule :: PandocMonad m => TagParser m Blocks
513pHrule = do
515pHrule = do
@@ -557,18 +559,7 @@ pFigure = try $ do
557pCodeBlock :: PandocMonad m => TagParser m Blocks
559pCodeBlock :: PandocMonad m => TagParser m Blocks
558pCodeBlock = try $ do
560pCodeBlock = try $ do
559 TagOpen _ attr' <- pSatisfy (matchTagOpen "pre" [])
561 TagOpen _ attr' <- pSatisfy (matchTagOpen "pre" [])
560− -- if the `pre` has no attributes, try if it is followed by a `code`
562+ let attr = toAttr attr'
561− -- element and use those attributes if possible.
562− attr <- case attr' of
563− _:_ -> pure (toAttr attr')
564− [] -> option nullAttr $ do
565− TagOpen _ codeAttr <- pSatisfy (matchTagOpen "code" [])
566− pure $ toAttr
567− [ (k, v') | (k, v) <- codeAttr
568− -- strip language from class
569− , let v' = if k == "class"
570− then fromMaybe v (T.stripPrefix "language-" v)
571− else v ]
572 contents <- manyTill pAny (pCloses "pre" <|> eof)
563 contents <- manyTill pAny (pCloses "pre" <|> eof)
573 let rawText = T.concat $ map tagToText contents
564 let rawText = T.concat $ map tagToText contents
574 -- drop leading newline if any
565 -- drop leading newline if any
@@ -839,19 +830,17 @@ pInlinesInTags tagtype f = extractSpaces f <$> pInTags tagtype inline
839
830
840pTagText :: PandocMonad m => TagParser m Inlines
831pTagText :: PandocMonad m => TagParser m Inlines
841pTagText = try $ do
832pTagText = try $ do
842− pos <- getPosition
843 (TagText str) <- pSatisfy isTagText
833 (TagText str) <- pSatisfy isTagText
844 st <- getState
834 st <- getState
845 qu <- ask
835 qu <- ask
846 parsed <- lift $ lift $
836 parsed <- lift $ lift $
847− flip runReaderT qu $ runParserT (many pTagContents) st "text"
837+ flip runReaderT qu $ runParserT (many pTagContents) st "text" str
848− (Sources [(pos, str)])
849 case parsed of
838 case parsed of
850 Left _ -> throwError $ PandocParseError $
839 Left _ -> throwError $ PandocParseError $
851 "Could not parse `" <> str <> "'"
840 "Could not parse `" <> str <> "'"
852 Right result -> return $ mconcat result
841 Right result -> return $ mconcat result
853
842
854−type InlinesParser m = HTMLParser m Sources
843+type InlinesParser m = HTMLParser m Text
855
844
856pTagContents :: PandocMonad m => InlinesParser m Inlines
845pTagContents :: PandocMonad m => InlinesParser m Inlines
857pTagContents =
846pTagContents =
@@ -951,15 +940,13 @@ getTagName (TagClose t) = Just t
951getTagName _ = Nothing
940getTagName _ = Nothing
952
941
953isInlineTag :: Tag Text -> Bool
942isInlineTag :: Tag Text -> Bool
943+isInlineTag t =
954−isInlineTag t = isCommentTag t || case t of
944+ isCommentTag t ||
945+ case getTagName t of
946+ Nothing -> False
955− TagOpen "script" _ -> "math/tex" `T.isPrefixOf` fromAttrib "type" t
947+ Just "script" -> "math/tex" `T.isPrefixOf` fromAttrib "type" t
956− TagClose "script" -> True
957− TagOpen name _ -> isInlineTagName name
958− TagClose name -> isInlineTagName name
959− _ -> False
960− where isInlineTagName x =
961− x `Set.notMember` blockTags ||
948+ Just x -> x `Set.notMember` blockTags ||
962− T.take 1 x == "?" -- processing instr.
949+ T.take 1 x == "?" -- processing instr.
963
950
964isBlockTag :: Tag Text -> Bool
951isBlockTag :: Tag Text -> Bool
965isBlockTag t = isBlockTagName || isTagComment t
952isBlockTag t = isBlockTagName || isTagComment t
@@ -983,14 +970,13 @@ isCommentTag = tagComment (const True)
983-- | Matches a stretch of HTML in balanced tags.
970-- | Matches a stretch of HTML in balanced tags.
984htmlInBalanced :: Monad m
971htmlInBalanced :: Monad m
985 => (Tag Text -> Bool)
972 => (Tag Text -> Bool)
986− -> ParserT Sources st m Text
973+ -> ParserT Text st m Text
987htmlInBalanced f = try $ do
974htmlInBalanced f = try $ do
988 lookAhead (char '<')
975 lookAhead (char '<')
989− sources <- getInput
976+ inp <- getInput
990− let ts = canonicalizeTags
977+ let ts = canonicalizeTags $
991− $ parseTagsOptions parseOptions{ optTagWarning = True,
978+ parseTagsOptions parseOptions{ optTagWarning = True,
992− optTagPosition = True }
979+ optTagPosition = True } inp
993− $ sourcesToText sources
994 case ts of
980 case ts of
995 (TagPosition sr sc : t@(TagOpen tn _) : rest) -> do
981 (TagPosition sr sc : t@(TagOpen tn _) : rest) -> do
996 guard $ f t
982 guard $ f t
@@ -1032,17 +1018,15 @@ hasTagWarning _ = False
1032-- | Matches a tag meeting a certain condition.
1018-- | Matches a tag meeting a certain condition.
1033htmlTag :: (HasReaderOptions st, Monad m)
1019htmlTag :: (HasReaderOptions st, Monad m)
1034 => (Tag Text -> Bool)
1020 => (Tag Text -> Bool)
1035− -> ParserT Sources st m (Tag Text, Text)
1021+ -> ParserT Text st m (Tag Text, Text)
1036htmlTag f = try $ do
1022htmlTag f = try $ do
1037 lookAhead (char '<')
1023 lookAhead (char '<')
1038 startpos <- getPosition
1024 startpos <- getPosition
1039− sources <- getInput
1025+ inp <- getInput
1040− let inp = sourcesToText sources
1041 let ts = canonicalizeTags $ parseTagsOptions
1026 let ts = canonicalizeTags $ parseTagsOptions
1042 parseOptions{ optTagWarning = False
1027 parseOptions{ optTagWarning = False
1043 , optTagPosition = True }
1028 , optTagPosition = True }
1044− (inp <> " ")
1045− -- add space to ensure that
1029+ (inp <> " ") -- add space to ensure that
1046 -- we get a TagPosition after the tag
1030 -- we get a TagPosition after the tag
1047 (next, ln, col) <- case ts of
1031 (next, ln, col) <- case ts of
1048 (TagPosition{} : next : TagPosition ln col : _)
1032 (TagPosition{} : next : TagPosition ln col : _)
src/Text/Pandoc/Readers/HTML/Table.hs+14−33
@@ -17,7 +17,6 @@ module Text.Pandoc.Readers.HTML.Table (pTable) where
17
17
18import Control.Applicative ((<|>))
18import Control.Applicative ((<|>))
19import Data.Maybe (fromMaybe)
19import Data.Maybe (fromMaybe)
20−import Data.Either (lefts, rights)
21import Data.List.NonEmpty (nonEmpty)
20import Data.List.NonEmpty (nonEmpty)
22import Data.Text (Text)
21import Data.Text (Text)
23import Text.HTML.TagSoup
22import Text.HTML.TagSoup
@@ -34,51 +33,34 @@ import Text.Pandoc.Shared (onlySimpleTableCells, safeRead)
34import qualified Data.Text as T
33import qualified Data.Text as T
35import qualified Text.Pandoc.Builder as B
34import qualified Text.Pandoc.Builder as B
36
35
37−-- | Parses a @<col>@ element, returning the column's width.
36+-- | Parses a @<col>@ element, returning the column's width. Defaults to
38−-- An Either value is used: Left i means a "relative length" with
39−-- integral value i (see https://www.w3.org/TR/html4/types.html#h-6.6);
40−-- Right w means a regular width. Defaults to @'Right ColWidthDefault'@
41−-- if the width is not set or cannot be determined.
37+-- @'ColWidthDefault'@ if the width is not set or cannot be determined.
42−pCol :: PandocMonad m => TagParser m (Either Int ColWidth)
38+pCol :: PandocMonad m => TagParser m ColWidth
43pCol = try $ do
39pCol = try $ do
44 TagOpen _ attribs' <- pSatisfy (matchTagOpen "col" [])
40 TagOpen _ attribs' <- pSatisfy (matchTagOpen "col" [])
45 let attribs = toStringAttr attribs'
41 let attribs = toStringAttr attribs'
46 skipMany pBlank
42 skipMany pBlank
47 optional $ pSatisfy (matchTagClose "col")
43 optional $ pSatisfy (matchTagClose "col")
48 skipMany pBlank
44 skipMany pBlank
49− return $ case lookup "width" attribs of
45+ let width = case lookup "width" attribs of
50 Nothing -> case lookup "style" attribs of
46 Nothing -> case lookup "style" attribs of
51 Just (T.stripPrefix "width:" -> Just xs) | T.any (== '%') xs ->
47 Just (T.stripPrefix "width:" -> Just xs) | T.any (== '%') xs ->
52− maybe (Right ColWidthDefault) (Right . ColWidth . (/ 100.0))
48+ fromMaybe 0.0 $ safeRead (T.filter
53− $ safeRead (T.filter
54− (`notElem` (" \t\r\n%'\";" :: [Char])) xs)
49+ (`notElem` (" \t\r\n%'\";" :: [Char])) xs)
55− _ -> Right ColWidthDefault
50+ _ -> 0.0
56− Just (T.unsnoc -> Just (xs, '*')) ->
57− maybe (Left 1) Left $ safeRead xs
58 Just (T.unsnoc -> Just (xs, '%')) ->
51 Just (T.unsnoc -> Just (xs, '%')) ->
59− maybe (Right ColWidthDefault)
60− (Right . ColWidth . (/ 100.0)) $ safeRead xs
52+ fromMaybe 0.0 $ safeRead xs
53+ _ -> 0.0
54+ if width > 0.0
55+ then return $ ColWidth $ width / 100.0
61− _ -> Right ColWidthDefault
56+ else return ColWidthDefault
62
57
63−pColgroup :: PandocMonad m => TagParser m [Either Int ColWidth]
58+pColgroup :: PandocMonad m => TagParser m [ColWidth]
64pColgroup = try $ do
59pColgroup = try $ do
65 pSatisfy (matchTagOpen "colgroup" [])
60 pSatisfy (matchTagOpen "colgroup" [])
66 skipMany pBlank
61 skipMany pBlank
67 manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank
62 manyTill pCol (pCloses "colgroup" <|> eof) <* skipMany pBlank
68
63
69−resolveRelativeLengths :: [Either Int ColWidth] -> [ColWidth]
70−resolveRelativeLengths ws =
71− let remaining = 1 - sum (map getColWidth $ rights ws)
72− relatives = sum $ lefts ws
73− relUnit = remaining / fromIntegral relatives
74− toColWidth (Right x) = x
75− toColWidth (Left i) = ColWidth (fromIntegral i * relUnit)
76− in map toColWidth ws
77−
78−getColWidth :: ColWidth -> Double
79−getColWidth ColWidthDefault = 0
80−getColWidth (ColWidth w) = w
81−
82data CellType
64data CellType
83 = HeaderCell
65 = HeaderCell
84 | BodyCell
66 | BodyCell
@@ -200,8 +182,7 @@ pTable :: PandocMonad m
200pTable block = try $ do
182pTable block = try $ do
201 TagOpen _ attribs <- pSatisfy (matchTagOpen "table" []) <* skipMany pBlank
183 TagOpen _ attribs <- pSatisfy (matchTagOpen "table" []) <* skipMany pBlank
202 caption <- option mempty $ pInTags "caption" block <* skipMany pBlank
184 caption <- option mempty $ pInTags "caption" block <* skipMany pBlank
203− widths <- resolveRelativeLengths <$>
204− ((mconcat <$> many1 pColgroup) <|> many pCol) <* skipMany pBlank
185+ widths <- ((mconcat <$> many1 pColgroup) <|> many pCol) <* skipMany pBlank
205 thead <- pTableHead block <* skipMany pBlank
186 thead <- pTableHead block <* skipMany pBlank
206 topfoot <- optionMaybe (pTableFoot block) <* skipMany pBlank
187 topfoot <- optionMaybe (pTableFoot block) <* skipMany pBlank
207 tbodies <- many (pTableBody block) <* skipMany pBlank
188 tbodies <- many (pTableBody block) <* skipMany pBlank
src/Text/Pandoc/Readers/Haddock.hs+6−9
@@ -19,7 +19,7 @@ import Control.Monad.Except (throwError)
19import Data.List (intersperse)
19import Data.List (intersperse)
20import Data.List.NonEmpty (nonEmpty)
20import Data.List.NonEmpty (nonEmpty)
21import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
22−import Data.Text (unpack)
22+import Data.Text (Text, unpack)
23import qualified Data.Text as T
23import qualified Data.Text as T
24import Documentation.Haddock.Parser
24import Documentation.Haddock.Parser
25import Documentation.Haddock.Types as H
25import Documentation.Haddock.Types as H
@@ -29,17 +29,15 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad)
29import Text.Pandoc.Definition
29import Text.Pandoc.Definition
30import Text.Pandoc.Error
30import Text.Pandoc.Error
31import Text.Pandoc.Options
31import Text.Pandoc.Options
32−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
33−import Text.Pandoc.Shared (splitTextBy, trim)
32+import Text.Pandoc.Shared (crFilter, splitTextBy, trim)
34
33
35
34
36-- | Parse Haddock markup and return a 'Pandoc' document.
35-- | Parse Haddock markup and return a 'Pandoc' document.
37−readHaddock :: (PandocMonad m, ToSources a)
36+readHaddock :: PandocMonad m
38 => ReaderOptions
37 => ReaderOptions
39− -> a
38+ -> Text
40 -> m Pandoc
39 -> m Pandoc
41−readHaddock opts s = case readHaddockEither opts
40+readHaddock opts s = case readHaddockEither opts (unpack (crFilter s)) of
42− (unpack . sourcesToText . toSources $ s) of
43 Right result -> return result
41 Right result -> return result
44 Left e -> throwError e
42 Left e -> throwError e
45
43
@@ -131,8 +129,7 @@ docHToInlines isCode d' =
131 DocIdentifier s -> B.codeWith ("",["haskell","identifier"],[]) $ T.pack s
129 DocIdentifier s -> B.codeWith ("",["haskell","identifier"],[]) $ T.pack s
132 _ -> mempty
130 _ -> mempty
133 DocIdentifierUnchecked s -> B.codeWith ("",["haskell","identifier"],[]) $ T.pack s
131 DocIdentifierUnchecked s -> B.codeWith ("",["haskell","identifier"],[]) $ T.pack s
134− DocModule s -> B.codeWith ("",["haskell","module"],[]) $
132+ DocModule s -> B.codeWith ("",["haskell","module"],[]) $ T.pack s
135− T.pack (modLinkName s)
136 DocWarning _ -> mempty -- TODO
133 DocWarning _ -> mempty -- TODO
137 DocEmphasis d -> B.emph (docHToInlines isCode d)
134 DocEmphasis d -> B.emph (docHToInlines isCode d)
138 DocMonospaced (DocString s) -> B.code $ T.pack s
135 DocMonospaced (DocString s) -> B.code $ T.pack s
src/Text/Pandoc/Readers/Ipynb.hs+3−5
@@ -39,12 +39,10 @@ import Data.Aeson as Aeson
39import Control.Monad.Except (throwError)
39import Control.Monad.Except (throwError)
40import Text.Pandoc.Readers.Markdown (readMarkdown)
40import Text.Pandoc.Readers.Markdown (readMarkdown)
41import qualified Text.Pandoc.UTF8 as UTF8
41import qualified Text.Pandoc.UTF8 as UTF8
42−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
43
42
44−readIpynb :: (PandocMonad m, ToSources a)
45− => ReaderOptions -> a -> m Pandoc
43+readIpynb :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
46−readIpynb opts x = do
44+readIpynb opts t = do
47− let src = BL.fromStrict . TE.encodeUtf8 . sourcesToText $ toSources x
45+ let src = BL.fromStrict (TE.encodeUtf8 t)
48 case eitherDecode src of
46 case eitherDecode src of
49 Right (notebook4 :: Notebook NbV4) -> notebookToPandoc opts notebook4
47 Right (notebook4 :: Notebook NbV4) -> notebookToPandoc opts notebook4
50 Left _ ->
48 Left _ ->
src/Text/Pandoc/Readers/JATS.hs+3−8
@@ -29,12 +29,11 @@ import Text.HTML.TagSoup.Entity (lookupEntity)
29import Text.Pandoc.Builder
29import Text.Pandoc.Builder
30import Text.Pandoc.Class.PandocMonad (PandocMonad)
30import Text.Pandoc.Class.PandocMonad (PandocMonad)
31import Text.Pandoc.Options
31import Text.Pandoc.Options
32−import Text.Pandoc.Shared (safeRead, extractSpaces)
32+import Text.Pandoc.Shared (crFilter, safeRead, extractSpaces)
33import Text.TeXMath (readMathML, writeTeX)
33import Text.TeXMath (readMathML, writeTeX)
34import Text.Pandoc.XML.Light
34import Text.Pandoc.XML.Light
35import qualified Data.Set as S (fromList, member)
35import qualified Data.Set as S (fromList, member)
36import Data.Set ((\\))
36import Data.Set ((\\))
37−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
38
37
39type JATS m = StateT JATSState m
38type JATS m = StateT JATSState m
40
39
@@ -53,14 +52,10 @@ instance Default JATSState where
53 , jatsContent = [] }
52 , jatsContent = [] }
54
53
55
54
56−readJATS :: (PandocMonad m, ToSources a)
55+readJATS :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
57− => ReaderOptions
58− -> a
59− -> m Pandoc
60readJATS _ inp = do
56readJATS _ inp = do
61− let sources = toSources inp
62 tree <- either (throwError . PandocXMLError "") return $
57 tree <- either (throwError . PandocXMLError "") return $
63− parseXMLContents (TL.fromStrict . sourcesToText $ sources)
58+ parseXMLContents (TL.fromStrict $ crFilter inp)
64 (bs, st') <- flip runStateT (def{ jatsContent = tree }) $ mapM parseBlock tree
59 (bs, st') <- flip runStateT (def{ jatsContent = tree }) $ mapM parseBlock tree
65 return $ Pandoc (jatsMeta st') (toList . mconcat $ bs)
60 return $ Pandoc (jatsMeta st') (toList . mconcat $ bs)
66
61
src/Text/Pandoc/Readers/Jira.hs+7−11
@@ -20,20 +20,18 @@ import Text.Pandoc.Builder hiding (cell)
20import Text.Pandoc.Error (PandocError (PandocParseError))
20import Text.Pandoc.Error (PandocError (PandocParseError))
21import Text.Pandoc.Options (ReaderOptions)
21import Text.Pandoc.Options (ReaderOptions)
22import Text.Pandoc.Shared (stringify)
22import Text.Pandoc.Shared (stringify)
23−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
23+
24import qualified Text.Jira.Markup as Jira
24import qualified Text.Jira.Markup as Jira
25
25
26-- | Read Jira wiki markup.
26-- | Read Jira wiki markup.
27−readJira :: (PandocMonad m, ToSources a)
27+readJira :: PandocMonad m
28 => ReaderOptions
28 => ReaderOptions
29− -> a
29+ -> Text
30 -> m Pandoc
30 -> m Pandoc
31−readJira _opts inp = do
31+readJira _opts s = case parse s of
32− let sources = toSources inp
33− case parse (sourcesToText sources) of
34− Right d -> return $ jiraToPandoc d
32+ Right d -> return $ jiraToPandoc d
35− Left e -> throwError . PandocParseError $
33+ Left e -> throwError . PandocParseError $
36− "Jira parse error" `append` pack (show e)
34+ "Jira parse error" `append` pack (show e)
37
35
38jiraToPandoc :: Jira.Doc -> Pandoc
36jiraToPandoc :: Jira.Doc -> Pandoc
39jiraToPandoc (Jira.Doc blks) = doc $ foldMap jiraToPandocBlocks blks
37jiraToPandoc (Jira.Doc blks) = doc $ foldMap jiraToPandocBlocks blks
@@ -172,8 +170,6 @@ jiraLinkToPandoc linkType alias url =
172 Jira.Email -> link ("mailto:" <> url') "" alias'
170 Jira.Email -> link ("mailto:" <> url') "" alias'
173 Jira.Attachment -> linkWith ("", ["attachment"], []) url' "" alias'
171 Jira.Attachment -> linkWith ("", ["attachment"], []) url' "" alias'
174 Jira.User -> linkWith ("", ["user-account"], []) url' "" alias'
172 Jira.User -> linkWith ("", ["user-account"], []) url' "" alias'
175− Jira.SmartCard -> linkWith ("", ["smart-card"], []) url' "" alias'
176− Jira.SmartLink -> linkWith ("", ["smart-link"], []) url' "" alias'
177
173
178-- | Get unicode representation of a Jira icon.
174-- | Get unicode representation of a Jira icon.
179iconUnicode :: Jira.Icon -> Text
175iconUnicode :: Jira.Icon -> Text
src/Text/Pandoc/Readers/LaTeX.hs+27−20
@@ -24,7 +24,7 @@ module Text.Pandoc.Readers.LaTeX ( readLaTeX,
24import Control.Applicative (many, optional, (<|>))
24import Control.Applicative (many, optional, (<|>))
25import Control.Monad
25import Control.Monad
26import Control.Monad.Except (throwError)
26import Control.Monad.Except (throwError)
27−import Data.Char (isDigit, isLetter, isAlphaNum, toUpper, chr)
27+import Data.Char (isDigit, isLetter, toUpper, chr)
28import Data.Default
28import Data.Default
29import Data.List (intercalate)
29import Data.List (intercalate)
30import qualified Data.Map as M
30import qualified Data.Map as M
@@ -32,9 +32,8 @@ import Data.Maybe (fromMaybe, maybeToList)
32import qualified Data.Set as Set
32import qualified Data.Set as Set
33import Data.Text (Text)
33import Data.Text (Text)
34import qualified Data.Text as T
34import qualified Data.Text as T
35−import Skylighting (defaultSyntaxMap)
36import System.FilePath (addExtension, replaceExtension, takeExtension)
35import System.FilePath (addExtension, replaceExtension, takeExtension)
37−import Text.Collate.Lang (renderLang)
36+import Text.Pandoc.BCP47 (renderLang)
38import Text.Pandoc.Builder as B
37import Text.Pandoc.Builder as B
39import Text.Pandoc.Class.PandocPure (PandocPure)
38import Text.Pandoc.Class.PandocPure (PandocPure)
40import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath,
39import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath,
@@ -77,17 +76,16 @@ import Data.List.NonEmpty (nonEmpty)
77-- import Debug.Trace (traceShowId)
76-- import Debug.Trace (traceShowId)
78
77
79-- | Parse LaTeX from string and return 'Pandoc' document.
78-- | Parse LaTeX from string and return 'Pandoc' document.
80−readLaTeX :: (PandocMonad m, ToSources a)
79+readLaTeX :: PandocMonad m
81 => ReaderOptions -- ^ Reader options
80 => ReaderOptions -- ^ Reader options
82− -> a -- ^ Input to parse
81+ -> Text -- ^ String to parse (assumes @'\n'@ line endings)
83 -> m Pandoc
82 -> m Pandoc
84readLaTeX opts ltx = do
83readLaTeX opts ltx = do
85− let sources = toSources ltx
86 parsed <- runParserT parseLaTeX def{ sOptions = opts } "source"
84 parsed <- runParserT parseLaTeX def{ sOptions = opts } "source"
87− (tokenizeSources sources)
85+ (tokenize "source" (crFilter ltx))
88 case parsed of
86 case parsed of
89 Right result -> return result
87 Right result -> return result
90− Left e -> throwError $ PandocParsecError sources e
88+ Left e -> throwError $ PandocParsecError ltx e
91
89
92parseLaTeX :: PandocMonad m => LP m Pandoc
90parseLaTeX :: PandocMonad m => LP m Pandoc
93parseLaTeX = do
91parseLaTeX = do
@@ -133,11 +131,11 @@ resolveRefs _ x = x
133
131
134
132
135rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
133rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
136− => ParserT Sources s m Text
134+ => ParserT Text s m Text
137rawLaTeXBlock = do
135rawLaTeXBlock = do
138 lookAhead (try (char '\\' >> letter))
136 lookAhead (try (char '\\' >> letter))
139 inp <- getInput
137 inp <- getInput
140− let toks = tokenizeSources inp
138+ let toks = tokenize "source" inp
141 snd <$> (rawLaTeXParser toks False (macroDef (const mempty)) blocks
139 snd <$> (rawLaTeXParser toks False (macroDef (const mempty)) blocks
142 <|> rawLaTeXParser toks True
140 <|> rawLaTeXParser toks True
143 (do choice (map controlSeq
141 (do choice (map controlSeq
@@ -164,11 +162,11 @@ beginOrEndCommand = try $ do
164 (txt <> untokenize rawargs)
162 (txt <> untokenize rawargs)
165
163
166rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
164rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
167− => ParserT Sources s m Text
165+ => ParserT Text s m Text
168rawLaTeXInline = do
166rawLaTeXInline = do
169 lookAhead (try (char '\\' >> letter))
167 lookAhead (try (char '\\' >> letter))
170 inp <- getInput
168 inp <- getInput
171− let toks = tokenizeSources inp
169+ let toks = tokenize "source" inp
172 raw <- snd <$>
170 raw <- snd <$>
173 ( rawLaTeXParser toks True
171 ( rawLaTeXParser toks True
174 (mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))
172 (mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))
@@ -179,11 +177,11 @@ rawLaTeXInline = do
179 finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439
177 finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439
180 return $ raw <> T.pack finalbraces
178 return $ raw <> T.pack finalbraces
181
179
182−inlineCommand :: PandocMonad m => ParserT Sources ParserState m Inlines
180+inlineCommand :: PandocMonad m => ParserT Text ParserState m Inlines
183inlineCommand = do
181inlineCommand = do
184 lookAhead (try (char '\\' >> letter))
182 lookAhead (try (char '\\' >> letter))
185 inp <- getInput
183 inp <- getInput
186− let toks = tokenizeSources inp
184+ let toks = tokenize "source" inp
187 fst <$> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
185 fst <$> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
188 inlines
186 inlines
189
187
@@ -232,6 +230,16 @@ mkImage options (T.unpack -> src) = do
232 _ -> return src
230 _ -> return src
233 return $ imageWith attr (T.pack src') "" alt
231 return $ imageWith attr (T.pack src') "" alt
234
232
233+doxspace :: PandocMonad m => LP m Inlines
234+doxspace =
235+ (space <$ lookAhead (satisfyTok startsWithLetter)) <|> return mempty
236+ where startsWithLetter (Tok _ Word t) =
237+ case T.uncons t of
238+ Just (c, _) | isLetter c -> True
239+ _ -> False
240+ startsWithLetter _ = False
241+
242+
235removeDoubleQuotes :: Text -> Text
243removeDoubleQuotes :: Text -> Text
236removeDoubleQuotes t =
244removeDoubleQuotes t =
237 Data.Maybe.fromMaybe t $ T.stripPrefix "\"" t >>= T.stripSuffix "\""
245 Data.Maybe.fromMaybe t $ T.stripPrefix "\"" t >>= T.stripSuffix "\""
@@ -300,9 +308,7 @@ inlineCommand' :: PandocMonad m => LP m Inlines
300inlineCommand' = try $ do
308inlineCommand' = try $ do
301 Tok _ (CtrlSeq name) cmd <- anyControlSeq
309 Tok _ (CtrlSeq name) cmd <- anyControlSeq
302 guard $ name /= "begin" && name /= "end" && name /= "and"
310 guard $ name /= "begin" && name /= "end" && name /= "and"
303− star <- if T.all isAlphaNum name
304− then option "" ("*" <$ symbol '*' <* sp)
311+ star <- option "" ("*" <$ symbol '*' <* sp)
305− else pure ""
306 overlay <- option "" overlaySpecification
312 overlay <- option "" overlaySpecification
307 let name' = name <> star <> overlay
313 let name' = name <> star <> overlay
308 let names = ordNub [name', name] -- check non-starred as fallback
314 let names = ordNub [name', name] -- check non-starred as fallback
@@ -409,6 +415,8 @@ inlineCommands = M.unions
409 -- LaTeX colors
415 -- LaTeX colors
410 , ("textcolor", coloredInline "color")
416 , ("textcolor", coloredInline "color")
411 , ("colorbox", coloredInline "background-color")
417 , ("colorbox", coloredInline "background-color")
418+ -- xspace
419+ , ("xspace", doxspace)
412 -- etoolbox
420 -- etoolbox
413 , ("ifstrequal", ifstrequal)
421 , ("ifstrequal", ifstrequal)
414 , ("newtoggle", braced >>= newToggle)
422 , ("newtoggle", braced >>= newToggle)
@@ -632,7 +640,7 @@ opt = do
632 parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
640 parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
633 case parsed of
641 case parsed of
634 Right result -> return result
642 Right result -> return result
635− Left e -> throwError $ PandocParsecError (toSources toks) e
643+ Left e -> throwError $ PandocParsecError (untokenize toks) e
636
644
637-- block elements:
645-- block elements:
638
646
@@ -1162,8 +1170,7 @@ inputListing = do
1162 let (ident,classes,kvs) = parseListingsOptions options
1170 let (ident,classes,kvs) = parseListingsOptions options
1163 let classes' =
1171 let classes' =
1164 (case listingsLanguage options of
1172 (case listingsLanguage options of
1165− Nothing -> (take 1 (languagesByExtension defaultSyntaxMap
1166− (T.pack $ takeExtension $ T.unpack f)) <>)
1173+ Nothing -> (take 1 (languagesByExtension (T.pack $ takeExtension $ T.unpack f)) <>)
1167 Just _ -> id) classes
1174 Just _ -> id) classes
1168 let firstline = fromMaybe 1 $ lookup "firstline" options >>= safeRead
1175 let firstline = fromMaybe 1 $ lookup "firstline" options >>= safeRead
1169 let lastline = fromMaybe (length codeLines) $
1176 let lastline = fromMaybe (length codeLines) $
src/Text/Pandoc/Readers/LaTeX/Citation.hs+1−1
@@ -120,7 +120,7 @@ simpleCiteArgs inline = try $ do
120 runParserT (mconcat <$> many inline) st "bracketed option" toks
120 runParserT (mconcat <$> many inline) st "bracketed option" toks
121 case parsed of
121 case parsed of
122 Right result -> return result
122 Right result -> return result
123− Left e -> throwError $ PandocParsecError (toSources toks) e
123+ Left e -> throwError $ PandocParsecError (untokenize toks) e
124
124
125
125
126
126
src/Text/Pandoc/Readers/LaTeX/Lang.hs+119−122
@@ -23,7 +23,7 @@ import qualified Data.Map as M
23import Data.Text (Text)
23import Data.Text (Text)
24import qualified Data.Text as T
24import qualified Data.Text as T
25import Text.Pandoc.Shared (extractSpaces)
25import Text.Pandoc.Shared (extractSpaces)
26−import Text.Collate.Lang (Lang(..), renderLang)
26+import Text.Pandoc.BCP47 (Lang(..), renderLang)
27import Text.Pandoc.Class (PandocMonad(..), setTranslations)
27import Text.Pandoc.Class (PandocMonad(..), setTranslations)
28import Text.Pandoc.Readers.LaTeX.Parsing
28import Text.Pandoc.Readers.LaTeX.Parsing
29import Text.Pandoc.Parsing (updateState, option, getState, QuoteContext(..),
29import Text.Pandoc.Parsing (updateState, option, getState, QuoteContext(..),
@@ -99,136 +99,133 @@ setDefaultLanguage = do
99polyglossiaLangToBCP47 :: M.Map T.Text (T.Text -> Lang)
99polyglossiaLangToBCP47 :: M.Map T.Text (T.Text -> Lang)
100polyglossiaLangToBCP47 = M.fromList
100polyglossiaLangToBCP47 = M.fromList
101 [ ("arabic", \o -> case T.filter (/=' ') o of
101 [ ("arabic", \o -> case T.filter (/=' ') o of
102− "locale=algeria" -> Lang "ar" Nothing (Just "DZ") [] [] []
102+ "locale=algeria" -> Lang "ar" "" "DZ" []
103− "locale=mashriq" -> Lang "ar" Nothing (Just "SY") [] [] []
103+ "locale=mashriq" -> Lang "ar" "" "SY" []
104− "locale=libya" -> Lang "ar" Nothing (Just "LY") [] [] []
104+ "locale=libya" -> Lang "ar" "" "LY" []
105− "locale=morocco" -> Lang "ar" Nothing (Just "MA") [] [] []
105+ "locale=morocco" -> Lang "ar" "" "MA" []
106− "locale=mauritania" -> Lang "ar" Nothing (Just "MR") [] [] []
106+ "locale=mauritania" -> Lang "ar" "" "MR" []
107− "locale=tunisia" -> Lang "ar" Nothing (Just "TN") [] [] []
107+ "locale=tunisia" -> Lang "ar" "" "TN" []
108− _ -> Lang "ar" Nothing (Just "") [] [] [])
108+ _ -> Lang "ar" "" "" [])
109 , ("german", \o -> case T.filter (/=' ') o of
109 , ("german", \o -> case T.filter (/=' ') o of
110− "spelling=old" -> Lang "de" Nothing (Just "DE") ["1901"] [] []
110+ "spelling=old" -> Lang "de" "" "DE" ["1901"]
111 "variant=austrian,spelling=old"
111 "variant=austrian,spelling=old"
112− -> Lang "de" Nothing (Just "AT") ["1901"] [] []
112+ -> Lang "de" "" "AT" ["1901"]
113− "variant=austrian" -> Lang "de" Nothing (Just "AT") [] [] []
113+ "variant=austrian" -> Lang "de" "" "AT" []
114 "variant=swiss,spelling=old"
114 "variant=swiss,spelling=old"
115− -> Lang "de" Nothing (Just "CH") ["1901"] [] []
115+ -> Lang "de" "" "CH" ["1901"]
116− "variant=swiss" -> Lang "de" Nothing (Just "CH") [] [] []
116+ "variant=swiss" -> Lang "de" "" "CH" []
117− _ -> Lang "de" Nothing Nothing [] [] [])
117+ _ -> Lang "de" "" "" [])
118− , ("lsorbian", \_ -> Lang "dsb" Nothing Nothing [] [] [])
118+ , ("lsorbian", \_ -> Lang "dsb" "" "" [])
119 , ("greek", \o -> case T.filter (/=' ') o of
119 , ("greek", \o -> case T.filter (/=' ') o of
120− "variant=poly" -> Lang "el" Nothing (Just "polyton") [] [] []
120+ "variant=poly" -> Lang "el" "" "polyton" []
121− "variant=ancient" -> Lang "grc" Nothing Nothing [] [] []
121+ "variant=ancient" -> Lang "grc" "" "" []
122− _ -> Lang "el" Nothing Nothing [] [] [])
122+ _ -> Lang "el" "" "" [])
123 , ("english", \o -> case T.filter (/=' ') o of
123 , ("english", \o -> case T.filter (/=' ') o of
124− "variant=australian" -> Lang "en" Nothing (Just "AU") [] [] []
124+ "variant=australian" -> Lang "en" "" "AU" []
125− "variant=canadian" -> Lang "en" Nothing (Just "CA") [] [] []
125+ "variant=canadian" -> Lang "en" "" "CA" []
126− "variant=british" -> Lang "en" Nothing (Just "GB") [] [] []
126+ "variant=british" -> Lang "en" "" "GB" []
127− "variant=newzealand" -> Lang "en" Nothing (Just "NZ") [] [] []
127+ "variant=newzealand" -> Lang "en" "" "NZ" []
128− "variant=american" -> Lang "en" Nothing (Just "US") [] [] []
128+ "variant=american" -> Lang "en" "" "US" []
129− _ -> Lang "en" Nothing (Just "") [] [] [])
129+ _ -> Lang "en" "" "" [])
130− , ("usorbian", \_ -> Lang "hsb" Nothing Nothing [] [] [])
130+ , ("usorbian", \_ -> Lang "hsb" "" "" [])
131 , ("latin", \o -> case T.filter (/=' ') o of
131 , ("latin", \o -> case T.filter (/=' ') o of
132− "variant=classic" -> Lang "la" Nothing Nothing ["x-classic"] [] []
132+ "variant=classic" -> Lang "la" "" "" ["x-classic"]
133− _ -> Lang "la" Nothing Nothing [] [] [])
133+ _ -> Lang "la" "" "" [])
134− , ("slovenian", \_ -> Lang "sl" Nothing Nothing [] [] [])
134+ , ("slovenian", \_ -> Lang "sl" "" "" [])
135− , ("serbianc", \_ -> Lang "sr" (Just "Cyrl") Nothing [] [] [])
135+ , ("serbianc", \_ -> Lang "sr" "cyrl" "" [])
136− , ("pinyin", \_ -> Lang "zh" (Just "Latn") Nothing ["pinyin"] [] [])
136+ , ("pinyin", \_ -> Lang "zh" "Latn" "" ["pinyin"])
137− , ("afrikaans", \_ -> simpleLang "af")
137+ , ("afrikaans", \_ -> Lang "af" "" "" [])
138− , ("amharic", \_ -> simpleLang "am")
138+ , ("amharic", \_ -> Lang "am" "" "" [])
139− , ("assamese", \_ -> simpleLang "as")
139+ , ("assamese", \_ -> Lang "as" "" "" [])
140− , ("asturian", \_ -> simpleLang "ast")
140+ , ("asturian", \_ -> Lang "ast" "" "" [])
141− , ("bulgarian", \_ -> simpleLang "bg")
141+ , ("bulgarian", \_ -> Lang "bg" "" "" [])
142− , ("bengali", \_ -> simpleLang "bn")
142+ , ("bengali", \_ -> Lang "bn" "" "" [])
143− , ("tibetan", \_ -> simpleLang "bo")
143+ , ("tibetan", \_ -> Lang "bo" "" "" [])
144− , ("breton", \_ -> simpleLang "br")
144+ , ("breton", \_ -> Lang "br" "" "" [])
145− , ("catalan", \_ -> simpleLang "ca")
145+ , ("catalan", \_ -> Lang "ca" "" "" [])
146− , ("welsh", \_ -> simpleLang "cy")
146+ , ("welsh", \_ -> Lang "cy" "" "" [])
147− , ("czech", \_ -> simpleLang "cs")
147+ , ("czech", \_ -> Lang "cs" "" "" [])
148− , ("coptic", \_ -> simpleLang "cop")
148+ , ("coptic", \_ -> Lang "cop" "" "" [])
149− , ("danish", \_ -> simpleLang "da")
149+ , ("danish", \_ -> Lang "da" "" "" [])
150− , ("divehi", \_ -> simpleLang "dv")
150+ , ("divehi", \_ -> Lang "dv" "" "" [])
151− , ("esperanto", \_ -> simpleLang "eo")
151+ , ("esperanto", \_ -> Lang "eo" "" "" [])
152− , ("spanish", \_ -> simpleLang "es")
152+ , ("spanish", \_ -> Lang "es" "" "" [])
153− , ("estonian", \_ -> simpleLang "et")
153+ , ("estonian", \_ -> Lang "et" "" "" [])
154− , ("basque", \_ -> simpleLang "eu")
154+ , ("basque", \_ -> Lang "eu" "" "" [])
155− , ("farsi", \_ -> simpleLang "fa")
155+ , ("farsi", \_ -> Lang "fa" "" "" [])
156− , ("finnish", \_ -> simpleLang "fi")
156+ , ("finnish", \_ -> Lang "fi" "" "" [])
157− , ("french", \_ -> simpleLang "fr")
157+ , ("french", \_ -> Lang "fr" "" "" [])
158− , ("friulan", \_ -> simpleLang "fur")
158+ , ("friulan", \_ -> Lang "fur" "" "" [])
159− , ("irish", \_ -> simpleLang "ga")
159+ , ("irish", \_ -> Lang "ga" "" "" [])
160− , ("scottish", \_ -> simpleLang "gd")
160+ , ("scottish", \_ -> Lang "gd" "" "" [])
161− , ("ethiopic", \_ -> simpleLang "gez")
161+ , ("ethiopic", \_ -> Lang "gez" "" "" [])
162− , ("galician", \_ -> simpleLang "gl")
162+ , ("galician", \_ -> Lang "gl" "" "" [])
163− , ("hebrew", \_ -> simpleLang "he")
163+ , ("hebrew", \_ -> Lang "he" "" "" [])
164− , ("hindi", \_ -> simpleLang "hi")
164+ , ("hindi", \_ -> Lang "hi" "" "" [])
165− , ("croatian", \_ -> simpleLang "hr")
165+ , ("croatian", \_ -> Lang "hr" "" "" [])
166− , ("magyar", \_ -> simpleLang "hu")
166+ , ("magyar", \_ -> Lang "hu" "" "" [])
167− , ("armenian", \_ -> simpleLang "hy")
167+ , ("armenian", \_ -> Lang "hy" "" "" [])
168− , ("interlingua", \_ -> simpleLang "ia")
168+ , ("interlingua", \_ -> Lang "ia" "" "" [])
169− , ("indonesian", \_ -> simpleLang "id")
169+ , ("indonesian", \_ -> Lang "id" "" "" [])
170− , ("icelandic", \_ -> simpleLang "is")
170+ , ("icelandic", \_ -> Lang "is" "" "" [])
171− , ("italian", \_ -> simpleLang "it")
171+ , ("italian", \_ -> Lang "it" "" "" [])
172− , ("japanese", \_ -> simpleLang "jp")
172+ , ("japanese", \_ -> Lang "jp" "" "" [])
173− , ("khmer", \_ -> simpleLang "km")
173+ , ("khmer", \_ -> Lang "km" "" "" [])
174− , ("kurmanji", \_ -> simpleLang "kmr")
174+ , ("kurmanji", \_ -> Lang "kmr" "" "" [])
175− , ("kannada", \_ -> simpleLang "kn")
175+ , ("kannada", \_ -> Lang "kn" "" "" [])
176− , ("korean", \_ -> simpleLang "ko")
176+ , ("korean", \_ -> Lang "ko" "" "" [])
177− , ("lao", \_ -> simpleLang "lo")
177+ , ("lao", \_ -> Lang "lo" "" "" [])
178− , ("lithuanian", \_ -> simpleLang "lt")
178+ , ("lithuanian", \_ -> Lang "lt" "" "" [])
179− , ("latvian", \_ -> simpleLang "lv")
179+ , ("latvian", \_ -> Lang "lv" "" "" [])
180− , ("malayalam", \_ -> simpleLang "ml")
180+ , ("malayalam", \_ -> Lang "ml" "" "" [])
181− , ("mongolian", \_ -> simpleLang "mn")
181+ , ("mongolian", \_ -> Lang "mn" "" "" [])
182− , ("marathi", \_ -> simpleLang "mr")
182+ , ("marathi", \_ -> Lang "mr" "" "" [])
183− , ("dutch", \_ -> simpleLang "nl")
183+ , ("dutch", \_ -> Lang "nl" "" "" [])
184− , ("nynorsk", \_ -> simpleLang "nn")
184+ , ("nynorsk", \_ -> Lang "nn" "" "" [])
185− , ("norsk", \_ -> simpleLang "no")
185+ , ("norsk", \_ -> Lang "no" "" "" [])
186− , ("nko", \_ -> simpleLang "nqo")
186+ , ("nko", \_ -> Lang "nqo" "" "" [])
187− , ("occitan", \_ -> simpleLang "oc")
187+ , ("occitan", \_ -> Lang "oc" "" "" [])
188− , ("panjabi", \_ -> simpleLang "pa")
188+ , ("panjabi", \_ -> Lang "pa" "" "" [])
189− , ("polish", \_ -> simpleLang "pl")
189+ , ("polish", \_ -> Lang "pl" "" "" [])
190− , ("piedmontese", \_ -> simpleLang "pms")
190+ , ("piedmontese", \_ -> Lang "pms" "" "" [])
191− , ("portuguese", \_ -> simpleLang "pt")
191+ , ("portuguese", \_ -> Lang "pt" "" "" [])
192− , ("romansh", \_ -> simpleLang "rm")
192+ , ("romansh", \_ -> Lang "rm" "" "" [])
193− , ("romanian", \_ -> simpleLang "ro")
193+ , ("romanian", \_ -> Lang "ro" "" "" [])
194− , ("russian", \_ -> simpleLang "ru")
194+ , ("russian", \_ -> Lang "ru" "" "" [])
195− , ("sanskrit", \_ -> simpleLang "sa")
195+ , ("sanskrit", \_ -> Lang "sa" "" "" [])
196− , ("samin", \_ -> simpleLang "se")
196+ , ("samin", \_ -> Lang "se" "" "" [])
197− , ("slovak", \_ -> simpleLang "sk")
197+ , ("slovak", \_ -> Lang "sk" "" "" [])
198− , ("albanian", \_ -> simpleLang "sq")
198+ , ("albanian", \_ -> Lang "sq" "" "" [])
199− , ("serbian", \_ -> simpleLang "sr")
199+ , ("serbian", \_ -> Lang "sr" "" "" [])
200− , ("swedish", \_ -> simpleLang "sv")
200+ , ("swedish", \_ -> Lang "sv" "" "" [])
201− , ("syriac", \_ -> simpleLang "syr")
201+ , ("syriac", \_ -> Lang "syr" "" "" [])
202− , ("tamil", \_ -> simpleLang "ta")
202+ , ("tamil", \_ -> Lang "ta" "" "" [])
203− , ("telugu", \_ -> simpleLang "te")
203+ , ("telugu", \_ -> Lang "te" "" "" [])
204− , ("thai", \_ -> simpleLang "th")
204+ , ("thai", \_ -> Lang "th" "" "" [])
205− , ("turkmen", \_ -> simpleLang "tk")
205+ , ("turkmen", \_ -> Lang "tk" "" "" [])
206− , ("turkish", \_ -> simpleLang "tr")
206+ , ("turkish", \_ -> Lang "tr" "" "" [])
207− , ("ukrainian", \_ -> simpleLang "uk")
207+ , ("ukrainian", \_ -> Lang "uk" "" "" [])
208− , ("urdu", \_ -> simpleLang "ur")
208+ , ("urdu", \_ -> Lang "ur" "" "" [])
209− , ("vietnamese", \_ -> simpleLang "vi")
209+ , ("vietnamese", \_ -> Lang "vi" "" "" [])
210 ]
210 ]
211
211
212−simpleLang :: Text -> Lang
213−simpleLang l = Lang l Nothing Nothing [] [] []
214−
215babelLangToBCP47 :: T.Text -> Maybe Lang
212babelLangToBCP47 :: T.Text -> Maybe Lang
216babelLangToBCP47 s =
213babelLangToBCP47 s =
217 case s of
214 case s of
218− "austrian" -> Just $ Lang "de" Nothing (Just "AT") ["1901"] [] []
215+ "austrian" -> Just $ Lang "de" "" "AT" ["1901"]
219− "naustrian" -> Just $ Lang "de" Nothing (Just "AT") [] [] []
216+ "naustrian" -> Just $ Lang "de" "" "AT" []
220− "swissgerman" -> Just $ Lang "de" Nothing (Just "CH") ["1901"] [] []
217+ "swissgerman" -> Just $ Lang "de" "" "CH" ["1901"]
221− "nswissgerman" -> Just $ Lang "de" Nothing (Just "CH") [] [] []
218+ "nswissgerman" -> Just $ Lang "de" "" "CH" []
222− "german" -> Just $ Lang "de" Nothing (Just "DE") ["1901"] [] []
219+ "german" -> Just $ Lang "de" "" "DE" ["1901"]
223− "ngerman" -> Just $ Lang "de" Nothing (Just "DE") [] [] []
220+ "ngerman" -> Just $ Lang "de" "" "DE" []
224− "lowersorbian" -> Just $ Lang "dsb" Nothing Nothing [] [] []
221+ "lowersorbian" -> Just $ Lang "dsb" "" "" []
225− "uppersorbian" -> Just $ Lang "hsb" Nothing Nothing [] [] []
222+ "uppersorbian" -> Just $ Lang "hsb" "" "" []
226− "polutonikogreek" -> Just $ Lang "el" Nothing Nothing ["polyton"] [] []
223+ "polutonikogreek" -> Just $ Lang "el" "" "" ["polyton"]
227− "slovene" -> Just $ simpleLang "sl"
224+ "slovene" -> Just $ Lang "sl" "" "" []
228− "australian" -> Just $ Lang "en" Nothing (Just "AU") [] [] []
225+ "australian" -> Just $ Lang "en" "" "AU" []
229− "canadian" -> Just $ Lang "en" Nothing (Just "CA") [] [] []
226+ "canadian" -> Just $ Lang "en" "" "CA" []
230− "british" -> Just $ Lang "en" Nothing (Just "GB") [] [] []
227+ "british" -> Just $ Lang "en" "" "GB" []
231− "newzealand" -> Just $ Lang "en" Nothing (Just "NZ") [] [] []
228+ "newzealand" -> Just $ Lang "en" "" "NZ" []
232− "american" -> Just $ Lang "en" Nothing (Just "US") [] [] []
229+ "american" -> Just $ Lang "en" "" "US" []
233− "classiclatin" -> Just $ Lang "la" Nothing Nothing ["x-classic"] [] []
230+ "classiclatin" -> Just $ Lang "la" "" "" ["x-classic"]
234 _ -> ($ "") <$> M.lookup s polyglossiaLangToBCP47
231 _ -> ($ "") <$> M.lookup s polyglossiaLangToBCP47
src/Text/Pandoc/Readers/LaTeX/Macro.hs+14−45
@@ -14,7 +14,6 @@ import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,
14import Control.Applicative ((<|>), optional)
14import Control.Applicative ((<|>), optional)
15import qualified Data.Map as M
15import qualified Data.Map as M
16import Data.Text (Text)
16import Data.Text (Text)
17−import qualified Data.Text as T
18
17
19macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
18macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
20macroDef constructor = do
19macroDef constructor = do
@@ -23,11 +22,9 @@ macroDef constructor = do
23 guardDisabled Ext_latex_macros)
22 guardDisabled Ext_latex_macros)
24 <|> return mempty
23 <|> return mempty
25 where commandDef = do
24 where commandDef = do
26− nameMacroPairs <- newcommand <|> letmacro <|> defmacro <|> newif
25+ (name, macro') <- newcommand <|> letmacro <|> defmacro
27 guardDisabled Ext_latex_macros <|>
26 guardDisabled Ext_latex_macros <|>
28− mapM_ (\(name, macro') ->
29− updateState (\s -> s{ sMacros = M.insert name macro'
27+ updateState (\s -> s{ sMacros = M.insert name macro' (sMacros s) })
30− (sMacros s) })) nameMacroPairs
31 environmentDef = do
28 environmentDef = do
32 mbenv <- newenvironment
29 mbenv <- newenvironment
33 case mbenv of
30 case mbenv of
@@ -43,7 +40,7 @@ macroDef constructor = do
43 -- @\newcommand{\envname}[n-args][default]{begin}@
40 -- @\newcommand{\envname}[n-args][default]{begin}@
44 -- @\newcommand{\endenvname}@
41 -- @\newcommand{\endenvname}@
45
42
46−letmacro :: PandocMonad m => LP m [(Text, Macro)]
43+letmacro :: PandocMonad m => LP m (Text, Macro)
47letmacro = do
44letmacro = do
48 controlSeq "let"
45 controlSeq "let"
49 (name, contents) <- withVerbatimMode $ do
46 (name, contents) <- withVerbatimMode $ do
@@ -56,47 +53,18 @@ letmacro = do
56 contents <- bracedOrToken
53 contents <- bracedOrToken
57 return (name, contents)
54 return (name, contents)
58 contents' <- doMacros' 0 contents
55 contents' <- doMacros' 0 contents
59− return [(name, Macro ExpandWhenDefined [] Nothing contents')]
56+ return (name, Macro ExpandWhenDefined [] Nothing contents')
60
57
61−defmacro :: PandocMonad m => LP m [(Text, Macro)]
58+defmacro :: PandocMonad m => LP m (Text, Macro)
62−defmacro = do
59+defmacro = try $
63 -- we use withVerbatimMode, because macros are to be expanded
60 -- we use withVerbatimMode, because macros are to be expanded
64 -- at point of use, not point of definition
61 -- at point of use, not point of definition
65− controlSeq "def"
66 withVerbatimMode $ do
62 withVerbatimMode $ do
63+ controlSeq "def"
67 Tok _ (CtrlSeq name) _ <- anyControlSeq
64 Tok _ (CtrlSeq name) _ <- anyControlSeq
68 argspecs <- many (argspecArg <|> argspecPattern)
65 argspecs <- many (argspecArg <|> argspecPattern)
69 contents <- bracedOrToken
66 contents <- bracedOrToken
70− return [(name, Macro ExpandWhenUsed argspecs Nothing contents)]
67+ return (name, Macro ExpandWhenUsed argspecs Nothing contents)
71−
72−-- \newif\iffoo' defines:
73−-- \iffoo to be \iffalse
74−-- \footrue to be a command that defines \iffoo to be \iftrue
75−-- \foofalse to be a command that defines \iffoo to be \iffalse
76−newif :: PandocMonad m => LP m [(Text, Macro)]
77−newif = do
78− controlSeq "newif"
79− withVerbatimMode $ do
80− Tok pos (CtrlSeq name) _ <- anyControlSeq
81− -- \def\iffoo\iffalse
82− -- \def\footrue{\def\iffoo\iftrue}
83− -- \def\foofalse{\def\iffoo\iffalse}
84− let base = T.drop 2 name
85− return [ (name, Macro ExpandWhenUsed [] Nothing
86− [Tok pos (CtrlSeq "iffalse") "\\iffalse"])
87− , (base <> "true",
88− Macro ExpandWhenUsed [] Nothing
89− [ Tok pos (CtrlSeq "def") "\\def"
90− , Tok pos (CtrlSeq name) ("\\" <> name)
91− , Tok pos (CtrlSeq "iftrue") "\\iftrue"
92− ])
93− , (base <> "false",
94− Macro ExpandWhenUsed [] Nothing
95− [ Tok pos (CtrlSeq "def") "\\def"
96− , Tok pos (CtrlSeq name) ("\\" <> name)
97− , Tok pos (CtrlSeq "iffalse") "\\iffalse"
98− ])
99− ]
100
68
101argspecArg :: PandocMonad m => LP m ArgSpec
69argspecArg :: PandocMonad m => LP m ArgSpec
102argspecArg = do
70argspecArg = do
@@ -109,9 +77,10 @@ argspecPattern =
109 (toktype' == Symbol || toktype' == Word) &&
77 (toktype' == Symbol || toktype' == Word) &&
110 (txt /= "{" && txt /= "\\" && txt /= "}")))
78 (txt /= "{" && txt /= "\\" && txt /= "}")))
111
79
112−newcommand :: PandocMonad m => LP m [(Text, Macro)]
80+newcommand :: PandocMonad m => LP m (Text, Macro)
113newcommand = do
81newcommand = do
82+ pos <- getPosition
114− Tok pos (CtrlSeq mtype) _ <- controlSeq "newcommand" <|>
83+ Tok _ (CtrlSeq mtype) _ <- controlSeq "newcommand" <|>
115 controlSeq "renewcommand" <|>
84 controlSeq "renewcommand" <|>
116 controlSeq "providecommand" <|>
85 controlSeq "providecommand" <|>
117 controlSeq "DeclareMathOperator" <|>
86 controlSeq "DeclareMathOperator" <|>
@@ -143,9 +112,9 @@ newcommand = do
143 Just macro
112 Just macro
144 | mtype == "newcommand" -> do
113 | mtype == "newcommand" -> do
145 report $ MacroAlreadyDefined txt pos
114 report $ MacroAlreadyDefined txt pos
146− return [(name, macro)]
115+ return (name, macro)
147− | mtype == "providecommand" -> return [(name, macro)]
116+ | mtype == "providecommand" -> return (name, macro)
148− _ -> return [(name, Macro ExpandWhenUsed argspecs optarg contents)]
117+ _ -> return (name, Macro ExpandWhenUsed argspecs optarg contents)
149
118
150newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
119newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
151newenvironment = do
120newenvironment = do
src/Text/Pandoc/Readers/LaTeX/Parsing.hs+7−48
@@ -27,7 +27,6 @@ module Text.Pandoc.Readers.LaTeX.Parsing
27 , rawLaTeXParser
27 , rawLaTeXParser
28 , applyMacros
28 , applyMacros
29 , tokenize
29 , tokenize
30− , tokenizeSources
31 , untokenize
30 , untokenize
32 , untoken
31 , untoken
33 , totoks
32 , totoks
@@ -113,6 +112,7 @@ import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
113 ArgSpec (..), Tok (..), TokType (..))
112 ArgSpec (..), Tok (..), TokType (..))
114import Text.Pandoc.Shared
113import Text.Pandoc.Shared
115import Text.Parsec.Pos
114import Text.Parsec.Pos
115+-- import Debug.Trace
116
116
117newtype DottedNum = DottedNum [Int]
117newtype DottedNum = DottedNum [Int]
118 deriving (Show, Eq)
118 deriving (Show, Eq)
@@ -248,7 +248,7 @@ withVerbatimMode parser = do
248
248
249rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s)
249rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s)
250 => [Tok] -> Bool -> LP m a -> LP m a
250 => [Tok] -> Bool -> LP m a -> LP m a
251− -> ParserT Sources s m (a, Text)
251+ -> ParserT Text s m (a, Text)
252rawLaTeXParser toks retokenize parser valParser = do
252rawLaTeXParser toks retokenize parser valParser = do
253 pstate <- getState
253 pstate <- getState
254 let lstate = def{ sOptions = extractReaderOptions pstate }
254 let lstate = def{ sOptions = extractReaderOptions pstate }
@@ -268,7 +268,7 @@ rawLaTeXParser toks retokenize parser valParser = do
268 Left _ -> mzero
268 Left _ -> mzero
269 Right ((val, raw), st) -> do
269 Right ((val, raw), st) -> do
270 updateState (updateMacros (sMacros st <>))
270 updateState (updateMacros (sMacros st <>))
271− void $ count (T.length (untokenize toks')) anyChar
271+ _ <- takeP (T.length (untokenize toks'))
272 let result = untokenize raw
272 let result = untokenize raw
273 -- ensure we end with space if input did, see #4442
273 -- ensure we end with space if input did, see #4442
274 let result' =
274 let result' =
@@ -281,7 +281,7 @@ rawLaTeXParser toks retokenize parser valParser = do
281 return (val, result')
281 return (val, result')
282
282
283applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
283applyMacros :: (PandocMonad m, HasMacros s, HasReaderOptions s)
284− => Text -> ParserT Sources s m Text
284+ => Text -> ParserT Text s m Text
285applyMacros s = (guardDisabled Ext_latex_macros >> return s) <|>
285applyMacros s = (guardDisabled Ext_latex_macros >> return s) <|>
286 do let retokenize = untokenize <$> many (satisfyTok (const True))
286 do let retokenize = untokenize <$> many (satisfyTok (const True))
287 pstate <- getState
287 pstate <- getState
@@ -301,11 +301,6 @@ QuickCheck property:
301> let t = T.pack s in untokenize (tokenize "random" t) == t
301> let t = T.pack s in untokenize (tokenize "random" t) == t
302-}
302-}
303
303
304−tokenizeSources :: Sources -> [Tok]
305−tokenizeSources = concatMap tokenizeSource . unSources
306− where
307− tokenizeSource (pos, t) = totoks pos t
308−
309tokenize :: SourceName -> Text -> [Tok]
304tokenize :: SourceName -> Text -> [Tok]
310tokenize sourcename = totoks (initialPos sourcename)
305tokenize sourcename = totoks (initialPos sourcename)
311
306
@@ -463,7 +458,7 @@ satisfyTok f = do
463doMacros :: PandocMonad m => LP m ()
458doMacros :: PandocMonad m => LP m ()
464doMacros = do
459doMacros = do
465 st <- getState
460 st <- getState
466− unless (sVerbatimMode st) $
461+ unless (sVerbatimMode st || M.null (sMacros st)) $ do
467 getInput >>= doMacros' 1 >>= setInput
462 getInput >>= doMacros' 1 >>= setInput
468
463
469doMacros' :: PandocMonad m => Int -> [Tok] -> LP m [Tok]
464doMacros' :: PandocMonad m => Int -> [Tok] -> LP m [Tok]
@@ -525,7 +520,7 @@ doMacros' n inp =
525 $ throwError $ PandocMacroLoop name
520 $ throwError $ PandocMacroLoop name
526 macros <- sMacros <$> getState
521 macros <- sMacros <$> getState
527 case M.lookup name macros of
522 case M.lookup name macros of
528− Nothing -> trySpecialMacro name ts
523+ Nothing -> mzero
529 Just (Macro expansionPoint argspecs optarg newtoks) -> do
524 Just (Macro expansionPoint argspecs optarg newtoks) -> do
530 let getargs' = do
525 let getargs' = do
531 args <-
526 args <-
@@ -553,41 +548,6 @@ doMacros' n inp =
553 ExpandWhenUsed -> doMacros' (n' + 1) result
548 ExpandWhenUsed -> doMacros' (n' + 1) result
554 ExpandWhenDefined -> return result
549 ExpandWhenDefined -> return result
555
550
556−-- | Certain macros do low-level tex manipulations that can't
557−-- be represented in our Macro type, so we handle them here.
558−trySpecialMacro :: PandocMonad m => Text -> [Tok] -> LP m [Tok]
559−trySpecialMacro "xspace" ts = do
560− ts' <- doMacros' 1 ts
561− case ts' of
562− Tok pos Word t : _
563− | startsWithAlphaNum t -> return $ Tok pos Spaces " " : ts'
564− _ -> return ts'
565−trySpecialMacro "iftrue" ts = handleIf True ts
566−trySpecialMacro "iffalse" ts = handleIf False ts
567−trySpecialMacro _ _ = mzero
568−
569−handleIf :: PandocMonad m => Bool -> [Tok] -> LP m [Tok]
570−handleIf b ts = do
571− res' <- lift $ runParserT (ifParser b) defaultLaTeXState "tokens" ts
572− case res' of
573− Left _ -> Prelude.fail "Could not parse conditional"
574− Right ts' -> return ts'
575−
576−ifParser :: PandocMonad m => Bool -> LP m [Tok]
577−ifParser b = do
578− ifToks <- many (notFollowedBy (controlSeq "else" <|> controlSeq "fi")
579− *> anyTok)
580− elseToks <- (controlSeq "else" >> manyTill anyTok (controlSeq "fi"))
581− <|> ([] <$ controlSeq "fi")
582− rest <- getInput
583− return $ (if b then ifToks else elseToks) ++ rest
584−
585−startsWithAlphaNum :: Text -> Bool
586−startsWithAlphaNum t =
587− case T.uncons t of
588− Just (c, _) | isAlphaNum c -> True
589− _ -> False
590−
591setpos :: SourcePos -> Tok -> Tok
551setpos :: SourcePos -> Tok -> Tok
592setpos spos (Tok _ tt txt) = Tok spos tt txt
552setpos spos (Tok _ tt txt) = Tok spos tt txt
593
553
@@ -823,8 +783,7 @@ withRaw parser = do
823
783
824keyval :: PandocMonad m => LP m (Text, Text)
784keyval :: PandocMonad m => LP m (Text, Text)
825keyval = try $ do
785keyval = try $ do
826− key <- untokenize <$> many1 (notFollowedBy (symbol '=') >>
827− (symbol '-' <|> symbol '_' <|> satisfyTok isWordTok))
786+ Tok _ Word key <- satisfyTok isWordTok
828 sp
787 sp
829 val <- option mempty $ do
788 val <- option mempty $ do
830 symbol '='
789 symbol '='
src/Text/Pandoc/Readers/LaTeX/SIunitx.hs+66−140
@@ -1,4 +1,3 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
3module Text.Pandoc.Readers.LaTeX.SIunitx
2module Text.Pandoc.Readers.LaTeX.SIunitx
4 ( siunitxCommands )
3 ( siunitxCommands )
@@ -10,32 +9,27 @@ import Text.Pandoc.Class
10import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,
9import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,
11 optional, space, spaces, withRaw, (<|>))
10 optional, space, spaces, withRaw, (<|>))
12import Control.Applicative ((<|>))
11import Control.Applicative ((<|>))
13−import Control.Monad (void)
14import qualified Data.Map as M
12import qualified Data.Map as M
15import Data.Char (isDigit)
13import Data.Char (isDigit)
16import Data.Text (Text)
14import Data.Text (Text)
17import qualified Data.Text as T
15import qualified Data.Text as T
18import Data.List (intersperse)
16import Data.List (intersperse)
19−import qualified Data.Sequence as Seq
17+
20−import Text.Pandoc.Walk (walk)
21
18
22siunitxCommands :: PandocMonad m
19siunitxCommands :: PandocMonad m
23 => LP m Inlines -> M.Map Text (LP m Inlines)
20 => LP m Inlines -> M.Map Text (LP m Inlines)
24siunitxCommands tok = M.fromList
21siunitxCommands tok = M.fromList
25− [ ("si", dosi tok)
22+ [ ("si", skipopts *> dosi tok)
26 , ("SI", doSI tok)
23 , ("SI", doSI tok)
27 , ("SIrange", doSIrange True tok)
24 , ("SIrange", doSIrange True tok)
28 , ("numrange", doSIrange False tok)
25 , ("numrange", doSIrange False tok)
29 , ("numlist", doSInumlist)
26 , ("numlist", doSInumlist)
30− , ("SIlist", doSIlist tok)
31 , ("num", doSInum)
27 , ("num", doSInum)
32 , ("ang", doSIang)
28 , ("ang", doSIang)
33 ]
29 ]
34
30
35dosi :: PandocMonad m => LP m Inlines -> LP m Inlines
31dosi :: PandocMonad m => LP m Inlines -> LP m Inlines
36−dosi tok = do
37− options <- option [] keyvals
38− grouped (siUnit options tok) <|> siUnit options tok
32+dosi tok = grouped (siUnit tok) <|> siUnit tok
39
33
40-- converts e.g. \SI{1}[\$]{} to "$ 1" or \SI{1}{\euro} to "1 €"
34-- converts e.g. \SI{1}[\$]{} to "$ 1" or \SI{1}{\euro} to "1 €"
41doSI :: PandocMonad m => LP m Inlines -> LP m Inlines
35doSI :: PandocMonad m => LP m Inlines -> LP m Inlines
@@ -70,50 +64,23 @@ doSInumlist = do
70 mconcat (intersperse (str "," <> space) (init xs)) <>
64 mconcat (intersperse (str "," <> space) (init xs)) <>
71 text ", & " <> last xs
65 text ", & " <> last xs
72
66
73−doSIlist :: PandocMonad m => LP m Inlines -> LP m Inlines
74−doSIlist tok = do
75− options <- option [] keyvals
76− nums <- map tonum . T.splitOn ";" . untokenize <$> braced
77− unit <- grouped (siUnit options tok) <|> siUnit options tok
78− let xs = map (<> (str "\xa0" <> unit)) nums
79− case xs of
80− [] -> return mempty
81− [x] -> return x
82− _ -> return $
83− mconcat (intersperse (str "," <> space) (init xs)) <>
84− text ", & " <> last xs
85−
86parseNum :: Parser Text () Inlines
67parseNum :: Parser Text () Inlines
87parseNum = (mconcat <$> many parseNumPart) <* eof
68parseNum = (mconcat <$> many parseNumPart) <* eof
88
69
89−minus :: Text
90−minus = "\x2212"
91−
92−hyphenToMinus :: Inline -> Inline
93−hyphenToMinus (Str t) = Str (T.replace "-" minus t)
94−hyphenToMinus x = x
95−
96parseNumPart :: Parser Text () Inlines
70parseNumPart :: Parser Text () Inlines
97parseNumPart =
71parseNumPart =
98 parseDecimalNum <|>
72 parseDecimalNum <|>
99 parseComma <|>
73 parseComma <|>
100 parsePlusMinus <|>
74 parsePlusMinus <|>
101− parsePM <|>
102 parseI <|>
75 parseI <|>
103 parseExp <|>
76 parseExp <|>
104 parseX <|>
77 parseX <|>
105 parseSpace
78 parseSpace
106 where
79 where
107− parseDecimalNum, parsePlusMinus, parsePM,
80+ parseDecimalNum = do
108− parseComma, parseI, parseX,
109− parseExp, parseSpace :: Parser Text () Inlines
110− parseDecimalNum = try $ do
111− pref <- option mempty $ (mempty <$ char '+') <|> (minus <$ char '-')
81+ pref <- option mempty $ (mempty <$ char '+') <|> ("\x2212" <$ char '-')
82+ basenum <- (pref <>) . T.pack
112− basenum' <- many1 (satisfy (\c -> isDigit c || c == '.'))
83+ <$> many1 (satisfy (\c -> isDigit c || c == '.'))
113− let basenum = pref <> T.pack
114− (case basenum' of
115− '.':_ -> '0':basenum'
116− _ -> basenum')
117 uncertainty <- option mempty $ T.pack <$> parseParens
84 uncertainty <- option mempty $ T.pack <$> parseParens
118 if T.null uncertainty
85 if T.null uncertainty
119 then return $ str basenum
86 then return $ str basenum
@@ -131,7 +98,6 @@ parseNumPart =
131 | otherwise -> "." <> t
98 | otherwise -> "." <> t
132 parseComma = str "." <$ char ','
99 parseComma = str "." <$ char ','
133 parsePlusMinus = str "\xa0\xb1\xa0" <$ try (string "+-")
100 parsePlusMinus = str "\xa0\xb1\xa0" <$ try (string "+-")
134− parsePM = str "\xa0\xb1\xa0" <$ try (string "\\pm")
135 parseParens =
101 parseParens =
136 char '(' *> many1 (satisfy (\c -> isDigit c || c == '.')) <* char ')'
102 char '(' *> many1 (satisfy (\c -> isDigit c || c == '.')) <* char ')'
137 parseI = str "i" <$ char 'i'
103 parseI = str "i" <$ char 'i'
@@ -144,14 +110,11 @@ doSIang :: PandocMonad m => LP m Inlines
144doSIang = do
110doSIang = do
145 skipopts
111 skipopts
146 ps <- T.splitOn ";" . untokenize <$> braced
112 ps <- T.splitOn ";" . untokenize <$> braced
147− let dropPlus t = case T.uncons t of
148− Just ('+',t') -> t'
149− _ -> t
150 case ps ++ repeat "" of
113 case ps ++ repeat "" of
151 (d:m:s:_) -> return $
114 (d:m:s:_) -> return $
152− (if T.null d then mempty else str (dropPlus d) <> str "\xb0") <>
115+ (if T.null d then mempty else str d <> str "\xb0") <>
153− (if T.null m then mempty else str (dropPlus m) <> str "\x2032") <>
116+ (if T.null m then mempty else str m <> str "\x2032") <>
154− (if T.null s then mempty else str (dropPlus s) <> str "\x2033")
117+ (if T.null s then mempty else str s <> str "\x2033")
155 _ -> return mempty
118 _ -> return mempty
156
119
157-- converts e.g. \SIrange{100}{200}{\ms} to "100 ms--200 ms"
120-- converts e.g. \SIrange{100}{200}{\ms} to "100 ms--200 ms"
@@ -180,99 +143,40 @@ doSIrange includeUnits tok = do
180emptyOr160 :: Inlines -> Inlines
143emptyOr160 :: Inlines -> Inlines
181emptyOr160 x = if x == mempty then x else str "\160"
144emptyOr160 x = if x == mempty then x else str "\160"
182
145
183−siUnit :: forall m. PandocMonad m => [(Text,Text)] -> LP m Inlines -> LP m Inlines
146+siUnit :: PandocMonad m => LP m Inlines -> LP m Inlines
184−siUnit options tok = mconcat . intersperse (str "\xa0") <$> many1 siUnitPart
147+siUnit tok = try (do
185− where
148+ Tok _ (CtrlSeq name) _ <- anyControlSeq
186− siUnitPart :: LP m Inlines
149+ case name of
187− siUnitPart = try $ do
188− skipMany (void (symbol '.') <|> void (symbol '~') <|> spaces1)
189− x <- ((siPrefix <*> siBase)
190− <|> (do u <- siBase <|> tok
191− option u $ siSuffix <*> pure u))
192− option x (siInfix x)
193− siInfix :: Inlines -> LP m Inlines
194− siInfix u1 = try $
195− (do _ <- controlSeq "per"
196− u2 <- siUnitPart
197− let useSlash = lookup "per-mode" options == Just "symbol"
198− if useSlash
199− then return (u1 <> str "/" <> u2)
200− else return (u1 <> str "\xa0" <> negateExponent u2))
201− <|> (do _ <- symbol '/'
202− u2 <- siUnitPart
203− return (u1 <> str "/" <> u2))
204− siPrefix :: LP m (Inlines -> Inlines)
205− siPrefix =
206− (do _ <- controlSeq "square"
150+ "square" -> do
207− skipopts
151+ unit <- siUnit tok
208− return (<> superscript "2"))
152+ return $ unit <> superscript "2"
209− <|> (do _ <- controlSeq "cubic"
153+ "cubic" -> do
210− skipopts
154+ unit <- siUnit tok
211− return (<> superscript "3"))
155+ return $ unit <> superscript "3"
212− <|> (do _ <- controlSeq "raisetothe"
156+ "raisetothe" -> do
213− skipopts
157+ n <- tok
214− n <- walk hyphenToMinus <$> tok
158+ unit <- siUnit tok
215− return (<> superscript n))
159+ return $ unit <> superscript n
216− siSuffix :: LP m (Inlines -> Inlines)
160+ _ ->
217− siSuffix =
161+ case M.lookup name siUnitMap of
162+ Just il ->
163+ option il $
164+ choice
218− (do _ <- controlSeq "squared"
165+ [ (il <> superscript "2") <$ controlSeq "squared"
219− skipopts
220− return (<> superscript "2"))
221− <|> (do _ <- controlSeq "cubed"
166+ , (il <> superscript "3") <$ controlSeq "cubed"
222− skipopts
223− return (<> superscript "3"))
224− <|> (do _ <- controlSeq "tothe"
167+ , (\n -> il <> superscript n) <$> (controlSeq "tothe" *> tok)
225− skipopts
168+ ]
226− n <- walk hyphenToMinus <$> tok
227− return (<> superscript n))
228− <|> (symbol '^' *> (do n <- walk hyphenToMinus <$> tok
229− return (<> superscript n)))
230− <|> (symbol '_' *> (do n <- walk hyphenToMinus <$> tok
231− return (<> subscript n)))
232− negateExponent :: Inlines -> Inlines
233− negateExponent ils =
234− case Seq.viewr (unMany ils) of
235− xs Seq.:> Superscript ss -> (Many xs) <>
236− superscript (str minus <> fromList ss)
237− _ -> ils <> superscript (str (minus <> "1"))
238− siBase :: LP m Inlines
239− siBase =
240− ((try
241− (do Tok _ (CtrlSeq name) _ <- anyControlSeq
242− case M.lookup name siUnitModifierMap of
243− Just il -> (il <>) <$> siBase
244− Nothing ->
245− case M.lookup name siUnitMap of
246− Just il -> pure il
247− Nothing -> fail "not a unit command"))
169+ Nothing -> fail "not an siunit unit command")
170+ <|> (lookAhead anyControlSeq >> tok)
248− <|> (do Tok _ Word t <- satisfyTok isWordTok
171+ <|> (do Tok _ Word t <- satisfyTok isWordTok
249− return $ str t)
172+ return $ str t)
250− )
173+ <|> (symbol '^' *> (superscript <$> tok))
251−
174+ <|> (symbol '_' *> (subscript <$> tok))
252−siUnitModifierMap :: M.Map Text Inlines
175+ <|> ("\xa0" <$ symbol '.')
253−siUnitModifierMap = M.fromList
176+ <|> ("\xa0" <$ symbol '~')
254− [ ("atto", str "a")
177+ <|> tok
255− , ("centi", str "c")
178+ <|> (do Tok _ _ t <- anyTok
256− , ("deca", str "d")
179+ return (str t))
257− , ("deci", str "d")
258− , ("deka", str "d")
259− , ("exa", str "E")
260− , ("femto", str "f")
261− , ("giga", str "G")
262− , ("hecto", str "h")
263− , ("kilo", str "k")
264− , ("mega", str "M")
265− , ("micro", str "μ")
266− , ("milli", str "m")
267− , ("nano", str "n")
268− , ("peta", str "P")
269− , ("pico", str "p")
270− , ("tera", str "T")
271− , ("yocto", str "y")
272− , ("yotta", str "Y")
273− , ("zepto", str "z")
274− , ("zetta", str "Z")
275− ]
276
180
277siUnitMap :: M.Map Text Inlines
181siUnitMap :: M.Map Text Inlines
278siUnitMap = M.fromList
182siUnitMap = M.fromList
@@ -372,6 +276,7 @@ siUnitMap = M.fromList
372 , ("arcsecond", str "″")
276 , ("arcsecond", str "″")
373 , ("astronomicalunit", str "ua")
277 , ("astronomicalunit", str "ua")
374 , ("atomicmassunit", str "u")
278 , ("atomicmassunit", str "u")
279+ , ("atto", str "a")
375 , ("bar", str "bar")
280 , ("bar", str "bar")
376 , ("barn", str "b")
281 , ("barn", str "b")
377 , ("becquerel", str "Bq")
282 , ("becquerel", str "Bq")
@@ -379,38 +284,51 @@ siUnitMap = M.fromList
379 , ("bohr", emph (str "a") <> subscript (str "0"))
284 , ("bohr", emph (str "a") <> subscript (str "0"))
380 , ("candela", str "cd")
285 , ("candela", str "cd")
381 , ("celsius", str "°C")
286 , ("celsius", str "°C")
287+ , ("centi", str "c")
382 , ("clight", emph (str "c") <> subscript (str "0"))
288 , ("clight", emph (str "c") <> subscript (str "0"))
383 , ("coulomb", str "C")
289 , ("coulomb", str "C")
384 , ("dalton", str "Da")
290 , ("dalton", str "Da")
385 , ("day", str "d")
291 , ("day", str "d")
292+ , ("deca", str "d")
293+ , ("deci", str "d")
386 , ("decibel", str "db")
294 , ("decibel", str "db")
387 , ("degreeCelsius",str "°C")
295 , ("degreeCelsius",str "°C")
388 , ("degree", str "°")
296 , ("degree", str "°")
297+ , ("deka", str "d")
389 , ("electronmass", emph (str "m") <> subscript (str "e"))
298 , ("electronmass", emph (str "m") <> subscript (str "e"))
390 , ("electronvolt", str "eV")
299 , ("electronvolt", str "eV")
391 , ("elementarycharge", emph (str "e"))
300 , ("elementarycharge", emph (str "e"))
301+ , ("exa", str "E")
392 , ("farad", str "F")
302 , ("farad", str "F")
303+ , ("femto", str "f")
304+ , ("giga", str "G")
393 , ("gram", str "g")
305 , ("gram", str "g")
394 , ("gray", str "Gy")
306 , ("gray", str "Gy")
395 , ("hartree", emph (str "E") <> subscript (str "h"))
307 , ("hartree", emph (str "E") <> subscript (str "h"))
396 , ("hectare", str "ha")
308 , ("hectare", str "ha")
309+ , ("hecto", str "h")
397 , ("henry", str "H")
310 , ("henry", str "H")
398 , ("hertz", str "Hz")
311 , ("hertz", str "Hz")
399 , ("hour", str "h")
312 , ("hour", str "h")
400 , ("joule", str "J")
313 , ("joule", str "J")
401 , ("katal", str "kat")
314 , ("katal", str "kat")
402 , ("kelvin", str "K")
315 , ("kelvin", str "K")
316+ , ("kilo", str "k")
403 , ("kilogram", str "kg")
317 , ("kilogram", str "kg")
404 , ("knot", str "kn")
318 , ("knot", str "kn")
405 , ("liter", str "L")
319 , ("liter", str "L")
406 , ("litre", str "l")
320 , ("litre", str "l")
407 , ("lumen", str "lm")
321 , ("lumen", str "lm")
408 , ("lux", str "lx")
322 , ("lux", str "lx")
323+ , ("mega", str "M")
409 , ("meter", str "m")
324 , ("meter", str "m")
410 , ("metre", str "m")
325 , ("metre", str "m")
326+ , ("micro", str "μ")
327+ , ("milli", str "m")
411 , ("minute", str "min")
328 , ("minute", str "min")
412 , ("mmHg", str "mmHg")
329 , ("mmHg", str "mmHg")
413 , ("mole", str "mol")
330 , ("mole", str "mol")
331+ , ("nano", str "n")
414 , ("nauticalmile", str "M")
332 , ("nauticalmile", str "M")
415 , ("neper", str "Np")
333 , ("neper", str "Np")
416 , ("newton", str "N")
334 , ("newton", str "N")
@@ -418,17 +336,25 @@ siUnitMap = M.fromList
418 , ("Pa", str "Pa")
336 , ("Pa", str "Pa")
419 , ("pascal", str "Pa")
337 , ("pascal", str "Pa")
420 , ("percent", str "%")
338 , ("percent", str "%")
339+ , ("per", str "/")
340+ , ("peta", str "P")
341+ , ("pico", str "p")
421 , ("planckbar", emph (str "\x210f"))
342 , ("planckbar", emph (str "\x210f"))
422 , ("radian", str "rad")
343 , ("radian", str "rad")
423 , ("second", str "s")
344 , ("second", str "s")
424 , ("siemens", str "S")
345 , ("siemens", str "S")
425 , ("sievert", str "Sv")
346 , ("sievert", str "Sv")
426 , ("steradian", str "sr")
347 , ("steradian", str "sr")
348+ , ("tera", str "T")
427 , ("tesla", str "T")
349 , ("tesla", str "T")
428 , ("tonne", str "t")
350 , ("tonne", str "t")
429 , ("volt", str "V")
351 , ("volt", str "V")
430 , ("watt", str "W")
352 , ("watt", str "W")
431 , ("weber", str "Wb")
353 , ("weber", str "Wb")
354+ , ("yocto", str "y")
355+ , ("yotta", str "Y")
356+ , ("zepto", str "z")
357+ , ("zetta", str "Z")
432 ]
358 ]
433
359
434
360
src/Text/Pandoc/Readers/LaTeX/Types.hs+1−14
@@ -1,4 +1,3 @@
1−{-# LANGUAGE FlexibleInstances #-}
2{- |
1{- |
3 Module : Text.Pandoc.Readers.LaTeX.Types
2 Module : Text.Pandoc.Readers.LaTeX.Types
4 Copyright : Copyright (C) 2017-2021 John MacFarlane
3 Copyright : Copyright (C) 2017-2021 John MacFarlane
@@ -19,9 +18,7 @@ module Text.Pandoc.Readers.LaTeX.Types ( Tok(..)
19 )
18 )
20where
19where
21import Data.Text (Text)
20import Data.Text (Text)
22−import Text.Parsec.Pos (SourcePos, sourceName)
21+import Text.Parsec.Pos (SourcePos)
23−import Text.Pandoc.Sources
24−import Data.List (groupBy)
25
22
26data TokType = CtrlSeq Text | Spaces | Newline | Symbol | Word | Comment |
23data TokType = CtrlSeq Text | Spaces | Newline | Symbol | Word | Comment |
27 Esc1 | Esc2 | Arg Int
24 Esc1 | Esc2 | Arg Int
@@ -30,16 +27,6 @@ data TokType = CtrlSeq Text | Spaces | Newline | Symbol | Word | Comment |
30data Tok = Tok SourcePos TokType Text
27data Tok = Tok SourcePos TokType Text
31 deriving (Eq, Ord, Show)
28 deriving (Eq, Ord, Show)
32
29
33−instance ToSources [Tok] where
34− toSources = Sources
35− . map (\ts -> case ts of
36− Tok p _ _ : _ -> (p, mconcat $ map tokToText ts)
37− _ -> error "toSources [Tok] encountered empty group")
38− . groupBy (\(Tok p1 _ _) (Tok p2 _ _) -> sourceName p1 == sourceName p2)
39−
40−tokToText :: Tok -> Text
41−tokToText (Tok _ _ t) = t
42−
43data ExpansionPoint = ExpandWhenDefined | ExpandWhenUsed
30data ExpansionPoint = ExpandWhenDefined | ExpandWhenUsed
44 deriving (Eq, Ord, Show)
31 deriving (Eq, Ord, Show)
45
32
src/Text/Pandoc/Readers/Man.hs+11−18
@@ -20,7 +20,7 @@ import Control.Monad (liftM, mzero, guard, void)
20import Control.Monad.Trans (lift)
20import Control.Monad.Trans (lift)
21import Control.Monad.Except (throwError)
21import Control.Monad.Except (throwError)
22import Data.Maybe (catMaybes, isJust)
22import Data.Maybe (catMaybes, isJust)
23−import Data.List (intersperse)
23+import Data.List (intersperse, intercalate)
24import qualified Data.Text as T
24import qualified Data.Text as T
25import Text.Pandoc.Builder as B
25import Text.Pandoc.Builder as B
26import Text.Pandoc.Class.PandocMonad (PandocMonad(..), report)
26import Text.Pandoc.Class.PandocMonad (PandocMonad(..), report)
@@ -29,8 +29,9 @@ import Text.Pandoc.Logging (LogMessage(..))
29import Text.Pandoc.Options
29import Text.Pandoc.Options
30import Text.Pandoc.Parsing
30import Text.Pandoc.Parsing
31import Text.Pandoc.Walk (query)
31import Text.Pandoc.Walk (query)
32−import Text.Pandoc.Shared (mapLeft)
32+import Text.Pandoc.Shared (crFilter, mapLeft)
33import Text.Pandoc.Readers.Roff -- TODO explicit imports
33import Text.Pandoc.Readers.Roff -- TODO explicit imports
34+import Text.Parsec hiding (tokenPrim)
34import qualified Text.Parsec as Parsec
35import qualified Text.Parsec as Parsec
35import Text.Parsec.Pos (updatePosString)
36import Text.Parsec.Pos (updatePosString)
36import qualified Data.Foldable as Foldable
37import qualified Data.Foldable as Foldable
@@ -49,20 +50,13 @@ type ManParser m = ParserT [RoffToken] ManState m
49
50
50
51
51-- | Read man (troff) from an input string and return a Pandoc document.
52-- | Read man (troff) from an input string and return a Pandoc document.
52−readMan :: (PandocMonad m, ToSources a)
53+readMan :: PandocMonad m => ReaderOptions -> T.Text -> m Pandoc
53− => ReaderOptions
54− -> a
55− -> m Pandoc
56−readMan opts s = do
54+readMan opts txt = do
57− let Sources inps = toSources s
55+ tokenz <- lexRoff (initialPos "input") (crFilter txt)
58− tokenz <- mconcat <$> mapM (uncurry lexRoff) inps
59 let state = def {readerOptions = opts} :: ManState
56 let state = def {readerOptions = opts} :: ManState
60− let fixError (PandocParsecError _ e) = PandocParsecError (Sources inps) e
61− fixError e = e
62 eitherdoc <- readWithMTokens parseMan state
57 eitherdoc <- readWithMTokens parseMan state
63 (Foldable.toList . unRoffTokens $ tokenz)
58 (Foldable.toList . unRoffTokens $ tokenz)
64− either (throwError . fixError) return eitherdoc
59+ either throwError return eitherdoc
65−
66
60
67readWithMTokens :: PandocMonad m
61readWithMTokens :: PandocMonad m
68 => ParserT [RoffToken] ManState m a -- ^ parser
62 => ParserT [RoffToken] ManState m a -- ^ parser
@@ -70,10 +64,9 @@ readWithMTokens :: PandocMonad m
70 -> [RoffToken] -- ^ input
64 -> [RoffToken] -- ^ input
71 -> m (Either PandocError a)
65 -> m (Either PandocError a)
72readWithMTokens parser state input =
66readWithMTokens parser state input =
73− let leftF = PandocParsecError mempty
67+ let leftF = PandocParsecError . T.pack . intercalate "\n" $ show <$> input
74 in mapLeft leftF `liftM` runParserT parser state "source" input
68 in mapLeft leftF `liftM` runParserT parser state "source" input
75
69
76−
77parseMan :: PandocMonad m => ManParser m Pandoc
70parseMan :: PandocMonad m => ManParser m Pandoc
78parseMan = do
71parseMan = do
79 bs <- many parseBlock <* eof
72 bs <- many parseBlock <* eof
@@ -96,7 +89,7 @@ parseBlock = choice [ parseList
96
89
97parseTable :: PandocMonad m => ManParser m Blocks
90parseTable :: PandocMonad m => ManParser m Blocks
98parseTable = do
91parseTable = do
99− updateState $ \st -> st { tableCellsPlain = True }
92+ modifyState $ \st -> st { tableCellsPlain = True }
100 let isTbl Tbl{} = True
93 let isTbl Tbl{} = True
101 isTbl _ = False
94 isTbl _ = False
102 Tbl _opts rows pos <- msatisfy isTbl
95 Tbl _opts rows pos <- msatisfy isTbl
@@ -142,7 +135,7 @@ parseTable = do
142 case res' of
135 case res' of
143 Left _ -> Prelude.fail "Could not parse table cell"
136 Left _ -> Prelude.fail "Could not parse table cell"
144 Right x -> do
137 Right x -> do
145− updateState $ \s -> s{ tableCellsPlain = False }
138+ modifyState $ \s -> s{ tableCellsPlain = False }
146 return x
139 return x
147 Right x -> return x
140 Right x -> return x
148
141
@@ -229,7 +222,7 @@ parseTitle = do
229 setMeta "section" (linePartsToInlines y)
222 setMeta "section" (linePartsToInlines y)
230 [x] -> setMeta "title" (linePartsToInlines x)
223 [x] -> setMeta "title" (linePartsToInlines x)
231 [] -> id
224 [] -> id
232− updateState $ \st -> st{ metadata = adjustMeta $ metadata st }
225+ modifyState $ \st -> st{ metadata = adjustMeta $ metadata st }
233 return mempty
226 return mempty
234
227
235linePartsToInlines :: [LinePart] -> Inlines
228linePartsToInlines :: [LinePart] -> Inlines
src/Text/Pandoc/Readers/Markdown.hs+45−76
@@ -29,9 +29,7 @@ import qualified Data.Set as Set
29import Data.Text (Text)
29import Data.Text (Text)
30import qualified Data.Text as T
30import qualified Data.Text as T
31import qualified Data.ByteString.Lazy as BL
31import qualified Data.ByteString.Lazy as BL
32−import System.FilePath (addExtension, takeExtension, takeDirectory)
32+import System.FilePath (addExtension, takeExtension)
33−import qualified System.FilePath.Windows as Windows
34−import qualified System.FilePath.Posix as Posix
35import Text.HTML.TagSoup hiding (Row)
33import Text.HTML.TagSoup hiding (Row)
36import Text.Pandoc.Builder (Blocks, Inlines)
34import Text.Pandoc.Builder (Blocks, Inlines)
37import qualified Text.Pandoc.Builder as B
35import qualified Text.Pandoc.Builder as B
@@ -49,20 +47,19 @@ import Text.Pandoc.Readers.LaTeX (applyMacros, rawLaTeXBlock, rawLaTeXInline)
49import Text.Pandoc.Shared
47import Text.Pandoc.Shared
50import Text.Pandoc.XML (fromEntities)
48import Text.Pandoc.XML (fromEntities)
51import Text.Pandoc.Readers.Metadata (yamlBsToMeta, yamlBsToRefs, yamlMetaBlock)
49import Text.Pandoc.Readers.Metadata (yamlBsToMeta, yamlBsToRefs, yamlMetaBlock)
52−-- import Debug.Trace (traceShowId)
53
50
54−type MarkdownParser m = ParserT Sources ParserState m
51+type MarkdownParser m = ParserT Text ParserState m
55
52
56type F = Future ParserState
53type F = Future ParserState
57
54
58-- | Read markdown from an input string and return a Pandoc document.
55-- | Read markdown from an input string and return a Pandoc document.
59−readMarkdown :: (PandocMonad m, ToSources a)
56+readMarkdown :: PandocMonad m
60 => ReaderOptions -- ^ Reader options
57 => ReaderOptions -- ^ Reader options
61− -> a -- ^ Input
58+ -> Text -- ^ String to parse (assuming @'\n'@ line endings)
62 -> m Pandoc
59 -> m Pandoc
63readMarkdown opts s = do
60readMarkdown opts s = do
64 parsed <- readWithM parseMarkdown def{ stateOptions = opts }
61 parsed <- readWithM parseMarkdown def{ stateOptions = opts }
65− (ensureFinalNewlines 3 (toSources s))
62+ (crFilter s <> "\n\n")
66 case parsed of
63 case parsed of
67 Right result -> return result
64 Right result -> return result
68 Left e -> throwError e
65 Left e -> throwError e
@@ -83,7 +80,7 @@ yamlToMeta opts mbfp bstr = do
83 meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
80 meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
84 setPosition oldPos
81 setPosition oldPos
85 return $ runF meta defaultParserState
82 return $ runF meta defaultParserState
86− parsed <- readWithM parser def{ stateOptions = opts } ("" :: Text)
83+ parsed <- readWithM parser def{ stateOptions = opts } ""
87 case parsed of
84 case parsed of
88 Right result -> return result
85 Right result -> return result
89 Left e -> throwError e
86 Left e -> throwError e
@@ -99,12 +96,14 @@ yamlToRefs :: PandocMonad m
99 -> m [MetaValue]
96 -> m [MetaValue]
100yamlToRefs idpred opts mbfp bstr = do
97yamlToRefs idpred opts mbfp bstr = do
101 let parser = do
98 let parser = do
99+ oldPos <- getPosition
102 case mbfp of
100 case mbfp of
103 Nothing -> return ()
101 Nothing -> return ()
104 Just fp -> setPosition $ initialPos fp
102 Just fp -> setPosition $ initialPos fp
105 refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr
103 refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr
104+ setPosition oldPos
106 return $ runF refs defaultParserState
105 return $ runF refs defaultParserState
107− parsed <- readWithM parser def{ stateOptions = opts } ("" :: Text)
106+ parsed <- readWithM parser def{ stateOptions = opts } ""
108 case parsed of
107 case parsed of
109 Right result -> return result
108 Right result -> return result
110 Left e -> throwError e
109 Left e -> throwError e
@@ -147,14 +146,14 @@ inList = do
147 ctx <- stateParserContext <$> getState
146 ctx <- stateParserContext <$> getState
148 guard (ctx == ListItemState)
147 guard (ctx == ListItemState)
149
148
150−spnl :: PandocMonad m => ParserT Sources st m ()
149+spnl :: PandocMonad m => ParserT Text st m ()
151spnl = try $ do
150spnl = try $ do
152 skipSpaces
151 skipSpaces
153 optional newline
152 optional newline
154 skipSpaces
153 skipSpaces
155 notFollowedBy (char '\n')
154 notFollowedBy (char '\n')
156
155
157−spnl' :: PandocMonad m => ParserT Sources st m Text
156+spnl' :: PandocMonad m => ParserT Text st m Text
158spnl' = try $ do
157spnl' = try $ do
159 xs <- many spaceChar
158 xs <- many spaceChar
160 ys <- option "" $ try $ (:) <$> newline
159 ys <- option "" $ try $ (:) <$> newline
@@ -299,7 +298,7 @@ kvPair allowEmpty = try $ do
299 (try $ newline >> lookAhead (blankline <|> nonspaceChar))
298 (try $ newline >> lookAhead (blankline <|> nonspaceChar))
300 guard $ allowEmpty || not (T.null val)
299 guard $ allowEmpty || not (T.null val)
301 let key' = T.concat $ T.words $ T.toLower key
300 let key' = T.concat $ T.words $ T.toLower key
302− let val' = MetaInlines $ B.toList $ B.text val
301+ let val' = MetaBlocks $ B.toList $ B.plain $ B.text val
303 return (key',val')
302 return (key',val')
304
303
305parseMarkdown :: PandocMonad m => MarkdownParser m Pandoc
304parseMarkdown :: PandocMonad m => MarkdownParser m Pandoc
@@ -338,9 +337,7 @@ referenceKey = try $ do
338 notFollowedBy' (() <$ reference)
337 notFollowedBy' (() <$ reference)
339 many1Char $ notFollowedBy space >> litChar
338 many1Char $ notFollowedBy space >> litChar
340 let betweenAngles = try $ char '<' >> manyTillChar litChar (char '>')
339 let betweenAngles = try $ char '<' >> manyTillChar litChar (char '>')
341− rebase <- option False (True <$ guardEnabled Ext_rebase_relative_paths)
342− src <- (if rebase then rebasePath pos else id) <$>
343− (try betweenAngles <|> sourceURL)
340+ src <- try betweenAngles <|> sourceURL
344 tit <- option "" referenceTitle
341 tit <- option "" referenceTitle
345 attr <- option nullAttr $ try $
342 attr <- option nullAttr $ try $
346 do guardEnabled Ext_link_attributes
343 do guardEnabled Ext_link_attributes
@@ -571,7 +568,7 @@ registerImplicitHeader raw attr@(ident, _, _)
571-- hrule block
568-- hrule block
572--
569--
573
570
574−hrule :: PandocMonad m => ParserT Sources st m (F Blocks)
571+hrule :: PandocMonad m => ParserT Text st m (F Blocks)
575hrule = try $ do
572hrule = try $ do
576 skipSpaces
573 skipSpaces
577 start <- satisfy isHruleChar
574 start <- satisfy isHruleChar
@@ -591,7 +588,7 @@ indentedLine = indentSpaces >> anyLineNewline
591blockDelimiter :: PandocMonad m
588blockDelimiter :: PandocMonad m
592 => (Char -> Bool)
589 => (Char -> Bool)
593 -> Maybe Int
590 -> Maybe Int
594− -> ParserT Sources ParserState m Int
591+ -> ParserT Text ParserState m Int
595blockDelimiter f len = try $ do
592blockDelimiter f len = try $ do
596 skipNonindentSpaces
593 skipNonindentSpaces
597 c <- lookAhead (satisfy f)
594 c <- lookAhead (satisfy f)
@@ -735,7 +732,7 @@ lhsCodeBlockBirdWith c = try $ do
735 blanklines
732 blanklines
736 return $ T.intercalate "\n" lns'
733 return $ T.intercalate "\n" lns'
737
734
738−birdTrackLine :: PandocMonad m => Char -> ParserT Sources st m Text
735+birdTrackLine :: PandocMonad m => Char -> ParserT Text st m Text
739birdTrackLine c = try $ do
736birdTrackLine c = try $ do
740 char c
737 char c
741 -- allow html tags on left margin:
738 -- allow html tags on left margin:
@@ -1028,7 +1025,7 @@ para = try $ do
1028 option (B.plain <$> result)
1025 option (B.plain <$> result)
1029 $ try $ do
1026 $ try $ do
1030 newline
1027 newline
1031− (mempty <$ blanklines)
1028+ (blanklines >> return mempty)
1032 <|> (guardDisabled Ext_blank_before_blockquote >> () <$ lookAhead blockQuote)
1029 <|> (guardDisabled Ext_blank_before_blockquote >> () <$ lookAhead blockQuote)
1033 <|> (guardEnabled Ext_backtick_code_blocks >> () <$ lookAhead codeBlockFenced)
1030 <|> (guardEnabled Ext_backtick_code_blocks >> () <$ lookAhead codeBlockFenced)
1034 <|> (guardDisabled Ext_blank_before_header >> () <$ lookAhead header)
1031 <|> (guardDisabled Ext_blank_before_header >> () <$ lookAhead header)
@@ -1173,7 +1170,7 @@ lineBlock = do
1173-- and the length including trailing space.
1170-- and the length including trailing space.
1174dashedLine :: PandocMonad m
1171dashedLine :: PandocMonad m
1175 => Char
1172 => Char
1176− -> ParserT Sources st m (Int, Int)
1173+ -> ParserT Text st m (Int, Int)
1177dashedLine ch = do
1174dashedLine ch = do
1178 dashes <- many1 (char ch)
1175 dashes <- many1 (char ch)
1179 sp <- many spaceChar
1176 sp <- many spaceChar
@@ -1242,7 +1239,7 @@ rawTableLine :: PandocMonad m
1242 -> MarkdownParser m [Text]
1239 -> MarkdownParser m [Text]
1243rawTableLine indices = do
1240rawTableLine indices = do
1244 notFollowedBy' (blanklines' <|> tableFooter)
1241 notFollowedBy' (blanklines' <|> tableFooter)
1245− line <- anyLine
1242+ line <- take1WhileP (/='\n') <* newline
1246 return $ map trim $ tail $
1243 return $ map trim $ tail $
1247 splitTextByIndices (init indices) line
1244 splitTextByIndices (init indices) line
1248
1245
@@ -1393,7 +1390,7 @@ pipeTableCell =
1393 return $ B.plain <$> result)
1390 return $ B.plain <$> result)
1394 <|> return mempty
1391 <|> return mempty
1395
1392
1396−pipeTableHeaderPart :: PandocMonad m => ParserT Sources st m (Alignment, Int)
1393+pipeTableHeaderPart :: PandocMonad m => ParserT Text st m (Alignment, Int)
1397pipeTableHeaderPart = try $ do
1394pipeTableHeaderPart = try $ do
1398 skipMany spaceChar
1395 skipMany spaceChar
1399 left <- optionMaybe (char ':')
1396 left <- optionMaybe (char ':')
@@ -1409,14 +1406,10 @@ pipeTableHeaderPart = try $ do
1409 (Just _,Just _) -> AlignCenter, len)
1406 (Just _,Just _) -> AlignCenter, len)
1410
1407
1411-- Succeed only if current line contains a pipe.
1408-- Succeed only if current line contains a pipe.
1412−scanForPipe :: PandocMonad m => ParserT Sources st m ()
1409+scanForPipe :: PandocMonad m => ParserT Text st m ()
1413scanForPipe = do
1410scanForPipe = do
1414− Sources inps <- getInput
1411+ inp <- getInput
1415− let ln = case inps of
1416− [] -> ""
1417− ((_,t):(_,t'):_) | T.null t -> t'
1418− ((_,t):_) -> t
1419− case T.break (\c -> c == '\n' || c == '|') ln of
1412+ case T.break (\c -> c == '\n' || c == '|') inp of
1420 (_, T.uncons -> Just ('|', _)) -> return ()
1413 (_, T.uncons -> Just ('|', _)) -> return ()
1421 _ -> mzero
1414 _ -> mzero
1422
1415
@@ -1710,13 +1703,13 @@ whitespace = spaceChar >> return <$> (lb <|> regsp) <?> "whitespace"
1710 where lb = spaceChar >> skipMany spaceChar >> option B.space (endline >> return B.linebreak)
1703 where lb = spaceChar >> skipMany spaceChar >> option B.space (endline >> return B.linebreak)
1711 regsp = skipMany spaceChar >> return B.space
1704 regsp = skipMany spaceChar >> return B.space
1712
1705
1713−nonEndline :: PandocMonad m => ParserT Sources st m Char
1706+nonEndline :: PandocMonad m => ParserT Text st m Char
1714nonEndline = satisfy (/='\n')
1707nonEndline = satisfy (/='\n')
1715
1708
1716str :: PandocMonad m => MarkdownParser m (F Inlines)
1709str :: PandocMonad m => MarkdownParser m (F Inlines)
1717str = do
1710str = do
1718 result <- mconcat <$> many1
1711 result <- mconcat <$> many1
1719− ( T.pack <$> (many1 alphaNum)
1712+ ( take1WhileP isAlphaNum
1720 <|> "." <$ try (char '.' <* notFollowedBy (char '.')) )
1713 <|> "." <$ try (char '.' <* notFollowedBy (char '.')) )
1721 updateLastStrPos
1714 updateLastStrPos
1722 (do guardEnabled Ext_smart
1715 (do guardEnabled Ext_smart
@@ -1840,12 +1833,9 @@ regLink :: PandocMonad m
1840 -> MarkdownParser m (F Inlines)
1833 -> MarkdownParser m (F Inlines)
1841regLink constructor lab = try $ do
1834regLink constructor lab = try $ do
1842 (src, tit) <- source
1835 (src, tit) <- source
1843− rebase <- option False (True <$ guardEnabled Ext_rebase_relative_paths)
1844− pos <- getPosition
1845− let src' = if rebase then rebasePath pos src else src
1846 attr <- option nullAttr $
1836 attr <- option nullAttr $
1847 guardEnabled Ext_link_attributes >> attributes
1837 guardEnabled Ext_link_attributes >> attributes
1848− return $ constructor attr src' tit <$> lab
1838+ return $ constructor attr src tit <$> lab
1849
1839
1850-- a link like [this][ref] or [this][] or [this]
1840-- a link like [this][ref] or [this][] or [this]
1851referenceLink :: PandocMonad m
1841referenceLink :: PandocMonad m
@@ -1885,8 +1875,7 @@ referenceLink constructor (lab, raw) = do
1885 Just ((src, tit), _) -> constructor nullAttr src tit <$> lab
1875 Just ((src, tit), _) -> constructor nullAttr src tit <$> lab
1886 Nothing -> makeFallback
1876 Nothing -> makeFallback
1887 else makeFallback
1877 else makeFallback
1888− Just ((src,tit), attr) ->
1889− constructor attr src tit <$> lab
1878+ Just ((src,tit), attr) -> constructor attr src tit <$> lab
1890
1879
1891dropBrackets :: Text -> Text
1880dropBrackets :: Text -> Text
1892dropBrackets = dropRB . dropLB
1881dropBrackets = dropRB . dropLB
@@ -1919,33 +1908,15 @@ autoLink = try $ do
1919 return $ return $ B.linkWith attr (src <> escapeURI extra) ""
1908 return $ return $ B.linkWith attr (src <> escapeURI extra) ""
1920 (B.str $ orig <> extra)
1909 (B.str $ orig <> extra)
1921
1910
1922−-- | Rebase a relative path, by adding the (relative) directory
1923−-- of the containing source position. Absolute links and URLs
1924−-- are untouched.
1925−rebasePath :: SourcePos -> Text -> Text
1926−rebasePath pos path = do
1927− let fp = sourceName pos
1928− isFragment = T.take 1 path == "#"
1929− path' = T.unpack path
1930− isAbsolutePath = Posix.isAbsolute path' || Windows.isAbsolute path'
1931− in if T.null path || isFragment || isAbsolutePath || isURI path
1932− then path
1933− else
1934− case takeDirectory fp of
1935− "" -> path
1936− "." -> path
1937− d -> T.pack d <> "/" <> path
1938−
1939image :: PandocMonad m => MarkdownParser m (F Inlines)
1911image :: PandocMonad m => MarkdownParser m (F Inlines)
1940image = try $ do
1912image = try $ do
1941 char '!'
1913 char '!'
1942 (lab,raw) <- reference
1914 (lab,raw) <- reference
1943 defaultExt <- getOption readerDefaultImageExtension
1915 defaultExt <- getOption readerDefaultImageExtension
1944− let constructor attr' src =
1945− case takeExtension (T.unpack src) of
1916+ let constructor attr' src = case takeExtension (T.unpack src) of
1946− "" -> B.imageWith attr' (T.pack $ addExtension (T.unpack src)
1917+ "" -> B.imageWith attr' (T.pack $ addExtension (T.unpack src)
1947− $ T.unpack defaultExt)
1918+ $ T.unpack defaultExt)
1948− _ -> B.imageWith attr' src
1919+ _ -> B.imageWith attr' src
1949 regLink constructor lab <|> referenceLink constructor (lab,raw)
1920 regLink constructor lab <|> referenceLink constructor (lab,raw)
1950
1921
1951note :: PandocMonad m => MarkdownParser m (F Inlines)
1922note :: PandocMonad m => MarkdownParser m (F Inlines)
@@ -1991,7 +1962,7 @@ rawLaTeXInline' = do
1991 s <- rawLaTeXInline
1962 s <- rawLaTeXInline
1992 return $ return $ B.rawInline "tex" s -- "tex" because it might be context
1963 return $ return $ B.rawInline "tex" s -- "tex" because it might be context
1993
1964
1994−rawConTeXtEnvironment :: PandocMonad m => ParserT Sources st m Text
1965+rawConTeXtEnvironment :: PandocMonad m => ParserT Text st m Text
1995rawConTeXtEnvironment = try $ do
1966rawConTeXtEnvironment = try $ do
1996 string "\\start"
1967 string "\\start"
1997 completion <- inBrackets (letter <|> digit <|> spaceChar)
1968 completion <- inBrackets (letter <|> digit <|> spaceChar)
@@ -2000,7 +1971,7 @@ rawConTeXtEnvironment = try $ do
2000 (try $ string "\\stop" >> textStr completion)
1971 (try $ string "\\stop" >> textStr completion)
2001 return $ "\\start" <> completion <> T.concat contents <> "\\stop" <> completion
1972 return $ "\\start" <> completion <> T.concat contents <> "\\stop" <> completion
2002
1973
2003−inBrackets :: PandocMonad m => ParserT Sources st m Char -> ParserT Sources st m Text
1974+inBrackets :: PandocMonad m => ParserT Text st m Char -> ParserT Text st m Text
2004inBrackets parser = do
1975inBrackets parser = do
2005 char '['
1976 char '['
2006 contents <- manyChar parser
1977 contents <- manyChar parser
@@ -2120,7 +2091,7 @@ cite = do
2120
2091
2121textualCite :: PandocMonad m => MarkdownParser m (F Inlines)
2092textualCite :: PandocMonad m => MarkdownParser m (F Inlines)
2122textualCite = try $ do
2093textualCite = try $ do
2123− (suppressAuthor, key) <- citeKey True
2094+ (suppressAuthor, key) <- citeKey
2124 -- If this is a reference to an earlier example list item,
2095 -- If this is a reference to an earlier example list item,
2125 -- then don't parse it as a citation. If the example list
2096 -- then don't parse it as a citation. If the example list
2126 -- item comes later, we'll parse it here and figure out in
2097 -- item comes later, we'll parse it here and figure out in
@@ -2200,7 +2171,7 @@ prefix = trimInlinesF . mconcat <$>
2200 manyTill inline (char ']'
2171 manyTill inline (char ']'
2201 <|> lookAhead
2172 <|> lookAhead
2202 (try $ do optional (try (char ';' >> spnl))
2173 (try $ do optional (try (char ';' >> spnl))
2203− citeKey True
2174+ citeKey
2204 return ']'))
2175 return ']'))
2205
2176
2206citeList :: PandocMonad m => MarkdownParser m (F [Citation])
2177citeList :: PandocMonad m => MarkdownParser m (F [Citation])
@@ -2209,7 +2180,7 @@ citeList = fmap sequence $ sepBy1 citation (try $ char ';' >> spnl)
2209citation :: PandocMonad m => MarkdownParser m (F Citation)
2180citation :: PandocMonad m => MarkdownParser m (F Citation)
2210citation = try $ do
2181citation = try $ do
2211 pref <- prefix
2182 pref <- prefix
2212− (suppress_author, key) <- citeKey True
2183+ (suppress_author, key) <- citeKey
2213 suff <- suffix
2184 suff <- suffix
2214 noteNum <- stateNoteNumber <$> getState
2185 noteNum <- stateNoteNumber <$> getState
2215 return $ do
2186 return $ do
@@ -2228,30 +2199,28 @@ citation = try $ do
2228smart :: PandocMonad m => MarkdownParser m (F Inlines)
2199smart :: PandocMonad m => MarkdownParser m (F Inlines)
2229smart = do
2200smart = do
2230 guardEnabled Ext_smart
2201 guardEnabled Ext_smart
2231− doubleQuoted <|> singleQuoted <|> (return <$> doubleCloseQuote) <|>
2202+ doubleQuoted <|> singleQuoted <|>
2232− (return <$> apostrophe) <|> (return <$> dash) <|> (return <$> ellipses)
2203+ choice (map (return <$>) [apostrophe, dash, ellipses])
2233
2204
2234singleQuoted :: PandocMonad m => MarkdownParser m (F Inlines)
2205singleQuoted :: PandocMonad m => MarkdownParser m (F Inlines)
2235−singleQuoted = do
2206+singleQuoted = try $ do
2236 singleQuoteStart
2207 singleQuoteStart
2237− (try (withQuoteContext InSingleQuote $
2208+ withQuoteContext InSingleQuote $
2238 fmap B.singleQuoted . trimInlinesF . mconcat <$>
2209 fmap B.singleQuoted . trimInlinesF . mconcat <$>
2239− many1Till inline singleQuoteEnd))
2210+ many1Till inline singleQuoteEnd
2240− <|> (return (return (B.str "\8217")))
2241
2211
2242-- doubleQuoted will handle regular double-quoted sections, as well
2212-- doubleQuoted will handle regular double-quoted sections, as well
2243-- as dialogues with an open double-quote without a close double-quote
2213-- as dialogues with an open double-quote without a close double-quote
2244-- in the same paragraph.
2214-- in the same paragraph.
2245doubleQuoted :: PandocMonad m => MarkdownParser m (F Inlines)
2215doubleQuoted :: PandocMonad m => MarkdownParser m (F Inlines)
2246−doubleQuoted = do
2216+doubleQuoted = try $ do
2247 doubleQuoteStart
2217 doubleQuoteStart
2248− (try (withQuoteContext InDoubleQuote $
2218+ withQuoteContext InDoubleQuote $
2249 fmap B.doubleQuoted . trimInlinesF . mconcat <$>
2219 fmap B.doubleQuoted . trimInlinesF . mconcat <$>
2250− many1Till inline doubleQuoteEnd))
2220+ many1Till inline doubleQuoteEnd
2251− <|> (return (return (B.str "\8220")))
2252
2221
2253toRow :: [Blocks] -> Row
2222toRow :: [Blocks] -> Row
2254toRow = Row nullAttr . map B.simpleCell
2223toRow = Row nullAttr . map B.simpleCell
2255
2224
2256toHeaderRow :: [Blocks] -> [Row]
2225toHeaderRow :: [Blocks] -> [Row]
2257−toHeaderRow l = [toRow l | not (null l) && not (all null l)]
2226+toHeaderRow l = [toRow l | not (null l)]
src/Text/Pandoc/Readers/MediaWiki.hs+6−7
@@ -36,18 +36,17 @@ import Text.Pandoc.Logging
36import Text.Pandoc.Options
36import Text.Pandoc.Options
37import Text.Pandoc.Parsing hiding (nested)
37import Text.Pandoc.Parsing hiding (nested)
38import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isCommentTag)
38import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isCommentTag)
39−import Text.Pandoc.Shared (safeRead, stringify, stripTrailingNewlines,
39+import Text.Pandoc.Shared (crFilter, safeRead, stringify, stripTrailingNewlines,
40 trim, splitTextBy, tshow)
40 trim, splitTextBy, tshow)
41import Text.Pandoc.Walk (walk)
41import Text.Pandoc.Walk (walk)
42import Text.Pandoc.XML (fromEntities)
42import Text.Pandoc.XML (fromEntities)
43
43
44-- | Read mediawiki from an input string and return a Pandoc document.
44-- | Read mediawiki from an input string and return a Pandoc document.
45−readMediaWiki :: (PandocMonad m, ToSources a)
45+readMediaWiki :: PandocMonad m
46− => ReaderOptions
46+ => ReaderOptions -- ^ Reader options
47− -> a
47+ -> Text -- ^ String to parse (assuming @'\n'@ line endings)
48 -> m Pandoc
48 -> m Pandoc
49readMediaWiki opts s = do
49readMediaWiki opts s = do
50− let sources = toSources s
51 parsed <- readWithM parseMediaWiki MWState{ mwOptions = opts
50 parsed <- readWithM parseMediaWiki MWState{ mwOptions = opts
52 , mwMaxNestingLevel = 4
51 , mwMaxNestingLevel = 4
53 , mwNextLinkNumber = 1
52 , mwNextLinkNumber = 1
@@ -56,7 +55,7 @@ readMediaWiki opts s = do
56 , mwLogMessages = []
55 , mwLogMessages = []
57 , mwInTT = False
56 , mwInTT = False
58 }
57 }
59− sources
58+ (crFilter s <> "\n")
60 case parsed of
59 case parsed of
61 Right result -> return result
60 Right result -> return result
62 Left e -> throwError e
61 Left e -> throwError e
@@ -70,7 +69,7 @@ data MWState = MWState { mwOptions :: ReaderOptions
70 , mwInTT :: Bool
69 , mwInTT :: Bool
71 }
70 }
72
71
73−type MWParser m = ParserT Sources MWState m
72+type MWParser m = ParserT Text MWState m
74
73
75instance HasReaderOptions MWState where
74instance HasReaderOptions MWState where
76 extractReaderOptions = mwOptions
75 extractReaderOptions = mwOptions
src/Text/Pandoc/Readers/Metadata.hs+15−22
@@ -35,9 +35,9 @@ import qualified Data.Text.Lazy as TL
35import qualified Text.Pandoc.UTF8 as UTF8
35import qualified Text.Pandoc.UTF8 as UTF8
36
36
37yamlBsToMeta :: (PandocMonad m, HasLastStrPosition st)
37yamlBsToMeta :: (PandocMonad m, HasLastStrPosition st)
38− => ParserT Sources st m (Future st MetaValue)
38+ => ParserT Text st m (Future st MetaValue)
39 -> BL.ByteString
39 -> BL.ByteString
40− -> ParserT Sources st m (Future st Meta)
40+ -> ParserT Text st m (Future st Meta)
41yamlBsToMeta pMetaValue bstr = do
41yamlBsToMeta pMetaValue bstr = do
42 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
42 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
43 Right (YAML.Doc (YAML.Mapping _ _ o):_)
43 Right (YAML.Doc (YAML.Mapping _ _ o):_)
@@ -45,9 +45,6 @@ yamlBsToMeta pMetaValue bstr = do
45 Right [] -> return . return $ mempty
45 Right [] -> return . return $ mempty
46 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
46 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
47 -> return . return $ mempty
47 -> return . return $ mempty
48− -- the following is what we get from a comment:
49− Right [YAML.Doc (YAML.Scalar _ (YAML.SUnknown _ ""))]
50− -> return . return $ mempty
51 Right _ -> Prelude.fail "expected YAML object"
48 Right _ -> Prelude.fail "expected YAML object"
52 Left (yamlpos, err')
49 Left (yamlpos, err')
53 -> do pos <- getPosition
50 -> do pos <- getPosition
@@ -70,10 +67,10 @@ lookupYAML _ _ = Nothing
70
67
71-- Returns filtered list of references.
68-- Returns filtered list of references.
72yamlBsToRefs :: (PandocMonad m, HasLastStrPosition st)
69yamlBsToRefs :: (PandocMonad m, HasLastStrPosition st)
73− => ParserT Sources st m (Future st MetaValue)
70+ => ParserT Text st m (Future st MetaValue)
74 -> (Text -> Bool) -- ^ Filter for id
71 -> (Text -> Bool) -- ^ Filter for id
75 -> BL.ByteString
72 -> BL.ByteString
76− -> ParserT Sources st m (Future st [MetaValue])
73+ -> ParserT Text st m (Future st [MetaValue])
77yamlBsToRefs pMetaValue idpred bstr =
74yamlBsToRefs pMetaValue idpred bstr =
78 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
75 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
79 Right (YAML.Doc o@YAML.Mapping{}:_)
76 Right (YAML.Doc o@YAML.Mapping{}:_)
@@ -101,12 +98,8 @@ yamlBsToRefs pMetaValue idpred bstr =
101 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
98 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
102 -> return . return $ mempty
99 -> return . return $ mempty
103 Right _ -> Prelude.fail "expecting YAML object"
100 Right _ -> Prelude.fail "expecting YAML object"
104− Left (yamlpos, err')
101+ Left (_pos, err')
105− -> do pos <- getPosition
106− setPosition $ incSourceLine
107− (setSourceColumn pos (YE.posColumn yamlpos))
108− (YE.posLine yamlpos - 1)
109− Prelude.fail err'
102+ -> Prelude.fail err'
110
103
111
104
112nodeToKey :: YAML.Node YE.Pos -> Maybe Text
105nodeToKey :: YAML.Node YE.Pos -> Maybe Text
@@ -115,9 +108,9 @@ nodeToKey (YAML.Scalar _ (YAML.SUnknown _ t)) = Just t
115nodeToKey _ = Nothing
108nodeToKey _ = Nothing
116
109
117normalizeMetaValue :: (PandocMonad m, HasLastStrPosition st)
110normalizeMetaValue :: (PandocMonad m, HasLastStrPosition st)
118− => ParserT Sources st m (Future st MetaValue)
111+ => ParserT Text st m (Future st MetaValue)
119 -> Text
112 -> Text
120− -> ParserT Sources st m (Future st MetaValue)
113+ -> ParserT Text st m (Future st MetaValue)
121normalizeMetaValue pMetaValue x =
114normalizeMetaValue pMetaValue x =
122 -- Note: a standard quoted or unquoted YAML value will
115 -- Note: a standard quoted or unquoted YAML value will
123 -- not end in a newline, but a "block" set off with
116 -- not end in a newline, but a "block" set off with
@@ -140,9 +133,9 @@ checkBoolean t
140 | otherwise = Nothing
133 | otherwise = Nothing
141
134
142yamlToMetaValue :: (PandocMonad m, HasLastStrPosition st)
135yamlToMetaValue :: (PandocMonad m, HasLastStrPosition st)
143− => ParserT Sources st m (Future st MetaValue)
136+ => ParserT Text st m (Future st MetaValue)
144 -> YAML.Node YE.Pos
137 -> YAML.Node YE.Pos
145− -> ParserT Sources st m (Future st MetaValue)
138+ -> ParserT Text st m (Future st MetaValue)
146yamlToMetaValue pMetaValue (YAML.Scalar _ x) =
139yamlToMetaValue pMetaValue (YAML.Scalar _ x) =
147 case x of
140 case x of
148 YAML.SStr t -> normalizeMetaValue pMetaValue t
141 YAML.SStr t -> normalizeMetaValue pMetaValue t
@@ -163,9 +156,9 @@ yamlToMetaValue pMetaValue (YAML.Mapping _ _ o) =
163yamlToMetaValue _ _ = return $ return $ MetaString ""
156yamlToMetaValue _ _ = return $ return $ MetaString ""
164
157
165yamlMap :: (PandocMonad m, HasLastStrPosition st)
158yamlMap :: (PandocMonad m, HasLastStrPosition st)
166− => ParserT Sources st m (Future st MetaValue)
159+ => ParserT Text st m (Future st MetaValue)
167 -> M.Map (YAML.Node YE.Pos) (YAML.Node YE.Pos)
160 -> M.Map (YAML.Node YE.Pos) (YAML.Node YE.Pos)
168− -> ParserT Sources st m (Future st (M.Map Text MetaValue))
161+ -> ParserT Text st m (Future st (M.Map Text MetaValue))
169yamlMap pMetaValue o = do
162yamlMap pMetaValue o = do
170 kvs <- forM (M.toList o) $ \(key, v) -> do
163 kvs <- forM (M.toList o) $ \(key, v) -> do
171 k <- maybe (throwError $ PandocParseError
164 k <- maybe (throwError $ PandocParseError
@@ -184,8 +177,8 @@ yamlMap pMetaValue o = do
184
177
185-- | Parse a YAML metadata block using the supplied 'MetaValue' parser.
178-- | Parse a YAML metadata block using the supplied 'MetaValue' parser.
186yamlMetaBlock :: (HasLastStrPosition st, PandocMonad m)
179yamlMetaBlock :: (HasLastStrPosition st, PandocMonad m)
187− => ParserT Sources st m (Future st MetaValue)
180+ => ParserT Text st m (Future st MetaValue)
188− -> ParserT Sources st m (Future st Meta)
181+ -> ParserT Text st m (Future st Meta)
189yamlMetaBlock parser = try $ do
182yamlMetaBlock parser = try $ do
190 string "---"
183 string "---"
191 blankline
184 blankline
@@ -196,5 +189,5 @@ yamlMetaBlock parser = try $ do
196 optional blanklines
189 optional blanklines
197 yamlBsToMeta parser $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
190 yamlBsToMeta parser $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
198
191
199−stopLine :: Monad m => ParserT Sources st m ()
192+stopLine :: Monad m => ParserT Text st m ()
200stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
193stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
src/Text/Pandoc/Readers/Muse.hs+8−9
@@ -37,19 +37,18 @@ import Text.Pandoc.Error (PandocError (PandocParsecError))
37import Text.Pandoc.Logging
37import Text.Pandoc.Logging
38import Text.Pandoc.Options
38import Text.Pandoc.Options
39import Text.Pandoc.Parsing
39import Text.Pandoc.Parsing
40−import Text.Pandoc.Shared (trimr, tshow)
40+import Text.Pandoc.Shared (crFilter, trimr, tshow)
41
41
42-- | Read Muse from an input string and return a Pandoc document.
42-- | Read Muse from an input string and return a Pandoc document.
43−readMuse :: (PandocMonad m, ToSources a)
43+readMuse :: PandocMonad m
44 => ReaderOptions
44 => ReaderOptions
45− -> a
45+ -> Text
46 -> m Pandoc
46 -> m Pandoc
47readMuse opts s = do
47readMuse opts s = do
48− let sources = toSources s
48+ let input = crFilter s
49− res <- flip runReaderT def $ runParserT parseMuse def{ museOptions = opts }
49+ res <- flip runReaderT def $ runParserT parseMuse def{ museOptions = opts } "source" input
50− (initialSourceName sources) sources
51 case res of
50 case res of
52− Left e -> throwError $ PandocParsecError sources e
51+ Left e -> throwError $ PandocParsecError input e
53 Right d -> return d
52 Right d -> return d
54
53
55type F = Future MuseState
54type F = Future MuseState
@@ -83,7 +82,7 @@ instance Default MuseEnv where
83 , museInPara = False
82 , museInPara = False
84 }
83 }
85
84
86−type MuseParser m = ParserT Sources MuseState (ReaderT MuseEnv m)
85+type MuseParser m = ParserT Text MuseState (ReaderT MuseEnv m)
87
86
88instance HasReaderOptions MuseState where
87instance HasReaderOptions MuseState where
89 extractReaderOptions = museOptions
88 extractReaderOptions = museOptions
@@ -156,7 +155,7 @@ firstColumn = getPosition >>= \pos -> guard (sourceColumn pos == 1)
156-- * Parsers
155-- * Parsers
157
156
158-- | Parse end-of-line, which can be either a newline or end-of-file.
157-- | Parse end-of-line, which can be either a newline or end-of-file.
159−eol :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s st m ()
158+eol :: Stream s m Char => ParserT s st m ()
160eol = void newline <|> eof
159eol = void newline <|> eof
161
160
162getIndent :: PandocMonad m
161getIndent :: PandocMonad m
src/Text/Pandoc/Readers/Native.hs+5−7
@@ -21,7 +21,6 @@ import Control.Monad.Except (throwError)
21import Data.Text (Text)
21import Data.Text (Text)
22import Text.Pandoc.Class.PandocMonad (PandocMonad)
22import Text.Pandoc.Class.PandocMonad (PandocMonad)
23import Text.Pandoc.Error
23import Text.Pandoc.Error
24−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
25
24
26-- | Read native formatted text and return a Pandoc document.
25-- | Read native formatted text and return a Pandoc document.
27-- The input may be a full pandoc document, a block list, a block,
26-- The input may be a full pandoc document, a block list, a block,
@@ -33,15 +32,14 @@ import Text.Pandoc.Sources (ToSources(..), sourcesToText)
33--
32--
34-- > Pandoc nullMeta [Plain [Str "hi"]]
33-- > Pandoc nullMeta [Plain [Str "hi"]]
35--
34--
36−readNative :: (PandocMonad m, ToSources a)
35+readNative :: PandocMonad m
37 => ReaderOptions
36 => ReaderOptions
38− -> a
37+ -> Text -- ^ String to parse (assuming @'\n'@ line endings)
39 -> m Pandoc
38 -> m Pandoc
40readNative _ s =
39readNative _ s =
41− let t = sourcesToText . toSources $ s
42− in case maybe (Pandoc nullMeta <$> readBlocks t) Right (safeRead t) of
40+ case maybe (Pandoc nullMeta <$> readBlocks s) Right (safeRead s) of
43− Right doc -> return doc
41+ Right doc -> return doc
44− Left _ -> throwError $ PandocParseError "couldn't read native"
42+ Left _ -> throwError $ PandocParseError "couldn't read native"
45
43
46readBlocks :: Text -> Either PandocError [Block]
44readBlocks :: Text -> Either PandocError [Block]
47readBlocks s = maybe ((:[]) <$> readBlock s) Right (safeRead s)
45readBlocks s = maybe ((:[]) <$> readBlock s) Right (safeRead s)
src/Text/Pandoc/Readers/OPML.hs+4−9
@@ -24,8 +24,7 @@ import Text.Pandoc.Options
24import Text.Pandoc.Error (PandocError(..))
24import Text.Pandoc.Error (PandocError(..))
25import Text.Pandoc.Readers.HTML (readHtml)
25import Text.Pandoc.Readers.HTML (readHtml)
26import Text.Pandoc.Readers.Markdown (readMarkdown)
26import Text.Pandoc.Readers.Markdown (readMarkdown)
27−import Text.Pandoc.Shared (blocksToInlines')
27+import Text.Pandoc.Shared (crFilter, blocksToInlines')
28−import Text.Pandoc.Sources (ToSources(..), sourcesToText)
29import Text.Pandoc.XML.Light
28import Text.Pandoc.XML.Light
30import Control.Monad.Except (throwError)
29import Control.Monad.Except (throwError)
31
30
@@ -47,14 +46,10 @@ instance Default OPMLState where
47 , opmlOptions = def
46 , opmlOptions = def
48 }
47 }
49
48
50−readOPML :: (PandocMonad m, ToSources a)
49+readOPML :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
51− => ReaderOptions
52− -> a
53− -> m Pandoc
54readOPML opts inp = do
50readOPML opts inp = do
55− let sources = toSources inp
56− (bs, st') <-
51+ (bs, st') <- runStateT
57− runStateT (case parseXMLContents (TL.fromStrict . sourcesToText $ sources) of
52+ (case parseXMLContents (TL.fromStrict (crFilter inp)) of
58 Left msg -> throwError $ PandocXMLError "" msg
53 Left msg -> throwError $ PandocXMLError "" msg
59 Right ns -> mapM parseBlock ns)
54 Right ns -> mapM parseBlock ns)
60 def{ opmlOptions = opts }
55 def{ opmlOptions = opts }
src/Text/Pandoc/Readers/Odt/ContentReader.hs+6−5
@@ -1,5 +1,4 @@
1{-# LANGUAGE Arrows #-}
1{-# LANGUAGE Arrows #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DeriveFoldable #-}
2{-# LANGUAGE DeriveFoldable #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE PatternGuards #-}
4{-# LANGUAGE PatternGuards #-}
@@ -34,7 +33,7 @@ import Data.List (find)
34import qualified Data.Map as M
33import qualified Data.Map as M
35import qualified Data.Text as T
34import qualified Data.Text as T
36import Data.Maybe
35import Data.Maybe
37−import Data.Monoid (Alt (..))
36+import Data.Semigroup (First(..), Option(..))
38
37
39import Text.TeXMath (readMathML, writeTeX)
38import Text.TeXMath (readMathML, writeTeX)
40import qualified Text.Pandoc.XML.Light as XML
39import qualified Text.Pandoc.XML.Light as XML
@@ -506,11 +505,13 @@ type InlineMatcher = ElementMatcher Inlines
506
505
507type BlockMatcher = ElementMatcher Blocks
506type BlockMatcher = ElementMatcher Blocks
508
507
508+
509−newtype FirstMatch a = FirstMatch (Alt Maybe a)
509+newtype FirstMatch a = FirstMatch (Option (First a))
510− deriving (Foldable, Monoid, Semigroup)
510+ deriving (Foldable, Monoid, Semigroup)
511
511
512firstMatch :: a -> FirstMatch a
512firstMatch :: a -> FirstMatch a
513−firstMatch = FirstMatch . Alt . Just
513+firstMatch = FirstMatch . Option . Just . First
514+
514
515
515--
516--
516matchingElement :: (Monoid e)
517matchingElement :: (Monoid e)
src/Text/Pandoc/Readers/Org.hs+7−4
@@ -18,19 +18,22 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad)
18import Text.Pandoc.Definition
18import Text.Pandoc.Definition
19import Text.Pandoc.Options
19import Text.Pandoc.Options
20import Text.Pandoc.Parsing (reportLogMessages)
20import Text.Pandoc.Parsing (reportLogMessages)
21−import Text.Pandoc.Sources (ToSources(..), ensureFinalNewlines)
21+import Text.Pandoc.Shared (crFilter)
22+
22import Control.Monad.Except (throwError)
23import Control.Monad.Except (throwError)
23import Control.Monad.Reader (runReaderT)
24import Control.Monad.Reader (runReaderT)
24
25
26+import Data.Text (Text)
27+
25-- | Parse org-mode string and return a Pandoc document.
28-- | Parse org-mode string and return a Pandoc document.
26−readOrg :: (PandocMonad m, ToSources a)
29+readOrg :: PandocMonad m
27 => ReaderOptions -- ^ Reader options
30 => ReaderOptions -- ^ Reader options
28− -> a
31+ -> Text -- ^ String to parse (assuming @'\n'@ line endings)
29 -> m Pandoc
32 -> m Pandoc
30readOrg opts s = do
33readOrg opts s = do
31 parsed <- flip runReaderT def $
34 parsed <- flip runReaderT def $
32 readWithM parseOrg (optionsToParserState opts)
35 readWithM parseOrg (optionsToParserState opts)
33− (ensureFinalNewlines 2 (toSources s))
36+ (crFilter s <> "\n\n")
34 case parsed of
37 case parsed of
35 Right result -> return result
38 Right result -> return result
36 Left e -> throwError e
39 Left e -> throwError e
src/Text/Pandoc/Readers/Org/Blocks.hs+2−5
@@ -40,11 +40,10 @@ import Data.List (foldl', intersperse)
40import Data.Maybe (fromMaybe, isJust, isNothing)
40import Data.Maybe (fromMaybe, isJust, isNothing)
41import Data.Text (Text)
41import Data.Text (Text)
42import Data.List.NonEmpty (nonEmpty)
42import Data.List.NonEmpty (nonEmpty)
43−import System.FilePath
43+
44import qualified Data.Text as T
44import qualified Data.Text as T
45import qualified Text.Pandoc.Builder as B
45import qualified Text.Pandoc.Builder as B
46import qualified Text.Pandoc.Walk as Walk
46import qualified Text.Pandoc.Walk as Walk
47−import Text.Pandoc.Sources (ToSources(..))
48
47
49--
48--
50-- parsing blocks
49-- parsing blocks
@@ -528,9 +527,7 @@ include = try $ do
528 _ -> nullAttr
527 _ -> nullAttr
529 return $ pure . B.codeBlockWith attr <$> parseRaw
528 return $ pure . B.codeBlockWith attr <$> parseRaw
530 _ -> return $ return . B.fromList . blockFilter params <$> blockList
529 _ -> return $ return . B.fromList . blockFilter params <$> blockList
531− currentDir <- takeDirectory . sourceName <$> getPosition
530+ insertIncludedFileF blocksParser ["."] filename
532− insertIncludedFile blocksParser toSources
533− [currentDir] filename Nothing Nothing
534 where
531 where
535 includeTarget :: PandocMonad m => OrgParser m FilePath
532 includeTarget :: PandocMonad m => OrgParser m FilePath
536 includeTarget = do
533 includeTarget = do
src/Text/Pandoc/Readers/Org/Inlines.hs+5−6
@@ -29,7 +29,6 @@ import Text.Pandoc.Definition
29import Text.Pandoc.Options
29import Text.Pandoc.Options
30import Text.Pandoc.Readers.LaTeX (inlineCommand, rawLaTeXInline)
30import Text.Pandoc.Readers.LaTeX (inlineCommand, rawLaTeXInline)
31import Text.TeXMath (DisplayType (..), readTeX, writePandoc)
31import Text.TeXMath (DisplayType (..), readTeX, writePandoc)
32−import Text.Pandoc.Sources (ToSources(..))
33import qualified Text.TeXMath.Readers.MathML.EntityMap as MathMLEntityMap
32import qualified Text.TeXMath.Readers.MathML.EntityMap as MathMLEntityMap
34
33
35import Control.Monad (guard, mplus, mzero, unless, void, when)
34import Control.Monad (guard, mplus, mzero, unless, void, when)
@@ -263,7 +262,7 @@ berkeleyCitationList = try $ do
263 where
262 where
264 citationListPart :: PandocMonad m => OrgParser m (F Inlines)
263 citationListPart :: PandocMonad m => OrgParser m (F Inlines)
265 citationListPart = fmap (trimInlinesF . mconcat) . try . many1 $ do
264 citationListPart = fmap (trimInlinesF . mconcat) . try . many1 $ do
266− notFollowedBy' $ citeKey False
265+ notFollowedBy' citeKey
267 notFollowedBy (oneOf ";]")
266 notFollowedBy (oneOf ";]")
268 inline
267 inline
269
268
@@ -278,7 +277,7 @@ berkeleyBareTag' = try $ void (string "cite")
278
277
279berkeleyTextualCite :: PandocMonad m => OrgParser m (F [Citation])
278berkeleyTextualCite :: PandocMonad m => OrgParser m (F [Citation])
280berkeleyTextualCite = try $ do
279berkeleyTextualCite = try $ do
281− (suppressAuthor, key) <- citeKey False
280+ (suppressAuthor, key) <- citeKey
282 returnF . return $ Citation
281 returnF . return $ Citation
283 { citationId = key
282 { citationId = key
284 , citationPrefix = mempty
283 , citationPrefix = mempty
@@ -351,7 +350,7 @@ citeList = sequence <$> sepEndBy1 citation (try $ char ';' *> skipSpaces)
351citation :: PandocMonad m => OrgParser m (F Citation)
350citation :: PandocMonad m => OrgParser m (F Citation)
352citation = try $ do
351citation = try $ do
353 pref <- prefix
352 pref <- prefix
354− (suppress_author, key) <- citeKey False
353+ (suppress_author, key) <- citeKey
355 suff <- suffix
354 suff <- suffix
356 return $ do
355 return $ do
357 x <- pref
356 x <- pref
@@ -368,7 +367,7 @@ citation = try $ do
368 }
367 }
369 where
368 where
370 prefix = trimInlinesF . mconcat <$>
369 prefix = trimInlinesF . mconcat <$>
371− manyTill inline (char ']' <|> (']' <$ lookAhead (citeKey False)))
370+ manyTill inline (char ']' <|> (']' <$ lookAhead citeKey))
372 suffix = try $ do
371 suffix = try $ do
373 hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
372 hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
374 skipSpaces
373 skipSpaces
@@ -803,7 +802,7 @@ inlineLaTeX = try $ do
803 parseAsInlineLaTeX :: PandocMonad m
802 parseAsInlineLaTeX :: PandocMonad m
804 => Text -> TeXExport -> OrgParser m (Maybe Inlines)
803 => Text -> TeXExport -> OrgParser m (Maybe Inlines)
805 parseAsInlineLaTeX cs = \case
804 parseAsInlineLaTeX cs = \case
806− TeXExport -> maybeRight <$> runParserT inlineCommand state "" (toSources cs)
805+ TeXExport -> maybeRight <$> runParserT inlineCommand state "" cs
807 TeXIgnore -> return (Just mempty)
806 TeXIgnore -> return (Just mempty)
808 TeXVerbatim -> return (Just $ B.str cs)
807 TeXVerbatim -> return (Just $ B.str cs)
809
808
src/Text/Pandoc/Readers/Org/Parsing.hs+3−3
@@ -63,7 +63,8 @@ module Text.Pandoc.Readers.Org.Parsing
63 , ellipses
63 , ellipses
64 , citeKey
64 , citeKey
65 , gridTableWith
65 , gridTableWith
66− , insertIncludedFile
66+ , insertIncludedFileF
67+ -- * Re-exports from Text.Pandoc.Parsec
67 , runParser
68 , runParser
68 , runParserT
69 , runParserT
69 , getInput
70 , getInput
@@ -99,7 +100,6 @@ module Text.Pandoc.Readers.Org.Parsing
99 , getState
100 , getState
100 , updateState
101 , updateState
101 , SourcePos
102 , SourcePos
102− , sourceName
103 , getPosition
103 , getPosition
104 ) where
104 ) where
105
105
@@ -114,7 +114,7 @@ import Control.Monad (guard)
114import Control.Monad.Reader (ReaderT)
114import Control.Monad.Reader (ReaderT)
115
115
116-- | The parser used to read org files.
116-- | The parser used to read org files.
117−type OrgParser m = ParserT Sources OrgParserState (ReaderT OrgParserLocal m)
117+type OrgParser m = ParserT Text OrgParserState (ReaderT OrgParserLocal m)
118
118
119--
119--
120-- Adaptions and specializations of parsing utilities
120-- Adaptions and specializations of parsing utilities
src/Text/Pandoc/Readers/RST.hs+109−76
@@ -27,7 +27,8 @@ import Data.Text (Text)
27import qualified Data.Text as T
27import qualified Data.Text as T
28import Text.Pandoc.Builder (Blocks, Inlines, fromList, setMeta, trimInlines)
28import Text.Pandoc.Builder (Blocks, Inlines, fromList, setMeta, trimInlines)
29import qualified Text.Pandoc.Builder as B
29import qualified Text.Pandoc.Builder as B
30−import Text.Pandoc.Class.PandocMonad (PandocMonad, fetchItem, getTimestamp)
30+import Text.Pandoc.Class.PandocMonad (PandocMonad, fetchItem,
31+ readFileFromDirs, getTimestamp)
31import Text.Pandoc.CSV (CSVOptions (..), defaultCSVOptions, parseCSV)
32import Text.Pandoc.CSV (CSVOptions (..), defaultCSVOptions, parseCSV)
32import Text.Pandoc.Definition
33import Text.Pandoc.Definition
33import Text.Pandoc.Error
34import Text.Pandoc.Error
@@ -37,25 +38,25 @@ import Text.Pandoc.Options
37import Text.Pandoc.Parsing
38import Text.Pandoc.Parsing
38import Text.Pandoc.Shared
39import Text.Pandoc.Shared
39import qualified Text.Pandoc.UTF8 as UTF8
40import qualified Text.Pandoc.UTF8 as UTF8
41+import Text.Printf (printf)
40import Data.Time.Format
42import Data.Time.Format
41−import System.FilePath (takeDirectory)
42
43
43-- TODO:
44-- TODO:
44-- [ ] .. parsed-literal
45-- [ ] .. parsed-literal
45
46
46-- | Parse reStructuredText string and return Pandoc document.
47-- | Parse reStructuredText string and return Pandoc document.
47−readRST :: (PandocMonad m, ToSources a)
48+readRST :: PandocMonad m
48 => ReaderOptions -- ^ Reader options
49 => ReaderOptions -- ^ Reader options
49− -> a
50+ -> Text -- ^ Text to parse (assuming @'\n'@ line endings)
50 -> m Pandoc
51 -> m Pandoc
51readRST opts s = do
52readRST opts s = do
52 parsed <- readWithM parseRST def{ stateOptions = opts }
53 parsed <- readWithM parseRST def{ stateOptions = opts }
53− (ensureFinalNewlines 2 (toSources s))
54+ (crFilter s <> "\n\n")
54 case parsed of
55 case parsed of
55 Right result -> return result
56 Right result -> return result
56 Left e -> throwError e
57 Left e -> throwError e
57
58
58−type RSTParser m = ParserT Sources ParserState m
59+type RSTParser m = ParserT Text ParserState m
59
60
60--
61--
61-- Constants and data structure definitions
62-- Constants and data structure definitions
@@ -150,19 +151,11 @@ parseRST = do
150 startPos <- getPosition
151 startPos <- getPosition
151 -- go through once just to get list of reference keys and notes
152 -- go through once just to get list of reference keys and notes
152 -- docMinusKeys is the raw document with blanks where the keys were...
153 -- docMinusKeys is the raw document with blanks where the keys were...
154+ docMinusKeys <- T.concat <$>
153− let chunk = referenceKey
155+ manyTill (referenceKey <|> anchorDef <|>
154− <|> anchorDef
155− <|> noteBlock
156− <|> citationBlock
156+ noteBlock <|> citationBlock <|>
157− <|> (snd <$> withRaw comment)
157+ (snd <$> withRaw comment) <|>
158− <|> headerBlock
158+ headerBlock <|> lineClump) eof
159− <|> lineClump
160− docMinusKeys <- Sources <$>
161− manyTill (do pos <- getPosition
162− t <- chunk
163− return (pos, t)) eof
164− -- UGLY: we collapse source position information.
165− -- TODO: fix the parser to use the F monad instead of two passes
166 setInput docMinusKeys
159 setInput docMinusKeys
167 setPosition startPos
160 setPosition startPos
168 st' <- getState
161 st' <- getState
@@ -355,7 +348,7 @@ singleHeader' = try $ do
355-- hrule block
348-- hrule block
356--
349--
357
350
358−hrule :: Monad m => ParserT Sources st m Blocks
351+hrule :: Monad m => ParserT Text st m Blocks
359hrule = try $ do
352hrule = try $ do
360 chr <- oneOf underlineChars
353 chr <- oneOf underlineChars
361 count 3 (char chr)
354 count 3 (char chr)
@@ -370,7 +363,7 @@ hrule = try $ do
370
363
371-- read a line indented by a given string
364-- read a line indented by a given string
372indentedLine :: (HasReaderOptions st, Monad m)
365indentedLine :: (HasReaderOptions st, Monad m)
373− => Int -> ParserT Sources st m Text
366+ => Int -> ParserT Text st m Text
374indentedLine indents = try $ do
367indentedLine indents = try $ do
375 lookAhead spaceChar
368 lookAhead spaceChar
376 gobbleAtMostSpaces indents
369 gobbleAtMostSpaces indents
@@ -379,7 +372,7 @@ indentedLine indents = try $ do
379-- one or more indented lines, possibly separated by blank lines.
372-- one or more indented lines, possibly separated by blank lines.
380-- any amount of indentation will work.
373-- any amount of indentation will work.
381indentedBlock :: (HasReaderOptions st, Monad m)
374indentedBlock :: (HasReaderOptions st, Monad m)
382− => ParserT Sources st m Text
375+ => ParserT Text st m Text
383indentedBlock = try $ do
376indentedBlock = try $ do
384 indents <- length <$> lookAhead (many1 spaceChar)
377 indents <- length <$> lookAhead (many1 spaceChar)
385 lns <- many1 $ try $ do b <- option "" blanklines
378 lns <- many1 $ try $ do b <- option "" blanklines
@@ -388,20 +381,20 @@ indentedBlock = try $ do
388 optional blanklines
381 optional blanklines
389 return $ T.unlines lns
382 return $ T.unlines lns
390
383
391−quotedBlock :: Monad m => ParserT Sources st m Text
384+quotedBlock :: Monad m => ParserT Text st m Text
392quotedBlock = try $ do
385quotedBlock = try $ do
393 quote <- lookAhead $ oneOf "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
386 quote <- lookAhead $ oneOf "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
394 lns <- many1 $ lookAhead (char quote) >> anyLine
387 lns <- many1 $ lookAhead (char quote) >> anyLine
395 optional blanklines
388 optional blanklines
396 return $ T.unlines lns
389 return $ T.unlines lns
397
390
398−codeBlockStart :: Monad m => ParserT Sources st m Char
391+codeBlockStart :: Monad m => ParserT Text st m Char
399codeBlockStart = string "::" >> blankline >> blankline
392codeBlockStart = string "::" >> blankline >> blankline
400
393
401−codeBlock :: Monad m => ParserT Sources ParserState m Blocks
394+codeBlock :: Monad m => ParserT Text ParserState m Blocks
402codeBlock = try $ codeBlockStart >> codeBlockBody
395codeBlock = try $ codeBlockStart >> codeBlockBody
403
396
404−codeBlockBody :: Monad m => ParserT Sources ParserState m Blocks
397+codeBlockBody :: Monad m => ParserT Text ParserState m Blocks
405codeBlockBody = do
398codeBlockBody = do
406 lang <- stateRstHighlight <$> getState
399 lang <- stateRstHighlight <$> getState
407 try $ B.codeBlockWith ("", maybeToList lang, []) . stripTrailingNewlines <$>
400 try $ B.codeBlockWith ("", maybeToList lang, []) . stripTrailingNewlines <$>
@@ -417,14 +410,14 @@ lhsCodeBlock = try $ do
417 return $ B.codeBlockWith ("", ["haskell","literate"], [])
410 return $ B.codeBlockWith ("", ["haskell","literate"], [])
418 $ T.intercalate "\n" lns
411 $ T.intercalate "\n" lns
419
412
420−latexCodeBlock :: Monad m => ParserT Sources st m [Text]
413+latexCodeBlock :: Monad m => ParserT Text st m [Text]
421latexCodeBlock = try $ do
414latexCodeBlock = try $ do
422 try (latexBlockLine "\\begin{code}")
415 try (latexBlockLine "\\begin{code}")
423 many1Till anyLine (try $ latexBlockLine "\\end{code}")
416 many1Till anyLine (try $ latexBlockLine "\\end{code}")
424 where
417 where
425 latexBlockLine s = skipMany spaceChar >> string s >> blankline
418 latexBlockLine s = skipMany spaceChar >> string s >> blankline
426
419
427−birdCodeBlock :: Monad m => ParserT Sources st m [Text]
420+birdCodeBlock :: Monad m => ParserT Text st m [Text]
428birdCodeBlock = filterSpace <$> many1 birdTrackLine
421birdCodeBlock = filterSpace <$> many1 birdTrackLine
429 where filterSpace lns =
422 where filterSpace lns =
430 -- if (as is normal) there is always a space after >, drop it
423 -- if (as is normal) there is always a space after >, drop it
@@ -432,7 +425,7 @@ birdCodeBlock = filterSpace <$> many1 birdTrackLine
432 then map (T.drop 1) lns
425 then map (T.drop 1) lns
433 else lns
426 else lns
434
427
435−birdTrackLine :: Monad m => ParserT Sources st m Text
428+birdTrackLine :: Monad m => ParserT Text st m Text
436birdTrackLine = char '>' >> anyLine
429birdTrackLine = char '>' >> anyLine
437
430
438--
431--
@@ -453,39 +446,64 @@ encoding
453-}
446-}
454
447
455includeDirective :: PandocMonad m
448includeDirective :: PandocMonad m
456− => Text
457− -> [(Text, Text)]
449+ => Text -> [(Text, Text)] -> Text
458− -> Text
459 -> RSTParser m Blocks
450 -> RSTParser m Blocks
460includeDirective top fields body = do
451includeDirective top fields body = do
461− let f = T.unpack $ trim top
452+ let f = trim top
462− guard $ not $ null f
453+ guard $ not (T.null f)
463 guard $ T.null (trim body)
454 guard $ T.null (trim body)
455+ -- options
464− let startLine = lookup "start-line" fields >>= safeRead
456+ let (startLine :: Maybe Int) = lookup "start-line" fields >>= safeRead
465− let endLine = lookup "end-line" fields >>= safeRead
457+ let (endLine :: Maybe Int) = lookup "end-line" fields >>= safeRead
458+ oldPos <- getPosition
459+ oldInput <- getInput
460+ containers <- stateContainers <$> getState
461+ when (f `elem` containers) $
462+ throwError $ PandocParseError $ "Include file loop at " <> tshow oldPos
463+ updateState $ \s -> s{ stateContainers = f : stateContainers s }
464+ mbContents <- readFileFromDirs ["."] $ T.unpack f
465+ contentLines <- case mbContents of
466+ Just s -> return $ T.lines s
467+ Nothing -> do
468+ logMessage $ CouldNotLoadIncludeFile f oldPos
469+ return []
470+ let numLines = length contentLines
471+ let startLine' = case startLine of
472+ Nothing -> 1
473+ Just x | x >= 0 -> x
474+ | otherwise -> numLines + x -- negative from end
475+ let endLine' = case endLine of
476+ Nothing -> numLines + 1
477+ Just x | x >= 0 -> x
478+ | otherwise -> numLines + x -- negative from end
479+ let contentLines' = drop (startLine' - 1)
480+ $ take (endLine' - 1) contentLines
481+ let contentLines'' = (case trim <$> lookup "end-before" fields of
482+ Just patt -> takeWhile (not . (patt `T.isInfixOf`))
483+ Nothing -> id) .
484+ (case trim <$> lookup "start-after" fields of
485+ Just patt -> drop 1 .
486+ dropWhile (not . (patt `T.isInfixOf`))
487+ Nothing -> id) $ contentLines'
488+ let contents' = T.unlines contentLines''
489+ case lookup "code" fields of
490+ Just lang -> do
466− let classes = maybe [] T.words (lookup "class" fields)
491+ let classes = maybe [] T.words (lookup "class" fields)
467− let ident = maybe "" trimr $ lookup "name" fields
492+ let ident = maybe "" trimr $ lookup "name" fields
468− let parser =
469− case lookup "code" fields of
470− Just lang ->
471− (codeblock ident classes fields (trimr lang) False
493+ codeblock ident classes fields (trimr lang) contents' False
472− . sourcesToText) <$> getInput
473− Nothing ->
474− case lookup "literal" fields of
494+ Nothing -> case lookup "literal" fields of
475− Just _ -> B.rawBlock "rst" . sourcesToText <$> getInput
495+ Just _ -> return $ B.rawBlock "rst" contents'
476− Nothing -> parseBlocks
496+ Nothing -> do
477− let selectLines =
497+ setPosition $ newPos (T.unpack f) 1 1
478− (case trim <$> lookup "end-before" fields of
498+ setInput $ contents' <> "\n"
479− Just patt -> takeWhile (not . (patt `T.isInfixOf`))
499+ bs <- optional blanklines >>
480− Nothing -> id) .
500+ (mconcat <$> many block)
481− (case trim <$> lookup "start-after" fields of
501+ setInput oldInput
482− Just patt -> drop 1 .
502+ setPosition oldPos
483− dropWhile (not . (patt `T.isInfixOf`))
503+ updateState $ \s -> s{ stateContainers =
484− Nothing -> id)
504+ tail $ stateContainers s }
485− let toStream t =
505+ return bs
486− toSources [(f, T.unlines . selectLines . T.lines $ t)]
506+
487− currentDir <- takeDirectory . sourceName <$> getPosition
488− insertIncludedFile parser toStream [currentDir] f startLine endLine
489
507
490--
508--
491-- list blocks
509-- list blocks
@@ -508,7 +526,7 @@ definitionList :: PandocMonad m => RSTParser m Blocks
508definitionList = B.definitionList <$> many1 definitionListItem
526definitionList = B.definitionList <$> many1 definitionListItem
509
527
510-- parses bullet list start and returns its length (inc. following whitespace)
528-- parses bullet list start and returns its length (inc. following whitespace)
511−bulletListStart :: Monad m => ParserT Sources st m Int
529+bulletListStart :: Monad m => ParserT Text st m Int
512bulletListStart = try $ do
530bulletListStart = try $ do
513 notFollowedBy' hrule -- because hrules start out just like lists
531 notFollowedBy' hrule -- because hrules start out just like lists
514 marker <- oneOf bulletListMarkers
532 marker <- oneOf bulletListMarkers
@@ -714,8 +732,8 @@ directive' = do
714 "" -> stateRstHighlight def
732 "" -> stateRstHighlight def
715 lang -> Just lang })
733 lang -> Just lang })
716 x | x == "code" || x == "code-block" || x == "sourcecode" ->
734 x | x == "code" || x == "code-block" || x == "sourcecode" ->
717− return $ codeblock name classes (map (second trimr) fields)
735+ codeblock name classes (map (second trimr) fields)
718− (trim top) True body
736+ (trim top) body True
719 "aafig" -> do
737 "aafig" -> do
720 let attribs = (name, ["aafig"], map (second trimr) fields)
738 let attribs = (name, ["aafig"], map (second trimr) fields)
721 return $ B.codeBlockWith attribs $ stripTrailingNewlines body
739 return $ B.codeBlockWith attribs $ stripTrailingNewlines body
@@ -1001,10 +1019,10 @@ toChunks = dropWhile T.null
1001 then "\\begin{aligned}\n" <> s <> "\n\\end{aligned}"
1019 then "\\begin{aligned}\n" <> s <> "\n\\end{aligned}"
1002 else s
1020 else s
1003
1021
1004−codeblock :: Text -> [Text] -> [(Text, Text)] -> Text -> Bool -> Text
1022+codeblock :: Text -> [Text] -> [(Text, Text)] -> Text -> Text -> Bool
1005− -> Blocks
1023+ -> RSTParser m Blocks
1006−codeblock ident classes fields lang rmTrailingNewlines body =
1024+codeblock ident classes fields lang body rmTrailingNewlines =
1007− B.codeBlockWith attribs $ stripTrailingNewlines' body
1025+ return $ B.codeBlockWith attribs $ stripTrailingNewlines' body
1008 where stripTrailingNewlines' = if rmTrailingNewlines
1026 where stripTrailingNewlines' = if rmTrailingNewlines
1009 then stripTrailingNewlines
1027 then stripTrailingNewlines
1010 else id
1028 else id
@@ -1085,7 +1103,7 @@ quotedReferenceName = try $ do
1085-- plus isolated (no two adjacent) internal hyphens, underscores,
1103-- plus isolated (no two adjacent) internal hyphens, underscores,
1086-- periods, colons and plus signs; no whitespace or other characters
1104-- periods, colons and plus signs; no whitespace or other characters
1087-- are allowed.
1105-- are allowed.
1088−simpleReferenceName :: Monad m => ParserT Sources st m Text
1106+simpleReferenceName :: Monad m => ParserT Text st m Text
1089simpleReferenceName = do
1107simpleReferenceName = do
1090 x <- alphaNum
1108 x <- alphaNum
1091 xs <- many $ alphaNum
1109 xs <- many $ alphaNum
@@ -1104,7 +1122,7 @@ referenceKey = do
1104 -- return enough blanks to replace key
1122 -- return enough blanks to replace key
1105 return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
1123 return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
1106
1124
1107−targetURI :: Monad m => ParserT Sources st m Text
1125+targetURI :: Monad m => ParserT Text st m Text
1108targetURI = do
1126targetURI = do
1109 skipSpaces
1127 skipSpaces
1110 optional $ try $ newline >> notFollowedBy blankline
1128 optional $ try $ newline >> notFollowedBy blankline
@@ -1142,10 +1160,8 @@ anonymousKey :: Monad m => RSTParser m ()
1142anonymousKey = try $ do
1160anonymousKey = try $ do
1143 oneOfStrings [".. __:", "__"]
1161 oneOfStrings [".. __:", "__"]
1144 src <- targetURI
1162 src <- targetURI
1145− -- we need to ensure that the keys are ordered by occurrence in
1163+ pos <- getPosition
1146− -- the document.
1147− numKeys <- M.size . stateKeys <$> getState
1148− let key = toKey $ "_" <> T.pack (show numKeys)
1164+ let key = toKey $ "_" <> T.pack (printf "%09d" (sourceLine pos))
1149 updateState $ \s -> s { stateKeys = M.insert key ((src,""), nullAttr) $
1165 updateState $ \s -> s { stateKeys = M.insert key ((src,""), nullAttr) $
1150 stateKeys s }
1166 stateKeys s }
1151
1167
@@ -1234,13 +1250,13 @@ headerBlock = do
1234-- Grid tables TODO:
1250-- Grid tables TODO:
1235-- - column spans
1251-- - column spans
1236
1252
1237−dashedLine :: Monad m => Char -> ParserT Sources st m (Int, Int)
1253+dashedLine :: Monad m => Char -> ParserT Text st m (Int, Int)
1238dashedLine ch = do
1254dashedLine ch = do
1239 dashes <- many1 (char ch)
1255 dashes <- many1 (char ch)
1240 sp <- many (char ' ')
1256 sp <- many (char ' ')
1241 return (length dashes, length $ dashes ++ sp)
1257 return (length dashes, length $ dashes ++ sp)
1242
1258
1243−simpleDashedLines :: Monad m => Char -> ParserT Sources st m [(Int,Int)]
1259+simpleDashedLines :: Monad m => Char -> ParserT Text st m [(Int,Int)]
1244simpleDashedLines ch = try $ many1 (dashedLine ch)
1260simpleDashedLines ch = try $ many1 (dashedLine ch)
1245
1261
1246-- Parse a table row separator
1262-- Parse a table row separator
@@ -1366,7 +1382,7 @@ hyphens = do
1366 -- don't want to treat endline after hyphen or dash as a space
1382 -- don't want to treat endline after hyphen or dash as a space
1367 return $ B.str result
1383 return $ B.str result
1368
1384
1369−escapedChar :: Monad m => ParserT Sources st m Inlines
1385+escapedChar :: Monad m => ParserT Text st m Inlines
1370escapedChar = do c <- escaped anyChar
1386escapedChar = do c <- escaped anyChar
1371 return $ if c == ' ' || c == '\n' || c == '\r'
1387 return $ if c == ' ' || c == '\n' || c == '\r'
1372 -- '\ ' is null in RST
1388 -- '\ ' is null in RST
@@ -1642,4 +1658,21 @@ note = try $ do
1642 return $ B.note contents
1658 return $ B.note contents
1643
1659
1644smart :: PandocMonad m => RSTParser m Inlines
1660smart :: PandocMonad m => RSTParser m Inlines
1645−smart = smartPunctuation inline
1661+smart = do
1662+ guardEnabled Ext_smart
1663+ doubleQuoted <|> singleQuoted <|>
1664+ choice [apostrophe, dash, ellipses]
1665+
1666+singleQuoted :: PandocMonad m => RSTParser m Inlines
1667+singleQuoted = try $ do
1668+ singleQuoteStart
1669+ withQuoteContext InSingleQuote $
1670+ B.singleQuoted . trimInlines . mconcat <$>
1671+ many1Till inline singleQuoteEnd
1672+
1673+doubleQuoted :: PandocMonad m => RSTParser m Inlines
1674+doubleQuoted = try $ do
1675+ doubleQuoteStart
1676+ withQuoteContext InDoubleQuote $
1677+ B.doubleQuoted . trimInlines . mconcat <$>
1678+ many1Till inline doubleQuoteEnd
src/Text/Pandoc/Readers/Roff.hs+18−16
@@ -42,6 +42,7 @@ import Text.Pandoc.Logging (LogMessage(..))
42import Text.Pandoc.Options
42import Text.Pandoc.Options
43import Text.Pandoc.Parsing
43import Text.Pandoc.Parsing
44import Text.Pandoc.Shared (safeRead)
44import Text.Pandoc.Shared (safeRead)
45+import Text.Parsec hiding (tokenPrim)
45import Text.Pandoc.RoffChar (characterCodes, combiningAccents)
46import Text.Pandoc.RoffChar (characterCodes, combiningAccents)
46import qualified Data.Sequence as Seq
47import qualified Data.Sequence as Seq
47import qualified Data.Foldable as Foldable
48import qualified Data.Foldable as Foldable
@@ -121,16 +122,16 @@ instance Default RoffState where
121 , afterConditional = False
122 , afterConditional = False
122 }
123 }
123
124
124−type RoffLexer m = ParserT Sources RoffState m
125+type RoffLexer m = ParserT T.Text RoffState m
125
126
126--
127--
127-- Lexer: T.Text -> RoffToken
128-- Lexer: T.Text -> RoffToken
128--
129--
129
130
130−eofline :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s u m ()
131+eofline :: Stream s m Char => ParsecT s u m ()
131eofline = void newline <|> eof <|> () <$ lookAhead (string "\\}")
132eofline = void newline <|> eof <|> () <$ lookAhead (string "\\}")
132
133
133−spacetab :: (Stream s m Char, UpdateSourcePos s Char) => ParserT s u m Char
134+spacetab :: Stream s m Char => ParsecT s u m Char
134spacetab = char ' ' <|> char '\t'
135spacetab = char ' ' <|> char '\t'
135
136
136characterCodeMap :: M.Map T.Text Char
137characterCodeMap :: M.Map T.Text Char
@@ -302,7 +303,8 @@ expandString = try $ do
302 char '*'
303 char '*'
303 cs <- escapeArg <|> countChar 1 anyChar
304 cs <- escapeArg <|> countChar 1 anyChar
304 s <- linePartsToText <$> resolveText cs pos
305 s <- linePartsToText <$> resolveText cs pos
305− addToInput s
306+ getInput >>= setInput . (s <>)
307+ return ()
306
308
307-- Parses: '..'
309-- Parses: '..'
308quoteArg :: PandocMonad m => RoffLexer m T.Text
310quoteArg :: PandocMonad m => RoffLexer m T.Text
@@ -314,7 +316,7 @@ escFont = do
314 font' <- if T.null font || font == "P"
316 font' <- if T.null font || font == "P"
315 then prevFont <$> getState
317 then prevFont <$> getState
316 else return $ foldr processFontLetter defaultFontSpec $ T.unpack font
318 else return $ foldr processFontLetter defaultFontSpec $ T.unpack font
317− updateState $ \st -> st{ prevFont = currentFont st
319+ modifyState $ \st -> st{ prevFont = currentFont st
318 , currentFont = font' }
320 , currentFont = font' }
319 return [Font font']
321 return [Font font']
320 where
322 where
@@ -370,8 +372,8 @@ lexTable pos = do
370 spaces
372 spaces
371 opts <- try tableOptions <|> [] <$ optional (char ';')
373 opts <- try tableOptions <|> [] <$ optional (char ';')
372 case lookup "tab" opts of
374 case lookup "tab" opts of
373− Just (T.uncons -> Just (c, _)) -> updateState $ \st -> st{ tableTabChar = c }
375+ Just (T.uncons -> Just (c, _)) -> modifyState $ \st -> st{ tableTabChar = c }
374− _ -> updateState $ \st -> st{ tableTabChar = '\t' }
376+ _ -> modifyState $ \st -> st{ tableTabChar = '\t' }
375 spaces
377 spaces
376 skipMany lexComment
378 skipMany lexComment
377 spaces
379 spaces
@@ -487,18 +489,18 @@ lexConditional mname = do
487 ifPart <- do
489 ifPart <- do
488 optional $ try $ char '\\' >> newline
490 optional $ try $ char '\\' >> newline
489 lexGroup
491 lexGroup
490− <|> do updateState $ \s -> s{ afterConditional = True }
492+ <|> do modifyState $ \s -> s{ afterConditional = True }
491 t <- manToken
493 t <- manToken
492− updateState $ \s -> s{ afterConditional = False }
494+ modifyState $ \s -> s{ afterConditional = False }
493 return t
495 return t
494 case mbtest of
496 case mbtest of
495 Nothing -> do
497 Nothing -> do
496− setState st -- reset state, so we don't record macros in skipped section
498+ putState st -- reset state, so we don't record macros in skipped section
497 report $ SkippedContent (T.cons '.' mname) pos
499 report $ SkippedContent (T.cons '.' mname) pos
498 return mempty
500 return mempty
499 Just True -> return ifPart
501 Just True -> return ifPart
500 Just False -> do
502 Just False -> do
501− setState st
503+ putState st
502 return mempty
504 return mempty
503
505
504expression :: PandocMonad m => RoffLexer m (Maybe Bool)
506expression :: PandocMonad m => RoffLexer m (Maybe Bool)
@@ -513,7 +515,7 @@ expression = do
513 _ -> Nothing
515 _ -> Nothing
514 where
516 where
515 returnValue v = do
517 returnValue v = do
516− updateState $ \st -> st{ lastExpression = v }
518+ modifyState $ \st -> st{ lastExpression = v }
517 return v
519 return v
518
520
519lexGroup :: PandocMonad m => RoffLexer m RoffTokens
521lexGroup :: PandocMonad m => RoffLexer m RoffTokens
@@ -534,7 +536,7 @@ lexIncludeFile args = do
534 result <- readFileFromDirs dirs $ T.unpack fp
536 result <- readFileFromDirs dirs $ T.unpack fp
535 case result of
537 case result of
536 Nothing -> report $ CouldNotLoadIncludeFile fp pos
538 Nothing -> report $ CouldNotLoadIncludeFile fp pos
537− Just s -> addToInput s
539+ Just s -> getInput >>= setInput . (s <>)
538 return mempty
540 return mempty
539 [] -> return mempty
541 [] -> return mempty
540
542
@@ -562,13 +564,13 @@ lexStringDef args = do -- string definition
562 (x:ys) -> do
564 (x:ys) -> do
563 let ts = singleTok $ TextLine (intercalate [RoffStr " " ] ys)
565 let ts = singleTok $ TextLine (intercalate [RoffStr " " ] ys)
564 let stringName = linePartsToText x
566 let stringName = linePartsToText x
565− updateState $ \st ->
567+ modifyState $ \st ->
566 st{ customMacros = M.insert stringName ts (customMacros st) }
568 st{ customMacros = M.insert stringName ts (customMacros st) }
567 return mempty
569 return mempty
568
570
569lexMacroDef :: PandocMonad m => [Arg] -> RoffLexer m RoffTokens
571lexMacroDef :: PandocMonad m => [Arg] -> RoffLexer m RoffTokens
570lexMacroDef args = do -- macro definition
572lexMacroDef args = do -- macro definition
571− updateState $ \st -> st{ roffMode = CopyMode }
573+ modifyState $ \st -> st{ roffMode = CopyMode }
572 (macroName, stopMacro) <-
574 (macroName, stopMacro) <-
573 case args of
575 case args of
574 (x : y : _) -> return (linePartsToText x, linePartsToText y)
576 (x : y : _) -> return (linePartsToText x, linePartsToText y)
@@ -582,7 +584,7 @@ lexMacroDef args = do -- macro definition
582 _ <- lexArgs
584 _ <- lexArgs
583 return ()
585 return ()
584 ts <- mconcat <$> manyTill manToken stop
586 ts <- mconcat <$> manyTill manToken stop
585− updateState $ \st ->
587+ modifyState $ \st ->
586 st{ customMacros = M.insert macroName ts (customMacros st)
588 st{ customMacros = M.insert macroName ts (customMacros st)
587 , roffMode = NormalMode }
589 , roffMode = NormalMode }
588 return mempty
590 return mempty
src/Text/Pandoc/Readers/TWiki.hs+27−7
@@ -28,22 +28,22 @@ import Text.Pandoc.Definition
28import Text.Pandoc.Options
28import Text.Pandoc.Options
29import Text.Pandoc.Parsing hiding (enclosed, nested)
29import Text.Pandoc.Parsing hiding (enclosed, nested)
30import Text.Pandoc.Readers.HTML (htmlTag, isCommentTag)
30import Text.Pandoc.Readers.HTML (htmlTag, isCommentTag)
31−import Text.Pandoc.Shared (tshow)
31+import Text.Pandoc.Shared (crFilter, tshow)
32import Text.Pandoc.XML (fromEntities)
32import Text.Pandoc.XML (fromEntities)
33
33
34-- | Read twiki from an input string and return a Pandoc document.
34-- | Read twiki from an input string and return a Pandoc document.
35−readTWiki :: (PandocMonad m, ToSources a)
35+readTWiki :: PandocMonad m
36 => ReaderOptions
36 => ReaderOptions
37− -> a
37+ -> Text
38 -> m Pandoc
38 -> m Pandoc
39readTWiki opts s = do
39readTWiki opts s = do
40− let sources = ensureFinalNewlines 2 (toSources s)
41− res <- readWithM parseTWiki def{ stateOptions = opts } sources
40+ res <- readWithM parseTWiki def{ stateOptions = opts }
41+ (crFilter s <> "\n\n")
42 case res of
42 case res of
43 Left e -> throwError e
43 Left e -> throwError e
44 Right d -> return d
44 Right d -> return d
45
45
46−type TWParser = ParserT Sources ParserState
46+type TWParser = ParserT Text ParserState
47
47
48--
48--
49-- utility functions
49-- utility functions
@@ -469,7 +469,27 @@ symbol :: PandocMonad m => TWParser m B.Inlines
469symbol = B.str <$> countChar 1 nonspaceChar
469symbol = B.str <$> countChar 1 nonspaceChar
470
470
471smart :: PandocMonad m => TWParser m B.Inlines
471smart :: PandocMonad m => TWParser m B.Inlines
472−smart = smartPunctuation inline
472+smart = do
473+ guardEnabled Ext_smart
474+ doubleQuoted <|> singleQuoted <|>
475+ choice [ apostrophe
476+ , dash
477+ , ellipses
478+ ]
479+
480+singleQuoted :: PandocMonad m => TWParser m B.Inlines
481+singleQuoted = try $ do
482+ singleQuoteStart
483+ withQuoteContext InSingleQuote
484+ (B.singleQuoted . B.trimInlines . mconcat <$> many1Till inline singleQuoteEnd)
485+
486+doubleQuoted :: PandocMonad m => TWParser m B.Inlines
487+doubleQuoted = try $ do
488+ doubleQuoteStart
489+ contents <- mconcat <$> many (try $ notFollowedBy doubleQuoteEnd >> inline)
490+ withQuoteContext InDoubleQuote (doubleQuoteEnd >>
491+ return (B.doubleQuoted $ B.trimInlines contents))
492+ <|> return (B.str "\8220" B.<> contents)
473
493
474link :: PandocMonad m => TWParser m B.Inlines
494link :: PandocMonad m => TWParser m B.Inlines
475link = try $ do
495link = try $ do
src/Text/Pandoc/Readers/Textile.hs+84−88
@@ -53,34 +53,30 @@ import Text.Pandoc.Options
53import Text.Pandoc.Parsing
53import Text.Pandoc.Parsing
54import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isInlineTag)
54import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isInlineTag)
55import Text.Pandoc.Readers.LaTeX (rawLaTeXBlock, rawLaTeXInline)
55import Text.Pandoc.Readers.LaTeX (rawLaTeXBlock, rawLaTeXInline)
56−import Text.Pandoc.Shared (trim, tshow)
56+import Text.Pandoc.Shared (crFilter, trim, tshow)
57
57
58-- | Parse a Textile text and return a Pandoc document.
58-- | Parse a Textile text and return a Pandoc document.
59−readTextile :: (PandocMonad m, ToSources a)
59+readTextile :: PandocMonad m
60 => ReaderOptions -- ^ Reader options
60 => ReaderOptions -- ^ Reader options
61− -> a
61+ -> Text -- ^ String to parse (assuming @'\n'@ line endings)
62 -> m Pandoc
62 -> m Pandoc
63readTextile opts s = do
63readTextile opts s = do
64− let sources = ensureFinalNewlines 2 (toSources s)
65− parsed <- readWithM parseTextile def{ stateOptions = opts } sources
64+ parsed <- readWithM parseTextile def{ stateOptions = opts }
65+ (crFilter s <> "\n\n")
66 case parsed of
66 case parsed of
67 Right result -> return result
67 Right result -> return result
68 Left e -> throwError e
68 Left e -> throwError e
69
69
70−type TextileParser = ParserT Sources ParserState
71
70
72-- | Generate a Pandoc ADT from a textile document
71-- | Generate a Pandoc ADT from a textile document
73−parseTextile :: PandocMonad m => TextileParser m Pandoc
72+parseTextile :: PandocMonad m => ParserT Text ParserState m Pandoc
74parseTextile = do
73parseTextile = do
75 many blankline
74 many blankline
76 startPos <- getPosition
75 startPos <- getPosition
77 -- go through once just to get list of reference keys and notes
76 -- go through once just to get list of reference keys and notes
78 -- docMinusKeys is the raw document with blanks where the keys/notes were...
77 -- docMinusKeys is the raw document with blanks where the keys/notes were...
79− let firstPassParser = do
80− pos <- getPosition
81− t <- noteBlock <|> lineClump
78+ let firstPassParser = noteBlock <|> lineClump
82− return (pos, t)
83− manyTill firstPassParser eof >>= setInput . Sources
79+ manyTill firstPassParser eof >>= setInput . T.concat
84 setPosition startPos
80 setPosition startPos
85 st' <- getState
81 st' <- getState
86 let reversedNotes = stateNotes st'
82 let reversedNotes = stateNotes st'
@@ -88,10 +84,10 @@ parseTextile = do
88 -- now parse it for real...
84 -- now parse it for real...
89 Pandoc nullMeta . B.toList <$> parseBlocks -- FIXME
85 Pandoc nullMeta . B.toList <$> parseBlocks -- FIXME
90
86
91−noteMarker :: PandocMonad m => TextileParser m Text
87+noteMarker :: PandocMonad m => ParserT Text ParserState m Text
92noteMarker = skipMany spaceChar >> string "fn" >> T.pack <$> manyTill digit (char '.')
88noteMarker = skipMany spaceChar >> string "fn" >> T.pack <$> manyTill digit (char '.')
93
89
94−noteBlock :: PandocMonad m => TextileParser m Text
90+noteBlock :: PandocMonad m => ParserT Text ParserState m Text
95noteBlock = try $ do
91noteBlock = try $ do
96 startPos <- getPosition
92 startPos <- getPosition
97 ref <- noteMarker
93 ref <- noteMarker
@@ -106,11 +102,11 @@ noteBlock = try $ do
106 return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
102 return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
107
103
108-- | Parse document blocks
104-- | Parse document blocks
109−parseBlocks :: PandocMonad m => TextileParser m Blocks
105+parseBlocks :: PandocMonad m => ParserT Text ParserState m Blocks
110parseBlocks = mconcat <$> manyTill block eof
106parseBlocks = mconcat <$> manyTill block eof
111
107
112-- | Block parsers list tried in definition order
108-- | Block parsers list tried in definition order
113−blockParsers :: PandocMonad m => [TextileParser m Blocks]
109+blockParsers :: PandocMonad m => [ParserT Text ParserState m Blocks]
114blockParsers = [ codeBlock
110blockParsers = [ codeBlock
115 , header
111 , header
116 , blockQuote
112 , blockQuote
@@ -125,22 +121,22 @@ blockParsers = [ codeBlock
125 ]
121 ]
126
122
127-- | Any block in the order of definition of blockParsers
123-- | Any block in the order of definition of blockParsers
128−block :: PandocMonad m => TextileParser m Blocks
124+block :: PandocMonad m => ParserT Text ParserState m Blocks
129block = do
125block = do
130 res <- choice blockParsers <?> "block"
126 res <- choice blockParsers <?> "block"
131 trace (T.take 60 $ tshow $ B.toList res)
127 trace (T.take 60 $ tshow $ B.toList res)
132 return res
128 return res
133
129
134−commentBlock :: PandocMonad m => TextileParser m Blocks
130+commentBlock :: PandocMonad m => ParserT Text ParserState m Blocks
135commentBlock = try $ do
131commentBlock = try $ do
136 string "###."
132 string "###."
137 manyTill anyLine blanklines
133 manyTill anyLine blanklines
138 return mempty
134 return mempty
139
135
140−codeBlock :: PandocMonad m => TextileParser m Blocks
136+codeBlock :: PandocMonad m => ParserT Text ParserState m Blocks
141codeBlock = codeBlockTextile <|> codeBlockHtml
137codeBlock = codeBlockTextile <|> codeBlockHtml
142
138
143−codeBlockTextile :: PandocMonad m => TextileParser m Blocks
139+codeBlockTextile :: PandocMonad m => ParserT Text ParserState m Blocks
144codeBlockTextile = try $ do
140codeBlockTextile = try $ do
145 string "bc." <|> string "pre."
141 string "bc." <|> string "pre."
146 extended <- option False (True <$ char '.')
142 extended <- option False (True <$ char '.')
@@ -160,7 +156,7 @@ trimTrailingNewlines :: Text -> Text
160trimTrailingNewlines = T.dropWhileEnd (=='\n')
156trimTrailingNewlines = T.dropWhileEnd (=='\n')
161
157
162-- | Code Blocks in Textile are between <pre> and </pre>
158-- | Code Blocks in Textile are between <pre> and </pre>
163−codeBlockHtml :: PandocMonad m => TextileParser m Blocks
159+codeBlockHtml :: PandocMonad m => ParserT Text ParserState m Blocks
164codeBlockHtml = try $ do
160codeBlockHtml = try $ do
165 (t@(TagOpen _ attrs),_) <- htmlTag (tagOpen (=="pre") (const True))
161 (t@(TagOpen _ attrs),_) <- htmlTag (tagOpen (=="pre") (const True))
166 result' <- T.pack <$> manyTill anyChar (htmlTag (tagClose (=="pre")))
162 result' <- T.pack <$> manyTill anyChar (htmlTag (tagClose (=="pre")))
@@ -178,7 +174,7 @@ codeBlockHtml = try $ do
178 return $ B.codeBlockWith (ident,classes,kvs) result'''
174 return $ B.codeBlockWith (ident,classes,kvs) result'''
179
175
180-- | Header of the form "hN. content" with N in 1..6
176-- | Header of the form "hN. content" with N in 1..6
181−header :: PandocMonad m => TextileParser m Blocks
177+header :: PandocMonad m => ParserT Text ParserState m Blocks
182header = try $ do
178header = try $ do
183 char 'h'
179 char 'h'
184 level <- digitToInt <$> oneOf "123456"
180 level <- digitToInt <$> oneOf "123456"
@@ -190,14 +186,14 @@ header = try $ do
190 return $ B.headerWith attr' level name
186 return $ B.headerWith attr' level name
191
187
192-- | Blockquote of the form "bq. content"
188-- | Blockquote of the form "bq. content"
193−blockQuote :: PandocMonad m => TextileParser m Blocks
189+blockQuote :: PandocMonad m => ParserT Text ParserState m Blocks
194blockQuote = try $ do
190blockQuote = try $ do
195 string "bq" >> attributes >> char '.' >> whitespace
191 string "bq" >> attributes >> char '.' >> whitespace
196 B.blockQuote <$> para
192 B.blockQuote <$> para
197
193
198-- Horizontal rule
194-- Horizontal rule
199
195
200−hrule :: PandocMonad m => TextileParser m Blocks
196+hrule :: PandocMonad m => ParserT Text st m Blocks
201hrule = try $ do
197hrule = try $ do
202 skipSpaces
198 skipSpaces
203 start <- oneOf "-*"
199 start <- oneOf "-*"
@@ -212,39 +208,39 @@ hrule = try $ do
212-- | Can be a bullet list or an ordered list. This implementation is
208-- | Can be a bullet list or an ordered list. This implementation is
213-- strict in the nesting, sublist must start at exactly "parent depth
209-- strict in the nesting, sublist must start at exactly "parent depth
214-- plus one"
210-- plus one"
215−anyList :: PandocMonad m => TextileParser m Blocks
211+anyList :: PandocMonad m => ParserT Text ParserState m Blocks
216anyList = try $ anyListAtDepth 1 <* blanklines
212anyList = try $ anyListAtDepth 1 <* blanklines
217
213
218-- | This allow one type of list to be nested into an other type,
214-- | This allow one type of list to be nested into an other type,
219-- provided correct nesting
215-- provided correct nesting
220−anyListAtDepth :: PandocMonad m => Int -> TextileParser m Blocks
216+anyListAtDepth :: PandocMonad m => Int -> ParserT Text ParserState m Blocks
221anyListAtDepth depth = choice [ bulletListAtDepth depth,
217anyListAtDepth depth = choice [ bulletListAtDepth depth,
222 orderedListAtDepth depth,
218 orderedListAtDepth depth,
223 definitionList ]
219 definitionList ]
224
220
225-- | Bullet List of given depth, depth being the number of leading '*'
221-- | Bullet List of given depth, depth being the number of leading '*'
226−bulletListAtDepth :: PandocMonad m => Int -> TextileParser m Blocks
222+bulletListAtDepth :: PandocMonad m => Int -> ParserT Text ParserState m Blocks
227bulletListAtDepth depth = try $ B.bulletList <$> many1 (bulletListItemAtDepth depth)
223bulletListAtDepth depth = try $ B.bulletList <$> many1 (bulletListItemAtDepth depth)
228
224
229-- | Bullet List Item of given depth, depth being the number of
225-- | Bullet List Item of given depth, depth being the number of
230-- leading '*'
226-- leading '*'
231−bulletListItemAtDepth :: PandocMonad m => Int -> TextileParser m Blocks
227+bulletListItemAtDepth :: PandocMonad m => Int -> ParserT Text ParserState m Blocks
232bulletListItemAtDepth = genericListItemAtDepth '*'
228bulletListItemAtDepth = genericListItemAtDepth '*'
233
229
234-- | Ordered List of given depth, depth being the number of
230-- | Ordered List of given depth, depth being the number of
235-- leading '#'
231-- leading '#'
236−orderedListAtDepth :: PandocMonad m => Int -> TextileParser m Blocks
232+orderedListAtDepth :: PandocMonad m => Int -> ParserT Text ParserState m Blocks
237orderedListAtDepth depth = try $ do
233orderedListAtDepth depth = try $ do
238 items <- many1 (orderedListItemAtDepth depth)
234 items <- many1 (orderedListItemAtDepth depth)
239 return $ B.orderedList items
235 return $ B.orderedList items
240
236
241-- | Ordered List Item of given depth, depth being the number of
237-- | Ordered List Item of given depth, depth being the number of
242-- leading '#'
238-- leading '#'
243−orderedListItemAtDepth :: PandocMonad m => Int -> TextileParser m Blocks
239+orderedListItemAtDepth :: PandocMonad m => Int -> ParserT Text ParserState m Blocks
244orderedListItemAtDepth = genericListItemAtDepth '#'
240orderedListItemAtDepth = genericListItemAtDepth '#'
245
241
246-- | Common implementation of list items
242-- | Common implementation of list items
247−genericListItemAtDepth :: PandocMonad m => Char -> Int -> TextileParser m Blocks
243+genericListItemAtDepth :: PandocMonad m => Char -> Int -> ParserT Text ParserState m Blocks
248genericListItemAtDepth c depth = try $ do
244genericListItemAtDepth c depth = try $ do
249 count depth (char c) >> attributes >> whitespace
245 count depth (char c) >> attributes >> whitespace
250 contents <- mconcat <$> many ((B.plain . mconcat <$> many1 inline) <|>
246 contents <- mconcat <$> many ((B.plain . mconcat <$> many1 inline) <|>
@@ -254,25 +250,25 @@ genericListItemAtDepth c depth = try $ do
254 return $ contents <> sublist
250 return $ contents <> sublist
255
251
256-- | A definition list is a set of consecutive definition items
252-- | A definition list is a set of consecutive definition items
257−definitionList :: PandocMonad m => TextileParser m Blocks
253+definitionList :: PandocMonad m => ParserT Text ParserState m Blocks
258definitionList = try $ B.definitionList <$> many1 definitionListItem
254definitionList = try $ B.definitionList <$> many1 definitionListItem
259
255
260-- | List start character.
256-- | List start character.
261−listStart :: PandocMonad m => TextileParser m ()
257+listStart :: PandocMonad m => ParserT Text ParserState m ()
262listStart = genericListStart '*'
258listStart = genericListStart '*'
263 <|> () <$ genericListStart '#'
259 <|> () <$ genericListStart '#'
264 <|> () <$ definitionListStart
260 <|> () <$ definitionListStart
265
261
266−genericListStart :: PandocMonad m => Char -> TextileParser m ()
262+genericListStart :: PandocMonad m => Char -> ParserT Text st m ()
267genericListStart c = () <$ try (many1 (char c) >> whitespace)
263genericListStart c = () <$ try (many1 (char c) >> whitespace)
268
264
269−basicDLStart :: PandocMonad m => TextileParser m ()
265+basicDLStart :: PandocMonad m => ParserT Text ParserState m ()
270basicDLStart = do
266basicDLStart = do
271 char '-'
267 char '-'
272 whitespace
268 whitespace
273 notFollowedBy newline
269 notFollowedBy newline
274
270
275−definitionListStart :: PandocMonad m => TextileParser m Inlines
271+definitionListStart :: PandocMonad m => ParserT Text ParserState m Inlines
276definitionListStart = try $ do
272definitionListStart = try $ do
277 basicDLStart
273 basicDLStart
278 trimInlines . mconcat <$>
274 trimInlines . mconcat <$>
@@ -285,15 +281,15 @@ definitionListStart = try $ do
285-- the term defined, then spaces and ":=". The definition follows, on
281-- the term defined, then spaces and ":=". The definition follows, on
286-- the same single line, or spaned on multiple line, after a line
282-- the same single line, or spaned on multiple line, after a line
287-- break.
283-- break.
288−definitionListItem :: PandocMonad m => TextileParser m (Inlines, [Blocks])
284+definitionListItem :: PandocMonad m => ParserT Text ParserState m (Inlines, [Blocks])
289definitionListItem = try $ do
285definitionListItem = try $ do
290 term <- mconcat . intersperse B.linebreak <$> many1 definitionListStart
286 term <- mconcat . intersperse B.linebreak <$> many1 definitionListStart
291 def' <- string ":=" *> optional whitespace *> (multilineDef <|> inlineDef)
287 def' <- string ":=" *> optional whitespace *> (multilineDef <|> inlineDef)
292 return (term, def')
288 return (term, def')
293− where inlineDef :: PandocMonad m => TextileParser m [Blocks]
289+ where inlineDef :: PandocMonad m => ParserT Text ParserState m [Blocks]
294 inlineDef = liftM (\d -> [B.plain d])
290 inlineDef = liftM (\d -> [B.plain d])
295 $ optional whitespace >> (trimInlines . mconcat <$> many inline) <* newline
291 $ optional whitespace >> (trimInlines . mconcat <$> many inline) <* newline
296− multilineDef :: PandocMonad m => TextileParser m [Blocks]
292+ multilineDef :: PandocMonad m => ParserT Text ParserState m [Blocks]
297 multilineDef = try $ do
293 multilineDef = try $ do
298 optional whitespace >> newline
294 optional whitespace >> newline
299 s <- T.pack <$> many1Till anyChar (try (string "=:" >> newline))
295 s <- T.pack <$> many1Till anyChar (try (string "=:" >> newline))
@@ -304,7 +300,7 @@ definitionListItem = try $ do
304-- raw content
300-- raw content
305
301
306-- | A raw Html Block, optionally followed by blanklines
302-- | A raw Html Block, optionally followed by blanklines
307−rawHtmlBlock :: PandocMonad m => TextileParser m Blocks
303+rawHtmlBlock :: PandocMonad m => ParserT Text ParserState m Blocks
308rawHtmlBlock = try $ do
304rawHtmlBlock = try $ do
309 skipMany spaceChar
305 skipMany spaceChar
310 (_,b) <- htmlTag isBlockTag
306 (_,b) <- htmlTag isBlockTag
@@ -312,14 +308,14 @@ rawHtmlBlock = try $ do
312 return $ B.rawBlock "html" b
308 return $ B.rawBlock "html" b
313
309
314-- | Raw block of LaTeX content
310-- | Raw block of LaTeX content
315−rawLaTeXBlock' :: PandocMonad m => TextileParser m Blocks
311+rawLaTeXBlock' :: PandocMonad m => ParserT Text ParserState m Blocks
316rawLaTeXBlock' = do
312rawLaTeXBlock' = do
317 guardEnabled Ext_raw_tex
313 guardEnabled Ext_raw_tex
318 B.rawBlock "latex" <$> (rawLaTeXBlock <* spaces)
314 B.rawBlock "latex" <$> (rawLaTeXBlock <* spaces)
319
315
320
316
321-- | In textile, paragraphs are separated by blank lines.
317-- | In textile, paragraphs are separated by blank lines.
322−para :: PandocMonad m => TextileParser m Blocks
318+para :: PandocMonad m => ParserT Text ParserState m Blocks
323para = B.para . trimInlines . mconcat <$> many1 inline
319para = B.para . trimInlines . mconcat <$> many1 inline
324
320
325-- Tables
321-- Tables
@@ -330,7 +326,7 @@ toAlignment '>' = AlignRight
330toAlignment '=' = AlignCenter
326toAlignment '=' = AlignCenter
331toAlignment _ = AlignDefault
327toAlignment _ = AlignDefault
332
328
333−cellAttributes :: PandocMonad m => TextileParser m (Bool, Alignment)
329+cellAttributes :: PandocMonad m => ParserT Text ParserState m (Bool, Alignment)
334cellAttributes = try $ do
330cellAttributes = try $ do
335 isHeader <- option False (True <$ char '_')
331 isHeader <- option False (True <$ char '_')
336 -- we just ignore colspan and rowspan markers:
332 -- we just ignore colspan and rowspan markers:
@@ -343,7 +339,7 @@ cellAttributes = try $ do
343 return (isHeader, alignment)
339 return (isHeader, alignment)
344
340
345-- | A table cell spans until a pipe |
341-- | A table cell spans until a pipe |
346−tableCell :: PandocMonad m => TextileParser m ((Bool, Alignment), Blocks)
342+tableCell :: PandocMonad m => ParserT Text ParserState m ((Bool, Alignment), Blocks)
347tableCell = try $ do
343tableCell = try $ do
348 char '|'
344 char '|'
349 (isHeader, alignment) <- option (False, AlignDefault) cellAttributes
345 (isHeader, alignment) <- option (False, AlignDefault) cellAttributes
@@ -354,7 +350,7 @@ tableCell = try $ do
354 return ((isHeader, alignment), B.plain content)
350 return ((isHeader, alignment), B.plain content)
355
351
356-- | A table row is made of many table cells
352-- | A table row is made of many table cells
357−tableRow :: PandocMonad m => TextileParser m [((Bool, Alignment), Blocks)]
353+tableRow :: PandocMonad m => ParserT Text ParserState m [((Bool, Alignment), Blocks)]
358tableRow = try $ do
354tableRow = try $ do
359 -- skip optional row attributes
355 -- skip optional row attributes
360 optional $ try $ do
356 optional $ try $ do
@@ -364,7 +360,7 @@ tableRow = try $ do
364 many1 tableCell <* char '|' <* blankline
360 many1 tableCell <* char '|' <* blankline
365
361
366-- | A table with an optional header.
362-- | A table with an optional header.
367−table :: PandocMonad m => TextileParser m Blocks
363+table :: PandocMonad m => ParserT Text ParserState m Blocks
368table = try $ do
364table = try $ do
369 -- ignore table attributes
365 -- ignore table attributes
370 caption <- option mempty $ try $ do
366 caption <- option mempty $ try $ do
@@ -392,7 +388,7 @@ table = try $ do
392 (TableFoot nullAttr [])
388 (TableFoot nullAttr [])
393
389
394-- | Ignore markers for cols, thead, tfoot.
390-- | Ignore markers for cols, thead, tfoot.
395−ignorableRow :: PandocMonad m => TextileParser m ()
391+ignorableRow :: PandocMonad m => ParserT Text ParserState m ()
396ignorableRow = try $ do
392ignorableRow = try $ do
397 char '|'
393 char '|'
398 oneOf ":^-~"
394 oneOf ":^-~"
@@ -401,7 +397,7 @@ ignorableRow = try $ do
401 _ <- anyLine
397 _ <- anyLine
402 return ()
398 return ()
403
399
404−explicitBlockStart :: PandocMonad m => Text -> TextileParser m ()
400+explicitBlockStart :: PandocMonad m => Text -> ParserT Text ParserState m ()
405explicitBlockStart name = try $ do
401explicitBlockStart name = try $ do
406 string (T.unpack name)
402 string (T.unpack name)
407 attributes
403 attributes
@@ -413,8 +409,8 @@ explicitBlockStart name = try $ do
413-- However, they can be used to set HTML/CSS attributes when needed.
409-- However, they can be used to set HTML/CSS attributes when needed.
414maybeExplicitBlock :: PandocMonad m
410maybeExplicitBlock :: PandocMonad m
415 => Text -- ^ block tag name
411 => Text -- ^ block tag name
416− -> TextileParser m Blocks -- ^ implicit block
412+ -> ParserT Text ParserState m Blocks -- ^ implicit block
417− -> TextileParser m Blocks
413+ -> ParserT Text ParserState m Blocks
418maybeExplicitBlock name blk = try $ do
414maybeExplicitBlock name blk = try $ do
419 optional $ explicitBlockStart name
415 optional $ explicitBlockStart name
420 blk
416 blk
@@ -427,11 +423,11 @@ maybeExplicitBlock name blk = try $ do
427
423
428
424
429-- | Any inline element
425-- | Any inline element
430−inline :: PandocMonad m => TextileParser m Inlines
426+inline :: PandocMonad m => ParserT Text ParserState m Inlines
431inline = choice inlineParsers <?> "inline"
427inline = choice inlineParsers <?> "inline"
432
428
433-- | Inline parsers tried in order
429-- | Inline parsers tried in order
434−inlineParsers :: PandocMonad m => [TextileParser m Inlines]
430+inlineParsers :: PandocMonad m => [ParserT Text ParserState m Inlines]
435inlineParsers = [ str
431inlineParsers = [ str
436 , whitespace
432 , whitespace
437 , endline
433 , endline
@@ -451,7 +447,7 @@ inlineParsers = [ str
451 ]
447 ]
452
448
453-- | Inline markups
449-- | Inline markups
454−inlineMarkup :: PandocMonad m => TextileParser m Inlines
450+inlineMarkup :: PandocMonad m => ParserT Text ParserState m Inlines
455inlineMarkup = choice [ simpleInline (string "??") (B.cite [])
451inlineMarkup = choice [ simpleInline (string "??") (B.cite [])
456 , simpleInline (string "**") B.strong
452 , simpleInline (string "**") B.strong
457 , simpleInline (string "__") B.emph
453 , simpleInline (string "__") B.emph
@@ -465,29 +461,29 @@ inlineMarkup = choice [ simpleInline (string "??") (B.cite [])
465 ]
461 ]
466
462
467-- | Trademark, registered, copyright
463-- | Trademark, registered, copyright
468−mark :: PandocMonad m => TextileParser m Inlines
464+mark :: PandocMonad m => ParserT Text st m Inlines
469mark = try $ char '(' >> (try tm <|> try reg <|> copy)
465mark = try $ char '(' >> (try tm <|> try reg <|> copy)
470
466
471−reg :: PandocMonad m => TextileParser m Inlines
467+reg :: PandocMonad m => ParserT Text st m Inlines
472reg = do
468reg = do
473 oneOf "Rr"
469 oneOf "Rr"
474 char ')'
470 char ')'
475 return $ B.str "\174"
471 return $ B.str "\174"
476
472
477−tm :: PandocMonad m => TextileParser m Inlines
473+tm :: PandocMonad m => ParserT Text st m Inlines
478tm = do
474tm = do
479 oneOf "Tt"
475 oneOf "Tt"
480 oneOf "Mm"
476 oneOf "Mm"
481 char ')'
477 char ')'
482 return $ B.str "\8482"
478 return $ B.str "\8482"
483
479
484−copy :: PandocMonad m => TextileParser m Inlines
480+copy :: PandocMonad m => ParserT Text st m Inlines
485copy = do
481copy = do
486 oneOf "Cc"
482 oneOf "Cc"
487 char ')'
483 char ')'
488 return $ B.str "\169"
484 return $ B.str "\169"
489
485
490−note :: PandocMonad m => TextileParser m Inlines
486+note :: PandocMonad m => ParserT Text ParserState m Inlines
491note = try $ do
487note = try $ do
492 ref <- char '[' *> many1 digit <* char ']'
488 ref <- char '[' *> many1 digit <* char ']'
493 notes <- stateNotes <$> getState
489 notes <- stateNotes <$> getState
@@ -511,13 +507,13 @@ wordBoundaries :: [Char]
511wordBoundaries = markupChars <> stringBreakers
507wordBoundaries = markupChars <> stringBreakers
512
508
513-- | Parse a hyphened sequence of words
509-- | Parse a hyphened sequence of words
514−hyphenedWords :: PandocMonad m => TextileParser m Text
510+hyphenedWords :: PandocMonad m => ParserT Text ParserState m Text
515hyphenedWords = do
511hyphenedWords = do
516 x <- wordChunk
512 x <- wordChunk
517 xs <- many (try $ char '-' >> wordChunk)
513 xs <- many (try $ char '-' >> wordChunk)
518 return $ T.intercalate "-" (x:xs)
514 return $ T.intercalate "-" (x:xs)
519
515
520−wordChunk :: PandocMonad m => TextileParser m Text
516+wordChunk :: PandocMonad m => ParserT Text ParserState m Text
521wordChunk = try $ do
517wordChunk = try $ do
522 hd <- noneOf wordBoundaries
518 hd <- noneOf wordBoundaries
523 tl <- many ( noneOf wordBoundaries <|>
519 tl <- many ( noneOf wordBoundaries <|>
@@ -526,7 +522,7 @@ wordChunk = try $ do
526 return $ T.pack $ hd:tl
522 return $ T.pack $ hd:tl
527
523
528-- | Any string
524-- | Any string
529−str :: PandocMonad m => TextileParser m Inlines
525+str :: PandocMonad m => ParserT Text ParserState m Inlines
530str = do
526str = do
531 baseStr <- hyphenedWords
527 baseStr <- hyphenedWords
532 -- RedCloth compliance : if parsed word is uppercase and immediately
528 -- RedCloth compliance : if parsed word is uppercase and immediately
@@ -539,11 +535,11 @@ str = do
539 return $ B.str fullStr
535 return $ B.str fullStr
540
536
541-- | Some number of space chars
537-- | Some number of space chars
542−whitespace :: PandocMonad m => TextileParser m Inlines
538+whitespace :: PandocMonad m => ParserT Text st m Inlines
543whitespace = many1 spaceChar >> return B.space <?> "whitespace"
539whitespace = many1 spaceChar >> return B.space <?> "whitespace"
544
540
545-- | In Textile, an isolated endline character is a line break
541-- | In Textile, an isolated endline character is a line break
546−endline :: PandocMonad m => TextileParser m Inlines
542+endline :: PandocMonad m => ParserT Text ParserState m Inlines
547endline = try $ do
543endline = try $ do
548 newline
544 newline
549 notFollowedBy blankline
545 notFollowedBy blankline
@@ -551,18 +547,18 @@ endline = try $ do
551 notFollowedBy rawHtmlBlock
547 notFollowedBy rawHtmlBlock
552 return B.linebreak
548 return B.linebreak
553
549
554−rawHtmlInline :: PandocMonad m => TextileParser m Inlines
550+rawHtmlInline :: PandocMonad m => ParserT Text ParserState m Inlines
555rawHtmlInline = B.rawInline "html" . snd <$> htmlTag isInlineTag
551rawHtmlInline = B.rawInline "html" . snd <$> htmlTag isInlineTag
556
552
557-- | Raw LaTeX Inline
553-- | Raw LaTeX Inline
558−rawLaTeXInline' :: PandocMonad m => TextileParser m Inlines
554+rawLaTeXInline' :: PandocMonad m => ParserT Text ParserState m Inlines
559rawLaTeXInline' = try $ do
555rawLaTeXInline' = try $ do
560 guardEnabled Ext_raw_tex
556 guardEnabled Ext_raw_tex
561 B.rawInline "latex" <$> rawLaTeXInline
557 B.rawInline "latex" <$> rawLaTeXInline
562
558
563-- | Textile standard link syntax is "label":target. But we
559-- | Textile standard link syntax is "label":target. But we
564-- can also have ["label":target].
560-- can also have ["label":target].
565−link :: PandocMonad m => TextileParser m Inlines
561+link :: PandocMonad m => ParserT Text ParserState m Inlines
566link = try $ do
562link = try $ do
567 bracketed <- (True <$ char '[') <|> return False
563 bracketed <- (True <$ char '[') <|> return False
568 char '"' *> notFollowedBy (oneOf " \t\n\r")
564 char '"' *> notFollowedBy (oneOf " \t\n\r")
@@ -582,7 +578,7 @@ link = try $ do
582 else B.spanWith attr $ B.link url "" name'
578 else B.spanWith attr $ B.link url "" name'
583
579
584-- | image embedding
580-- | image embedding
585−image :: PandocMonad m => TextileParser m Inlines
581+image :: PandocMonad m => ParserT Text ParserState m Inlines
586image = try $ do
582image = try $ do
587 char '!' >> notFollowedBy space
583 char '!' >> notFollowedBy space
588 (ident, cls, kvs) <- attributes
584 (ident, cls, kvs) <- attributes
@@ -594,51 +590,51 @@ image = try $ do
594 char '!'
590 char '!'
595 return $ B.imageWith attr src alt (B.str alt)
591 return $ B.imageWith attr src alt (B.str alt)
596
592
597−escapedInline :: PandocMonad m => TextileParser m Inlines
593+escapedInline :: PandocMonad m => ParserT Text ParserState m Inlines
598escapedInline = escapedEqs <|> escapedTag
594escapedInline = escapedEqs <|> escapedTag
599
595
600−escapedEqs :: PandocMonad m => TextileParser m Inlines
596+escapedEqs :: PandocMonad m => ParserT Text ParserState m Inlines
601escapedEqs = B.str . T.pack <$>
597escapedEqs = B.str . T.pack <$>
602 try (string "==" *> manyTill anyChar' (try $ string "=="))
598 try (string "==" *> manyTill anyChar' (try $ string "=="))
603
599
604-- | literal text escaped btw <notextile> tags
600-- | literal text escaped btw <notextile> tags
605−escapedTag :: PandocMonad m => TextileParser m Inlines
601+escapedTag :: PandocMonad m => ParserT Text ParserState m Inlines
606escapedTag = B.str . T.pack <$>
602escapedTag = B.str . T.pack <$>
607 try (string "<notextile>" *>
603 try (string "<notextile>" *>
608 manyTill anyChar' (try $ string "</notextile>"))
604 manyTill anyChar' (try $ string "</notextile>"))
609
605
610-- | Any special symbol defined in wordBoundaries
606-- | Any special symbol defined in wordBoundaries
611−symbol :: PandocMonad m => TextileParser m Inlines
607+symbol :: PandocMonad m => ParserT Text ParserState m Inlines
612symbol = B.str . T.singleton <$> (notFollowedBy newline *>
608symbol = B.str . T.singleton <$> (notFollowedBy newline *>
613 notFollowedBy rawHtmlBlock *>
609 notFollowedBy rawHtmlBlock *>
614 oneOf wordBoundaries)
610 oneOf wordBoundaries)
615
611
616-- | Inline code
612-- | Inline code
617−code :: PandocMonad m => TextileParser m Inlines
613+code :: PandocMonad m => ParserT Text ParserState m Inlines
618code = code1 <|> code2
614code = code1 <|> code2
619
615
620-- any character except a newline before a blank line
616-- any character except a newline before a blank line
621−anyChar' :: PandocMonad m => TextileParser m Char
617+anyChar' :: PandocMonad m => ParserT Text ParserState m Char
622anyChar' =
618anyChar' =
623 satisfy (/='\n') <|>
619 satisfy (/='\n') <|>
624 try (char '\n' <* notFollowedBy blankline)
620 try (char '\n' <* notFollowedBy blankline)
625
621
626−code1 :: PandocMonad m => TextileParser m Inlines
622+code1 :: PandocMonad m => ParserT Text ParserState m Inlines
627code1 = B.code . T.pack <$> surrounded (char '@') anyChar'
623code1 = B.code . T.pack <$> surrounded (char '@') anyChar'
628
624
629−code2 :: PandocMonad m => TextileParser m Inlines
625+code2 :: PandocMonad m => ParserT Text ParserState m Inlines
630code2 = do
626code2 = do
631 htmlTag (tagOpen (=="tt") null)
627 htmlTag (tagOpen (=="tt") null)
632 B.code . T.pack <$> manyTill anyChar' (try $ htmlTag $ tagClose (=="tt"))
628 B.code . T.pack <$> manyTill anyChar' (try $ htmlTag $ tagClose (=="tt"))
633
629
634-- | Html / CSS attributes
630-- | Html / CSS attributes
635−attributes :: PandocMonad m => TextileParser m Attr
631+attributes :: PandocMonad m => ParserT Text ParserState m Attr
636attributes = foldl' (flip ($)) ("",[],[]) <$>
632attributes = foldl' (flip ($)) ("",[],[]) <$>
637 try (do special <- option id specialAttribute
633 try (do special <- option id specialAttribute
638 attrs <- many attribute
634 attrs <- many attribute
639 return (special : attrs))
635 return (special : attrs))
640
636
641−specialAttribute :: PandocMonad m => TextileParser m (Attr -> Attr)
637+specialAttribute :: PandocMonad m => ParserT Text ParserState m (Attr -> Attr)
642specialAttribute = do
638specialAttribute = do
643 alignStr <- ("center" <$ char '=') <|>
639 alignStr <- ("center" <$ char '=') <|>
644 ("justify" <$ try (string "<>")) <|>
640 ("justify" <$ try (string "<>")) <|>
@@ -647,11 +643,11 @@ specialAttribute = do
647 notFollowedBy spaceChar
643 notFollowedBy spaceChar
648 return $ addStyle $ T.pack $ "text-align:" ++ alignStr
644 return $ addStyle $ T.pack $ "text-align:" ++ alignStr
649
645
650−attribute :: PandocMonad m => TextileParser m (Attr -> Attr)
646+attribute :: PandocMonad m => ParserT Text ParserState m (Attr -> Attr)
651attribute = try $
647attribute = try $
652 (classIdAttr <|> styleAttr <|> langAttr) <* notFollowedBy spaceChar
648 (classIdAttr <|> styleAttr <|> langAttr) <* notFollowedBy spaceChar
653
649
654−classIdAttr :: PandocMonad m => TextileParser m (Attr -> Attr)
650+classIdAttr :: PandocMonad m => ParserT Text ParserState m (Attr -> Attr)
655classIdAttr = try $ do -- (class class #id)
651classIdAttr = try $ do -- (class class #id)
656 char '('
652 char '('
657 ws <- T.words `fmap` T.pack <$> manyTill anyChar' (char ')')
653 ws <- T.words `fmap` T.pack <$> manyTill anyChar' (char ')')
@@ -663,7 +659,7 @@ classIdAttr = try $ do -- (class class #id)
663 classes'
659 classes'
664 -> return $ \(_,_,keyvals) -> ("",classes',keyvals)
660 -> return $ \(_,_,keyvals) -> ("",classes',keyvals)
665
661
666−styleAttr :: PandocMonad m => TextileParser m (Attr -> Attr)
662+styleAttr :: PandocMonad m => ParserT Text ParserState m (Attr -> Attr)
667styleAttr = do
663styleAttr = do
668 style <- try $ enclosed (char '{') (char '}') anyChar'
664 style <- try $ enclosed (char '{') (char '}') anyChar'
669 return $ addStyle $ T.pack style
665 return $ addStyle $ T.pack style
@@ -674,23 +670,23 @@ addStyle style (id',classes,keyvals) =
674 where keyvals' = ("style", style') : [(k,v) | (k,v) <- keyvals, k /= "style"]
670 where keyvals' = ("style", style') : [(k,v) | (k,v) <- keyvals, k /= "style"]
675 style' = style <> ";" <> T.concat [v | ("style",v) <- keyvals]
671 style' = style <> ";" <> T.concat [v | ("style",v) <- keyvals]
676
672
677−langAttr :: PandocMonad m => TextileParser m (Attr -> Attr)
673+langAttr :: PandocMonad m => ParserT Text ParserState m (Attr -> Attr)
678langAttr = do
674langAttr = do
679 lang <- try $ enclosed (char '[') (char ']') alphaNum
675 lang <- try $ enclosed (char '[') (char ']') alphaNum
680 return $ \(id',classes,keyvals) -> (id',classes,("lang",T.pack lang):keyvals)
676 return $ \(id',classes,keyvals) -> (id',classes,("lang",T.pack lang):keyvals)
681
677
682-- | Parses material surrounded by a parser.
678-- | Parses material surrounded by a parser.
683surrounded :: (PandocMonad m, Show t)
679surrounded :: (PandocMonad m, Show t)
684− => ParserT Sources st m t -- ^ surrounding parser
680+ => ParserT Text st m t -- ^ surrounding parser
685− -> ParserT Sources st m a -- ^ content parser (to be used repeatedly)
681+ -> ParserT Text st m a -- ^ content parser (to be used repeatedly)
686− -> ParserT Sources st m [a]
682+ -> ParserT Text st m [a]
687surrounded border =
683surrounded border =
688 enclosed (border *> notFollowedBy (oneOf " \t\n\r")) (try border)
684 enclosed (border *> notFollowedBy (oneOf " \t\n\r")) (try border)
689
685
690simpleInline :: PandocMonad m
686simpleInline :: PandocMonad m
691− => TextileParser m t -- ^ surrounding parser
687+ => ParserT Text ParserState m t -- ^ surrounding parser
692 -> (Inlines -> Inlines) -- ^ Inline constructor
688 -> (Inlines -> Inlines) -- ^ Inline constructor
693− -> TextileParser m Inlines -- ^ content parser (to be used repeatedly)
689+ -> ParserT Text ParserState m Inlines -- ^ content parser (to be used repeatedly)
694simpleInline border construct = try $ do
690simpleInline border construct = try $ do
695 notAfterString
691 notAfterString
696 border *> notFollowedBy (oneOf " \t\n\r")
692 border *> notFollowedBy (oneOf " \t\n\r")
@@ -704,7 +700,7 @@ simpleInline border construct = try $ do
704 then body
700 then body
705 else B.spanWith attr body
701 else B.spanWith attr body
706
702
707−groupedInlineMarkup :: PandocMonad m => TextileParser m Inlines
703+groupedInlineMarkup :: PandocMonad m => ParserT Text ParserState m Inlines
708groupedInlineMarkup = try $ do
704groupedInlineMarkup = try $ do
709 char '['
705 char '['
710 sp1 <- option mempty $ B.space <$ whitespace
706 sp1 <- option mempty $ B.space <$ whitespace
@@ -713,5 +709,5 @@ groupedInlineMarkup = try $ do
713 char ']'
709 char ']'
714 return $ sp1 <> result <> sp2
710 return $ sp1 <> result <> sp2
715
711
716−eof' :: Monad m => ParserT Sources s m Char
712+eof' :: Monad m => ParserT Text s m Char
717eof' = '\n' <$ eof
713eof' = '\n' <$ eof
src/Text/Pandoc/Readers/TikiWiki.hs+6−6
@@ -30,23 +30,23 @@ import Text.Pandoc.Definition
30import Text.Pandoc.Logging (Verbosity (..))
30import Text.Pandoc.Logging (Verbosity (..))
31import Text.Pandoc.Options
31import Text.Pandoc.Options
32import Text.Pandoc.Parsing hiding (enclosed, nested)
32import Text.Pandoc.Parsing hiding (enclosed, nested)
33−import Text.Pandoc.Shared (safeRead)
33+import Text.Pandoc.Shared (crFilter, safeRead)
34import Text.Pandoc.XML (fromEntities)
34import Text.Pandoc.XML (fromEntities)
35import Text.Printf (printf)
35import Text.Printf (printf)
36
36
37-- | Read TikiWiki from an input string and return a Pandoc document.
37-- | Read TikiWiki from an input string and return a Pandoc document.
38−readTikiWiki :: (PandocMonad m, ToSources a)
38+readTikiWiki :: PandocMonad m
39 => ReaderOptions
39 => ReaderOptions
40− -> a
40+ -> Text
41 -> m Pandoc
41 -> m Pandoc
42readTikiWiki opts s = do
42readTikiWiki opts s = do
43− let sources = ensureFinalNewlines 2 (toSources s)
44− res <- readWithM parseTikiWiki def{ stateOptions = opts } sources
43+ res <- readWithM parseTikiWiki def{ stateOptions = opts }
44+ (crFilter s <> "\n\n")
45 case res of
45 case res of
46 Left e -> throwError e
46 Left e -> throwError e
47 Right d -> return d
47 Right d -> return d
48
48
49−type TikiWikiParser = ParserT Sources ParserState
49+type TikiWikiParser = ParserT Text ParserState
50
50
51--
51--
52-- utility functions
52-- utility functions
src/Text/Pandoc/Readers/Txt2Tags.hs+7−27
@@ -33,9 +33,9 @@ import Data.Time (defaultTimeLocale)
33import Text.Pandoc.Definition
33import Text.Pandoc.Definition
34import Text.Pandoc.Options
34import Text.Pandoc.Options
35import Text.Pandoc.Parsing hiding (space, spaces, uri)
35import Text.Pandoc.Parsing hiding (space, spaces, uri)
36−import Text.Pandoc.Shared (compactify, compactifyDL, escapeURI)
36+import Text.Pandoc.Shared (compactify, compactifyDL, crFilter, escapeURI)
37
37
38−type T2T = ParserT Sources ParserState (Reader T2TMeta)
38+type T2T = ParserT Text ParserState (Reader T2TMeta)
39
39
40-- | An object for the T2T macros meta information
40-- | An object for the T2T macros meta information
41-- the contents of each field is simply substituted verbatim into the file
41-- the contents of each field is simply substituted verbatim into the file
@@ -68,15 +68,15 @@ getT2TMeta = do
68 (intercalate ", " inps) outp
68 (intercalate ", " inps) outp
69
69
70-- | Read Txt2Tags from an input string returning a Pandoc document
70-- | Read Txt2Tags from an input string returning a Pandoc document
71−readTxt2Tags :: (PandocMonad m, ToSources a)
71+readTxt2Tags :: PandocMonad m
72 => ReaderOptions
72 => ReaderOptions
73− -> a
73+ -> Text
74 -> m Pandoc
74 -> m Pandoc
75readTxt2Tags opts s = do
75readTxt2Tags opts s = do
76− let sources = ensureFinalNewlines 2 (toSources s)
77 meta <- getT2TMeta
76 meta <- getT2TMeta
78 let parsed = flip runReader meta $
77 let parsed = flip runReader meta $
79− readWithM parseT2T (def {stateOptions = opts}) sources
78+ readWithM parseT2T (def {stateOptions = opts}) $
79+ crFilter s <> "\n\n"
80 case parsed of
80 case parsed of
81 Right result -> return result
81 Right result -> return result
82 Left e -> throwError e
82 Left e -> throwError e
@@ -478,29 +478,9 @@ macro = try $ do
478-- raw URLs in text are automatically linked
478-- raw URLs in text are automatically linked
479url :: T2T Inlines
479url :: T2T Inlines
480url = try $ do
480url = try $ do
481− (rawUrl, escapedUrl) <- try uri <|> emailAddress'
481+ (rawUrl, escapedUrl) <- try uri <|> emailAddress
482 return $ B.link rawUrl "" (B.str escapedUrl)
482 return $ B.link rawUrl "" (B.str escapedUrl)
483
483
484−emailAddress' :: T2T (Text, Text)
485−emailAddress' = do
486− (base, mailURI) <- emailAddress
487− query <- option "" emailQuery
488− return (base <> query, mailURI <> query)
489−
490−emailQuery :: T2T Text
491−emailQuery = do
492− char '?'
493− parts <- kv `sepBy1` (char '&')
494− return $ "?" <> T.intercalate "&" parts
495−
496−kv :: T2T Text
497−kv = do
498− k <- T.pack <$> many1 alphaNum
499− char '='
500− let vchar = alphaNum <|> try (oneOf "%._/~:,=$@&+-;*" <* lookAhead alphaNum)
501− v <- T.pack <$> many1 vchar
502− return (k <> "=" <> v)
503−
504uri :: T2T (Text, Text)
484uri :: T2T (Text, Text)
505uri = try $ do
485uri = try $ do
506 address <- t2tURI
486 address <- t2tURI
src/Text/Pandoc/Readers/Vimwiki.hs+7−12
@@ -74,28 +74,23 @@ import Text.Pandoc.Parsing (ParserState, ParserT, blanklines, emailAddress,
74 many1Till, orderedListMarker, readWithM,
74 many1Till, orderedListMarker, readWithM,
75 registerHeader, spaceChar, stateMeta,
75 registerHeader, spaceChar, stateMeta,
76 stateOptions, uri, manyTillChar, manyChar, textStr,
76 stateOptions, uri, manyTillChar, manyChar, textStr,
77− many1Char, countChar, many1TillChar,
77+ many1Char, countChar, many1TillChar)
78− alphaNum, anyChar, char, newline, noneOf, oneOf,
79− space, spaces, string)
80−import Text.Pandoc.Sources (ToSources(..), Sources)
81−import Text.Pandoc.Shared (splitTextBy, stringify, stripFirstAndLast,
78+import Text.Pandoc.Shared (crFilter, splitTextBy, stringify, stripFirstAndLast,
82 isURI, tshow)
79 isURI, tshow)
80+import Text.Parsec.Char (alphaNum, anyChar, char, newline, noneOf, oneOf, space,
81+ spaces, string)
83import Text.Parsec.Combinator (between, choice, eof, lookAhead, many1,
82import Text.Parsec.Combinator (between, choice, eof, lookAhead, many1,
84 manyTill, notFollowedBy, option, skipMany1)
83 manyTill, notFollowedBy, option, skipMany1)
85import Text.Parsec.Prim (getState, many, try, updateState, (<|>))
84import Text.Parsec.Prim (getState, many, try, updateState, (<|>))
86
85
87−readVimwiki :: (PandocMonad m, ToSources a)
86+readVimwiki :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
88− => ReaderOptions
89− -> a
90− -> m Pandoc
91readVimwiki opts s = do
87readVimwiki opts s = do
92− let sources = toSources s
93− res <- readWithM parseVimwiki def{ stateOptions = opts } sources
88+ res <- readWithM parseVimwiki def{ stateOptions = opts } $ crFilter s
94 case res of
89 case res of
95 Left e -> throwError e
90 Left e -> throwError e
96 Right result -> return result
91 Right result -> return result
97
92
98−type VwParser = ParserT Sources ParserState
93+type VwParser = ParserT Text ParserState
99
94
100
95
101-- constants
96-- constants
src/Text/Pandoc/Shared.hs+1−1
@@ -298,7 +298,6 @@ tabFilter tabStop = T.unlines . map go . T.lines
298 (tabStop - (T.length s1 `mod` tabStop)) (T.pack " ")
298 (tabStop - (T.length s1 `mod` tabStop)) (T.pack " ")
299 <> go (T.drop 1 s2)
299 <> go (T.drop 1 s2)
300
300
301−{-# DEPRECATED crFilter "readers filter crs automatically" #-}
302-- | Strip out DOS line endings.
301-- | Strip out DOS line endings.
303crFilter :: T.Text -> T.Text
302crFilter :: T.Text -> T.Text
304crFilter = T.filter (/= '\r')
303crFilter = T.filter (/= '\r')
@@ -853,6 +852,7 @@ filteredFilesFromArchive zf f =
853 fileAndBinary :: Archive -> FilePath -> Maybe (FilePath, BL.ByteString)
852 fileAndBinary :: Archive -> FilePath -> Maybe (FilePath, BL.ByteString)
854 fileAndBinary a fp = findEntryByPath fp a >>= \e -> Just (fp, fromEntry e)
853 fileAndBinary a fp = findEntryByPath fp a >>= \e -> Just (fp, fromEntry e)
855
854
855+
856--
856--
857-- IANA URIs
857-- IANA URIs
858--
858--
src/Text/Pandoc/Sources.hsdeleted−195
@@ -1,195 +0,0 @@
1−{-# LANGUAGE FlexibleInstances #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−{-# LANGUAGE OverloadedStrings #-}
6−{- |
7− Module : Text.Pandoc.Sources
8− Copyright : Copyright (C) 2021 John MacFarlane
9− License : GNU GPL, version 2 or above
10−
11− Maintainer : John MacFarlane <jgm@berkeley.edu>
12− Stability : alpha
13− Portability : portable
14−
15−Defines Sources object to be used as input to pandoc parsers and redefines Char
16−parsers so they get source position information from it.
17−-}
18−
19−module Text.Pandoc.Sources
20− ( Sources(..)
21− , ToSources(..)
22− , UpdateSourcePos(..)
23− , sourcesToText
24− , initialSourceName
25− , addToSources
26− , ensureFinalNewlines
27− , addToInput
28− , satisfy
29− , oneOf
30− , noneOf
31− , anyChar
32− , char
33− , string
34− , newline
35− , space
36− , spaces
37− , letter
38− , digit
39− , hexDigit
40− , alphaNum
41− )
42−where
43−import qualified Text.Parsec as P
44−import Text.Parsec (Stream(..), ParsecT)
45−import Text.Parsec.Pos as P
46−import Data.Text (Text)
47−import qualified Data.Text as T
48−import Data.Char (isSpace, isLetter, isAlphaNum, isDigit, isHexDigit)
49−import Data.String (IsString(..))
50−import qualified Data.List.NonEmpty as NonEmpty
51−
52−-- | A list of inputs labeled with source positions. It is assumed
53−-- that the 'Text's have @\n@ line endings.
54−newtype Sources = Sources { unSources :: [(SourcePos, Text)] }
55− deriving (Show, Semigroup, Monoid)
56−
57−instance Monad m => Stream Sources m Char where
58− uncons (Sources []) = return Nothing
59− uncons (Sources ((pos,t):rest)) =
60− case T.uncons t of
61− Nothing -> uncons (Sources rest)
62− Just (c,t') -> return $ Just (c, Sources ((pos,t'):rest))
63−
64−instance IsString Sources where
65− fromString s = Sources [(P.initialPos "", T.pack (filter (/='\r') s))]
66−
67−class ToSources a where
68− toSources :: a -> Sources
69−
70−instance ToSources Text where
71− toSources t = Sources [(P.initialPos "", T.filter (/='\r') t)]
72−
73−instance ToSources [(FilePath, Text)] where
74− toSources = Sources
75− . map (\(fp,t) ->
76− (P.initialPos fp, T.snoc (T.filter (/='\r') t) '\n'))
77−
78−instance ToSources Sources where
79− toSources = id
80−
81−sourcesToText :: Sources -> Text
82−sourcesToText (Sources xs) = mconcat $ map snd xs
83−
84−addToSources :: Monad m => SourcePos -> Text -> ParsecT Sources u m ()
85−addToSources pos t = do
86− curpos <- P.getPosition
87− Sources xs <- P.getInput
88− let xs' = case xs of
89− [] -> []
90− ((_,t'):rest) -> (curpos,t'):rest
91− P.setInput $ Sources ((pos, T.filter (/='\r') t):xs')
92−
93−ensureFinalNewlines :: Int -- ^ number of trailing newlines
94− -> Sources
95− -> Sources
96−ensureFinalNewlines n (Sources xs) =
97− case NonEmpty.nonEmpty xs of
98− Nothing -> Sources [(initialPos "", T.replicate n "\n")]
99− Just lst ->
100− case NonEmpty.last lst of
101− (spos, t) ->
102− case T.length (T.takeWhileEnd (=='\n') t) of
103− len | len >= n -> Sources xs
104− | otherwise -> Sources (NonEmpty.init lst ++
105− [(spos,
106− t <> T.replicate (n - len) "\n")])
107−
108−class UpdateSourcePos s c where
109− updateSourcePos :: SourcePos -> c -> s -> SourcePos
110−
111−instance UpdateSourcePos Text Char where
112− updateSourcePos pos c _ = updatePosChar pos c
113−
114−instance UpdateSourcePos Sources Char where
115− updateSourcePos pos c sources =
116− case sources of
117− Sources [] -> updatePosChar pos c
118− Sources ((_,t):(pos',_):_)
119− | T.null t -> pos'
120− Sources _ ->
121− case c of
122− '\n' -> incSourceLine (setSourceColumn pos 1) 1
123− '\t' -> incSourceColumn pos (4 - ((sourceColumn pos - 1) `mod` 4))
124− _ -> incSourceColumn pos 1
125−
126−-- | Get name of first source in 'Sources'.
127−initialSourceName :: Sources -> FilePath
128−initialSourceName (Sources []) = ""
129−initialSourceName (Sources ((pos,_):_)) = sourceName pos
130−
131−-- | Add some text to the beginning of the input sources.
132−-- This simplifies code that expands macros.
133−addToInput :: Monad m => Text -> ParsecT Sources u m ()
134−addToInput t = do
135− Sources xs <- P.getInput
136− case xs of
137− [] -> P.setInput $ Sources [(initialPos "",t)]
138− (pos,t'):rest -> P.setInput $ Sources ((pos, t <> t'):rest)
139−
140−-- We need to redefine the parsers in Text.Parsec.Char so that they
141−-- update source positions properly from the Sources stream.
142−
143−satisfy :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
144− => (Char -> Bool) -> ParsecT s u m Char
145−satisfy f = P.tokenPrim show updateSourcePos matcher
146− where
147− matcher c = if f c then Just c else Nothing
148−
149−oneOf :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
150− => [Char] -> ParsecT s u m Char
151−oneOf cs = satisfy (`elem` cs)
152−
153−noneOf :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
154− => [Char] -> ParsecT s u m Char
155−noneOf cs = satisfy (`notElem` cs)
156−
157−anyChar :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
158− => ParsecT s u m Char
159−anyChar = satisfy (const True)
160−
161−char :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
162− => Char -> ParsecT s u m Char
163−char c = satisfy (== c)
164−
165−string :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
166− => [Char] -> ParsecT s u m [Char]
167−string = mapM char
168−
169−newline :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
170− => ParsecT s u m Char
171−newline = satisfy (== '\n')
172−
173−space :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
174− => ParsecT s u m Char
175−space = satisfy isSpace
176−
177−spaces :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
178− => ParsecT s u m ()
179−spaces = P.skipMany space P.<?> "white space"
180−
181−letter :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
182− => ParsecT s u m Char
183−letter = satisfy isLetter
184−
185−alphaNum :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
186− => ParsecT s u m Char
187−alphaNum = satisfy isAlphaNum
188−
189−digit :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
190− => ParsecT s u m Char
191−digit = satisfy isDigit
192−
193−hexDigit :: (Monad m, Stream s m Char, UpdateSourcePos s Char)
194− => ParsecT s u m Char
195−hexDigit = satisfy isHexDigit
src/Text/Pandoc/Writers.hs+3−3
@@ -81,7 +81,6 @@ import Data.Aeson
81import qualified Data.ByteString.Lazy as BL
81import qualified Data.ByteString.Lazy as BL
82import Data.Text (Text)
82import Data.Text (Text)
83import qualified Data.Text as T
83import qualified Data.Text as T
84−import Text.Pandoc.Shared (tshow)
85import Text.Pandoc.Class
84import Text.Pandoc.Class
86import Text.Pandoc.Definition
85import Text.Pandoc.Definition
87import Text.Pandoc.Options
86import Text.Pandoc.Options
@@ -123,6 +122,7 @@ import Text.Pandoc.Writers.Texinfo
123import Text.Pandoc.Writers.Textile
122import Text.Pandoc.Writers.Textile
124import Text.Pandoc.Writers.XWiki
123import Text.Pandoc.Writers.XWiki
125import Text.Pandoc.Writers.ZimWiki
124import Text.Pandoc.Writers.ZimWiki
125+import Text.Parsec.Error
126
126
127data Writer m = TextWriter (WriterOptions -> Pandoc -> m Text)
127data Writer m = TextWriter (WriterOptions -> Pandoc -> m Text)
128 | ByteStringWriter (WriterOptions -> Pandoc -> m BL.ByteString)
128 | ByteStringWriter (WriterOptions -> Pandoc -> m BL.ByteString)
@@ -196,8 +196,8 @@ writers = [
196getWriter :: PandocMonad m => Text -> m (Writer m, Extensions)
196getWriter :: PandocMonad m => Text -> m (Writer m, Extensions)
197getWriter s =
197getWriter s =
198 case parseFormatSpec s of
198 case parseFormatSpec s of
199− Left e -> throwError $ PandocAppError $
199+ Left e -> throwError $ PandocAppError
200− "Error parsing writer format " <> tshow s <> ": " <> tshow e
200+ $ T.intercalate "\n" [T.pack m | Message m <- errorMessages e]
201 Right (writerName, extsToEnable, extsToDisable) ->
201 Right (writerName, extsToEnable, extsToDisable) ->
202 case lookup writerName writers of
202 case lookup writerName writers of
203 Nothing -> throwError $
203 Nothing -> throwError $
src/Text/Pandoc/Writers/BibTeX.hs+1−1
@@ -43,7 +43,7 @@ writeBibTeX' :: PandocMonad m => Variant -> WriterOptions -> Pandoc -> m Text
43writeBibTeX' variant opts (Pandoc meta _) = do
43writeBibTeX' variant opts (Pandoc meta _) = do
44 let mblang = case lookupMetaString "lang" meta of
44 let mblang = case lookupMetaString "lang" meta of
45 "" -> Nothing
45 "" -> Nothing
46− t -> either (const Nothing) Just $ parseLang t
46+ t -> Just $ parseLang t
47 let refs = case lookupMeta "references" meta of
47 let refs = case lookupMeta "references" meta of
48 Just (MetaList xs) -> mapMaybe metaValueToReference xs
48 Just (MetaList xs) -> mapMaybe metaValueToReference xs
49 _ -> []
49 _ -> []
src/Text/Pandoc/Writers/ConTeXt.hs+39−39
@@ -16,11 +16,12 @@ module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where
16import Control.Monad.State.Strict
16import Control.Monad.State.Strict
17import Data.Char (ord, isDigit)
17import Data.Char (ord, isDigit)
18import Data.List (intersperse)
18import Data.List (intersperse)
19+import Data.List.NonEmpty (nonEmpty)
19import Data.Maybe (mapMaybe)
20import Data.Maybe (mapMaybe)
20import Data.Text (Text)
21import Data.Text (Text)
21import qualified Data.Text as T
22import qualified Data.Text as T
22import Network.URI (unEscapeString)
23import Network.URI (unEscapeString)
23−import Text.Collate.Lang (Lang(..))
24+import Text.Pandoc.BCP47
24import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
25import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
25import Text.Pandoc.Definition
26import Text.Pandoc.Definition
26import Text.Pandoc.ImageSize
27import Text.Pandoc.ImageSize
@@ -177,12 +178,8 @@ blockToConTeXt (Para lst) = do
177 contents <- inlineListToConTeXt lst
178 contents <- inlineListToConTeXt lst
178 return $ contents <> blankline
179 return $ contents <> blankline
179blockToConTeXt (LineBlock lns) = do
180blockToConTeXt (LineBlock lns) = do
180− let emptyToBlankline doc = if isEmpty doc
181− then blankline
182− else doc
183− doclines <- mapM inlineListToConTeXt lns
181+ doclines <- nowrap . vcat <$> mapM inlineListToConTeXt lns
184− let contextLines = vcat . map emptyToBlankline $ doclines
185− return $ "\\startlines" $$ contextLines $$ "\\stoplines" <> blankline
182+ return $ "\\startlines" $$ doclines $$ "\\stoplines" <> blankline
186blockToConTeXt (BlockQuote lst) = do
183blockToConTeXt (BlockQuote lst) = do
187 contents <- blockListToConTeXt lst
184 contents <- blockListToConTeXt lst
188 return $ "\\startblockquote" $$ nest 0 contents $$ "\\stopblockquote" <> blankline
185 return $ "\\startblockquote" $$ nest 0 contents $$ "\\stopblockquote" <> blankline
@@ -232,7 +229,14 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
232 Period -> "stopper=."
229 Period -> "stopper=."
233 OneParen -> "stopper=)"
230 OneParen -> "stopper=)"
234 TwoParens -> "left=(,stopper=)"
231 TwoParens -> "left=(,stopper=)"
232+ let width = maybe 0 maximum $ nonEmpty $ map T.length $
233+ take (length contents)
234+ (orderedListMarkers (start, style', delim))
235+ let width' = (toEnum width + 1) / 2
236+ let width'' = if width' > (1.5 :: Double)
237+ then "width=" <> tshow width' <> "em"
238+ else ""
235− let specs2Items = filter (not . T.null) [start', delim']
239+ let specs2Items = filter (not . T.null) [start', delim', width'']
236 let specs2 = if null specs2Items
240 let specs2 = if null specs2Items
237 then ""
241 then ""
238 else "[" <> T.intercalate "," specs2Items <> "]"
242 else "[" <> T.intercalate "," specs2Items <> "]"
@@ -246,8 +250,8 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
246 UpperAlpha -> 'A') :
250 UpperAlpha -> 'A') :
247 if isTightList lst then ",packed]" else "]"
251 if isTightList lst then ",packed]" else "]"
248 let specs = T.pack style'' <> specs2
252 let specs = T.pack style'' <> specs2
249− return $ "\\startenumerate" <> literal specs $$ vcat contents $$
253+ return $ "\\startitemize" <> literal specs $$ vcat contents $$
250− "\\stopenumerate" <> blankline
254+ "\\stopitemize" <> blankline
251blockToConTeXt (DefinitionList lst) =
255blockToConTeXt (DefinitionList lst) =
252 liftM vcat $ mapM defListItemToConTeXt lst
256 liftM vcat $ mapM defListItemToConTeXt lst
253blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
257blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
@@ -479,7 +483,7 @@ inlineToConTeXt (Note contents) = do
479 then literal "\\footnote{" <> nest 2 (chomp contents') <> char '}'
483 then literal "\\footnote{" <> nest 2 (chomp contents') <> char '}'
480 else literal "\\startbuffer " <> nest 2 (chomp contents') <>
484 else literal "\\startbuffer " <> nest 2 (chomp contents') <>
481 literal "\\stopbuffer\\footnote{\\getbuffer}"
485 literal "\\stopbuffer\\footnote{\\getbuffer}"
482−inlineToConTeXt (Span (ident,_,kvs) ils) = do
486+inlineToConTeXt (Span (_,_,kvs) ils) = do
483 mblang <- fromBCP47 (lookup "lang" kvs)
487 mblang <- fromBCP47 (lookup "lang" kvs)
484 let wrapDir txt = case lookup "dir" kvs of
488 let wrapDir txt = case lookup "dir" kvs of
485 Just "rtl" -> braces $ "\\righttoleft " <> txt
489 Just "rtl" -> braces $ "\\righttoleft " <> txt
@@ -489,11 +493,7 @@ inlineToConTeXt (Span (ident,_,kvs) ils) = do
489 Just lng -> braces ("\\language" <>
493 Just lng -> braces ("\\language" <>
490 brackets (literal lng) <> txt)
494 brackets (literal lng) <> txt)
491 Nothing -> txt
495 Nothing -> txt
492− addReference =
493− if T.null ident
494− then id
495− else (("\\reference" <> brackets (literal ident) <> "{}") <>)
496− addReference . wrapLang . wrapDir <$> inlineListToConTeXt ils
496+ wrapLang . wrapDir <$> inlineListToConTeXt ils
497
497
498-- | Craft the section header, inserting the section reference, if supplied.
498-- | Craft the section header, inserting the section reference, if supplied.
499sectionHeader :: PandocMonad m
499sectionHeader :: PandocMonad m
@@ -555,26 +555,26 @@ fromBCP47 mbs = fromBCP47' <$> toLang mbs
555-- https://tools.ietf.org/html/bcp47#section-2.1
555-- https://tools.ietf.org/html/bcp47#section-2.1
556-- http://wiki.contextgarden.net/Language_Codes
556-- http://wiki.contextgarden.net/Language_Codes
557fromBCP47' :: Maybe Lang -> Maybe Text
557fromBCP47' :: Maybe Lang -> Maybe Text
558−fromBCP47' (Just (Lang "ar" _ (Just "SY") _ _ _)) = Just "ar-sy"
558+fromBCP47' (Just (Lang "ar" _ "SY" _) ) = Just "ar-sy"
559−fromBCP47' (Just (Lang "ar" _ (Just "IQ") _ _ _)) = Just "ar-iq"
559+fromBCP47' (Just (Lang "ar" _ "IQ" _) ) = Just "ar-iq"
560−fromBCP47' (Just (Lang "ar" _ (Just "JO") _ _ _)) = Just "ar-jo"
560+fromBCP47' (Just (Lang "ar" _ "JO" _) ) = Just "ar-jo"
561−fromBCP47' (Just (Lang "ar" _ (Just "LB") _ _ _)) = Just "ar-lb"
561+fromBCP47' (Just (Lang "ar" _ "LB" _) ) = Just "ar-lb"
562−fromBCP47' (Just (Lang "ar" _ (Just "DZ") _ _ _)) = Just "ar-dz"
562+fromBCP47' (Just (Lang "ar" _ "DZ" _) ) = Just "ar-dz"
563−fromBCP47' (Just (Lang "ar" _ (Just "MA") _ _ _)) = Just "ar-ma"
563+fromBCP47' (Just (Lang "ar" _ "MA" _) ) = Just "ar-ma"
564−fromBCP47' (Just (Lang "de" _ _ ["1901"] _ _)) = Just "deo"
564+fromBCP47' (Just (Lang "de" _ _ ["1901"]) ) = Just "deo"
565−fromBCP47' (Just (Lang "de" _ (Just "DE") _ _ _)) = Just "de-de"
565+fromBCP47' (Just (Lang "de" _ "DE" _) ) = Just "de-de"
566−fromBCP47' (Just (Lang "de" _ (Just "AT") _ _ _)) = Just "de-at"
566+fromBCP47' (Just (Lang "de" _ "AT" _) ) = Just "de-at"
567−fromBCP47' (Just (Lang "de" _ (Just "CH") _ _ _)) = Just "de-ch"
567+fromBCP47' (Just (Lang "de" _ "CH" _) ) = Just "de-ch"
568−fromBCP47' (Just (Lang "el" _ _ ["poly"] _ _)) = Just "agr"
568+fromBCP47' (Just (Lang "el" _ _ ["poly"]) ) = Just "agr"
569−fromBCP47' (Just (Lang "en" _ (Just "US") _ _ _)) = Just "en-us"
569+fromBCP47' (Just (Lang "en" _ "US" _) ) = Just "en-us"
570−fromBCP47' (Just (Lang "en" _ (Just "GB") _ _ _)) = Just "en-gb"
570+fromBCP47' (Just (Lang "en" _ "GB" _) ) = Just "en-gb"
571−fromBCP47' (Just (Lang "grc"_ _ _ _ _)) = Just "agr"
571+fromBCP47' (Just (Lang "grc"_ _ _) ) = Just "agr"
572−fromBCP47' (Just (Lang "el" _ _ _ _ _)) = Just "gr"
572+fromBCP47' (Just (Lang "el" _ _ _) ) = Just "gr"
573−fromBCP47' (Just (Lang "eu" _ _ _ _ _)) = Just "ba"
573+fromBCP47' (Just (Lang "eu" _ _ _) ) = Just "ba"
574−fromBCP47' (Just (Lang "he" _ _ _ _ _)) = Just "il"
574+fromBCP47' (Just (Lang "he" _ _ _) ) = Just "il"
575−fromBCP47' (Just (Lang "jp" _ _ _ _ _)) = Just "ja"
575+fromBCP47' (Just (Lang "jp" _ _ _) ) = Just "ja"
576−fromBCP47' (Just (Lang "uk" _ _ _ _ _)) = Just "ua"
576+fromBCP47' (Just (Lang "uk" _ _ _) ) = Just "ua"
577−fromBCP47' (Just (Lang "vi" _ _ _ _ _)) = Just "vn"
577+fromBCP47' (Just (Lang "vi" _ _ _) ) = Just "vn"
578−fromBCP47' (Just (Lang "zh" _ _ _ _ _)) = Just "cn"
578+fromBCP47' (Just (Lang "zh" _ _ _) ) = Just "cn"
579−fromBCP47' (Just (Lang l _ _ _ _ _)) = Just l
579+fromBCP47' (Just (Lang l _ _ _) ) = Just l
580−fromBCP47' Nothing = Nothing
580+fromBCP47' Nothing = Nothing
src/Text/Pandoc/Writers/CslJson.hs+3−4
@@ -34,16 +34,15 @@ import Control.Monad.Identity
34import Citeproc.Locale (getLocale)
34import Citeproc.Locale (getLocale)
35import Citeproc.CslJson
35import Citeproc.CslJson
36import Text.Pandoc.Options (WriterOptions)
36import Text.Pandoc.Options (WriterOptions)
37−import Data.Maybe (mapMaybe, fromMaybe)
37+import Data.Maybe (mapMaybe)
38import Data.Aeson.Encode.Pretty (Config (..), Indent (Spaces),
38import Data.Aeson.Encode.Pretty (Config (..), Indent (Spaces),
39 NumberFormat (Generic),
39 NumberFormat (Generic),
40 defConfig, encodePretty')
40 defConfig, encodePretty')
41
41
42writeCslJson :: PandocMonad m => WriterOptions -> Pandoc -> m Text
42writeCslJson :: PandocMonad m => WriterOptions -> Pandoc -> m Text
43writeCslJson _opts (Pandoc meta _) = do
43writeCslJson _opts (Pandoc meta _) = do
44− let lang = fromMaybe (Lang "en" Nothing (Just "US") [] [] [])
44+ let lang = maybe (Lang "en" (Just "US")) parseLang
45− (lookupMeta "lang" meta >>= metaValueToText >>=
45+ (lookupMeta "lang" meta >>= metaValueToText)
46− either (const Nothing) Just . parseLang)
47 locale <- case getLocale lang of
46 locale <- case getLocale lang of
48 Left e -> throwError $ PandocCiteprocError e
47 Left e -> throwError $ PandocCiteprocError e
49 Right l -> return l
48 Right l -> return l
src/Text/Pandoc/Writers/Docbook.hs+6−6
@@ -198,7 +198,8 @@ blockToDocbook opts (Div (id',"section":_,_) (Header lvl (_,_,attrs) ils : xs))
198blockToDocbook opts (Div (ident,classes,_) bs) = do
198blockToDocbook opts (Div (ident,classes,_) bs) = do
199 version <- ask
199 version <- ask
200 let identAttribs = [(idName version, ident) | not (T.null ident)]
200 let identAttribs = [(idName version, ident) | not (T.null ident)]
201+ admonitions = ["attention","caution","danger","error","hint",
201− admonitions = ["caution","danger","important","note","tip","warning"]
202+ "important","note","tip","warning"]
202 case classes of
203 case classes of
203 (l:_) | l `elem` admonitions -> do
204 (l:_) | l `elem` admonitions -> do
204 let (mTitleBs, bodyBs) =
205 let (mTitleBs, bodyBs) =
@@ -252,18 +253,17 @@ blockToDocbook opts (LineBlock lns) =
252 blockToDocbook opts $ linesToPara lns
253 blockToDocbook opts $ linesToPara lns
253blockToDocbook opts (BlockQuote blocks) =
254blockToDocbook opts (BlockQuote blocks) =
254 inTagsIndented "blockquote" <$> blocksToDocbook opts blocks
255 inTagsIndented "blockquote" <$> blocksToDocbook opts blocks
255−blockToDocbook opts (CodeBlock (_,classes,_) str) = return $
256+blockToDocbook _ (CodeBlock (_,classes,_) str) = return $
256 literal ("<programlisting" <> lang <> ">") <> cr <>
257 literal ("<programlisting" <> lang <> ">") <> cr <>
257 flush (literal (escapeStringForXML str) <> cr <> literal "</programlisting>")
258 flush (literal (escapeStringForXML str) <> cr <> literal "</programlisting>")
258 where lang = if null langs
259 where lang = if null langs
259 then ""
260 then ""
260 else " language=\"" <> escapeStringForXML (head langs) <>
261 else " language=\"" <> escapeStringForXML (head langs) <>
261 "\""
262 "\""
262− syntaxMap = writerSyntaxMap opts
263− isLang l = T.toLower l `elem` map T.toLower (languages syntaxMap)
263+ isLang l = T.toLower l `elem` map T.toLower languages
264 langsFrom s = if isLang s
264 langsFrom s = if isLang s
265 then [s]
265 then [s]
266− else (languagesByExtension syntaxMap) . T.toLower $ s
266+ else languagesByExtension . T.toLower $ s
267 langs = concatMap langsFrom classes
267 langs = concatMap langsFrom classes
268blockToDocbook opts (BulletList lst) = do
268blockToDocbook opts (BulletList lst) = do
269 let attribs = [("spacing", "compact") | isTightList lst]
269 let attribs = [("spacing", "compact") | isTightList lst]
@@ -493,4 +493,4 @@ isSectionAttr DocBook4 ("os",_) = True
493isSectionAttr DocBook4 ("revision",_) = True
493isSectionAttr DocBook4 ("revision",_) = True
494isSectionAttr DocBook4 ("security",_) = True
494isSectionAttr DocBook4 ("security",_) = True
495isSectionAttr DocBook4 ("vendor",_) = True
495isSectionAttr DocBook4 ("vendor",_) = True
496−isSectionAttr _ (_,_) = False
496+isSectionAttr _ (_,_) = False
src/Text/Pandoc/Writers/Docx.hs+238−56
@@ -22,6 +22,7 @@ import Control.Applicative ((<|>))
22import Control.Monad.Except (catchError, throwError)
22import Control.Monad.Except (catchError, throwError)
23import Control.Monad.Reader
23import Control.Monad.Reader
24import Control.Monad.State.Strict
24import Control.Monad.State.Strict
25+import qualified Data.ByteString as B
25import qualified Data.ByteString.Lazy as BL
26import qualified Data.ByteString.Lazy as BL
26import Data.Char (isSpace, isLetter)
27import Data.Char (isSpace, isLetter)
27import Data.List (intercalate, isPrefixOf, isSuffixOf)
28import Data.List (intercalate, isPrefixOf, isSuffixOf)
@@ -35,9 +36,8 @@ import qualified Data.Text.Lazy as TL
35import Data.Time.Clock.POSIX
36import Data.Time.Clock.POSIX
36import Data.Digest.Pure.SHA (sha1, showDigest)
37import Data.Digest.Pure.SHA (sha1, showDigest)
37import Skylighting
38import Skylighting
38−import Text.Collate.Lang (renderLang)
39+import Text.Pandoc.BCP47 (getLang, renderLang)
39−import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang, translateTerm)
40+import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
40−import qualified Text.Pandoc.Translations as Term
41import qualified Text.Pandoc.Class.PandocMonad as P
41import qualified Text.Pandoc.Class.PandocMonad as P
42import Data.Time
42import Data.Time
43import Text.Pandoc.UTF8 (fromTextLazy)
43import Text.Pandoc.UTF8 (fromTextLazy)
@@ -47,25 +47,123 @@ import Text.Pandoc.Highlighting (highlight)
47import Text.Pandoc.Error
47import Text.Pandoc.Error
48import Text.Pandoc.ImageSize
48import Text.Pandoc.ImageSize
49import Text.Pandoc.Logging
49import Text.Pandoc.Logging
50−import Text.Pandoc.MIME (extensionFromMimeType, getMimeType, getMimeTypeDef)
50+import Text.Pandoc.MIME (MimeType, extensionFromMimeType, getMimeType,
51+ getMimeTypeDef)
51import Text.Pandoc.Options
52import Text.Pandoc.Options
52import Text.Pandoc.Writers.Docx.StyleMap
53import Text.Pandoc.Writers.Docx.StyleMap
53−import Text.Pandoc.Writers.Docx.Table
54−import Text.Pandoc.Writers.Docx.Types
55import Text.Pandoc.Shared
54import Text.Pandoc.Shared
56import Text.Pandoc.Walk
55import Text.Pandoc.Walk
57−import qualified Text.Pandoc.Writers.GridTable as Grid
58import Text.Pandoc.Writers.Math
56import Text.Pandoc.Writers.Math
59import Text.Pandoc.Writers.Shared
57import Text.Pandoc.Writers.Shared
58+import Text.Printf (printf)
60import Text.TeXMath
59import Text.TeXMath
61import Text.Pandoc.Writers.OOXML
60import Text.Pandoc.Writers.OOXML
62import Text.Pandoc.XML.Light as XML
61import Text.Pandoc.XML.Light as XML
63import Data.Generics (mkT, everywhere)
62import Data.Generics (mkT, everywhere)
64
63
64+data ListMarker = NoMarker
65+ | BulletMarker
66+ | NumberMarker ListNumberStyle ListNumberDelim Int
67+ deriving (Show, Read, Eq, Ord)
68+
69+listMarkerToId :: ListMarker -> Text
70+listMarkerToId NoMarker = "990"
71+listMarkerToId BulletMarker = "991"
72+listMarkerToId (NumberMarker sty delim n) = T.pack $
73+ '9' : '9' : styNum : delimNum : show n
74+ where styNum = case sty of
75+ DefaultStyle -> '2'
76+ Example -> '3'
77+ Decimal -> '4'
78+ LowerRoman -> '5'
79+ UpperRoman -> '6'
80+ LowerAlpha -> '7'
81+ UpperAlpha -> '8'
82+ delimNum = case delim of
83+ DefaultDelim -> '0'
84+ Period -> '1'
85+ OneParen -> '2'
86+ TwoParens -> '3'
87+
88+data EnvProps = EnvProps{ styleElement :: Maybe Element
89+ , otherElements :: [Element]
90+ }
91+
92+instance Semigroup EnvProps where
93+ EnvProps s es <> EnvProps s' es' = EnvProps (s <|> s') (es ++ es')
94+
95+instance Monoid EnvProps where
96+ mempty = EnvProps Nothing []
97+ mappend = (<>)
98+
65squashProps :: EnvProps -> [Element]
99squashProps :: EnvProps -> [Element]
66squashProps (EnvProps Nothing es) = es
100squashProps (EnvProps Nothing es) = es
67squashProps (EnvProps (Just e) es) = e : es
101squashProps (EnvProps (Just e) es) = e : es
68
102
103+data WriterEnv = WriterEnv{ envTextProperties :: EnvProps
104+ , envParaProperties :: EnvProps
105+ , envRTL :: Bool
106+ , envListLevel :: Int
107+ , envListNumId :: Int
108+ , envInDel :: Bool
109+ , envChangesAuthor :: Text
110+ , envChangesDate :: Text
111+ , envPrintWidth :: Integer
112+ }
113+
114+defaultWriterEnv :: WriterEnv
115+defaultWriterEnv = WriterEnv{ envTextProperties = mempty
116+ , envParaProperties = mempty
117+ , envRTL = False
118+ , envListLevel = -1
119+ , envListNumId = 1
120+ , envInDel = False
121+ , envChangesAuthor = "unknown"
122+ , envChangesDate = "1969-12-31T19:00:00Z"
123+ , envPrintWidth = 1
124+ }
125+
126+data WriterState = WriterState{
127+ stFootnotes :: [Element]
128+ , stComments :: [([(Text, Text)], [Inline])]
129+ , stSectionIds :: Set.Set Text
130+ , stExternalLinks :: M.Map Text Text
131+ , stImages :: M.Map FilePath (String, String, Maybe MimeType, B.ByteString)
132+ , stLists :: [ListMarker]
133+ , stInsId :: Int
134+ , stDelId :: Int
135+ , stStyleMaps :: StyleMaps
136+ , stFirstPara :: Bool
137+ , stInTable :: Bool
138+ , stInList :: Bool
139+ , stTocTitle :: [Inline]
140+ , stDynamicParaProps :: Set.Set ParaStyleName
141+ , stDynamicTextProps :: Set.Set CharStyleName
142+ , stCurId :: Int
143+ }
144+
145+defaultWriterState :: WriterState
146+defaultWriterState = WriterState{
147+ stFootnotes = defaultFootnotes
148+ , stComments = []
149+ , stSectionIds = Set.empty
150+ , stExternalLinks = M.empty
151+ , stImages = M.empty
152+ , stLists = [NoMarker]
153+ , stInsId = 1
154+ , stDelId = 1
155+ , stStyleMaps = StyleMaps M.empty M.empty
156+ , stFirstPara = False
157+ , stInTable = False
158+ , stInList = False
159+ , stTocTitle = [Str "Table of Contents"]
160+ , stDynamicParaProps = Set.empty
161+ , stDynamicTextProps = Set.empty
162+ , stCurId = 20
163+ }
164+
165+type WS m = ReaderT WriterEnv (StateT WriterState m)
166+
69renumIdMap :: Int -> [Element] -> M.Map Text Text
167renumIdMap :: Int -> [Element] -> M.Map Text Text
70renumIdMap _ [] = M.empty
168renumIdMap _ [] = M.empty
71renumIdMap n (e:es)
169renumIdMap n (e:es)
@@ -470,27 +568,12 @@ writeDocx opts doc = do
470 -- adds references to footnotes or endnotes we don't have...
568 -- adds references to footnotes or endnotes we don't have...
471 -- we do, however, copy some settings over from reference
569 -- we do, however, copy some settings over from reference
472 let settingsPath = "word/settings.xml"
570 let settingsPath = "word/settings.xml"
473− settingsList = [ "zoom"
474− , "embedSystemFonts"
475− , "doNotTrackMoves"
476− , "defaultTabStop"
477− , "drawingGridHorizontalSpacing"
478− , "drawingGridVerticalSpacing"
479− , "displayHorizontalDrawingGridEvery"
480− , "displayVerticalDrawingGridEvery"
481− , "characterSpacingControl"
482− , "savePreviewPicture"
483− , "mathPr"
484− , "themeFontLang"
485− , "decimalSymbol"
486− , "listSeparator"
487− , "autoHyphenation"
571+ settingsList = [ "w:autoHyphenation"
488− , "consecutiveHyphenLimit"
572+ , "w:consecutiveHyphenLimit"
489− , "hyphenationZone"
573+ , "w:hyphenationZone"
490− , "doNotHyphenateCap"
574+ , "w:doNotHyphenateCap"
491− , "evenAndOddHeaders"
575+ , "w:evenAndOddHeaders"
492− , "proofState"
576+ , "w:proofState"
493− , "compat"
494 ]
577 ]
495 settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime settingsList
578 settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime settingsList
496
579
@@ -593,17 +676,16 @@ copyChildren :: (PandocMonad m)
593copyChildren refArchive distArchive path timestamp elNames = do
676copyChildren refArchive distArchive path timestamp elNames = do
594 ref <- parseXml refArchive distArchive path
677 ref <- parseXml refArchive distArchive path
595 dist <- parseXml distArchive distArchive path
678 dist <- parseXml distArchive distArchive path
596− let elsToCopy =
597− map cleanElem $ filterChildrenName (\e -> qName e `elem` elNames) ref
598− let elsToKeep =
599− [e | Elem e <- elContent dist, not (any (hasSameNameAs e) elsToCopy)]
600 return $ toEntry path timestamp $ renderXml dist{
679 return $ toEntry path timestamp $ renderXml dist{
601− elContent = map Elem elsToKeep ++ map Elem elsToCopy
680+ elContent = elContent dist ++ copyContent ref
602 }
681 }
603 where
682 where
604− hasSameNameAs (Element {elName = n1}) (Element {elName = n2}) =
683+ strName QName{qName=name, qPrefix=prefix}
605− qName n1 == qName n2
684+ | Just p <- prefix = p <> ":" <> name
685+ | otherwise = name
686+ shouldCopy = (`elem` elNames) . strName
606− cleanElem el@Element{elName=name} = el{elName=name{qURI=Nothing}}
687+ cleanElem el@Element{elName=name} = Elem el{elName=name{qURI=Nothing}}
688+ copyContent = map cleanElem . filterChildrenName shouldCopy
607
689
608-- this is the lowest number used for a list numId
690-- this is the lowest number used for a list numId
609baseListId :: Int
691baseListId :: Int
@@ -776,6 +858,12 @@ separateTables (x@Table{}:xs@(Table{}:_)) =
776 x : RawBlock (Format "openxml") "<w:p />" : separateTables xs
858 x : RawBlock (Format "openxml") "<w:p />" : separateTables xs
777separateTables (x:xs) = x : separateTables xs
859separateTables (x:xs) = x : separateTables xs
778
860
861+pStyleM :: (PandocMonad m) => ParaStyleName -> WS m XML.Element
862+pStyleM styleName = do
863+ pStyleMap <- gets (smParaStyle . stStyleMaps)
864+ let sty' = getStyleIdFromName styleName pStyleMap
865+ return $ mknode "w:pStyle" [("w:val", fromStyleId sty')] ()
866+
779rStyleM :: (PandocMonad m) => CharStyleName -> WS m XML.Element
867rStyleM :: (PandocMonad m) => CharStyleName -> WS m XML.Element
780rStyleM styleName = do
868rStyleM styleName = do
781 cStyleMap <- gets (smCharStyle . stStyleMaps)
869 cStyleMap <- gets (smCharStyle . stStyleMaps)
@@ -855,28 +943,14 @@ blockToOpenXML' opts (Plain lst) = do
855-- title beginning with fig: indicates that the image is a figure
943-- title beginning with fig: indicates that the image is a figure
856blockToOpenXML' opts (Para [Image attr alt (src,T.stripPrefix "fig:" -> Just tit)]) = do
944blockToOpenXML' opts (Para [Image attr alt (src,T.stripPrefix "fig:" -> Just tit)]) = do
857 setFirstPara
945 setFirstPara
858− fignum <- gets stNextFigureNum
859− unless (null alt) $ modify $ \st -> st{ stNextFigureNum = fignum + 1 }
860− let figid = "fig" <> tshow fignum
861− figname <- translateTerm Term.Figure
862 prop <- pStyleM $
946 prop <- pStyleM $
863 if null alt
947 if null alt
864 then "Figure"
948 then "Figure"
865 else "Captioned Figure"
949 else "Captioned Figure"
866 paraProps <- local (\env -> env { envParaProperties = EnvProps (Just prop) [] <> envParaProperties env }) (getParaProps False)
950 paraProps <- local (\env -> env { envParaProperties = EnvProps (Just prop) [] <> envParaProperties env }) (getParaProps False)
867 contents <- inlinesToOpenXML opts [Image attr alt (src,tit)]
951 contents <- inlinesToOpenXML opts [Image attr alt (src,tit)]
868− captionNode <- if null alt
869− then return []
870− else withParaPropM (pStyleM "Image Caption")
952+ captionNode <- withParaPropM (pStyleM "Image Caption")
871− $ blockToOpenXML opts
953+ $ blockToOpenXML opts (Para alt)
872− (Para $ Span (figid,[],[])
873− [Str (figname <> "\160"),
874− RawInline (Format "openxml")
875− ("<w:fldSimple w:instr=\"SEQ Figure"
876− <> " \\* ARABIC \"><w:r><w:t>"
877− <> tshow fignum
878− <> "</w:t></w:r></w:fldSimple>"),
879− Str ":", Space] : alt)
880 return $
954 return $
881 Elem (mknode "w:p" [] (map Elem paraProps ++ contents))
955 Elem (mknode "w:p" [] (map Elem paraProps ++ contents))
882 : captionNode
956 : captionNode
@@ -921,9 +995,78 @@ blockToOpenXML' _ HorizontalRule = do
921 $ mknode "v:rect" [("style","width:0;height:1.5pt"),
995 $ mknode "v:rect" [("style","width:0;height:1.5pt"),
922 ("o:hralign","center"),
996 ("o:hralign","center"),
923 ("o:hrstd","t"),("o:hr","t")] () ]
997 ("o:hrstd","t"),("o:hr","t")] () ]
924−blockToOpenXML' opts (Table attr caption colspecs thead tbodies tfoot) =
998+blockToOpenXML' opts (Table _ blkCapt specs thead tbody tfoot) = do
999+ let (caption, aligns, widths, headers, rows) = toLegacyTable blkCapt specs thead tbody tfoot
1000+ setFirstPara
1001+ modify $ \s -> s { stInTable = True }
1002+ let captionStr = stringify caption
1003+ caption' <- if null caption
1004+ then return []
1005+ else withParaPropM (pStyleM "Table Caption")
1006+ $ blockToOpenXML opts (Para caption)
1007+ let alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()
1008+ -- Table cells require a <w:p> element, even an empty one!
1009+ -- Not in the spec but in Word 2007, 2010. See #4953. And
1010+ -- apparently the last element must be a <w:p>, see #6983.
1011+ let cellToOpenXML (al, cell) = do
925− tableToOpenXML (blocksToOpenXML opts)
1012+ es <- withParaProp (alignmentFor al) $ blocksToOpenXML opts cell
926− (Grid.toTable attr caption colspecs thead tbodies tfoot)
1013+ return $
1014+ case reverse (onlyElems es) of
1015+ b:e:_ | qName (elName b) == "bookmarkEnd"
1016+ , qName (elName e) == "p" -> es
1017+ e:_ | qName (elName e) == "p" -> es
1018+ _ -> es ++ [Elem $ mknode "w:p" [] ()]
1019+ headers' <- mapM cellToOpenXML $ zip aligns headers
1020+ rows' <- mapM (mapM cellToOpenXML . zip aligns) rows
1021+ compactStyle <- pStyleM "Compact"
1022+ let emptyCell' = [Elem $ mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]]
1023+ let mkcell contents = mknode "w:tc" []
1024+ $ if null contents
1025+ then emptyCell'
1026+ else contents
1027+ let mkrow cells =
1028+ mknode "w:tr" [] $
1029+ map mkcell cells
1030+ let textwidth = 7920 -- 5.5 in in twips, 1/20 pt
1031+ let fullrow = 5000 -- 100% specified in pct
1032+ let (rowwidth :: Int) = round $ fullrow * sum widths
1033+ let mkgridcol w = mknode "w:gridCol"
1034+ [("w:w", tshow (floor (textwidth * w) :: Integer))] ()
1035+ let hasHeader = not $ all null headers
1036+ modify $ \s -> s { stInTable = False }
1037+ -- for compatibility with Word <= 2007, we include a val with a bitmask
1038+ -- 0×0020 Apply first row conditional formatting
1039+ -- 0×0040 Apply last row conditional formatting
1040+ -- 0×0080 Apply first column conditional formatting
1041+ -- 0×0100 Apply last column conditional formatting
1042+ -- 0×0200 Do not apply row banding conditional formatting
1043+ -- 0×0400 Do not apply column banding conditional formattin
1044+ let tblLookVal :: Int
1045+ tblLookVal = if hasHeader then 0x20 else 0
1046+ return $
1047+ caption' ++
1048+ [Elem $
1049+ mknode "w:tbl" []
1050+ ( mknode "w:tblPr" []
1051+ ( mknode "w:tblStyle" [("w:val","Table")] () :
1052+ mknode "w:tblW" [("w:type", "pct"), ("w:w", tshow rowwidth)] () :
1053+ mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0")
1054+ ,("w:lastRow","0")
1055+ ,("w:firstColumn","0")
1056+ ,("w:lastColumn","0")
1057+ ,("w:noHBand","0")
1058+ ,("w:noVBand","0")
1059+ ,("w:val", T.pack $ printf "%04x" tblLookVal)
1060+ ] () :
1061+ [ mknode "w:tblCaption" [("w:val", captionStr)] ()
1062+ | not (null caption) ] )
1063+ : mknode "w:tblGrid" []
1064+ (if all (==0) widths
1065+ then []
1066+ else map mkgridcol widths)
1067+ : [ mkrow headers' | hasHeader ] ++
1068+ map mkrow rows'
1069+ )]
927blockToOpenXML' opts el
1070blockToOpenXML' opts el
928 | BulletList lst <- el = addOpenXMLList BulletMarker lst
1071 | BulletList lst <- el = addOpenXMLList BulletMarker lst
929 | OrderedList (start, numstyle, numdelim) lst <- el
1072 | OrderedList (start, numstyle, numdelim) lst <- el
@@ -978,6 +1121,13 @@ listItemToOpenXML opts numid (first:rest) = do
978 modify $ \st -> st{ stInList = oldInList }
1121 modify $ \st -> st{ stInList = oldInList }
979 return $ first'' ++ rest''
1122 return $ first'' ++ rest''
980
1123
1124+alignmentToString :: Alignment -> Text
1125+alignmentToString alignment = case alignment of
1126+ AlignLeft -> "left"
1127+ AlignRight -> "right"
1128+ AlignCenter -> "center"
1129+ AlignDefault -> "left"
1130+
981-- | Convert a list of inline elements to OpenXML.
1131-- | Convert a list of inline elements to OpenXML.
982inlinesToOpenXML :: PandocMonad m => WriterOptions -> [Inline] -> WS m [Content]
1132inlinesToOpenXML :: PandocMonad m => WriterOptions -> [Inline] -> WS m [Content]
983inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst
1133inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst
@@ -988,6 +1138,10 @@ withNumId numid = local $ \env -> env{ envListNumId = numid }
988asList :: (PandocMonad m) => WS m a -> WS m a
1138asList :: (PandocMonad m) => WS m a -> WS m a
989asList = local $ \env -> env{ envListLevel = envListLevel env + 1 }
1139asList = local $ \env -> env{ envListLevel = envListLevel env + 1 }
990
1140
1141+isStyle :: Element -> Bool
1142+isStyle e = isElem [] "w" "rStyle" e ||
1143+ isElem [] "w" "pStyle" e
1144+
991getTextProps :: (PandocMonad m) => WS m [Element]
1145getTextProps :: (PandocMonad m) => WS m [Element]
992getTextProps = do
1146getTextProps = do
993 props <- asks envTextProperties
1147 props <- asks envTextProperties
@@ -1016,6 +1170,16 @@ getParaProps displayMathPara = do
1016 [] -> []
1170 [] -> []
1017 ps -> [mknode "w:pPr" [] ps]
1171 ps -> [mknode "w:pPr" [] ps]
1018
1172
1173+withParaProp :: PandocMonad m => Element -> WS m a -> WS m a
1174+withParaProp d p =
1175+ local (\env -> env {envParaProperties = ep <> envParaProperties env}) p
1176+ where ep = if isStyle d then EnvProps (Just d) [] else EnvProps Nothing [d]
1177+
1178+withParaPropM :: PandocMonad m => WS m Element -> WS m a -> WS m a
1179+withParaPropM md p = do
1180+ d <- md
1181+ withParaProp d p
1182+
1019formattedString :: PandocMonad m => Text -> WS m [Element]
1183formattedString :: PandocMonad m => Text -> WS m [Element]
1020formattedString str =
1184formattedString str =
1021 -- properly handle soft hyphens
1185 -- properly handle soft hyphens
@@ -1036,6 +1200,9 @@ formattedRun els = do
1036 props <- getTextProps
1200 props <- getTextProps
1037 return [ mknode "w:r" [] $ props ++ els ]
1201 return [ mknode "w:r" [] $ props ++ els ]
1038
1202
1203+setFirstPara :: PandocMonad m => WS m ()
1204+setFirstPara = modify $ \s -> s { stFirstPara = True }
1205+
1039-- | Convert an inline element to OpenXML.
1206-- | Convert an inline element to OpenXML.
1040inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Content]
1207inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Content]
1041inlineToOpenXML opts il = withDirection $ inlineToOpenXML' opts il
1208inlineToOpenXML opts il = withDirection $ inlineToOpenXML' opts il
@@ -1304,7 +1471,6 @@ inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do
1304 Just Eps -> ".eps"
1471 Just Eps -> ".eps"
1305 Just Svg -> ".svg"
1472 Just Svg -> ".svg"
1306 Just Emf -> ".emf"
1473 Just Emf -> ".emf"
1307− Just Tiff -> ".tiff"
1308 Nothing -> ""
1474 Nothing -> ""
1309 imgpath = "media/" <> ident <> imgext
1475 imgpath = "media/" <> ident <> imgext
1310 mbMimeType = mt <|> getMimeType (T.unpack imgpath)
1476 mbMimeType = mt <|> getMimeType (T.unpack imgpath)
@@ -1328,6 +1494,22 @@ inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do
1328br :: Element
1494br :: Element
1329br = mknode "w:r" [] [mknode "w:br" [] ()]
1495br = mknode "w:r" [] [mknode "w:br" [] ()]
1330
1496
1497+-- Word will insert these footnotes into the settings.xml file
1498+-- (whether or not they're visible in the document). If they're in the
1499+-- file, but not in the footnotes.xml file, it will produce
1500+-- problems. So we want to make sure we insert them into our document.
1501+defaultFootnotes :: [Element]
1502+defaultFootnotes = [ mknode "w:footnote"
1503+ [("w:type", "separator"), ("w:id", "-1")]
1504+ [ mknode "w:p" []
1505+ [mknode "w:r" []
1506+ [ mknode "w:separator" [] ()]]]
1507+ , mknode "w:footnote"
1508+ [("w:type", "continuationSeparator"), ("w:id", "0")]
1509+ [ mknode "w:p" []
1510+ [ mknode "w:r" []
1511+ [ mknode "w:continuationSeparator" [] ()]]]]
1512+
1331
1513
1332withDirection :: PandocMonad m => WS m a -> WS m a
1514withDirection :: PandocMonad m => WS m a -> WS m a
1333withDirection x = do
1515withDirection x = do
src/Text/Pandoc/Writers/Docx/Table.hsdeleted−227
@@ -1,227 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−{- |
5−Module : Text.Pandoc.Writers.Docx.Table
6−Copyright : Copyright (C) 2012-2021 John MacFarlane
7−License : GNU GPL, version 2 or above
8−Maintainer : John MacFarlane <jgm@berkeley.edu>
9−
10−Conversion of table blocks to docx.
11−-}
12−module Text.Pandoc.Writers.Docx.Table
13− ( tableToOpenXML
14− ) where
15−
16−import Control.Monad.State.Strict
17−import Data.Array
18−import Data.Text (Text)
19−import Text.Pandoc.Definition
20−import Text.Pandoc.Class.PandocMonad (PandocMonad, translateTerm)
21−import Text.Pandoc.Writers.Docx.Types
22−import Text.Pandoc.Shared
23−import Text.Printf (printf)
24−import Text.Pandoc.Writers.GridTable hiding (Table)
25−import Text.Pandoc.Writers.OOXML
26−import Text.Pandoc.XML.Light as XML hiding (Attr)
27−import qualified Data.Text as T
28−import qualified Text.Pandoc.Translations as Term
29−import qualified Text.Pandoc.Writers.GridTable as Grid
30−
31−tableToOpenXML :: PandocMonad m
32− => ([Block] -> WS m [Content])
33− -> Grid.Table
34− -> WS m [Content]
35−tableToOpenXML blocksToOpenXML gridTable = do
36− setFirstPara
37− let (Grid.Table (ident,_,_) caption colspecs _rowheads thead tbodies tfoot) =
38− gridTable
39− let (Caption _maybeShortCaption captionBlocks) = caption
40− tablenum <- gets stNextTableNum
41− unless (null captionBlocks) $
42− modify $ \st -> st{ stNextTableNum = tablenum + 1 }
43− let tableid = if T.null ident
44− then "table" <> tshow tablenum
45− else ident
46− tablename <- translateTerm Term.Table
47− let captionStr = stringify captionBlocks
48− let aligns = map fst $ elems colspecs
49− captionXml <- if null captionBlocks
50− then return []
51− else withParaPropM (pStyleM "Table Caption")
52− $ blocksToOpenXML
53− $ addLabel tableid tablename tablenum captionBlocks
54− -- We set "in table" after processing the caption, because we don't
55− -- want the "Table Caption" style to be overwritten with "Compact".
56− modify $ \s -> s { stInTable = True }
57− head' <- cellGridToOpenXML blocksToOpenXML HeadRow aligns thead
58− bodies <- mapM (cellGridToOpenXML blocksToOpenXML BodyRow aligns) tbodies
59− foot' <- cellGridToOpenXML blocksToOpenXML FootRow aligns tfoot
60−
61− let hasHeader = not . null . indices . partRowAttrs $ thead
62− let hasFooter = not . null . indices . partRowAttrs $ tfoot
63− -- for compatibility with Word <= 2007, we include a val with a bitmask
64− -- 0×0020 Apply first row conditional formatting
65− -- 0×0040 Apply last row conditional formatting
66− -- 0×0080 Apply first column conditional formatting
67− -- 0×0100 Apply last column conditional formatting
68− -- 0×0200 Do not apply row banding conditional formatting
69− -- 0×0400 Do not apply column banding conditional formattin
70− let tblLookVal = if hasHeader then (0x20 :: Int) else 0
71− let (gridCols, tblWattr) = tableLayout (elems colspecs)
72− let tbl = mknode "w:tbl" []
73− ( mknode "w:tblPr" []
74− ( mknode "w:tblStyle" [("w:val","Table")] () :
75− mknode "w:tblW" tblWattr () :
76− mknode "w:tblLook" [("w:firstRow",if hasHeader then "1" else "0")
77− ,("w:lastRow",if hasFooter then "1" else "0")
78− ,("w:firstColumn","0")
79− ,("w:lastColumn","0")
80− ,("w:noHBand","0")
81− ,("w:noVBand","0")
82− ,("w:val", T.pack $ printf "%04x" tblLookVal)
83− ] () :
84− [ mknode "w:tblCaption" [("w:val", captionStr)] ()
85− | not (T.null captionStr) ]
86− )
87− : mknode "w:tblGrid" [] gridCols
88− : head' ++ mconcat bodies ++ foot'
89− )
90− modify $ \s -> s { stInTable = False }
91− return $ captionXml ++ [Elem tbl]
92−
93−addLabel :: Text -> Text -> Int -> [Block] -> [Block]
94−addLabel tableid tablename tablenum bs =
95− case bs of
96− (Para ils : rest) -> Para (label : Space : ils) : rest
97− (Plain ils : rest) -> Plain (label : Space : ils) : rest
98− _ -> Para [label] : bs
99− where
100− label = Span (tableid,[],[])
101− [Str (tablename <> "\160"),
102− RawInline (Format "openxml")
103− ("<w:fldSimple w:instr=\"SEQ Table"
104− <> " \\* ARABIC \"><w:r><w:t>"
105− <> tshow tablenum
106− <> "</w:t></w:r></w:fldSimple>"),
107− Str ":"]
108−
109−-- | Parts of a table
110−data RowType = HeadRow | BodyRow | FootRow
111−
112−alignmentToString :: Alignment -> Text
113−alignmentToString = \case
114− AlignLeft -> "left"
115− AlignRight -> "right"
116− AlignCenter -> "center"
117− AlignDefault -> "left"
118−
119−tableLayout :: [ColSpec] -> ([Element], [(Text, Text)])
120−tableLayout specs =
121− let
122− textwidth = 7920 -- 5.5 in in twips (1 twip == 1/20 pt)
123− fullrow = 5000 -- 100% specified in pct (1 pct == 1/50th of a percent)
124− ncols = length specs
125− getWidth = \case
126− ColWidth n -> n
127− _ -> 0
128− widths = map (getWidth . snd) specs
129− rowwidth = round (fullrow * sum widths) :: Int
130− widthToTwips w = floor (textwidth * w) :: Int
131− mkGridCol w = mknode "w:gridCol" [("w:w", tshow (widthToTwips w))] ()
132− in if all (== 0) widths
133− then ( replicate ncols $ mkGridCol (1.0 / fromIntegral ncols)
134− , [ ("w:type", "auto"), ("w:w", "0")])
135− else ( map mkGridCol widths
136− , [ ("w:type", "pct"), ("w:w", tshow rowwidth) ])
137−
138−cellGridToOpenXML :: PandocMonad m
139− => ([Block] -> WS m [Content])
140− -> RowType
141− -> [Alignment]
142− -> Part
143− -> WS m [Element]
144−cellGridToOpenXML blocksToOpenXML rowType aligns part@(Part _ cellArray _) =
145− if null (elems cellArray)
146− then return mempty
147− else mapM (rowToOpenXML blocksToOpenXML) $
148− partToRows rowType aligns part
149−
150−data OOXMLCell
151− = OOXMLCell Attr Alignment RowSpan ColSpan [Block]
152− | OOXMLCellMerge ColSpan
153−
154−data OOXMLRow = OOXMLRow RowType Attr [OOXMLCell]
155−
156−partToRows :: RowType -> [Alignment] -> Part -> [OOXMLRow]
157−partToRows rowType aligns part =
158− let
159− toOOXMLCell :: Alignment -> RowIndex -> ColIndex -> GridCell -> [OOXMLCell]
160− toOOXMLCell columnAlign ridx cidx = \case
161− ContentCell attr align rowspan colspan blocks ->
162− -- Respect non-default, cell specific alignment.
163− let align' = case align of
164− AlignDefault -> columnAlign
165− _ -> align
166− in [OOXMLCell attr align' rowspan colspan blocks]
167− ContinuationCell idx'@(ridx',cidx') | ridx /= ridx', cidx == cidx' ->
168− case (partCellArray part)!idx' of
169− (ContentCell _ _ _ colspan _) -> [OOXMLCellMerge colspan]
170− x -> error $ "Content cell expected, got, " ++ show x ++
171− " at index " ++ show idx'
172− _ -> mempty
173− mkRow :: (RowIndex, Attr) -> OOXMLRow
174− mkRow (ridx, attr) = OOXMLRow rowType attr
175− . mconcat
176− . zipWith (\align -> uncurry $ toOOXMLCell align ridx)
177− aligns
178− . assocs
179− . rowArray ridx
180− $ partCellArray part
181− in map mkRow $ assocs (partRowAttrs part)
182−
183−rowToOpenXML :: PandocMonad m
184− => ([Block] -> WS m [Content])
185− -> OOXMLRow
186− -> WS m Element
187−rowToOpenXML blocksToOpenXML (OOXMLRow rowType _attr cells) = do
188− xmlcells <- mapM (ooxmlCellToOpenXML blocksToOpenXML) cells
189− let addTrPr = case rowType of
190− HeadRow -> (mknode "w:trPr" []
191− [mknode "w:tblHeader" [("w:val", "true")] ()] :)
192− BodyRow -> id
193− FootRow -> id
194− return $ mknode "w:tr" [] (addTrPr xmlcells)
195−
196−ooxmlCellToOpenXML :: PandocMonad m
197− => ([Block] -> WS m [Content])
198− -> OOXMLCell
199− -> WS m Element
200−ooxmlCellToOpenXML blocksToOpenXML = \case
201− OOXMLCellMerge (ColSpan colspan) -> do
202− return $ mknode "w:tc" []
203− [ mknode "w:tcPr" [] [ mknode "w:gridSpan" [("w:val", tshow colspan)] ()
204− , mknode "w:vMerge" [("w:val", "continue")] () ]
205− , mknode "w:p" [] [mknode "w:pPr" [] ()]]
206− OOXMLCell _attr align rowspan (ColSpan colspan) contents -> do
207− compactStyle <- pStyleM "Compact"
208− es <- withParaProp (alignmentFor align) $ blocksToOpenXML contents
209− -- Table cells require a <w:p> element, even an empty one!
210− -- Not in the spec but in Word 2007, 2010. See #4953. And
211− -- apparently the last element must be a <w:p>, see #6983.
212− return . mknode "w:tc" [] $
213− Elem
214− (mknode "w:tcPr" [] ([ mknode "w:gridSpan" [("w:val", tshow colspan)] ()
215− | colspan > 1] ++
216− [ mknode "w:vMerge" [("w:val", "restart")] ()
217− | rowspan > RowSpan 1 ])) :
218− if null contents
219− then [Elem $ mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]]
220− else case reverse (onlyElems es) of
221− b:e:_ | qName (elName b) == "bookmarkEnd" -- y tho?
222− , qName (elName e) == "p" -> es
223− e:_ | qName (elName e) == "p" -> es
224− _ -> es ++ [Elem $ mknode "w:p" [] ()]
225−
226−alignmentFor :: Alignment -> Element
227−alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()
src/Text/Pandoc/Writers/Docx/Types.hsdeleted−185
@@ -1,185 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{- |
3−Module : Text.Pandoc.Writers.Docx
4−Copyright : Copyright (C) 2012-2021 John MacFarlane
5−License : GNU GPL, version 2 or above
6−Maintainer : John MacFarlane <jgm@berkeley.edu>
7−
8−Conversion of table blocks to docx.
9−-}
10−module Text.Pandoc.Writers.Docx.Types
11− ( EnvProps (..)
12− , WriterEnv (..)
13− , defaultWriterEnv
14− , WriterState (..)
15− , defaultWriterState
16− , WS
17− , ListMarker (..)
18− , listMarkerToId
19− , pStyleM
20− , isStyle
21− , setFirstPara
22− , withParaProp
23− , withParaPropM
24− ) where
25−
26−import Control.Applicative ((<|>))
27−import Control.Monad.Reader
28−import Control.Monad.State.Strict
29−import Data.Text (Text)
30−import Text.Pandoc.Class.PandocMonad (PandocMonad)
31−import Text.Pandoc.Definition
32−import Text.Pandoc.MIME (MimeType)
33−import Text.Pandoc.Writers.Docx.StyleMap
34−import Text.Pandoc.Writers.OOXML
35−import Text.Pandoc.XML.Light as XML
36−import qualified Data.ByteString as B
37−import qualified Data.Map as M
38−import qualified Data.Set as Set
39−import qualified Data.Text as T
40−
41−data ListMarker = NoMarker
42− | BulletMarker
43− | NumberMarker ListNumberStyle ListNumberDelim Int
44− deriving (Show, Read, Eq, Ord)
45−
46−listMarkerToId :: ListMarker -> Text
47−listMarkerToId NoMarker = "990"
48−listMarkerToId BulletMarker = "991"
49−listMarkerToId (NumberMarker sty delim n) = T.pack $
50− '9' : '9' : styNum : delimNum : show n
51− where styNum = case sty of
52− DefaultStyle -> '2'
53− Example -> '3'
54− Decimal -> '4'
55− LowerRoman -> '5'
56− UpperRoman -> '6'
57− LowerAlpha -> '7'
58− UpperAlpha -> '8'
59− delimNum = case delim of
60− DefaultDelim -> '0'
61− Period -> '1'
62− OneParen -> '2'
63− TwoParens -> '3'
64−
65−
66−data EnvProps = EnvProps{ styleElement :: Maybe Element
67− , otherElements :: [Element]
68− }
69−
70−instance Semigroup EnvProps where
71− EnvProps s es <> EnvProps s' es' = EnvProps (s <|> s') (es ++ es')
72−
73−instance Monoid EnvProps where
74− mempty = EnvProps Nothing []
75− mappend = (<>)
76−
77−data WriterEnv = WriterEnv
78− { envTextProperties :: EnvProps
79− , envParaProperties :: EnvProps
80− , envRTL :: Bool
81− , envListLevel :: Int
82− , envListNumId :: Int
83− , envInDel :: Bool
84− , envChangesAuthor :: Text
85− , envChangesDate :: Text
86− , envPrintWidth :: Integer
87− }
88−
89−defaultWriterEnv :: WriterEnv
90−defaultWriterEnv = WriterEnv
91− { envTextProperties = mempty
92− , envParaProperties = mempty
93− , envRTL = False
94− , envListLevel = -1
95− , envListNumId = 1
96− , envInDel = False
97− , envChangesAuthor = "unknown"
98− , envChangesDate = "1969-12-31T19:00:00Z"
99− , envPrintWidth = 1
100− }
101−
102−
103−data WriterState = WriterState{
104− stFootnotes :: [Element]
105− , stComments :: [([(Text, Text)], [Inline])]
106− , stSectionIds :: Set.Set Text
107− , stExternalLinks :: M.Map Text Text
108− , stImages :: M.Map FilePath (String, String, Maybe MimeType, B.ByteString)
109− , stLists :: [ListMarker]
110− , stInsId :: Int
111− , stDelId :: Int
112− , stStyleMaps :: StyleMaps
113− , stFirstPara :: Bool
114− , stInTable :: Bool
115− , stInList :: Bool
116− , stTocTitle :: [Inline]
117− , stDynamicParaProps :: Set.Set ParaStyleName
118− , stDynamicTextProps :: Set.Set CharStyleName
119− , stCurId :: Int
120− , stNextFigureNum :: Int
121− , stNextTableNum :: Int
122− }
123−
124−defaultWriterState :: WriterState
125−defaultWriterState = WriterState{
126− stFootnotes = defaultFootnotes
127− , stComments = []
128− , stSectionIds = Set.empty
129− , stExternalLinks = M.empty
130− , stImages = M.empty
131− , stLists = [NoMarker]
132− , stInsId = 1
133− , stDelId = 1
134− , stStyleMaps = StyleMaps M.empty M.empty
135− , stFirstPara = False
136− , stInTable = False
137− , stInList = False
138− , stTocTitle = [Str "Table of Contents"]
139− , stDynamicParaProps = Set.empty
140− , stDynamicTextProps = Set.empty
141− , stCurId = 20
142− , stNextFigureNum = 1
143− , stNextTableNum = 1
144− }
145−
146−setFirstPara :: PandocMonad m => WS m ()
147−setFirstPara = modify $ \s -> s { stFirstPara = True }
148−
149−type WS m = ReaderT WriterEnv (StateT WriterState m)
150−
151−-- Word will insert these footnotes into the settings.xml file
152−-- (whether or not they're visible in the document). If they're in the
153−-- file, but not in the footnotes.xml file, it will produce
154−-- problems. So we want to make sure we insert them into our document.
155−defaultFootnotes :: [Element]
156−defaultFootnotes = [ mknode "w:footnote"
157− [("w:type", "separator"), ("w:id", "-1")]
158− [ mknode "w:p" []
159− [mknode "w:r" []
160− [ mknode "w:separator" [] ()]]]
161− , mknode "w:footnote"
162− [("w:type", "continuationSeparator"), ("w:id", "0")]
163− [ mknode "w:p" []
164− [ mknode "w:r" []
165− [ mknode "w:continuationSeparator" [] ()]]]]
166−
167−pStyleM :: (PandocMonad m) => ParaStyleName -> WS m XML.Element
168−pStyleM styleName = do
169− pStyleMap <- gets (smParaStyle . stStyleMaps)
170− let sty' = getStyleIdFromName styleName pStyleMap
171− return $ mknode "w:pStyle" [("w:val", fromStyleId sty')] ()
172−
173−withParaProp :: PandocMonad m => Element -> WS m a -> WS m a
174−withParaProp d p =
175− local (\env -> env {envParaProperties = ep <> envParaProperties env}) p
176− where ep = if isStyle d then EnvProps (Just d) [] else EnvProps Nothing [d]
177−
178−withParaPropM :: PandocMonad m => WS m Element -> WS m a -> WS m a
179−withParaPropM md p = do
180− d <- md
181− withParaProp d p
182−
183−isStyle :: Element -> Bool
184−isStyle e = isElem [] "w" "rStyle" e ||
185− isElem [] "w" "pStyle" e
src/Text/Pandoc/Writers/EPUB.hs+3−3
@@ -991,12 +991,12 @@ metadataElement version md currentTime =
991 showDateTimeISO8601 currentTime | version == EPUB3 ]
991 showDateTimeISO8601 currentTime | version == EPUB3 ]
992 belongsToCollectionNodes =
992 belongsToCollectionNodes =
993 maybe []
993 maybe []
994− (\belongsToCollection -> (unode "meta" ! [("property", "belongs-to-collection"), ("id", "epub-collection-1")] $ belongsToCollection )
994+ (\belongsToCollection -> (unode "meta" ! [("property", "belongs-to-collection"), ("id", "epub-id-1")] $ belongsToCollection )
995 :
995 :
996− [unode "meta" ! [("refines", "#epub-collection-1"), ("property", "collection-type")] $ ("series" :: Text) ])
996+ [unode "meta" ! [("refines", "#epub-id-1"), ("property", "collection-type")] $ ("series" :: Text) ])
997 (epubBelongsToCollection md)++
997 (epubBelongsToCollection md)++
998 maybe []
998 maybe []
999− (\groupPosition -> [unode "meta" ! [("refines", "#epub-collection-1"), ("property", "group-position")] $ groupPosition ])
999+ (\groupPosition -> [unode "meta" ! [("refines", "#epub-id-1"), ("property", "group-position")] $ groupPosition ])
1000 (epubGroupPosition md)
1000 (epubGroupPosition md)
1001 dcTag n s = unode ("dc:" <> n) s
1001 dcTag n s = unode ("dc:" <> n) s
1002 dcTag' n s = [dcTag n s]
1002 dcTag' n s = [dcTag n s]
src/Text/Pandoc/Writers/GridTable.hsdeleted−157
@@ -1,157 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE LambdaCase #-}
4−{-# LANGUAGE TupleSections #-}
5−
6−{- |
7−Module : Text.Pandoc.Writers.GridTable
8−Copyright : © 2020-2021 Albert Krewinkel
9−License : GNU GPL, version 2 or above
10−
11−Maintainer : Albert Krewinkel <albert@zeitkraut.de>
12−
13−Grid representation of pandoc tables.
14−-}
15−module Text.Pandoc.Writers.GridTable
16− ( Table (..)
17− , GridCell (..)
18− , RowIndex (..)
19− , ColIndex (..)
20− , CellIndex
21− , Part (..)
22− , toTable
23− , rowArray
24− ) where
25−
26−import Control.Monad (forM_)
27−import Control.Monad.ST
28−import Data.Array
29−import Data.Array.MArray
30−import Data.Array.ST
31−import Data.Maybe (listToMaybe)
32−import Data.STRef
33−import Text.Pandoc.Definition hiding (Table)
34−import qualified Text.Pandoc.Builder as B
35−
36−-- | A grid cell contains either a real table cell, or is the
37−-- continuation of a column or row-spanning cell. In the latter case,
38−-- the index of the continued cell is provided.
39−data GridCell
40− = ContentCell Attr Alignment RowSpan ColSpan [Block]
41− | ContinuationCell CellIndex
42− deriving (Show)
43−
44−-- | Row index in a table part.
45−newtype RowIndex = RowIndex Int deriving (Enum, Eq, Ix, Ord, Show)
46−-- | Column index in a table part.
47−newtype ColIndex = ColIndex Int deriving (Enum, Eq, Ix, Ord, Show)
48−
49−-- | Index to a cell in a table part.
50−type CellIndex = (RowIndex, ColIndex)
51−
52−-- | Cells are placed on a grid. Row attributes are stored in a separate
53−-- array.
54−data Part = Part
55− { partAttr :: Attr
56− , partCellArray :: Array (RowIndex,ColIndex) GridCell
57− , partRowAttrs :: Array RowIndex Attr
58− }
59−
60−data Table = Table
61− { tableAttr :: Attr
62− , tableCaption :: Caption
63− , tableColSpecs :: Array ColIndex ColSpec
64− , tableRowHeads :: RowHeadColumns
65− , tableHead :: Part
66− , tableBodies :: [Part]
67− , tableFoot :: Part
68− }
69−
70−toTable
71− :: B.Attr
72− -> B.Caption
73− -> [B.ColSpec]
74− -> B.TableHead
75− -> [B.TableBody]
76− -> B.TableFoot
77− -> Table
78−toTable attr caption colSpecs thead tbodies tfoot =
79− Table attr caption colSpecs' rowHeads thGrid tbGrids tfGrid
80− where
81− colSpecs' = listArray (ColIndex 1, ColIndex $ length colSpecs) colSpecs
82− rowHeads = case listToMaybe tbodies of
83− Nothing -> RowHeadColumns 0
84− Just (TableBody _attr rowHeadCols _headerRows _rows) -> rowHeadCols
85− thGrid = let (TableHead headAttr rows) = thead
86− in rowsToPart headAttr rows
87− tbGrids = map bodyToGrid tbodies
88− tfGrid = let (TableFoot footAttr rows) = tfoot
89− in rowsToPart footAttr rows
90− bodyToGrid (TableBody bodyAttr _rowHeadCols headRows rows) =
91− rowsToPart bodyAttr (headRows ++ rows)
92−
93−data BuilderCell
94− = FilledCell GridCell
95− | FreeCell
96−
97−fromBuilderCell :: BuilderCell -> GridCell
98−fromBuilderCell = \case
99− FilledCell c -> c
100− FreeCell -> error "Found an unassigned cell."
101−
102−rowsToPart :: Attr -> [B.Row] -> Part
103−rowsToPart attr = \case
104− [] -> Part
105− attr
106− (listArray ((RowIndex 1, ColIndex 1), (RowIndex 0, ColIndex 0)) [])
107− (listArray (RowIndex 1, RowIndex 0) [])
108− rows@(Row _attr firstRow:_) ->
109− let nrows = length rows
110− ncols = sum $ map (\(Cell _ _ _ (ColSpan cs) _) -> cs) firstRow
111− gbounds = ((RowIndex 1, ColIndex 1), (RowIndex nrows, ColIndex ncols))
112− mutableGrid :: ST s (STArray s CellIndex GridCell)
113− mutableGrid = do
114− grid <- newArray gbounds FreeCell
115− ridx <- newSTRef (RowIndex 1)
116− forM_ rows $ \(Row _attr cells) -> do
117− cidx <- newSTRef (ColIndex 1)
118− forM_ cells $ \(Cell cellAttr align rs cs blks) -> do
119− ridx' <- readSTRef ridx
120− let nextFreeInRow colindex@(ColIndex c) = do
121− readArray grid (ridx', colindex) >>= \case
122− FreeCell -> pure colindex
123− _ -> nextFreeInRow $ ColIndex (c + 1)
124− cidx' <- readSTRef cidx >>= nextFreeInRow
125− writeArray grid (ridx', cidx') . FilledCell $
126− ContentCell cellAttr align rs cs blks
127− forM_ (continuationIndices ridx' cidx' rs cs) $ \idx -> do
128− writeArray grid idx . FilledCell $
129− ContinuationCell (ridx', cidx')
130− -- go to new column
131− writeSTRef cidx cidx'
132− -- go to next row
133− modifySTRef ridx (incrRowIndex 1)
134− -- Swap BuilderCells with normal GridCells.
135− mapArray fromBuilderCell grid
136− in Part
137− { partCellArray = runSTArray mutableGrid
138− , partRowAttrs = listArray (RowIndex 1, RowIndex nrows) $
139− map (\(Row rowAttr _) -> rowAttr) rows
140− , partAttr = attr
141− }
142−
143−continuationIndices :: RowIndex -> ColIndex -> RowSpan -> ColSpan -> [CellIndex]
144−continuationIndices (RowIndex ridx) (ColIndex cidx) rowspan colspan =
145− let (RowSpan rs) = rowspan
146− (ColSpan cs) = colspan
147− in [ (RowIndex r, ColIndex c) | r <- [ridx..(ridx + rs - 1)]
148− , c <- [cidx..(cidx + cs - 1)]
149− , (r, c) /= (ridx, cidx)]
150−
151−rowArray :: RowIndex -> Array CellIndex GridCell -> Array ColIndex GridCell
152−rowArray ridx grid =
153− let ((_minRidx, minCidx), (_maxRidx, maxCidx)) = bounds grid
154− in ixmap (minCidx, maxCidx) (ridx,) grid
155−
156−incrRowIndex :: RowSpan -> RowIndex -> RowIndex
157−incrRowIndex (RowSpan n) (RowIndex r) = RowIndex $ r + n
src/Text/Pandoc/Writers/HTML.hs+12−80
@@ -26,13 +26,8 @@ module Text.Pandoc.Writers.HTML (
26 writeSlideous,
26 writeSlideous,
27 writeDZSlides,
27 writeDZSlides,
28 writeRevealJs,
28 writeRevealJs,
29− tagWithAttributes,
29+ tagWithAttributes
30− inlineToHtml,
31− blockToHtml,
32− WriterState(..),
33− defaultWriterState
34 ) where
30 ) where
35−
36import Control.Monad.State.Strict
31import Control.Monad.State.Strict
37import Data.Char (ord)
32import Data.Char (ord)
38import Data.List (intercalate, intersperse, partition, delete, (\\), foldl')
33import Data.List (intercalate, intersperse, partition, delete, (\\), foldl')
@@ -349,52 +344,6 @@ pandocToHtml opts (Pandoc meta blocks) = do
349 PlainMath -> defField "displaymath-css" True
344 PlainMath -> defField "displaymath-css" True
350 WebTeX _ -> defField "displaymath-css" True
345 WebTeX _ -> defField "displaymath-css" True
351 _ -> id) .
346 _ -> id) .
352− (if slideVariant == RevealJsSlides
353− then -- set boolean options explicitly, since
354− -- template can't distinguish False/undefined
355− defField "controls" True .
356− defField "controlsTutorial" True .
357− defField "controlsLayout" ("bottom-right" :: Text) .
358− defField "controlsBackArrows" ("faded" :: Text) .
359− defField "progress" True .
360− defField "slideNumber" False .
361− defField "showSlideNumber" ("all" :: Text) .
362− defField "hashOneBasedIndex" False .
363− defField "hash" False .
364− defField "respondToHashChanges" True .
365− defField "history" False .
366− defField "keyboard" True .
367− defField "overview" True .
368− defField "disableLayout" False .
369− defField "center" True .
370− defField "touch" True .
371− defField "loop" False .
372− defField "rtl" False .
373− defField "navigationMode" ("default" :: Text) .
374− defField "shuffle" False .
375− defField "fragments" True .
376− defField "fragmentInURL" True .
377− defField "embedded" False .
378− defField "help" True .
379− defField "pause" True .
380− defField "showNotes" False .
381− defField "autoPlayMedia" ("null" :: Text) .
382− defField "preloadIframes" ("null" :: Text) .
383− defField "autoSlide" ("0" :: Text) .
384− defField "autoSlideStoppable" True .
385− defField "autoSlideMethod" ("null" :: Text) .
386− defField "defaultTiming" ("null" :: Text) .
387− defField "mouseWheel" False .
388− defField "display" ("block" :: Text) .
389− defField "hideInactiveCursor" True .
390− defField "hideCursorTime" ("5000" :: Text) .
391− defField "previewLinks" False .
392− defField "transition" ("slide" :: Text) .
393− defField "transitionSpeed" ("default" :: Text) .
394− defField "backgroundTransition" ("fade" :: Text) .
395− defField "viewDistance" ("3" :: Text) .
396− defField "mobileViewDistance" ("2" :: Text)
397− else id) .
398 defField "document-css" (isNothing mCss && slideVariant == NoSlides) .
347 defField "document-css" (isNothing mCss && slideVariant == NoSlides) .
399 defField "quotes" (stQuotes st) .
348 defField "quotes" (stQuotes st) .
400 -- for backwards compatibility we populate toc
349 -- for backwards compatibility we populate toc
@@ -664,20 +613,17 @@ dimensionsToAttrList attr = consolidateStyles $ go Width ++ go Height
664figure :: PandocMonad m
613figure :: PandocMonad m
665 => WriterOptions -> Attr -> [Inline] -> (Text, Text)
614 => WriterOptions -> Attr -> [Inline] -> (Text, Text)
666 -> StateT WriterState m Html
615 -> StateT WriterState m Html
667−figure opts attr@(_, _, attrList) txt (s,tit) = do
616+figure opts attr txt (s,tit) = do
668 html5 <- gets stHtml5
617 html5 <- gets stHtml5
669 -- Screen-readers will normally read the @alt@ text and the figure; we
618 -- Screen-readers will normally read the @alt@ text and the figure; we
670 -- want to avoid them reading the same text twice. With HTML5 we can
619 -- want to avoid them reading the same text twice. With HTML5 we can
671 -- use aria-hidden for the caption; with HTML4, we use an empty
620 -- use aria-hidden for the caption; with HTML4, we use an empty
672 -- alt-text instead.
621 -- alt-text instead.
673− -- When the alt text differs from the caption both should be read.
674 let alt = if html5 then txt else [Str ""]
622 let alt = if html5 then txt else [Str ""]
675 let tocapt = if html5
623 let tocapt = if html5
676− then (H5.figcaption !) $
624+ then H5.figcaption !
677− if isJust (lookup "alt" attrList)
678− then mempty
679− else H5.customAttribute (textTag "aria-hidden")
625+ H5.customAttribute (textTag "aria-hidden")
680− (toValue @Text "true")
626+ (toValue @Text "true")
681 else H.p ! A.class_ "caption"
627 else H.p ! A.class_ "caption"
682 img <- inlineToHtml opts (Image attr alt (s,tit))
628 img <- inlineToHtml opts (Image attr alt (s,tit))
683 capt <- if null txt
629 capt <- if null txt
@@ -824,10 +770,9 @@ blockToHtml opts (Div attr@(ident, classes, kvs') bs) = do
824 lookup "entry-spacing" kvs' >>=
770 lookup "entry-spacing" kvs' >>=
825 safeRead }
771 safeRead }
826 let isCslBibEntry = "csl-entry" `elem` classes
772 let isCslBibEntry = "csl-entry" `elem` classes
827− let kvs = [(k,v) | (k,v) <- kvs'
773+ let kvs = [(k,v) | (k,v) <- kvs', k /= "width"] ++
828− , k /= "width" || "column" `notElem` classes] ++
829− [("style", "width:" <> w <> ";") | "column" `elem` classes
774+ [("style", "width:" <> w <> ";") | "column" `elem` classes,
830− , ("width", w) <- kvs'] ++
775+ ("width", w) <- kvs'] ++
831 [("role", "doc-bibliography") | isCslBibBody && html5] ++
776 [("role", "doc-bibliography") | isCslBibBody && html5] ++
832 [("role", "doc-biblioentry") | isCslBibEntry && html5]
777 [("role", "doc-biblioentry") | isCslBibEntry && html5]
833 let speakerNotes = "notes" `elem` classes
778 let speakerNotes = "notes" `elem` classes
@@ -937,7 +882,7 @@ blockToHtml opts (BlockQuote blocks) = do
937 else do
882 else do
938 contents <- blockListToHtml opts blocks
883 contents <- blockListToHtml opts blocks
939 return $ H.blockquote $ nl opts >> contents >> nl opts
884 return $ H.blockquote $ nl opts >> contents >> nl opts
940−blockToHtml opts (Header level (ident,classes,kvs) lst) = do
885+blockToHtml opts (Header level attr@(_,classes,kvs) lst) = do
941 contents <- inlineListToHtml opts lst
886 contents <- inlineListToHtml opts lst
942 let secnum = fromMaybe mempty $ lookup "number" kvs
887 let secnum = fromMaybe mempty $ lookup "number" kvs
943 let contents' = if writerNumberSections opts && not (T.null secnum)
888 let contents' = if writerNumberSections opts && not (T.null secnum)
@@ -945,13 +890,7 @@ blockToHtml opts (Header level (ident,classes,kvs) lst) = do
945 then (H.span ! A.class_ "header-section-number"
890 then (H.span ! A.class_ "header-section-number"
946 $ toHtml secnum) >> strToHtml " " >> contents
891 $ toHtml secnum) >> strToHtml " " >> contents
947 else contents
892 else contents
948− html5 <- gets stHtml5
949− let kvs' = if html5
950− then kvs
951− else [ (k, v) | (k, v) <- kvs
952− , k `elem` (["lang", "dir", "title", "style"
953− , "align"] ++ intrinsicEventsHTML4)]
954− addAttrs opts (ident,classes,kvs')
893+ addAttrs opts attr
955 $ case level of
894 $ case level of
956 1 -> H.h1 contents'
895 1 -> H.h1 contents'
957 2 -> H.h2 contents'
896 2 -> H.h2 contents'
@@ -1441,7 +1380,7 @@ inlineToHtml opts inline = do
1441 return $ if T.null tit
1380 return $ if T.null tit
1442 then link'
1381 then link'
1443 else link' ! A.title (toValue tit)
1382 else link' ! A.title (toValue tit)
1444− (Image attr@(_, _, attrList) txt (s, tit)) -> do
1383+ (Image attr txt (s,tit)) -> do
1445 let alternate = stringify txt
1384 let alternate = stringify txt
1446 slideVariant <- gets stSlideVariant
1385 slideVariant <- gets stSlideVariant
1447 let isReveal = slideVariant == RevealJsSlides
1386 let isReveal = slideVariant == RevealJsSlides
@@ -1454,8 +1393,7 @@ inlineToHtml opts inline = do
1454 [A.title $ toValue tit | not (T.null tit)] ++
1393 [A.title $ toValue tit | not (T.null tit)] ++
1455 attrs
1394 attrs
1456 imageTag = (if html5 then H5.img else H.img
1395 imageTag = (if html5 then H5.img else H.img
1457− , [A.alt $ toValue alternate | not (null txt) &&
1396+ , [A.alt $ toValue alternate | not (null txt)] )
1458− isNothing (lookup "alt" attrList)] )
1459 mediaTag tg fallbackTxt =
1397 mediaTag tg fallbackTxt =
1460 let linkTxt = if null txt
1398 let linkTxt = if null txt
1461 then fallbackTxt
1399 then fallbackTxt
@@ -1588,12 +1526,6 @@ allowsMathEnvironments MathML = True
1588allowsMathEnvironments (WebTeX _) = True
1526allowsMathEnvironments (WebTeX _) = True
1589allowsMathEnvironments _ = False
1527allowsMathEnvironments _ = False
1590
1528
1591−-- | List of intrinsic event attributes allowed on all elements in HTML4.
1592−intrinsicEventsHTML4 :: [Text]
1593−intrinsicEventsHTML4 =
1594− [ "onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover"
1595− , "onmouseout", "onmouseout", "onkeypress", "onkeydown", "onkeyup"]
1596−
1597isRawHtml :: PandocMonad m => Format -> StateT WriterState m Bool
1529isRawHtml :: PandocMonad m => Format -> StateT WriterState m Bool
1598isRawHtml f = do
1530isRawHtml f = do
1599 html5 <- gets stHtml5
1531 html5 <- gets stHtml5
src/Text/Pandoc/Writers/JATS.hs+31−51
@@ -1,7 +1,6 @@
1−{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE ScopedTypeVariables #-}
1{-# LANGUAGE ScopedTypeVariables #-}
2+{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE ViewPatterns #-}
3+{-# LANGUAGE ViewPatterns #-}
5{- |
4{- |
6 Module : Text.Pandoc.Writers.JATS
5 Module : Text.Pandoc.Writers.JATS
7 Copyright : 2017-2021 John MacFarlane
6 Copyright : 2017-2021 John MacFarlane
@@ -21,13 +20,12 @@ module Text.Pandoc.Writers.JATS
21 , writeJatsPublishing
20 , writeJatsPublishing
22 , writeJatsArticleAuthoring
21 , writeJatsArticleAuthoring
23 ) where
22 ) where
24−import Control.Applicative ((<|>))
25import Control.Monad.Reader
23import Control.Monad.Reader
26import Control.Monad.State
24import Control.Monad.State
27import Data.Generics (everywhere, mkT)
25import Data.Generics (everywhere, mkT)
28import Data.List (partition)
26import Data.List (partition)
29import qualified Data.Map as M
27import qualified Data.Map as M
30−import Data.Maybe (fromMaybe, listToMaybe)
28+import Data.Maybe (fromMaybe)
31import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
29import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
32import qualified Data.Text as T
30import qualified Data.Text as T
33import Data.Text (Text)
31import Data.Text (Text)
@@ -82,7 +80,7 @@ writeJats tagSet opts d = do
82 let environment = JATSEnv
80 let environment = JATSEnv
83 { jatsTagSet = tagSet
81 { jatsTagSet = tagSet
84 , jatsInlinesWriter = inlinesToJATS
82 , jatsInlinesWriter = inlinesToJATS
85− , jatsBlockWriter = wrappedBlocksToJATS
83+ , jatsBlockWriter = blockToJATS
86 , jatsReferences = refs
84 , jatsReferences = refs
87 }
85 }
88 let initialState = JATSState { jatsNotes = [] }
86 let initialState = JATSState { jatsNotes = [] }
@@ -164,9 +162,11 @@ wrappedBlocksToJATS needsWrap opts =
164 wrappedBlockToJATS b = do
162 wrappedBlockToJATS b = do
165 inner <- blockToJATS opts b
163 inner <- blockToJATS opts b
166 return $
164 return $
167− if needsWrap b
165+ if needsWrap b || isBlockQuote b -- see #7041
168 then inTags True "p" [("specific-use","wrapper")] inner
166 then inTags True "p" [("specific-use","wrapper")] inner
169 else inner
167 else inner
168+ isBlockQuote (BlockQuote _) = True
169+ isBlockQuote _ = False
170
170
171-- | Auxiliary function to convert Plain block to Para.
171-- | Auxiliary function to convert Plain block to Para.
172plainToPara :: Block -> Block
172plainToPara :: Block -> Block
@@ -225,21 +225,19 @@ imageMimeType src kvs =
225 (T.drop 1 . T.dropWhile (/='/') <$> mbMT)
225 (T.drop 1 . T.dropWhile (/='/') <$> mbMT)
226 in (maintype, subtype)
226 in (maintype, subtype)
227
227
228−languageFor :: WriterOptions -> [Text] -> Text
228+languageFor :: [Text] -> Text
229−languageFor opts classes =
229+languageFor classes =
230 case langs of
230 case langs of
231 (l:_) -> escapeStringForXML l
231 (l:_) -> escapeStringForXML l
232 [] -> ""
232 [] -> ""
233− where
234− syntaxMap = writerSyntaxMap opts
235− isLang l = T.toLower l `elem` map T.toLower (languages syntaxMap)
233+ where isLang l = T.toLower l `elem` map T.toLower languages
236 langsFrom s = if isLang s
234 langsFrom s = if isLang s
237 then [s]
235 then [s]
238− else (languagesByExtension syntaxMap) . T.toLower $ s
236+ else languagesByExtension . T.toLower $ s
239 langs = concatMap langsFrom classes
237 langs = concatMap langsFrom classes
240
238
241−codeAttr :: WriterOptions -> Attr -> (Text, [(Text, Text)])
239+codeAttr :: Attr -> (Text, [(Text, Text)])
242−codeAttr opts (ident,classes,kvs) = (lang, attr)
240+codeAttr (ident,classes,kvs) = (lang, attr)
243 where
241 where
244 attr = [("id", escapeNCName ident) | not (T.null ident)] ++
242 attr = [("id", escapeNCName ident) | not (T.null ident)] ++
245 [("language",lang) | not (T.null lang)] ++
243 [("language",lang) | not (T.null lang)] ++
@@ -247,7 +245,7 @@ codeAttr opts (ident,classes,kvs) = (lang, attr)
247 "code-version", "executable",
245 "code-version", "executable",
248 "language-version", "orientation",
246 "language-version", "orientation",
249 "platforms", "position", "specific-use"]]
247 "platforms", "position", "specific-use"]]
250− lang = languageFor opts classes
248+ lang = languageFor classes
251
249
252-- | Convert a Pandoc block element to JATS.
250-- | Convert a Pandoc block element to JATS.
253blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m (Doc Text)
251blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m (Doc Text)
@@ -326,16 +324,13 @@ blockToJATS opts (LineBlock lns) =
326 blockToJATS opts $ linesToPara lns
324 blockToJATS opts $ linesToPara lns
327blockToJATS opts (BlockQuote blocks) = do
325blockToJATS opts (BlockQuote blocks) = do
328 tagSet <- asks jatsTagSet
326 tagSet <- asks jatsTagSet
329− let needsWrap = if tagSet == TagSetArticleAuthoring
327+ let blocksToJats' = if tagSet == TagSetArticleAuthoring
330− then not . isPara
328+ then wrappedBlocksToJATS (not . isPara)
331− else \case
329+ else blocksToJATS
332− Header{} -> True
333− HorizontalRule -> True
334− _ -> False
335− inTagsIndented "disp-quote" <$> wrappedBlocksToJATS needsWrap opts blocks
330+ inTagsIndented "disp-quote" <$> blocksToJats' opts blocks
336−blockToJATS opts (CodeBlock a str) = return $
331+blockToJATS _ (CodeBlock a str) = return $
337 inTags False tag attr (flush (text (T.unpack $ escapeStringForXML str)))
332 inTags False tag attr (flush (text (T.unpack $ escapeStringForXML str)))
338− where (lang, attr) = codeAttr opts a
333+ where (lang, attr) = codeAttr a
339 tag = if T.null lang then "preformat" else "code"
334 tag = if T.null lang then "preformat" else "code"
340blockToJATS _ (BulletList []) = return empty
335blockToJATS _ (BulletList []) = return empty
341blockToJATS opts (BulletList lst) =
336blockToJATS opts (BulletList lst) =
@@ -415,9 +410,9 @@ inlineToJATS opts (Quoted SingleQuote lst) = do
415inlineToJATS opts (Quoted DoubleQuote lst) = do
410inlineToJATS opts (Quoted DoubleQuote lst) = do
416 contents <- inlinesToJATS opts lst
411 contents <- inlinesToJATS opts lst
417 return $ char '“' <> contents <> char '”'
412 return $ char '“' <> contents <> char '”'
418−inlineToJATS opts (Code a str) =
413+inlineToJATS _ (Code a str) =
419 return $ inTags False tag attr $ literal (escapeStringForXML str)
414 return $ inTags False tag attr $ literal (escapeStringForXML str)
420− where (lang, attr) = codeAttr opts a
415+ where (lang, attr) = codeAttr a
421 tag = if T.null lang then "monospace" else "code"
416 tag = if T.null lang then "monospace" else "code"
422inlineToJATS _ il@(RawInline f x)
417inlineToJATS _ il@(RawInline f x)
423 | f == "jats" = return $ literal x
418 | f == "jats" = return $ literal x
@@ -450,33 +445,18 @@ inlineToJATS opts (Note contents) = do
450 $ text (show notenum)
445 $ text (show notenum)
451inlineToJATS opts (Cite _ lst) =
446inlineToJATS opts (Cite _ lst) =
452 inlinesToJATS opts lst
447 inlinesToJATS opts lst
453−inlineToJATS opts (Span (ident,classes,kvs) ils) = do
448+inlineToJATS opts (Span (ident,_,kvs) ils) = do
454 contents <- inlinesToJATS opts ils
449 contents <- inlinesToJATS opts ils
455− let commonAttr = [("id", escapeNCName ident) | not (T.null ident)] ++
450+ let attr = [("id", escapeNCName ident) | not (T.null ident)] ++
456− [("xml:lang",l) | ("lang",l) <- kvs] ++
451+ [("xml:lang",l) | ("lang",l) <- kvs] ++
452+ [(k,v) | (k,v) <- kvs
457− [(k,v) | (k,v) <- kvs, k `elem` ["alt", "specific-use"]]
453+ , k `elem` ["alt", "content-type", "rid", "specific-use",
458− -- A named-content element is a good fit for spans, but requires a
459− -- content-type attribute to be present. We use either the explicit
460− -- attribute or the first class as content type. If neither is
461− -- available, then we fall back to using a @styled-content@ element.
462− let (tag, specificAttr) =
463− case lookup "content-type" kvs <|> listToMaybe classes of
464− Just ct -> ( "named-content"
465− , ("content-type", ct) :
466− [(k, v) | (k, v) <- kvs
467− , k `elem` ["rid", "vocab", "vocab-identifier",
454+ "vocab", "vocab-identifier", "vocab-term",
468− "vocab-term", "vocab-term-identifier"]])
455+ "vocab-term-identifier"]]
469− -- Fall back to styled-content
470− Nothing -> ("styled-content"
471− , [(k, v) | (k,v) <- kvs
472− , k `elem` ["style", "style-type", "style-detail",
473− "toggle"]])
474− let attr = commonAttr ++ specificAttr
475− -- unwrap if wrapping element would have no attributes
476 return $
456 return $
477 if null attr
457 if null attr
478− then contents
458+ then contents -- unwrap if no relevant attributes are given
479− else inTags False tag attr contents
459+ else inTags False "named-content" attr contents
480inlineToJATS _ (Math t str) = do
460inlineToJATS _ (Math t str) = do
481 let addPref (Xml.Attr q v)
461 let addPref (Xml.Attr q v)
482 | Xml.qName q == "xmlns" = Xml.Attr q{ Xml.qName = "xmlns:mml" } v
462 | Xml.qName q == "xmlns" = Xml.Attr q{ Xml.qName = "xmlns:mml" } v
src/Text/Pandoc/Writers/JATS/Table.hs+3−23
@@ -34,19 +34,13 @@ tableToJATS :: PandocMonad m
34 -> JATS m (Doc Text)
34 -> JATS m (Doc Text)
35tableToJATS opts (Ann.Table attr caption colspecs thead tbodies tfoot) = do
35tableToJATS opts (Ann.Table attr caption colspecs thead tbodies tfoot) = do
36 let (Caption _maybeShortCaption captionBlocks) = caption
36 let (Caption _maybeShortCaption captionBlocks) = caption
37− -- Only paragraphs are allowed in captions, all other blocks must be
38− -- wrapped in @<p>@ elements.
39− let needsWrapping = \case
40− Plain{} -> False
41− Para{} -> False
42− _ -> True
43 tbl <- captionlessTable opts attr colspecs thead tbodies tfoot
37 tbl <- captionlessTable opts attr colspecs thead tbodies tfoot
44 captionDoc <- if null captionBlocks
38 captionDoc <- if null captionBlocks
45 then return empty
39 then return empty
46 else do
40 else do
47 blockToJATS <- asks jatsBlockWriter
41 blockToJATS <- asks jatsBlockWriter
48− inTagsIndented "caption" <$>
42+ inTagsIndented "caption" . vcat <$>
49− blockToJATS needsWrapping opts captionBlocks
43+ mapM (blockToJATS opts) captionBlocks
50 return $ inTags True "table-wrap" [] $ captionDoc $$ tbl
44 return $ inTags True "table-wrap" [] $ captionDoc $$ tbl
51
45
52captionlessTable :: PandocMonad m
46captionlessTable :: PandocMonad m
@@ -236,7 +230,7 @@ tableCellToJats opts ctype colAlign (Cell attr align rowspan colspan item) = do
236 inlinesToJats <- asks jatsInlinesWriter
230 inlinesToJats <- asks jatsInlinesWriter
237 let cellContents = \case
231 let cellContents = \case
238 [Plain inlines] -> inlinesToJats opts inlines
232 [Plain inlines] -> inlinesToJats opts inlines
239− blocks -> blockToJats needsWrapInCell opts blocks
233+ blocks -> vcat <$> mapM (blockToJats opts) blocks
240 let tag' = case ctype of
234 let tag' = case ctype of
241 BodyCell -> "td"
235 BodyCell -> "td"
242 HeaderCell -> "th"
236 HeaderCell -> "th"
@@ -252,17 +246,3 @@ tableCellToJats opts ctype colAlign (Cell attr align rowspan colspan item) = do
252 . maybeCons (colspanAttrib colspan)
246 . maybeCons (colspanAttrib colspan)
253 $ toAttribs attr validAttribs
247 $ toAttribs attr validAttribs
254 inTags False tag' attribs <$> cellContents item
248 inTags False tag' attribs <$> cellContents item
255−
256−-- | Whether the JATS produced from this block should be wrapped in a
257−-- @<p>@ element when put directly below a @<td>@ element.
258−needsWrapInCell :: Block -> Bool
259−needsWrapInCell = \case
260− Plain{} -> False -- should be unwrapped anyway
261− Para{} -> False
262− BulletList{} -> False
263− OrderedList{} -> False
264− DefinitionList{} -> False
265− HorizontalRule -> False
266− CodeBlock{} -> False
267− RawBlock{} -> False -- responsibility of the user
268− _ -> True
src/Text/Pandoc/Writers/JATS/Types.hs+3−12
@@ -37,20 +37,11 @@ newtype JATSState = JATSState
37 { jatsNotes :: [(Int, Doc Text)]
37 { jatsNotes :: [(Int, Doc Text)]
38 }
38 }
39
39
40−-- | Environment containing all information relevant for rendering.
41data JATSEnv m = JATSEnv
40data JATSEnv m = JATSEnv
42− { jatsTagSet :: JATSTagSet -- ^ The tag set that's being ouput
41+ { jatsTagSet :: JATSTagSet
43−
44− , jatsBlockWriter :: (Block -> Bool)
45− -> WriterOptions -> [Block] -> JATS m (Doc Text)
46− -- ^ Converts a block list to JATS, wrapping top-level blocks into a
47− -- @<p>@ element if the property evaluates to @True@.
48− -- See #7227.
49−
50 , jatsInlinesWriter :: WriterOptions -> [Inline] -> JATS m (Doc Text)
42 , jatsInlinesWriter :: WriterOptions -> [Inline] -> JATS m (Doc Text)
51− -- ^ Converts an inline list to JATS.
43+ , jatsBlockWriter :: WriterOptions -> Block -> JATS m (Doc Text)
52−
53− , jatsReferences :: [Reference Inlines] -- ^ List of references
44+ , jatsReferences :: [Reference Inlines]
54 }
45 }
55
46
56-- | JATS writer type
47-- | JATS writer type
src/Text/Pandoc/Writers/Jira.hs+3−9
@@ -280,8 +280,6 @@ toJiraLink (_, classes, _) (url, _) alias = do
280 | Just email <- T.stripPrefix "mailto:" url' = (Jira.Email, email)
280 | Just email <- T.stripPrefix "mailto:" url' = (Jira.Email, email)
281 | "user-account" `elem` classes = (Jira.User, dropTilde url)
281 | "user-account" `elem` classes = (Jira.User, dropTilde url)
282 | "attachment" `elem` classes = (Jira.Attachment, url)
282 | "attachment" `elem` classes = (Jira.Attachment, url)
283− | "smart-card" `elem` classes = (Jira.SmartCard, url)
284− | "smart-link" `elem` classes = (Jira.SmartLink, url)
285 | otherwise = (Jira.External, url)
283 | otherwise = (Jira.External, url)
286 dropTilde txt = case T.uncons txt of
284 dropTilde txt = case T.uncons txt of
287 Just ('~', username) -> username
285 Just ('~', username) -> username
@@ -311,13 +309,9 @@ quotedToJira qtype xs = do
311spanToJira :: PandocMonad m
309spanToJira :: PandocMonad m
312 => Attr -> [Inline]
310 => Attr -> [Inline]
313 -> JiraConverter m [Jira.Inline]
311 -> JiraConverter m [Jira.Inline]
314−spanToJira (ident, _classes, attribs) inls =
312+spanToJira (ident, _classes, _attribs) inls = case ident of
315− let wrap = case lookup "color" attribs of
316− Nothing -> id
317− Just color -> singleton . Jira.ColorInline (Jira.ColorName color)
318− in wrap <$> case ident of
319− "" -> toJiraInlines inls
313+ "" -> toJiraInlines inls
320− _ -> (Jira.Anchor ident :) <$> toJiraInlines inls
314+ _ -> (Jira.Anchor ident :) <$> toJiraInlines inls
321
315
322registerNotes :: PandocMonad m => [Block] -> JiraConverter m [Jira.Inline]
316registerNotes :: PandocMonad m => [Block] -> JiraConverter m [Jira.Inline]
323registerNotes contents = do
317registerNotes contents = do
src/Text/Pandoc/Writers/LaTeX.hs+9−14
@@ -29,7 +29,7 @@ import qualified Data.Text as T
29import Network.URI (unEscapeString)
29import Network.URI (unEscapeString)
30import Text.DocTemplates (FromContext(lookupContext), renderTemplate,
30import Text.DocTemplates (FromContext(lookupContext), renderTemplate,
31 Val(..), Context(..))
31 Val(..), Context(..))
32−import Text.Collate.Lang (Lang (..), renderLang)
32+import Text.Pandoc.BCP47 (Lang (..), getLang, renderLang)
33import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
33import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
34import Text.Pandoc.Definition
34import Text.Pandoc.Definition
35import Text.Pandoc.Highlighting (formatLaTeXBlock, formatLaTeXInline, highlight,
35import Text.Pandoc.Highlighting (formatLaTeXBlock, formatLaTeXInline, highlight,
@@ -173,7 +173,6 @@ pandocToLaTeX options (Pandoc meta blocks) = do
173 defField "has-chapters" (stHasChapters st) $
173 defField "has-chapters" (stHasChapters st) $
174 defField "has-frontmatter" (documentClass `elem` frontmatterClasses) $
174 defField "has-frontmatter" (documentClass `elem` frontmatterClasses) $
175 defField "listings" (writerListings options || stLHS st) $
175 defField "listings" (writerListings options || stLHS st) $
176− defField "zero-width-non-joiner" (stZwnj st) $
177 defField "beamer" beamer $
176 defField "beamer" beamer $
178 (if stHighlighting st
177 (if stHighlighting st
179 then case writerHighlightStyle options of
178 then case writerHighlightStyle options of
@@ -291,12 +290,7 @@ blockToLaTeX :: PandocMonad m
291 => Block -- ^ Block to convert
290 => Block -- ^ Block to convert
292 -> LW m (Doc Text)
291 -> LW m (Doc Text)
293blockToLaTeX Null = return empty
292blockToLaTeX Null = return empty
294−blockToLaTeX (Div attr@(identifier,"block":dclasses,_)
293+blockToLaTeX (Div attr@(identifier,"block":_,_) (Header _ _ ils : bs)) = do
295− (Header _ _ ils : bs)) = do
296− let blockname
297− | "example" `elem` dclasses = "exampleblock"
298− | "alert" `elem` dclasses = "alertblock"
299− | otherwise = "block"
300 ref <- toLabel identifier
294 ref <- toLabel identifier
301 let anchor = if T.null identifier
295 let anchor = if T.null identifier
302 then empty
296 then empty
@@ -304,8 +298,8 @@ blockToLaTeX (Div attr@(identifier,"block":dclasses,_)
304 braces (literal ref) <> braces empty
298 braces (literal ref) <> braces empty
305 title' <- inlineListToLaTeX ils
299 title' <- inlineListToLaTeX ils
306 contents <- blockListToLaTeX bs
300 contents <- blockListToLaTeX bs
307− wrapDiv attr $ ("\\begin" <> braces blockname <> braces title' <> anchor) $$
301+ wrapDiv attr $ ("\\begin{block}" <> braces title' <> anchor) $$
308− contents $$ "\\end" <> braces blockname
302+ contents $$ "\\end{block}"
309blockToLaTeX (Div (identifier,"slide":dclasses,dkvs)
303blockToLaTeX (Div (identifier,"slide":dclasses,dkvs)
310 (Header _ (_,hclasses,hkvs) ils : bs)) = do
304 (Header _ (_,hclasses,hkvs) ils : bs)) = do
311 -- note: [fragile] is required or verbatim breaks
305 -- note: [fragile] is required or verbatim breaks
@@ -894,9 +888,8 @@ inlineToLaTeX (Quoted qt lst) = do
894 then char '`' <> inner <> char '\''
888 then char '`' <> inner <> char '\''
895 else char '\x2018' <> inner <> char '\x2019'
889 else char '\x2018' <> inner <> char '\x2019'
896 where
890 where
897− isQuoted (Span _ (x:_)) = isQuoted x
898− isQuoted (Quoted _ _) = True
891+ isQuoted (Quoted _ _) = True
899− isQuoted _ = False
892+ isQuoted _ = False
900inlineToLaTeX (Str str) = do
893inlineToLaTeX (Str str) = do
901 setEmptyLine False
894 setEmptyLine False
902 liftM literal $ stringToLaTeX TextString str
895 liftM literal $ stringToLaTeX TextString str
@@ -919,7 +912,7 @@ inlineToLaTeX il@(RawInline f str) = do
919inlineToLaTeX LineBreak = do
912inlineToLaTeX LineBreak = do
920 emptyLine <- gets stEmptyLine
913 emptyLine <- gets stEmptyLine
921 setEmptyLine True
914 setEmptyLine True
922− return $ (if emptyLine then "\\strut " else "") <> "\\\\" <> cr
915+ return $ (if emptyLine then "~" else "") <> "\\\\" <> cr
923inlineToLaTeX SoftBreak = do
916inlineToLaTeX SoftBreak = do
924 wrapText <- gets (writerWrapText . stOptions)
917 wrapText <- gets (writerWrapText . stOptions)
925 case wrapText of
918 case wrapText of
@@ -1050,3 +1043,5 @@ extractInline _ _ = []
1050-- Look up a key in an attribute and give a list of its values
1043-- Look up a key in an attribute and give a list of its values
1051lookKey :: Text -> Attr -> [Text]
1044lookKey :: Text -> Attr -> [Text]
1052lookKey key (_,_,kvs) = maybe [] T.words $ lookup key kvs
1045lookKey key (_,_,kvs) = maybe [] T.words $ lookup key kvs
1046+
1047+
src/Text/Pandoc/Writers/LaTeX/Lang.hs+60−61
@@ -15,7 +15,7 @@ module Text.Pandoc.Writers.LaTeX.Lang
15 toBabel
15 toBabel
16 ) where
16 ) where
17import Data.Text (Text)
17import Data.Text (Text)
18−import Text.Collate.Lang (Lang(..))
18+import Text.Pandoc.BCP47 (Lang (..))
19
19
20
20
21-- In environments \Arabic instead of \arabic is used
21-- In environments \Arabic instead of \arabic is used
@@ -25,89 +25,88 @@ toPolyglossiaEnv l =
25 ("arabic", o) -> ("Arabic", o)
25 ("arabic", o) -> ("Arabic", o)
26 x -> x
26 x -> x
27
27
28−-- Takes a list of the constituents of a BCP47 language code and
28+-- Takes a list of the constituents of a BCP 47 language code and
29-- converts it to a Polyglossia (language, options) tuple
29-- converts it to a Polyglossia (language, options) tuple
30-- http://mirrors.ctan.org/macros/latex/contrib/polyglossia/polyglossia.pdf
30-- http://mirrors.ctan.org/macros/latex/contrib/polyglossia/polyglossia.pdf
31toPolyglossia :: Lang -> (Text, Text)
31toPolyglossia :: Lang -> (Text, Text)
32−toPolyglossia (Lang "ar" _ (Just "DZ") _ _ _) = ("arabic", "locale=algeria")
32+toPolyglossia (Lang "ar" _ "DZ" _) = ("arabic", "locale=algeria")
33−toPolyglossia (Lang "ar" _ (Just "IQ") _ _ _) = ("arabic", "locale=mashriq")
33+toPolyglossia (Lang "ar" _ "IQ" _) = ("arabic", "locale=mashriq")
34−toPolyglossia (Lang "ar" _ (Just "JO") _ _ _) = ("arabic", "locale=mashriq")
34+toPolyglossia (Lang "ar" _ "JO" _) = ("arabic", "locale=mashriq")
35−toPolyglossia (Lang "ar" _ (Just "LB") _ _ _) = ("arabic", "locale=mashriq")
35+toPolyglossia (Lang "ar" _ "LB" _) = ("arabic", "locale=mashriq")
36−toPolyglossia (Lang "ar" _ (Just "LY") _ _ _) = ("arabic", "locale=libya")
36+toPolyglossia (Lang "ar" _ "LY" _) = ("arabic", "locale=libya")
37−toPolyglossia (Lang "ar" _ (Just "MA") _ _ _) = ("arabic", "locale=morocco")
37+toPolyglossia (Lang "ar" _ "MA" _) = ("arabic", "locale=morocco")
38−toPolyglossia (Lang "ar" _ (Just "MR") _ _ _) = ("arabic", "locale=mauritania")
38+toPolyglossia (Lang "ar" _ "MR" _) = ("arabic", "locale=mauritania")
39−toPolyglossia (Lang "ar" _ (Just "PS") _ _ _) = ("arabic", "locale=mashriq")
39+toPolyglossia (Lang "ar" _ "PS" _) = ("arabic", "locale=mashriq")
40−toPolyglossia (Lang "ar" _ (Just "SY") _ _ _) = ("arabic", "locale=mashriq")
40+toPolyglossia (Lang "ar" _ "SY" _) = ("arabic", "locale=mashriq")
41−toPolyglossia (Lang "ar" _ (Just "TN") _ _ _) = ("arabic", "locale=tunisia")
41+toPolyglossia (Lang "ar" _ "TN" _) = ("arabic", "locale=tunisia")
42−toPolyglossia (Lang "de" _ _ vars _ _)
42+toPolyglossia (Lang "de" _ _ vars)
43− | "1901" `elem` vars = ("german", "spelling=old")
43+ | "1901" `elem` vars = ("german", "spelling=old")
44−toPolyglossia (Lang "de" _ (Just "AT") vars _ _)
44+toPolyglossia (Lang "de" _ "AT" vars)
45− | "1901" `elem` vars = ("german", "variant=austrian, spelling=old")
45+ | "1901" `elem` vars = ("german", "variant=austrian, spelling=old")
46−toPolyglossia (Lang "de" _ (Just "AT") _ _ _) = ("german", "variant=austrian")
46+toPolyglossia (Lang "de" _ "AT" _) = ("german", "variant=austrian")
47−toPolyglossia (Lang "de" _ (Just "CH") vars _ _)
47+toPolyglossia (Lang "de" _ "CH" vars)
48− | "1901" `elem` vars = ("german", "variant=swiss, spelling=old")
48+ | "1901" `elem` vars = ("german", "variant=swiss, spelling=old")
49−toPolyglossia (Lang "de" _ (Just "CH") _ _ _) = ("german", "variant=swiss")
49+toPolyglossia (Lang "de" _ "CH" _) = ("german", "variant=swiss")
50−toPolyglossia (Lang "de" _ _ _ _ _) = ("german", "")
50+toPolyglossia (Lang "de" _ _ _) = ("german", "")
51−toPolyglossia (Lang "dsb" _ _ _ _ _) = ("lsorbian", "")
51+toPolyglossia (Lang "dsb" _ _ _) = ("lsorbian", "")
52−toPolyglossia (Lang "el" _ _ vars _ _)
53− | "polyton" `elem` vars = ("greek", "variant=poly")
52+toPolyglossia (Lang "el" _ "polyton" _) = ("greek", "variant=poly")
54−toPolyglossia (Lang "en" _ (Just "AU") _ _ _) = ("english", "variant=australian")
53+toPolyglossia (Lang "en" _ "AU" _) = ("english", "variant=australian")
55−toPolyglossia (Lang "en" _ (Just "CA") _ _ _) = ("english", "variant=canadian")
54+toPolyglossia (Lang "en" _ "CA" _) = ("english", "variant=canadian")
56−toPolyglossia (Lang "en" _ (Just "GB") _ _ _) = ("english", "variant=british")
55+toPolyglossia (Lang "en" _ "GB" _) = ("english", "variant=british")
57−toPolyglossia (Lang "en" _ (Just "NZ") _ _ _) = ("english", "variant=newzealand")
56+toPolyglossia (Lang "en" _ "NZ" _) = ("english", "variant=newzealand")
58−toPolyglossia (Lang "en" _ (Just "UK") _ _ _) = ("english", "variant=british")
57+toPolyglossia (Lang "en" _ "UK" _) = ("english", "variant=british")
59−toPolyglossia (Lang "en" _ (Just "US") _ _ _) = ("english", "variant=american")
58+toPolyglossia (Lang "en" _ "US" _) = ("english", "variant=american")
60−toPolyglossia (Lang "grc" _ _ _ _ _) = ("greek", "variant=ancient")
59+toPolyglossia (Lang "grc" _ _ _) = ("greek", "variant=ancient")
61−toPolyglossia (Lang "hsb" _ _ _ _ _) = ("usorbian", "")
60+toPolyglossia (Lang "hsb" _ _ _) = ("usorbian", "")
62−toPolyglossia (Lang "la" _ _ vars _ _)
61+toPolyglossia (Lang "la" _ _ vars)
63− | "x-classic" `elem` vars = ("latin", "variant=classic")
62+ | "x-classic" `elem` vars = ("latin", "variant=classic")
64−toPolyglossia (Lang "pt" _ (Just "BR") _ _ _) = ("portuguese", "variant=brazilian")
63+toPolyglossia (Lang "pt" _ "BR" _) = ("portuguese", "variant=brazilian")
65−toPolyglossia (Lang "sl" _ _ _ _ _) = ("slovenian", "")
64+toPolyglossia (Lang "sl" _ _ _) = ("slovenian", "")
66−toPolyglossia x = (commonFromBcp47 x, "")
65+toPolyglossia x = (commonFromBcp47 x, "")
67
66
68−-- Takes a list of the constituents of a BCP47 language code and
67+-- Takes a list of the constituents of a BCP 47 language code and
69-- converts it to a Babel language string.
68-- converts it to a Babel language string.
70-- http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf
69-- http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf
71-- List of supported languages (slightly outdated):
70-- List of supported languages (slightly outdated):
72-- http://tug.ctan.org/language/hyph-utf8/doc/generic/hyph-utf8/hyphenation.pdf
71-- http://tug.ctan.org/language/hyph-utf8/doc/generic/hyph-utf8/hyphenation.pdf
73toBabel :: Lang -> Text
72toBabel :: Lang -> Text
74−toBabel (Lang "de" _ (Just "AT") vars _ _)
73+toBabel (Lang "de" _ "AT" vars)
75 | "1901" `elem` vars = "austrian"
74 | "1901" `elem` vars = "austrian"
76 | otherwise = "naustrian"
75 | otherwise = "naustrian"
77−toBabel (Lang "de" _ (Just "CH") vars _ _)
76+toBabel (Lang "de" _ "CH" vars)
78 | "1901" `elem` vars = "swissgerman"
77 | "1901" `elem` vars = "swissgerman"
79 | otherwise = "nswissgerman"
78 | otherwise = "nswissgerman"
80−toBabel (Lang "de" _ _ vars _ _)
79+toBabel (Lang "de" _ _ vars)
81 | "1901" `elem` vars = "german"
80 | "1901" `elem` vars = "german"
82 | otherwise = "ngerman"
81 | otherwise = "ngerman"
83−toBabel (Lang "dsb" _ _ _ _ _) = "lowersorbian"
82+toBabel (Lang "dsb" _ _ _) = "lowersorbian"
84−toBabel (Lang "el" _ _ vars _ _)
83+toBabel (Lang "el" _ _ vars)
85 | "polyton" `elem` vars = "polutonikogreek"
84 | "polyton" `elem` vars = "polutonikogreek"
86−toBabel (Lang "en" _ (Just "AU") _ _ _) = "australian"
85+toBabel (Lang "en" _ "AU" _) = "australian"
87−toBabel (Lang "en" _ (Just "CA") _ _ _) = "canadian"
86+toBabel (Lang "en" _ "CA" _) = "canadian"
88−toBabel (Lang "en" _ (Just "GB") _ _ _) = "british"
87+toBabel (Lang "en" _ "GB" _) = "british"
89−toBabel (Lang "en" _ (Just "NZ") _ _ _) = "newzealand"
88+toBabel (Lang "en" _ "NZ" _) = "newzealand"
90−toBabel (Lang "en" _ (Just "UK") _ _ _) = "british"
89+toBabel (Lang "en" _ "UK" _) = "british"
91−toBabel (Lang "en" _ (Just "US") _ _ _) = "american"
90+toBabel (Lang "en" _ "US" _) = "american"
92−toBabel (Lang "fr" _ (Just "CA") _ _ _) = "canadien"
91+toBabel (Lang "fr" _ "CA" _) = "canadien"
93−toBabel (Lang "fra" _ _ vars _ _)
92+toBabel (Lang "fra" _ _ vars)
94 | "aca" `elem` vars = "acadian"
93 | "aca" `elem` vars = "acadian"
95−toBabel (Lang "grc" _ _ _ _ _) = "polutonikogreek"
94+toBabel (Lang "grc" _ _ _) = "polutonikogreek"
96−toBabel (Lang "hsb" _ _ _ _ _) = "uppersorbian"
95+toBabel (Lang "hsb" _ _ _) = "uppersorbian"
97−toBabel (Lang "la" _ _ vars _ _)
96+toBabel (Lang "la" _ _ vars)
98 | "x-classic" `elem` vars = "classiclatin"
97 | "x-classic" `elem` vars = "classiclatin"
99−toBabel (Lang "pt" _ (Just "BR") _ _ _) = "brazilian"
98+toBabel (Lang "pt" _ "BR" _) = "brazilian"
100−toBabel (Lang "sl" _ _ _ _ _) = "slovene"
99+toBabel (Lang "sl" _ _ _) = "slovene"
101toBabel x = commonFromBcp47 x
100toBabel x = commonFromBcp47 x
102
101
103−-- Takes a list of the constituents of a BCP47 language code
102+-- Takes a list of the constituents of a BCP 47 language code
104-- and converts it to a string shared by Babel and Polyglossia.
103-- and converts it to a string shared by Babel and Polyglossia.
105-- https://tools.ietf.org/html/bcp47#section-2.1
104-- https://tools.ietf.org/html/bcp47#section-2.1
106commonFromBcp47 :: Lang -> Text
105commonFromBcp47 :: Lang -> Text
107−commonFromBcp47 (Lang "sr" (Just "Cyrl") _ _ _ _) = "serbianc"
106+commonFromBcp47 (Lang "sr" "Cyrl" _ _) = "serbianc"
108−commonFromBcp47 (Lang "zh" (Just "Latn") _ vars _ _)
107+commonFromBcp47 (Lang "zh" "Latn" _ vars)
109− | "pinyin" `elem` vars = "pinyin"
108+ | "pinyin" `elem` vars = "pinyin"
110−commonFromBcp47 (Lang l _ _ _ _ _) = fromIso l
109+commonFromBcp47 (Lang l _ _ _) = fromIso l
111 where
110 where
112 fromIso "af" = "afrikaans"
111 fromIso "af" = "afrikaans"
113 fromIso "am" = "amharic"
112 fromIso "am" = "amharic"
src/Text/Pandoc/Writers/LaTeX/Table.hs+8−21
@@ -16,7 +16,6 @@ module Text.Pandoc.Writers.LaTeX.Table
16 ) where
16 ) where
17import Control.Monad.State.Strict
17import Control.Monad.State.Strict
18import Data.List (intersperse)
18import Data.List (intersperse)
19−import qualified Data.List.NonEmpty as NonEmpty
20import Data.List.NonEmpty (NonEmpty ((:|)))
19import Data.List.NonEmpty (NonEmpty ((:|)))
21import Data.Text (Text)
20import Data.Text (Text)
22import qualified Data.Text as T
21import qualified Data.Text as T
@@ -26,8 +25,7 @@ import Text.DocLayout
26 ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest
25 ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest
27 , text, vcat, ($$) )
26 , text, vcat, ($$) )
28import Text.Pandoc.Shared (blocksToInlines, splitBy, tshow)
27import Text.Pandoc.Shared (blocksToInlines, splitBy, tshow)
29−import Text.Pandoc.Walk (walk, query)
28+import Text.Pandoc.Walk (walk)
30−import Data.Monoid (Any(..))
31import Text.Pandoc.Writers.LaTeX.Caption (getCaption)
29import Text.Pandoc.Writers.LaTeX.Caption (getCaption)
32import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
30import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
33import Text.Pandoc.Writers.LaTeX.Types
31import Text.Pandoc.Writers.LaTeX.Types
@@ -221,7 +219,9 @@ footRows (Ann.TableFoot _attr rows) = map headerRowCells rows
221-- we need to go to some lengths to get line breaks working:
219-- we need to go to some lengths to get line breaks working:
222-- as LineBreak bs = \vtop{\hbox{\strut as}\hbox{\strut bs}}.
220-- as LineBreak bs = \vtop{\hbox{\strut as}\hbox{\strut bs}}.
223fixLineBreaks :: Block -> Block
221fixLineBreaks :: Block -> Block
224−fixLineBreaks = walk fixLineBreaks'
222+fixLineBreaks (Para ils) = Para $ fixLineBreaks' ils
223+fixLineBreaks (Plain ils) = Plain $ fixLineBreaks' ils
224+fixLineBreaks x = x
225
225
226fixLineBreaks' :: [Inline] -> [Inline]
226fixLineBreaks' :: [Inline] -> [Inline]
227fixLineBreaks' ils = case splitBy (== LineBreak) ils of
227fixLineBreaks' ils = case splitBy (== LineBreak) ils of
@@ -245,13 +245,8 @@ cellToLaTeX :: PandocMonad m
245 -> Ann.Cell
245 -> Ann.Cell
246 -> LW m (Doc Text)
246 -> LW m (Doc Text)
247cellToLaTeX blockListToLaTeX celltype annotatedCell = do
247cellToLaTeX blockListToLaTeX celltype annotatedCell = do
248− let (Ann.Cell specs _colnum cell) = annotatedCell
248+ let (Ann.Cell _specs _colnum cell) = annotatedCell
249− let hasWidths = snd (NonEmpty.head specs) /= ColWidthDefault
250− let specAlign = fst (NonEmpty.head specs)
251− let (Cell _attr align' rowspan colspan blocks) = cell
249+ let (Cell _attr align rowspan colspan blocks) = cell
252− let align = case align' of
253− AlignDefault -> specAlign
254− _ -> align'
255 beamer <- gets stBeamer
250 beamer <- gets stBeamer
256 externalNotes <- gets stExternalNotes
251 externalNotes <- gets stExternalNotes
257 inMinipage <- gets stInMinipage
252 inMinipage <- gets stInMinipage
@@ -262,13 +257,8 @@ cellToLaTeX blockListToLaTeX celltype annotatedCell = do
262 Para{} -> True
257 Para{} -> True
263 Plain{} -> True
258 Plain{} -> True
264 _ -> False
259 _ -> False
265− let hasLineBreak LineBreak = Any True
266− hasLineBreak _ = Any False
267− let hasLineBreaks = getAny $ query hasLineBreak blocks
268 result <-
260 result <-
269− if not hasWidths || (celltype /= HeaderCell
270− && all isPlainOrPara blocks
261+ if all isPlainOrPara blocks
271− && not hasLineBreaks)
272 then
262 then
273 blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
263 blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
274 else do
264 else do
@@ -281,9 +271,7 @@ cellToLaTeX blockListToLaTeX celltype annotatedCell = do
281 let halign = literal $ alignCommand align
271 let halign = literal $ alignCommand align
282 return $ "\\begin{minipage}" <> valign <>
272 return $ "\\begin{minipage}" <> valign <>
283 braces "\\linewidth" <> halign <> cr <>
273 braces "\\linewidth" <> halign <> cr <>
284− cellContents <>
274+ cellContents <> cr <>
285− (if hasLineBreaks then "\\strut" else mempty)
286− <> cr <>
287 "\\end{minipage}"
275 "\\end{minipage}"
288 modify $ \st -> st{ stExternalNotes = externalNotes }
276 modify $ \st -> st{ stExternalNotes = externalNotes }
289 when (rowspan /= RowSpan 1) $
277 when (rowspan /= RowSpan 1) $
@@ -304,4 +292,3 @@ cellToLaTeX blockListToLaTeX celltype annotatedCell = do
304data CellType
292data CellType
305 = HeaderCell
293 = HeaderCell
306 | BodyCell
294 | BodyCell
307− deriving Eq
src/Text/Pandoc/Writers/LaTeX/Types.hs+1−2
@@ -40,7 +40,7 @@ data WriterState =
40 , stCsquotes :: Bool -- ^ true if document uses csquotes
40 , stCsquotes :: Bool -- ^ true if document uses csquotes
41 , stHighlighting :: Bool -- ^ true if document has highlighted code
41 , stHighlighting :: Bool -- ^ true if document has highlighted code
42 , stIncremental :: Bool -- ^ true if beamer lists should be
42 , stIncremental :: Bool -- ^ true if beamer lists should be
43− , stZwnj :: Bool -- ^ true if document has a ZWNJ character
43+ -- displayed bit by bit
44 , stInternalLinks :: [Text] -- ^ list of internal link targets
44 , stInternalLinks :: [Text] -- ^ list of internal link targets
45 , stBeamer :: Bool -- ^ produce beamer
45 , stBeamer :: Bool -- ^ produce beamer
46 , stEmptyLine :: Bool -- ^ true if no content on line
46 , stEmptyLine :: Bool -- ^ true if no content on line
@@ -74,7 +74,6 @@ startingState options =
74 , stCsquotes = False
74 , stCsquotes = False
75 , stHighlighting = False
75 , stHighlighting = False
76 , stIncremental = writerIncremental options
76 , stIncremental = writerIncremental options
77− , stZwnj = False
78 , stInternalLinks = []
77 , stInternalLinks = []
79 , stBeamer = False
78 , stBeamer = False
80 , stEmptyLine = True
79 , stEmptyLine = True
src/Text/Pandoc/Writers/LaTeX/Util.hs+3−4
@@ -22,7 +22,6 @@ module Text.Pandoc.Writers.LaTeX.Util (
22where
22where
23
23
24import Control.Applicative ((<|>))
24import Control.Applicative ((<|>))
25−import Control.Monad (when)
26import Text.Pandoc.Class (PandocMonad, toLang)
25import Text.Pandoc.Class (PandocMonad, toLang)
27import Text.Pandoc.Options (WriterOptions(..), isEnabled)
26import Text.Pandoc.Options (WriterOptions(..), isEnabled)
28import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState(..))
27import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState(..))
@@ -31,7 +30,7 @@ import Text.Pandoc.Highlighting (toListingsLanguage)
31import Text.DocLayout
30import Text.DocLayout
32import Text.Pandoc.Definition
31import Text.Pandoc.Definition
33import Text.Pandoc.ImageSize (showFl)
32import Text.Pandoc.ImageSize (showFl)
34−import Control.Monad.State.Strict (gets, modify)
33+import Control.Monad.State.Strict (gets)
35import Data.Text (Text)
34import Data.Text (Text)
36import qualified Data.Text as T
35import qualified Data.Text as T
37import Text.Pandoc.Extensions (Extension(Ext_smart))
36import Text.Pandoc.Extensions (Extension(Ext_smart))
@@ -50,8 +49,6 @@ data StringContext = TextString
50stringToLaTeX :: PandocMonad m => StringContext -> Text -> LW m Text
49stringToLaTeX :: PandocMonad m => StringContext -> Text -> LW m Text
51stringToLaTeX context zs = do
50stringToLaTeX context zs = do
52 opts <- gets stOptions
51 opts <- gets stOptions
53− when ('\x200c' `elemText` zs) $
54− modify (\s -> s { stZwnj = True })
55 return $ T.pack $
52 return $ T.pack $
56 foldr (go opts context) mempty $ T.unpack $
53 foldr (go opts context) mempty $ T.unpack $
57 if writerPreferAscii opts
54 if writerPreferAscii opts
@@ -273,3 +270,5 @@ mbBraced :: Text -> Text
273mbBraced x = if not (T.all isAlphaNum x)
270mbBraced x = if not (T.all isAlphaNum x)
274 then "{" <> x <> "}"
271 then "{" <> x <> "}"
275 else x
272 else x
273+
274+
src/Text/Pandoc/Writers/Markdown.hs+41−26
@@ -26,7 +26,7 @@ import Data.Default
26import Data.List (intersperse, sortOn, transpose)
26import Data.List (intersperse, sortOn, transpose)
27import Data.List.NonEmpty (nonEmpty, NonEmpty(..))
27import Data.List.NonEmpty (nonEmpty, NonEmpty(..))
28import qualified Data.Map as M
28import qualified Data.Map as M
29−import Data.Maybe (fromMaybe, mapMaybe, isNothing)
29+import Data.Maybe (fromMaybe, mapMaybe)
30import qualified Data.Set as Set
30import qualified Data.Set as Set
31import Data.Text (Text)
31import Data.Text (Text)
32import qualified Data.Text as T
32import qualified Data.Text as T
@@ -43,7 +43,7 @@ import Text.Pandoc.Templates (renderTemplate)
43import Text.DocTemplates (Val(..), Context(..), FromContext(..))
43import Text.DocTemplates (Val(..), Context(..), FromContext(..))
44import Text.Pandoc.Walk
44import Text.Pandoc.Walk
45import Text.Pandoc.Writers.HTML (writeHtml5String)
45import Text.Pandoc.Writers.HTML (writeHtml5String)
46−import Text.Pandoc.Writers.Markdown.Inline (inlineListToMarkdown, linkAttributes, attrsToMarkdown)
46+import Text.Pandoc.Writers.Markdown.Inline (inlineListToMarkdown)
47import Text.Pandoc.Writers.Markdown.Types (MarkdownVariant(..),
47import Text.Pandoc.Writers.Markdown.Types (MarkdownVariant(..),
48 WriterState(..),
48 WriterState(..),
49 WriterEnv(..),
49 WriterEnv(..),
@@ -75,6 +75,7 @@ writeCommonMark opts document =
75 -- we set them here so that escapeText will behave
75 -- we set them here so that escapeText will behave
76 -- properly.
76 -- properly.
77 enableExtension Ext_all_symbols_escapable $
77 enableExtension Ext_all_symbols_escapable $
78+ enableExtension Ext_pipe_tables $
78 enableExtension Ext_intraword_underscores $
79 enableExtension Ext_intraword_underscores $
79 writerExtensions opts }
80 writerExtensions opts }
80
81
@@ -141,17 +142,18 @@ valToYaml (SimpleVal x)
141 | otherwise =
142 | otherwise =
142 if hasNewlines x
143 if hasNewlines x
143 then hang 0 ("|" <> cr) x
144 then hang 0 ("|" <> cr) x
144− else if isNothing $ foldM needsDoubleQuotes True x
145+ else if fst $ foldr needsDoubleQuotes (False, True) x
145 then "\"" <> fmap escapeInDoubleQuotes x <> "\""
146 then "\"" <> fmap escapeInDoubleQuotes x <> "\""
146 else x
147 else x
147 where
148 where
148− needsDoubleQuotes isFirst t
149+ needsDoubleQuotes t (positive, isFirst)
149 = if T.any isBadAnywhere t ||
150 = if T.any isBadAnywhere t ||
150 (isFirst && T.any isYamlPunct (T.take 1 t))
151 (isFirst && T.any isYamlPunct (T.take 1 t))
151− then Nothing
152+ then (True, False)
152− else Just False
153+ else (positive, False)
153 isBadAnywhere '#' = True
154 isBadAnywhere '#' = True
154 isBadAnywhere ':' = True
155 isBadAnywhere ':' = True
156+ isBadAnywhere '`' = False
155 isBadAnywhere _ = False
157 isBadAnywhere _ = False
156 hasNewlines NewLine = True
158 hasNewlines NewLine = True
157 hasNewlines BlankLines{} = True
159 hasNewlines BlankLines{} = True
@@ -256,11 +258,32 @@ noteToMarkdown opts num blocks = do
256 then hang (writerTabStop opts) (marker <> spacer) contents
258 then hang (writerTabStop opts) (marker <> spacer) contents
257 else marker <> spacer <> contents
259 else marker <> spacer <> contents
258
260
259−-- | (Code) blocks with a single class and no attributes can just use it
261+attrsToMarkdown :: Attr -> Doc Text
260−-- standalone, no need to bother with curly braces.
262+attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
261−classOrAttrsToMarkdown :: Attr -> Doc Text
263+ where attribId = case attribs of
262−classOrAttrsToMarkdown ("",[cls],[]) = literal cls
264+ ("",_,_) -> empty
265+ (i,_,_) -> "#" <> escAttr i
266+ attribClasses = case attribs of
267+ (_,[],_) -> empty
268+ (_,cs,_) -> hsep $
269+ map (escAttr . ("."<>))
270+ cs
271+ attribKeys = case attribs of
272+ (_,_,[]) -> empty
273+ (_,_,ks) -> hsep $
274+ map (\(k,v) -> escAttr k
275+ <> "=\"" <>
276+ escAttr v <> "\"") ks
277+ escAttr = mconcat . map escAttrChar . T.unpack
278+ escAttrChar '"' = literal "\\\""
279+ escAttrChar '\\' = literal "\\\\"
280+ escAttrChar c = literal $ T.singleton c
281+
282+linkAttributes :: WriterOptions -> Attr -> Doc Text
283+linkAttributes opts attr =
284+ if isEnabled Ext_link_attributes opts && attr /= nullAttr
263−classOrAttrsToMarkdown attrs = attrsToMarkdown attrs
285+ then attrsToMarkdown attr
286+ else empty
264
287
265-- | Ordered list start parser for use in Para below.
288-- | Ordered list start parser for use in Para below.
266olMarker :: Parser Text ParserState ()
289olMarker :: Parser Text ParserState ()
@@ -321,12 +344,9 @@ blockToMarkdown' opts (Div attrs ils) = do
321 case () of
344 case () of
322 _ | isEnabled Ext_fenced_divs opts &&
345 _ | isEnabled Ext_fenced_divs opts &&
323 attrs /= nullAttr ->
346 attrs /= nullAttr ->
324− let attrsToMd = if variant == Commonmark
325− then attrsToMarkdown
326− else classOrAttrsToMarkdown
327− in nowrap (literal ":::" <+> attrsToMd attrs) $$
347+ nowrap (literal ":::" <+> attrsToMarkdown attrs) $$
328− chomp contents $$
348+ chomp contents $$
329− literal ":::" <> blankline
349+ literal ":::" <> blankline
330 | isEnabled Ext_native_divs opts ||
350 | isEnabled Ext_native_divs opts ||
331 (isEnabled Ext_raw_html opts &&
351 (isEnabled Ext_raw_html opts &&
332 (variant == Commonmark ||
352 (variant == Commonmark ||
@@ -368,7 +388,7 @@ blockToMarkdown' opts (Plain inlines) = do
368-- title beginning with fig: indicates figure
388-- title beginning with fig: indicates figure
369blockToMarkdown' opts (Para [Image attr alt (src,tgt@(T.stripPrefix "fig:" -> Just tit))])
389blockToMarkdown' opts (Para [Image attr alt (src,tgt@(T.stripPrefix "fig:" -> Just tit))])
370 | isEnabled Ext_raw_html opts &&
390 | isEnabled Ext_raw_html opts &&
371− not (isEnabled Ext_link_attributes opts || isEnabled Ext_attributes opts) &&
391+ not (isEnabled Ext_link_attributes opts) &&
372 attr /= nullAttr = -- use raw HTML
392 attr /= nullAttr = -- use raw HTML
373 (<> blankline) . literal . T.strip <$>
393 (<> blankline) . literal . T.strip <$>
374 writeHtml5String opts{ writerTemplate = Nothing }
394 writeHtml5String opts{ writerTemplate = Nothing }
@@ -433,8 +453,7 @@ blockToMarkdown' opts (Header level attr inlines) = do
433 && id' == autoId -> empty
453 && id' == autoId -> empty
434 (id',_,_) | isEnabled Ext_mmd_header_identifiers opts ->
454 (id',_,_) | isEnabled Ext_mmd_header_identifiers opts ->
435 space <> brackets (literal id')
455 space <> brackets (literal id')
436− _ | isEnabled Ext_header_attributes opts ||
456+ _ | isEnabled Ext_header_attributes opts ->
437− isEnabled Ext_attributes opts ->
438 space <> attrsToMarkdown attr
457 space <> attrsToMarkdown attr
439 | otherwise -> empty
458 | otherwise -> empty
440 contents <- inlineListToMarkdown opts $
459 contents <- inlineListToMarkdown opts $
@@ -493,9 +512,8 @@ blockToMarkdown' opts (CodeBlock attribs str) = do
493 endline c = literal $ T.replicate (endlineLen c) $ T.singleton c
512 endline c = literal $ T.replicate (endlineLen c) $ T.singleton c
494 backticks = endline '`'
513 backticks = endline '`'
495 tildes = endline '~'
514 tildes = endline '~'
496− attrs = if isEnabled Ext_fenced_code_attributes opts ||
515+ attrs = if isEnabled Ext_fenced_code_attributes opts
497− isEnabled Ext_attributes opts
498− then nowrap $ " " <> classOrAttrsToMarkdown attribs
516+ then nowrap $ " " <> attrsToMarkdown attribs
499 else case attribs of
517 else case attribs of
500 (_,cls:_,_) -> " " <> literal cls
518 (_,cls:_,_) -> " " <> literal cls
501 _ -> empty
519 _ -> empty
@@ -791,9 +809,6 @@ blockListToMarkdown opts blocks = do
791 b1 : commentSep : fixBlocks (b2:bs)
809 b1 : commentSep : fixBlocks (b2:bs)
792 fixBlocks (Plain ils : bs@(RawBlock{}:_)) =
810 fixBlocks (Plain ils : bs@(RawBlock{}:_)) =
793 Plain ils : fixBlocks bs
811 Plain ils : fixBlocks bs
794− fixBlocks (Plain ils : bs@(Div{}:_))
795− | isEnabled Ext_fenced_divs opts =
796− Para ils : fixBlocks bs
797 fixBlocks (Plain ils : bs) | inlist =
812 fixBlocks (Plain ils : bs) | inlist =
798 Plain ils : fixBlocks bs
813 Plain ils : fixBlocks bs
799 fixBlocks (Plain ils : bs) =
814 fixBlocks (Plain ils : bs) =
src/Text/Pandoc/Writers/Markdown/Inline.hs+16−34
@@ -11,9 +11,7 @@
11 Portability : portable
11 Portability : portable
12-}
12-}
13module Text.Pandoc.Writers.Markdown.Inline (
13module Text.Pandoc.Writers.Markdown.Inline (
14− inlineListToMarkdown,
14+ inlineListToMarkdown
15− linkAttributes,
16− attrsToMarkdown
17 ) where
15 ) where
18import Control.Monad.Reader
16import Control.Monad.Reader
19import Control.Monad.State.Strict
17import Control.Monad.State.Strict
@@ -45,11 +43,7 @@ import Text.Pandoc.Writers.Markdown.Types (MarkdownVariant(..),
45-- | Escape special characters for Markdown.
43-- | Escape special characters for Markdown.
46escapeText :: WriterOptions -> Text -> Text
44escapeText :: WriterOptions -> Text -> Text
47escapeText opts = T.pack . go . T.unpack
45escapeText opts = T.pack . go . T.unpack
48− where
46+ where
49− startsWithSpace (' ':_) = True
50− startsWithSpace ('\t':_) = True
51− startsWithSpace [] = True
52− startsWithSpace _ = False
53 go [] = []
47 go [] = []
54 go (c:cs) =
48 go (c:cs) =
55 case c of
49 case c of
@@ -62,13 +56,10 @@ escapeText opts = T.pack . go . T.unpack
62 '@' | isEnabled Ext_citations opts ->
56 '@' | isEnabled Ext_citations opts ->
63 case cs of
57 case cs of
64 (d:_)
58 (d:_)
65− | isAlphaNum d || d == '_' || d == '{'
59+ | isAlphaNum d || d == '_'
66 -> '\\':'@':go cs
60 -> '\\':'@':go cs
67 _ -> '@':go cs
61 _ -> '@':go cs
68− '#' | isEnabled Ext_space_in_atx_header opts
69− , startsWithSpace cs
70− -> '\\':'#':go cs
71− _ | c `elem` ['\\','`','*','_','[',']'] ->
62+ _ | c `elem` ['\\','`','*','_','[',']','#'] ->
72 '\\':c:go cs
63 '\\':c:go cs
73 '|' | isEnabled Ext_pipe_tables opts -> '\\':'|':go cs
64 '|' | isEnabled Ext_pipe_tables opts -> '\\':'|':go cs
74 '^' | isEnabled Ext_superscript opts -> '\\':'^':go cs
65 '^' | isEnabled Ext_superscript opts -> '\\':'^':go cs
@@ -90,8 +81,6 @@ escapeText opts = T.pack . go . T.unpack
90 | isEnabled Ext_intraword_underscores opts
81 | isEnabled Ext_intraword_underscores opts
91 , isAlphaNum c
82 , isAlphaNum c
92 , isAlphaNum x -> c : '_' : x : go xs
83 , isAlphaNum x -> c : '_' : x : go xs
93− '#':xs -> c : '#' : go xs
94− '>':xs -> c : '>' : go xs
95 _ -> c : go cs
84 _ -> c : go cs
96
85
97attrsToMarkdown :: Attr -> Doc Text
86attrsToMarkdown :: Attr -> Doc Text
@@ -117,7 +106,7 @@ attrsToMarkdown attribs = braces $ hsep [attribId, attribClasses, attribKeys]
117
106
118linkAttributes :: WriterOptions -> Attr -> Doc Text
107linkAttributes :: WriterOptions -> Attr -> Doc Text
119linkAttributes opts attr =
108linkAttributes opts attr =
120− if (isEnabled Ext_link_attributes opts || isEnabled Ext_attributes opts) && attr /= nullAttr
109+ if isEnabled Ext_link_attributes opts && attr /= nullAttr
121 then attrsToMarkdown attr
110 then attrsToMarkdown attr
122 else empty
111 else empty
123
112
@@ -394,15 +383,13 @@ inlineToMarkdown opts (Quoted DoubleQuote lst) = do
394 then "&ldquo;" <> contents <> "&rdquo;"
383 then "&ldquo;" <> contents <> "&rdquo;"
395 else "“" <> contents <> "”"
384 else "“" <> contents <> "”"
396inlineToMarkdown opts (Code attr str) = do
385inlineToMarkdown opts (Code attr str) = do
397− let tickGroups = filter (T.any (== '`')) $ T.group str
386+ let tickGroups = filter (T.any (== '`')) $ T.group str
398− let longest = maybe 0 maximum $ nonEmpty $ map T.length tickGroups
387+ let longest = maybe 0 maximum $ nonEmpty $ map T.length tickGroups
399− let marker = T.replicate (longest + 1) "`"
388+ let marker = T.replicate (longest + 1) "`"
400− let spacer = if longest == 0 then "" else " "
389+ let spacer = if longest == 0 then "" else " "
401− let attrsEnabled = isEnabled Ext_inline_code_attributes opts ||
390+ let attrs = if isEnabled Ext_inline_code_attributes opts && attr /= nullAttr
402− isEnabled Ext_attributes opts
403− let attrs = if attrsEnabled && attr /= nullAttr
404− then attrsToMarkdown attr
391+ then attrsToMarkdown attr
405− else empty
392+ else empty
406 variant <- asks envVariant
393 variant <- asks envVariant
407 case variant of
394 case variant of
408 PlainText -> return $ literal str
395 PlainText -> return $ literal str
@@ -504,16 +491,11 @@ inlineToMarkdown opts (Cite (c:cs) lst)
504 rest <- mapM convertOne cs
491 rest <- mapM convertOne cs
505 let inbr = suffs <+> joincits rest
492 let inbr = suffs <+> joincits rest
506 br = if isEmpty inbr then empty else char '[' <> inbr <> char ']'
493 br = if isEmpty inbr then empty else char '[' <> inbr <> char ']'
507− return $ literal ("@" <> maybeInBraces (citationId c)) <+> br
494+ return $ literal ("@" <> citationId c) <+> br
508 else do
495 else do
509 cits <- mapM convertOne (c:cs)
496 cits <- mapM convertOne (c:cs)
510 return $ literal "[" <> joincits cits <> literal "]"
497 return $ literal "[" <> joincits cits <> literal "]"
511 where
498 where
512− maybeInBraces key =
513− case readWith (citeKey False >> spaces >> eof)
514− defaultParserState ("@" <> key) of
515− Left _ -> "{" <> key <> "}"
516− Right _ -> key
517 joincits = hcat . intersperse (literal "; ") . filter (not . isEmpty)
499 joincits = hcat . intersperse (literal "; ") . filter (not . isEmpty)
518 convertOne Citation { citationId = k
500 convertOne Citation { citationId = k
519 , citationPrefix = pinlines
501 , citationPrefix = pinlines
@@ -522,7 +504,7 @@ inlineToMarkdown opts (Cite (c:cs) lst)
522 = do
504 = do
523 pdoc <- inlineListToMarkdown opts pinlines
505 pdoc <- inlineListToMarkdown opts pinlines
524 sdoc <- inlineListToMarkdown opts sinlines
506 sdoc <- inlineListToMarkdown opts sinlines
525− let k' = literal (modekey m <> "@" <> maybeInBraces k)
507+ let k' = literal (modekey m <> "@" <> k)
526 r = case sinlines of
508 r = case sinlines of
527 Str (T.uncons -> Just (y,_)):_ | y `elem` (",;]@" :: String) -> k' <> sdoc
509 Str (T.uncons -> Just (y,_)):_ | y `elem` (",;]@" :: String) -> k' <> sdoc
528 _ -> k' <+> sdoc
510 _ -> k' <+> sdoc
@@ -561,7 +543,7 @@ inlineToMarkdown opts lnk@(Link attr txt (src, tit)) = do
561 else "[" <> reftext <> "]"
543 else "[" <> reftext <> "]"
562 in return $ first <> second
544 in return $ first <> second
563 | isEnabled Ext_raw_html opts
545 | isEnabled Ext_raw_html opts
564− , not (isEnabled Ext_link_attributes opts || isEnabled Ext_attributes opts)
546+ , not (isEnabled Ext_link_attributes opts)
565 , attr /= nullAttr -> -- use raw HTML to render attributes
547 , attr /= nullAttr -> -- use raw HTML to render attributes
566 literal . T.strip <$>
548 literal . T.strip <$>
567 writeHtml5String opts{ writerTemplate = Nothing }
549 writeHtml5String opts{ writerTemplate = Nothing }
@@ -571,7 +553,7 @@ inlineToMarkdown opts lnk@(Link attr txt (src, tit)) = do
571 linkAttributes opts attr
553 linkAttributes opts attr
572inlineToMarkdown opts img@(Image attr alternate (source, tit))
554inlineToMarkdown opts img@(Image attr alternate (source, tit))
573 | isEnabled Ext_raw_html opts &&
555 | isEnabled Ext_raw_html opts &&
574− not (isEnabled Ext_link_attributes opts || isEnabled Ext_attributes opts) &&
556+ not (isEnabled Ext_link_attributes opts) &&
575 attr /= nullAttr = -- use raw HTML
557 attr /= nullAttr = -- use raw HTML
576 literal . T.strip <$>
558 literal . T.strip <$>
577 writeHtml5String opts{ writerTemplate = Nothing } (Pandoc nullMeta [Plain [img]])
559 writeHtml5String opts{ writerTemplate = Nothing } (Pandoc nullMeta [Plain [img]])
src/Text/Pandoc/Writers/Ms.hs+6−22
@@ -245,17 +245,13 @@ blockToMs opts (Table _ blkCapt specs thead tbody tfoot) =
245 aligncode AlignDefault = "l"
245 aligncode AlignDefault = "l"
246 in do
246 in do
247 caption' <- inlineListToMs' opts caption
247 caption' <- inlineListToMs' opts caption
248− let isSimple = all (== 0) widths
248+ let iwidths = if all (== 0) widths
249− let totalWidth = 70
249+ then repeat ""
250+ else map (T.pack . printf "w(%0.1fn)" . (70 *)) widths
250 -- 78n default width - 8n indent = 70n
251 -- 78n default width - 8n indent = 70n
251 let coldescriptions = literal $ T.unwords
252 let coldescriptions = literal $ T.unwords
252− (zipWith (\align width -> aligncode align <>
253+ (zipWith (\align width -> aligncode align <> width)
253− if width == 0
254− then ""
255− else T.pack $
256− printf "w(%0.1fn)"
257− (totalWidth * width))
258− alignments widths) <> "."
254+ alignments iwidths) <> "."
259 colheadings <- mapM (blockListToMs opts) headers
255 colheadings <- mapM (blockListToMs opts) headers
260 let makeRow cols = literal "T{" $$
256 let makeRow cols = literal "T{" $$
261 vcat (intersperse (literal "T}\tT{") cols) $$
257 vcat (intersperse (literal "T}\tT{") cols) $$
@@ -264,25 +260,13 @@ blockToMs opts (Table _ blkCapt specs thead tbody tfoot) =
264 then empty
260 then empty
265 else makeRow colheadings $$ char '_'
261 else makeRow colheadings $$ char '_'
266 body <- mapM (\row -> do
262 body <- mapM (\row -> do
267− cols <- mapM (\(cell, w) ->
268− (if isSimple
269− then id
270− else (literal (".nr LL " <>
271− T.pack (printf "%0.1fn"
272− (w * totalWidth))) $$)) <$>
273− blockListToMs opts cell) (zip row widths)
263+ cols <- mapM (blockListToMs opts) row
274 return $ makeRow cols) rows
264 return $ makeRow cols) rows
275 setFirstPara
265 setFirstPara
276 return $ literal ".PP" $$ caption' $$
266 return $ literal ".PP" $$ caption' $$
277 literal ".na" $$ -- we don't want justification in table cells
267 literal ".na" $$ -- we don't want justification in table cells
278− (if isSimple
279− then ""
280− else ".nr LLold \\n[LL]") $$
281 literal ".TS" $$ literal "delim(@@) tab(\t);" $$ coldescriptions $$
268 literal ".TS" $$ literal "delim(@@) tab(\t);" $$ coldescriptions $$
282 colheadings' $$ vcat body $$ literal ".TE" $$
269 colheadings' $$ vcat body $$ literal ".TE" $$
283− (if isSimple
284− then ""
285− else ".nr LL \\n[LLold]") $$
286 literal ".ad"
270 literal ".ad"
287
271
288blockToMs opts (BulletList items) = do
272blockToMs opts (BulletList items) = do
src/Text/Pandoc/Writers/ODT.hs+3−4
@@ -16,7 +16,6 @@ import Codec.Archive.Zip
16import Control.Monad.Except (catchError, throwError)
16import Control.Monad.Except (catchError, throwError)
17import Control.Monad.State.Strict
17import Control.Monad.State.Strict
18import qualified Data.ByteString.Lazy as B
18import qualified Data.ByteString.Lazy as B
19−import Data.Maybe (fromMaybe)
20import Data.Generics (everywhere', mkT)
19import Data.Generics (everywhere', mkT)
21import Data.List (isPrefixOf)
20import Data.List (isPrefixOf)
22import qualified Data.Map as Map
21import qualified Data.Map as Map
@@ -24,7 +23,7 @@ import qualified Data.Text as T
24import qualified Data.Text.Lazy as TL
23import qualified Data.Text.Lazy as TL
25import Data.Time
24import Data.Time
26import System.FilePath (takeDirectory, takeExtension, (<.>))
25import System.FilePath (takeDirectory, takeExtension, (<.>))
27−import Text.Collate.Lang (Lang (..), renderLang)
26+import Text.Pandoc.BCP47 (Lang (..), getLang, renderLang)
28import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
27import Text.Pandoc.Class.PandocMonad (PandocMonad, report, toLang)
29import qualified Text.Pandoc.Class.PandocMonad as P
28import qualified Text.Pandoc.Class.PandocMonad as P
30import Text.Pandoc.Definition
29import Text.Pandoc.Definition
@@ -36,7 +35,7 @@ import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
36import Text.DocLayout
35import Text.DocLayout
37import Text.Pandoc.Shared (stringify, pandocVersion, tshow)
36import Text.Pandoc.Shared (stringify, pandocVersion, tshow)
38import Text.Pandoc.Writers.Shared (lookupMetaString, lookupMetaBlocks,
37import Text.Pandoc.Writers.Shared (lookupMetaString, lookupMetaBlocks,
39− fixDisplayMath, getLang)
38+ fixDisplayMath)
40import Text.Pandoc.UTF8 (fromStringLazy, fromTextLazy, toTextLazy)
39import Text.Pandoc.UTF8 (fromStringLazy, fromTextLazy, toTextLazy)
41import Text.Pandoc.Walk
40import Text.Pandoc.Walk
42import Text.Pandoc.Writers.OpenDocument (writeOpenDocument)
41import Text.Pandoc.Writers.OpenDocument (writeOpenDocument)
@@ -195,7 +194,7 @@ addLang lang = everywhere' (mkT updateLangAttr)
195 where updateLangAttr (Attr n@(QName "language" _ (Just "fo")) _)
194 where updateLangAttr (Attr n@(QName "language" _ (Just "fo")) _)
196 = Attr n (langLanguage lang)
195 = Attr n (langLanguage lang)
197 updateLangAttr (Attr n@(QName "country" _ (Just "fo")) _)
196 updateLangAttr (Attr n@(QName "country" _ (Just "fo")) _)
198− = Attr n (fromMaybe "" $ langRegion lang)
197+ = Attr n (langRegion lang)
199 updateLangAttr x = x
198 updateLangAttr x = x
200
199
201-- | transform both Image and Math elements
200-- | transform both Image and Math elements
src/Text/Pandoc/Writers/OpenDocument.hs+54−50
@@ -1,5 +1,4 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE LambdaCase #-}
3{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE PatternGuards #-}
3{-# LANGUAGE PatternGuards #-}
5{-# LANGUAGE ViewPatterns #-}
4{-# LANGUAGE ViewPatterns #-}
@@ -26,7 +25,7 @@ import Data.Ord (comparing)
26import qualified Data.Set as Set
25import qualified Data.Set as Set
27import Data.Text (Text)
26import Data.Text (Text)
28import qualified Data.Text as T
27import qualified Data.Text as T
29−import Text.Collate.Lang (Lang (..), parseLang)
28+import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
30import Text.Pandoc.Class.PandocMonad (PandocMonad, report, translateTerm,
29import Text.Pandoc.Class.PandocMonad (PandocMonad, report, translateTerm,
31 setTranslations, toLang)
30 setTranslations, toLang)
32import Text.Pandoc.Definition
31import Text.Pandoc.Definition
@@ -237,7 +236,7 @@ handleSpaces s = case T.uncons s of
237-- | Convert Pandoc document to string in OpenDocument format.
236-- | Convert Pandoc document to string in OpenDocument format.
238writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m Text
237writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m Text
239writeOpenDocument opts (Pandoc meta blocks) = do
238writeOpenDocument opts (Pandoc meta blocks) = do
240− let defLang = Lang "en" (Just "US") Nothing [] [] []
239+ let defLang = Lang "en" "US" "" []
241 lang <- case lookupMetaString "lang" meta of
240 lang <- case lookupMetaString "lang" meta of
242 "" -> pure defLang
241 "" -> pure defLang
243 s -> fromMaybe defLang <$> toLang (Just s)
242 s -> fromMaybe defLang <$> toLang (Just s)
@@ -373,32 +372,36 @@ blocksToOpenDocument o b = vcat <$> mapM (blockToOpenDocument o) b
373
372
374-- | Convert a Pandoc block element to OpenDocument.
373-- | Convert a Pandoc block element to OpenDocument.
375blockToOpenDocument :: PandocMonad m => WriterOptions -> Block -> OD m (Doc Text)
374blockToOpenDocument :: PandocMonad m => WriterOptions -> Block -> OD m (Doc Text)
376−blockToOpenDocument o = \case
375+blockToOpenDocument o bs
377− Plain b -> if null b
376+ | Plain b <- bs = if null b
378− then return empty
377+ then return empty
379− else inParagraphTags =<< inlinesToOpenDocument o b
378+ else inParagraphTags =<< inlinesToOpenDocument o b
380− Para [Image attr c (s,T.stripPrefix "fig:" -> Just t)] -> figure attr c s t
379+ | Para [Image attr c (s,T.stripPrefix "fig:" -> Just t)] <- bs
380+ = figure attr c s t
381− Para b -> if null b &&
381+ | Para b <- bs = if null b &&
382− not (isEnabled Ext_empty_paragraphs o)
382+ not (isEnabled Ext_empty_paragraphs o)
383− then return empty
383+ then return empty
384− else inParagraphTags =<< inlinesToOpenDocument o b
384+ else inParagraphTags =<< inlinesToOpenDocument o b
385− LineBlock b -> blockToOpenDocument o $ linesToPara b
385+ | LineBlock b <- bs = blockToOpenDocument o $ linesToPara b
386− Div attr xs -> mkDiv attr xs
386+ | Div attr xs <- bs = mkDiv attr xs
387− Header i (ident,_,_) b -> do
387+ | Header i (ident,_,_) b
388− setFirstPara
388+ <- bs = setFirstPara >> (inHeaderTags i ident
389− inHeaderTags i ident =<< inlinesToOpenDocument o b
389+ =<< inlinesToOpenDocument o b)
390− BlockQuote b -> setFirstPara >> mkBlockQuote b
390+ | BlockQuote b <- bs = setFirstPara >> mkBlockQuote b
391− DefinitionList b -> setFirstPara >> defList b
391+ | DefinitionList b <- bs = setFirstPara >> defList b
392− BulletList b -> setFirstPara >> bulletListToOpenDocument o b
392+ | BulletList b <- bs = setFirstPara >> bulletListToOpenDocument o b
393− OrderedList a b -> setFirstPara >> orderedList a b
393+ | OrderedList a b <- bs = setFirstPara >> orderedList a b
394− CodeBlock _ s -> setFirstPara >> preformatted s
394+ | CodeBlock _ s <- bs = setFirstPara >> preformatted s
395− Table a bc s th tb tf -> setFirstPara >> table (Ann.toTable a bc s th tb tf)
395+ | Table a bc s th tb tf <- bs = setFirstPara >> table (Ann.toTable a bc s th tb tf)
396− HorizontalRule -> setFirstPara >> return (selfClosingTag "text:p"
396+ | HorizontalRule <- bs = setFirstPara >> return (selfClosingTag "text:p"
397− [ ("text:style-name", "Horizontal_20_Line") ])
397+ [ ("text:style-name", "Horizontal_20_Line") ])
398− b@(RawBlock f s) -> if f == Format "opendocument"
398+ | RawBlock f s <- bs = if f == Format "opendocument"
399− then return $ text $ T.unpack s
399+ then return $ text $ T.unpack s
400+ else do
400− else empty <$ report (BlockNotRendered b)
401+ report $ BlockNotRendered bs
402+ return empty
403+ | Null <- bs = return empty
401− Null -> return empty
404+ | otherwise = return empty
402 where
405 where
403 defList b = do setInDefinitionList True
406 defList b = do setInDefinitionList True
404 r <- vcat <$> mapM (deflistItemToOpenDocument o) b
407 r <- vcat <$> mapM (deflistItemToOpenDocument o) b
@@ -871,33 +874,34 @@ data TextStyle = Italic
871textStyleAttr :: Map.Map Text Text
874textStyleAttr :: Map.Map Text Text
872 -> TextStyle
875 -> TextStyle
873 -> Map.Map Text Text
876 -> Map.Map Text Text
874−textStyleAttr m = \case
877+textStyleAttr m s
875− Italic -> Map.insert "fo:font-style" "italic" .
878+ | Italic <- s = Map.insert "fo:font-style" "italic" .
876− Map.insert "style:font-style-asian" "italic" .
879+ Map.insert "style:font-style-asian" "italic" .
877− Map.insert "style:font-style-complex" "italic" $ m
880+ Map.insert "style:font-style-complex" "italic" $ m
878− Bold -> Map.insert "fo:font-weight" "bold" .
881+ | Bold <- s = Map.insert "fo:font-weight" "bold" .
879− Map.insert "style:font-weight-asian" "bold" .
882+ Map.insert "style:font-weight-asian" "bold" .
880− Map.insert "style:font-weight-complex" "bold" $ m
883+ Map.insert "style:font-weight-complex" "bold" $ m
881− Under -> Map.insert "style:text-underline-style" "solid" .
884+ | Under <- s = Map.insert "style:text-underline-style" "solid" .
882− Map.insert "style:text-underline-width" "auto" .
885+ Map.insert "style:text-underline-width" "auto" .
883− Map.insert "style:text-underline-color" "font-color" $ m
886+ Map.insert "style:text-underline-color" "font-color" $ m
884− Strike -> Map.insert "style:text-line-through-style" "solid" m
887+ | Strike <- s = Map.insert "style:text-line-through-style" "solid" m
885− Sub -> Map.insert "style:text-position" "sub 58%" m
888+ | Sub <- s = Map.insert "style:text-position" "sub 58%" m
886− Sup -> Map.insert "style:text-position" "super 58%" m
889+ | Sup <- s = Map.insert "style:text-position" "super 58%" m
887− SmallC -> Map.insert "fo:font-variant" "small-caps" m
890+ | SmallC <- s = Map.insert "fo:font-variant" "small-caps" m
888− Pre -> Map.insert "style:font-name" "Courier New" .
891+ | Pre <- s = Map.insert "style:font-name" "Courier New" .
889− Map.insert "style:font-name-asian" "Courier New" .
892+ Map.insert "style:font-name-asian" "Courier New" .
890− Map.insert "style:font-name-complex" "Courier New" $ m
893+ Map.insert "style:font-name-complex" "Courier New" $ m
891− Language lang ->
894+ | Language lang <- s
892− Map.insert "fo:language" (langLanguage lang) .
895+ = Map.insert "fo:language" (langLanguage lang) .
893− maybe id (Map.insert "fo:country") (langRegion lang) $ m
896+ Map.insert "fo:country" (langRegion lang) $ m
897+ | otherwise = m
894
898
895withLangFromAttr :: PandocMonad m => Attr -> OD m a -> OD m a
899withLangFromAttr :: PandocMonad m => Attr -> OD m a -> OD m a
896withLangFromAttr (_,_,kvs) action =
900withLangFromAttr (_,_,kvs) action =
897 case lookup "lang" kvs of
901 case lookup "lang" kvs of
898 Nothing -> action
902 Nothing -> action
899 Just l ->
903 Just l ->
900− case parseLang l of
904+ case parseBCP47 l of
901 Right lang -> withTextStyle (Language lang) action
905 Right lang -> withTextStyle (Language lang) action
902 Left _ -> do
906 Left _ -> do
903 report $ InvalidLang l
907 report $ InvalidLang l
src/Text/Pandoc/Writers/Org.hs−2
@@ -407,8 +407,6 @@ inlineToOrg (Math t str) = do
407 then "\\(" <> literal str <> "\\)"
407 then "\\(" <> literal str <> "\\)"
408 else "\\[" <> literal str <> "\\]"
408 else "\\[" <> literal str <> "\\]"
409inlineToOrg il@(RawInline f str)
409inlineToOrg il@(RawInline f str)
410− | elem f ["tex", "latex"] && T.isPrefixOf "\\begin" str =
411− return $ cr <> literal str <> cr
412 | isRawFormat f = return $ literal str
410 | isRawFormat f = return $ literal str
413 | otherwise = do
411 | otherwise = do
414 report $ InlineNotRendered il
412 report $ InlineNotRendered il
src/Text/Pandoc/Writers/Powerpoint/Output.hs−1
@@ -537,7 +537,6 @@ registerMedia fp caption = do
537 Just Eps -> Just ".eps"
537 Just Eps -> Just ".eps"
538 Just Svg -> Just ".svg"
538 Just Svg -> Just ".svg"
539 Just Emf -> Just ".emf"
539 Just Emf -> Just ".emf"
540− Just Tiff -> Just ".tiff"
541 Nothing -> Nothing
540 Nothing -> Nothing
542
541
543 let newGlobalId = fromMaybe (maxGlobalId + 1) (M.lookup fp globalIds)
542 let newGlobalId = fromMaybe (maxGlobalId + 1) (M.lookup fp globalIds)
src/Text/Pandoc/Writers/Shared.hs−15
@@ -20,7 +20,6 @@ module Text.Pandoc.Writers.Shared (
20 , setField
20 , setField
21 , resetField
21 , resetField
22 , defField
22 , defField
23− , getLang
24 , tagWithAttrs
23 , tagWithAttrs
25 , isDisplayMath
24 , isDisplayMath
26 , fixDisplayMath
25 , fixDisplayMath
@@ -148,19 +147,6 @@ defField field val (Context m) =
148 where
147 where
149 f _newval oldval = oldval
148 f _newval oldval = oldval
150
149
151−-- | Get the contents of the `lang` metadata field or variable.
152−getLang :: WriterOptions -> Meta -> Maybe T.Text
153−getLang opts meta =
154− case lookupContext "lang" (writerVariables opts) of
155− Just s -> Just s
156− _ ->
157− case lookupMeta "lang" meta of
158− Just (MetaBlocks [Para [Str s]]) -> Just s
159− Just (MetaBlocks [Plain [Str s]]) -> Just s
160− Just (MetaInlines [Str s]) -> Just s
161− Just (MetaString s) -> Just s
162− _ -> Nothing
163−
164-- | Produce an HTML tag with the given pandoc attributes.
150-- | Produce an HTML tag with the given pandoc attributes.
165tagWithAttrs :: HasChars a => T.Text -> Attr -> Doc a
151tagWithAttrs :: HasChars a => T.Text -> Attr -> Doc a
166tagWithAttrs tag (ident,classes,kvs) = hsep
152tagWithAttrs tag (ident,classes,kvs) = hsep
@@ -394,7 +380,6 @@ toSuperscript '2' = Just '\x00B2'
394toSuperscript '3' = Just '\x00B3'
380toSuperscript '3' = Just '\x00B3'
395toSuperscript '+' = Just '\x207A'
381toSuperscript '+' = Just '\x207A'
396toSuperscript '-' = Just '\x207B'
382toSuperscript '-' = Just '\x207B'
397−toSuperscript '\x2212' = Just '\x207B' -- unicode minus
398toSuperscript '=' = Just '\x207C'
383toSuperscript '=' = Just '\x207C'
399toSuperscript '(' = Just '\x207D'
384toSuperscript '(' = Just '\x207D'
400toSuperscript ')' = Just '\x207E'
385toSuperscript ')' = Just '\x207E'
src/Text/Pandoc/Writers/TEI.hs+3−4
@@ -146,17 +146,16 @@ blockToTEI opts (LineBlock lns) =
146 blockToTEI opts $ linesToPara lns
146 blockToTEI opts $ linesToPara lns
147blockToTEI opts (BlockQuote blocks) =
147blockToTEI opts (BlockQuote blocks) =
148 inTagsIndented "quote" <$> blocksToTEI opts blocks
148 inTagsIndented "quote" <$> blocksToTEI opts blocks
149−blockToTEI opts (CodeBlock (_,classes,_) str) =
149+blockToTEI _ (CodeBlock (_,classes,_) str) =
150 return $ literal ("<ab type='codeblock " <> lang <> "'>") <> cr <>
150 return $ literal ("<ab type='codeblock " <> lang <> "'>") <> cr <>
151 flush (literal (escapeStringForXML str) <> cr <> text "</ab>")
151 flush (literal (escapeStringForXML str) <> cr <> text "</ab>")
152 where lang = if null langs
152 where lang = if null langs
153 then ""
153 then ""
154 else escapeStringForXML (head langs)
154 else escapeStringForXML (head langs)
155− syntaxMap = writerSyntaxMap opts
156− isLang l = T.toLower l `elem` map T.toLower (languages syntaxMap)
155+ isLang l = T.toLower l `elem` map T.toLower languages
157 langsFrom s = if isLang s
156 langsFrom s = if isLang s
158 then [s]
157 then [s]
159− else (languagesByExtension syntaxMap) . T.toLower $ s
158+ else languagesByExtension . T.toLower $ s
160 langs = concatMap langsFrom classes
159 langs = concatMap langsFrom classes
161blockToTEI opts (BulletList lst) = do
160blockToTEI opts (BulletList lst) = do
162 let attribs = [("type", "unordered")]
161 let attribs = [("type", "unordered")]
src/Text/Pandoc/Writers/ZimWiki.hs+1−1
@@ -116,7 +116,7 @@ blockToZimWiki opts b@(RawBlock f str)
116blockToZimWiki _ HorizontalRule = return "\n----\n"
116blockToZimWiki _ HorizontalRule = return "\n----\n"
117
117
118blockToZimWiki opts (Header level _ inlines) = do
118blockToZimWiki opts (Header level _ inlines) = do
119− contents <- inlineListToZimWiki opts inlines
119+ contents <- inlineListToZimWiki opts $ removeFormatting inlines -- emphasis, links etc. not allowed in headers
120 let eqs = T.replicate ( 7 - level ) "="
120 let eqs = T.replicate ( 7 - level ) "="
121 return $ eqs <> " " <> contents <> " " <> eqs <> "\n"
121 return $ eqs <> " " <> contents <> " " <> eqs <> "\n"
122
122
src/Text/Pandoc/XML/Light/Types.hs+4−4
@@ -53,7 +53,7 @@ type Line = Integer
53data Content = Elem Element
53data Content = Elem Element
54 | Text CData
54 | Text CData
55 | CRef Text
55 | CRef Text
56− deriving (Show, Typeable, Data, Ord, Eq)
56+ deriving (Show, Typeable, Data)
57
57
58-- | XML elements
58-- | XML elements
59data Element = Element {
59data Element = Element {
@@ -61,7 +61,7 @@ data Element = Element {
61 elAttribs :: [Attr],
61 elAttribs :: [Attr],
62 elContent :: [Content],
62 elContent :: [Content],
63 elLine :: Maybe Line
63 elLine :: Maybe Line
64− } deriving (Show, Typeable, Data, Ord, Eq)
64+ } deriving (Show, Typeable, Data)
65
65
66-- | XML attributes
66-- | XML attributes
67data Attr = Attr {
67data Attr = Attr {
@@ -74,13 +74,13 @@ data CData = CData {
74 cdVerbatim :: CDataKind,
74 cdVerbatim :: CDataKind,
75 cdData :: Text,
75 cdData :: Text,
76 cdLine :: Maybe Line
76 cdLine :: Maybe Line
77− } deriving (Show, Typeable, Data, Ord, Eq)
77+ } deriving (Show, Typeable, Data)
78
78
79data CDataKind
79data CDataKind
80 = CDataText -- ^ Ordinary character data; pretty printer escapes &, < etc.
80 = CDataText -- ^ Ordinary character data; pretty printer escapes &, < etc.
81 | CDataVerbatim -- ^ Unescaped character data; pretty printer embeds it in <![CDATA[..
81 | CDataVerbatim -- ^ Unescaped character data; pretty printer embeds it in <![CDATA[..
82 | CDataRaw -- ^ As-is character data; pretty printer passes it along without any escaping or CDATA wrap-up.
82 | CDataRaw -- ^ As-is character data; pretty printer passes it along without any escaping or CDATA wrap-up.
83− deriving ( Eq, Ord, Show, Typeable, Data )
83+ deriving ( Eq, Show, Typeable, Data )
84
84
85-- | XML qualified names
85-- | XML qualified names
86data QName = QName {
86data QName = QName {
stack.yaml+10−9
@@ -7,16 +7,17 @@ flags:
7packages:
7packages:
8- '.'
8- '.'
9extra-deps:
9extra-deps:
10−- commonmark-0.2.1
10+- hslua-1.3.0
11−- commonmark-pandoc-0.2.1.1
11+- hslua-module-path-0.1.0
12+- jira-wiki-markup-1.3.4
12−- skylighting-core-0.10.5.2
13+- skylighting-core-0.10.5.1
13−- skylighting-0.10.5.2
14+- skylighting-0.10.5.1
14−- git: https://github.com/jgm/doctemplates
15+- doclayout-0.3.0.2
15− commit: 428c26d5303cf7a2b1051fe1ffd9aafe9ba71c81
16−- git: https://github.com/jgm/citeproc
16+- citeproc-0.3.0.9
17− commit: 4ce0501cd6f9c86eee087afcf878c256e49b9615
17+- texmath-0.12.2
18+- random-1.2.0
18ghc-options:
19ghc-options:
19 "$locals": -fhide-source-paths -Wno-missing-home-modules
20 "$locals": -fhide-source-paths -Wno-missing-home-modules
20−resolver: lts-18.0
21+resolver: lts-17.5
21nix:
22nix:
22 packages: [zlib]
23 packages: [zlib]
test/Tests/Command.hs+1−4
@@ -130,7 +130,4 @@ extractCommandTest testExePath fp = unsafePerformIO $ do
130 def{ readerExtensions = pandocExtensions } contents)
130 def{ readerExtensions = pandocExtensions } contents)
131 let codeblocks = map extractCode $ filter isCodeBlock blocks
131 let codeblocks = map extractCode $ filter isCodeBlock blocks
132 let cases = zipWith (runCommandTest testExePath fp) [1..] codeblocks
132 let cases = zipWith (runCommandTest testExePath fp) [1..] codeblocks
133− return $ testGroup fp
133+ return $ testGroup fp cases
134− $ if null cases
135− then [testCase "!!" $ assertFailure "No command tests defined"]
136− else cases
test/Tests/Readers/Docx.hs+5−25
@@ -24,7 +24,7 @@ import Test.Tasty.HUnit
24import Tests.Helpers
24import Tests.Helpers
25import Text.Pandoc
25import Text.Pandoc
26import qualified Text.Pandoc.Class as P
26import qualified Text.Pandoc.Class as P
27−import qualified Text.Pandoc.MediaBag as MB
27+import Text.Pandoc.MediaBag (MediaBag, lookupMedia, mediaDirectory)
28import Text.Pandoc.UTF8 as UTF8
28import Text.Pandoc.UTF8 as UTF8
29
29
30-- We define a wrapper around pandoc that doesn't normalize in the
30-- We define a wrapper around pandoc that doesn't normalize in the
@@ -91,11 +91,11 @@ getMedia :: FilePath -> FilePath -> IO (Maybe B.ByteString)
91getMedia archivePath mediaPath = fmap fromEntry . findEntryByPath
91getMedia archivePath mediaPath = fmap fromEntry . findEntryByPath
92 ("word/" ++ mediaPath) . toArchive <$> B.readFile archivePath
92 ("word/" ++ mediaPath) . toArchive <$> B.readFile archivePath
93
93
94−compareMediaPathIO :: FilePath -> MB.MediaBag -> FilePath -> IO Bool
94+compareMediaPathIO :: FilePath -> MediaBag -> FilePath -> IO Bool
95compareMediaPathIO mediaPath mediaBag docxPath = do
95compareMediaPathIO mediaPath mediaBag docxPath = do
96 docxMedia <- getMedia docxPath mediaPath
96 docxMedia <- getMedia docxPath mediaPath
97− let mbBS = case MB.lookupMedia mediaPath mediaBag of
97+ let mbBS = case lookupMedia mediaPath mediaBag of
98− Just item -> MB.mediaContents item
98+ Just (_, bs) -> bs
99 Nothing -> error ("couldn't find " ++
99 Nothing -> error ("couldn't find " ++
100 mediaPath ++
100 mediaPath ++
101 " in media bag")
101 " in media bag")
@@ -110,7 +110,7 @@ compareMediaBagIO docxFile = do
110 mb <- runIOorExplode $ readDocx defopts df >> P.getMediaBag
110 mb <- runIOorExplode $ readDocx defopts df >> P.getMediaBag
111 bools <- mapM
111 bools <- mapM
112 (\(fp, _, _) -> compareMediaPathIO fp mb docxFile)
112 (\(fp, _, _) -> compareMediaPathIO fp mb docxFile)
113− (MB.mediaDirectory mb)
113+ (mediaDirectory mb)
114 return $ and bools
114 return $ and bools
115
115
116testMediaBagIO :: String -> FilePath -> IO TestTree
116testMediaBagIO :: String -> FilePath -> IO TestTree
@@ -155,10 +155,6 @@ tests = [ testGroup "document"
155 "VML image"
155 "VML image"
156 "docx/image_vml.docx"
156 "docx/image_vml.docx"
157 "docx/image_vml.native"
157 "docx/image_vml.native"
158− , testCompare
159− "VML image as object"
160− "docx/image_vml_as_object.docx"
161− "docx/image_vml_as_object.native"
162 , testCompare
158 , testCompare
163 "inline image in links"
159 "inline image in links"
164 "docx/inline_images.docx"
160 "docx/inline_images.docx"
@@ -317,30 +313,14 @@ tests = [ testGroup "document"
317 "tables with lists in cells"
313 "tables with lists in cells"
318 "docx/table_with_list_cell.docx"
314 "docx/table_with_list_cell.docx"
319 "docx/table_with_list_cell.native"
315 "docx/table_with_list_cell.native"
320− , testCompare
321− "a table with a header which contains rowspans greater than 1"
322− "docx/table_header_rowspan.docx"
323− "docx/table_header_rowspan.native"
324 , testCompare
316 , testCompare
325 "tables with one row"
317 "tables with one row"
326 "docx/table_one_row.docx"
318 "docx/table_one_row.docx"
327 "docx/table_one_row.native"
319 "docx/table_one_row.native"
328− , testCompare
329− "tables with just one row, which is a header"
330− "docx/table_one_header_row.docx"
331− "docx/table_one_header_row.native"
332 , testCompare
320 , testCompare
333 "tables with variable width"
321 "tables with variable width"
334 "docx/table_variable_width.docx"
322 "docx/table_variable_width.docx"
335 "docx/table_variable_width.native"
323 "docx/table_variable_width.native"
336− , testCompare
337− "tables with captions which contain a Table field"
338− "docx/table_captions_with_field.docx"
339− "docx/table_captions_with_field.native"
340− , testCompare
341− "tables with captions which don't contain a Table field"
342− "docx/table_captions_no_field.docx"
343− "docx/table_captions_no_field.native"
344 , testCompare
324 , testCompare
345 "code block"
325 "code block"
346 "docx/codeblock.docx"
326 "docx/codeblock.docx"
test/Tests/Readers/EPUB.hs+1−1
@@ -47,7 +47,7 @@ featuresBag = [("img/check.gif","image/gif",1340)
47
47
48-- with additional meta tag for cover in EPUB2 format
48-- with additional meta tag for cover in EPUB2 format
49epub3CoverBag :: [(String, String, Int)]
49epub3CoverBag :: [(String, String, Int)]
50−epub3CoverBag = [("wasteland-cover.jpg","image/jpeg", 16586)]
50+epub3CoverBag = [("wasteland-cover.jpg","image/jpeg",103477)]
51
51
52epub3NoCoverBag :: [(String, String, Int)]
52epub3NoCoverBag :: [(String, String, Int)]
53epub3NoCoverBag = [("img/check.gif","image/gif",1340)
53epub3NoCoverBag = [("img/check.gif","image/gif",1340)
test/Tests/Readers/HTML.hs+5−20
@@ -99,26 +99,11 @@ tests = [ testGroup "base tag"
99 plain (codeWith ("",["sample"],[]) "Answer is 42")
99 plain (codeWith ("",["sample"],[]) "Answer is 42")
100 ]
100 ]
101 , testGroup "var"
101 , testGroup "var"
102+ [
102− [ test html "inline var block" $
103+ test html "inline var block" $
103− "<var>result</var>" =?>
104+ "<var>result</var>" =?>
104− plain (codeWith ("",["variable"],[]) "result")
105+ plain (codeWith ("",["variable"],[]) "result")
105− ]
106− , testGroup "header"
107− [ test htmlNativeDivs "<header> is parsed as a div" $
108− "<header id=\"title\">Title</header>" =?>
109− divWith ("title", mempty, mempty) (plain "Title")
110− ]
111− , testGroup "code block"
112− [ test html "attributes in pre > code element" $
113− "<pre><code id=\"a\" class=\"python\">\nprint('hi')\n</code></pre>"
114− =?>
115− codeBlockWith ("a", ["python"], []) "print('hi')"
116−
117− , test html "attributes in pre take precendence" $
118− "<pre id=\"c\"><code id=\"d\">\nprint('hi mom!')\n</code></pre>"
119− =?>
120− codeBlockWith ("c", [], []) "print('hi mom!')"
121− ]
106+ ]
122 , askOption $ \(QuickCheckTests numtests) ->
107 , askOption $ \(QuickCheckTests numtests) ->
123 testProperty "Round trip" $
108 testProperty "Round trip" $
124 withMaxSuccess (if QuickCheckTests numtests == defaultValue
109 withMaxSuccess (if QuickCheckTests numtests == defaultValue
test/Tests/Readers/Jira.hs−8
@@ -167,14 +167,6 @@ tests =
167 , "user with description" =:
167 , "user with description" =:
168 "[John Doe|~johndoe]" =?>
168 "[John Doe|~johndoe]" =?>
169 para (linkWith ("", ["user-account"], []) "~johndoe" "" "John Doe")
169 para (linkWith ("", ["user-account"], []) "~johndoe" "" "John Doe")
170−
171− , "'smart' link" =:
172− "[x|http://example.com|smart-link]" =?>
173− para (linkWith ("", ["smart-link"], []) "http://example.com" "" "x")
174−
175− , "'smart' card" =:
176− "[x|http://example.com|smart-card]" =?>
177− para (linkWith ("", ["smart-card"], []) "http://example.com" "" "x")
178 ]
170 ]
179
171
180 , "image" =:
172 , "image" =:
test/Tests/Readers/Markdown.hs+3−3
@@ -358,7 +358,7 @@ tests = [ testGroup "inline code"
358 para (text "The value of the " <> math "x" <> text "\8217s and the systems\8217 condition.")
358 para (text "The value of the " <> math "x" <> text "\8217s and the systems\8217 condition.")
359 , test markdownSmart "unclosed double quote"
359 , test markdownSmart "unclosed double quote"
360 ("**this should \"be bold**"
360 ("**this should \"be bold**"
361− =?> para (strong "this should \8220be bold"))
361+ =?> para (strong "this should \"be bold"))
362 ]
362 ]
363 , testGroup "footnotes"
363 , testGroup "footnotes"
364 [ "indent followed by newline and flush-left text" =:
364 [ "indent followed by newline and flush-left text" =:
@@ -374,8 +374,8 @@ tests = [ testGroup "inline code"
374 , testGroup "lhs"
374 , testGroup "lhs"
375 [ test (purely $ readMarkdown def{ readerExtensions = enableExtension
375 [ test (purely $ readMarkdown def{ readerExtensions = enableExtension
376 Ext_literate_haskell pandocExtensions })
376 Ext_literate_haskell pandocExtensions })
377− "inverse bird tracks and html"
377+ "inverse bird tracks and html" $
378− $ ("> a\n\n< b\n\n<div>\n" :: Text)
378+ "> a\n\n< b\n\n<div>\n"
379 =?> codeBlockWith ("",["haskell","literate"],[]) "a"
379 =?> codeBlockWith ("",["haskell","literate"],[]) "a"
380 <>
380 <>
381 codeBlockWith ("",["haskell"],[]) "b"
381 codeBlockWith ("",["haskell"],[]) "b"
test/Tests/Writers/ConTeXt.hs+113−122
@@ -39,125 +39,116 @@ infix 4 =:
39(=:) = test context
39(=:) = test context
40
40
41tests :: [TestTree]
41tests :: [TestTree]
42−tests =
43− [ testGroup "inline code"
42+tests = [ testGroup "inline code"
44− [ "with '}'" =: code "}" =?> "\\mono{\\}}"
43+ [ "with '}'" =: code "}" =?> "\\mono{\\}}"
45− , "without '}'" =: code "]" =?> "\\type{]}"
44+ , "without '}'" =: code "]" =?> "\\type{]}"
46− , "span with ID" =:
47− spanWith ("city", [], []) "Berlin" =?>
48− "\\reference[city]{}Berlin"
49− , testProperty "code property" $ \s -> null s || '\n' `elem` s ||
45+ , testProperty "code property" $ \s -> null s || '\n' `elem` s ||
50− if '{' `elem` s || '}' `elem` s
46+ if '{' `elem` s || '}' `elem` s
51− then context' (code $ pack s) == "\\mono{" ++
47+ then context' (code $ pack s) == "\\mono{" ++
52− context' (str $ pack s) ++ "}"
48+ context' (str $ pack s) ++ "}"
53− else context' (code $ pack s) == "\\type{" ++ s ++ "}"
49+ else context' (code $ pack s) == "\\type{" ++ s ++ "}"
54− ]
50+ ]
55− , testGroup "headers"
51+ , testGroup "headers"
56− [ "level 1" =:
52+ [ "level 1" =:
57− headerWith ("my-header",[],[]) 1 "My header" =?>
58− "\\section[title={My header},reference={my-header}]"
53+ headerWith ("my-header",[],[]) 1 "My header" =?> "\\section[title={My header},reference={my-header}]"
59− , test contextDiv "section-divs" $
54+ , test contextDiv "section-divs" $
60− ( headerWith ("header1", [], []) 1 (text "Header1")
55+ ( headerWith ("header1", [], []) 1 (text "Header1")
61− <> headerWith ("header2", [], []) 2 (text "Header2")
56+ <> headerWith ("header2", [], []) 2 (text "Header2")
62− <> headerWith ("header3", [], []) 3 (text "Header3")
57+ <> headerWith ("header3", [], []) 3 (text "Header3")
63− <> headerWith ("header4", [], []) 4 (text "Header4")
58+ <> headerWith ("header4", [], []) 4 (text "Header4")
64− <> headerWith ("header5", [], []) 5 (text "Header5")
59+ <> headerWith ("header5", [], []) 5 (text "Header5")
65− <> headerWith ("header6", [], []) 6 (text "Header6"))
60+ <> headerWith ("header6", [], []) 6 (text "Header6"))
66− =?>
61+ =?>
67− unlines
68− [ "\\startsection[title={Header1},reference={header1}]\n"
62+ unlines [ "\\startsection[title={Header1},reference={header1}]\n"
69− , "\\startsubsection[title={Header2},reference={header2}]\n"
63+ , "\\startsubsection[title={Header2},reference={header2}]\n"
70− , "\\startsubsubsection[title={Header3},reference={header3}]\n"
64+ , "\\startsubsubsection[title={Header3},reference={header3}]\n"
71− , "\\startsubsubsubsection[title={Header4},reference={header4}]\n"
65+ , "\\startsubsubsubsection[title={Header4},reference={header4}]\n"
72− , "\\startsubsubsubsubsection[title={Header5},reference={header5}]\n"
66+ , "\\startsubsubsubsubsection[title={Header5},reference={header5}]\n"
73− , "\\startsubsubsubsubsubsection[title={Header6},reference={header6}]\n"
67+ , "\\startsubsubsubsubsubsection[title={Header6},reference={header6}]\n"
74− , "\\stopsubsubsubsubsubsection\n"
68+ , "\\stopsubsubsubsubsubsection\n"
75− , "\\stopsubsubsubsubsection\n"
69+ , "\\stopsubsubsubsubsection\n"
76− , "\\stopsubsubsubsection\n"
70+ , "\\stopsubsubsubsection\n"
77− , "\\stopsubsubsection\n"
71+ , "\\stopsubsubsection\n"
78− , "\\stopsubsection\n"
72+ , "\\stopsubsection\n"
79− , "\\stopsection" ]
73+ , "\\stopsection" ]
80− ]
74+ ]
81− , testGroup "bullet lists"
75+ , testGroup "bullet lists"
82− [ "nested" =:
76+ [ "nested" =:
83− bulletList [
77+ bulletList [
84− plain (text "top")
78+ plain (text "top")
85− <> bulletList [
79+ <> bulletList [
86− plain (text "next")
80+ plain (text "next")
87− <> bulletList [plain (text "bot")]
81+ <> bulletList [plain (text "bot")]
88− ]
82+ ]
89− ] =?> unlines
83+ ] =?> unlines
90− [ "\\startitemize[packed]"
84+ [ "\\startitemize[packed]"
91− , "\\item"
85+ , "\\item"
92− , " top"
86+ , " top"
93− , " \\startitemize[packed]"
87+ , " \\startitemize[packed]"
94− , " \\item"
88+ , " \\item"
95− , " next"
89+ , " next"
96− , " \\startitemize[packed]"
90+ , " \\startitemize[packed]"
97− , " \\item"
91+ , " \\item"
98− , " bot"
92+ , " bot"
99− , " \\stopitemize"
93+ , " \\stopitemize"
100− , " \\stopitemize"
94+ , " \\stopitemize"
101− , "\\stopitemize" ]
95+ , "\\stopitemize" ]
102− ]
96+ ]
103− , testGroup "natural tables"
97+ , testGroup "natural tables"
104− [ test contextNtb "table with header and caption" $
98+ [ test contextNtb "table with header and caption" $
105− let capt = text "Table 1"
99+ let capt = text "Table 1"
106− aligns = [ (AlignRight, ColWidthDefault)
100+ aligns = [(AlignRight, ColWidthDefault), (AlignLeft, ColWidthDefault), (AlignCenter, ColWidthDefault), (AlignDefault, ColWidthDefault)]
107− , (AlignLeft, ColWidthDefault)
108− , (AlignCenter, ColWidthDefault)
109− , (AlignDefault, ColWidthDefault) ]
110− headers = [plain $ text "Right",
101+ headers = [plain $ text "Right",
111− plain $ text "Left",
102+ plain $ text "Left",
112− plain $ text "Center",
103+ plain $ text "Center",
113− plain $ text "Default"]
104+ plain $ text "Default"]
114− rows = [[plain $ text "1.1",
105+ rows = [[plain $ text "1.1",
115− plain $ text "1.2",
106+ plain $ text "1.2",
116− plain $ text "1.3",
107+ plain $ text "1.3",
117− plain $ text "1.4"]
108+ plain $ text "1.4"]
118− ,[plain $ text "2.1",
109+ ,[plain $ text "2.1",
119− plain $ text "2.2",
110+ plain $ text "2.2",
120− plain $ text "2.3",
111+ plain $ text "2.3",
121− plain $ text "2.4"]
112+ plain $ text "2.4"]
122− ,[plain $ text "3.1",
113+ ,[plain $ text "3.1",
123− plain $ text "3.2",
114+ plain $ text "3.2",
124− plain $ text "3.3",
115+ plain $ text "3.3",
125− plain $ text "3.4"]]
116+ plain $ text "3.4"]]
126− toRow = Row nullAttr . map simpleCell
117+ toRow = Row nullAttr . map simpleCell
127− in table (simpleCaption $ plain capt)
118+ in table (simpleCaption $ plain capt)
128− aligns
119+ aligns
129− (TableHead nullAttr [toRow headers])
120+ (TableHead nullAttr [toRow headers])
130− [TableBody nullAttr 0 [] $ map toRow rows]
121+ [TableBody nullAttr 0 [] $ map toRow rows]
131− (TableFoot nullAttr [])
122+ (TableFoot nullAttr [])
132− =?> unlines [ "\\startplacetable[title={Table 1}]"
123+ =?> unlines [ "\\startplacetable[title={Table 1}]"
133− , "\\startTABLE"
124+ , "\\startTABLE"
134− , "\\startTABLEhead"
125+ , "\\startTABLEhead"
135− , "\\NC[align=left] Right"
126+ , "\\NC[align=left] Right"
136− , "\\NC[align=right] Left"
127+ , "\\NC[align=right] Left"
137− , "\\NC[align=middle] Center"
128+ , "\\NC[align=middle] Center"
138− , "\\NC Default"
129+ , "\\NC Default"
139− , "\\NC\\NR"
130+ , "\\NC\\NR"
140− , "\\stopTABLEhead"
131+ , "\\stopTABLEhead"
141− , "\\startTABLEbody"
132+ , "\\startTABLEbody"
142− , "\\NC[align=left] 1.1"
133+ , "\\NC[align=left] 1.1"
143− , "\\NC[align=right] 1.2"
134+ , "\\NC[align=right] 1.2"
144− , "\\NC[align=middle] 1.3"
135+ , "\\NC[align=middle] 1.3"
145− , "\\NC 1.4"
136+ , "\\NC 1.4"
146− , "\\NC\\NR"
137+ , "\\NC\\NR"
147− , "\\NC[align=left] 2.1"
138+ , "\\NC[align=left] 2.1"
148− , "\\NC[align=right] 2.2"
139+ , "\\NC[align=right] 2.2"
149− , "\\NC[align=middle] 2.3"
140+ , "\\NC[align=middle] 2.3"
150− , "\\NC 2.4"
141+ , "\\NC 2.4"
151− , "\\NC\\NR"
142+ , "\\NC\\NR"
152− , "\\stopTABLEbody"
143+ , "\\stopTABLEbody"
153− , "\\startTABLEfoot"
144+ , "\\startTABLEfoot"
154− , "\\NC[align=left] 3.1"
145+ , "\\NC[align=left] 3.1"
155− , "\\NC[align=right] 3.2"
146+ , "\\NC[align=right] 3.2"
156− , "\\NC[align=middle] 3.3"
147+ , "\\NC[align=middle] 3.3"
157− , "\\NC 3.4"
148+ , "\\NC 3.4"
158− , "\\NC\\NR"
149+ , "\\NC\\NR"
159− , "\\stopTABLEfoot"
150+ , "\\stopTABLEfoot"
160− , "\\stopTABLE"
151+ , "\\stopTABLE"
161− , "\\stopplacetable" ]
152+ , "\\stopplacetable" ]
162− ]
153+ ]
163− ]
154+ ]
test/Tests/Writers/Docbook.hs+6−6
@@ -83,32 +83,32 @@ tests = [ testGroup "line blocks"
83 , "</warning>"
83 , "</warning>"
84 ]
84 ]
85 , "admonition-with-title" =:
85 , "admonition-with-title" =:
86− divWith ("foo", ["note"], []) (
86+ divWith ("foo", ["attention"], []) (
87 divWith ("foo", ["title"], [])
87 divWith ("foo", ["title"], [])
88 (plain (text "This is title")) <>
88 (plain (text "This is title")) <>
89 para "This is a test"
89 para "This is a test"
90 )
90 )
91 =?> unlines
91 =?> unlines
92− [ "<note id=\"foo\">"
92+ [ "<attention id=\"foo\">"
93 , " <title>This is title</title>"
93 , " <title>This is title</title>"
94 , " <para>"
94 , " <para>"
95 , " This is a test"
95 , " This is a test"
96 , " </para>"
96 , " </para>"
97− , "</note>"
97+ , "</attention>"
98 ]
98 ]
99 , "admonition-with-title-in-para" =:
99 , "admonition-with-title-in-para" =:
100− divWith ("foo", ["note"], []) (
100+ divWith ("foo", ["attention"], []) (
101 divWith ("foo", ["title"], [])
101 divWith ("foo", ["title"], [])
102 (para "This is title") <>
102 (para "This is title") <>
103 para "This is a test"
103 para "This is a test"
104 )
104 )
105 =?> unlines
105 =?> unlines
106− [ "<note id=\"foo\">"
106+ [ "<attention id=\"foo\">"
107 , " <title>This is title</title>"
107 , " <title>This is title</title>"
108 , " <para>"
108 , " <para>"
109 , " This is a test"
109 , " This is a test"
110 , " </para>"
110 , " </para>"
111− , "</note>"
111+ , "</attention>"
112 ]
112 ]
113 , "single-child" =:
113 , "single-child" =:
114 divWith ("foo", [], []) (para "This is a test")
114 divWith ("foo", [], []) (para "This is a test")
test/Tests/Writers/Docx.hs−5
@@ -111,11 +111,6 @@ tests = [ testGroup "inlines"
111 def
111 def
112 "docx/tables.native"
112 "docx/tables.native"
113 "docx/golden/tables.docx"
113 "docx/golden/tables.docx"
114− , docxTest
115− "tables without explicit column widths"
116− def
117− "docx/tables-default-widths.native"
118− "docx/golden/tables-default-widths.docx"
119 , docxTest
114 , docxTest
120 "tables with lists in cells"
115 "tables with lists in cells"
121 def
116 def
test/Tests/Writers/HTML.hs+52−57
@@ -34,60 +34,55 @@ infix 4 =:
34(=:) = test html
34(=:) = test html
35
35
36tests :: [TestTree]
36tests :: [TestTree]
37−tests =
38− [ testGroup "inline code"
37+tests = [ testGroup "inline code"
39− [ "basic" =: code "@&" =?> "<code>@&amp;</code>"
38+ [ "basic" =: code "@&" =?> "<code>@&amp;</code>"
40− , "haskell" =: codeWith ("",["haskell"],[]) ">>="
39+ , "haskell" =: codeWith ("",["haskell"],[]) ">>="
41− =?> "<code class=\"sourceCode haskell\"><span class=\"op\">&gt;&gt;=</span></code>"
40+ =?> "<code class=\"sourceCode haskell\"><span class=\"op\">&gt;&gt;=</span></code>"
42− , "nolanguage" =: codeWith ("",["nolanguage"],[]) ">>="
41+ , "nolanguage" =: codeWith ("",["nolanguage"],[]) ">>="
43− =?> "<code class=\"nolanguage\">&gt;&gt;=</code>"
42+ =?> "<code class=\"nolanguage\">&gt;&gt;=</code>"
44− ]
43+ ]
45− , testGroup "images"
44+ , testGroup "images"
46− [ "alt with formatting" =:
45+ [ "alt with formatting" =:
47− image "/url" "title" ("my " <> emph "image")
46+ image "/url" "title" ("my " <> emph "image")
48− =?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"
47+ =?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"
49− ]
48+ ]
50− , testGroup "blocks"
49+ , testGroup "blocks"
51− [ "definition list with empty <dt>" =:
50+ [ "definition list with empty <dt>" =:
52− definitionList [(mempty, [para $ text "foo bar"])]
51+ definitionList [(mempty, [para $ text "foo bar"])]
53− =?> "<dl><dt></dt><dd><p>foo bar</p></dd></dl>"
52+ =?> "<dl><dt></dt><dd><p>foo bar</p></dd></dl>"
54− , "heading with disallowed attributes" =:
53+ ]
55− headerWith ("", [], [("invalid","1"), ("lang", "en")]) 1 "test"
56− =?>
57− "<h1 lang=\"en\">test</h1>"
58− ]
59− , testGroup "quotes"
54+ , testGroup "quotes"
60− [ "quote with cite attribute (without q-tags)" =:
55+ [ "quote with cite attribute (without q-tags)" =:
61− doubleQuoted (spanWith ("", [], [("cite", "http://example.org")]) (str "examples"))
56+ doubleQuoted (spanWith ("", [], [("cite", "http://example.org")]) (str "examples"))
62− =?> "“<span cite=\"http://example.org\">examples</span>”"
57+ =?> "“<span cite=\"http://example.org\">examples</span>”"
63− , tQ "quote with cite attribute (with q-tags)" $
58+ , tQ "quote with cite attribute (with q-tags)" $
64− doubleQuoted (spanWith ("", [], [("cite", "http://example.org")]) (str "examples"))
59+ doubleQuoted (spanWith ("", [], [("cite", "http://example.org")]) (str "examples"))
65− =?> "<q cite=\"http://example.org\">examples</q>"
60+ =?> "<q cite=\"http://example.org\">examples</q>"
66− ]
61+ ]
67− , testGroup "sample"
62+ , testGroup "sample"
68− [ "sample should be rendered correctly" =:
63+ [ "sample should be rendered correctly" =:
69− plain (codeWith ("",["sample"],[]) "Answer is 42") =?>
64+ plain (codeWith ("",["sample"],[]) "Answer is 42") =?>
70− "<samp>Answer is 42</samp>"
65+ "<samp>Answer is 42</samp>"
71− ]
66+ ]
72− , testGroup "variable"
67+ , testGroup "variable"
73− [ "variable should be rendered correctly" =:
68+ [ "variable should be rendered correctly" =:
74− plain (codeWith ("",["variable"],[]) "result") =?>
69+ plain (codeWith ("",["variable"],[]) "result") =?>
75− "<var>result</var>"
70+ "<var>result</var>"
76− ]
71+ ]
77− , testGroup "sample with style"
72+ , testGroup "sample with style"
78− [ "samp should wrap highlighted code" =:
73+ [ "samp should wrap highlighted code" =:
79− codeWith ("",["sample","haskell"],[]) ">>="
74+ codeWith ("",["sample","haskell"],[]) ">>="
80− =?> ("<samp><code class=\"sourceCode haskell\">" ++
75+ =?> ("<samp><code class=\"sourceCode haskell\">" ++
81− "<span class=\"op\">&gt;&gt;=</span></code></samp>")
76+ "<span class=\"op\">&gt;&gt;=</span></code></samp>")
82− ]
77+ ]
83− , testGroup "variable with style"
78+ , testGroup "variable with style"
84− [ "var should wrap highlighted code" =:
79+ [ "var should wrap highlighted code" =:
85− codeWith ("",["haskell","variable"],[]) ">>="
80+ codeWith ("",["haskell","variable"],[]) ">>="
86− =?> ("<var><code class=\"sourceCode haskell\">" ++
81+ =?> ("<var><code class=\"sourceCode haskell\">" ++
87− "<span class=\"op\">&gt;&gt;=</span></code></var>")
82+ "<span class=\"op\">&gt;&gt;=</span></code></var>")
88− ]
83+ ]
89− ]
84+ ]
90− where
85+ where
91− tQ :: (ToString a, ToPandoc a)
86+ tQ :: (ToString a, ToPandoc a)
92− => String -> (a, String) -> TestTree
87+ => String -> (a, String) -> TestTree
93− tQ = test htmlQTags
88+ tQ = test htmlQTags
test/Tests/Writers/JATS.hs+5−9
@@ -148,17 +148,13 @@ tests =
148 spanWith nullAttr "text in span" =?>
148 spanWith nullAttr "text in span" =?>
149 "<p>text in span</p>"
149 "<p>text in span</p>"
150
150
151− , "converted to named-content element if class given" =:
151+ , "converted to named-content element" =:
152− spanWith ("a", ["genus-species"], [("alt", "aa")]) "C. elegans" =?>
152+ spanWith ("a", ["ignored"], [("alt", "aa")]) "text" =?>
153− ("<p><named-content id=\"a\" alt=\"aa\" content-type=\"genus-species\">"
153+ "<p><named-content id=\"a\" alt=\"aa\">text</named-content></p>"
154− <> "C. elegans</named-content></p>")
155
154
156− , "unwrapped if styled-content element would have no attributes" =:
155+ , "unwrapped if named-content element would have no attributes" =:
157− spanWith ("", [], [("hidden", "true")]) "text in span" =?>
156+ spanWith ("", ["ignored"], [("hidden", "true")]) "text in span" =?>
158 "<p>text in span</p>"
157 "<p>text in span</p>"
159
158
160− , "use content-type attribute if present" =:
161− spanWith ("", [], [("content-type", "species")]) "E. coli" =?>
162− "<p><named-content content-type=\"species\">E. coli</named-content></p>"
163 ]
159 ]
164 ]
160 ]
test/Tests/Writers/Jira.hs−12
@@ -61,24 +61,12 @@ tests =
61 , "user link with user as description" =:
61 , "user link with user as description" =:
62 linkWith ("", ["user-account"], []) "~johndoe" "" "~johndoe" =?>
62 linkWith ("", ["user-account"], []) "~johndoe" "" "~johndoe" =?>
63 "[~johndoe]"
63 "[~johndoe]"
64−
65− , "'smart' link" =:
66− para (linkWith ("", ["smart-link"], []) "http://example.com" "" "x") =?>
67− "[x|http://example.com|smart-link]"
68−
69− , "'smart' card" =:
70− para (linkWith ("", ["smart-card"], []) "http://example.org" "" "x") =?>
71− "[x|http://example.org|smart-card]"
72 ]
64 ]
73
65
74 , testGroup "spans"
66 , testGroup "spans"
75 [ "id is used as anchor" =:
67 [ "id is used as anchor" =:
76 spanWith ("unicorn", [], []) (str "Unicorn") =?>
68 spanWith ("unicorn", [], []) (str "Unicorn") =?>
77 "{anchor:unicorn}Unicorn"
69 "{anchor:unicorn}Unicorn"
78−
79− , "use `color` attribute" =:
80− spanWith ("",[],[("color","red")]) "ruby" =?>
81− "{color:red}ruby{color}"
82 ]
70 ]
83
71
84 , testGroup "code"
72 , testGroup "code"
test/Tests/Writers/OOXML.hs+1−3
@@ -55,9 +55,7 @@ testArchive :: (WriterOptions -> Pandoc -> PandocIO BL.ByteString)
55 -> IO Archive
55 -> IO Archive
56testArchive writerFn opts fp = do
56testArchive writerFn opts fp = do
57 txt <- T.readFile fp
57 txt <- T.readFile fp
58− bs <- runIOorExplode $ do
59− setTranslations "en-US"
60− readNative def txt >>= writerFn opts
58+ bs <- runIOorExplode $ readNative def txt >>= writerFn opts
61 return $ toArchive bs
59 return $ toArchive bs
62
60
63compareFileList :: FilePath -> Archive -> Archive -> Maybe String
61compareFileList :: FilePath -> Archive -> Archive -> Maybe String
test/command/1279.md+1−1
@@ -9,7 +9,7 @@ title: My Article
9[^1]: Dept. of This and That
9[^1]: Dept. of This and That
10^D
10^D
11---
11---
12−author: John Doe[^1]
12+author: "John Doe[^1]"
13date: 2014
13date: 2014
14title: My Article
14title: My Article
15---
15---
test/command/2103.mddeleted−8
@@ -1,8 +0,0 @@
1−```
2−pandoc -t latex
3−| A happy pandoc user said "fix this bug please
4−| or I'll go crazy!"
5−^D
6−A happy pandoc user said ``fix this bug please\\
7−or I'll go crazy!''
8−```
test/command/2874.md+2−2
@@ -3,12 +3,12 @@
3<a></a>
3<a></a>
4<br/>
4<br/>
5^D
5^D
6−{}\strut \\
6+{}~\\
7```
7```
8
8
9```
9```
10% pandoc -f html -t latex
10% pandoc -f html -t latex
11<a name="foo"></a><br/>
11<a name="foo"></a><br/>
12^D
12^D
13−\protect\hypertarget{foo}{}{}\strut \\
13+\protect\hypertarget{foo}{}{}~\\
14```
14```
test/command/3752.mddeleted−60
@@ -1,60 +0,0 @@
1−```
2−% pandoc command/chap1/text.md command/chap2/text.md -f markdown+rebase_relative_paths --verbose -t docx -o - | pandoc -f docx -t plain
3−^D
4−[INFO] Loaded command/chap1/spider.png from command/chap1/spider.png
5−[INFO] Loaded command/chap2/spider.png from command/chap2/spider.png
6−[INFO] Loaded command/chap1/../../lalune.jpg from command/chap1/../../lalune.jpg
7−Chapter one
8−
9−A spider: [spider]
10−
11−Another spider: [another spider]
12−
13−The moon: [moon]
14−
15−Link to spider picture.
16−
17−URL left alone: manual.
18−
19−Absolute path left alone: absolute.
20−
21−Link to fragment: chapter two.
22−
23−Empty path: empty.
24−
25−Chapter two
26−
27−A spider: [spider]
28−```
29−
30−```
31−% pandoc command/chap1/text.md command/chap2/text.md -f markdown+rebase_relative_paths -t html
32−^D
33−<h1 id="chapter-one">Chapter one</h1>
34−<p>A spider: <img src="command/chap1/spider.png" alt="spider" /></p>
35−<p>Another spider: <img src="command/chap2/spider.png" alt="another spider" /></p>
36−<p>The moon: <img src="command/chap1/../../lalune.jpg" alt="moon" /></p>
37−<p>Link to <a href="command/chap1/spider.png">spider picture</a>.</p>
38−<p>URL left alone: <a href="https://pandoc.org/MANUAL.html">manual</a>.</p>
39−<p>Absolute path left alone: <a href="/foo/bar/baz.png">absolute</a>.</p>
40−<p>Link to fragment: <a href="#chapter-two">chapter two</a>.</p>
41−<p>Empty path: <a href="">empty</a>.</p>
42−<h1 id="chapter-two">Chapter two</h1>
43−<p>A spider: <img src="command/chap2/spider.png" alt="spider" /></p>
44−```
45−
46−```
47−% pandoc command/chap1/text.md command/chap2/text.md -f commonmark+rebase_relative_paths -t html
48−^D
49−<h1>Chapter one</h1>
50−<p>A spider: <img src="command/chap1/spider.png" alt="spider" /></p>
51−<p>Another spider: <img src="command/chap2/spider.png" alt="another spider" /></p>
52−<p>The moon: <img src="command/chap1/../../lalune.jpg" alt="moon" /></p>
53−<p>Link to <a href="command/chap1/spider.png">spider picture</a>.</p>
54−<p>URL left alone: <a href="https://pandoc.org/MANUAL.html">manual</a>.</p>
55−<p>Absolute path left alone: <a href="/foo/bar/baz.png">absolute</a>.</p>
56−<p>Link to fragment: <a href="#chapter-two">chapter two</a>.</p>
57−<p>Empty path: <a href="">empty</a>.</p>
58−<h1>Chapter two</h1>
59−<p>A spider: <img src="command/chap2/spider.png" alt="spider" /></p>
60−```
test/command/3792.md+1−1
@@ -6,7 +6,7 @@ and properly escaped.
6ok
6ok
7^D
7^D
8---
8---
9−title: \<this> \*that\*
9+title: \<this\> \*that\*
10---
10---
11
11
12ok
12ok
test/command/4063.mddeleted−29
@@ -1,29 +0,0 @@
1−```
2−% pandoc -f html -t native
3−<table>
4−<colgroup>
5− <col width="30%" />
6− <col width="*" />
7−</colgroup>
8−<tr>
9− <td>1</td>
10− <td>2</td>
11−</tr>
12−</table>
13−^D
14−[Table ("",[],[]) (Caption Nothing
15− [])
16− [(AlignDefault,ColWidth 0.3)
17− ,(AlignDefault,ColWidth 0.7)]
18− (TableHead ("",[],[])
19− [])
20− [(TableBody ("",[],[]) (RowHeadColumns 0)
21− []
22− [Row ("",[],[])
23− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
24− [Plain [Str "1"]]
25− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
26− [Plain [Str "2"]]]])]
27− (TableFoot ("",[],[])
28− [])]
29−```
test/command/4164.md+1−1
@@ -26,6 +26,6 @@ Here is inline html:
26
26
27Here is inline html:
27Here is inline html:
28
28
29−\<div> \<balise> bla bla \</div>
29+\<div\> \<balise\> bla bla \</div\>
30
30
31```
31```
test/command/4442.md+1−1
@@ -5,5 +5,5 @@
5^D
5^D
6\newcommand{\myFruit}{Mango\xspace}
6\newcommand{\myFruit}{Mango\xspace}
7
7
8−Mango is the king of fruits.
8+Mango\xspace is the king of fruits.
9```
9```
test/command/4465.mddeleted−15
@@ -1,15 +0,0 @@
1−```
2−% pandoc -f html -t markdown
3−<ol>
4− <li>An ordered list can contain block-level elements ind html, it means that divs are also allowed.</li>
5− <li>Let's see the problem! <div class="example">This is an example.</div></li>
6−</ol>
7−^D
8−1. An ordered list can contain block-level elements ind html, it means
9− that divs are also allowed.
10−2. Let\'s see the problem!
11−
12− ::: example
13− This is an example.
14− :::
15−```
test/command/5304.md+1−1
@@ -11,7 +11,7 @@
11...
11...
12```
12```
13^D
13^D
14−``` markdown
14+``` {.markdown}
15`«sträng»`
15`«sträng»`
16
16
17`` «sträng» ``
17`` «sträng» ``
test/command/5367.md+2−6
@@ -24,15 +24,11 @@ hello\footnote{doc footnote}
24 >{\centering\arraybackslash}p{(\columnwidth - 0\tabcolsep) * \real{0.17}}@{}}
24 >{\centering\arraybackslash}p{(\columnwidth - 0\tabcolsep) * \real{0.17}}@{}}
25\caption[Sample table.]{Sample table.\footnote{caption footnote}}\tabularnewline
25\caption[Sample table.]{Sample table.\footnote{caption footnote}}\tabularnewline
26\toprule
26\toprule
27−\begin{minipage}[b]{\linewidth}\centering
28−Fruit\footnote{header footnote}
27+Fruit\footnote{header footnote} \\
29−\end{minipage} \\
30\midrule
28\midrule
31\endfirsthead
29\endfirsthead
32\toprule
30\toprule
33−\begin{minipage}[b]{\linewidth}\centering
34−Fruit{}
31+Fruit{} \\
35−\end{minipage} \\
36\midrule
32\midrule
37\endhead
33\endhead
38Bans\footnote{table cell footnote} \\
34Bans\footnote{table cell footnote} \\
test/command/5519.md+1−1
@@ -6,7 +6,7 @@
6 ```
6 ```
7``````
7``````
8^D
8^D
9−```` attr
9+```` {.attr}
10 ```
10 ```
11 code
11 code
12 ```
12 ```
test/command/6026.mddeleted−19
@@ -1,19 +0,0 @@
1−```
2−% pandoc -t native
3−@{https://openreview.net/forum?id=HkwoSDPgg}
4−
5−@https://openreview.net/forum?id=HkwoSDPgg
6−^D
7−[Para [Cite [Citation {citationId = "https://openreview.net/forum?id=HkwoSDPgg", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 1, citationHash = 0}] [Str "@https://openreview.net/forum?id=HkwoSDPgg"]]
8−,Para [Cite [Citation {citationId = "https://openreview.net/forum?id", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 2, citationHash = 0}] [Str "@https://openreview.net/forum?id"],Str "=HkwoSDPgg"]]
9−```
10−```
11−% pandoc -t markdown
12−@{https://openreview.net/forum?id=HkwoSDPgg}
13−
14−@https://openreview.net/forum?id=HkwoSDPgg
15−^D
16−@{https://openreview.net/forum?id=HkwoSDPgg}
17−
18−@https://openreview.net/forum?id=HkwoSDPgg
19−```
test/command/6541.mddeleted−27
@@ -1,27 +0,0 @@
1−```
2−% pandoc -f docbook -t markdown -s
3−<?xml version="1.0"?>
4−<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
5− "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
6−<book>
7−
8−<bookinfo>
9−<title>Title</title>
10−<author>
11−<firstname>Firstname</firstname><surname>Lastname</surname>
12−</author>
13−<releaseinfo>1.17</releaseinfo>
14−</bookinfo>
15−
16−<para>Text.</para>
17−
18−</book>
19−^D
20−---
21−author: Firstname Lastname
22−releaseinfo: 1.17
23−title: Title
24−---
25−
26−Text.
27−```
test/command/6620.md−3
@@ -7,12 +7,9 @@
7\SI{0.135(21)}{\m}
7\SI{0.135(21)}{\m}
8
8
9\SI{12.3(60)}{\m}
9\SI{12.3(60)}{\m}
10−
11−\SI{10.0 \pm 3.3}{\ms}
12^D
10^D
13<p>23 ± 2 m</p>
11<p>23 ± 2 m</p>
14<p>125 ± 12 m</p>
12<p>125 ± 12 m</p>
15<p>0.135 ± 0.021 m</p>
13<p>0.135 ± 0.021 m</p>
16<p>12.3 ± 6 m</p>
14<p>12.3 ± 6 m</p>
17−<p>10.0 ± 3.3 ms</p>
18```
15```
test/command/6658.mddeleted−75
@@ -1,75 +0,0 @@
1−```
2−pandoc -f latex -t html
3−\num{12345,67890}
4−
5−\num{1+-2i}
6−
7−\num{.3e45}
8−
9−\num{1.654 x 2.34 x 3.430}
10−
11−\si{kg.m.s^{-1}}
12−
13−\si{\kilogram\metre\per\second}
14−
15−\si[per-mode=symbol]{\kilogram\metre\per\second}
16−
17−\si[per-mode=symbol]{\kilogram\metre\per\ampere\per\second}
18−
19−\numlist{10;20;30}
20−
21−\SIlist{0.13;0.67;0.80}{\milli\metre}
22−
23−\numrange{10}{20}
24−
25−\SIrange{0.13}{0.67}{\milli\metre}
26−
27−\ang{10}
28−
29−\ang{1;2;3}
30−
31−\ang{;;1}
32−
33−\ang{+10;;}
34−
35−\ang{-0;1;}
36−
37−\si{kg.m/s^2}
38−
39−\si{g_{polymer}~mol_{cat}.s^{-1}}
40−
41−\si{\kilo\gram\metre\per\square\second}
42−
43−\si{\gram\per\cubic\centi\metre}
44−
45−\si{\square\volt\cubic\lumen\per\farad}
46−
47−\si{\metre\squared\per\gray\cubic\lux}
48−
49−\si{\henry\second}
50−^D
51−<p>12345.67890</p>
52−<p>1 ± 2i</p>
53−<p>0.3 × 10<sup>45</sup></p>
54−<p>1.654 × 2.34 × 3.430</p>
55−<p>kg m s<sup>−1</sup></p>
56−<p>kg m s<sup>−1</sup></p>
57−<p>kg m/s</p>
58−<p>kg m/A/s</p>
59−<p>10, 20, &amp; 30</p>
60−<p>0.13 mm, 0.67 mm, &amp; 0.80 mm</p>
61−<p>10–20</p>
62−<p>0.13 mm–0.67 mm</p>
63−<p>10°</p>
64−<p>1°2′3″</p>
65−<p>1″</p>
66−<p>10°</p>
67−<p>-0°1′</p>
68−<p>kg m/s<sup>2</sup></p>
69−<p>g<sub>polymer</sub> mol<sub>cat</sub> s<sup>−1</sup></p>
70−<p>kg m s<sup>−2</sup></p>
71−<p>g cm<sup>−3</sup></p>
72−<p>V<sup>2</sup> lm<sup>3</sup> F<sup>−1</sup></p>
73−<p>m<sup>2</sup> Gy<sup>−1</sup> lx<sup>3</sup></p>
74−<p>H s</p>
75−```
test/command/6709.mddeleted−11
@@ -1,11 +0,0 @@
1−Tabs must be expanded even if --file-scope is used
2−````
3−% pandoc -t native --file-scope --tab-stop=2
4−```
5−if true; then
6− echo "yup"
7−fi
8−```
9−^D
10−[CodeBlock ("",[],[]) "if true; then\n echo \"yup\"\nfi"]
11−````
test/command/6890.md+2−2
@@ -23,12 +23,12 @@ references:
23
23
24@fruchtel-sozialer-2013a
24@fruchtel-sozialer-2013a
25
25
26−Some text.[^1]
26+Some text [^1].
27
27
28[^1]: @fruchtel-sozialer-2013a
28[^1]: @fruchtel-sozialer-2013a
29^D
29^D
30[Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 1, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]
30[Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 1, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]
31−,Para [Str "Some",Space,Str "text.",Note [Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 2, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]]]
31+,Para [Str "Some",Space,Str "text",Str ".",Note [Para [Cite [Citation {citationId = "fruchtel-sozialer-2013a", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 2, citationHash = 0}] [Str "Fr\252chtel,",Space,Str "Budde,",Space,Str "and",Space,Str "Cyprian",Space,Str "(2013)"]]],Str ""]
32,Div ("refs",["references","csl-bib-body","hanging-indent"],[])
32,Div ("refs",["references","csl-bib-body","hanging-indent"],[])
33 [Div ("ref-fruchtel-sozialer-2013a",["csl-entry"],[])
33 [Div ("ref-fruchtel-sozialer-2013a",["csl-entry"],[])
34 [Para [Str "Fr\252chtel,",Space,Str "Frank,",Space,Str "Wolfgang",Space,Str "Budde,",Space,Str "and",Space,Str "Gudrun",Space,Str "Cyprian.",Space,Str "2013.",Space,Emph [Str "Sozialer",Space,Str "Raum",Space,Str "und",Space,Str "Soziale",Space,Str "Arbeit",Space,Str "Fieldbook:",Space,Str "Methoden",Space,Str "und",Space,Str "Techniken"],Str ".",Space,Str "3rd",Space,Str "ed.",Space,Str "Wiesbaden,",Space,Str "Germany:",Space,Str "Springer",Space,Str "VS."]]]]
34 [Para [Str "Fr\252chtel,",Space,Str "Frank,",Space,Str "Wolfgang",Space,Str "Budde,",Space,Str "and",Space,Str "Gudrun",Space,Str "Cyprian.",Space,Str "2013.",Space,Emph [Str "Sozialer",Space,Str "Raum",Space,Str "und",Space,Str "Soziale",Space,Str "Arbeit",Space,Str "Fieldbook:",Space,Str "Methoden",Space,Str "und",Space,Str "Techniken"],Str ".",Space,Str "3rd",Space,Str "ed.",Space,Str "Wiesbaden,",Space,Str "Germany:",Space,Str "Springer",Space,Str "VS."]]]]
test/command/6925.md+2−2
@@ -20,13 +20,13 @@ a
20\end{thm2}
20\end{thm2}
21\end{document}
21\end{document}
22^D
22^D
23−::: thm
23+::: {.thm}
24**Theorem 1**. *a*
24**Theorem 1**. *a*
25
25
26![image](1.png)
26![image](1.png)
27:::
27:::
28
28
29−::: thm2
29+::: {.thm2}
30**Theorem 1**. a
30**Theorem 1**. a
31
31
32![image](1.png)
32![image](1.png)
test/command/6958.mddeleted−10
@@ -1,10 +0,0 @@
1−Add thin space between single and double quotes.
2−```
3−% pandoc -t latex+smart
4−---
5−lang: en-GB
6−---
7−'["On the Outside"]{}: Constructing Cycling Citizenship.'
8−^D
9−`\,{``On the Outside''}: Constructing Cycling Citizenship.'
10−```
test/command/7041.mddeleted−23
@@ -1,23 +0,0 @@
1−```
2−% pandoc -f html -t jats
3−<table>
4− <tr><td><blockquote>Fly, you fools!</blockquote></td></tr>
5−</table>
6−^D
7−<table-wrap>
8− <table>
9− <colgroup>
10− <col width="100%" />
11− </colgroup>
12− <tbody>
13− <tr>
14− <td><p specific-use="wrapper">
15− <disp-quote>
16− <p>Fly, you fools!</p>
17− </disp-quote>
18− </p></td>
19− </tr>
20− </tbody>
21− </table>
22−</table-wrap>
23−```
test/command/7099.md+1−1
@@ -11,7 +11,7 @@
11<iframe src="h:invalid@url"></iframe>
11<iframe src="h:invalid@url"></iframe>
12^D
12^D
13[INFO] Fetching h:invalid@url...
13[INFO] Fetching h:invalid@url...
14−[WARNING] Could not fetch resource h:invalid@url: Could not fetch h:invalid@url
14+[WARNING] Could not fetch resource 'h:invalid@url': Could not fetch h:invalid@url
15 InvalidUrlException "h:invalid@url" "Invalid scheme"
15 InvalidUrlException "h:invalid@url" "Invalid scheme"
16[INFO] Skipped '<iframe src="h:invalid@url"></iframe>' at input line 1 column 29
16[INFO] Skipped '<iframe src="h:invalid@url"></iframe>' at input line 1 column 29
17[]
17[]
test/command/7208.md+1−1
@@ -2,5 +2,5 @@
2% pandoc -t gfm
2% pandoc -t gfm
3\<hi\>
3\<hi\>
4^D
4^D
5−\<hi>
5+\<hi\>
6```
6```
test/command/7216.mddeleted−19
@@ -1,19 +0,0 @@
1−```
2−pandoc -t latex
3−"This is some text in quotes. Another paragraph by the same speaker follows. The first paragraph should have no close quote.
4−
5−"The second paragraph should have open and close quotes."
6−
7−| "Open quote on this line,
8−| Close quote on the next line."
9−| "Quotes on the same line."
10−^D
11−``This is some text in quotes. Another paragraph by the same speaker
12−follows. The first paragraph should have no close quote.
13−
14−``The second paragraph should have open and close quotes.''
15−
16−``Open quote on this line,\\
17−Close quote on the next line.''\\
18−``Quotes on the same line.''
19−```
test/command/7266.mddeleted−10
@@ -1,10 +0,0 @@
1−```
2−% pandoc -f biblatex -t biblatex -s
3−@article{id,
4− annote = "annotation"
5−}
6−^D
7−@article{id,
8− annote = {annotation}
9−}
10−```
test/command/7272.mddeleted−27
@@ -1,27 +0,0 @@
1−```
2−% pandoc -t latex -f html
3−<table>
4− <tbody>
5− <tr>
6− <td>
7− <span>
8− text
9− <br />
10− text2
11− </span>
12− </td>
13− </tr>
14− </tbody>
15−</table>
16−^D
17−\begin{longtable}[]{@{}
18− >{\raggedright\arraybackslash}p{(\columnwidth - 0\tabcolsep) * \real{1.00}}@{}}
19−\toprule
20−\endhead
21−\begin{minipage}[t]{\linewidth}\raggedright
22−{ text\\
23−text2 }\strut
24−\end{minipage} \\
25−\bottomrule
26−\end{longtable}
27−```
test/command/7278.mddeleted−38
@@ -1,38 +0,0 @@
1−```
2−% pandoc -t beamer
3−# Slide
4−
5−Some blocks:
6−
7−## example block title {.example}
8−
9−text in block
10−
11−## alert block title {.alert}
12−
13−text in block
14−
15−## block title
16−
17−text in block
18−^D
19−\begin{frame}{Slide}
20−\protect\hypertarget{slide}{}
21−Some blocks:
22−
23−\begin{exampleblock}{example block title}
24−\protect\hypertarget{example-block-title}{}
25−text in block
26−\end{exampleblock}
27−
28−\begin{alertblock}{alert block title}
29−\protect\hypertarget{alert-block-title}{}
30−text in block
31−\end{alertblock}
32−
33−\begin{block}{block title}
34−\protect\hypertarget{block-title}{}
35−text in block
36−\end{block}
37−\end{frame}
38−```
test/command/7282.mddeleted−7
@@ -1,7 +0,0 @@
1−Don't crash on unmatched closing tag.
2−```
3−% pandoc -f html -t native
4−</script>
5−^D
6−[]
7−```
test/command/7288.mddeleted−40
@@ -1,40 +0,0 @@
1−```
2−% pandoc -f rst -t ms
3−.. list-table::
4− :widths: 50 50
5− :header-rows: 1
6−
7− * - Left
8− - Right
9− * - Long text that should be easy to break up into multiple lines
10− - Another long text that should be easy to break up into multiple lines
11−
12− Bar
13−^D
14−.PP
15−.na
16−.nr LLold \n[LL]
17−.TS
18−delim(@@) tab( );
19−lw(35.0n) lw(35.0n).
20−T{
21−Left
22−T} T{
23−Right
24−T}
25−_
26−T{
27−.nr LL 35.0n
28−.LP
29−Long text that should be easy to break up into multiple lines
30−T} T{
31−.nr LL 35.0n
32−.PP
33−Another long text that should be easy to break up into multiple lines
34−.PP
35−Bar
36−T}
37−.TE
38−.nr LL \n[LLold]
39−.ad
40−```
test/command/7299.mddeleted−23
@@ -1,23 +0,0 @@
1−```
2−% pandoc -f latex -t plain
3−$1-{\ensuremath{r}\xspace}$
4−^D
5−1 − r
6−```
7−
8−```
9−% pandoc -f latex -t plain
10−\newcommand{\foo}{Foo\xspace}
11−
12−$\text{\foo bar}$
13−^D
14−Foo bar
15−```
16−
17−```
18−% pandoc -f latex -t plain
19−a\xspace b
20−^D
21−a b
22−```
23−
test/command/7321.mddeleted−24
@@ -1,24 +0,0 @@
1−```
2−% pandoc -t plain --citeproc --wrap=none
3−---
4−references:
5−- id: fenner2012a
6− title: One-click science marketing
7− author:
8− - family: Fenner
9− given: Martin
10− container-title: Nature Materials
11− volume: 11
12− issue: 4
13− publisher: Nature Publishing Group
14− type: article-journal
15− issued:
16− year: 2012
17−---
18−
19−[@fenner2012a, $a^2+b^2=c^2$]
20−^D
21−(Fenner 2012, a² + b² = c²)
22−
23−Fenner, Martin. 2012. “One-Click Science Marketing.” Nature Materials 11 (4).
24−```
test/command/7323.mddeleted−29
@@ -1,29 +0,0 @@
1−```
2−% pandoc --citeproc -t plain
3−---
4−references:
5−- id: smith
6− author: John Smith
7− issued: 2019
8− title: Insects
9− type: book
10−...
11−
12−@smith [chap. 6]
13−
14−@smith [chapter 6]
15−
16−@smith [Chap. 6]
17−
18−@smith [Chapter 6]
19−^D
20−John Smith (2019, chap. 6)
21−
22−John Smith (2019, chap. 6)
23−
24−John Smith (2019, chap. 6)
25−
26−John Smith (2019, chap. 6)
27−
28−John Smith. 2019. Insects.
29−```
test/command/7324.mddeleted−25
@@ -1,25 +0,0 @@
1−```
2−% pandoc --citeproc -t plain
3−---
4−references:
5−- id: smith
6− author: John Smith
7− issued: 2019
8− title: Insects
9− type: book
10−...
11−
12−@smith [, among others]
13−
14−@smith [ among others]
15−
16−@smith [among others]
17−^D
18−John Smith (2019, among others)
19−
20−John Smith (2019 among others)
21−
22−John Smith (2019, among others)
23−
24−John Smith. 2019. Insects.
25−```
test/command/7339.mddeleted−11
@@ -1,11 +0,0 @@
1−```
2−% pandoc -f gfm -s -t native
3−---
4−title: Test
5−---
6−
7−Hi
8−^D
9−Pandoc (Meta {unMeta = fromList [("title",MetaInlines [Str "Test"])]})
10−[Para [Str "Hi"]]
11−```
test/command/7340.mddeleted−6
@@ -1,6 +0,0 @@
1−```
2−% pandoc -f latex -t native
3−\(*\)
4−^D
5−[Para [Math InlineMath "*"]]
6−```
test/command/7376.mddeleted−16
@@ -1,16 +0,0 @@
1−```
2−% pandoc --citeproc -t plain
3−---
4−references:
5−- id: item1
6− type: book
7− author:
8− - family: Doe
9− given: Jane
10− issued: 2020
11− title: The title
12−...
13−^D
14−
15−
16−```
test/command/7394.mddeleted−85
@@ -1,85 +0,0 @@
1−```
2−% pandoc -f markdown -t plain --citeproc
3−---
4−csl: command/chicago-fullnote-bibliography.csl
5−references:
6−- author:
7− - family: Wandt
8− given: Manfred
9− edition: 6
10− id: wandt2014ges-sv
11− issued: 2014
12− publisher: Franz Vahlen
13− publisher-place: München
14− title: Gesetzliche schuldverhältnisse
15− title-short: Gesetzl SV
16− type: book
17−- author:
18− - family: Smith
19− given: Zenda
20− edition: 6
21− id: smith2015
22− issued: 2015
23− publisher: Macmillan
24− publisher-place: New York
25− title: A verb and a noun
26− type: book
27−---
28−
29−Hi^[@wandt2014ges-sv.].
30−
31−Hi^[[@wandt2014ges-sv].].
32−
33−Hi^[[See also @wandt2014ges-sv].].
34−
35−Hi^[See also @wandt2014ges-sv.].
36−
37−Hi^[@wandt2014ges-sv [@smith2015].].
38−
39−Hi^[[@wandt2014ges-sv; @smith2015].].
40−
41−Hi [@wandt2014ges-sv].
42−
43−Hi [see also @wandt2014ges-sv].
44−
45−^D
46−Hi[1].
47−
48−Hi[2].
49−
50−Hi[3].
51−
52−Hi[4].
53−
54−Hi[5].
55−
56−Hi[6].
57−
58−Hi.[7]
59−
60−Hi.[8]
61−
62−Smith, Zenda. A Verb and a Noun. 6th ed. New York: Macmillan, 2015.
63−
64−Wandt, Manfred. Gesetzliche Schuldverhältnisse. 6th ed. München: Franz
65−Vahlen, 2014.
66−
67−[1] Manfred Wandt, Gesetzliche Schuldverhältnisse, 6th ed. (München:
68−Franz Vahlen, 2014).
69−
70−[2] Wandt.
71−
72−[3] See also Wandt.
73−
74−[4] See also Wandt.
75−
76−[5] Wandt, Zenda Smith, A Verb and a Noun, 6th ed. (New York: Macmillan,
77−2015).
78−
79−[6] Wandt, Gesetzl SV; Smith, A Verb and a Noun.
80−
81−[7] Wandt, Gesetzl SV.
82−
83−[8] See also Wandt.
84−```
85−
test/command/7397.mddeleted−14
@@ -1,14 +0,0 @@
1−````
2−% pandoc -t markdown
3−~~~~ { .haskell startFrom="100"}
4−qsort [] = []
5−qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
6− qsort (filter (>= x) xs)
7−~~~~
8−^D
9−``` {.haskell startFrom="100"}
10−qsort [] = []
11−qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
12− qsort (filter (>= x) xs)
13−```
14−````
test/command/7400.mddeleted−9
@@ -1,9 +0,0 @@
1−```
2−% pandoc -t native -s
3−---
4−# Comment only
5−...
6−^D
7−Pandoc (Meta {unMeta = fromList []})
8−[]
9−```
test/command/7416.mddeleted−19
@@ -1,19 +0,0 @@
1−```
2−% pandoc -f markdown -t html
3−![caption](../media/rId25.jpg "title"){alt="alt"}
4−
5−^D
6−<figure>
7−<img src="../media/rId25.jpg" title="title" alt="alt" /><figcaption>caption</figcaption>
8−</figure>
9−```
10−
11−```
12−% pandoc -f markdown -t html
13−![caption](../media/rId25.jpg "title")
14−
15−^D
16−<figure>
17−<img src="../media/rId25.jpg" title="title" alt="caption" /><figcaption aria-hidden="true">caption</figcaption>
18−</figure>
19−```
test/command/averroes.bibdeleted−95
@@ -1,95 +0,0 @@
1−@string{anch-ie = {Angew.~Chem. Int.~Ed.}}
2−@string{cup = {Cambridge University Press}}
3−@string{dtv = {Deutscher Taschenbuch-Verlag}}
4−@string{hup = {Harvard University Press}}
5−@string{jams = {J.~Amer. Math. Soc.}}
6−@string{jchph = {J.~Chem. Phys.}}
7−@string{jomch = {J.~Organomet. Chem.}}
8−@string{pup = {Princeton University Press}}
9−
10−@book{averroes/bland,
11− author = {Averroes},
12− title = {The Epistle on the Possibility of Conjunction with the Active
13− Intellect by {Ibn Rushd} with the Commentary of {Moses Narboni}},
14− date = 1982,
15− editor = {Bland, Kalman P.},
16− translator = {Bland, Kalman P.},
17− series = {Moreshet: Studies in {Jewish} History, Literature and Thought},
18− number = 7,
19− publisher = {Jewish Theological Seminary of America},
20− location = {New York},
21− keywords = {primary},
22− langid = {english},
23− langidopts = {variant=american},
24− indextitle = {Epistle on the Possibility of Conjunction, The},
25− shorttitle = {Possibility of Conjunction},
26− annotation = {A \texttt{book} entry with a \texttt{series} and a
27− \texttt{number}. Note the concatenation of the \texttt{editor}
28− and \texttt{translator} fields as well as the
29− \texttt{indextitle} field},
30−}
31−
32−@book{averroes/hannes,
33− author = {Averroes},
34− title = {Des Averro{\"e}s Abhandlung: \mkbibquote{{\"U}ber die
35− M{\"o}glichkeit der Conjunktion} oder \mkbibquote{{\"U}ber den
36− materiellen Intellekt}},
37− date = 1892,
38− editor = {Hannes, Ludwig},
39− translator = {Hannes, Ludwig},
40− annotator = {Hannes, Ludwig},
41− publisher = {C.~A. Kaemmerer},
42− location = {Halle an der Saale},
43− keywords = {primary},
44− langid = {german},
45− sorttitle = {Uber die Moglichkeit der Conjunktion},
46− indexsorttitle= {Uber die Moglichkeit der Conjunktion},
47− indextitle = {{\"U}ber die M{\"o}glichkeit der Conjunktion},
48− shorttitle = {{\"U}ber die M{\"o}glichkeit der Conjunktion},
49− annotation = {An annotated edition. Note the concatenation of the
50− \texttt{editor}, \texttt{translator}, and \texttt{annotator}
51− fields. Also note the \texttt{shorttitle},
52− \texttt{indextitle}, \texttt{sorttitle}, and
53− \texttt{indexsorttitle} fields},
54−}
55−
56−@book{averroes/hercz,
57− author = {Averroes},
58− title = {Drei Abhandlungen {\"u}ber die Conjunction des separaten
59− Intellects mit dem Menschen},
60− date = 1869,
61− editor = {Hercz, J.},
62− translator = {Hercz, J.},
63− publisher = {S.~Hermann},
64− location = {Berlin},
65− keywords = {primary},
66− langid = {german},
67− indexsorttitle= {Drei Abhandlungen uber die Conjunction},
68− indextitle = {Drei Abhandlungen {\"u}ber die Conjunction},
69− subtitle = {Von Averroes (Vater und Sohn), aus dem Arabischen
70− {\"u}bersetzt von Samuel Ibn Tibbon},
71− shorttitle = {Drei Abhandlungen},
72− annotation = {A \texttt{book} entry. Note the concatenation of the
73− \texttt{editor} and \texttt{translator} fields as well as the
74− \texttt{indextitle} and \texttt{indexsorttitle} fields},
75−}
76−
77−@book{cicero,
78− author = {Cicero, Marcus Tullius},
79− title = {De natura deorum. {\"U}ber das Wesen der G{\"o}tter},
80− date = 1995,
81− editor = {Blank-Sangmeister, Ursula},
82− translator = {Blank-Sangmeister, Ursula},
83− afterword = {Thraede, Klaus},
84− language = {langlatin and langgerman},
85− publisher = {Reclam},
86− location = {Stuttgart},
87− langid = {german},
88− indextitle = {De natura deorum},
89− shorttitle = {De natura deorum},
90− annotation = {A bilingual edition of Cicero's \emph{De natura deorum}, with
91− a German translation. Note the format of the \texttt{language}
92− field in the database file, the concatenation of the
93− \texttt{editor} and \texttt{translator} fields, and the
94− \texttt{afterword} field},
95−}
test/command/biblatex-basic.md+3−5
@@ -1,5 +1,3 @@
1−```
2−% pandoc -f biblatex -t markdown -s
3@Book{item1,
1@Book{item1,
4author="John Doe",
2author="John Doe",
5title="First Book",
3title="First Book",
@@ -29,7 +27,7 @@ year="2007"
29
27
30^D
28^D
31---
29---
32−nocite: "[@*]"
30+nocite: '[@*]'
33references:
31references:
34- author:
32- author:
35 - family: Doe
33 - family: Doe
@@ -46,9 +44,9 @@ references:
46 container-title: Journal of Generic Studies
44 container-title: Journal of Generic Studies
47 id: item2
45 id: item2
48 issued: 2006
46 issued: 2006
49− page: 33-34
47+ page: '33-34'
50 title: Article
48 title: Article
51− type: article-journal
49+ type: 'article-journal'
52 volume: 6
50 volume: 6
53- author:
51- author:
54 - family: Doe
52 - family: Doe
test/command/biblatex-examples.bibnew file+1674
@@ -0,0 +1,1674 @@
1+@string{anch-ie = {Angew.~Chem. Int.~Ed.}}
2+@string{cup = {Cambridge University Press}}
3+@string{dtv = {Deutscher Taschenbuch-Verlag}}
4+@string{hup = {Harvard University Press}}
5+@string{jams = {J.~Amer. Math. Soc.}}
6+@string{jchph = {J.~Chem. Phys.}}
7+@string{jomch = {J.~Organomet. Chem.}}
8+@string{pup = {Princeton University Press}}
9+
10+@incollection{westfahl:space,
11+ author = {Westfahl, Gary},
12+ title = {The True Frontier},
13+ subtitle = {Confronting and Avoiding the Realities of Space in {American}
14+ Science Fiction Films},
15+ pages = {55-65},
16+ crossref = {westfahl:frontier},
17+ langid = {english},
18+ langidopts = {variant=american},
19+ indextitle = {True Frontier, The},
20+ annotation = {A cross-referenced article from a \texttt{collection}. This is
21+ an \texttt{incollection} entry with a \texttt{crossref}
22+ field. Note the \texttt{subtitle} and \texttt{indextitle}
23+ fields},
24+}
25+
26+@set{set,
27+ entryset = {herrmann,aksin,yoon},
28+ annotation = {A \texttt{set} with three members. The \texttt{crossref} field
29+ in the \texttt{@set} entry and the \texttt{entryset} field in
30+ each set member entry is needed only when using BibTeX as the
31+ backend},
32+}
33+
34+@set{stdmodel,
35+ entryset = {glashow,weinberg,salam},
36+ annotation = {A \texttt{set} with three members discussing the standard
37+ model of particle physics. The \texttt{crossref} field
38+ in the \texttt{@set} entry and the \texttt{entryset} field in
39+ each set member entry is needed only when using BibTeX as the
40+ backend},
41+}
42+
43+@article{aksin,
44+ author = {Aks{\i}n, {\"O}zge and T{\"u}rkmen, Hayati and Artok, Levent
45+ and {\c{C}}etinkaya, Bekir and Ni, Chaoying and
46+ B{\"u}y{\"u}kg{\"u}ng{\"o}r, Orhan and {\"O}zkal, Erhan},
47+ title = {Effect of immobilization on catalytic characteristics of
48+ saturated {Pd-N}-heterocyclic carbenes in {Mizoroki-Heck}
49+ reactions},
50+ journaltitle = jomch,
51+ date = 2006,
52+ volume = 691,
53+ number = 13,
54+ pages = {3027-3036},
55+ indextitle = {Effect of immobilization on catalytic characteristics},
56+}
57+
58+@article{angenendt,
59+ author = {Angenendt, Arnold},
60+ title = {In Honore Salvatoris~-- Vom Sinn und Unsinn der
61+ Patrozinienkunde},
62+ journaltitle = {Revue d'Histoire Eccl{\'e}siastique},
63+ date = 2002,
64+ volume = 97,
65+ pages = {431--456, 791--823},
66+ langid = {german},
67+ indextitle = {In Honore Salvatoris},
68+ shorttitle = {In Honore Salvatoris},
69+ annotation = {A German article in a French journal. Apart from that, a
70+ typical \texttt{article} entry. Note the \texttt{indextitle}
71+ field},
72+}
73+
74+@article{baez/article,
75+ author = {Baez, John C. and Lauda, Aaron D.},
76+ title = {Higher-Dimensional Algebra {V}: 2-Groups},
77+ journaltitle = {Theory and Applications of Categories},
78+ date = 2004,
79+ volume = 12,
80+ pages = {423-491},
81+ version = 3,
82+ eprint = {math/0307200v3},
83+ eprinttype = {arxiv},
84+ langid = {english},
85+ langidopts = {variant=american},
86+ annotation = {An \texttt{article} with \texttt{eprint} and
87+ \texttt{eprinttype} fields. Note that the arXiv reference is
88+ transformed into a clickable link if \texttt{hyperref} support
89+ has been enabled. Compare \texttt{baez\slash online}, which
90+ is the same item given as an \texttt{online} entry},
91+}
92+
93+@article{bertram,
94+ author = {Bertram, Aaron and Wentworth, Richard},
95+ title = {Gromov invariants for holomorphic maps on {Riemann} surfaces},
96+ journaltitle = jams,
97+ date = 1996,
98+ volume = 9,
99+ number = 2,
100+ pages = {529-571},
101+ langid = {english},
102+ langidopts = {variant=american},
103+ shorttitle = {Gromov invariants},
104+ annotation = {An \texttt{article} entry with a \texttt{volume} and a
105+ \texttt{number} field},
106+}
107+
108+@article{doody,
109+ author = {Doody, Terrence},
110+ title = {Hemingway's Style and {Jake's} Narration},
111+ year = 1974,
112+ volume = 4,
113+ number = 3,
114+ pages = {212-225},
115+ langid = {english},
116+ langidopts = {variant=american},
117+ related = {matuz:doody},
118+ relatedstring= {\autocap{e}xcerpt in},
119+ journal = {The Journal of Narrative Technique},
120+ annotation = {An \texttt{article} entry cited as an excerpt from a
121+ \texttt{collection} entry. Note the format of the
122+ \texttt{related} and \texttt{relatedstring} fields},
123+}
124+
125+@collection{matuz:doody,
126+ editor = {Matuz, Roger},
127+ title = {Contemporary Literary Criticism},
128+ year = 1990,
129+ volume = 61,
130+ publisher = {Gale},
131+ location = {Detroit},
132+ pages = {204-208},
133+ langid = {english},
134+ langidopts = {variant=american},
135+ annotation = {A \texttt{collection} entry providing the excerpt information
136+ for the \texttt{doody} entry. Note the format of the
137+ \texttt{pages} field},
138+}
139+
140+@article{gillies,
141+ author = {Gillies, Alexander},
142+ title = {Herder and the Preparation of {Goethe's} Idea of World
143+ Literature},
144+ journaltitle = {Publications of the English Goethe Society},
145+ date = 1933,
146+ series = {newseries},
147+ volume = 9,
148+ pages = {46-67},
149+ langid = {english},
150+ langidopts = {variant=british},
151+ annotation = {An \texttt{article} entry with a \texttt{series} and a
152+ \texttt{volume} field. Note that format of the \texttt{series}
153+ field in the database file},
154+}
155+
156+@article{glashow,
157+ author = {Glashow, Sheldon},
158+ title = {Partial Symmetries of Weak Interactions},
159+ journaltitle = {Nucl.~Phys.},
160+ date = 1961,
161+ volume = 22,
162+ pages = {579-588},
163+}
164+
165+@article{herrmann,
166+ author = {Herrmann, Wolfgang A. and {\"O}fele, Karl and Schneider,
167+ Sabine K. and Herdtweck, Eberhardt and Hoffmann, Stephan D.},
168+ title = {A carbocyclic carbene as an efficient catalyst ligand for {C--C}
169+ coupling reactions},
170+ journaltitle = anch-ie,
171+ date = 2006,
172+ volume = 45,
173+ number = 23,
174+ pages = {3859-3862},
175+ indextitle = {Carbocyclic carbene as an efficient catalyst, A},
176+}
177+
178+@article{kastenholz,
179+ author = {Kastenholz, M. A. and H{\"u}nenberger, Philippe H.},
180+ title = {Computation of methodology\hyphen independent ionic solvation
181+ free energies from molecular simulations},
182+ journaltitle = jchph,
183+ date = 2006,
184+ subtitle = {{I}. {The} electrostatic potential in molecular liquids},
185+ volume = 124,
186+ eid = 124106,
187+ doi = {10.1063/1.2172593},
188+ langid = {english},
189+ langidopts = {variant=american},
190+ indextitle = {Computation of ionic solvation free energies},
191+ annotation = {An \texttt{article} entry with an \texttt{eid} and a
192+ \texttt{doi} field. Note that the \textsc{doi} is transformed
193+ into a clickable link if \texttt{hyperref} support has been
194+ enabled},
195+ abstract = {The computation of ionic solvation free energies from
196+ atomistic simulations is a surprisingly difficult problem that
197+ has found no satisfactory solution for more than 15 years. The
198+ reason is that the charging free energies evaluated from such
199+ simulations are affected by very large errors. One of these is
200+ related to the choice of a specific convention for summing up
201+ the contributions of solvent charges to the electrostatic
202+ potential in the ionic cavity, namely, on the basis of point
203+ charges within entire solvent molecules (M scheme) or on the
204+ basis of individual point charges (P scheme). The use of an
205+ inappropriate convention may lead to a charge-independent
206+ offset in the calculated potential, which depends on the
207+ details of the summation scheme, on the quadrupole-moment
208+ trace of the solvent molecule, and on the approximate form
209+ used to represent electrostatic interactions in the
210+ system. However, whether the M or P scheme (if any) represents
211+ the appropriate convention is still a matter of on-going
212+ debate. The goal of the present article is to settle this
213+ long-standing controversy by carefully analyzing (both
214+ analytically and numerically) the properties of the
215+ electrostatic potential in molecular liquids (and inside
216+ cavities within them).},
217+}
218+
219+@article{murray,
220+ author = {Hostetler, Michael J. and Wingate, Julia E. and Zhong,
221+ Chuan-Jian and Harris, Jay E. and Vachet, Richard W. and
222+ Clark, Michael R. and Londono, J. David and Green, Stephen
223+ J. and Stokes, Jennifer J. and Wignall, George D. and Glish,
224+ Gary L. and Porter, Marc D. and Evans, Neal D. and Murray,
225+ Royce W.},
226+ title = {Alkanethiolate gold cluster molecules with core diameters from
227+ 1.5 to 5.2~{nm}},
228+ journaltitle = {Langmuir},
229+ date = 1998,
230+ subtitle = {Core and monolayer properties as a function of core size},
231+ volume = 14,
232+ number = 1,
233+ pages = {17-30},
234+ langid = {english},
235+ langidopts = {variant=american},
236+ indextitle = {Alkanethiolate gold cluster molecules},
237+ shorttitle = {Alkanethiolate gold cluster molecules},
238+ annotation = {An \texttt{article} entry with \arabic{author} authors. By
239+ default, long author and editor lists are automatically
240+ truncated. This is configurable},
241+}
242+
243+@article{reese,
244+ author = {Reese, Trevor R.},
245+ title = {Georgia in {Anglo-Spanish} Diplomacy, 1736--1739},
246+ journaltitle = {William and Mary Quarterly},
247+ date = 1958,
248+ series = 3,
249+ volume = 15,
250+ pages = {168-190},
251+ langid = {english},
252+ langidopts = {variant=american},
253+ annotation = {An \texttt{article} entry with a \texttt{series} and a
254+ \texttt{volume} field. Note the format of the series. If the
255+ value of the \texttt{series} field is an integer, this number
256+ is printed as an ordinal and the string \enquote*{series} is
257+ appended automatically},
258+}
259+
260+@article{sarfraz,
261+ author = {M. Sarfraz and M. F. A. Razzak},
262+ title = {Technical section: {An} algorithm for automatic capturing of
263+ the font outlines},
264+ year = 2002,
265+ volume = 26,
266+ number = 5,
267+ pages = {795-804},
268+ issn = {0097-8493},
269+ journal = {Computers and Graphics},
270+ annotation = {An \texttt{article} entry with an \texttt{issn} field},
271+}
272+
273+@article{shore,
274+ author = {Shore, Bradd},
275+ title = {Twice-Born, Once Conceived},
276+ journaltitle = {American Anthropologist},
277+ date = {1991-03},
278+ subtitle = {Meaning Construction and Cultural Cognition},
279+ series = {newseries},
280+ volume = 93,
281+ number = 1,
282+ pages = {9-27},
283+ annotation = {An \texttt{article} entry with \texttt{series},
284+ \texttt{volume}, and \texttt{number} fields. Note the format
285+ of the \texttt{series} which is a localization key},
286+}
287+
288+@article{sigfridsson,
289+ author = {Sigfridsson, Emma and Ryde, Ulf},
290+ title = {Comparison of methods for deriving atomic charges from the
291+ electrostatic potential and moments},
292+ journaltitle = {Journal of Computational Chemistry},
293+ date = 1998,
294+ volume = 19,
295+ number = 4,
296+ pages = {377-395},
297+ doi = {10.1002/(SICI)1096-987X(199803)19:4<377::AID-JCC1>3.0.CO;2-P},
298+ langid = {english},
299+ langidopts = {variant=american},
300+ indextitle = {Methods for deriving atomic charges},
301+ annotation = {An \texttt{article} entry with \texttt{volume},
302+ \texttt{number}, and \texttt{doi} fields. Note that the
303+ \textsc{doi} is transformed into a clickable link if
304+ \texttt{hyperref} support has been enabled},
305+ abstract = {Four methods for deriving partial atomic charges from the
306+ quantum chemical electrostatic potential (CHELP, CHELPG,
307+ Merz-Kollman, and RESP) have been compared and critically
308+ evaluated. It is shown that charges strongly depend on how and
309+ where the potential points are selected. Two alternative
310+ methods are suggested to avoid the arbitrariness in the
311+ point-selection schemes and van der Waals exclusion radii:
312+ CHELP-BOW, which also estimates the charges from the
313+ electrostatic potential, but with potential points that are
314+ Boltzmann-weighted after their occurrence in actual
315+ simulations using the energy function of the program in which
316+ the charges will be used, and CHELMO, which estimates the
317+ charges directly from the electrostatic multipole
318+ moments. Different criteria for the quality of the charges are
319+ discussed.},
320+}
321+
322+@article{spiegelberg,
323+ author = {Spiegelberg, Herbert},
324+ title = {\mkbibquote{Intention} und \mkbibquote{Intentionalit{\"a}t} in
325+ der Scholastik, bei Brentano und Husserl},
326+ journaltitle = {Studia Philosophica},
327+ date = 1969,
328+ volume = 29,
329+ pages = {189-216},
330+ langid = {german},
331+ sorttitle = {Intention und Intentionalitat in der Scholastik, bei Brentano
332+ und Husserl},
333+ indexsorttitle= {Intention und Intentionalitat in der Scholastik, bei Brentano
334+ und Husserl},
335+ shorttitle = {Intention und Intentionalit{\"a}t},
336+ annotation = {An \texttt{article} entry. Note the \texttt{sorttitle} and
337+ \texttt{indexsorttitle} fields and the markup of the quotes in
338+ the database file},
339+}
340+
341+@article{springer,
342+ author = {Springer, Otto},
343+ title = {Mediaeval Pilgrim Routes from {Scandinavia} to {Rome}},
344+ journaltitle = {Mediaeval Studies},
345+ date = 1950,
346+ volume = 12,
347+ pages = {92-122},
348+ langid = {english},
349+ langidopts = {variant=british},
350+ shorttitle = {Mediaeval Pilgrim Routes},
351+ annotation = {A plain \texttt{article} entry},
352+}
353+
354+@article{weinberg,
355+ author = {Weinberg, Steven},
356+ title = {A Model of Leptons},
357+ journaltitle = {Phys.~Rev.~Lett.},
358+ date = 1967,
359+ volume = 19,
360+ pages = {1264-1266},
361+}
362+
363+@article{yoon,
364+ author = {Yoon, Myeong S. and Ryu, Dowook and Kim, Jeongryul and Ahn,
365+ Kyo Han},
366+ title = {Palladium pincer complexes with reduced bond angle strain:
367+ efficient catalysts for the {Heck} reaction},
368+ journaltitle = {Organometallics},
369+ date = 2006,
370+ volume = 25,
371+ number = 10,
372+ pages = {2409-2411},
373+ indextitle = {Palladium pincer complexes},
374+}
375+
376+@book{aristotle:anima,
377+ author = {Aristotle},
378+ title = {De Anima},
379+ date = 1907,
380+ editor = {Hicks, Robert Drew},
381+ publisher = cup,
382+ location = {Cambridge},
383+ keywords = {primary},
384+ langid = {english},
385+ langidopts = {variant=british},
386+ annotation = {A \texttt{book} entry with an \texttt{author} and an
387+ \texttt{editor}},
388+}
389+
390+@book{aristotle:physics,
391+ author = {Aristotle},
392+ title = {Physics},
393+ date = 1929,
394+ translator = {Wicksteed, P. H. and Cornford, F. M.},
395+ publisher = {G. P. Putnam},
396+ location = {New York},
397+ keywords = {primary},
398+ langid = {english},
399+ langidopts = {variant=american},
400+ shorttitle = {Physics},
401+ annotation = {A \texttt{book} entry with a \texttt{translator} field},
402+}
403+
404+@book{aristotle:poetics,
405+ author = {Aristotle},
406+ title = {Poetics},
407+ date = 1968,
408+ editor = {Lucas, D. W.},
409+ series = {Clarendon {Aristotle}},
410+ publisher = {Clarendon Press},
411+ location = {Oxford},
412+ keywords = {primary},
413+ langid = {english},
414+ langidopts = {variant=british},
415+ shorttitle = {Poetics},
416+ annotation = {A \texttt{book} entry with an \texttt{author} and an
417+ \texttt{editor} as well as a \texttt{series} field},
418+}
419+
420+@book{aristotle:rhetoric,
421+ author = {Aristotle},
422+ title = {The Rhetoric of {Aristotle} with a commentary by the late {Edward
423+ Meredith Cope}},
424+ date = 1877,
425+ editor = {Cope, Edward Meredith},
426+ commentator = {Cope, Edward Meredith},
427+ volumes = 3,
428+ publisher = cup,
429+ keywords = {primary},
430+ langid = {english},
431+ langidopts = {variant=british},
432+ sorttitle = {Rhetoric of Aristotle},
433+ indextitle = {Rhetoric of {Aristotle}, The},
434+ shorttitle = {Rhetoric},
435+ annotation = {A commented edition. Note the concatenation of the
436+ \texttt{editor} and \texttt{commentator} fields as well as the
437+ \texttt{volumes}, \texttt{sorttitle}, and \texttt{indextitle}
438+ fields},
439+}
440+
441+@book{augustine,
442+ author = {Augustine, Robert L.},
443+ title = {Heterogeneous catalysis for the synthetic chemist},
444+ date = 1995,
445+ publisher = {Marcel Dekker},
446+ location = {New York},
447+ langid = {english},
448+ langidopts = {variant=american},
449+ shorttitle = {Heterogeneous catalysis},
450+ annotation = {A plain \texttt{book} entry},
451+}
452+
453+@book{averroes/bland,
454+ author = {Averroes},
455+ title = {The Epistle on the Possibility of Conjunction with the Active
456+ Intellect by {Ibn Rushd} with the Commentary of {Moses Narboni}},
457+ date = 1982,
458+ editor = {Bland, Kalman P.},
459+ translator = {Bland, Kalman P.},
460+ series = {Moreshet: Studies in {Jewish} History, Literature and Thought},
461+ number = 7,
462+ publisher = {Jewish Theological Seminary of America},
463+ location = {New York},
464+ keywords = {primary},
465+ langid = {english},
466+ langidopts = {variant=american},
467+ indextitle = {Epistle on the Possibility of Conjunction, The},
468+ shorttitle = {Possibility of Conjunction},
469+ annotation = {A \texttt{book} entry with a \texttt{series} and a
470+ \texttt{number}. Note the concatenation of the \texttt{editor}
471+ and \texttt{translator} fields as well as the
472+ \texttt{indextitle} field},
473+}
474+
475+@book{averroes/hannes,
476+ author = {Averroes},
477+ title = {Des Averro{\"e}s Abhandlung: \mkbibquote{{\"U}ber die
478+ M{\"o}glichkeit der Conjunktion} oder \mkbibquote{{\"U}ber den
479+ materiellen Intellekt}},
480+ date = 1892,
481+ editor = {Hannes, Ludwig},
482+ translator = {Hannes, Ludwig},
483+ annotator = {Hannes, Ludwig},
484+ publisher = {C.~A. Kaemmerer},
485+ location = {Halle an der Saale},
486+ keywords = {primary},
487+ langid = {german},
488+ sorttitle = {Uber die Moglichkeit der Conjunktion},
489+ indexsorttitle= {Uber die Moglichkeit der Conjunktion},
490+ indextitle = {{\"U}ber die M{\"o}glichkeit der Conjunktion},
491+ shorttitle = {{\"U}ber die M{\"o}glichkeit der Conjunktion},
492+ annotation = {An annotated edition. Note the concatenation of the
493+ \texttt{editor}, \texttt{translator}, and \texttt{annotator}
494+ fields. Also note the \texttt{shorttitle},
495+ \texttt{indextitle}, \texttt{sorttitle}, and
496+ \texttt{indexsorttitle} fields},
497+}
498+
499+@book{averroes/hercz,
500+ author = {Averroes},
501+ title = {Drei Abhandlungen {\"u}ber die Conjunction des separaten
502+ Intellects mit dem Menschen},
503+ date = 1869,
504+ editor = {Hercz, J.},
505+ translator = {Hercz, J.},
506+ publisher = {S.~Hermann},
507+ location = {Berlin},
508+ keywords = {primary},
509+ langid = {german},
510+ indexsorttitle= {Drei Abhandlungen uber die Conjunction},
511+ indextitle = {Drei Abhandlungen {\"u}ber die Conjunction},
512+ subtitle = {Von Averroes (Vater und Sohn), aus dem Arabischen
513+ {\"u}bersetzt von Samuel Ibn Tibbon},
514+ shorttitle = {Drei Abhandlungen},
515+ annotation = {A \texttt{book} entry. Note the concatenation of the
516+ \texttt{editor} and \texttt{translator} fields as well as the
517+ \texttt{indextitle} and \texttt{indexsorttitle} fields},
518+}
519+
520+@book{cicero,
521+ author = {Cicero, Marcus Tullius},
522+ title = {De natura deorum. {\"U}ber das Wesen der G{\"o}tter},
523+ date = 1995,
524+ editor = {Blank-Sangmeister, Ursula},
525+ translator = {Blank-Sangmeister, Ursula},
526+ afterword = {Thraede, Klaus},
527+ language = {langlatin and langgerman},
528+ publisher = {Reclam},
529+ location = {Stuttgart},
530+ langid = {german},
531+ indextitle = {De natura deorum},
532+ shorttitle = {De natura deorum},
533+ annotation = {A bilingual edition of Cicero's \emph{De natura deorum}, with
534+ a German translation. Note the format of the \texttt{language}
535+ field in the database file, the concatenation of the
536+ \texttt{editor} and \texttt{translator} fields, and the
537+ \texttt{afterword} field},
538+}
539+
540+@book{coleridge,
541+ author = {Coleridge, Samuel Taylor},
542+ title = {Biographia literaria, or {Biographical} sketches of my literary
543+ life and opinions},
544+ date = 1983,
545+ editor = {Coburn, Kathleen and Engell, James and Bate, W. Jackson},
546+ maintitle = {The collected works of {Samuel Taylor Coleridge}},
547+ volume = 7,
548+ part = 2,
549+ series = {Bollingen Series},
550+ number = 75,
551+ publisher = {Routledge {and} Kegan Paul},
552+ location = {London},
553+ langid = {english},
554+ langidopts = {variant=british},
555+ indextitle = {Biographia literaria},
556+ shorttitle = {Biographia literaria},
557+ annotation = {One (partial) volume of a multivolume book. This is a
558+ \texttt{book} entry with a \texttt{volume} and a \texttt{part}
559+ field which explicitly refers to the second (physical) part of
560+ the seventh (logical) volume. Also note the \texttt{series}
561+ and \texttt{number} fields},
562+}
563+
564+@book{companion,
565+ author = {Goossens, Michel and Mittelbach, Frank and Samarin, Alexander},
566+ title = {The {LaTeX} Companion},
567+ date = 1994,
568+ edition = 1,
569+ publisher = {Addison-Wesley},
570+ location = {Reading, Mass.},
571+ pagetotal = 528,
572+ langid = {english},
573+ langidopts = {variant=american},
574+ sorttitle = {LaTeX Companion},
575+ indextitle = {LaTeX Companion, The},
576+ shorttitle = {LaTeX Companion},
577+ annotation = {A book with three authors. Note the formatting of the author
578+ list. By default, only the first name is reversed in the
579+ bibliography},
580+}
581+
582+@book{cotton,
583+ author = {Cotton, Frank Albert and Wilkinson, Geoffrey and Murillio,
584+ Carlos A. and Bochmann, Manfred},
585+ title = {Advanced inorganic chemistry},
586+ date = 1999,
587+ edition = 6,
588+ publisher = {Wiley},
589+ location = {Chichester},
590+ langid = {english},
591+ langidopts = {variant=british},
592+ annotation = {A \texttt{book} entry with \arabic{author} authors and an
593+ \texttt{edition} field. By default, long \texttt{author} and
594+ \texttt{editor} lists are automatically truncated. This is
595+ configurable},
596+}
597+
598+@book{gerhardt,
599+ author = {Gerhardt, Michael J.},
600+ title = {The Federal Appointments Process},
601+ date = 2000,
602+ publisher = {Duke University Press},
603+ location = {Durham and London},
604+ langid = {english},
605+ langidopts = {variant=american},
606+ sorttitle = {Federal Appointments Process},
607+ indextitle = {Federal Appointments Process, The},
608+ subtitle = {A Constitutional and Historical Analysis},
609+ shorttitle = {Federal Appointments Process},
610+ annotation = {This is a \texttt{book} entry. Note the format of the
611+ \texttt{location} field as well as the \texttt{sorttitle} and
612+ \texttt{indextitle} fields},
613+}
614+
615+@book{gonzalez,
616+ author = {Gonzalez, Ray},
617+ title = {The Ghost of {John Wayne} and Other Stories},
618+ date = 2001,
619+ publisher = {The University of Arizona Press},
620+ location = {Tucson},
621+ isbn = {0-816-52066-6},
622+ langid = {english},
623+ langidopts = {variant=american},
624+ sorttitle = {Ghost of John Wayne and Other Stories},
625+ indextitle = {Ghost of {John Wayne} and Other Stories, The},
626+ shorttitle = {Ghost of {John Wayne}},
627+ annotation = {A collection of short stories. This is a \texttt{book} entry.
628+ Note the \texttt{sorttitle} and \texttt{indextitle} fields in
629+ the database file. There's also an \texttt{isbn} field},
630+}
631+
632+@book{hammond,
633+ author = {Hammond, Christopher},
634+ title = {The basics of crystallography and diffraction},
635+ date = 1997,
636+ publisher = {International Union of Crystallography and Oxford University
637+ Press},
638+ location = {Oxford},
639+ langid = {english},
640+ langidopts = {variant=british},
641+ sorttitle = {Basics of crystallography and diffraction},
642+ indextitle = {Basics of crystallography and diffraction, The},
643+ shorttitle = {Crystallography and diffraction},
644+ annotation = {A \texttt{book} entry. Note the \texttt{sorttitle} and
645+ \texttt{indextitle} fields as well as the format of the
646+ \texttt{publisher} field},
647+}
648+
649+@book{iliad,
650+ author = {Homer},
651+ title = {Die Ilias},
652+ date = 2004,
653+ translator = {Schadewaldt, Wolfgang},
654+ introduction = {Latacz, Joachim},
655+ edition = 3,
656+ publisher = {Artemis \& Winkler},
657+ location = {D{\"u}sseldorf and Z{\"u}rich},
658+ langid = {german},
659+ sorttitle = {Ilias},
660+ indextitle = {Ilias, Die},
661+ shorttitle = {Ilias},
662+ annotation = {A German translation of the \emph{Iliad}. Note the
663+ \texttt{translator} and \texttt{introduction} fields and the
664+ format of the \texttt{location} field in the database
665+ file. Also note the \texttt{sorttitle} and \texttt{indextitle}
666+ fields},
667+}
668+
669+@book{knuth:ct,
670+ author = {Knuth, Donald E.},
671+ title = {Computers \& Typesetting},
672+ date = {1984/1986},
673+ volumes = 5,
674+ publisher = {Addison-Wesley},
675+ location = {Reading, Mass.},
676+ langid = {english},
677+ langidopts = {variant=american},
678+ sortyear = {1984-0},
679+ sorttitle = {Computers & Typesetting},
680+ indexsorttitle= {Computers & Typesetting},
681+ annotation = {A five-volume book cited as a whole. This is a \texttt{book}
682+ entry, note the \texttt{volumes} field},
683+}
684+
685+@book{knuth:ct:a,
686+ author = {Knuth, Donald E.},
687+ title = {The {\TeX} book},
688+ date = 1984,
689+ maintitle = {Computers \& Typesetting},
690+ volume = {A},
691+ publisher = {Addison-Wesley},
692+ location = {Reading, Mass.},
693+ langid = {english},
694+ langidopts = {variant=american},
695+ sortyear = {1984-1},
696+ sorttitle = {Computers & Typesetting A},
697+ indexsorttitle= {The TeXbook},
698+ indextitle = {\protect\TeX book, The},
699+ shorttitle = {\TeX book},
700+ annotation = {The first volume of a five-volume book. Note the
701+ \texttt{sorttitle} and \texttt{sortyear} fields. We want this
702+ volume to be listed after the entry referring to the entire
703+ five-volume set. Also note the \texttt{indextitle} and
704+ \texttt{indexsorttitle} fields. Indexing packages that don't
705+ generate robust index entries require some control sequences
706+ to be protected from expansion},
707+}
708+
709+@book{knuth:ct:b,
710+ author = {Knuth, Donald E.},
711+ title = {\TeX: The Program},
712+ date = 1986,
713+ maintitle = {Computers \& Typesetting},
714+ volume = {B},
715+ publisher = {Addison-Wesley},
716+ location = {Reading, Mass.},
717+ langid = {english},
718+ langidopts = {variant=american},
719+ sortyear = {1986-1},
720+ sorttitle = {Computers & Typesetting B},
721+ indexsorttitle= {TeX: The Program},
722+ shorttitle = {\TeX},
723+ annotation = {The second volume of a five-volume book. Note the
724+ \texttt{sorttitle} and \texttt{sortyear} fields. Also note the
725+ \texttt{indexsorttitle} field},
726+}
727+
728+@book{knuth:ct:c,
729+ author = {Knuth, Donald E.},
730+ title = {The {METAFONTbook}},
731+ date = 1986,
732+ maintitle = {Computers \& Typesetting},
733+ volume = {C},
734+ publisher = {Addison-Wesley},
735+ location = {Reading, Mass.},
736+ langid = {english},
737+ langidopts = {variant=american},
738+ sortyear = {1986-2},
739+ sorttitle = {Computers & Typesetting C},
740+ indextitle = {METAFONTbook, The},
741+ shorttitle = {METAFONTbook},
742+ annotation = {The third volume of a five-volume book. Note the
743+ \texttt{sorttitle} and \texttt{sortyear} fields as well as the
744+ \texttt{indextitle} field},
745+}
746+
747+@book{knuth:ct:d,
748+ author = {Knuth, Donald E.},
749+ title = {METAFONT: The Program},
750+ date = 1986,
751+ maintitle = {Computers \& Typesetting},
752+ volume = {D},
753+ publisher = {Addison-Wesley},
754+ location = {Reading, Mass.},
755+ langid = {english},
756+ langidopts = {variant=american},
757+ sortyear = {1986-3},
758+ sorttitle = {Computers & Typesetting D},
759+ shorttitle = {METAFONT},
760+ annotation = {The fourth volume of a five-volume book. Note the
761+ \texttt{sorttitle} and \texttt{sortyear} fields},
762+}
763+
764+@book{knuth:ct:e,
765+ author = {Knuth, Donald E.},
766+ title = {{Computer Modern} Typefaces},
767+ date = 1986,
768+ maintitle = {Computers \& Typesetting},
769+ volume = {E},
770+ publisher = {Addison-Wesley},
771+ location = {Reading, Mass.},
772+ langid = {english},
773+ langidopts = {variant=american},
774+ sortyear = {1986-4},
775+ sorttitle = {Computers & Typesetting E},
776+ annotation = {The fifth volume of a five-volume book. Note the
777+ \texttt{sorttitle} and \texttt{sortyear} fields},
778+}
779+
780+@book{knuth:ct:related,
781+ author = {Knuth, Donald E.},
782+ title = {Computers \& Typesetting},
783+ date = {1984/1986},
784+ volumes = 5,
785+ publisher = {Addison-Wesley},
786+ location = {Reading, Mass.},
787+ langid = {english},
788+ langidopts = {variant=american},
789+ sortyear = {1984-0},
790+ sorttitle = {Computers & Typesetting},
791+ indexsorttitle= {Computers & Typesetting},
792+ related = {knuth:ct:a,knuth:ct:b,knuth:ct:c,knuth:ct:d,knuth:ct:e},
793+ relatedtype = {multivolume},
794+ annotation = {A five-volume book cited as a whole and related to its
795+ individual volumes. Note the \texttt{related} and
796+ \texttt{relatedtype} fields},
797+}
798+
799+@book{kullback,
800+ author = {Kullback, Solomon},
801+ title = {Information Theory and Statistics},
802+ year = 1959,
803+ publisher = {John Wiley \& Sons},
804+ location = {New York},
805+ langid = {english},
806+ langidopts = {variant=american},
807+}
808+
809+@book{kullback:reprint,
810+ author = {Kullback, Solomon},
811+ title = {Information Theory and Statistics},
812+ year = 1997,
813+ publisher = {Dover Publications},
814+ location = {New York},
815+ origyear = 1959,
816+ origpublisher= {John Wiley \& Sons},
817+ langid = {english},
818+ langidopts = {variant=american},
819+ annotation = {A reprint of the \texttt{kullback} entry. Note the format of
820+ \texttt{origyear} and \texttt{origpublisher}. These fields are
821+ not used by the standard bibliography styles},
822+}
823+
824+@book{kullback:related,
825+ author = {Kullback, Solomon},
826+ title = {Information Theory and Statistics},
827+ year = 1997,
828+ publisher = {Dover Publications},
829+ location = {New York},
830+ langid = {english},
831+ langidopts = {variant=american},
832+ related = {kullback},
833+ relatedtype = {origpubin},
834+ annotation = {A reprint of the \texttt{kullback} entry. Note the format of
835+ the \texttt{related} and \texttt{relatedtype} fields},
836+}
837+
838+@book{malinowski,
839+ author = {Malinowski, Bronis{\l}aw},
840+ title = {Argonauts of the {Western Pacific}},
841+ date = 1972,
842+ edition = 8,
843+ publisher = {Routledge {and} Kegan Paul},
844+ location = {London},
845+ langid = {english},
846+ langidopts = {variant=british},
847+ subtitle = {An account of native enterprise and adventure in the
848+ Archipelagoes of {Melanesian New Guinea}},
849+ shorttitle = {Argonauts},
850+ annotation = {This is a \texttt{book} entry. Note the format of the
851+ \texttt{publisher} and \texttt{edition} fields as well as the
852+ \texttt{subtitle} field},
853+}
854+
855+@book{maron,
856+ author = {Maron, Monika},
857+ title = {Animal Triste},
858+ date = 2000,
859+ translator = {Brigitte Goldstein},
860+ origlanguage = {german},
861+ publisher = {University of Nebraska Press},
862+ location = {Lincoln},
863+ langid = {english},
864+ langidopts = {variant=american},
865+ shorttitle = {Animal Triste},
866+ annotation = {An English translation of a German novel with a French title.
867+ In other words: a \texttt{book} entry with a
868+ \texttt{translator} field. Note the \texttt{origlanguage}
869+ field which is concatenated with the \texttt{translator}},
870+}
871+
872+@book{massa,
873+ author = {Werner Massa},
874+ title = {Crystal structure determination},
875+ date = 2004,
876+ edition = 2,
877+ publisher = {Spinger},
878+ location = {Berlin},
879+ langid = {english},
880+ langidopts = {variant=british},
881+ annotation = {A \texttt{book} entry with an \texttt{edition} field},
882+}
883+
884+@article{moore,
885+ author = {Moore, Gordon E.},
886+ title = {Cramming more components onto integrated circuits},
887+ journaltitle = {Electronics},
888+ year = 1965,
889+ volume = 38,
890+ number = 8,
891+ pages = {114-117},
892+ langid = {english},
893+ langidopts = {variant=american},
894+}
895+
896+@article{moore:related,
897+ author = {Moore, Gordon E.},
898+ title = {Cramming more components onto integrated circuits},
899+ journaltitle = {Proceedings of the {IEEE}},
900+ year = 1998,
901+ volume = 86,
902+ number = 1,
903+ pages = {82-85},
904+ langid = {english},
905+ langidopts = {variant=american},
906+ related = {moore},
907+ relatedtype = {reprintfrom},
908+ annotation = {A reprint of Moore's law. Note the \texttt{related} and
909+ \texttt{relatedtype} fields},
910+}
911+
912+@book{nietzsche:ksa,
913+ author = {Nietzsche, Friedrich},
914+ title = {S{\"a}mtliche Werke},
915+ date = 1988,
916+ editor = {Colli, Giorgio and Montinari, Mazzino},
917+ edition = 2,
918+ volumes = 15,
919+ publisher = dtv # { and Walter de Gruyter},
920+ location = {M{\"u}nchen and Berlin and New York},
921+ langid = {german},
922+ sortyear = {1988-0},
923+ sorttitle = {Werke-00-000},
924+ indexsorttitle= {Samtliche Werke},
925+ subtitle = {Kritische Studienausgabe},
926+ annotation = {The critical edition of Nietzsche's works. This is a
927+ \texttt{book} entry referring to a 15-volume work as a
928+ whole. Note the \texttt{volumes} field and the format of the
929+ \texttt{publisher} and \texttt{location} fields in the
930+ database file. Also note the \texttt{sorttitle} and
931+ \texttt{sortyear} fields which are used to fine-tune the
932+ sorting order of the bibliography. We want this item listed
933+ first in the bibliography},
934+}
935+
936+@book{nietzsche:ksa1,
937+ author = {Nietzsche, Friedrich},
938+ title = {Die Geburt der Trag{\"o}die. Unzeitgem{\"a}{\ss}e
939+ Betrachtungen I--IV. Nachgelassene Schriften 1870--1973},
940+ date = 1988,
941+ editor = {Colli, Giorgio and Montinari, Mazzino},
942+ maintitle = {S{\"a}mtliche Werke},
943+ mainsubtitle = {Kritische Studienausgabe},
944+ volume = 1,
945+ edition = 2,
946+ publisher = dtv # { and Walter de Gruyter},
947+ location = {M{\"u}nchen and Berlin and New York},
948+ langid = {german},
949+ sortyear = {1988-1},
950+ sorttitle = {Werke-01-000},
951+ indexsorttitle= {Samtliche Werke I},
952+ bookauthor = {Nietzsche, Friedrich},
953+ indextitle = {S{\"a}mtliche Werke I},
954+ shorttitle = {S{\"a}mtliche Werke I},
955+ annotation = {A single volume from the critical edition of Nietzsche's
956+ works. This \texttt{book} entry explicitly refers to the first
957+ volume only. Note the \texttt{title} and \texttt{maintitle}
958+ fields. Also note the \texttt{sorttitle} and \texttt{sortyear}
959+ fields. We want this entry to be listed after the entry
960+ referring to the entire edition},
961+}
962+
963+@book{nussbaum,
964+ author = {Nussbaum, Martha},
965+ title = {Aristotle's \mkbibquote{De Motu Animalium}},
966+ date = 1978,
967+ publisher = pup,
968+ location = {Princeton},
969+ keywords = {secondary},
970+ langid = {english},
971+ langidopts = {variant=american},
972+ sorttitle = {Aristotle's De Motu Animalium},
973+ indexsorttitle= {Aristotle's De Motu Animalium},
974+ annotation = {A \texttt{book} entry. Note the \texttt{sorttitle} and
975+ \texttt{indexsorttitle} fields and the markup of the quotes in
976+ the database file},
977+}
978+
979+@book{piccato,
980+ author = {Piccato, Pablo},
981+ title = {City of Suspects},
982+ date = 2001,
983+ publisher = {Duke University Press},
984+ location = {Durham and London},
985+ langid = {english},
986+ langidopts = {variant=american},
987+ subtitle = {Crime in {Mexico City}, 1900--1931},
988+ shorttitle = {City of Suspects},
989+ annotation = {This is a \texttt{book} entry. Note the format of the
990+ \texttt{location} field in the database file},
991+}
992+
993+@book{vangennep,
994+ author = {van Gennep, Arnold},
995+ title = {Les rites de passage},
996+ date = 1909,
997+ publisher = {Nourry},
998+ location = {Paris},
999+ options = {useprefix},
1000+ langid = {french},
1001+ sorttitle = {Rites de passage},
1002+ indextitle = {Rites de passage, Les},
1003+ shorttitle = {Rites de passage},
1004+ annotation = {A \texttt{book} entry. Note the format of the printed name and
1005+ compare the \texttt{useprefix} option in the \texttt{options}
1006+ field as well as \texttt{brandt} and \texttt{geer}},
1007+}
1008+
1009+@book{vangennep:trans,
1010+ author = {van Gennep, Arnold},
1011+ title = {The Rites of Passage},
1012+ year = 1960,
1013+ translator = {Vizedom, Monika B. and Caffee, Gabrielle L.},
1014+ language = {english},
1015+ origlanguage = {french},
1016+ publisher = {University of Chicago Press},
1017+ options = {useprefix},
1018+ indextitle = {Rites of Passage, The},
1019+ sorttitle = {Rites of Passage},
1020+ shorttitle = {Rites of Passage},
1021+ langid = {english},
1022+ langidopts = {variant=american},
1023+ annotation = {A translation of the \texttt{vangennep} entry. Note the
1024+ \texttt{translator} and \texttt{origlanguage} fields. Compare
1025+ with the \texttt{vangennep:related} entry.},
1026+}
1027+
1028+@book{vangennep:related,
1029+ author = {van Gennep, Arnold},
1030+ title = {Les rites de passage},
1031+ date = 1909,
1032+ publisher = {Nourry},
1033+ location = {Paris},
1034+ options = {useprefix},
1035+ langid = {french},
1036+ related = {vizedom:related},
1037+ relatedtype = {bytranslator},
1038+ sorttitle = {Rites de passage},
1039+ indextitle = {Rites de passage, Les},
1040+ shorttitle = {Rites de passage},
1041+ annotation = {A variant of the \texttt{vangennep} entry related to its
1042+ translation. Note the format of the \texttt{related} and
1043+ \texttt{relatedtype} fields},
1044+}
1045+
1046+@book{vizedom:related,
1047+ title = {The Rites of Passage},
1048+ year = 1960,
1049+ translator = {Vizedom, Monika B. and Caffee, Gabrielle L.},
1050+ language = {english},
1051+ publisher = {University of Chicago Press},
1052+ langid = {english},
1053+ langidopts = {variant=american},
1054+ options = {usetranslator},
1055+ related = {vangennep},
1056+ relatedtype = {translationof},
1057+ indextitle = {Rites of Passage, The},
1058+ sorttitle = {Rites of Passage},
1059+ shorttitle = {Rites of Passage},
1060+ annotation = {A translated work from \texttt{vangennep}. Note the format of
1061+ the \texttt{related} and \texttt{relatedtype} fields},
1062+}
1063+
1064+@book{vazques-de-parga,
1065+ author = {V{\'a}zques{ de }Parga, Luis and Lacarra, Jos{\'e} Mar{\'i}a
1066+ and Ur{\'i}a R{\'i}u, Juan},
1067+ title = {Las Peregrinaciones a Santiago de Compostela},
1068+ date = 1993,
1069+ volumes = 3,
1070+ note = {Ed. facs. de la realizada en 1948--49},
1071+ publisher = {Iberdrola},
1072+ location = {Pamplona},
1073+ langid = {spanish},
1074+ sorttitle = {Peregrinaciones a Santiago de Compostela},
1075+ indextitle = {Peregrinaciones a Santiago de Compostela, Las},
1076+ shorttitle = {Peregrinaciones},
1077+ annotation = {A multivolume book cited as a whole. This is a \texttt{book}
1078+ entry with \texttt{volumes}, \texttt{note},
1079+ \texttt{sorttitle}, and \texttt{indextitle} fields},
1080+}
1081+
1082+@book{wilde,
1083+ author = {Wilde, Oscar},
1084+ title = {The Importance of Being Earnest: A Trivial Comedy for Serious
1085+ People},
1086+ year = 1899,
1087+ series = {English and {American} drama of the Nineteenth Century},
1088+ publisher = {Leonard Smithers {and} Company},
1089+ eprint = {4HIWAAAAYAAJ},
1090+ eprinttype = {googlebooks},
1091+ annotation = {A \texttt{book} with \texttt{eprint} and \texttt{eprinttype}
1092+ fields.},
1093+}
1094+
1095+@book{worman,
1096+ author = {Worman, Nancy},
1097+ title = {The Cast of Character},
1098+ date = 2002,
1099+ publisher = {University of Texas Press},
1100+ location = {Austin},
1101+ langid = {english},
1102+ langidopts = {variant=american},
1103+ sorttitle = {Cast of Character},
1104+ indextitle = {Cast of Character, The},
1105+ subtitle = {Style in {Greek} Literature},
1106+ shorttitle = {Cast of Character},
1107+ annotation = {A \texttt{book} entry. Note the \texttt{sorttitle} and
1108+ \texttt{indextitle} fields},
1109+}
1110+
1111+@collection{britannica,
1112+ editor = {Preece, Warren E.},
1113+ title = {The {New Encyclop{\ae}dia Britannica}},
1114+ date = 2003,
1115+ edition = 15,
1116+ volumes = 32,
1117+ publisher = {Encyclop{\ae}dia Britannica},
1118+ location = {Chicago, Ill.},
1119+ options = {useeditor=false},
1120+ label = {EB},
1121+ langid = {english},
1122+ langidopts = {variant=british},
1123+ sorttitle = {Encyclop{\ae}dia Britannica},
1124+ indextitle = {{Encyclop{\ae}dia Britannica}, The {New}},
1125+ shorttitle = {{Encyclop{\ae}dia Britannica}},
1126+ annotation = {This is a \texttt{collection} entry for an encyclopedia. Note
1127+ the \texttt{useeditor} option in the \texttt{options} field as
1128+ well as the \texttt{sorttitle} field. We want this entry to be
1129+ cited and alphabetized by title even though there is an
1130+ editor. In addition to that, we want the title to be
1131+ alphabetized under \enquote*{E} rather than \enquote*{T}. Also
1132+ note the \texttt{label} field which is provided for
1133+ author-year citation styles},
1134+}
1135+
1136+@collection{gaonkar,
1137+ editor = {Gaonkar, Dilip Parameshwar},
1138+ title = {Alternative Modernities},
1139+ date = 2001,
1140+ publisher = {Duke University Press},
1141+ location = {Durham and London},
1142+ isbn = {0-822-32714-7},
1143+ langid = {english},
1144+ langidopts = {variant=american},
1145+ annotation = {This is a \texttt{collection} entry. Note the format of the
1146+ \texttt{location} field in the database file as well as the
1147+ \texttt{isbn} field},
1148+}
1149+
1150+@InCollection{gaonkar:in,
1151+ author = {Gaonkar, Dilip Parameshwar},
1152+ editor = {Gaonkar, Dilip Parameshwar},
1153+ title = {On Alternative Modernities},
1154+ date = 2001,
1155+ booktitle = {Alternative Modernities},
1156+ publisher = {Duke University Press},
1157+ location = {Durham and London},
1158+ isbn = {0-822-32714-7},
1159+ pages = {1-23},
1160+}
1161+
1162+@collection{jaffe,
1163+ editor = {Jaff{\'e}, Philipp},
1164+ title = {Regesta Pontificum Romanorum ab condita ecclesia ad annum post
1165+ Christum natum \textsc{mcxcviii}},
1166+ date = {1885/1888},
1167+ editora = {Loewenfeld, Samuel and Kaltenbrunner, Ferdinand and Ewald,
1168+ Paul},
1169+ edition = 2,
1170+ volumes = 2,
1171+ location = {Leipzig},
1172+ langid = {latin},
1173+ editoratype = {redactor},
1174+ indextitle = {Regesta Pontificum Romanorum},
1175+ shorttitle = {Regesta Pontificum Romanorum},
1176+ annotation = {A \texttt{collection} entry with \texttt{edition} and
1177+ \texttt{volumes} fields. Note the \texttt{editora} and
1178+ \texttt{editoratype} fields},
1179+}
1180+
1181+@collection{westfahl:frontier,
1182+ editor = {Westfahl, Gary},
1183+ title = {Space and Beyond},
1184+ date = 2000,
1185+ subtitle = {The Frontier Theme in Science Fiction},
1186+ publisher = {Greenwood},
1187+ location = {Westport, Conn. and London},
1188+ langid = {english},
1189+ langidopts = {variant=american},
1190+ booktitle = {Space and Beyond},
1191+ booksubtitle = {The Frontier Theme in Science Fiction},
1192+ annotation = {This is a \texttt{collection} entry. Note the format of the
1193+ \texttt{location} field as well as the \texttt{subtitle} and
1194+ \texttt{booksubtitle} fields},
1195+}
1196+
1197+@inbook{kant:kpv,
1198+ title = {Kritik der praktischen Vernunft},
1199+ date = 1968,
1200+ author = {Kant, Immanuel},
1201+ booktitle = {Kritik der praktischen Vernunft. Kritik der Urtheilskraft},
1202+ bookauthor = {Kant, Immanuel},
1203+ maintitle = {Kants Werke. Akademie Textausgabe},
1204+ volume = 5,
1205+ publisher = {Walter de Gruyter},
1206+ location = {Berlin},
1207+ pages = {1-163},
1208+ shorthand = {KpV},
1209+ langid = {german},
1210+ shorttitle = {Kritik der praktischen Vernunft},
1211+ annotation = {An edition of Kant's \emph{Collected Works}, volume five. This
1212+ is an \texttt{inbook} entry which explicitly refers to the
1213+ \emph{Critique of Practical Reason} only, not to the entire
1214+ fifth volume. Note the \texttt{author} and \texttt{bookauthor}
1215+ fields in the database file. By default, the
1216+ \texttt{bookauthor} is omitted if the values of the
1217+ \texttt{author} and \texttt{bookauthor} fields are identical},
1218+}
1219+
1220+@inbook{kant:ku,
1221+ title = {Kritik der Urtheilskraft},
1222+ date = 1968,
1223+ author = {Kant, Immanuel},
1224+ booktitle = {Kritik der praktischen Vernunft. Kritik der Urtheilskraft},
1225+ bookauthor = {Kant, Immanuel},
1226+ maintitle = {Kants Werke. Akademie Textausgabe},
1227+ volume = 5,
1228+ publisher = {Walter de Gruyter},
1229+ location = {Berlin},
1230+ pages = {165-485},
1231+ shorthand = {KU},
1232+ langid = {german},
1233+ annotation = {An edition of Kant's \emph{Collected Works}, volume five. This
1234+ is an \texttt{inbook} entry which explicitly refers to the
1235+ \emph{Critique of Judgment} only, not to the entire fifth
1236+ volume},
1237+}
1238+
1239+@inbook{nietzsche:historie,
1240+ title = {Unzeitgem{\"a}sse Betrachtungen. Zweites St{\"u}ck},
1241+ date = 1988,
1242+ author = {Nietzsche, Friedrich},
1243+ booktitle = {Die Geburt der Trag{\"o}die. Unzeitgem{\"a}{\ss}e
1244+ Betrachtungen I--IV. Nachgelassene Schriften 1870--1973},
1245+ bookauthor = {Nietzsche, Friedrich},
1246+ editor = {Colli, Giorgio and Montinari, Mazzino},
1247+ subtitle = {Vom Nutzen und Nachtheil der Historie f{\"u}r das Leben},
1248+ maintitle = {S{\"a}mtliche Werke},
1249+ mainsubtitle = {Kritische Studienausgabe},
1250+ volume = 1,
1251+ publisher = dtv # { and Walter de Gruyter},
1252+ location = {M{\"u}nchen and Berlin and New York},
1253+ pages = {243-334},
1254+ langid = {german},
1255+ sortyear = {1988-2},
1256+ sorttitle = {Werke-01-243},
1257+ indexsorttitle= {Vom Nutzen und Nachtheil der Historie fur das Leben},
1258+ indextitle = {Vom Nutzen und Nachtheil der Historie f{\"u}r das Leben},
1259+ shorttitle = {Vom Nutzen und Nachtheil der Historie},
1260+ annotation = {A single essay from the critical edition of Nietzsche's works.
1261+ This \texttt{inbook} entry explicitly refers to an essay found
1262+ in the first volume. Note the \texttt{title},
1263+ \texttt{booktitle}, and \texttt{maintitle} fields. Also note
1264+ the \texttt{sorttitle} and \texttt{sortyear} fields. We want
1265+ this entry to be listed after the entry referring to the
1266+ entire first volume},
1267+}
1268+
1269+@incollection{brandt,
1270+ author = {von Brandt, Ahasver and Erich Hoffmann},
1271+ editor = {Ferdinand Seibt},
1272+ title = {Die nordischen L{\"a}nder von der Mitte des 11.~Jahrhunderts
1273+ bis 1448},
1274+ date = 1987,
1275+ booktitle = {Europa im Hoch- und Sp{\"a}tmittelalter},
1276+ series = {Handbuch der europ{\"a}ischen Geschichte},
1277+ number = 2,
1278+ publisher = {Klett-Cotta},
1279+ location = {Stuttgart},
1280+ pages = {884-917},
1281+ options = {useprefix=false},
1282+ langid = {german},
1283+ indexsorttitle= {Nordischen Lander von der Mitte des 11. Jahrhunderts bis
1284+ 1448},
1285+ indextitle = {Nordischen L{\"a}nder von der Mitte des 11.~Jahrhunderts bis
1286+ 1448, Die},
1287+ shorttitle = {Die nordischen L{\"a}nder},
1288+ annotation = {An \texttt{incollection} entry with a \texttt{series} and a
1289+ \texttt{number}. Note the format of the printed name and
1290+ compare the \texttt{useprefix} option in the \texttt{options}
1291+ field as well as \texttt{vangennep}. Also note the
1292+ \texttt{indextitle, and \texttt{indexsorttitle} fields}},
1293+}
1294+
1295+@incollection{hyman,
1296+ author = {Arthur Hyman},
1297+ editor = {O'Meara, Dominic J.},
1298+ title = {Aristotle's Theory of the Intellect and its Interpretation by
1299+ {Averroes}},
1300+ date = 1981,
1301+ booktitle = {Studies in {Aristotle}},
1302+ series = {Studies in Philosophy and the History of Philosophy},
1303+ number = 9,
1304+ publisher = {The Catholic University of America Press},
1305+ location = {Washington, D.C.},
1306+ pages = {161-191},
1307+ keywords = {secondary},
1308+ langid = {english},
1309+ langidopts = {variant=american},
1310+ indextitle = {Aristotle's Theory of the Intellect},
1311+ shorttitle = {Aristotle's Theory of the Intellect},
1312+ annotation = {An \texttt{incollection} entry with a \texttt{series} and
1313+ \texttt{number} field},
1314+}
1315+
1316+@incollection{pines,
1317+ author = {Pines, Shlomo},
1318+ editor = {Twersky, Isadore},
1319+ title = {The Limitations of Human Knowledge According to {Al-Farabi}, {ibn
1320+ Bajja}, and {Maimonides}},
1321+ date = 1979,
1322+ booktitle = {Studies in Medieval {Jewish} History and Literature},
1323+ publisher = hup,
1324+ location = {Cambridge, Mass.},
1325+ pages = {82-109},
1326+ keywords = {secondary},
1327+ langid = {english},
1328+ langidopts = {variant=american},
1329+ indextitle = {Limitations of Human Knowledge According to {Al-Farabi}, {ibn
1330+ Bajja}, and {Maimonides}, The},
1331+ shorttitle = {Limitations of Human Knowledge},
1332+ annotation = {A typical \texttt{incollection} entry. Note the
1333+ \texttt{indextitle} field},
1334+}
1335+
1336+@inproceedings{moraux,
1337+ author = {Moraux, Paul},
1338+ editor = {Lloyd, G. E. R. and Owen, G. E. L.},
1339+ title = {Le \emph{De Anima} dans la tradition gr{\`e}cque},
1340+ date = 1979,
1341+ booktitle = {Aristotle on Mind and the Senses},
1342+ subtitle = {Quelques aspects de l'interpretation du trait{\'e}, de
1343+ Theophraste {\`a} Themistius},
1344+ booktitleaddon= {Proceedings of the Seventh Symposium Aristotelicum},
1345+ eventdate = 1975,
1346+ publisher = cup,
1347+ location = {Cambridge},
1348+ pages = {281-324},
1349+ keywords = {secondary},
1350+ langid = {french},
1351+ indexsorttitle= {De Anima dans la tradition grecque},
1352+ indextitle = {\emph{De Anima} dans la tradition gr{\`e}cque, Le},
1353+ shorttitle = {\emph{De Anima} dans la tradition gr{\`e}cque},
1354+ annotation = {This is a typical \texttt{inproceedings} entry. Note the
1355+ \texttt{booksubtitle}, \texttt{shorttitle},
1356+ \texttt{indextitle}, and \texttt{indexsorttitle} fields. Also
1357+ note the \texttt{eventdate} field.},
1358+}
1359+
1360+@inproceedings{salam,
1361+ author = {Salam, Abdus},
1362+ editor = {Svartholm, Nils},
1363+ title = {Weak and Electromagnetic Interactions},
1364+ date = 1968,
1365+ booktitle = {Elementary particle theory},
1366+ booksubtitle = {Relativistic groups and analyticity},
1367+ booktitleaddon= {Proceedings of the {Eighth Nobel Symposium}},
1368+ eventdate = {1968-05-19/1968-05-25},
1369+ venue = {Aspen{\"a}sgarden, Lerum},
1370+ publisher = {Almquist \& Wiksell},
1371+ location = {Stockholm},
1372+ pages = {367-377},
1373+}
1374+
1375+@manual{cms,
1376+ title = {The {Chicago} Manual of Style},
1377+ date = 2003,
1378+ subtitle = {The Essential Guide for Writers, Editors, and Publishers},
1379+ edition = 15,
1380+ publisher = {University of Chicago Press},
1381+ location = {Chicago, Ill.},
1382+ isbn = {0-226-10403-6},
1383+ label = {CMS},
1384+ langid = {english},
1385+ langidopts = {variant=american},
1386+ sorttitle = {Chicago Manual of Style},
1387+ indextitle = {Chicago Manual of Style, The},
1388+ shorttitle = {Chicago Manual of Style},
1389+ annotation = {This is a \texttt{manual} entry without an \texttt{author} or
1390+ \texttt{editor}. Note the \texttt{label} field in the database
1391+ file which is provided for author-year citation styles. Also
1392+ note the \texttt{sorttitle} and \texttt{indextitle} fields. By
1393+ default, all entries without an \texttt{author} or
1394+ \texttt{editor} are alphabetized by \texttt{title} but we want
1395+ this entry to be alphabetized under \enquote*{C} rather than
1396+ \enquote*{T}. There's also an \texttt{isbn} field},
1397+}
1398+
1399+@online{baez/online,
1400+ author = {Baez, John C. and Lauda, Aaron D.},
1401+ title = {Higher-Dimensional Algebra {V}: 2-Groups},
1402+ date = {2004-10-27},
1403+ version = 3,
1404+ langid = {english},
1405+ langidopts = {variant=american},
1406+ eprinttype = {arxiv},
1407+ eprint = {math/0307200v3},
1408+ annotation = {An \texttt{online} reference from arXiv. Note the
1409+ \texttt{eprint} and \texttt{eprinttype} fields. Compare
1410+ \texttt{baez\slash article} which is the same item given as an
1411+ \texttt{article} entry with eprint information},
1412+}
1413+
1414+@online{ctan,
1415+ title = {CTAN},
1416+ date = 2006,
1417+ url = {http://www.ctan.org},
1418+ subtitle = {The {Comprehensive TeX Archive Network}},
1419+ urldate = {2006-10-01},
1420+ label = {CTAN},
1421+ langid = {english},
1422+ langidopts = {variant=american},
1423+ annotation = {This is an \texttt{online} entry. The \textsc{url}, which is
1424+ given in the \texttt{url} field, is transformed into a
1425+ clickable link if \texttt{hyperref} support has been
1426+ enabled. Note the format of the \texttt{urldate} field
1427+ (\texttt{yyyy-mm-dd}) in the database file. Also note the
1428+ \texttt{label} field which may be used as a fallback by
1429+ citation styles which need an \texttt{author} and\slash or a
1430+ \texttt{year}},
1431+}
1432+
1433+@online{itzhaki,
1434+ author = {Itzhaki, Nissan},
1435+ title = {Some remarks on {'t Hooft's} {S}-matrix for black holes},
1436+ date = {1996-03-11},
1437+ version = 1,
1438+ langid = {english},
1439+ langidopts = {variant=american},
1440+ eprinttype = {arxiv},
1441+ eprint = {hep-th/9603067},
1442+ annotation = {An \texttt{online} reference from arXiv. Note the
1443+ \texttt{eprint} and \texttt{eprinttype} fields. Also note that
1444+ the arXiv reference is transformed into a clickable link if
1445+ \texttt{hyperref} support has been enabled},
1446+ abstract = {We discuss the limitations of 't Hooft's proposal for the
1447+ black hole S-matrix. We find that the validity of the S-matrix
1448+ implies violation of the semi-classical approximation at
1449+ scales large compared to the Planck scale. We also show that
1450+ the effect of the centrifugal barrier on the S-matrix is
1451+ crucial even for large transverse distances.},
1452+}
1453+
1454+@online{markey,
1455+ author = {Markey, Nicolas},
1456+ title = {Tame the {BeaST}},
1457+ date = {2005-10-16},
1458+ url = {http://mirror.ctan.org/info/bibtex/tamethebeast/ttb_en.pdf},
1459+ subtitle = {The {B} to {X} of {BibTeX}},
1460+ version = {1.3},
1461+ urldate = {2006-10-01},
1462+ langid = {english},
1463+ langidopts = {variant=american},
1464+ sorttitle = {Tame the Beast},
1465+ annotation = {An \texttt{online} entry for a tutorial. Note the format of
1466+ the \texttt{date} field (\texttt{yyyy-mm-dd}) in the database
1467+ file.},
1468+}
1469+
1470+@online{wassenberg,
1471+ author = {Wassenberg, Jan and Sanders, Peter},
1472+ title = {Faster Radix Sort via Virtual Memory and Write-Combining},
1473+ date = {2010-08-17},
1474+ version = 1,
1475+ langid = {english},
1476+ langidopts = {variant=american},
1477+ eprinttype = {arxiv},
1478+ eprintclass = {cs.DS},
1479+ eprint = {1008.2849v1},
1480+ annotation = {A recent \texttt{online} reference from arXiv using the new
1481+ (April 2007 onward) identifier format. Note the
1482+ \texttt{eprint}, \texttt{eprinttype}, and \texttt{eprintclass}
1483+ fields. Also note that the arXiv reference is transformed into
1484+ a clickable link if \texttt{hyperref} support has been
1485+ enabled},
1486+ abstract = {Sorting algorithms are the deciding factor for the performance
1487+ of common operations such as removal of duplicates or database
1488+ sort-merge joins. This work focuses on 32-bit integer keys,
1489+ optionally paired with a 32-bit value. We present a fast radix
1490+ sorting algorithm that builds upon a microarchitecture-aware
1491+ variant of counting sort},
1492+}
1493+
1494+@patent{almendro,
1495+ author = {Almendro, Jos{\'e} L. and Mart{\'i}n, Jacinto and S{\'a}nchez,
1496+ Alberto and Nozal, Fernando},
1497+ title = {Elektromagnetisches Signalhorn},
1498+ number = {EU-29702195U},
1499+ date = 1998,
1500+ location = {countryfr and countryuk and countryde},
1501+ langid = {german},
1502+ annotation = {This is a \texttt{patent} entry with a \texttt{location}
1503+ field. The number is given in the \texttt{number} field. Note
1504+ the format of the \texttt{location} field in the database
1505+ file. Compare \texttt{laufenberg}, \texttt{sorace}, and
1506+ \texttt{kowalik}},
1507+}
1508+
1509+@patent{kowalik,
1510+ author = {Kowalik, F. and Isard, M.},
1511+ title = {Estimateur d'un d{\'e}faut de fonctionnement d'un modulateur
1512+ en quadrature et {\'e}tage de modulation l'utilisant},
1513+ number = 9500261,
1514+ date = {1995-01-11},
1515+ type = {patreqfr},
1516+ langid = {french},
1517+ indextitle = {Estimateur d'un d{\'e}faut de fonctionnement},
1518+ annotation = {This is a \texttt{patent} entry for a French patent request
1519+ with a full date. The number is given in the \texttt{number}
1520+ field. Note the format of the \texttt{type} and \texttt{date}
1521+ fields in the database file. Compare \texttt{almendro},
1522+ \texttt{laufenberg}, and \texttt{sorace}},
1523+}
1524+
1525+@patent{laufenberg,
1526+ author = {Laufenberg, Xaver and Eynius, Dominique and Suelzle, Helmut
1527+ and Usbeck, Stephan and Spaeth, Matthias and Neuser-Hoffmann,
1528+ Miriam and Myrzik, Christian and Schmid, Manfred and Nietfeld,
1529+ Franz and Thiel, Alexander and Braun, Harald and Ebner,
1530+ Norbert},
1531+ title = {Elektrische Einrichtung und Betriebsverfahren},
1532+ number = 1700367,
1533+ date = {2006-09-13},
1534+ holder = {{Robert Bosch GmbH} and {Daimler Chrysler AG} and {Bayerische
1535+ Motoren Werke AG}},
1536+ type = {patenteu},
1537+ langid = {german},
1538+ annotation = {This is a \texttt{patent} entry with a \texttt{holder} field.
1539+ Note the format of the \texttt{type} and \texttt{location}
1540+ fields in the database file. Compare \texttt{almendro},
1541+ \texttt{sorace}, and \texttt{kowalik}},
1542+ abstract = {The invention relates to an electric device comprising a
1543+ generator, in particular for use in the vehicle electric
1544+ system of a motor vehicle and a controller for controlling the
1545+ generator voltage. The device is equipped with a control zone,
1546+ in which the voltage is controlled and zones, in which the
1547+ torque is controlled. The invention also relates to methods
1548+ for operating a device of this type.},
1549+ file = {http://v3.espacenet.com/textdoc?IDX=EP1700367},
1550+}
1551+
1552+@patent{sorace,
1553+ author = {Sorace, Ronald E. and Reinhardt, Victor S. and Vaughn, Steven
1554+ A.},
1555+ title = {High-Speed Digital-to-{RF} Converter},
1556+ number = 5668842,
1557+ date = {1997-09-16},
1558+ holder = {{Hughes Aircraft Company}},
1559+ type = {patentus},
1560+ langid = {english},
1561+ langidopts = {variant=american},
1562+ annotation = {This is a \texttt{patent} entry with a \texttt{holder} field.
1563+ Note the format of the \texttt{type} and \texttt{date} fields
1564+ in the database file. Compare \texttt{almendro},
1565+ \texttt{laufenberg}, and \texttt{kowalik}},
1566+}
1567+
1568+@periodical{jcg,
1569+ title = {Computers and Graphics},
1570+ year = 2011,
1571+ issuetitle = {Semantic {3D} Media and Content},
1572+ volume = 35,
1573+ number = 4,
1574+ issn = {0097-8493},
1575+ annotation = {This is a \texttt{periodical} entry with an \texttt{issn}
1576+ field.},
1577+}
1578+
1579+@report{chiu,
1580+ author = {Chiu, Willy W. and Chow, We Min},
1581+ title = {A Hybrid Hierarchical Model of a {Multiple Virtual Storage}
1582+ ({MVS}) Operating System},
1583+ type = {resreport},
1584+ institution = {IBM},
1585+ date = 1978,
1586+ number = {RC-6947},
1587+ langid = {english},
1588+ langidopts = {variant=american},
1589+ sorttitle = {Hybrid Hierarchical Model of a Multiple Virtual Storage (MVS)
1590+ Operating System},
1591+ indextitle = {Hybrid Hierarchical Model, A},
1592+ annotation = {This is a \texttt{report} entry for a research report. Note
1593+ the format of the \texttt{type} field in the database file
1594+ which uses a localization key. The number of the report is
1595+ given in the \texttt{number} field. Also note the
1596+ \texttt{sorttitle} and \texttt{indextitle} fields},
1597+}
1598+
1599+@report{padhye,
1600+ author = {Padhye, Jitendra and Firoiu, Victor and Towsley, Don},
1601+ title = {A Stochastic Model of {TCP Reno} Congestion Avoidance and
1602+ Control},
1603+ type = {techreport},
1604+ institution = {University of Massachusetts},
1605+ date = 1999,
1606+ number = {99-02},
1607+ location = {Amherst, Mass.},
1608+ langid = {english},
1609+ langidopts = {variant=american},
1610+ sorttitle = {A Stochastic Model of TCP Reno Congestion Avoidance and
1611+ Control},
1612+ indextitle = {Stochastic Model of {TCP Reno} Congestion Avoidance and Control,
1613+ A},
1614+ annotation = {This is a \texttt{report} entry for a technical report. Note
1615+ the format of the \texttt{type} field in the database file
1616+ which uses a localization key. The number of the report is
1617+ given in the \texttt{number} field. Also note the
1618+ \texttt{sorttitle} and \texttt{indextitle} fields},
1619+ abstract = {The steady state performance of a bulk transfer TCP flow
1620+ (i.e. a flow with a large amount of data to send, such as FTP
1621+ transfers) may be characterized by three quantities. The first
1622+ is the send rate, which is the amount of data sent by the
1623+ sender in unit time. The second is the throughput, which is
1624+ the amount of data received by the receiver in unit time. Note
1625+ that the throughput will always be less than or equal to the
1626+ send rate due to losses. Finally, the number of non-duplicate
1627+ packets received by the receiver in unit time gives us the
1628+ goodput of the connection. The goodput is always less than or
1629+ equal to the throughput, since the receiver may receive two
1630+ copies of the same packet due to retransmissions by the
1631+ sender. In a previous paper, we presented a simple model for
1632+ predicting the steady state send rate of a bulk transfer TCP
1633+ flow as a function of loss rate and round trip time. In this
1634+ paper, we extend that work in two ways. First, we analyze the
1635+ performance of bulk transfer TCP flows using more precise,
1636+ stochastic analysis. Second, we build upon the previous
1637+ analysis to provide both an approximate formula as well as a
1638+ more accurate stochastic model for the steady state throughput
1639+ of a bulk transfer TCP flow.},
1640+ file = {ftp://gaia.cs.umass.edu/pub/Padhey99-markov.ps},
1641+}
1642+
1643+@thesis{geer,
1644+ author = {de Geer, Ingrid},
1645+ title = {Earl, Saint, Bishop, Skald~-- and Music},
1646+ type = {phdthesis},
1647+ institution = {Uppsala Universitet},
1648+ date = 1985,
1649+ subtitle = {The {Orkney Earldom} of the Twelfth Century. {A} Musicological
1650+ Study},
1651+ location = {Uppsala},
1652+ options = {useprefix=false},
1653+ langid = {english},
1654+ langidopts = {variant=british},
1655+ annotation = {This is a typical \texttt{thesis} entry for a PhD thesis. Note
1656+ the \texttt{type} field in the database file which uses a
1657+ localization key. Also note the format of the printed name and
1658+ compare the \texttt{useprefix} option in the \texttt{options}
1659+ field as well as \texttt{vangennep}},
1660+}
1661+
1662+@thesis{loh,
1663+ author = {Loh, Nin C.},
1664+ title = {High-Resolution Micromachined Interferometric Accelerometer},
1665+ type = {mathesis},
1666+ institution = {Massachusetts Institute of Technology},
1667+ date = 1992,
1668+ location = {Cambridge, Mass.},
1669+ langid = {english},
1670+ langidopts = {variant=american},
1671+ annotation = {This is a typical \texttt{thesis} entry for an MA thesis. Note
1672+ the \texttt{type} field in the database file which uses a
1673+ localization key},
1674+}
test/command/biblatex-inproceedings.md+1−1
@@ -63,7 +63,7 @@ references:
63 publisher-place: Cambridge
63 publisher-place: Cambridge
64 title: "Le *De Anima* dans la tradition grècque: Quelques aspects de
64 title: "Le *De Anima* dans la tradition grècque: Quelques aspects de
65 l'interpretation du traité, de Theophraste à Themistius"
65 l'interpretation du traité, de Theophraste à Themistius"
66− title-short: "*De Anima* dans la tradition grècque"
66+ title-short: *De Anima* dans la tradition grècque
67 type: paper-conference
67 type: paper-conference
68- author:
68- author:
69 - family: Salam
69 - family: Salam
test/command/biblatex-jaffe.md+2−2
@@ -72,8 +72,8 @@ references:
72 language: la
72 language: la
73 number-of-volumes: 2
73 number-of-volumes: 2
74 publisher-place: Leipzig
74 publisher-place: Leipzig
75− title: Regesta Pontificum Romanorum ab condita ecclesia ad annum post
75+ title: "Regesta Pontificum Romanorum ab condita ecclesia ad annum post
76− Christum natum [mcxcviii]{.smallcaps}
76+ Christum natum [mcxcviii]{.smallcaps}"
77 title-short: Regesta Pontificum Romanorum
77 title-short: Regesta Pontificum Romanorum
78 type: book
78 type: book
79---
79---
test/command/biblatex-moraux.md+1−1
@@ -86,7 +86,7 @@ references:
86 publisher-place: Cambridge
86 publisher-place: Cambridge
87 title: "Le *De Anima* dans la tradition grècque: Quelques aspects de
87 title: "Le *De Anima* dans la tradition grècque: Quelques aspects de
88 l'interpretation du traité, de Theophraste à Themistius"
88 l'interpretation du traité, de Theophraste à Themistius"
89− title-short: "*De Anima* dans la tradition grècque"
89+ title-short: *De Anima* dans la tradition grècque
90 type: paper-conference
90 type: paper-conference
91---
91---
92
92
test/command/biblatex-nussbaum.mdnew file+63
@@ -0,0 +1,63 @@
1+```
2+% pandoc -f biblatex -t markdown -s
3+@comment{
4+
5+Adapted from biblatex-example.bib
6+
7+
8+Formatted with pandoc and chicago-author-date.csl, 2013-10-23:
9+
10+(Nussbaum 1978)
11+
12+Nussbaum, Martha. 1978. *Aristotle’s “De Motu Animalium”*. Princeton:
13+Princeton University Press.
14+
15+
16+Formatted with pandoc and apa.csl, 2013-10-23:
17+
18+(Nussbaum, 1978)
19+
20+Nussbaum, M. (1978). *Aristotle’s “De Motu Animalium”*. Princeton:
21+Princeton University Press.
22+
23+
24+}
25+
26+@string{ pup = {Princeton University Press} }
27+
28+@Book{nussbaum,
29+ author = {Nussbaum, Martha},
30+ title = {Aristotle's \mkbibquote{De Motu Animalium}},
31+ date = 1978,
32+ publisher = pup,
33+ location = {Princeton},
34+ keywords = {secondary},
35+ hyphenation = {american},
36+ sorttitle = {Aristotle's De Motu Animalium},
37+ indexsorttitle= {Aristotle's De Motu Animalium},
38+ annotation = {A book entry. Note the sorttitle and
39+ indexsorttitle fields and the markup of the quotes in
40+ the database file},
41+}
42+
43+^D
44+---
45+nocite: "[@*]"
46+references:
47+- annote: A book entry. Note the sorttitle and indexsorttitle fields and
48+ the markup of the quotes in the database file
49+ author:
50+ - family: Nussbaum
51+ given: Martha
52+ id: nussbaum
53+ issued: 1978
54+ keyword: secondary
55+ language: en-US
56+ publisher: Princeton University Press
57+ publisher-place: Princeton
58+ title: "Aristotle's \"De Motu Animalium\""
59+ type: book
60+---
61+
62+
63+```
test/command/biblatex-quotes.md+1−1
@@ -36,7 +36,7 @@ references:
36 language: en-US
36 language: en-US
37 publisher: Princeton University Press
37 publisher: Princeton University Press
38 publisher-place: Princeton
38 publisher-place: Princeton
39− title: Aristotle's "De Motu Animalium"
39+ title: "Aristotle's \"De Motu Animalium\""
40 type: book
40 type: book
41---
41---
42
42
test/command/biblatex-sigfridsson.md+1−1
@@ -90,7 +90,7 @@ references:
90 - family: Ryde
90 - family: Ryde
91 given: Ulf
91 given: Ulf
92 container-title: Journal of Computational Chemistry
92 container-title: Journal of Computational Chemistry
93− doi: "10.1002/(SICI)1096-987X(199803)19:4\\<377::AID-JCC1>3.0.CO;2-P"
93+ doi: "10.1002/(SICI)1096-987X(199803)19:4\\<377::AID-JCC1\\>3.0.CO;2-P"
94 id: sigfridsson
94 id: sigfridsson
95 issue: 4
95 issue: 4
96 issued: 1998
96 issued: 1998
test/command/biblatex-spiegelberg.md+2−2
@@ -63,8 +63,8 @@ references:
63 issued: 1969
63 issued: 1969
64 language: de-DE
64 language: de-DE
65 page: 189-216
65 page: 189-216
66− title: "\"Intention\" und \"Intentionalität\" in der Scholastik, bei
66+ title: "Intention" und "Intentionalität" in der Scholastik, bei
67− Brentano und Husserl"
67+ Brentano und Husserl
68 title-short: Intention und Intentionalität
68 title-short: Intention und Intentionalität
69 type: article-journal
69 type: article-journal
70 volume: 29
70 volume: 29
test/command/biblatex-test-case-conversion.md+2−2
@@ -63,9 +63,9 @@ references:
63 id: item1
63 id: item1
64 issued: 2013
64 issued: 2013
65 language: en-US
65 language: en-US
66− title: A title, in English, with a Proper Name and an ACRONYM and a
66+ title: "A title, in English, with a Proper Name and an ACRONYM and a
67 [camelCase]{.nocase} word and some units, 400 [nm]{.nocase},
67 [camelCase]{.nocase} word and some units, 400 [nm]{.nocase},
68− 3 [cm]{.nocase}, and a quote, *Alea [iacta est]{.nocase}*
68+ 3 [cm]{.nocase}, and a quote, *Alea [iacta est]{.nocase}*"
69 type: article-journal
69 type: article-journal
70---
70---
71
71
test/command/biblatex-textnormal.md+1−1
@@ -9,7 +9,7 @@
9nocite: "[@*]"
9nocite: "[@*]"
10references:
10references:
11- id: item1
11- id: item1
12− title: The title [of this book]{.nodecor}
12+ title: "The title [of this book]{.nodecor}"
13 type: book
13 type: book
14---
14---
15
15
test/command/chap1/spider.pngdeleted

Binary file not shown.

test/command/chap1/text.mddeleted−17
@@ -1,17 +0,0 @@
1−# Chapter one
2−
3−A spider: ![spider](spider.png)
4−
5−Another spider: ![another spider][refspider]
6−
7−The moon: ![moon](../../lalune.jpg)
8−
9−Link to [spider picture](spider.png).
10−
11−URL left alone: [manual](https://pandoc.org/MANUAL.html).
12−
13−Absolute path left alone: [absolute](/foo/bar/baz.png).
14−
15−Link to fragment: [chapter two](#chapter-two).
16−
17−Empty path: [empty]().
test/command/chap2/spider.pngdeleted

Binary file not shown.

test/command/chap2/text.mddeleted−5
@@ -1,5 +0,0 @@
1−# Chapter two
2−
3−A spider: ![spider](spider.png)
4−
5−[refspider]: spider.png
test/command/defaults-inheritance-2.md+1−1
@@ -1,5 +1,5 @@
1```
1```
2−% pandoc -d command/defaults6 2>&1
2+% pandoc -d command/defaults6
3^D
3^D
4Error: Circular defaults file reference in 'command/defaults7.yaml'
4Error: Circular defaults file reference in 'command/defaults7.yaml'
5```
5```
test/command/mmd-metadata.mddeleted−20
@@ -1,20 +0,0 @@
1−```
2−% pandoc -f markdown_mmd -t markdown -s
3−Title: Blah blah blah
4−Author: Doo de Doo
5−Base Header Level: 1
6−Bibliography: Pubs.bib
7−Lang: en-GB
8−
9−body
10−^D
11−---
12−author: Doo de Doo
13−baseheaderlevel: 1
14−bibliography: Pubs.bib
15−lang: en-GB
16−title: Blah blah blah
17−---
18−
19−body
20−```
test/command/newif.mddeleted−55
@@ -1,55 +0,0 @@
1−```
2−% pandoc -f latex -t plain
3−\iftrue
4−should print
5−\iftrue
6−should print
7−\else
8−should not print
9−\fi
10−\else
11−should not print
12−\fi
13−
14−\iffalse
15−should not print
16−\else
17−\iftrue
18−should print
19−\else
20−should not print
21−\fi
22−\fi
23−
24−\newif\ifepub
25−
26−\ifepub
27−should not print
28−\fi
29−
30−\epubtrue
31−
32−\ifepub
33−should print
34−\else
35−should not print
36−\fi
37−
38−\epubfalse
39−
40−\ifepub
41−should not print
42−\else
43−should print
44−\fi
45−^D
46−should print
47−
48−should print
49−
50−should print
51−
52−should print
53−
54−should print
55−```
test/command/pandoc-citeproc-119.md+1−1
@@ -1,7 +1,7 @@
1```
1```
2% pandoc --citeproc -t markdown-citations
2% pandoc --citeproc -t markdown-citations
3---
3---
4−bibliography: 'command/averroes.bib'
4+bibliography: 'command/biblatex-examples.bib'
5csl: command/apa.csl
5csl: command/apa.csl
6---
6---
7
7
test/command/pandoc-citeproc-320a.md+3−3
@@ -49,7 +49,7 @@ references:
49Foo [@item1; @item2; @item3; @item4; @item5; @item6; @item7; @item8].
49Foo [@item1; @item2; @item3; @item4; @item5; @item6; @item7; @item8].
50^D
50^D
51Foo (al-ʾUdhrī, n.d.; al-ʿUdhrī, n.d.; al-\'Udhrī, n.d.; al-'Udhrī,
51Foo (al-ʾUdhrī, n.d.; al-ʿUdhrī, n.d.; al-\'Udhrī, n.d.; al-'Udhrī,
52−n.d.a, n.d.b; Uch, n.d.; Uebel, n.d.; Zzz, n.d.).
52+n.d.; al-'Udhrī, n.d.; Uch, n.d.; Uebel, n.d.; Zzz, n.d.).
53
53
54::: {#refs .references .csl-bib-body .hanging-indent}
54::: {#refs .references .csl-bib-body .hanging-indent}
55::: {#ref-item6 .csl-entry}
55::: {#ref-item6 .csl-entry}
@@ -69,11 +69,11 @@ Uch, Ann. n.d.
69:::
69:::
70
70
71::: {#ref-item4 .csl-entry}
71::: {#ref-item4 .csl-entry}
72−'Udhrī, Jamīl al-. n.d.a.
72+'Udhrī, Jamīl al-. n.d.
73:::
73:::
74
74
75::: {#ref-item5 .csl-entry}
75::: {#ref-item5 .csl-entry}
76−---------. n.d.b.
76+'Udhrī, Jamīl al-. n.d.
77:::
77:::
78
78
79::: {#ref-item7 .csl-entry}
79::: {#ref-item7 .csl-entry}
test/command/pandoc-citeproc-322.md+1−1
@@ -19,7 +19,7 @@ references:
19 type: 'article-journal'
19 type: 'article-journal'
20---
20---
21
21
22−Foo [@timmory__justice_1950].
22+Foo[@timmory__justice_1950].
23^D
23^D
24Foo.[^1]
24Foo.[^1]
25
25
test/command/pandoc-citeproc-356.md+7−2
@@ -15,6 +15,11 @@ references:
15
15
16[@bar]
16[@bar]
17^D
17^D
18−[WARNING] Citeproc: citation bar not found
18+(Alice 2042)
19−(**bar?**)
19+
20+::: {#refs .references .csl-bib-body .hanging-indent}
21+::: {#ref-foo .csl-entry}
22+Alice. 2042.
23+:::
24+:::
20```
25```
test/command/pandoc-citeproc-65.md+1−1
@@ -14,7 +14,7 @@ references:
14 id: 'stotz:1996handbuch'
14 id: 'stotz:1996handbuch'
15 issued:
15 issued:
16 literal: 1996_2004
16 literal: 1996_2004
17− language: de
17+ language: German
18 number-of-volumes: 5
18 number-of-volumes: 5
19 publisher: Beck
19 publisher: Beck
20 publisher-place: Munich
20 publisher-place: Munich
test/command/pandoc-citeproc-70.md+2−2
@@ -22,7 +22,7 @@ references:
22 issued:
22 issued:
23 date-parts:
23 date-parts:
24 - - 2009
24 - - 2009
25− language: fr
25+ language: French
26 page: '155--174'
26 page: '155--174'
27 publisher: 'Fédération Internationale des Instituts d''Études
27 publisher: 'Fédération Internationale des Instituts d''Études
28 Médiévales'
28 Médiévales'
@@ -42,7 +42,7 @@ references:
42 issued:
42 issued:
43 date-parts:
43 date-parts:
44 - - 1955
44 - - 1955
45− language: la
45+ language: Latin
46 note: 'ArticleType: research-article / Full publication date: 1955 /
46 note: 'ArticleType: research-article / Full publication date: 1955 /
47 Copyright © 1955 Fordham University'
47 Copyright © 1955 Fordham University'
48 page: '163--193'
48 page: '163--193'
test/command/pandoc-citeproc-chicago-author-date.md+7−7
@@ -54,14 +54,14 @@ References {#references .unnumbered}
54
54
55([**nonexistent?**](#ref-nonexistent))
55([**nonexistent?**](#ref-nonexistent))
56
56
57−Doe ([2005](#ref-item1)) says blah.
57+[Doe](#ref-item1) ([2005](#ref-item1)) says blah.
58
58
59−Doe ([2005, 30](#ref-item1)) says blah.
59+[Doe](#ref-item1) ([2005, 30](#ref-item1)) says blah.
60
60
61−Doe ([2005, 30](#ref-item1), with suffix) says blah.
61+[Doe](#ref-item1) ([2005, 30](#ref-item1), with suffix) says blah.
62
62
63−Doe ([2005](#ref-item1); [2006, 30](#ref-item2); see also [Doe and Roe
63+[Doe](#ref-item1) ([2005](#ref-item1); [2006, 30](#ref-item2); see also
64−2007](#ref-пункт3)) says blah.
64+[Doe and Roe 2007](#ref-пункт3)) says blah.
65
65
66In a note.[^1]
66In a note.[^1]
67
67
@@ -98,8 +98,8 @@ edited by Sam Smith. Oxford: Oxford University Press.
98:::
98:::
99:::
99:::
100
100
101−[^1]: Doe and Roe ([2007, 12](#ref-пункт3)) and a citation without
101+[^1]: [Doe and Roe](#ref-пункт3) ([2007, 12](#ref-пункт3)) and a
102− locators ([Doe and Roe 2007](#ref-пункт3)).
102+ citation without locators ([Doe and Roe 2007](#ref-пункт3)).
103
103
104[^2]: Some citations (see [Doe 2005, chap. 3](#ref-item1);
104[^2]: Some citations (see [Doe 2005, chap. 3](#ref-item1);
105 [2006](#ref-item2); [Doe and Roe 2007](#ref-пункт3)).
105 [2006](#ref-item2); [Doe and Roe 2007](#ref-пункт3)).
test/command/pandoc-citeproc-chicago-fullnote-bibliography.md+7−6
@@ -55,13 +55,13 @@ References {#references .unnumbered}
55
55
56[^2]
56[^2]
57
57
58−John Doe[^3] says blah.
58+[John Doe](#ref-item1)[^3] says blah.
59
59
60−Doe[^4] says blah.
60+[Doe](#ref-item1)[^4] says blah.
61
61
62−Doe[^5] says blah.
62+[Doe](#ref-item1)[^5] says blah.
63
63
64−Doe[^6] says blah.
64+[Doe](#ref-item1)[^6] says blah.
65
65
66In a note.[^7]
66In a note.[^7]
67
67
@@ -112,8 +112,9 @@ Sam Smith. Oxford: Oxford University Press, 2007.
112 Roe, "Why Water Is Wet," in *Third Book*, ed. Sam Smith (Oxford:
112 Roe, "Why Water Is Wet," in *Third Book*, ed. Sam Smith (Oxford:
113 Oxford University Press, 2007)](#ref-пункт3).
113 Oxford University Press, 2007)](#ref-пункт3).
114
114
115−[^7]: Doe and Roe, ["Why Water Is Wet," 12](#ref-пункт3) and a citation
115+[^7]: [Doe and Roe](#ref-пункт3), ["Why Water Is Wet," 12](#ref-пункт3)
116− without locators ([Doe and Roe, "Why Water Is Wet"](#ref-пункт3)).
116+ and a citation without locators ([Doe and Roe, "Why Water Is
117+ Wet"](#ref-пункт3)).
117
118
118[^8]: See [Doe, *First Book*, chap. 3](#ref-item1); also [Doe and Roe,
119[^8]: See [Doe, *First Book*, chap. 3](#ref-item1); also [Doe and Roe,
119 "Why Water Is Wet," 34--35](#ref-пункт3).
120 "Why Water Is Wet," 34--35](#ref-пункт3).
test/command/svg.md+1−1
@@ -2,7 +2,7 @@
2% pandoc -f latex -t icml
2% pandoc -f latex -t icml
3\includegraphics{command/corrupt.svg}
3\includegraphics{command/corrupt.svg}
4^D
4^D
5−[WARNING] Could not determine image size for command/corrupt.svg: could not determine image type
5+[WARNING] Could not determine image size for 'command/corrupt.svg': could not determine image type
6<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/Paragraph">
6<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/Paragraph">
7 <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">
7 <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">
8 <Rectangle Self="uec" StrokeWeight="0" ItemTransform="1 0 0 1 150 -100">
8 <Rectangle Self="uec" StrokeWeight="0" ItemTransform="1 0 0 1 150 -100">
test/command/toc.md+2−2
@@ -31,7 +31,7 @@
31
31
32## b
32## b
33
33
34−::: interior
34+::: {.interior}
35# C
35# C
36
36
37## cc
37## cc
@@ -39,7 +39,7 @@
39# D
39# D
40:::
40:::
41
41
42−::: blue
42+::: {.blue}
43# E
43# E
44
44
45## e
45## e
test/command/unicode-collation.mddeleted−130
@@ -1,130 +0,0 @@
1−```
2−% pandoc --citeproc -t plain
3−---
4−lang: en-US
5−csl: command/apa.csl
6−references:
7−- id: a1
8− type: book
9− author:
10− - family: Ubina
11− given: A. John
12− issued: 1985
13−- id: a2
14− type: book
15− author:
16− - family: Über
17− given: Aglaia
18− issued: 1996
19−- id: a3
20− type: book
21− author:
22− - family: Oñate
23− given: José
24− issued: 1985
25−- id: a4
26− type: book
27− author:
28− - family: Onush
29− given: Frank
30− issued: 2002
31−- id: a5
32− type: book
33− author:
34− - family: O'Neil
35− given: Timothy
36− issued: 2010
37−---
38−
39−[@a1;@a2;@a3;@a4;@a5]
40−^D
41−(O’Neil, 2010; Oñate, 1985; Onush, 2002; Über, 1996; Ubina, 1985)
42−
43−O’Neil, T. (2010).
44−
45−Oñate, J. (1985).
46−
47−Onush, F. (2002).
48−
49−Über, A. (1996).
50−
51−Ubina, A. J. (1985).
52−```
53−
54−```
55−% pandoc --citeproc -t plain
56−---
57−lang: es
58−csl: command/apa.csl
59−references:
60−- id: a1
61− type: book
62− author:
63− - family: Ubina
64− given: A. John
65− issued: 1985
66−- id: a2
67− type: book
68− author:
69− - family: Über
70− given: Aglaia
71− issued: 1996
72−- id: a3
73− type: book
74− author:
75− - family: Oñate
76− given: José
77− issued: 1985
78−- id: a4
79− type: book
80− author:
81− - family: Onush
82− given: Frank
83− issued: 2002
84−- id: a5
85− type: book
86− author:
87− - family: O'Neil
88− given: Timothy
89− issued: 2010
90−---
91−
92−[@a1;@a2;@a3;@a4;@a5]
93−^D
94−(O’Neil, 2010; Onush, 2002; Oñate, 1985; Über, 1996; Ubina, 1985)
95−
96−O’Neil, T. (2010).
97−
98−Onush, F. (2002).
99−
100−Oñate, J. (1985).
101−
102−Über, A. (1996).
103−
104−Ubina, A. J. (1985).
105−```
106−
107−```
108−% pandoc -C -t plain
109−---
110−nocite: '@*'
111−lang: fr-FR-u-kb-true
112−references:
113−- id: cote
114− author: cote
115−- id: côte
116− author: côte
117−- id: coté
118− author: coté
119−- id: côté
120− author: côté
121−...
122−^D
123−cote. s. d.
124−
125−côte. s. d.
126−
127−coté. s. d.
128−
129−côté. s. d.
130−```
test/docx/0_level_headers.native+2−2
@@ -1,6 +1,6 @@
1[Table ("",[],[]) (Caption Nothing
1[Table ("",[],[]) (Caption Nothing
2 [])
2 [])
3− [(AlignDefault,ColWidth 1.0)]
3+ [(AlignDefault,ColWidthDefault)]
4 (TableHead ("",[],[])
4 (TableHead ("",[],[])
5 [])
5 [])
6 [(TableBody ("",[],[]) (RowHeadColumns 0)
6 [(TableBody ("",[],[]) (RowHeadColumns 0)
@@ -49,4 +49,4 @@
49,Para [Strong [Str "Table",Space,Str "Page"]]
49,Para [Strong [Str "Table",Space,Str "Page"]]
50,Para [Strong [Str "No",Space,Str "table",Space,Str "of",Space,Str "figures",Space,Str "entries",Space,Str "found."]]
50,Para [Strong [Str "No",Space,Str "table",Space,Str "of",Space,Str "figures",Space,Str "entries",Space,Str "found."]]
51,Header 1 ("introduction",[],[]) [Str "Introduction"]
51,Header 1 ("introduction",[],[]) [Str "Introduction"]
52−,Para [Str "Nothing",Space,Str "to",Space,Str "introduce,",Space,Str "yet."]]
52+,Para [Str "Nothing",Space,Str "to",Space,Str "introduce,",Space,Str "yet."]]
test/docx/golden/block_quotes.docx

Binary file not shown.

test/docx/golden/codeblock.docx

Binary file not shown.

test/docx/golden/comments.docx

Binary file not shown.

test/docx/golden/custom_style_no_reference.docx

Binary file not shown.

test/docx/golden/custom_style_preserve.docx

Binary file not shown.

test/docx/golden/custom_style_reference.docx

Binary file not shown.

test/docx/golden/definition_list.docx

Binary file not shown.

test/docx/golden/document-properties-short-desc.docx

Binary file not shown.

test/docx/golden/document-properties.docx

Binary file not shown.

test/docx/golden/headers.docx

Binary file not shown.

test/docx/golden/image.docx

Binary file not shown.

test/docx/golden/inline_code.docx

Binary file not shown.

test/docx/golden/inline_formatting.docx

Binary file not shown.

test/docx/golden/inline_images.docx

Binary file not shown.

test/docx/golden/link_in_notes.docx

Binary file not shown.

test/docx/golden/links.docx

Binary file not shown.

test/docx/golden/lists.docx

Binary file not shown.

test/docx/golden/lists_continuing.docx

Binary file not shown.

test/docx/golden/lists_multiple_initial.docx

Binary file not shown.

test/docx/golden/lists_restarting.docx

Binary file not shown.

test/docx/golden/nested_anchors_in_header.docx

Binary file not shown.

test/docx/golden/notes.docx

Binary file not shown.

test/docx/golden/raw-blocks.docx

Binary file not shown.

test/docx/golden/raw-bookmarks.docx

Binary file not shown.

test/docx/golden/table_one_row.docx

Binary file not shown.

test/docx/golden/table_with_list_cell.docx

Binary file not shown.

test/docx/golden/tables-default-widths.docxdeleted

Binary file not shown.

test/docx/golden/tables.docx

Binary file not shown.

test/docx/golden/track_changes_deletion.docx

Binary file not shown.

test/docx/golden/track_changes_insertion.docx

Binary file not shown.

test/docx/golden/track_changes_move.docx

Binary file not shown.

test/docx/golden/track_changes_scrubbed_metadata.docx

Binary file not shown.

test/docx/golden/unicode.docx

Binary file not shown.

test/docx/golden/verbatim_subsuper.docx

Binary file not shown.

test/docx/image_vml_as_object.docxdeleted

Binary file not shown.

test/docx/image_vml_as_object.nativedeleted−2
@@ -1,2 +0,0 @@
1−[Para [Str "Test",Space,Str "with",Space,Str "object",Space,Str "as",Space,Str "image:"]
2−,Para [Image ("",[],[]) [] ("media/image1.emf","")]]
test/docx/sdt_elements.native+10−9
@@ -1,19 +1,20 @@
1[Table ("",[],[]) (Caption Nothing
1[Table ("",[],[]) (Caption Nothing
2 [])
2 [])
3− [(AlignDefault,ColWidth 0.22069570301081556)
3+ [(AlignDefault,ColWidthDefault)
4− ,(AlignDefault,ColWidth 0.22069570301081556)
4+ ,(AlignDefault,ColWidthDefault)
5− ,(AlignDefault,ColWidth 0.5586085939783689)]
5+ ,(AlignDefault,ColWidthDefault)]
6 (TableHead ("",[],[])
6 (TableHead ("",[],[])
7+ [])
8+ [(TableBody ("",[],[]) (RowHeadColumns 0)
9+ []
7− [Row ("",[],[])
10+ [Row ("",[],[])
8 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
9 [Plain [Strong [Str "col1Header"]]]
12 [Plain [Strong [Str "col1Header"]]]
10 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11 [Plain [Strong [Str "col2Header"]]]
14 [Plain [Strong [Str "col2Header"]]]
12 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
15 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13− [Plain [Strong [Str "col3Header"]]]]])
16+ [Plain [Strong [Str "col3Header"]]]]
14− [(TableBody ("",[],[]) (RowHeadColumns 0)
15− []
16− [Row ("",[],[])
17+ ,Row ("",[],[])
17 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
18 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
18 [Plain [Str "col1",Space,Str "content"]]
19 [Plain [Str "col1",Space,Str "content"]]
19 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
20 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
@@ -21,4 +22,4 @@
21 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
22 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
22 [Plain [Str "col3",Space,Str "content"]]]])]
23 [Plain [Str "col3",Space,Str "content"]]]])]
23 (TableFoot ("",[],[])
24 (TableFoot ("",[],[])
24− [])]
25+ [])]
test/docx/table_captions_no_field.docxdeleted

Binary file not shown.

test/docx/table_captions_no_field.nativedeleted−34
@@ -1,34 +0,0 @@
1−[Para [Str "See",Space,Str "Table",Space,Str "5.1."]
2−,Para [Str "Table",Space,Str "5.1"]
3−,Table ("",[],[]) (Caption Nothing
4− [])
5− [(AlignDefault,ColWidth 0.7605739372523825)
6− ,(AlignDefault,ColWidth 0.11971303137380876)
7− ,(AlignDefault,ColWidth 0.11971303137380876)]
8− (TableHead ("",[],[])
9−[Row ("",[],[])
10− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11− []
12− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13− [Plain [Str "Count"]]
14− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
15− [Plain [Str "%"]]]])
16− [(TableBody ("",[],[]) (RowHeadColumns 0)
17− []
18− [Row ("",[],[])
19− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
20− [Plain [Str "First",Space,Str "option"]]
21− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
22− [Plain [Str "242"]]
23− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
24− [Plain [Str "45"]]]
25−,Row ("",[],[])
26− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
27− [Plain [Str "Second",Space,Str "option"]]
28− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
29− [Plain [Str "99"]]
30− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
31− [Plain [Str "18"]]]])]
32− (TableFoot ("",[],[])
33− [])
34−,Header 2 ("section", [], []) []]
test/docx/table_captions_with_field.docxdeleted

Binary file not shown.

test/docx/table_captions_with_field.nativedeleted−54
@@ -1,54 +0,0 @@
1−[Para [Str "See",Space,Str "Table",Space,Str "1."]
2−,Para []
3−,Table ("",[],[]) (Caption Nothing
4− [Para [Str "Table",Space,Str "1"]])
5− [(AlignDefault,ColWidth 0.7605739372523825)
6− ,(AlignDefault,ColWidth 0.11971303137380876)
7− ,(AlignDefault,ColWidth 0.11971303137380876)]
8− (TableHead ("",[],[])
9−[Row ("",[],[])
10− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11− []
12− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13− [Plain [Str "Count"]]
14− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
15− [Plain [Str "%"]]]])
16− [(TableBody ("",[],[]) (RowHeadColumns 0)
17− []
18− [Row ("",[],[])
19− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
20− [Plain [Str "First",Space,Str "option"]]
21− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
22− [Plain [Str "242"]]
23− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
24− [Plain [Str "45"]]]
25−,Row ("",[],[])
26− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
27− [Plain [Str "Second",Space,Str "option"]]
28− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
29− [Plain [Str "99"]]
30− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
31− [Plain [Str "18"]]]])]
32− (TableFoot ("",[],[])
33− [])
34−,Header 2 ("section", [], []) []
35−,Table ("",[],[]) (Caption Nothing
36− [Para [Str "Table",Space,Str "2"]])
37− [(AlignDefault,ColWidth 0.3332963620230701)
38− ,(AlignDefault,ColWidth 0.3332963620230701)
39− ,(AlignDefault,ColWidth 0.3334072759538598)]
40− (TableHead ("",[],[])
41− [Row ("",[],[])
42− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
43− [Plain [Str "One"]]
44− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
45− [Plain [Str "Two"]]
46− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
47− [Plain [Str "Three"]]]])
48− [(TableBody ("",[],[]) (RowHeadColumns 0)
49− []
50− [])]
51− (TableFoot ("",[],[])
52− [])
53−,Para []
54−,Para [Str "See",Space,Str "Table",Space,Str "2."]]
test/docx/table_header_rowspan.docxdeleted

Binary file not shown.

test/docx/table_header_rowspan.nativedeleted−189
@@ -1,189 +0,0 @@
1−[Table ("",[],[]) (Caption Nothing
2− [])
3− [(AlignDefault,ColWidth 0.30701754385964913)
4− ,(AlignDefault,ColWidth 0.1364522417153996)
5− ,(AlignDefault,ColWidth 0.10009746588693957)
6− ,(AlignDefault,ColWidth 9.707602339181287e-2)
7− ,(AlignDefault,ColWidth 7.719298245614035e-2)
8− ,(AlignDefault,ColWidth 7.085769980506823e-2)
9− ,(AlignDefault,ColWidth 7.09551656920078e-2)
10− ,(AlignDefault,ColWidth 0.14035087719298245)]
11− (TableHead ("",[],[])
12−[Row ("",[],[])
13− [Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)
14− [Plain [Str "A"]]
15− ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)
16− [Plain [Strong [Str "B"]]]
17− ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)
18− [Plain [Strong [Str "C"]]]
19− ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)
20− [Plain [Strong [Str "D"]]]
21− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 3)
22− [Plain [Str "E"]]
23− ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1)
24− [Plain [Str "F"]]]
25−,Row ("",[],[])
26− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
27− [Plain [Strong [Str "G"]]]
28− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
29− [Plain [Strong [Str "H"]]]
30− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
31− [Plain [Strong [Str "I"]]]]])
32− [(TableBody ("",[],[]) (RowHeadColumns 0)
33− []
34− [Row ("",[],[])
35− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
36− [Plain [Str "1"]]
37− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
38− [Plain [Str "2"]]
39− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
40− [Plain [Str "3"]]
41− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
42− [Plain [Str "4"]]
43− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
44− [Plain [Str "5"]]
45− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
46− [Plain [Str "6"]]
47− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
48− [Plain [Str "7"]]
49− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
50− [Plain [Str "8"]]]
51− ,Row ("",[],[])
52− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
53− [Plain [Str "1"]]
54− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
55− [Plain [Str "2"]]
56− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
57− [Plain [Str "3"]]
58− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
59− [Plain [Str "4"]]
60− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
61− [Plain [Str "5"]]
62− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
63− [Plain [Str "6"]]
64− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
65− [Plain [Str "7"]]
66− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
67− [Plain [Str "8"]]]
68− ,Row ("",[],[])
69− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
70− [Plain [Str "1"]]
71− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
72− [Plain [Str "2"]]
73− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
74− [Plain [Str "3"]]
75− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
76− [Plain [Str "4"]]
77− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
78− [Plain [Str "5"]]
79− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
80− [Plain [Str "6"]]
81− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
82− [Plain [Str "7"]]
83− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
84− [Plain [Str "8"]]]
85− ,Row ("",[],[])
86− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
87− [Plain [Str "1"]]
88− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
89− [Plain [Str "2"]]
90− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
91− [Plain [Str "3"]]
92− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
93− [Plain [Str "4"]]
94− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
95− [Plain [Str "5"]]
96− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
97− [Plain [Str "6"]]
98− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
99− [Plain [Str "7"]]
100− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
101− [Plain [Str "8"]]]
102− ,Row ("",[],[])
103− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
104− [Plain [Str "1"]]
105− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
106− [Plain [Str "2"]]
107− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
108− [Plain [Str "3"]]
109− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
110− [Plain [Str "4"]]
111− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
112− [Plain [Str "5"]]
113− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
114− [Plain [Str "6"]]
115− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
116− [Plain [Str "7"]]
117− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
118− [Plain [Str "8"]]]
119− ,Row ("",[],[])
120− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
121− [Plain [Str "1"]]
122− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
123− [Plain [Str "2"]]
124− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
125− [Plain [Str "3"]]
126− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
127− [Plain [Str "4"]]
128− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
129− [Plain [Str "5"]]
130− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
131− [Plain [Str "6"]]
132− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
133− [Plain [Str "7"]]
134− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
135− [Plain [Str "8"]]]
136− ,Row ("",[],[])
137− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
138− [Plain [Str "1"]]
139− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
140− [Plain [Str "2"]]
141− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
142− [Plain [Str "3"]]
143− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
144− [Plain [Str "4"]]
145− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
146− [Plain [Str "5"]]
147− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
148− [Plain [Str "6"]]
149− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
150− [Plain [Str "7"]]
151− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
152− [Plain [Str "8"]]]
153− ,Row ("",[],[])
154− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
155− [Plain [Str "1"]]
156− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
157− [Plain [Str "2"]]
158− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
159− [Plain [Str "3"]]
160− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
161− [Plain [Str "4"]]
162− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
163− [Plain [Str "5"]]
164− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
165− [Plain [Str "6"]]
166− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
167− [Plain [Str "7"]]
168− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
169− [Plain [Str "8"]]]
170− ,Row ("",[],[])
171− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
172− [Plain [Str "1"]]
173− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
174− [Plain [Str "2"]]
175− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
176− [Plain [Str "3"]]
177− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
178− [Plain [Str "4"]]
179− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
180− [Plain [Str "5"]]
181− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
182− [Plain [Str "6"]]
183− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
184− [Plain [Str "7"]]
185− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
186− [Plain [Str "8"]]]
187− ])]
188− (TableFoot ("",[],[])
189− [])]
test/docx/table_one_header_row.docxdeleted

Binary file not shown.

test/docx/table_one_header_row.nativedeleted−18
@@ -1,18 +0,0 @@
1−[Table ("",[],[]) (Caption Nothing
2− [])
3− [(AlignDefault,ColWidth 0.33302433371958284)
4− ,(AlignDefault,ColWidth 0.3332560834298957)
5− ,(AlignDefault,ColWidth 0.33371958285052145)]
6− (TableHead ("",[],[])
7− [Row ("",[],[])
8− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
9− [Plain [Str "One"]]
10− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11− [Plain [Str "Row"]]
12− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13− [Plain [Str "Table"]]]])
14− [(TableBody ("",[],[]) (RowHeadColumns 0)
15− []
16− [])]
17− (TableFoot ("",[],[])
18− [])]
test/docx/table_one_row.docx

Binary file not shown.

test/docx/table_one_row.native+4−4
@@ -1,8 +1,8 @@
1[Table ("",[],[]) (Caption Nothing
1[Table ("",[],[]) (Caption Nothing
2 [])
2 [])
3− [(AlignDefault,ColWidth 0.3333333333333333)
3+ [(AlignDefault,ColWidthDefault)
4− ,(AlignDefault,ColWidth 0.3333333333333333)
4+ ,(AlignDefault,ColWidthDefault)
5− ,(AlignDefault,ColWidth 0.3333333333333333)]
5+ ,(AlignDefault,ColWidthDefault)]
6 (TableHead ("",[],[])
6 (TableHead ("",[],[])
7 [])
7 [])
8 [(TableBody ("",[],[]) (RowHeadColumns 0)
8 [(TableBody ("",[],[]) (RowHeadColumns 0)
@@ -15,4 +15,4 @@
15 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
15 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
16 [Plain [Str "Table"]]]])]
16 [Plain [Str "Table"]]]])]
17 (TableFoot ("",[],[])
17 (TableFoot ("",[],[])
18− [])]
18+ [])]
test/docx/table_variable_width.native+17−12
@@ -1,11 +1,10 @@
1[Table ("",[],[]) (Caption Nothing
1[Table ("",[],[]) (Caption Nothing
2 [])
2 [])
3− [(AlignDefault,ColWidth 2.0096205237840725e-2)
3+ [(AlignDefault,ColWidthDefault)
4− ,(AlignDefault,ColWidth 1.9882415820416888e-2)
4+ ,(AlignDefault,ColWidthDefault)
5− ,(AlignDefault,ColWidth 0.22202030999465527)
5+ ,(AlignDefault,ColWidthDefault)
6− ,(AlignDefault,ColWidth 0.4761090326028862)
6+ ,(AlignDefault,ColWidthDefault)
7− ,(AlignDefault,ColWidth 1.0689470871191876e-4)
7+ ,(AlignDefault,ColWidthDefault)]
8− ,(AlignDefault,ColWidth 0.26178514163548905)]
9 (TableHead ("",[],[])
8 (TableHead ("",[],[])
10 [Row ("",[],[])
9 [Row ("",[],[])
11 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
10 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
@@ -14,27 +13,33 @@
14 []
13 []
15 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
14 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
16 [Plain [Str "h3"]]
15 [Plain [Str "h3"]]
17− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)
16+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
18 [Plain [Str "h4"]]
17 [Plain [Str "h4"]]
19 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
18 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
20 [Plain [Str "h5"]]]])
19 [Plain [Str "h5"]]]])
21 [(TableBody ("",[],[]) (RowHeadColumns 0)
20 [(TableBody ("",[],[]) (RowHeadColumns 0)
22 []
21 []
23 [Row ("",[],[])
22 [Row ("",[],[])
24− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 3)
23+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
25 [Plain [Str "c11"]]
24 [Plain [Str "c11"]]
26 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
25 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
27 []
26 []
28− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)
27+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
28+ []
29+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
30+ []
31+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
29 []]
32 []]
30 ,Row ("",[],[])
33 ,Row ("",[],[])
31 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
34 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
32 []
35 []
33− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)
36+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
34 [Plain [Str "c22"]]
37 [Plain [Str "c22"]]
35 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
38 ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
36 [Plain [Str "c23"]]
39 [Plain [Str "c23"]]
37− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2)
40+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
41+ []
42+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
38 []]])]
43 []]])]
39 (TableFoot ("",[],[])
44 (TableFoot ("",[],[])
40− [])]
45+ [])]
test/docx/table_with_list_cell.native+3−3
@@ -1,7 +1,7 @@
1[Table ("",[],[]) (Caption Nothing
1[Table ("",[],[]) (Caption Nothing
2 [])
2 [])
3− [(AlignDefault,ColWidth 0.5)
3+ [(AlignDefault,ColWidthDefault)
4− ,(AlignDefault,ColWidth 0.5)]
4+ ,(AlignDefault,ColWidthDefault)]
5 (TableHead ("",[],[])
5 (TableHead ("",[],[])
6 [Row ("",[],[])
6 [Row ("",[],[])
7 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
7 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
@@ -22,4 +22,4 @@
22 ,[Para [Str "A"]]
22 ,[Para [Str "A"]]
23 ,[Para [Str "Numbered",Space,Str "list."]]]]]])]
23 ,[Para [Str "Numbered",Space,Str "list."]]]]]])]
24 (TableFoot ("",[],[])
24 (TableFoot ("",[],[])
25− [])]
25+ [])]
test/docx/tables-default-widths.nativedeleted−92
@@ -1,92 +0,0 @@
1−[Header 2 ("a-table-with-and-without-a-header-row",[],[]) [Str "A",Space,Str "table,",Space,Str "with",Space,Str "and",Space,Str "without",Space,Str "a",Space,Str "header",Space,Str "row"]
2−,Table ("",[],[]) (Caption Nothing
3− [])
4− [(AlignDefault,ColWidthDefault)
5− ,(AlignDefault,ColWidthDefault)
6− ,(AlignDefault,ColWidthDefault)
7− ,(AlignDefault,ColWidthDefault)]
8− (TableHead ("",[],[])
9− [Row ("",[],[])
10− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
11− [Plain [Str "Name"]]
12− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
13− [Plain [Str "Game"]]
14− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
15− [Plain [Str "Fame"]]
16− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
17− [Plain [Str "Blame"]]]])
18− [(TableBody ("",[],[]) (RowHeadColumns 0)
19− []
20− [Row ("",[],[])
21− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
22− [Plain [Str "Lebron",Space,Str "James"]]
23− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
24− [Plain [Str "Basketball"]]
25− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
26− [Plain [Str "Very",Space,Str "High"]]
27− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
28− [Plain [Str "Leaving",Space,Str "Cleveland"]]]
29− ,Row ("",[],[])
30− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
31− [Plain [Str "Ryan",Space,Str "Braun"]]
32− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
33− [Plain [Str "Baseball"]]
34− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
35− [Plain [Str "Moderate"]]
36− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
37− [Plain [Str "Steroids"]]]
38− ,Row ("",[],[])
39− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
40− [Plain [Str "Russell",Space,Str "Wilson"]]
41− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
42− [Plain [Str "Football"]]
43− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
44− [Plain [Str "High"]]
45− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
46− [Plain [Str "Tacky",Space,Str "uniform"]]]])]
47− (TableFoot ("",[],[])
48− [])
49−,Table ("",[],[]) (Caption Nothing
50− [])
51− [(AlignDefault,ColWidthDefault)
52− ,(AlignDefault,ColWidthDefault)]
53− (TableHead ("",[],[])
54− [])
55− [(TableBody ("",[],[]) (RowHeadColumns 0)
56− []
57− [Row ("",[],[])
58− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
59− [Plain [Str "Sinple"]]
60− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
61− [Plain [Str "Table"]]]
62− ,Row ("",[],[])
63− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
64− [Plain [Str "Without"]]
65− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
66− [Plain [Str "Header"]]]])]
67− (TableFoot ("",[],[])
68− [])
69−,Table ("",[],[]) (Caption Nothing
70− [])
71− [(AlignDefault,ColWidthDefault)
72− ,(AlignDefault,ColWidthDefault)]
73− (TableHead ("",[],[])
74− [])
75− [(TableBody ("",[],[]) (RowHeadColumns 0)
76− []
77− [Row ("",[],[])
78− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
79− [Para [Str "Simple"]
80− ,Para [Str "Multiparagraph"]]
81− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
82− [Para [Str "Table"]
83− ,Para [Str "Full"]]]
84− ,Row ("",[],[])
85− [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
86− [Para [Str "Of"]
87− ,Para [Str "Paragraphs"]]
88− ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
89− [Para [Str "In",Space,Str "each"]
90− ,Para [Str "Cell."]]]])]
91− (TableFoot ("",[],[])
92− [])]
test/docx/tables.native+9−9
@@ -1,10 +1,10 @@
1[Header 2 ("a-table-with-and-without-a-header-row",[],[]) [Str "A",Space,Str "table,",Space,Str "with",Space,Str "and",Space,Str "without",Space,Str "a",Space,Str "header",Space,Str "row"]
1[Header 2 ("a-table-with-and-without-a-header-row",[],[]) [Str "A",Space,Str "table,",Space,Str "with",Space,Str "and",Space,Str "without",Space,Str "a",Space,Str "header",Space,Str "row"]
2,Table ("",[],[]) (Caption Nothing
2,Table ("",[],[]) (Caption Nothing
3 [])
3 [])
4− [(AlignDefault,ColWidth 0.25)
4+ [(AlignDefault,ColWidthDefault)
5− ,(AlignDefault,ColWidth 0.25)
5+ ,(AlignDefault,ColWidthDefault)
6− ,(AlignDefault,ColWidth 0.25)
6+ ,(AlignDefault,ColWidthDefault)
7− ,(AlignDefault,ColWidth 0.25)]
7+ ,(AlignDefault,ColWidthDefault)]
8 (TableHead ("",[],[])
8 (TableHead ("",[],[])
9 [Row ("",[],[])
9 [Row ("",[],[])
10 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
10 [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
@@ -48,8 +48,8 @@
48 [])
48 [])
49,Table ("",[],[]) (Caption Nothing
49,Table ("",[],[]) (Caption Nothing
50 [])
50 [])
51− [(AlignDefault,ColWidth 0.5)
51+ [(AlignDefault,ColWidthDefault)
52− ,(AlignDefault,ColWidth 0.5)]
52+ ,(AlignDefault,ColWidthDefault)]
53 (TableHead ("",[],[])
53 (TableHead ("",[],[])
54 [])
54 [])
55 [(TableBody ("",[],[]) (RowHeadColumns 0)
55 [(TableBody ("",[],[]) (RowHeadColumns 0)
@@ -68,8 +68,8 @@
68 [])
68 [])
69,Table ("",[],[]) (Caption Nothing
69,Table ("",[],[]) (Caption Nothing
70 [])
70 [])
71− [(AlignDefault,ColWidth 0.5)
71+ [(AlignDefault,ColWidthDefault)
72− ,(AlignDefault,ColWidth 0.5)]
72+ ,(AlignDefault,ColWidthDefault)]
73 (TableHead ("",[],[])
73 (TableHead ("",[],[])
74 [])
74 [])
75 [(TableBody ("",[],[]) (RowHeadColumns 0)
75 [(TableBody ("",[],[]) (RowHeadColumns 0)
@@ -89,4 +89,4 @@
89 [Para [Str "In",Space,Str "each"]
89 [Para [Str "In",Space,Str "each"]
90 ,Para [Str "Cell."]]]])]
90 ,Para [Str "Cell."]]]])]
91 (TableFoot ("",[],[])
91 (TableFoot ("",[],[])
92− [])]
92+ [])]
test/epub/wasteland.epub

Binary file not shown.

test/fb2/images.fb2+1−1
@@ -1,2 +1,2 @@
1<?xml version="1.0" encoding="UTF-8"?>
1<?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></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section><p>This example test if Pandoc correctly embeds images into FictionBook.</p><p>Small inline image: <image l:href="#image1" l:type="inlineImageType" alt="alt text a small PNG image" />.</p><p>Paragraph image:</p><image l:href="#image2" l:type="imageType" alt="alt text of a big JPEG image" title="image title text" /><p>alt text of a big missing image</p><p>A missing image inline: alt text of missing image.</p></section></body><binary id="image2" content-type="image/jpeg">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</binary><binary id="image1" content-type="image/png">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</binary></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></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section><p>This example test if Pandoc correctly embeds images into FictionBook.</p><p>Small inline image: <image l:href="#image1" l:type="inlineImageType" alt="alt text a small PNG image" />.</p><p>Paragraph image:</p><image l:href="#image2" l:type="imageType" alt="alt text of a big JPEG image" title="image title text" /><p>alt text of a big missing image</p><p>A missing image inline: alt text of missing image.</p></section></body><binary id="image2" content-type="image/jpeg">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</binary><binary id="image1" content-type="image/png">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</binary></FictionBook>
test/fb2/test.jpg

Binary file not shown.

test/html-reader.native+1−2
@@ -1,6 +1,5 @@
1Pandoc (Meta {unMeta = fromList [("generator",MetaInlines [Str "pandoc"]),("title",MetaInlines [Str "Pandoc",Space,Str "Test",Space,Str "Suite"])]})
1Pandoc (Meta {unMeta = fromList [("generator",MetaInlines [Str "pandoc"]),("title",MetaInlines [Str "Pandoc",Space,Str "Test",Space,Str "Suite"])]})
2−[Header 1 ("pandoc-test-suite",["title"],[]) [Str "Pandoc",Space,Str "Test",Space,Str "Suite"]
3−,Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber's",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
2+[Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber's",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
4,HorizontalRule
3,HorizontalRule
5,Header 1 ("headers",[],[]) [Str "Headers"]
4,Header 1 ("headers",[],[]) [Str "Headers"]
6,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"] ("/url","")]
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"] ("/url","")]
test/lhs-test.html+1−2
@@ -21,7 +21,7 @@
21 padding-top: 50px;
21 padding-top: 50px;
22 padding-bottom: 50px;
22 padding-bottom: 50px;
23 hyphens: auto;
23 hyphens: auto;
24− overflow-wrap: break-word;
24+ word-wrap: break-word;
25 text-rendering: optimizeLegibility;
25 text-rendering: optimizeLegibility;
26 font-kerning: normal;
26 font-kerning: normal;
27 }
27 }
@@ -92,7 +92,6 @@
92 pre code {
92 pre code {
93 padding: 0;
93 padding: 0;
94 overflow: visible;
94 overflow: visible;
95− overflow-wrap: normal;
96 }
95 }
97 .sourceCode {
96 .sourceCode {
98 background-color: transparent;
97 background-color: transparent;
test/lhs-test.html+lhs+1−2
@@ -21,7 +21,7 @@
21 padding-top: 50px;
21 padding-top: 50px;
22 padding-bottom: 50px;
22 padding-bottom: 50px;
23 hyphens: auto;
23 hyphens: auto;
24− overflow-wrap: break-word;
24+ word-wrap: break-word;
25 text-rendering: optimizeLegibility;
25 text-rendering: optimizeLegibility;
26 font-kerning: normal;
26 font-kerning: normal;
27 }
27 }
@@ -92,7 +92,6 @@
92 pre code {
92 pre code {
93 padding: 0;
93 padding: 0;
94 overflow: visible;
94 overflow: visible;
95− overflow-wrap: normal;
96 }
95 }
97 .sourceCode {
96 .sourceCode {
98 background-color: transparent;
97 background-color: transparent;
test/pipe-tables.native+10−2
@@ -131,7 +131,13 @@
131 ,(AlignLeft,ColWidthDefault)
131 ,(AlignLeft,ColWidthDefault)
132 ,(AlignCenter,ColWidthDefault)]
132 ,(AlignCenter,ColWidthDefault)]
133 (TableHead ("",[],[])
133 (TableHead ("",[],[])
134+ [Row ("",[],[])
135+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
136+ []
137+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
138+ []
139+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
134− [])
140+ []]])
135 [(TableBody ("",[],[]) (RowHeadColumns 0)
141 [(TableBody ("",[],[]) (RowHeadColumns 0)
136 []
142 []
137 [Row ("",[],[])
143 [Row ("",[],[])
@@ -207,7 +213,9 @@
207 [])
213 [])
208 [(AlignCenter,ColWidthDefault)]
214 [(AlignCenter,ColWidthDefault)]
209 (TableHead ("",[],[])
215 (TableHead ("",[],[])
216+ [Row ("",[],[])
217+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)
210− [])
218+ []]])
211 [(TableBody ("",[],[]) (RowHeadColumns 0)
219 [(TableBody ("",[],[]) (RowHeadColumns 0)
212 []
220 []
213 [Row ("",[],[])
221 [Row ("",[],[])
test/pptx/code-custom_templated.pptx

Binary file not shown.

test/pptx/code_templated.pptx

Binary file not shown.

test/pptx/document-properties-short-desc_templated.pptx

Binary file not shown.

test/pptx/document-properties_templated.pptx

Binary file not shown.

test/pptx/endnotes_templated.pptx

Binary file not shown.

test/pptx/endnotes_toc_templated.pptx

Binary file not shown.

test/pptx/images_templated.pptx

Binary file not shown.

test/pptx/inline_formatting_templated.pptx

Binary file not shown.

test/pptx/lists_templated.pptx

Binary file not shown.

test/pptx/raw_ooxml_templated.pptx

Binary file not shown.

test/pptx/reference_depth.pptx

Binary file not shown.

test/pptx/remove_empty_slides_templated.pptx

Binary file not shown.

test/pptx/slide_breaks_slide_level_1_templated.pptx

Binary file not shown.

test/pptx/slide_breaks_templated.pptx

Binary file not shown.

test/pptx/slide_breaks_toc_templated.pptx

Binary file not shown.

test/pptx/speaker_notes_after_metadata_templated.pptx

Binary file not shown.

test/pptx/speaker_notes_afterheader_templated.pptx

Binary file not shown.

test/pptx/speaker_notes_afterseps_templated.pptx

Binary file not shown.

test/pptx/speaker_notes_templated.pptx

Binary file not shown.

test/pptx/start_numbering_at_templated.pptx

Binary file not shown.

test/pptx/tables_templated.pptx

Binary file not shown.

test/pptx/two_column_templated.pptx

Binary file not shown.

test/tables.latex+3−27
@@ -56,27 +56,11 @@ Multiline table with caption:
56 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}}
56 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}}
57\caption{Here's the caption. It may span multiple lines.}\tabularnewline
57\caption{Here's the caption. It may span multiple lines.}\tabularnewline
58\toprule
58\toprule
59−\begin{minipage}[b]{\linewidth}\centering
60−Centered Header
59+Centered Header & Left Aligned & Right Aligned & Default aligned \\
61−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
62−Left Aligned
63−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft
64−Right Aligned
65−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
66−Default aligned
67−\end{minipage} \\
68\midrule
60\midrule
69\endfirsthead
61\endfirsthead
70\toprule
62\toprule
71−\begin{minipage}[b]{\linewidth}\centering
72−Centered Header
63+Centered Header & Left Aligned & Right Aligned & Default aligned \\
73−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
74−Left Aligned
75−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft
76−Right Aligned
77−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
78−Default aligned
79−\end{minipage} \\
80\midrule
64\midrule
81\endhead
65\endhead
82First & row & 12.0 & Example of a row that spans multiple lines. \\
66First & row & 12.0 & Example of a row that spans multiple lines. \\
@@ -92,15 +76,7 @@ Multiline table without caption:
92 >{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.16}}
76 >{\raggedleft\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.16}}
93 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}}
77 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.35}}@{}}
94\toprule
78\toprule
95−\begin{minipage}[b]{\linewidth}\centering
96−Centered Header
79+Centered Header & Left Aligned & Right Aligned & Default aligned \\
97−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
98−Left Aligned
99−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft
100−Right Aligned
101−\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
102−Default aligned
103−\end{minipage} \\
104\midrule
80\midrule
105\endhead
81\endhead
106First & row & 12.0 & Example of a row that spans multiple lines. \\
82First & row & 12.0 & Example of a row that spans multiple lines. \\
test/tables.ms−30
@@ -143,7 +143,6 @@ Multiline table with caption:
143.PP
143.PP
144Here\[cq]s the caption. It may span multiple lines.
144Here\[cq]s the caption. It may span multiple lines.
145.na
145.na
146−.nr LLold \n[LL]
147.TS
146.TS
148delim(@@) tab( );
147delim(@@) tab( );
149cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
148cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
@@ -158,40 +157,30 @@ Default aligned
158T}
157T}
159_
158_
160T{
159T{
161−.nr LL 10.5n
162First
160First
163T} T{
161T} T{
164−.nr LL 9.6n
165row
162row
166T} T{
163T} T{
167−.nr LL 11.4n
16812.0
16412.0
169T} T{
165T} T{
170−.nr LL 24.5n
171Example of a row that spans multiple lines.
166Example of a row that spans multiple lines.
172T}
167T}
173T{
168T{
174−.nr LL 10.5n
175Second
169Second
176T} T{
170T} T{
177−.nr LL 9.6n
178row
171row
179T} T{
172T} T{
180−.nr LL 11.4n
1815.0
1735.0
182T} T{
174T} T{
183−.nr LL 24.5n
184Here\[cq]s another one.
175Here\[cq]s another one.
185Note the blank line between rows.
176Note the blank line between rows.
186T}
177T}
187.TE
178.TE
188−.nr LL \n[LLold]
189.ad
179.ad
190.LP
180.LP
191Multiline table without caption:
181Multiline table without caption:
192.PP
182.PP
193.na
183.na
194−.nr LLold \n[LL]
195.TS
184.TS
196delim(@@) tab( );
185delim(@@) tab( );
197cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
186cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
@@ -206,34 +195,25 @@ Default aligned
206T}
195T}
207_
196_
208T{
197T{
209−.nr LL 10.5n
210First
198First
211T} T{
199T} T{
212−.nr LL 9.6n
213row
200row
214T} T{
201T} T{
215−.nr LL 11.4n
21612.0
20212.0
217T} T{
203T} T{
218−.nr LL 24.5n
219Example of a row that spans multiple lines.
204Example of a row that spans multiple lines.
220T}
205T}
221T{
206T{
222−.nr LL 10.5n
223Second
207Second
224T} T{
208T} T{
225−.nr LL 9.6n
226row
209row
227T} T{
210T} T{
228−.nr LL 11.4n
2295.0
2115.0
230T} T{
212T} T{
231−.nr LL 24.5n
232Here\[cq]s another one.
213Here\[cq]s another one.
233Note the blank line between rows.
214Note the blank line between rows.
234T}
215T}
235.TE
216.TE
236−.nr LL \n[LLold]
237.ad
217.ad
238.LP
218.LP
239Table without column headers:
219Table without column headers:
@@ -275,37 +255,27 @@ T}
275Multiline table without column headers:
255Multiline table without column headers:
276.PP
256.PP
277.na
257.na
278−.nr LLold \n[LL]
279.TS
258.TS
280delim(@@) tab( );
259delim(@@) tab( );
281cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
260cw(10.5n) lw(9.6n) rw(11.4n) lw(24.5n).
282T{
261T{
283−.nr LL 10.5n
284First
262First
285T} T{
263T} T{
286−.nr LL 9.6n
287row
264row
288T} T{
265T} T{
289−.nr LL 11.4n
29012.0
26612.0
291T} T{
267T} T{
292−.nr LL 24.5n
293Example of a row that spans multiple lines.
268Example of a row that spans multiple lines.
294T}
269T}
295T{
270T{
296−.nr LL 10.5n
297Second
271Second
298T} T{
272T} T{
299−.nr LL 9.6n
300row
273row
301T} T{
274T} T{
302−.nr LL 11.4n
3035.0
2755.0
304T} T{
276T} T{
305−.nr LL 24.5n
306Here\[cq]s another one.
277Here\[cq]s another one.
307Note the blank line between rows.
278Note the blank line between rows.
308T}
279T}
309.TE
280.TE
310−.nr LL \n[LLold]
311.ad
281.ad
test/tables/nordics.latex+4−22
@@ -5,31 +5,13 @@
5 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.20}}@{}}
5 >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.20}}@{}}
6\caption{States belonging to the \emph{Nordics.}}\tabularnewline
6\caption{States belonging to the \emph{Nordics.}}\tabularnewline
7\toprule
7\toprule
8−\begin{minipage}[b]{\linewidth}\centering
8+Name & Capital & \vtop{\hbox{\strut Population}\hbox{\strut (in 2018)}} &
9−Name
10−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
11−Capital
12−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
13−Population\\
14−(in 2018)\strut
15−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
16−Area\\
17−(in km\textsuperscript{2})\strut
9+\vtop{\hbox{\strut Area}\hbox{\strut (in km\textsuperscript{2})}} \\
18−\end{minipage} \\
19\midrule
10\midrule
20\endfirsthead
11\endfirsthead
21\toprule
12\toprule
22−\begin{minipage}[b]{\linewidth}\centering
13+Name & Capital & \vtop{\hbox{\strut Population}\hbox{\strut (in 2018)}} &
23−Name
24−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
25−Capital
26−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
27−Population\\
28−(in 2018)\strut
29−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
30−Area\\
31−(in km\textsuperscript{2})\strut
14+\vtop{\hbox{\strut Area}\hbox{\strut (in km\textsuperscript{2})}} \\
32−\end{minipage} \\
33\midrule
15\midrule
34\endhead
16\endhead
35Denmark & Copenhagen & 5,809,502 & 43,094 \\
17Denmark & Copenhagen & 5,809,502 & 43,094 \\
test/tables/planets.latex+4−4
@@ -1,18 +1,18 @@
1\begin{longtable}[]{@{}cclrrrrrrrrl@{}}
1\begin{longtable}[]{@{}cclrrrrrrrrl@{}}
2\caption{Data about the planets of our solar system.}\tabularnewline
2\caption{Data about the planets of our solar system.}\tabularnewline
3\toprule
3\toprule
4−\multicolumn{2}{c}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density
4+\multicolumn{2}{l}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density
5(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun
5(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun
6(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\
6(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\
7\midrule
7\midrule
8\endfirsthead
8\endfirsthead
9\toprule
9\toprule
10−\multicolumn{2}{c}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density
10+\multicolumn{2}{l}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density
11(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun
11(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun
12(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\
12(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\
13\midrule
13\midrule
14\endhead
14\endhead
15−\multicolumn{2}{c}{\multirow{4}{*}{Terrestrial planets}} & Mercury & 0.330 &
15+\multicolumn{2}{l}{\multirow{4}{*}{Terrestrial planets}} & Mercury & 0.330 &
164,879 & 5427 & 3.7 & 4222.6 & 57.9 & 167 & 0 & Closest to the Sun \\
164,879 & 5427 & 3.7 & 4222.6 & 57.9 & 167 & 0 & Closest to the Sun \\
17& & Venus & 4.87 & 12,104 & 5243 & 8.9 & 2802.0 & 108.2 & 464 & 0 & \\
17& & Venus & 4.87 & 12,104 & 5243 & 8.9 & 2802.0 & 108.2 & 464 & 0 & \\
18& & Earth & 5.97 & 12,756 & 5514 & 9.8 & 24.0 & 149.6 & 15 & 1 & Our world \\
18& & Earth & 5.97 & 12,756 & 5514 & 9.8 & 24.0 & 149.6 & 15 & 1 & Our world \\
@@ -24,7 +24,7 @@ planet \\
24& \multirow{2}{*}{Ice giants} & Uranus & 86.8 & 51,118 & 1271 & 8.7 & 17.2 &
24& \multirow{2}{*}{Ice giants} & Uranus & 86.8 & 51,118 & 1271 & 8.7 & 17.2 &
252872.5 & -195 & 27 & \\
252872.5 & -195 & 27 & \\
26& & Neptune & 102 & 49,528 & 1638 & 11.0 & 16.1 & 4495.1 & -200 & 14 & \\
26& & Neptune & 102 & 49,528 & 1638 & 11.0 & 16.1 & 4495.1 & -200 & 14 & \\
27−\multicolumn{2}{c}{Dwarf planets} & Pluto & 0.0146 & 2,370 & 2095 & 0.7 &
27+\multicolumn{2}{l}{Dwarf planets} & Pluto & 0.0146 & 2,370 & 2095 & 0.7 &
28153.3 & 5906.4 & -225 & 5 & Declassified as a planet in 2006. \\
28153.3 & 5906.4 & -225 & 5 & Declassified as a planet in 2006. \\
29\bottomrule
29\bottomrule
30\end{longtable}
30\end{longtable}
test/tables/students.latex+2−10
@@ -3,19 +3,11 @@
3 >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.50}}@{}}
3 >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.50}}@{}}
4\caption{List of Students}\tabularnewline
4\caption{List of Students}\tabularnewline
5\toprule
5\toprule
6−\begin{minipage}[b]{\linewidth}\centering
7−Student ID
6+Student ID & Name \\
8−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
9−Name
10−\end{minipage} \\
11\midrule
7\midrule
12\endfirsthead
8\endfirsthead
13\toprule
9\toprule
14−\begin{minipage}[b]{\linewidth}\centering
15−Student ID
10+Student ID & Name \\
16−\end{minipage} & \begin{minipage}[b]{\linewidth}\centering
17−Name
18−\end{minipage} \\
19\midrule
11\midrule
20\endhead
12\endhead
21\multicolumn{2}{l}{Computer Science} \\
13\multicolumn{2}{l}{Computer Science} \\
test/writer.context+38−42
@@ -17,7 +17,6 @@
17
17
18% use microtypography
18% use microtypography
19\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
19\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
20−\definefontfeature[default:tnum][default][tnum=yes, pnum=no]
21\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
20\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
22\setupalign[hz,hanging]
21\setupalign[hz,hanging]
23\setupitaliccorrection[global, always]
22\setupitaliccorrection[global, always]
@@ -49,9 +48,6 @@
49\setupitemize[autointro] % prevent orphan list intro
48\setupitemize[autointro] % prevent orphan list intro
50\setupitemize[indentnext=no]
49\setupitemize[indentnext=no]
51
50
52−\defineitemgroup[enumerate]
53−\setupenumerate[each][fit][itemalign=left,distance=.5em,style={\feature[+][default:tnum]}]
54−
55\setupfloat[figure][default={here,nonumber}]
51\setupfloat[figure][default={here,nonumber}]
56\setupfloat[table][default={here,nonumber}]
52\setupfloat[table][default={here,nonumber}]
57
53
@@ -137,12 +133,12 @@ sub status {
137
133
138A list:
134A list:
139
135
140−\startenumerate[n,packed][stopper=.]
136+\startitemize[n,packed][stopper=.]
141\item
137\item
142 item one
138 item one
143\item
139\item
144 item two
140 item two
145−\stopenumerate
141+\stopitemize
146
142
147Nested block quotes:
143Nested block quotes:
148
144
@@ -259,51 +255,51 @@ Minuses loose:
259
255
260Tight:
256Tight:
261
257
262−\startenumerate[n,packed][stopper=.]
258+\startitemize[n,packed][stopper=.]
263\item
259\item
264 First
260 First
265\item
261\item
266 Second
262 Second
267\item
263\item
268 Third
264 Third
269−\stopenumerate
265+\stopitemize
270
266
271and:
267and:
272
268
273−\startenumerate[n,packed][stopper=.]
269+\startitemize[n,packed][stopper=.]
274\item
270\item
275 One
271 One
276\item
272\item
277 Two
273 Two
278\item
274\item
279 Three
275 Three
280−\stopenumerate
276+\stopitemize
281
277
282Loose using tabs:
278Loose using tabs:
283
279
284−\startenumerate[n][stopper=.]
280+\startitemize[n][stopper=.]
285\item
281\item
286 First
282 First
287\item
283\item
288 Second
284 Second
289\item
285\item
290 Third
286 Third
291−\stopenumerate
287+\stopitemize
292
288
293and using spaces:
289and using spaces:
294
290
295−\startenumerate[n][stopper=.]
291+\startitemize[n][stopper=.]
296\item
292\item
297 One
293 One
298\item
294\item
299 Two
295 Two
300\item
296\item
301 Three
297 Three
302−\stopenumerate
298+\stopitemize
303
299
304Multiple paragraphs:
300Multiple paragraphs:
305
301
306−\startenumerate[n][stopper=.]
302+\startitemize[n][stopper=.]
307\item
303\item
308 Item 1, graf one.
304 Item 1, graf one.
309
305
@@ -312,7 +308,7 @@ Multiple paragraphs:
312 Item 2.
308 Item 2.
313\item
309\item
314 Item 3.
310 Item 3.
315−\stopenumerate
311+\stopitemize
316
312
317\subsection[title={Nested},reference={nested}]
313\subsection[title={Nested},reference={nested}]
318
314
@@ -331,7 +327,7 @@ Multiple paragraphs:
331
327
332Here's another:
328Here's another:
333
329
334−\startenumerate[n,packed][stopper=.]
330+\startitemize[n,packed][stopper=.]
335\item
331\item
336 First
332 First
337\item
333\item
@@ -346,11 +342,11 @@ Here's another:
346 \stopitemize
342 \stopitemize
347\item
343\item
348 Third
344 Third
349−\stopenumerate
345+\stopitemize
350
346
351Same thing but with paragraphs:
347Same thing but with paragraphs:
352
348
353−\startenumerate[n][stopper=.]
349+\startitemize[n][stopper=.]
354\item
350\item
355 First
351 First
356\item
352\item
@@ -366,7 +362,7 @@ Same thing but with paragraphs:
366 \stopitemize
362 \stopitemize
367\item
363\item
368 Third
364 Third
369−\stopenumerate
365+\stopitemize
370
366
371\subsection[title={Tabs and spaces},reference={tabs-and-spaces}]
367\subsection[title={Tabs and spaces},reference={tabs-and-spaces}]
372
368
@@ -386,7 +382,7 @@ Same thing but with paragraphs:
386
382
387\subsection[title={Fancy list markers},reference={fancy-list-markers}]
383\subsection[title={Fancy list markers},reference={fancy-list-markers}]
388
384
389−\startenumerate[n][start=2,left=(,stopper=)]
385+\startitemize[n][start=2,left=(,stopper=),width=2.0em]
390\item
386\item
391 begins with 2
387 begins with 2
392\item
388\item
@@ -394,51 +390,51 @@ Same thing but with paragraphs:
394
390
395 with a continuation
391 with a continuation
396
392
397− \startenumerate[r,packed][start=4,stopper=.]
393+ \startitemize[r,packed][start=4,stopper=.,width=2.0em]
398 \item
394 \item
399 sublist with roman numerals, starting with 4
395 sublist with roman numerals, starting with 4
400 \item
396 \item
401 more items
397 more items
402− \startenumerate[A,packed][left=(,stopper=)]
398+ \startitemize[A,packed][left=(,stopper=),width=2.0em]
403 \item
399 \item
404 a subsublist
400 a subsublist
405 \item
401 \item
406 a subsublist
402 a subsublist
407− \stopenumerate
403+ \stopitemize
408− \stopenumerate
404+ \stopitemize
409−\stopenumerate
405+\stopitemize
410
406
411Nesting:
407Nesting:
412
408
413−\startenumerate[A,packed][stopper=.]
409+\startitemize[A,packed][stopper=.]
414\item
410\item
415 Upper Alpha
411 Upper Alpha
416− \startenumerate[R,packed][stopper=.]
412+ \startitemize[R,packed][stopper=.]
417 \item
413 \item
418 Upper Roman.
414 Upper Roman.
419− \startenumerate[n,packed][start=6,left=(,stopper=)]
415+ \startitemize[n,packed][start=6,left=(,stopper=),width=2.0em]
420 \item
416 \item
421 Decimal start with 6
417 Decimal start with 6
422− \startenumerate[a,packed][start=3,stopper=)]
418+ \startitemize[a,packed][start=3,stopper=)]
423 \item
419 \item
424 Lower alpha with paren
420 Lower alpha with paren
425− \stopenumerate
421+ \stopitemize
426− \stopenumerate
422+ \stopitemize
427− \stopenumerate
423+ \stopitemize
428−\stopenumerate
424+\stopitemize
429
425
430Autonumbering:
426Autonumbering:
431
427
432−\startenumerate[n,packed]
428+\startitemize[n,packed]
433\item
429\item
434 Autonumber.
430 Autonumber.
435\item
431\item
436 More.
432 More.
437− \startenumerate[a,packed]
433+ \startitemize[a,packed]
438 \item
434 \item
439 Nested.
435 Nested.
440− \stopenumerate
436+ \stopitemize
441−\stopenumerate
437+\stopitemize
442
438
443Should not be a list item:
439Should not be a list item:
444
440
@@ -551,12 +547,12 @@ Blank line after term, indented marker, alternate markers:
551\startdescription{orange}
547\startdescription{orange}
552 orange fruit
548 orange fruit
553
549
554− \startenumerate[n,packed][stopper=.]
550+ \startitemize[n,packed][stopper=.]
555 \item
551 \item
556 sublist
552 sublist
557 \item
553 \item
558 sublist
554 sublist
559− \stopenumerate
555+ \stopitemize
560\stopdescription
556\stopdescription
561
557
562\section[title={HTML Blocks},reference={html-blocks}]
558\section[title={HTML Blocks},reference={html-blocks}]
@@ -901,10 +897,10 @@ note{]} Here is an inline note.\footnote{This is {\em easier} to type. Inline
901Notes can go in quotes.\footnote{In quote.}
897Notes can go in quotes.\footnote{In quote.}
902\stopblockquote
898\stopblockquote
903
899
904−\startenumerate[n,packed][stopper=.]
900+\startitemize[n,packed][stopper=.]
905\item
901\item
906 And in list items.\footnote{In list.}
902 And in list items.\footnote{In list.}
907−\stopenumerate
903+\stopitemize
908
904
909This paragraph should not be part of the note, as it is not indented.
905This paragraph should not be part of the note, as it is not indented.
910
906
test/writer.html4+1−2
@@ -24,7 +24,7 @@
24 padding-top: 50px;
24 padding-top: 50px;
25 padding-bottom: 50px;
25 padding-bottom: 50px;
26 hyphens: auto;
26 hyphens: auto;
27− overflow-wrap: break-word;
27+ word-wrap: break-word;
28 text-rendering: optimizeLegibility;
28 text-rendering: optimizeLegibility;
29 font-kerning: normal;
29 font-kerning: normal;
30 }
30 }
@@ -95,7 +95,6 @@
95 pre code {
95 pre code {
96 padding: 0;
96 padding: 0;
97 overflow: visible;
97 overflow: visible;
98− overflow-wrap: normal;
99 }
98 }
100 .sourceCode {
99 .sourceCode {
101 background-color: transparent;
100 background-color: transparent;
test/writer.html5+1−2
@@ -24,7 +24,7 @@
24 padding-top: 50px;
24 padding-top: 50px;
25 padding-bottom: 50px;
25 padding-bottom: 50px;
26 hyphens: auto;
26 hyphens: auto;
27− overflow-wrap: break-word;
27+ word-wrap: break-word;
28 text-rendering: optimizeLegibility;
28 text-rendering: optimizeLegibility;
29 font-kerning: normal;
29 font-kerning: normal;
30 }
30 }
@@ -95,7 +95,6 @@
95 pre code {
95 pre code {
96 padding: 0;
96 padding: 0;
97 overflow: visible;
97 overflow: visible;
98− overflow-wrap: normal;
99 }
98 }
100 .sourceCode {
99 .sourceCode {
101 background-color: transparent;
100 background-color: transparent;
test/writer.jats_archiving+40−28
@@ -78,31 +78,39 @@ Gruber’s markdown test suite.</p>
78<sec id="block-quotes">
78<sec id="block-quotes">
79 <title>Block Quotes</title>
79 <title>Block Quotes</title>
80 <p>E-mail style:</p>
80 <p>E-mail style:</p>
81− <disp-quote>
81+ <p specific-use="wrapper">
82− <p>This is a block quote. It is pretty short.</p>
83− </disp-quote>
84− <disp-quote>
85− <p>Code in a block quote:</p>
86− <preformat>sub status {
87− print &quot;working&quot;;
88−}</preformat>
89− <p>A list:</p>
90− <list list-type="order">
91− <list-item>
92− <p>item one</p>
93− </list-item>
94− <list-item>
95− <p>item two</p>
96− </list-item>
97− </list>
98− <p>Nested block quotes:</p>
99 <disp-quote>
82 <disp-quote>
100− <p>nested</p>
83+ <p>This is a block quote. It is pretty short.</p>
101 </disp-quote>
84 </disp-quote>
85+ </p>
86+ <p specific-use="wrapper">
102 <disp-quote>
87 <disp-quote>
88+ <p>Code in a block quote:</p>
89+ <preformat>sub status {
90+ print &quot;working&quot;;
91+}</preformat>
92+ <p>A list:</p>
93+ <list list-type="order">
94+ <list-item>
95+ <p>item one</p>
96+ </list-item>
97+ <list-item>
98+ <p>item two</p>
99+ </list-item>
100+ </list>
101+ <p>Nested block quotes:</p>
102+ <p specific-use="wrapper">
103+ <disp-quote>
104+ <p>nested</p>
105+ </disp-quote>
106+ </p>
107+ <p specific-use="wrapper">
108+ <disp-quote>
103− <p>nested</p>
109+ <p>nested</p>
110+ </disp-quote>
111+ </p>
104 </disp-quote>
112 </disp-quote>
105− </disp-quote>
113+ </p>
106 <p>This should not be a block quote: 2 &gt; 1.</p>
114 <p>This should not be a block quote: 2 &gt; 1.</p>
107 <p>And a following paragraph.</p>
115 <p>And a following paragraph.</p>
108</sec>
116</sec>
@@ -829,10 +837,12 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
829 </list-item>
837 </list-item>
830 </list>
838 </list>
831 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
839 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
840+ <p specific-use="wrapper">
832− <disp-quote>
841+ <disp-quote>
833− <p>Blockquoted:
842+ <p>Blockquoted:
834− <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
843+ <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
835− </disp-quote>
844+ </disp-quote>
845+ </p>
836 <p>Auto-links should not occur here:
846 <p>Auto-links should not occur here:
837 <monospace>&lt;http://example.com/&gt;</monospace></p>
847 <monospace>&lt;http://example.com/&gt;</monospace></p>
838 <preformat>or here: &lt;http://example.com/&gt;</preformat>
848 <preformat>or here: &lt;http://example.com/&gt;</preformat>
@@ -856,9 +866,11 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
856 <italic>not</italic> be a footnote reference, because it contains a
866 <italic>not</italic> be a footnote reference, because it contains a
857 space.[^my note] Here is an inline
867 space.[^my note] Here is an inline
858 note.<xref ref-type="fn" rid="fn3">3</xref></p>
868 note.<xref ref-type="fn" rid="fn3">3</xref></p>
869+ <p specific-use="wrapper">
859− <disp-quote>
870+ <disp-quote>
860− <p>Notes can go in quotes.<xref ref-type="fn" rid="fn4">4</xref></p>
871+ <p>Notes can go in quotes.<xref ref-type="fn" rid="fn4">4</xref></p>
861− </disp-quote>
872+ </disp-quote>
873+ </p>
862 <list list-type="order">
874 <list list-type="order">
863 <list-item>
875 <list-item>
864 <p>And in list items.<xref ref-type="fn" rid="fn5">5</xref></p>
876 <p>And in list items.<xref ref-type="fn" rid="fn5">5</xref></p>
test/writer.jats_articleauthoring+48−40
@@ -67,39 +67,43 @@ Gruber’s markdown test suite.</p>
67<sec id="block-quotes">
67<sec id="block-quotes">
68 <title>Block Quotes</title>
68 <title>Block Quotes</title>
69 <p>E-mail style:</p>
69 <p>E-mail style:</p>
70+ <p specific-use="wrapper">
70− <disp-quote>
71+ <disp-quote>
71− <p>This is a block quote. It is pretty short.</p>
72+ <p>This is a block quote. It is pretty short.</p>
72− </disp-quote>
73+ </disp-quote>
74+ </p>
75+ <p specific-use="wrapper">
73− <disp-quote>
76+ <disp-quote>
74− <p>Code in a block quote:</p>
77+ <p>Code in a block quote:</p>
75− <p specific-use="wrapper">
78+ <p specific-use="wrapper">
76− <preformat>sub status {
79+ <preformat>sub status {
77 print &quot;working&quot;;
80 print &quot;working&quot;;
78}</preformat>
81}</preformat>
79− </p>
82+ </p>
80− <p>A list:</p>
83+ <p>A list:</p>
81− <p specific-use="wrapper">
84+ <p specific-use="wrapper">
82− <list list-type="order">
85+ <list list-type="order">
83− <list-item>
86+ <list-item>
84− <p>item one</p>
87+ <p>item one</p>
85− </list-item>
88+ </list-item>
86− <list-item>
89+ <list-item>
87− <p>item two</p>
90+ <p>item two</p>
88− </list-item>
91+ </list-item>
89− </list>
92+ </list>
90− </p>
93+ </p>
91− <p>Nested block quotes:</p>
94+ <p>Nested block quotes:</p>
92− <p specific-use="wrapper">
95+ <p specific-use="wrapper">
93− <disp-quote>
96+ <disp-quote>
94− <p>nested</p>
97+ <p>nested</p>
95− </disp-quote>
98+ </disp-quote>
96− </p>
99+ </p>
97− <p specific-use="wrapper">
100+ <p specific-use="wrapper">
98− <disp-quote>
101+ <disp-quote>
99− <p>nested</p>
102+ <p>nested</p>
100− </disp-quote>
103+ </disp-quote>
101− </p>
104+ </p>
102− </disp-quote>
105+ </disp-quote>
106+ </p>
103 <p>This should not be a block quote: 2 &gt; 1.</p>
107 <p>This should not be a block quote: 2 &gt; 1.</p>
104 <p>And a following paragraph.</p>
108 <p>And a following paragraph.</p>
105</sec>
109</sec>
@@ -813,10 +817,12 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
813 </list-item>
817 </list-item>
814 </list>
818 </list>
815 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
819 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
820+ <p specific-use="wrapper">
816− <disp-quote>
821+ <disp-quote>
817− <p>Blockquoted:
822+ <p>Blockquoted:
818− <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
823+ <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
819− </disp-quote>
824+ </disp-quote>
825+ </p>
820 <p>Auto-links should not occur here:
826 <p>Auto-links should not occur here:
821 <monospace>&lt;http://example.com/&gt;</monospace></p>
827 <monospace>&lt;http://example.com/&gt;</monospace></p>
822 <preformat>or here: &lt;http://example.com/&gt;</preformat>
828 <preformat>or here: &lt;http://example.com/&gt;</preformat>
@@ -854,11 +860,13 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
854 and <monospace>]</monospace> verbatim characters, as well as [bracketed
860 and <monospace>]</monospace> verbatim characters, as well as [bracketed
855 text].</p>
861 text].</p>
856 </fn></p>
862 </fn></p>
863+ <p specific-use="wrapper">
857− <disp-quote>
864+ <disp-quote>
858− <p>Notes can go in quotes.<fn>
865+ <p>Notes can go in quotes.<fn>
859− <p>In quote.</p>
866+ <p>In quote.</p>
860− </fn></p>
867+ </fn></p>
861− </disp-quote>
868+ </disp-quote>
869+ </p>
862 <list list-type="order">
870 <list list-type="order">
863 <list-item>
871 <list-item>
864 <p>And in list items.<fn>
872 <p>And in list items.<fn>
test/writer.jats_publishing+40−28
@@ -78,31 +78,39 @@ Gruber’s markdown test suite.</p>
78<sec id="block-quotes">
78<sec id="block-quotes">
79 <title>Block Quotes</title>
79 <title>Block Quotes</title>
80 <p>E-mail style:</p>
80 <p>E-mail style:</p>
81− <disp-quote>
81+ <p specific-use="wrapper">
82− <p>This is a block quote. It is pretty short.</p>
83− </disp-quote>
84− <disp-quote>
85− <p>Code in a block quote:</p>
86− <preformat>sub status {
87− print &quot;working&quot;;
88−}</preformat>
89− <p>A list:</p>
90− <list list-type="order">
91− <list-item>
92− <p>item one</p>
93− </list-item>
94− <list-item>
95− <p>item two</p>
96− </list-item>
97− </list>
98− <p>Nested block quotes:</p>
99 <disp-quote>
82 <disp-quote>
100− <p>nested</p>
83+ <p>This is a block quote. It is pretty short.</p>
101 </disp-quote>
84 </disp-quote>
85+ </p>
86+ <p specific-use="wrapper">
102 <disp-quote>
87 <disp-quote>
88+ <p>Code in a block quote:</p>
89+ <preformat>sub status {
90+ print &quot;working&quot;;
91+}</preformat>
92+ <p>A list:</p>
93+ <list list-type="order">
94+ <list-item>
95+ <p>item one</p>
96+ </list-item>
97+ <list-item>
98+ <p>item two</p>
99+ </list-item>
100+ </list>
101+ <p>Nested block quotes:</p>
102+ <p specific-use="wrapper">
103+ <disp-quote>
104+ <p>nested</p>
105+ </disp-quote>
106+ </p>
107+ <p specific-use="wrapper">
108+ <disp-quote>
103− <p>nested</p>
109+ <p>nested</p>
110+ </disp-quote>
111+ </p>
104 </disp-quote>
112 </disp-quote>
105− </disp-quote>
113+ </p>
106 <p>This should not be a block quote: 2 &gt; 1.</p>
114 <p>This should not be a block quote: 2 &gt; 1.</p>
107 <p>And a following paragraph.</p>
115 <p>And a following paragraph.</p>
108</sec>
116</sec>
@@ -829,10 +837,12 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
829 </list-item>
837 </list-item>
830 </list>
838 </list>
831 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
839 <p>An e-mail address: <email>nobody@nowhere.net</email></p>
840+ <p specific-use="wrapper">
832− <disp-quote>
841+ <disp-quote>
833− <p>Blockquoted:
842+ <p>Blockquoted:
834− <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
843+ <ext-link ext-link-type="uri" xlink:href="http://example.com/">http://example.com/</ext-link></p>
835− </disp-quote>
844+ </disp-quote>
845+ </p>
836 <p>Auto-links should not occur here:
846 <p>Auto-links should not occur here:
837 <monospace>&lt;http://example.com/&gt;</monospace></p>
847 <monospace>&lt;http://example.com/&gt;</monospace></p>
838 <preformat>or here: &lt;http://example.com/&gt;</preformat>
848 <preformat>or here: &lt;http://example.com/&gt;</preformat>
@@ -856,9 +866,11 @@ These should not be escaped: \$ \\ \&gt; \[ \{</preformat>
856 <italic>not</italic> be a footnote reference, because it contains a
866 <italic>not</italic> be a footnote reference, because it contains a
857 space.[^my note] Here is an inline
867 space.[^my note] Here is an inline
858 note.<xref ref-type="fn" rid="fn3">3</xref></p>
868 note.<xref ref-type="fn" rid="fn3">3</xref></p>
869+ <p specific-use="wrapper">
859− <disp-quote>
870+ <disp-quote>
860− <p>Notes can go in quotes.<xref ref-type="fn" rid="fn4">4</xref></p>
871+ <p>Notes can go in quotes.<xref ref-type="fn" rid="fn4">4</xref></p>
861− </disp-quote>
872+ </disp-quote>
873+ </p>
862 <list list-type="order">
874 <list list-type="order">
863 <list-item>
875 <list-item>
864 <p>And in list items.<xref ref-type="fn" rid="fn5">5</xref></p>
876 <p>And in list items.<xref ref-type="fn" rid="fn5">5</xref></p>
test/writer.opml+1−1
@@ -52,7 +52,7 @@
52</outline>
52</outline>
53<outline text="LaTeX" _note="- &#10;- 2 + 2 = 4&#10;- *x* ∈ *y*&#10;- *α* ∧ *ω*&#10;- 223&#10;- *p*-Tree&#10;- Here’s some display math:&#10; $$\\frac{d}{dx}f(x)=\\lim\_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$$&#10;- Here’s one that has a line break in it: *α* + *ω* × *x*².&#10;&#10;These shouldn’t be math:&#10;&#10;- To get the famous equation, write `$e = mc^2$`.&#10;- $22,000 is a *lot* of money. So is $34,000. (It worked if “lot” is&#10; emphasized.)&#10;- Shoes ($20) and socks ($5).&#10;- Escaped `$`: $73 *this should be emphasized* 23$.&#10;&#10;Here’s a LaTeX table:&#10;&#10;------------------------------------------------------------------------">
53<outline text="LaTeX" _note="- &#10;- 2 + 2 = 4&#10;- *x* ∈ *y*&#10;- *α* ∧ *ω*&#10;- 223&#10;- *p*-Tree&#10;- Here’s some display math:&#10; $$\\frac{d}{dx}f(x)=\\lim\_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$$&#10;- Here’s one that has a line break in it: *α* + *ω* × *x*².&#10;&#10;These shouldn’t be math:&#10;&#10;- To get the famous equation, write `$e = mc^2$`.&#10;- $22,000 is a *lot* of money. So is $34,000. (It worked if “lot” is&#10; emphasized.)&#10;- Shoes ($20) and socks ($5).&#10;- Escaped `$`: $73 *this should be emphasized* 23$.&#10;&#10;Here’s a LaTeX table:&#10;&#10;------------------------------------------------------------------------">
54</outline>
54</outline>
55−<outline text="Special Characters" _note="Here is some unicode:&#10;&#10;- I hat: Î&#10;- o umlaut: ö&#10;- section: §&#10;- set membership: ∈&#10;- copyright: ©&#10;&#10;AT&amp;T has an ampersand in their name.&#10;&#10;AT&amp;T is another way to write it.&#10;&#10;This &amp; that.&#10;&#10;4 &amp;lt; 5.&#10;&#10;6 &amp;gt; 5.&#10;&#10;Backslash: \\&#10;&#10;Backtick: \`&#10;&#10;Asterisk: \*&#10;&#10;Underscore: \_&#10;&#10;Left brace: {&#10;&#10;Right brace: }&#10;&#10;Left bracket: \[&#10;&#10;Right bracket: \]&#10;&#10;Left paren: (&#10;&#10;Right paren: )&#10;&#10;Greater-than: &amp;gt;&#10;&#10;Hash: #&#10;&#10;Period: .&#10;&#10;Bang: !&#10;&#10;Plus: +&#10;&#10;Minus: -&#10;&#10;------------------------------------------------------------------------">
55+<outline text="Special Characters" _note="Here is some unicode:&#10;&#10;- I hat: Î&#10;- o umlaut: ö&#10;- section: §&#10;- set membership: ∈&#10;- copyright: ©&#10;&#10;AT&amp;T has an ampersand in their name.&#10;&#10;AT&amp;T is another way to write it.&#10;&#10;This &amp; that.&#10;&#10;4 &amp;lt; 5.&#10;&#10;6 &amp;gt; 5.&#10;&#10;Backslash: \\&#10;&#10;Backtick: \`&#10;&#10;Asterisk: \*&#10;&#10;Underscore: \_&#10;&#10;Left brace: {&#10;&#10;Right brace: }&#10;&#10;Left bracket: \[&#10;&#10;Right bracket: \]&#10;&#10;Left paren: (&#10;&#10;Right paren: )&#10;&#10;Greater-than: &amp;gt;&#10;&#10;Hash: \#&#10;&#10;Period: .&#10;&#10;Bang: !&#10;&#10;Plus: +&#10;&#10;Minus: -&#10;&#10;------------------------------------------------------------------------">
56</outline>
56</outline>
57<outline text="Links">
57<outline text="Links">
58 <outline text="Explicit" _note="Just a [URL](/url/).&#10;&#10;[URL and title](/url/ &quot;title&quot;).&#10;&#10;[URL and title](/url/ &quot;title preceded by two spaces&quot;).&#10;&#10;[URL and title](/url/ &quot;title preceded by a tab&quot;).&#10;&#10;[URL and title](/url/ &quot;title with &quot;quotes&quot; in it&quot;)&#10;&#10;[URL and title](/url/ &quot;title with single quotes&quot;)&#10;&#10;[with\_underscore](/url/with_underscore)&#10;&#10;[Email link](mailto:nobody@nowhere.net)&#10;&#10;[Empty]().">
58 <outline text="Explicit" _note="Just a [URL](/url/).&#10;&#10;[URL and title](/url/ &quot;title&quot;).&#10;&#10;[URL and title](/url/ &quot;title preceded by two spaces&quot;).&#10;&#10;[URL and title](/url/ &quot;title preceded by a tab&quot;).&#10;&#10;[URL and title](/url/ &quot;title with &quot;quotes&quot; in it&quot;)&#10;&#10;[URL and title](/url/ &quot;title with single quotes&quot;)&#10;&#10;[with\_underscore](/url/with_underscore)&#10;&#10;[Email link](mailto:nobody@nowhere.net)&#10;&#10;[Empty]().">
test/writer.zimwiki+3−3
@@ -8,9 +8,9 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber’s
8
8
9====== Headers ======
9====== Headers ======
10
10
11−===== Level 2 with an [[url|embedded link]] =====
11+===== Level 2 with an embedded link =====
12
12
13−==== Level 3 with //emphasis// ====
13+==== Level 3 with emphasis ====
14
14
15=== Level 4 ===
15=== Level 4 ===
16
16
@@ -18,7 +18,7 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber’s
18
18
19====== Level 1 ======
19====== Level 1 ======
20
20
21−===== Level 2 with //emphasis// =====
21+===== Level 2 with emphasis =====
22
22
23==== Level 3 ====
23==== Level 3 ====
24
24
test/writers-lang-and-dir.context−4
@@ -15,7 +15,6 @@
15
15
16% use microtypography
16% use microtypography
17\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
17\definefontfeature[default][default][script=latn, protrusion=quality, expansion=quality, itlc=yes, textitalics=yes, onum=yes, pnum=yes]
18−\definefontfeature[default:tnum][default][tnum=yes, pnum=no]
19\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
18\definefontfeature[smallcaps][script=latn, protrusion=quality, expansion=quality, smcp=yes, onum=yes, pnum=yes]
20\setupalign[hz,hanging]
19\setupalign[hz,hanging]
21\setupitaliccorrection[global, always]
20\setupitaliccorrection[global, always]
@@ -47,9 +46,6 @@
47\setupitemize[autointro] % prevent orphan list intro
46\setupitemize[autointro] % prevent orphan list intro
48\setupitemize[indentnext=no]
47\setupitemize[indentnext=no]
49
48
50−\defineitemgroup[enumerate]
51−\setupenumerate[each][fit][itemalign=left,distance=.5em,style={\feature[+][default:tnum]}]
52−
53\setupfloat[figure][default={here,nonumber}]
49\setupfloat[figure][default={here,nonumber}]
54\setupfloat[table][default={here,nonumber}]
50\setupfloat[table][default={here,nonumber}]
55
51
tools/build-arm.sh+1−3
@@ -1,8 +1,6 @@
1#!/bin/sh
1#!/bin/sh
2
2
3−#old version:
4−#IMAGE_ID=ami-0fa8979d18f69948b
3+IMAGE_ID=ami-0fa8979d18f69948b
5−IMAGE_ID=ami-0cd6b53a434812702
6INSTANCE_TYPE=t4g.2xlarge
4INSTANCE_TYPE=t4g.2xlarge
7KEY_NAME=debian-arm-us-east-2
5KEY_NAME=debian-arm-us-east-2
8SECURITY_GROUP_ID=sg-086ffbadc286c5c00
6SECURITY_GROUP_ID=sg-086ffbadc286c5c00