pandoc 3.8.3 → 3.10
raw patch · 245 files changed
Files
- AUTHORS.md +18/−0
- CONTRIBUTING.md +4/−4
- COPYRIGHT +27/−0
- MANUAL.txt +218/−102
- README.md +7/−6
- changelog.md +794/−1
- data/bash_completion.tpl +1/−1
- data/odt/content.xml +81/−1
- data/odt/styles.xml +60/−5
- data/templates/default.beamer +1/−1
- data/templates/default.epub2 +1/−1
- data/templates/default.epub3 +1/−1
- data/templates/default.html4 +1/−1
- data/templates/default.html5 +2/−2
- data/templates/default.icml +5/−0
- data/templates/default.jats_articleauthoring +1/−1
- data/templates/default.latex +1/−0
- data/templates/default.revealjs +22/−3
- data/templates/default.typst +5/−9
- data/templates/document-metadata.latex +20/−0
- data/templates/hypersetup.latex +5/−1
- data/templates/styles.html +7/−3
- data/templates/template.typst +40/−39
- pandoc.cabal +44/−34
- src/Text/Pandoc/App.hs +3/−0
- src/Text/Pandoc/App/CommandLineOptions.hs +19/−9
- src/Text/Pandoc/App/Opt.hs +49/−27
- src/Text/Pandoc/Citeproc.hs +16/−3
- src/Text/Pandoc/Citeproc/BibTeX.hs +9/−7
- src/Text/Pandoc/Citeproc/Locator.hs +2/−2
- src/Text/Pandoc/Citeproc/Name.hs +2/−2
- src/Text/Pandoc/Class/CommonState.hs +7/−0
- src/Text/Pandoc/Class/IO.hs +36/−13
- src/Text/Pandoc/Class/PandocMonad.hs +1/−1
- src/Text/Pandoc/Error.hs +29/−25
- src/Text/Pandoc/Extensions.hs +2/−0
- src/Text/Pandoc/Format.hs +2/−2
- src/Text/Pandoc/ImageSize.hs +3/−1
- src/Text/Pandoc/Logging.hs +7/−0
- src/Text/Pandoc/Options.hs +3/−1
- src/Text/Pandoc/PDF.hs +2/−1
- src/Text/Pandoc/Parsing/General.hs +19/−18
- src/Text/Pandoc/Parsing/Lists.hs +1/−1
- src/Text/Pandoc/Parsing/Math.hs +22/−13
- src/Text/Pandoc/Readers/AsciiDoc.hs +3/−3
- src/Text/Pandoc/Readers/Djot.hs +1/−2
- src/Text/Pandoc/Readers/DocBook.hs +52/−35
- src/Text/Pandoc/Readers/Docx.hs +15/−8
- src/Text/Pandoc/Readers/Docx/Combine.hs +8/−7
- src/Text/Pandoc/Readers/Docx/Parse.hs +124/−34
- src/Text/Pandoc/Readers/EndNote.hs +1/−0
- src/Text/Pandoc/Readers/HTML.hs +17/−14
- src/Text/Pandoc/Readers/HTML/Table.hs +3/−3
- src/Text/Pandoc/Readers/JATS.hs +6/−7
- src/Text/Pandoc/Readers/LaTeX.hs +50/−2
- src/Text/Pandoc/Readers/LaTeX/Inline.hs +20/−0
- src/Text/Pandoc/Readers/LaTeX/Math.hs +13/−8
- src/Text/Pandoc/Readers/LaTeX/Parsing.hs +3/−1
- src/Text/Pandoc/Readers/LaTeX/Table.hs +4/−10
- src/Text/Pandoc/Readers/Man.hs +32/−5
- src/Text/Pandoc/Readers/Markdown.hs +58/−25
- src/Text/Pandoc/Readers/MediaWiki.hs +140/−22
- src/Text/Pandoc/Readers/ODT/Arrows/State.hs +2/−2
- src/Text/Pandoc/Readers/ODT/ContentReader.hs +105/−70
- src/Text/Pandoc/Readers/ODT/Generic/XMLConverter.hs +2/−2
- src/Text/Pandoc/Readers/ODT/StyleReader.hs +20/−20
- src/Text/Pandoc/Readers/Org/Blocks.hs +6/−6
- src/Text/Pandoc/Readers/RIS.hs +2/−2
- src/Text/Pandoc/Readers/RST.hs +0/−8
- src/Text/Pandoc/Readers/RTF.hs +68/−24
- src/Text/Pandoc/Readers/Roff.hs +2/−1
- src/Text/Pandoc/Readers/Textile.hs +9/−4
- src/Text/Pandoc/Readers/Typst.hs +38/−5
- src/Text/Pandoc/SelfContained.hs +1/−1
- src/Text/Pandoc/Shared.hs +60/−37
- src/Text/Pandoc/Translations.hs +19/−24
- src/Text/Pandoc/UTF8.hs +1/−1
- src/Text/Pandoc/Writers/AsciiDoc.hs +13/−8
- src/Text/Pandoc/Writers/DocBook.hs +1/−11
- src/Text/Pandoc/Writers/Docx.hs +824/−723
- src/Text/Pandoc/Writers/Docx/OpenXML.hs +20/−12
- src/Text/Pandoc/Writers/Docx/Types.hs +2/−0
- src/Text/Pandoc/Writers/EPUB.hs +35/−24
- src/Text/Pandoc/Writers/GridTable.hs +7/−2
- src/Text/Pandoc/Writers/HTML.hs +74/−36
- src/Text/Pandoc/Writers/ICML.hs +48/−19
- src/Text/Pandoc/Writers/JATS.hs +45/−11
- src/Text/Pandoc/Writers/LaTeX.hs +99/−4
- src/Text/Pandoc/Writers/LaTeX/Citation.hs +3/−3
- src/Text/Pandoc/Writers/LaTeX/Lang.hs +1/−1
- src/Text/Pandoc/Writers/LaTeX/Types.hs +8/−0
- src/Text/Pandoc/Writers/Man.hs +2/−2
- src/Text/Pandoc/Writers/Markdown.hs +27/−18
- src/Text/Pandoc/Writers/Markdown/Inline.hs +15/−9
- src/Text/Pandoc/Writers/MediaWiki.hs +144/−131
- src/Text/Pandoc/Writers/ODT.hs +53/−2
- src/Text/Pandoc/Writers/OpenDocument.hs +180/−159
- src/Text/Pandoc/Writers/Powerpoint/Output.hs +5/−1
- src/Text/Pandoc/Writers/Powerpoint/Presentation.hs +17/−15
- src/Text/Pandoc/Writers/RST.hs +3/−2
- src/Text/Pandoc/Writers/Shared.hs +65/−25
- src/Text/Pandoc/Writers/Texinfo.hs +22/−4
- src/Text/Pandoc/Writers/Typst.hs +65/−24
- test/Tests/MediaBag.hs +24/−16
- test/Tests/Old.hs +1/−1
- test/Tests/Readers/Docx.hs +25/−0
- test/Tests/Readers/HTML.hs +1/−1
- test/Tests/Readers/Markdown.hs +6/−0
- test/Tests/Readers/ODT.hs +4/−0
- test/Tests/Readers/Org/Block.hs +2/−2
- test/Tests/Readers/Org/Block/CodeBlock.hs +3/−3
- test/Tests/Writers/Docx.hs +163/−3
- test/Tests/Writers/HTML.hs +2/−2
- test/Tests/Writers/Powerpoint.hs +4/−0
- test/command/10271.md +1/−1
- test/command/10643.md +11/−0
- test/command/10791.md +4/−3
- test/command/10942.md +97/−0
- test/command/10965.md +6/−3
- test/command/11299.md +28/−0
- test/command/11300.md +67/−0
- test/command/11312.md +21/−0
- test/command/11323.md +12/−0
- test/command/11341.md +9/−0
- test/command/11342.md +33/−0
- test/command/11348.md +61/−0
- test/command/11362.md +17/−0
- test/command/11364.md +75/−0
- test/command/11374.md +6/−0
- test/command/11384.md +17/−0
- test/command/11409.md +11/−0
- test/command/11420.md +15/−0
- test/command/11422.md +12/−0
- test/command/11450.md +62/−0
- test/command/11455.md +26/−0
- test/command/11463.md +13/−0
- test/command/11479.md +31/−0
- test/command/11486.md +82/−0
- test/command/11486/scroll.revealjs +15/−0
- test/command/11490.md +13/−0
- test/command/11494.md +73/−0
- test/command/11498.md +121/−0
- test/command/11498.png binary
- test/command/11511.md +6/−0
- test/command/11534.md +42/−0
- test/command/11542.md +47/−0
- test/command/11562.md +10/−0
- test/command/11571.md +18/−0
- test/command/11583.md +16/−0
- test/command/11588.md +10/−0
- test/command/11589.md +20/−0
- test/command/11598.md +16/−0
- test/command/11604.md +22/−0
- test/command/11608.md +54/−0
- test/command/11635.md +28/−0
- test/command/11664.md +35/−0
- test/command/11668.md +42/−0
- test/command/11682.md +81/−0
- test/command/2434.md +19/−16
- test/command/4186.md +5/−5
- test/command/5543.md +1/−1
- test/command/5876.md +2/−2
- test/command/6137.md +62/−65
- test/command/6719.md +2/−2
- test/command/6858.md +4/−4
- test/command/7201.md +47/−0
- test/command/7521.md +1/−1
- test/command/7582.md +28/−0
- test/command/7861.md +1/−1
- test/command/8024.md +10/−0
- test/command/8024a.yaml +2/−0
- test/command/8024b.yaml +3/−0
- test/command/8256.md +1/−2
- test/command/8665.md +1/−1
- test/command/8783.md +33/−0
- test/command/8852.md +43/−0
- test/command/8880.md +42/−0
- test/command/8966.md +1/−1
- test/command/8997.md +4/−4
- test/command/9136.md +89/−0
- test/command/9201.md +2/−2
- test/command/9236.md +6/−5
- test/command/9391.md +1/−1
- test/command/9472.md +4/−0
- test/command/9700.md +2/−2
- test/command/9716.md +13/−0
- test/command/biblatex-crossref-nested.md +1/−1
- test/command/figures-mediawiki.md +0/−3
- test/command/grid-table-indented.md +65/−0
- test/command/mediawiki_behavior_switches.md +16/−0
- test/command/pdfstandard.md +616/−0
- test/command/reset-citation-positions.md +41/−0
- test/command/table-with-column-span.md +2/−2
- test/command/typst-image-alt.md +78/−0
- test/command/typst-images.md +32/−0
- test/command/typst-property-output.md +9/−6
- test/docbook-reader.docbook +38/−4
- test/docbook-reader.native +107/−4
- test/docx/german-reference.docx binary
- test/docx/image_with_textbox_caption.docx binary
- test/docx/image_with_textbox_caption.native +44/−0
- test/docx/table_gridbefore.docx binary
- test/docx/table_gridbefore.native +823/−0
- test/docx/textbox_image.docx binary
- test/docx/textbox_image.native +30/−0
- test/docx/textbox_image_duplicate_encoding.docx binary
- test/docx/textbox_image_duplicate_encoding.native +30/−0
- test/man-reader.native +20/−16
- test/odt/native/imageRelative.native +10/−0
- test/odt/native/preformattedText.native +4/−0
- test/odt/native/preformattedTextParentStyle.native +4/−0
- test/odt/native/sourceText.native +11/−0
- test/odt/native/tableWithSpans.native +134/−0
- test/odt/odt/imageRelative.odt binary
- test/odt/odt/preformattedText.odt binary
- test/odt/odt/preformattedTextParentStyle.odt binary
- test/odt/odt/sourceText.odt binary
- test/odt/odt/tableWithSpans.odt binary
- test/pptx/metadata-speaker-notes/input.native +3/−0
- test/pptx/metadata-speaker-notes/output.pptx binary
- test/pptx/metadata-speaker-notes/templated.pptx binary
- test/s5-basic.html +6/−3
- test/s5-fancy.html +7/−4
- test/s5-inserts.html +7/−4
- test/tables/nordics.markdown +17/−17
- test/tables/nordics.mediawiki +1/−1
- test/tables/nordics.typst +1/−3
- test/tables/students.mediawiki +1/−1
- test/typst-reader.native +18/−21
- test/writer.asciidoc +1/−1
- test/writer.asciidoc_legacy +1/−1
- test/writer.html4 +8/−4
- test/writer.html5 +9/−5
- test/writer.jats_archiving +5/−23
- test/writer.jats_articleauthoring +5/−23
- test/writer.jats_publishing +5/−23
- test/writer.latex +4/−0
- test/writer.man +13/−0
- test/writer.markdown +27/−27
- test/writer.mediawiki +13/−37
- test/writer.opendocument +952/−1902
- test/writer.opml +1/−1
- test/writer.plain +27/−27
- test/writer.typst +48/−52
- test/writers-lang-and-dir.latex +4/−0
AUTHORS.md view
@@ -2,10 +2,12 @@ - Aaron Wolen - Adelar da Silva Queiróz+- Agriya Khetarpal - Agustín Martín Barbero - Akash Patel - Akos Marton - Albert Krewinkel+- Albert Lei - Alex Ivkin - Alex Toldaiev - Alex Vong@@ -33,6 +35,7 @@ - Anti-Distinctlyminty - Antoine Latter - Anton Antich+- Anton Melnikov - Antonio Terceiro - Arata Mizuki - Arata Mizuki@@ -74,6 +77,7 @@ - Charles Tapley Hoyt - Charlotte Koch - Chris Black+- Chris Callison-Burch - Christian Conkle - Christian Christiansen - Christian Despres@@ -87,6 +91,7 @@ - Cormac Relf - Craig S. Bosma - Damien Clochard+- Dan Jacobson - Daniel Bergey - Daniel Kessler - Daniel Maslowski@@ -176,6 +181,7 @@ - Ivar de Bruin - Ivo Clarysse - Jaap de Jong+- Jacob Larkin - James J Balamuta - J. B. Rainsberger - J. Lewis Muir@@ -210,6 +216,7 @@ - Jez Cope - Joe Hermaszewski - Joe Hillenbrand+- Johan Larsson - John KetzerX - John Luke Bentley - John MacFarlane@@ -232,6 +239,7 @@ - Justin Bogner - Justin Wood - Karl Pettersson+- Keenan Brock - Keiichiro Shikano - Kelsey Hightower - Kevin Broch@@ -281,6 +289,7 @@ - Max Bolingbroke - Max Heller - Max Rydahl Andersen+- Meher Chaitanya - Merijn Verstraaten - Michael Beaumont - Michael Chladek@@ -334,6 +343,7 @@ - Pavol Otto - Per Christian Gaustad - Pete Ryland+- Peter Briggs - Peter Fabinksi - Peter Wang - Philip Pesca@@ -359,6 +369,7 @@ - RyanGlScott - Ryan Gibb - S.P.H+- Sai Asish Y - Salim B - Sam S. Almahri - Sam May@@ -379,6 +390,7 @@ - Shim Myeongseob - Shin Sang-jae - Sidarth Kapur+- Sidney Mau - Sidharth Kapur - Simon Hengel - Simon Schuster@@ -441,15 +453,18 @@ - Wout Gevaert - Xavier Olive - Yan Pashkovsky+- Yann Trividic - Yehuda Katz - YI - Yoan Blanc+- You Jiangbin - Yuchen Pei - Zihang Chen - 3w36zj6 - arcnmx - a-vrma - andrebauer+- benniekiss - black-desk - blmage - bucklereed@@ -466,6 +481,7 @@ - etclub - favonia - guqicun+- har7an - harabat - hseg - infinity0x@@ -484,6 +500,7 @@ - mjfs - mt_caret - nbehrnd+- nibras shami - niszet - nkalvi - nuew@@ -520,3 +537,4 @@ - wiefling - willj-dev - wuffi+- λx.x
CONTRIBUTING.md view
@@ -215,9 +215,9 @@ external C libraries should especially be avoided. 10. We aim for compatibility with at least the last three- released ghc versions, and sometimes more. Currently pandoc- can be compiled on ghc 8.6 an higher. All pull requests and- commits are tested automatically on GitHub Actions.+ released ghc versions, and sometimes more. Currently we+ support ghc versions 9.6 and higher. All pull requests+ and commits are tested automatically on GitHub Actions. Tests -----@@ -448,7 +448,7 @@ Lua filters ----------- -If you've written a useful pandoc [lua filter](lua-filters.html),+If you've written a useful pandoc [lua filter](./doc/lua-filters.md), you may want to consider submitting a pull request to the [lua-filters repository](https://github.com/pandoc/lua-filters).
COPYRIGHT view
@@ -196,3 +196,30 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.++------------------------------------------------------------------------+Some of the code in wasm/pandoc.js and the patches in wasm/patches is+from https://github.com/haskell-wasm/pandoc-wasm. It is released under+this license:++MIT License++Copyright (c) Tweag I/O Limited.++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
MANUAL.txt view
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: 2025-12-01+date: 2026-06-03 --- # Synopsis@@ -307,7 +307,7 @@ - `bbcode` [BBCode] - `bbcode_fluxbb` [BBCode (FluxBB)] - `bbcode_phpbb` [BBCode (phpBB)]- - `bbcode_steam` [BBCode (Hubzilla)]+ - `bbcode_steam` [BBCode (Steam)] - `bbcode_hubzilla` [BBCode (Hubzilla)] - `bbcode_xenforo` [BBCode (xenForo)] - `beamer` ([LaTeX beamer][`beamer`] slide show)@@ -416,17 +416,17 @@ `-d` *FILE*, `--defaults=`*FILE* -: Specify a set of default option settings. *FILE* is a YAML+: Specify a set of default option settings. *FILE* is a YAML or JSON file whose fields correspond to command-line option settings. All options for document conversion, including input and output files, can be set using a defaults file. The file will be searched for first in the working directory, and then in the `defaults` subdirectory of the user data directory- (see `--data-dir`). The `.yaml` extension may be omitted.- See the section [Defaults files] for more information on the- file format. Settings from the defaults file may be- overridden or extended by subsequent options on the command- line.+ (see `--data-dir`). The `.yaml` extension will be added if+ *FILE* lacs an extension. See the section [Defaults files]+ for more information on the file format. Settings from the+ defaults file may be overridden or extended by subsequent+ options on the command line. `--bash-completion` @@ -435,6 +435,24 @@ eval "$(pandoc --bash-completion)" +`--sandbox[=true|false]`++: Run pandoc in a sandbox, limiting IO operations in readers+ and writers to reading the files specified on the command line.+ Note that this option does not limit IO operations by+ filters or in the production of PDF documents. But it does+ offer security against, for example, disclosure of files+ through the use of `include` directives. Anyone using+ pandoc on untrusted user input should use this option.++ Note: some readers and writers (e.g., `docx`) need access to data+ files. If these are stored on the file system, then pandoc+ will not be able to find them when run in `--sandbox` mode+ and will raise an error. For these applications, we+ recommend using a pandoc binary compiled with the `embed_data_files`+ option, which causes the data files to be baked into the binary+ instead of being stored on the file system.+ `--verbose` : Give verbose debugging output.@@ -512,7 +530,7 @@ [Jira]: https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all [txt2tags]: https://txt2tags.org [EPUB]: http://idpf.org/epub-[OPML]: http://dev.opml.org/spec2.html+[OPML]: https://opml.org/spec2.opml [OpenDocument XML]: https://www.oasis-open.org/2021/06/16/opendocument-v1-3-oasis-standard-published/ [ODT]: https://en.wikipedia.org/wiki/OpenDocument [Plain Old Documentation]: https://perldoc.perl.org/perlpod@@ -544,7 +562,7 @@ [reveal.js]: https://revealjs.com/ [FictionBook2]: http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1 [Jupyter notebook]: https://nbformat.readthedocs.io/en/latest/-[InDesign ICML]: https://manualzz.com/doc/9627253/adobe-indesign-cs6-idml-cookbook+[InDesign ICML]: https://web.archive.org/web/20211006210211/https://wwwimages.adobe.com/www.adobe.com/content/dam/acom/en/devnet/indesign/sdk/cs6/idml/idml-cookbook.pdf [TEI Simple]: https://github.com/TEIC/TEI-Simple [Muse]: https://amusewiki.org/library/manual [PowerPoint]: https://en.wikipedia.org/wiki/Microsoft_PowerPoint@@ -736,7 +754,7 @@ affected paragraph break. This option only affects the docx reader. -`--extract-media=`*DIR*+`--extract-media=`*DIR*|*FILE*`.zip` : Extract images and other media contained in or linked from the source document to the path *DIR*, creating it if@@ -748,6 +766,10 @@ Otherwise filenames are constructed from the SHA1 hash of the contents. + If the path given ends in `.zip`, then instead of creating+ a directory, pandoc will create a zip archive containing the+ media files.+ `--abbreviations=`*FILE* : Specifies a custom abbreviations file, with abbreviations@@ -761,6 +783,13 @@ space, and the period will not produce sentence-ending space in formats like LaTeX. The strings may not contain spaces. +`--typst-input=`*KEY*[`=`*VAL*]++: Set a parameter value that will be made available to the typst+ parser in `sys.inputs`, like `--input` in the `typst` CLI.+ Either `:` or `=` may be used to separate *KEY* from *VAL*.+ Values containing spaces must be quoted.+ `--trace[=true|false]` : Print diagnostic output tracing parser progress to stderr.@@ -809,10 +838,10 @@ a *list* value, the value will be added to the list. If it already has another kind of value, it will be made into a list containing the previous and the new value. For example,- `-V keyword=Joe -V author=Sue` makes `author` contain a list+ `-V author=Joe -V author=Sue` makes `author` contain a list of strings: `Joe` and `Sue`. -`--variable-json=`*KEY*[`=`:*JSON*]+`--variable-json=`*KEY*[`=`*JSON*] : Set the template variable *KEY* to the value specified by a JSON string (this may be a boolean, a string, a list, or a mapping;@@ -823,24 +852,6 @@ separate *KEY* from *VAL*. If the variable already has a value, this value will be replaced. -`--sandbox[=true|false]`--: Run pandoc in a sandbox, limiting IO operations in readers- and writers to reading the files specified on the command line.- Note that this option does not limit IO operations by- filters or in the production of PDF documents. But it does- offer security against, for example, disclosure of files- through the use of `include` directives. Anyone using- pandoc on untrusted user input should use this option.-- Note: some readers and writers (e.g., `docx`) need access to data- files. If these are stored on the file system, then pandoc- will not be able to find them when run in `--sandbox` mode- and will raise an error. For these applications, we- recommend using a pandoc binary compiled with the `embed_data_files`- option, which causes the data files to be baked into the binary- instead of being stored on the file system.- `-D` *FORMAT*, `--print-default-template=`*FORMAT* : Print the system default template for an output *FORMAT*. (See `-t`@@ -907,13 +918,10 @@ on `man`, `docbook4`, `docbook5`, or `jats` output. Note that if you are producing a PDF via `ms` and using- (the default) `pdfroff` as a `--pdf-engine`, the table- of contents will appear at the beginning of the- document, before the title. If you would prefer it to- be at the end of the document, use the option- `--pdf-engine-opt=--no-toc-relocation`. If `groff` is- used as the `--pdf-engine`, the table of contents will- always appear at the end of the document.+ (the default) `groff` as a `--pdf-engine`, the table of+ contents will appear at the end of the document. If you would+ prefer it to be at the beginning of the document, before the+ title, you can use `--pdf-engine=pdfroff`. `--toc-depth=`*NUMBER* @@ -945,27 +953,20 @@ inside raw HTML blocks when the `markdown_in_html_blocks` extension is not set. -`--syntax-highlighting="default"|"none"|"idiomatic"|`*STYLE*`|`*FILE*+`--syntax-highlighting=default|none|idiomatic|`*STYLE*`|`*FILE* : The method to use for code syntax highlighting. Setting a specific *STYLE* causes highlighting to be performed with the internal highlighting engine, using KDE syntax definitions and- styles. The `"idiomatic"` method uses a format-specific+ styles. The `idiomatic` method uses a format-specific highlighter if one is available, or the default style if the target format has no idiomatic highlighting method. Setting this option to `none` disables all syntax highlighting. The- `"default"` method uses a format-specific default.+ `default` method uses a format-specific default. The default for HTML, EPUB, Docx, Ms, Man, and LaTeX output is- to use the internal highlighter with the default style; Typst- output relies on Typst's own syntax highlighting system by- default.-- The [`listings`][] LaTeX package is used for idiomatic- highlighting in LaTeX. The package does not support multi-byte- encoding for source code. To handle UTF-8 you would need to- use a custom template. This issue is fully documented here:- [Encoding issue with the listings package][].+ to use the internal highlighter with the default style; for Typst+ it is to use Typst's own syntax highlighting system. Style options are `pygments` (the default), `kate`, `monochrome`, `breezeDark`, `espresso`, `zenburn`, `haddock`,@@ -1312,7 +1313,7 @@ To produce a custom `reference.docx`, first get a copy of the default `reference.docx`: `pandoc -o custom-reference.docx --print-default-data-file reference.docx`.- Then open `custom-reference.docx` in Word, modify the+ Then open `custom-reference.docx` in Word or LibreOffice, modify the styles as you wish, and save the file. For best results, do not make changes to this file other than modifying the styles used by pandoc:@@ -1431,7 +1432,7 @@ In the template, `%n` will be replaced by the chunk number (padded with leading 0s to 3 digits), `%s` with the section number of the chunk, `%h` with the heading text (with formatting removed), `%i` with- the section identifier. For example, `%section-%s-%i.html` might+ the section identifier. For example, `section-%s-%i.html` might be resolved to `section-1.1-introduction.html`. The characters `/` and `\` are not allowed in chunk templates and will be ignored. The default is `%s-%i.html`.@@ -1542,7 +1543,7 @@ `pagedjs-cli`; see [print-css.rocks](https://print-css.rocks) for a good introduction to PDF generation from HTML/CSS)- - `-t ms`: `pdfroff`+ - `-t ms`: `groff` - `-t typst`: `typst` This option is normally intended to be used when a PDF@@ -1762,7 +1763,9 @@ # Defaults files The `--defaults` option may be used to specify a package-of options, in the form of a YAML file.+of options, in the form of a YAML or JSON file. Examples in+this section will be given in YAML, but the equivalent forms in+JSON will also work. Fields that are omitted will just have their regular default values. So a defaults file can be as simple as@@ -1772,6 +1775,12 @@ verbosity: INFO ``` +or in JSON:++``` json+{ "verbosity": "INFO" }+```+ In fields that expect a file path (or list of file paths), the following syntax may be used to interpolate environment variables: @@ -1964,6 +1973,11 @@ | ``` | ``` | +----------------------------------+-----------------------------------+ | ``` | ``` yaml |+| --typst-input foo=bar | typst-inputs: |+| | foo: bar |+| ``` | ``` |++----------------------------------+-----------------------------------++| ``` | ``` yaml | | --trace | trace: true | | ``` | ``` | +----------------------------------+-----------------------------------+@@ -2005,7 +2019,7 @@ | ``` | ``` | +----------------------------------+-----------------------------------+ | ``` | ``` yaml |-| --wrap 60 | wrap: 60 |+| --wrap preserve | wrap: "preserve" | | ``` | ``` | +----------------------------------+-----------------------------------+ | ``` | ``` yaml |@@ -2964,6 +2978,13 @@ : additional attributes for the title slide of reveal.js slide shows. See [background in reveal.js, beamer, and pptx] for an example. +`highlightjs-theme`+: highlight.js theme for code highlighting when using+ `--syntax-highlighting=idiomatic` with reveal.js (defaults to+ `monokai`). See the [highlight.js demo page] for available themes.++[highlight.js demo page]: https://highlightjs.org/demo+ All [reveal.js configuration options] are available as variables. To turn off boolean flags that default to true in reveal.js, use `0`. @@ -2987,6 +3008,9 @@ `logo` : logo image for slides +`logooptions`+: options for logo image (e.g., `width`, `height`)+ `navigation` : controls navigation symbols (default is `empty` for no navigation symbols; other valid values are `frame`, `vertical`, and `horizontal`)@@ -3004,7 +3028,7 @@ : image for title slide: can be a list `titlegraphicoptions`-: options for title slide image+: options for title slide image (e.g., `width`, `height`) `shorttitle`, `shortsubtitle`, `shortauthor`, `shortinstitute`, `shortdate` : some beamer themes use short versions of the title, subtitle, author,@@ -3276,6 +3300,17 @@ See the section on [reproducible builds]. +`pdfstandard`+: PDF standard(s) for the document, e.g. `ua-2`, `a-4f`.+ Supports PDF/A, PDF/X, and PDF/UA variants.+ Requires LuaLaTeX and LaTeX 2023+. Repeat for multiple standards:++ ---+ pdfstandard:+ - ua-2+ - a-4f+ ...+ [KOMA-Script]: https://ctan.org/pkg/koma-script [LaTeX Font Catalogue]: https://tug.org/FontCatalogue/ [LaTeX font encodings guide]: https://ctan.org/pkg/encguide@@ -3638,13 +3673,13 @@ This extension can be enabled/disabled for the following formats: input formats-: `markdown`, `latex`, `rst`, `mediawiki`, `textile`+: `markdown`, `latex`, `rst`, `mediawiki`, `textile`, `man` output formats : `markdown`, `muse` enabled by default in-: `markdown`, `muse`+: `markdown`, `muse`, `man` The default algorithm used to derive the identifier from the heading text is:@@ -4571,19 +4606,19 @@ or two spaces. A term may have multiple definitions, and each definition may-consist of one or more block elements (paragraph, code block,-list, etc.), each indented four spaces or one tab stop. The-body of the definition (not including the first line)-should be indented four spaces. However, as with-other Markdown lists, you can "lazily" omit indentation except-at the beginning of a paragraph or other block element:+consist of one or more indented block elements (paragraph, code block,+list, etc.). The blocks in the definition shoud be indented to the column+of the first non-space content after the `:` or `~` marker, or+(if the `four_space_rule` extension is enabled) four spaces or+one tab stop. As with other Markdown lists, you can "lazily" omit+indentation in paragraph continuation lines: Term 1 - : Definition+ : Definition with lazy continuation. - Second paragraph of the definition.+ Second paragraph of the definition. If you leave space before the definition (as in the example above), the text of the definition will be treated as a paragraph. In some@@ -5048,6 +5083,7 @@ (`...`) at the bottom. The initial line `---` must not be followed by a blank line. A YAML metadata block may occur anywhere in the document, but if it is not at the beginning, it must be preceded by a blank line.+(Note that JSON may be used as well, because JSON is a subset of YAML.) Note that, because of the way pandoc concatenates input files when several are provided, you may also keep the metadata in a@@ -5154,10 +5190,10 @@ \renewcommand{\section}[1]{\clearpage\oldsection{#1}} ``` -Note: the `yaml_metadata_block` extension works with-`commonmark` as well as `markdown` (and it is enabled by default-in `gfm` and `commonmark_x`). However, in these formats the-following restrictions apply:+Note: the `yaml_metadata_block` extension works not just with+`markdown` but with `commonmark` (and it is enabled by default in+`gfm` and `commonmark_x`). However, in `commonmark`, `gfm`,+and `commonmark_x`, the following restrictions apply: - The YAML metadata block must occur at the beginning of the document (and there can be only one). If multiple files are@@ -5626,22 +5662,34 @@ The link consists of link text in square brackets, followed by a label in square brackets. (There cannot be space between the two unless the-`spaced_reference_links` extension is enabled.) The link definition-consists of the bracketed label, followed by a colon and a space, followed by-the URL, and optionally (after a space) a link title either in quotes or in-parentheses. The label must not be parseable as a citation (assuming-the `citations` extension is enabled): citations take precedence over-link labels.+`spaced_reference_links` extension is enabled.) If the label is empty+(`[]`), then it will be implicitly be taken to be the same as the link text;+thus `[foo][]` is equivalent to `[foo][foo]`. (If the+`shortcut_reference_links` extension is enabled, the empty `[]`+may be omitted.) -Here are some examples:+The link definition consists of the bracketed label, followed by+a colon and a space, followed by the URL, and optionally (after a+space) a link title either in quotes or in parentheses. The label+must not be parseable as a citation (assuming the `citations`+extension is enabled): citations take precedence over link+labels. - [my label 1]: /foo/bar.html "My title, optional"- [my label 2]: /foo- [my label 3]: https://fsf.org (The Free Software Foundation)- [my label 4]: /bar#special 'A title in single quotes'+Here are some examples of reference links and link definitions; -The URL may optionally be surrounded by angle brackets:+ See [the website *I* built][my website]. + See [my website][] and [the bar page][1] and+ the [home page of the FSF][fsf].++ [my website]: http://foo.bar.baz+ [1]: /foo/bar.html "My title, optional"+ [fsf]: https://fsf.org (The Free Software Foundation)+ [special page]: /bar#special 'A title in single quotes'++The URL in a link definition may optionally be surrounded by+angle brackets:+ [my label 5]: <http://foo.bar.baz> The title may go on the next line:@@ -5655,18 +5703,14 @@ [Foo]: /bar/baz -In an *implicit* reference link, the second pair of brackets is-empty:-- See [my website][].-- [my website]: http://foo.bar.baz+The link definition may come either before or after a+reference link that uses the label. -Note: In `Markdown.pl` and most other Markdown implementations,-reference link definitions cannot occur in nested constructions-such as list items or block quotes. Pandoc lifts this-arbitrary-seeming restriction. So the following is fine in pandoc,-though not in most other implementations:+Note: In some Markdown implementations, reference link+definitions cannot occur in nested constructions such as list+items or block quotes. Pandoc lifts this arbitrary-seeming+restriction. So the following is fine in pandoc, though not in+all implementations: > My block [quote]. >@@ -5992,6 +6036,17 @@ this reason, it is sometimes preferable to use the author-in-text style inside notes when using a note style. +Many CSL styles will format citations differently when the+same source has been cited earlier. In documents with chapters,+it is usually desirable to reset this position information+at the beginning of every chapter. To do this, add the class+`reset-citation-positions` to the heading for each chapter:++ # The Beginning {.reset-citation-positions}++Note that this class only has an effect when placed on+top-level headings; it is ignored in nested blocks.+ [CSL user documentation]: https://citationstyles.org/authors/ [CSL]: https://docs.citationstyles.org/en/stable/specification.html [CSL markup specs]: https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html#html-like-formatting-tags@@ -6199,9 +6254,6 @@ [GitHub-style Markdown alerts]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts -Note: This extension currently only works with commonmark:-`commonmark`, `gfm`, `commonmark_x`.- ### Extension: `autolink_bare_uris` ### Makes all absolute URIs into links, even when not surrounded by@@ -6927,6 +6979,23 @@ Notes are not yet supported for other slide formats, but the notes will not appear on the slides themselves. +### Speaker notes on the title slide (PowerPoint)++For PowerPoint output, the title slide is generated from the document's+YAML metadata block. To add speaker notes to this slide, use a `notes`+field in the metadata:++ ---+ title: My Presentation+ author: Jane Doe+ notes: |+ Welcome everyone to this presentation.++ Remember to introduce yourself and mention the key topics.+ ---++The `notes` field can contain multiple paragraphs and Markdown formatting.+ ## Columns To put material in side by side columns, you can use a native@@ -7119,8 +7188,10 @@ ~ Either a string value or an object with fields `text` and `scheme`. Valid values for `scheme` are `ISBN-10`, `GTIN-13`, `UPC`, `ISMN-10`, `DOI`, `LCCN`, `GTIN-14`,- `ISBN-13`, `Legal deposit number`, `URN`, `OCLC`,- `ISMN-13`, `ISBN-A`, `JP`, `OLCC`.+ `ISBN-13`, `Legal deposit number`, `URN`, `OCLC number`,+ `Co-publisher’s ISBN-13`, `ISMN-13`, `ISBN-A`, `JP e-code`,+ `OLCC number`, `JP Magazine ID`, `UPC-12+5`, `BNF Control number`,+ `ISSN-13`, `ARK`, `Digital file internal version number`. `title` ~ Either a string value, or an object with fields `file-as` and@@ -7594,6 +7665,24 @@ To disable highlighting, use `--syntax-highlighting=none`. +To use a format's idiomatic syntax highlighting instead of+pandoc's built-in highlighting, use `--syntax-highlighting=idiomatic`.+Currently, `idiomatic` only affects the following formats:++- In reveal.js, it causes reveal.js's highlighting plugin to be+ used for source code highlighting. The style may be customized+ by setting the `highlightjs-theme` variable.++- In Typst, it causes Typst's built-in highlighting to be used.+ (This is also the default for Typst.)++- In LaTeX, it causes the [`listings`][] package to be used. Note that+ `listings` does not support multi-byte encoding for source code. To handle+ UTF-8 you would need to use a custom template. This issue is fully+ documented here: [Encoding issue with the listings package][].++- In other formats, `idiomatic` will have the same result as `default`.+ [skylighting]: https://github.com/jgm/skylighting # Custom Styles@@ -7646,6 +7735,14 @@ For docx or odt output, you don't need to enable any extensions for custom styles to work. +For icml output, you can also set an `object-style` in images:++ {object-style="fixedSizeImage"}++In InDesign you'll see that object style given to the image,+and you'll be able to customize it, or load its definition from+a template of yours.+ [pandoc filters]: https://pandoc.org/filters.html ## Input@@ -7769,10 +7866,10 @@ However, it is possible to generate accessible PDFs, which use tagging to add semantic information to the document. -Pandoc defaults to LaTeX to generate PDF. Tagging support in LaTeX-is in development and not readily available, so PDFs generated in-this way will always be untagged and not accessible. This means-that alternative engines must be used to generate accessible PDFs.+Pandoc defaults to LaTeX to generate PDF. LaTeX's `\DocumentMetadata`+interface supports PDF standards and tagging when using LuaLaTeX;+set the `pdfstandard` variable to enable this (see below). For older+LaTeX installations, alternative engines must be used. The PDF standards PDF/A and PDF/UA define further restrictions intended to optimize PDFs for archiving and accessibility. Tagging@@ -7783,6 +7880,25 @@ including the colorspace of embedded images. Pandoc cannot check this, and external programs must be used to ensure that generated PDFs are in compliance.++## LaTeX++Set the `pdfstandard` variable to produce tagged PDFs conforming+to PDF/A, PDF/X, or PDF/UA standards. For example:++ pandoc -V pdfstandard=ua-2 --pdf-engine=lualatex doc.md -o doc.pdf++Multiple standards can be combined:++ ---+ pdfstandard:+ - ua-2+ - a-4f+ ---++The required PDF version is inferred automatically. This feature+requires LuaLaTeX in TeX Live 2025 with LaTeX kernel 2025-06-01+or newer. ## ConTeXt
README.md view
@@ -88,7 +88,7 @@ - `native` (native Haskell) - `odt` ([OpenDocument text document](https://en.wikipedia.org/wiki/OpenDocument))-- `opml` ([OPML](http://dev.opml.org/spec2.html))+- `opml` ([OPML](https://opml.org/spec2.opml)) - `org` ([Emacs Org mode](https://orgmode.org)) - `pod` (Perl’s [Plain Old Documentation](https://perldoc.perl.org/perlpod))@@ -135,7 +135,7 @@ - `bbcode_phpbb` [BBCode (phpBB)](https://www.phpbb.com/community/help/bbcode) - `bbcode_steam` [BBCode- (Hubzilla)](https://hubzilla.org/help/member/bbcode)+ (Steam)](https://steamcommunity.com/comment/ForumTopic/formattinghelp) - `bbcode_hubzilla` [BBCode (Hubzilla)](https://hubzilla.org/help/member/bbcode) - `bbcode_xenforo` [BBCode@@ -174,7 +174,7 @@ markup](https://www.w3.org/TR/html-polyglot/)) - `html4` ([XHTML](https://www.w3.org/TR/xhtml1/) 1.0 Transitional) - `icml` ([InDesign- ICML](https://manualzz.com/doc/9627253/adobe-indesign-cs6-idml-cookbook))+ ICML](https://web.archive.org/web/20211006210211/https://wwwimages.adobe.com/www.adobe.com/content/dam/acom/en/devnet/indesign/sdk/cs6/idml/idml-cookbook.pdf)) - `ipynb` ([Jupyter notebook](https://nbformat.readthedocs.io/en/latest/)) - `jats_archiving` ([JATS](https://jats.nlm.nih.gov) XML, Archiving and@@ -206,7 +206,7 @@ - `native` (native Haskell) - `odt` ([OpenDocument text document](https://en.wikipedia.org/wiki/OpenDocument))-- `opml` ([OPML](http://dev.opml.org/spec2.html))+- `opml` ([OPML](https://opml.org/spec2.opml)) - `opendocument` ([OpenDocument XML](https://www.oasis-open.org/2021/06/16/opendocument-v1-3-oasis-standard-published/)) - `org` ([Emacs Org mode](https://orgmode.org))@@ -282,8 +282,9 @@ Guide](https://pandoc.org/MANUAL.html). It is also available [here](MANUAL.txt) as pandoc-flavored Markdown. The website also contains some [examples of the use of-pandoc](https://pandoc.org/demos.html) and a limited [online-demo](https://pandoc.org/try).+pandoc](https://pandoc.org/demos.html), a limited [online+demo](https://pandoc.org/try), and a [WebAssembly-based online+demo](https://pandoc.org/app). ## Contributing
changelog.md view
@@ -1,5 +1,798 @@ # Revision history for pandoc +## pandoc 3.10 (2026-06-03)++ * Add `--typst-input` CLI option (#11588). This allows one to+ pass parameters to typst, which are available at `sys.inputs`,+ just as `typst` itself does with its `--input` option.++ * Avoid trailing spaces in `--help` output (#11623).++ * Make groff the default pdf-engine for `ms` output (#11558).+ Formerly it was pdfroff.++ * Set default User-Agent request header to `pandoc/VERSION`.+ This can be overridden using the `--request-header` option.++ * Markdown reader:++ + Allow grid tables to be indented (#11671, Johan Larsson). Like+ the other table syntaxes (pipe, simple, and multiline tables)+ and block-level constructs generally, a grid table may now be+ indented by up to three spaces and still be recognized as a+ table. Previously the grid-table parser required the table to+ begin at the left margin, so an indented grid table was parsed+ as a paragraph.+ + Fix calculation of column widths for default columns in grid tables+ (#11664). This fixes a bug which produced too-narrow columns in some+ cases.+ + Don't produce empty Raw element with `--strip-comments` (#11625).+ + Fix quotes in inline notes (#11613, Andrew Dunning).+ + Allow spaces inside attributes in super/sub (#11589).+ + Simplify `checkNotes`, remove dead code+ + Various small performance optimizations.++ * HTML reader:++ + Parse aside as a Div with class "aside" (instead of using+ raw HTML) (#11626).+ + Add "header" class to Divs created from headers.++ * Docx reader:++ + Fix bug in bitmask checking (#8299). This led to some table rows+ being wrongly considered header rows.+ + Improve treatment of `tblHeader` element (#8299).+ If `tblHeader` exists but has `w:val="0"`, then don't consider+ the element a header.+ + With `citations` extension, prefer `citation-key` as the key for+ item data, if it is defined (#11581; cf. #10366, #11567). The `id` key+ used by Zotero is not exposed by their API and is generally not what+ is wanted when converting to biblatex.+ + Don't look to `ext` tags for image extent (#11580).+ This reverts a change from 7ff1b798c4e6681ef9050899442d80883116573a.+ The change was mistaken and could cause images to be parsed with+ the wrong sizes.++ * Man reader:++ + Support `auto_identifiers`, `gfm_auto_identifiers`, and+ `ascii_identifiers` extensions (#8852, Meher Chaitanya).+ Section headings parsed from .SH and .SS macros now receive+ auto-generated id attributes when the extension is enabled (as+ it is by default). This enables `--toc` to produce working anchor links.+ + Better handling of `.TP` macro (#11668). We parse these as+ DefinitionList items, but we previously sometimes stopped prematurely+ in including material in the definition. We should include everything+ until we hit a new indentation-changing macro.++ * Roff reader:++ + Handle `\` line continuation in table cells (#11635).++ * LaTeX reader:++ + Evaluate theorem name when used rather than evaluating it when+ the `\newtheorem` command is encountered (#11608). It may include+ macros only defined later.+ + Put identifier from label on table attributes rather than adding+ an enclosing Div (#11604).++ * Typst reader:++ + Fix issue parsing figure inside rotate or box (#11598).+ + Implement "rotate" as pass-through (#11531). Information about the+ angle is encoded in an attribute of an enclosing span or div.++ * RTF reader:++ + Fix tables parsed as deeply nested tables (#11682).++ * Docx writer:++ + Fix display of paragraph with just inline math (#11674).+ Word displays a paragraph containing just one inline math+ element as if it were display math. We don't want that,+ so we add a zero-width space to defeat this behavior.+ + Fix FirstParagraph style lost after heading with footnote (#11573).+ + Fix empty keywords in core document properties (#11666, Sai Asish Y).++ * OpenDocument/ODT writer:++ + Use predefined styles (#9316, #5086, #2747, #3426, #7336).+ Previously the OpenDocument writer emitted a fresh automatic+ style (L1..Ln, P1..Pn, T1..Tn) for nearly every list, list-item+ paragraph, block quote, preformatted block, and inline text+ style. This commit teaches the writer to reference the+ predefined styles that LibreOffice ships and that pandoc's+ reference.odt now exports:++ - Bullet lists use `List_20_1`; ordered lists with default start and+ decimal format use `Numbering_20_1`. Non-default ordered lists+ generate a single named override style (`Pandoc_Numbering_N`)+ memoised by (ListNumberStyle, ListNumberDelim); a non-default start+ value with the default format is expressed via `text:start-value`+ on the `text:list` element instead of a new style.+ - List-item paragraphs use `List_20_Bullet[_Tight]` and+ `List_20_Number[_Tight]`. The Tight variants are pandoc-specific+ (zero top/bottom margin) and are injected into the user's+ reference.odt if missing, just like the Skylighting token styles.+ - Block quotes use the predefined `Quotations` paragraph style+ directly. Nested block quotes use a single automatic style that+ inherits from Quotations and only adds extra margin-left, so a list+ inside a block quote now inherits its container's indent (#2747).+ - Preformatted blocks use `Preformatted_20_Text` directly.+ - Emphasis, Strong, Strikeout, Subscript, Superscript and Code spans+ use the predefined `Emphasis`, `Strong_20_Emphasis`, `Strikeout`,+ `Subscript`, `Superscript` and `Source_20_Text` text styles.+ - `paraStyle`/`paraStyleFromParent` no longer emit a wrapper automatic+ style when its only attribute would be `parent-style-name`; the+ parent name is returned directly.++ * EPUB writer:++ + Support multiple EPUB versions for raw content (#11628,+ nibras shami). This change ensures that raw content marked `epub2`+ will appear in (only) EPUBv2 output and content marked `epub3` will+ appear in (only) EPUBv3 output.++ * Typst writer:++ + Add zero-width space before a Span label if otherwise the label+ doesn't come after anything (#11568). (In this case typst will+ raise an error.)+ + Add newline after `#set text` directive (#11583). This ensures that+ blocks such as lists are parsed correctly after a `set text`.++ * LaTeX writer:++ + Fix `fr-CA` babel language mapping (#11575, Christophe+ Dervieux). Map fr-CA to `french` instead of deprecated `canadien`.+ The babel-french package's `canadien.ldf` is deprecated and+ broken: it never calls `\ldf@finish`, so `\bbl@main@language` is+ left undefined, causing babel to crash at `\begin{document}`.+ Since `canadien` was always just an unconditional alias for+ `french`, use `french` directly.++ * MediaWiki writer:++ + Handle some technically malformed URLs (#11562).+ + Fix escaping to avoid accidental lists (#11563).++ * Markdown writer:++ + Fix spacing issues with definition lists.+ - Properly handle the case where the first item is an indented+ code block (#11542).+ - Use correct indentation when `four_space_rule` extension is+ disabled.+ + Escape `:::` to avoid triggering unintended divs (#11571).++ * Man writer:++ + Don't run together successive definitions in a tight definition list+ with multiple definitions after a term (#11547).++ * Text.Pandoc.Writers.Shared:++ + `htmlAttrs`: use `data-` prefix when needed (#11680). This now+ behaves like the HTML writer, adding the `data-` prefix for+ custom attributes. This will affect, e.g., the mediawiki writer.++ * Text.Pandoc.Error:++ + Display IOError without stack trace (#11676).+ + Use single quotes around paths and format names (#11645) in+ displayed messages.++ * Text.Pandoc.App.Opt:++ + Opt has a new field `optTypstInputs` [API change].++ * Text.Pandoc.Options:++ + Change `defaultMathJaxURL` to use MathJax v4 (#11669).+ + ReaderOptions has a new field `readerTypstInputs` [API change].++ * Text.Pandoc.Citeproc.BibTeX:++ + Prevent wrong combination of `subtitle` and `titleaddon` with+ `maintitle` (#11677, Amir Dekel). When `maintitle` is present, `subtitle`+ should not be added to `title`, but only to `volume-title`.+ + BibLaTeX `inbook` should be CSL `book`, not `chapter` (#11552).+ + Allow `doi` field in bibtex (input and output) (#11617, Thomas Hodson).++ * Text.Pandoc.Translations:++ + Find lang-script type translations (#11648).+ E.g. for `zh-Hant-TW` look for (in order) `zh-Hant-TW.yaml`,+ `zh-Hant.yaml`, `zh.yaml`.++ * Text.Pandoc.Parsing:++ + Various small optimizations.+ + Fix bug in `extractIdClass` to ensure that both `id` and+ `class` are stripped from key/value attributes..++ * Text.Pandoc.Shared:++ + Various small optimizations.++ * ODT reference doc: demonstrate predefined styles (310327).+ This mirrors the demonstration content already present in+ the Word reference doc.++ * HTML templates:++ + Include pandoc-version in generator meta tag (#11624).+ + Styles: make screen-only CSS conditional (#11524, Keenan Brock).++ * EPUB templates:++ + Add dir attribute to html element (#11554).++ * LaTeX template: Define `\xmpquote` if not defined (#11528).+ `\xmpquote` is defined by the hyperref driver hyperxmp; we need a+ fallback for those who aren't using that.++ * Lua subsystem:++ + Add constructor `pandoc.TableBody`.++ * doc/lua-filters.md: Re-indent definition list items+ (Albert Krewinkel).++ * wasm/index.js: include filter to embed images for pdf-via-typst.+ Auto-inject `embed_images` filter for PDF via Typst. Otherwise+ conversion fails because we can't write the images in a temporary+ directory in the WASM sandbox. See jgm/pandoc#11584.++ * Fix test suite parallel execution failures (#11566).++ * linux/make_artifacts.sh: add `loong64` support (#11597,+ Olivier Benz).++ * `bash_completion.tpl`: add `groff` to `--pdf-engine` completions (#11555).++ * MANUAL.txt:++ + Improve description of reference links (#11643).+ + Update instructions for modifying reference.docx+ (#11600, Dan Jacobson). Mention LibreOffice as an alternative.+ + Clarify indentation rules for definition lists (#11542).+ + Move `--sandbox` to general options.+ + Reword restrictions on YAML metadata in commonmark (#11561).++ * Bump upper bound for time, tls, aeson.++ * Use latest releases of doclayout, asciidoc, texmath, typst,+ typst-symbols, pandoc-types, citeproc, commonmark, commonmark-pandoc,+ commonmark-extensions.++ * Add missing NAME heading to pandoc-lua, pandoc-server man pages (#11634).++## pandoc 3.9.0.2 (2026-03-19)++ * Typst template: fix regression introduced in 3.9.0.1 (#11538).++## pandoc 3.9.0.1 (2026-03-17)++ * WASM GUI:++ + Don't block everything while pandoc.wasm loads.+ + Fix bug with Unicode filenames (#11447).+ + Catch errors loading pandoc.++ * Docx reader:++ + Recognize media inside textboxes (#11053, Raymond Berger).+ + Properly handle media stored with packaged-rooted paths+ such as `/media` (#11518). This can be produced by the online version of Word.+ With this change, media stored at an absolute path will be stored+ with its original name and not given a SHA1-based name.+ + Preserve non-textbox content when unwrapping textboxes (#11510, #6893,+ #11412, #5394, #9633). Treat text inside a textbox containing an image+ as a figure caption.+ + Support `w:gridBefore` table row property (#11464, Jan Tojnar).++ * Typst reader:++ + Handle bibliography command (#11460). If this is present, a+ bibliography section is added to the document and the bibliography+ paths are added to `bibliography` in the metadata. This sets things+ up for using `--citeproc`.++ * Textile reader:++ + Handle block content in cells (#11455).++ * LaTeX reader:++ + Support `\footnotemark` and `\footnotetext` (#11450).+ These commands allow separating the footnote mark from its content, useful+ in tables, minipages, and other contexts where \footnote cannot be used+ directly.+ + Support supertabular environment (#11523, bodigrim).++ * ODT Reader:++ + Fix relative linked images (#11369, Tuong Nguyen Manh).+ + Recognize `Preformatted_20_Text` style Jan Tojnar+ This is used by LibreOffice, and we will switch to that as well.+ + Add block smushing logic (Jan Tojnar).+ + Support Preformatted Text style (#4841, Jan Tojnar).++ * Markdown reader:++ + Fix bug with `lists_without_preceding_blankline` (#11534).++ * Typst writer:++ + Don't add a carriage return after `\` for hard break (#11446).+ They are not necessary. Note that they can still be included+ if you use `--wrap=preserve` and add a newline in your source document.+ + Improve handling of data: URIs in images. Instead of using an+ SVG with a link containing the data URI (the solution of #10460),+ we can now simply produce a `bytes` object with the requisite bytes.+ Typst figures out the format automatically.+ + Fix escaping of quotes (#11463).+ + Include alt attributes on images (mcanouil).+ + Properly escape `.` after bracketed argument (#11511).++ * Docx writer:++ + Don't depend on `extractTarget` from Docx reader.+ + Fix section breaks with `--top-level-division` (#11482, #10578).++ * EPUB writer:++ + Add cover metadata for EPUB3 (#11479). This allows+ file managers to show cover thumbnails for EPUB3 files as well.+ + Update allowed values for EPUB3 metadata `identifier.scheme` (#11481,+ Pascal Wagler).++ * ODT writer:++ + Rename inline source class to match LibreOffice (#3390, Jan Tojnar).+ Rename the text style we use to represent `Code` inlines from+ `Source_20_Text` to `Source_Text`. This is the same name LibreOffice+ Writer uses so it will be recognized by the Character Styles section+ of the Styles menu.+ + Remove font size from inline source class (Jan Tojnar). This matches+ what LibreOffice Writer is doing. Also fixes literals inside+ headings being too small.+ + Modernize `Preformatted Text` & `Source Text` styles (Jan Tojnar).+ Presumably, `font-family-generic` and `font-pitch` will allow to find a+ replacement on systems that do not have `Courier New`.++ * Markdown writer:++ + Fix rendering of alerts (#11479). We only properly handled the case+ where the alert started with a paragraph, but it can start with a list+ or other block type.+ + Escape literal `&` that would trigger entity (#11490).++ * HTML writer:++ + For revealjs, default `scrollProgress` to `auto` (Christophe Dervieux).++ * PPTX writer:++ + Register content type for embedded fonts (#11492).++ * MediaWiki writer:++ + Use appropriate syntax for external images (#11494).+ Note that they will only be rendered as images if an option+ `$wgAllowExternalImages` is enabled in the MediaWiki instance.++ * ICML writer:++ + Support for image object styles (#11498, massifrg).+ This change allows users to style images in InDesign bysetting the+ `object-style` attribute in a pandoc Image, which is mapped to the+ AppliedObjectStyle attribute in the Rectangle element around an Image+ element in the resulting ICML.++ * JATS writer:++ + Improve representation of Divs (Albert Krewinkel). The writer now+ checks if the element used to represent (non-special) Divs has any+ `<boxed-text>` specific attributes. If it does, the writer keeps+ wrapping the Div contents in a `<boxed-text>`, as it did before.+ Otherwise, the writer falls back to the more appropriate `<p>` element+ or simply unwraps the Div if the wrapping element wouldn't have any+ attributes. The new behavior gives better semantic results in most cases,+ as `<boxed-text>` should be used for text that "is outside the flow of the+ narrative text", which doesn't apply to most divs.+ "Special" divs, like those used to mark sections, are not+ affected by this change.++ * Text.Pandoc.Writers.GridTable:++ + Normalize tables (#8102). Previously, if an invalid table was passed to+ `toTable`, an array index error could be raised. Normalizing the table+ forces it into a shape that won't allow this error.++ * Lua subsystem (Albert Krewinkel):++ + Add new function `pandoc.types.Sources` (#11441).++ * LaTeX template: properly handle keywords with commas.+ These need to be put in an `\xmpquote{..}` command. Closes #11528.++ * HTML styles template: avoid duplicate code selector.+ Consolidate two clauses. Closes #11484.++ * Revealjs template: fix type rendering of scroll-view options+ (Christophe Dervieux, #11486).++ * Typst template:++ + Use both place and block for title (Gordon Woodhull).+ Otherwise the title will be confined to the left column+ + Put title block in a conditional (#11529). This avoids an+ empty block for documents that lack metadata information.+ The empty block causes problems if `#set page` is used, as+ it will cause a page break.++ * Beamer template: add `logooption` variable (#11452, Sidney Mau).++ * Text.Pandoc.ImageSize:++ + Correctly handle percentage width, height on SVG (#11530).+ Previously we were getting image size of 0 when a percentage+ was specified for width or height on SVG. With this change,+ we simply ignore these percentages (becaues ImageSize doesn't+ know the size of the containing element).++ * Re-add `-threaded` to compile options in pandoc-cli.++ * Use released djot, asciidoc, texmath, typst.++ * Allow crypton 1.1, tls 2.2, http-client-tls 0.4.++ * Require auto-update >= 0.2.6 to fix server on macOS (#11488).++ * pandoc-cli.cabal: bump base min bound to 4.18 (same as pandoc).++ * MANUAL.txt:++ + Note that JSON may be used in YAML metadata blocks (#11525).+ + Update link for ICML in manual.+ + Fix outdated OPML spec URL in MANUAL.txt (#11504, Peter Briggs).++## pandoc 3.9 (2026-02-03)++ * Add support for compiling pandoc to WASM. (To build, `make+ pandoc.wasm`.) A stanza in `cabal.project` contains the+ necessary build modifications. We owe this almost entirely to+ TerrorJack, who created the original proof of context and+ came up with the necessary build flags and patches to some+ dependencies.++ `pandoc.wasm` has almost all the power of regular pandoc. The+ main limitations is that it operates in a WASM sandbox and thus+ cannot use HTTP to fetch resources and cannot run system commands.+ As a result, JSON filters cannot be used, `--embed-resources`+ works only with resources that have been explicitly provided in+ the WASM sandbox, and PDFs cannot be produced (since that requires+ running external commands). However, Lua filters can be used,+ as long as they do not run system commands.++ A JavaScript bridge module, `wasm/pandoc.js`, is provided; this+ handles the setup necessary to run `pandoc.wasm` in a browser.++ In addition, a full-featured GUI interface is provided in the+ `wasm` subdirectory. `make serve` from that directory and it+ will run locally, or visit <https://pandoc.org/app>. Note that+ once the relevant code has been downloaded by the browser, it runs+ entirely in the browser, and the conversions never touch a server.+ The GUI was developed in interaction with Claude Code. This app+ includes a WASM version of Typst and can produce PDF output via+ Typst.++ * Defaults files may now be either JSON or YAML (though a `.yaml`+ extension will still be assumed if the file has no extension).+ The structure of a JSON defaults file is isomorphic to that of+ a YAML defaults file.++ * Variable expansion now works even for the `defaults` field of+ defaults files (#8024, Jacob Larkin).++ * `--extract-media` will now create a zip archive containing the media+ (instead of a directory) if the path provided has a `.zip` extension.++ * Processing with `--citeproc` is now affected by a+ `reset-citation-positions` class on headings. When the+ `reset-citation-positions` class is added to a top-level+ heading, `--citeproc` will reset position information at that+ point in the document. This is needed in order to ensure that+ the first citation in a chapter to a work that has been cited+ in a previous chapter will not be in abbreviated form.++ * RST reader:++ + Fix definition lists where term ends with `-` (#11323).+ This reverts some old code giving special treatment to+ lines ending in hyphens; I don't understand why it was+ there, because rst2html does not seem to do this.++ * HTML reader:++ + Revert an earlier change that caused style tags in the body+ to be ignored (#10643, #11246).+ + Parse inline style elements as RawInline (#10643, #11246).++ * Markdown reader:++ + Fix parsing of inline math (`$...$`) (#11311, benniekiss).+ Do not allow blank lines before closing `$` delimiter. This brings the+ parser in line with the documentation.+ + Allow superscripted spans (#11409). These were being parsed as inline+ notes. Now we disallow an inline note followed by+ attributes, as this is almost certainly meant to be a span.+ + Support `alerts` extension for pandoc markdown (#9716). It is not+ enabled by default.++ * MediaWiki reader:++ + Add behavior switches support (#11354, Anton Melnikov).+ They add a field to metadata without producing any text.+ + Handle non-recognized tags as plain text (#11299).+ + Better handling of inline tags (#11299). `<mark>`, `<var>`,+ `<samp>`, and `<kbd>` now produce Code or Span elements with+ classes, which can be handled by multiple output formats,+ instead of simply being parsed as raw HTML tags.++ * RTF reader:++ + Ensure a new paragraph on `\pard` (#11361, Tuong Nguyen Manh). New+ paragraphs may start with `\pard` alone without an explicit paragraph+ break with `\par` preceding it.+ + Improve hyperlink parsing more (#10942, Tuong Nguyen Manh).+ Both the field instruction and its result may be ungrouped.+ + Fix bug where list items were incorporated into a following table+ (#11364).++ * ODT reader:++ + Add table row and column spans (#11366, Tuong Nguyen Manh).+ Parse the number-rows-spanned and number-columns-spanned attributes to+ create Cells for the Table.++ * DocBook reader:++ + Support "role" attribute (#11255, Yann Trividic). The `role`+ attribute is parsed and added to Pandoc AST elements, using a+ wrapper Div if needed.+ + Omit empty title when not required (#11422).+ This affects example and sidebar elements.+ + Fix adding wrong metadata (#11300, Tuong Nguyen Manh). Now+ keep track of the current element stack to only add metadata+ if inside an appropriate parent element.++ * DocBook/JATS reader:++ + Don't export surrounding space from inline elements (#11398). Previously+ we would export leading and trailing space inside elements like+ emphasis or ulink so they appeared outside the resulting pandoc Inline+ (Emph or Link). This is not really motivated; DocBook and XML in general+ treats leading and trailing whitespace in this context as significant.++ * Docx reader:++ + Handle tables without `tblGrid` (#11380).+ + Look inside v:rect as well as v:shape (#11412).++ * LaTeX reader:++ + Handle more quote macros from fontspec and ngerman babel (#6120).++ * Org reader:++ + Don't include 'example' class when parsing org example blocks (#11339).+ These are just unmarked code blocks.++ * Texinfo writer:++ + Improve handling of certain code blocks (#11312).+ MediaWiki, for example, will parse a code block containing+ formatting as a sequence of Code elements separated by+ LineBreaks. For this we now use a texinfo example block.++ * Typst writer:++ + Escape hyphens when needed (#11334).++ * HTML writer:++ + Include all classes on highlighted code elements (#11423). Previously,+ only the language class was included, and the others were dropped.+ + Slide formats: Make `. . .` pause work in nested blocks (#7201, #7582).+ + For revealjs, add idiomatic highlight.js support (#11420, Claude Opus 4.5).+ When using `--syntax-highlighting=idiomatic` with reveal.js output, pandoc+ now generates HTML compatible with reveal.js's built-in highlight.js plugin:+ Code blocks use `<pre><code class="language-X">` format.+ The template loads highlight.js CSS, JS, and RevealHighlight plugin.++ * Markdown writer:++ + Ensure that `\ ` line breaks are used for commonmark.+ + Use setext for headers containing line breaks for commonmark (#11341).+ + Allow display math to start/end with space (#11384).+ This reverts to earlier < 3.7 behavior.+ + Properly handle tables with footers (#11416).++ * JATS writer:++ + Fix XML output for nested figures (#11362, Albert Krewinkel).+ Subfigures are now wrapped inside a `<fig-group>` element. Furthermore,+ figure content that isn't allowed as children of `<fig>` elements, such as+ raw text, gets wrapped in `<p>` elements to ensure schema-conforming XML.++ * AsciiDoc writer:++ + Use doubled delims in more contexts (#11362). Also escape the `#` character.+ + Use a span with role for SmallCaps (#11374).+ + Export spaces inside delimited constructs like emph.++ * Docx writer:++ + Skip directory entries when building media overrides (#11379, You Jiangbin).+ Pandoc's docx writer was previously adding an `<Override>` for+ `/word/media/` in `[Content_Types].xml` when the reference doc contains+ media, which violates OPC rules and causes Word to report corruption.+ + Refactor the monolithic `writeDocx` into a number of smaller functions+ (Claude Opus 4.5).+ + Replace generic XML traversal with direct path navigation (Claude+ Opus 4.5). Instead of using Data.Generics `everywhere` to traverse the+ entire XML tree when setting language attributes, navigate directly to+ the known path `w:docDefaults/w:rPr/w:lang`. This is more efficient and+ removes the dependency on `Data.Generics`.++ * EPUB writer:++ + Don't use footnote backlinks for EPUBv3. Here we use aside elements,+ which are popups, and the backlinks are not needed; in some readers+ they cause a redundant number to appear, since the reader adds a note number.++ * MediaWiki writer:++ + Use Doc Text instead of Text for document construction (with Claude Open 4.5).+ This refactors the writer to use Text.DocLayout combinators (vcat, hcat,+ literal, blankline, cr, chomp) for building output, following the pattern+ used by other text format writers (RST, Markdown, Man). This enables+ better control over line spacing and paragraph separation.+ + Improve blank space around div elements (#11417). This is merely cosmetic.++ * PPTX writer:++ + Support notes field in metadata for title slide (#5844, Chris Callison-Burch).+ This adds support for a `notes` field in the YAML metadata block that will+ be used as speaker notes for the title slide in PowerPoint output.+ Previously, there was no way to add speaker notes to the title slide since+ it is generated from metadata rather than from content blocks.++ * LaTeX writer:++ + Add PDF standard support via DocumentMetadata (#11407, Gordon Woodhull+ with Claude Opus 4.5). The `pdfstandard` variable can be+ used to specify PDF standards (PDF/A, PDF/X, PDF/UA) in+ LaTeX output. This uses LaTeX's `\DocumentMetadata`+ command, which requires LuaLaTeX. PDF version requirements+ are automatically inferred, but can be explicitly overridden.+ Automatic tagging is added for standards that require it.++ * Typst template:++ + Fix keywords usage. (#11317, har7an).+ + Disable hyphenation for title, subtitle (#11375).+ + Improve accessibility of definition lists (#11436). Before this+ change, our show rule produced an error when typst was run with+ `--pdf-standard=ua1`.++ * HTML5 template:++ + Conditionally include lang attribute, instead of providing+ it with an empty value.++ * JATS template:++ + Fix author prefix placeholder (#11381, Christophe Dervieux).++ * Text.Pandoc.Citeproc:++ + Fix biblatex parsing of `@commentary` entries (#11322).+ + Fix typo affecting `jurisdiction` biblatex type (#11321).+ + Avoid adding an extra space at the beginning of a Cite.++ * Text.Pandoc.Shared:++ + Export `hasLineBreaks` [API change]. This was formerly+ defined in the DocBook writer but more generally useful.++ * Text.Pandoc.PDF:++ + Add `SOURCE_DATE_EPOCH` to verbose environment variable info.++ * Text.Pandoc.Class:++ + Factor out `openURL` into Text.Pandoc.Class.IO.HTTP (unexported module).++ * Lua subsystem (Albert Krewinkel):++ + Mark readers and writers with their types (#11367). The+ `pandoc.readers` and `pandoc.writers` maps now have string values+ instead of boolean values. The string signals the type of the+ reader/writer, `"text"` for TextReader/TextWriter and `"bytestring"`+ for ByteStringReader/ByteStringWriter.+ + Support equallity checks of LogMessage objects.+ + Add function `pandoc.with_state` (#10859). The function allows+ to run a callback with a modified pandoc state. This provides+ the ability to temporarily modify the resource path, the user+ data directory, and the HTTP request headers.+ + Let `pandoc.with_state` error on unknown options (#11376).+ + Add function `pandoc.utils.documentation` (#10999).+ This is now used to generate much of the Lua API documentation.++ * Text.Pandoc.App:++ + Remove redundant check for asciidoc in UnknownReader.++ * Text.Pandoc.Logging:++ + Add `pretty` field to ToJSON instance for LogMessage.+ This just reproduces the output of `logMessage`, for convenience for those+ who are using the JSON output outside of Haskell.++ * Text.Pandoc.Error:++ + Change PandocHttpError constructor to take a Text instead of an+ HttpException as the second argument (see #10980) [API change]+ Motivation: exposing HttpException in the public API makes it+ difficult to provide a version of pandoc that can be compiled+ to wasm, which currently can't handle the network libraries.+ + Define `displayException` for PandocError. This is a behavior change,+ not an API change, since there was already a definition that defaulted+ to using Show. The change here is that we use `renderError` for+ a more human-readable version.++ * Drop support for compilation with GHC versions < 9.6.++ * Use released citeproc 0.13, djot 0.1.3, skylighting-format-blaze-html+ 0.1.2 (see #11423), texmath 0.13.1, asciidoc 0.1.0.1, typst-0.9,+ hslua 2.5.++ * Add `-Wno-deriving-typeble` to cabal ghc-options for ghc >= 9.12.++ * Add `http` cabal flag (#10980). This allows pandoc to be+ compiled without support for making HTTP requests, which is+ useful when WASM is the target.++ * pandoc-lua-engine has a new build flag `repl`, allowing support+ for the Lua repl to be disabled for the wasm build.++ * We now sign Windows artifacts with a code signing+ certificate provided by SignPath.++ * Mention Excel in cabal description.++ * Makefile: remove some obsolete targets.++ * MANUAL.txt:++ + Fix typo about `--chunk-template` (#11358, Albert Lei).+ + Fix link for bbcode_steam (#11389).+ + Small rewrite of syntax-highlighting info.+ + Fix defaults.yaml example for `wrap`.++ * Fix a few mistakes in the contributing docs. (#11318, har7an).++ * Fix a couple small errors in `doc/lua-filters.md`,+ `doc/custom-writers.md`, and `doc/custom-readers.md`+ (#11408, #11388).+ ## pandoc 3.8.3 (2025-12-01) * Add `asciidoc` as an input format (#1456).@@ -2856,7 +3649,7 @@ * New module Text.Pandoc.Transforms [API change] (Albert Krewinkel). This module exports the following functions which were formerly- exported from Tetx.Pnadoc.Shared: `headerShift`,+ exported from Text.Pandoc.Shared: `headerShift`, `filterIpynbOutput`, `eastAsianLineBreakFilter`, as well as some functions that were previously not exported.
data/bash_completion.tpl view
@@ -34,7 +34,7 @@ return 0 ;; --pdf-engine)- COMPREPLY=( $(compgen -W "pdflatex lualatex xelatex latexmk tectonic wkhtmltopdf weasyprint prince context pdfroff" -- ${cur}) )+ COMPREPLY=( $(compgen -W "pdflatex lualatex xelatex latexmk tectonic wkhtmltopdf weasyprint prince context pdfroff groff" -- ${cur}) ) return 0 ;; --print-default-data-file)
data/odt/content.xml view
@@ -1,2 +1,82 @@ <?xml version="1.0" encoding="UTF-8"?>-<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.3"><office:scripts/><office:font-face-decls><style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/><style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/><style:font-face style:name="Courier New" svg:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/><style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="Lucida Sans Unicode" svg:font-family="'Lucida Sans Unicode'" style:font-family-generic="system" style:font-pitch="variable"/><style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles><style:style style:name="P1" style:family="paragraph" style:parent-style-name="Footer"><style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/></style:style></office:automatic-styles><office:body><office:text><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls><text:p text:style-name="Standard">Hello World!</text:p></office:text></office:body></office:document-content>+<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.3">+ <office:scripts/>+ <office:font-face-decls>+ <style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/>+ <style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/>+ <style:font-face style:name="Courier New" svg:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/>+ <style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/>+ <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>+ <style:font-face style:name="Lucida Sans Unicode" svg:font-family="'Lucida Sans Unicode'" style:font-family-generic="system" style:font-pitch="variable"/>+ <style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" style:font-pitch="variable"/>+ </office:font-face-decls>+ <office:automatic-styles>+ <style:style style:name="DemoTable" style:family="table">+ <style:table-properties style:width="6in" table:align="margins"/>+ </style:style>+ <style:style style:name="DemoTable.A" style:family="table-column">+ <style:table-column-properties style:column-width="3in"/>+ </style:style>+ </office:automatic-styles>+ <office:body>+ <office:text>+ <text:sequence-decls>+ <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>+ </text:sequence-decls>+ <text:p text:style-name="Title">Title</text:p>+ <text:p text:style-name="Subtitle">Subtitle</text:p>+ <text:p text:style-name="Author">Author</text:p>+ <text:p text:style-name="Date">Date</text:p>+ <text:p text:style-name="Abstract">Abstract.</text:p>+ <text:h text:style-name="Heading_20_1" text:outline-level="1">Heading 1</text:h>+ <text:h text:style-name="Heading_20_2" text:outline-level="2">Heading 2</text:h>+ <text:h text:style-name="Heading_20_3" text:outline-level="3">Heading 3</text:h>+ <text:h text:style-name="Heading_20_4" text:outline-level="4">Heading 4</text:h>+ <text:h text:style-name="Heading_20_5" text:outline-level="5">Heading 5</text:h>+ <text:h text:style-name="Heading_20_6" text:outline-level="6">Heading 6</text:h>+ <text:p text:style-name="First_20_paragraph">First Paragraph.</text:p>+ <text:p text:style-name="Text_20_body">Body Text. <text:span text:style-name="Emphasis">Emphasis</text:span>. <text:span text:style-name="Strong_20_Emphasis">Strong Emphasis</text:span>. <text:span text:style-name="Strikeout">Strikeout</text:span>. <text:span text:style-name="Superscript">Superscript</text:span>. <text:span text:style-name="Subscript">Subscript</text:span>. <text:span text:style-name="Source_20_Text">Source Text</text:span>. <text:span text:style-name="Highlighted">Highlighted</text:span>. <text:a xlink:type="simple" xlink:href="https://pandoc.org"><text:span text:style-name="Definition">Hyperlink</text:span></text:a>. Footnote.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote">Footnote text.</text:p></text:note-body></text:note></text:p>+ <text:p text:style-name="Quotations">Block quote.</text:p>+ <text:p text:style-name="Preformatted_20_Text">Preformatted Text.</text:p>+ <text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Bullet list item.</text:p>+ </text:list-item>+ </text:list>+ <text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number">Numbered list item.</text:p>+ </text:list-item>+ </text:list>+ <text:p text:style-name="TableCaption">Table caption.</text:p>+ <table:table table:name="DemoTable" table:style-name="DemoTable">+ <table:table-column table:style-name="DemoTable.A"/>+ <table:table-column table:style-name="DemoTable.A"/>+ <table:table-header-rows>+ <table:table-row>+ <table:table-cell office:value-type="string">+ <text:p text:style-name="Table_20_Heading">Table Heading</text:p>+ </table:table-cell>+ <table:table-cell office:value-type="string">+ <text:p text:style-name="Table_20_Heading">Table Heading</text:p>+ </table:table-cell>+ </table:table-row>+ </table:table-header-rows>+ <table:table-row>+ <table:table-cell office:value-type="string">+ <text:p text:style-name="Table_20_Contents">Table Contents</text:p>+ </table:table-cell>+ <table:table-cell office:value-type="string">+ <text:p text:style-name="Table_20_Contents">Table Contents</text:p>+ </table:table-cell>+ </table:table-row>+ </table:table>+ <text:p text:style-name="FigureCaption">Image caption.</text:p>+ <text:p text:style-name="Definition_20_Term">Definition Term</text:p>+ <text:p text:style-name="Definition_20_Definition">Definition.</text:p>+ </office:text>+ </office:body>+</office:document-content>
data/odt/styles.xml view
@@ -73,6 +73,26 @@ style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" /> </style:default-style>+ <style:style style:name="Title" style:family="paragraph"+ style:parent-style-name="Heading" style:next-style-name="Subtitle"+ style:class="chapter">+ <style:paragraph-properties fo:text-align="center"+ style:justify-single-word="false" fo:margin-top="0in"+ fo:margin-bottom="0.0835in" style:contextual-spacing="false" />+ <style:text-properties fo:font-size="28pt" fo:font-weight="bold"+ style:font-size-asian="28pt" style:font-weight-asian="bold"+ style:font-size-complex="28pt" style:font-weight-complex="bold" />+ </style:style>+ <style:style style:name="Subtitle" style:family="paragraph"+ style:parent-style-name="Heading" style:next-style-name="Text_20_body"+ style:class="chapter">+ <style:paragraph-properties fo:text-align="center"+ style:justify-single-word="false" fo:margin-top="0.0835in"+ fo:margin-bottom="0.0835in" style:contextual-spacing="false" />+ <style:text-properties fo:font-size="18pt" fo:font-style="italic"+ style:font-size-asian="18pt" style:font-style-asian="italic"+ style:font-size-complex="18pt" style:font-style-complex="italic" />+ </style:style> <style:style style:name="Author" style:family="paragraph" style:parent-style-name="Standard" style:class="html"> <style:paragraph-properties fo:text-align="center" />@@ -136,6 +156,24 @@ style:parent-style-name="Text_20_body" style:class="list"> <style:text-properties style:font-name-complex="Tahoma1" /> </style:style>+ <style:style style:name="List_20_Bullet"+ style:display-name="List Bullet" style:family="paragraph"+ style:parent-style-name="List" style:class="list" />+ <style:style style:name="List_20_Bullet_20_Tight"+ style:display-name="List Bullet Tight" style:family="paragraph"+ style:parent-style-name="List" style:class="list">+ <style:paragraph-properties fo:margin-top="0in"+ fo:margin-bottom="0in" style:contextual-spacing="false" />+ </style:style>+ <style:style style:name="List_20_Number"+ style:display-name="List Number" style:family="paragraph"+ style:parent-style-name="List" style:class="list" />+ <style:style style:name="List_20_Number_20_Tight"+ style:display-name="List Number Tight" style:family="paragraph"+ style:parent-style-name="List" style:class="list">+ <style:paragraph-properties fo:margin-top="0in"+ fo:margin-bottom="0in" style:contextual-spacing="false" />+ </style:style> <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> <style:paragraph-properties fo:margin-top="0.0835in"@@ -250,18 +288,35 @@ <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" style:contextual-spacing="false" /> <style:text-properties style:font-name="Courier New"- fo:font-size="10pt" style:font-name-asian="Courier New"+ fo:font-family="'Courier New'"+ style:font-family-generic="modern"+ style:font-pitch="fixed"+ fo:font-size="10pt"+ style:font-name-asian="Courier New"+ style:font-family-asian="'Courier New'"+ style:font-family-generic-asian="modern"+ style:font-pitch-asian="fixed" style:font-size-asian="10pt" style:font-name-complex="Courier New"+ style:font-family-complex="'Courier New'"+ style:font-family-generic-complex="modern"+ style:font-pitch-complex="fixed" style:font-size-complex="10pt" fo:language="zxx" /> </style:style>- <style:style style:name="Source_Text" style:family="text">+ <style:style style:name="Source_20_Text" style:display-name="Source Text" style:family="text"> <style:text-properties style:font-name="Courier New"- fo:font-size="10pt" style:font-name-asian="Courier New"- style:font-size-asian="10pt"+ fo:font-family="'Courier New'"+ style:font-family-generic="modern"+ style:font-pitch="fixed"+ style:font-name-asian="Courier New"+ style:font-family-asian="'Courier New'"+ style:font-family-generic-asian="modern"+ style:font-pitch-asian="fixed" style:font-name-complex="Courier New"- style:font-size-complex="10pt"+ style:font-family-complex="'Courier New'"+ style:font-family-generic-complex="modern"+ style:font-pitch-complex="fixed" fo:language="zxx" /> </style:style> <style:style style:name="Highlighted" style:family="text">
data/templates/default.beamer view
@@ -125,7 +125,7 @@ $endfor$} $endif$ $if(logo)$-\logo{\includegraphics{$logo$}}+\logo{\includegraphics$if(logooptions)$[$for(logooptions)$$logooptions$$sep$, $endfor$]$endif${$logo$}} $endif$ \begin{document}
data/templates/default.epub2 view
@@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">-<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$$if(dir)$ dir="$dir$"$endif$> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" />
data/templates/default.epub3 view
@@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html>-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$>+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$$if(dir)$ dir="$dir$"$endif$> <head> <meta charset="utf-8" /> <meta name="generator" content="pandoc" />
data/templates/default.html4 view
@@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" />- <meta name="generator" content="pandoc" />+ <meta name="generator" content="pandoc $pandoc-version$" /> $for(author-meta)$ <meta name="author" content="$author-meta$" /> $endfor$
data/templates/default.html5 view
@@ -1,8 +1,8 @@ <!DOCTYPE html>-<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>+<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$$if(dir)$ dir="$dir$"$endif$> <head> <meta charset="utf-8" />- <meta name="generator" content="pandoc" />+ <meta name="generator" content="pandoc $pandoc-version$" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> $for(author-meta)$ <meta name="author" content="$author-meta$" />
data/templates/default.icml view
@@ -28,6 +28,11 @@ <RootCellStyleGroup Self="pandoc_cell_styles"> <CellStyle Self="CellStyle/Cell" AppliedParagraphStyle="ParagraphStyle/$$ID/[No paragraph style]" Name="Cell" /> </RootCellStyleGroup>+$if(objectStyles)$+ <RootObjectStyleGroup Self="pandoc_object_styles">+ $objectStyles$+ </RootObjectStyleGroup>+$endif$ <Story Self="pandoc_story" TrackChanges="false" StoryTitle="$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$"
data/templates/default.jats_articleauthoring view
@@ -31,7 +31,7 @@ <surname>$if(author.non-dropping-particle)$${author.non-dropping-particle} $endif$${author.surname}</surname> <given-names>${author.given-names}$if(author.dropping-particle)$ ${author.dropping-particle}$endif$</given-names> $if(author.prefix)$-<prefix>${author.suffix}</prefix>+<prefix>${author.prefix}</prefix> $endif$ $if(author.suffix)$ <suffix>${author.suffix}</suffix>
data/templates/default.latex view
@@ -1,3 +1,4 @@+$document-metadata.latex()$ $passoptions.latex()$ \documentclass[ $for(babel-otherlangs)$
data/templates/default.revealjs view
@@ -29,6 +29,9 @@ $else$ <link rel="stylesheet" href="$revealjs-url$/dist/theme/black.css" id="theme"> $endif$+$if(highlight-js)$+ <link rel="stylesheet" href="$revealjs-url$/plugin/highlight/$highlightjs-theme$.css">+$endif$ $for(css)$ <link rel="stylesheet" href="$css$"/> $endfor$@@ -87,6 +90,9 @@ $if(mathjax)$ <script src="$revealjs-url$/plugin/math/math.js"></script> $endif$+$if(highlight-js)$+ <script src="$revealjs-url$/plugin/highlight/highlight.js"></script>+$endif$ <script> @@ -237,13 +243,23 @@ // Enable scroll view view: '$view/nowrap$', // see https://revealjs.com/scroll-view/#scrollbar+$if(scrollProgressAuto)$+ scrollProgress: 'auto',+$elseif(scrollProgress)$ scrollProgress: $scrollProgress$,+$else$+ scrollProgress: false,+$endif$ // see https://revealjs.com/scroll-view/#url-activation- scrollActivationWidth: '$scrollActivationWidth$',+ scrollActivationWidth: $scrollActivationWidth$, // see https://revealjs.com/scroll-view/#scroll-snapping- scrollSnap: '$scrollSnap$',+$if(scrollSnap)$+ scrollSnap: '$scrollSnap/nowrap$',+$else$+ scrollSnap: false,+$endif$ // Experimental. see https://revealjs.com/scroll-view/#scroll-snapping- scrollLayout: '$scrollLayout$',+ scrollLayout: '$scrollLayout/nowrap$', $endif$ $if(parallaxBackgroundImage)$ @@ -320,6 +336,9 @@ plugins: [ $if(mathjax)$ RevealMath,+$endif$+$if(highlight-js)$+ RevealHighlight, $endif$ RevealNotes, RevealSearch,
data/templates/default.typst view
@@ -1,13 +1,9 @@ #let horizontalrule = line(start: (25%,0%), end: (75%,0%)) -#show terms: it => {- it.children- .map(child => [- #strong[#child.term]- #block(inset: (left: 1.5em, top: -0.4em))[#child.description]- ])- .join()-}+#show terms.item: it => block(breakable: false)[+ #text(weight: "bold")[#it.term]+ #block(inset: (left: 1.5em, top: -0.4em))[#it.description]+] #set table( inset: 6pt,@@ -65,7 +61,7 @@ ), $endif$ $if(keywords)$- keywords: ($for(keywords)$$keyword$$sep$,$endfor$),+ keywords: ($for(keywords)$$keywords$$sep$,$endfor$), $endif$ $if(date)$ date: [$date$],
+ data/templates/document-metadata.latex view
@@ -0,0 +1,20 @@+$--+$-- PDF standard support (PDF/A, PDF/UA, PDF/X)+$-- Requires LuaLaTeX and recent LaTeX (2023+)+$--+$if(pdfstandard)$+\DocumentMetadata{+$if(pdfstandard.version)$+ pdfversion=$pdfstandard.version$,+$endif$+$if(pdfstandard.standards)$+ pdfstandard={$for(pdfstandard.standards)$$it$$sep$,$endfor$},+$endif$+$if(pdfstandard.tagging)$+ tagging=on,+$endif$+$if(lang)$+ lang=$lang$,+$endif$+ xmp=true}+$endif$
data/templates/hypersetup.latex view
@@ -1,3 +1,7 @@+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother \hypersetup{ $if(title-meta)$ pdftitle={$title-meta$},@@ -12,7 +16,7 @@ pdfsubject={$subject$}, $endif$ $if(keywords)$- pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$},+ pdfkeywords={$for(keywords)$\xmpquote{$keywords$}$sep$, $endfor$}, $endif$ $if(colorlinks)$ colorlinks=true,
data/templates/styles.html view
@@ -106,6 +106,7 @@ } $endif$ code {+ white-space: pre-wrap; font-family: $if(monofont)$$monofont$$else$Menlo, Monaco, Consolas, 'Lucida Console', monospace$endif$; $if(monobackgroundcolor)$ background-color: $monobackgroundcolor$;@@ -183,10 +184,13 @@ text-decoration: none; } $endif$-code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}-div.columns{display: flex; gap: min(4vw, 1.5em);}-div.column{flex: auto; overflow-x: auto;}+div.columns{display: flex; gap: 1.5em;}+div.column{flex: auto;}+@media screen {+div.columns{gap: min(4vw, 1.5em);}+div.column{overflow-x: auto;}+} div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */
data/templates/template.typst view
@@ -73,47 +73,48 @@ } } - block(below: 1em, width: 100%)[- #if title != none {- align(center, block[- #text(weight: "bold", size: 1.5em)[#title #if thanks != none {- footnote(thanks, numbering: "*")- counter(footnote).update(n => n - 1)- }]- #(- if subtitle != none {- parbreak()- text(weight: "bold", size: 1.25em)[#subtitle]- }- )])- }-- #if authors != none and authors != [] {- let count = authors.len()- let ncols = calc.min(count, 3)- grid(- columns: (1fr,) * ncols,- row-gutter: 1.5em,- ..authors.map(author => align(center)[- #author.name \- #author.affiliation \- #author.email- ])- )- }+ if title != none {+ place(top, float: true, scope: "parent", clearance: 4mm, block(below: 1em, width: 100%)[+ #if title != none {+ align(center, block[+ #text(weight: "bold", size: 1.5em, hyphenate: false)[#title #if thanks != none {+ footnote(thanks, numbering: "*")+ counter(footnote).update(n => n - 1)+ }]+ #(+ if subtitle != none {+ parbreak()+ text(weight: "bold", size: 1.25em, hyphenate: false)[#subtitle]+ }+ )])+ } - #if date != none {- align(center)[#block(inset: 1em)[- #date- ]]- }+ #if authors != none and authors != [] {+ let count = authors.len()+ let ncols = calc.min(count, 3)+ grid(+ columns: (1fr,) * ncols,+ row-gutter: 1.5em,+ ..authors.map(author => align(center)[+ #author.name \+ #author.affiliation \+ #author.email+ ])+ )+ } - #if abstract != none {- block(inset: 2em)[- #text(weight: "semibold")[#abstract-title] #h(1em) #abstract- ]- }- ]+ #if date != none {+ align(center)[#block(inset: 1em)[+ #date+ ]]+ } + #if abstract != none {+ block(inset: 2em)[+ #text(weight: "semibold")[#abstract-title] #h(1em) #abstract+ ]+ }+ ])+ } doc }
pandoc.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: pandoc-version: 3.8.3+version: 3.10 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -11,9 +11,7 @@ stability: alpha homepage: https://pandoc.org category: Text-tested-with: GHC == 8.10.7, GHC == 9.0.2,- GHC == 9.2.5, GHC == 9.4.4, GHC == 9.6.3,- GHC == 9.8.2, GHC == 9.10.1+tested-with: GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.3, GHC == 9.12.2 synopsis: Conversion between markup formats description: Pandoc is a Haskell library for converting from one markup format to another. The formats it can handle include@@ -38,7 +36,7 @@ Vimwiki, XWiki, ZimWiki, Jira wiki, Creole) - Slide show formats (LaTeX Beamer, PowerPoint, Slidy, reveal.js, Slideous, S5, DZSlides)- - Data formats (CSV and TSV tables)+ - Data formats (CSV and TSV tables, Excel spreadsheets) - PDF (via external programs such as pdflatex or wkhtmltopdf) . Pandoc can convert mathematical content in documents@@ -103,6 +101,7 @@ data/templates/affiliations.jats data/templates/default.markua data/templates/default.typst+ data/templates/document-metadata.latex data/templates/template.typst data/templates/common.latex data/templates/hypersetup.latex@@ -208,12 +207,13 @@ citeproc/biblatex-localization/*.lbx.strings -- documentation MANUAL.txt, COPYRIGHT-extra-doc-files:- changelog.md+extra-doc-files: changelog.md,+ AUTHORS.md,+ INSTALL.md,+ README.md,+ CONTRIBUTING.md,+ BUGS extra-source-files:- -- documentation- INSTALL.md, AUTHORS.md, README.md,- CONTRIBUTING.md, BUGS, -- tests test/bodybg.gif test/*.native@@ -250,6 +250,8 @@ test/command/defaults7.yaml test/command/defaults8.yaml test/command/defaults9.yaml+ test/command/8024a.yaml+ test/command/8024b.yaml test/command/3533-rst-csv-tables.csv test/command/3880.txt test/command/5182.txt@@ -275,6 +277,8 @@ test/command/6466-whole.hs test/command/7861.yaml test/command/7861/metadata/placeholder+ test/command/11486/scroll.revealjs+ test/command/11498.png test/asciidoc-reader.adoc test/asciidoc-reader.native test/asciidoc-reader-include.rb@@ -457,9 +461,13 @@ Description: Embed data files in binary for relocatable executable. Default: False +flag http+ Description: Support for fetching resources using HTTP.+ Default: True+ common common-options default-language: Haskell2010- build-depends: base >= 4.12 && < 5+ build-depends: base >= 4.18 && < 5 ghc-options: -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances@@ -470,12 +478,11 @@ -Wmissing-signatures -fhide-source-paths -Wmissing-export-lists-- if impl(ghc >= 8.10)- ghc-options: -Wunused-packages+ -Wunused-packages+ -Winvalid-haddock - if impl(ghc >= 9.0)- ghc-options: -Winvalid-haddock+ if impl(ghc >= 9.12)+ ghc-options: -Wno-deriving-typeable if os(windows) cpp-options: -D_WINDOWS@@ -504,7 +511,7 @@ build-depends: xml-light, Glob >= 0.7 && < 0.11, JuicyPixels >= 3.1.6.1 && < 3.4,- aeson >= 2.0.1.0 && < 2.3,+ aeson >= 2.0.1.0 && < 2.4, aeson-pretty >= 0.8.9 && < 0.9, array >= 0.5 && < 0.6, attoparsec >= 0.12 && < 0.15,@@ -514,13 +521,12 @@ blaze-markup >= 0.8 && < 0.9, bytestring >= 0.9 && < 0.13, case-insensitive >= 1.2 && < 1.3,- citeproc >= 0.12 && < 0.13,- commonmark >= 0.2.6.1 && < 0.3,- commonmark-extensions >= 0.2.6 && < 0.3,- commonmark-pandoc >= 0.2.3 && < 0.3,+ citeproc >= 0.13.0.1 && < 0.14,+ commonmark >= 0.3 && < 0.4,+ commonmark-extensions >= 0.2.7 && < 0.3,+ commonmark-pandoc >= 0.3 && < 0.4, containers >= 0.6.0.1 && < 0.9,- crypton >= 0.30 && < 1.1,- crypton-connection >= 0.3.1 && < 0.5,+ crypton >= 0.30 && < 1.2, data-default >= 0.4 && < 0.9, deepseq >= 1.3 && < 1.6, directory >= 1.2.3 && < 1.4,@@ -532,14 +538,11 @@ filepath >= 1.1 && < 1.6, gridtables >= 0.1 && < 0.2, haddock-library >= 1.10 && < 1.12,- http-client >= 0.4.30 && < 0.8,- http-client-tls >= 0.2.4 && < 0.4, http-types >= 0.8 && < 0.13, ipynb >= 0.2 && < 0.3, jira-wiki-markup >= 1.5.1 && < 1.6, mime-types >= 0.1.1 && < 0.2, mtl >= 2.2 && < 2.4,- network >= 2.6 && < 3.3, network-uri >= 2.6 && < 2.8, pandoc-types >= 1.23.1 && < 1.24, parsec >= 3.1 && < 3.2,@@ -555,10 +558,10 @@ syb >= 0.1 && < 0.8, tagsoup >= 0.14.6 && < 0.15, temporary >= 1.1 && < 1.4,- texmath >= 0.13.0.2 && < 0.14,+ texmath >= 0.13.1.2 && < 0.14, text >= 1.1.1.0 && < 2.2, text-conversions >= 0.3 && < 0.4,- time >= 1.5 && < 1.16,+ time >= 1.5 && < 1.17, unicode-collation >= 0.1.1 && < 0.2, unicode-data >= 0.6 && < 0.9, unicode-transforms >= 0.3 && < 0.5,@@ -567,18 +570,25 @@ zip-archive >= 0.4.3.1 && < 0.5, zlib >= 0.5 && < 0.8, xml >= 1.3.12 && < 1.4,- typst >= 0.8.1 && < 0.9,+ typst >= 0.10 && < 0.11, vector >= 0.12 && < 0.14,- djot >= 0.1.2.4 && < 0.2,- asciidoc >= 0.1 && < 0.2,- tls >= 2.0.1 && < 2.2,- crypton-x509-system >= 1.6.7 && < 1.7+ djot >= 0.1.4 && < 0.2,+ asciidoc >= 0.1.0.3 && < 0.2 if !os(windows) build-depends: unix >= 2.4 && < 2.9 if flag(embed_data_files) cpp-options: -DEMBED_DATA_FILES other-modules: Text.Pandoc.Data.BakedIn+ if flag(http)+ cpp-options: -DPANDOC_HTTP_SUPPORT+ build-depends:+ crypton-connection >= 0.3.1 && < 0.5,+ crypton-x509-system >= 1.6.7 && < 1.10,+ http-client >= 0.4.30 && < 0.8,+ http-client-tls >= 0.2.4 && < 0.5,+ network >= 2.6 && < 3.3,+ tls >= 2.0.1 && < 2.5 hs-source-dirs: src exposed-modules: Text.Pandoc,@@ -843,7 +853,7 @@ tasty-quickcheck >= 0.8 && < 0.12, text >= 1.1.1.0 && < 2.2, temporary >= 1.1 && < 1.4,- time >= 1.5 && < 1.16,+ time >= 1.5 && < 1.17, xml >= 1.3.12 && < 1.4, zip-archive >= 0.4.3 && < 0.5 other-modules: Tests.Old
src/Text/Pandoc/App.hs view
@@ -50,6 +50,7 @@ import System.FilePath ( takeBaseName, takeExtension, takeDirectory) import System.IO (nativeNewline, stdout) import qualified System.IO as IO (Newline (..))+import Data.Version (showVersion) import Text.Pandoc import Text.Pandoc.Builder (setMeta) import Text.Pandoc.MediaBag (mediaItems)@@ -237,6 +238,7 @@ , readerAbbreviations = abbrevs , readerExtensions = readerExts , readerStripComments = optStripComments opts+ , readerTypstInputs = optTypstInputs opts } metadataFromFile <- getMetadataFromFiles readerNameBase readerOpts@@ -357,6 +359,7 @@ setOutputFile (optOutputFile opts) setNoCheckCertificate (optNoCheckCertificate opts) + setRequestHeader "User-Agent" ("pandoc/" <> T.pack (showVersion pandocVersion)) mapM_ (uncurry setRequestHeader) (optRequestHeaders opts) case lookupMetaString "lang" (optMetadata opts) of
src/Text/Pandoc/App/CommandLineOptions.hs view
@@ -31,7 +31,8 @@ defConfig, Indent(..), NumberFormat(..)) import Data.Bifunctor (second) import Data.Char (toLower)-import Data.List (intercalate, sort, foldl')+import Data.List (intercalate, sort)+import qualified Data.List as L #ifdef _WINDOWS import Data.List (isPrefixOf) #endif@@ -100,7 +101,7 @@ if (null errors && null unknownOptionErrors) then -- thread option data structure through all supplied option actions- runExceptT $ adjustOpts <$> (foldl' (>>=) (return defaults) actions)+ runExceptT $ adjustOpts <$> (L.foldl' (>>=) (return defaults) actions) else return $ Left $ OptError $ PandocOptionError $ T.pack $ concat errors ++ unlines unknownOptionErrors ++ ("Try " ++ prg ++ " --help for more information.")@@ -198,7 +199,8 @@ VersionInfo -> versionInfo [] Nothing "" Help -> do prg <- getProgName- UTF8.hPutStr stdout (T.pack $ usageMessage prg options)+ mapM_ (UTF8.hPutStrLn stdout . T.stripEnd . T.pack) $+ lines $ usageMessage prg options OptError e -> E.throwIO e exitSuccess @@ -218,8 +220,8 @@ map ("html5",) htmlEngines ++ map ("latex",) latexEngines ++ map ("beamer",) latexEngines ++- [ ("ms", "pdfroff")- , ("ms", "groff")+ [ ("ms", "groff")+ , ("ms", "pdfroff") , ("typst", "typst") , ("context", "context") ]@@ -302,7 +304,7 @@ let (key, val) = splitField arg return opt{ optMetadata = addMeta key val $ optMetadata opt })- "KEY[:VALUE]")+ "KEY[=VALUE]") "" , Option "" ["metadata-file"]@@ -344,7 +346,7 @@ "true|false") "" - , Option "s" ["standalone"]+ , Option "s" ["standalone"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--standalone/-s" arg@@ -366,7 +368,7 @@ return opt{ optVariables = setVariable (T.pack key) (T.pack val) $ optVariables opt })- "KEY[:VALUE]")+ "KEY[=VALUE]") "" , Option "" ["variable-json"]@@ -662,7 +664,7 @@ let (key, val) = splitField arg return opt{ optRequestHeaders = (T.pack key, T.pack val) : optRequestHeaders opt })- "NAME:VALUE")+ "NAME=VALUE") "" , Option "" ["no-check-certificate"]@@ -679,6 +681,14 @@ Just $ normalizePath arg }) "FILE") "" -- "Specify file for custom abbreviations"++ , Option "" ["typst-input"]+ (ReqArg+ (\arg opt -> do+ let (key, val) = splitField arg+ return opt{ optTypstInputs = (T.pack key, T.pack val) : optTypstInputs opt })+ "KEY=VALUE")+ "" , Option "" ["indented-code-classes"] (ReqArg
src/Text/Pandoc/App/Opt.hs view
@@ -28,12 +28,12 @@ , fullDefaultsPath ) where import Control.Monad.Except (throwError)-import Control.Monad.Trans (MonadIO, liftIO)+import Control.Monad.Trans (MonadIO, liftIO, lift) import Control.Monad ((>=>), foldM) import Control.Monad.State.Strict (StateT, modify, gets) import System.FilePath ( addExtension, (</>), takeExtension, takeDirectory ) import System.Directory ( canonicalizePath )-import Data.Char (toLower)+import Data.Char (toLower, isSpace) import Data.Maybe (fromMaybe) import GHC.Generics hiding (Meta) import Text.Pandoc.Filter (Filter (..))@@ -62,7 +62,7 @@ import qualified Data.ByteString.Char8 as B8 import Text.Pandoc.Definition (Meta(..), MetaValue(..)) import Data.Aeson (defaultOptions, Options(..), Result(..),- genericToJSON, fromJSON, camelTo2)+ genericToJSON, fromJSON, camelTo2, eitherDecodeStrict) import Data.Aeson.TH (deriveJSON) import Control.Applicative ((<|>)) import Data.Yaml@@ -184,6 +184,7 @@ , optBibliography :: [FilePath] -- ^ Bibliography files , optCitationAbbreviations :: Maybe FilePath -- ^ Citation abbreviations , optSandbox :: Bool+ , optTypstInputs :: [(Text, Text)] -- ^ List of parameter values for typst } deriving (Generic, Show) instance FromJSON Opt where@@ -271,6 +272,7 @@ <*> o .:? "bibliography" .!= optBibliography defaultOpts <*> o .:? "citation-abbreviations" <*> o .:? "sandbox" .!= optSandbox defaultOpts+ <*> o .:? "typst-inputs" .!= optTypstInputs defaultOpts instance ToJSON Opt where toJSON = genericToJSON defaultOptions{@@ -395,39 +397,49 @@ } where- resolveVars :: FilePath -> StateT DefaultsState m FilePath- resolveVars [] = return []- resolveVars ('$':'{':xs) =+ resolveVars = expandVars (optDataDir opt)+ resolveVarsInFilter (JSONFilter fp) =+ JSONFilter <$> resolveVars fp+ resolveVarsInFilter (LuaFilter fp) =+ LuaFilter <$> resolveVars fp+ resolveVarsInFilter CiteprocFilter = return CiteprocFilter+++expandVars :: (PandocMonad m, MonadIO m)+ => Maybe FilePath+ -> FilePath+ -> StateT DefaultsState m FilePath+expandVars _ [] = return []+expandVars mbDataDir ('$':'{':xs) = let (ys, zs) = break (=='}') xs in if null zs then return $ '$':'{':xs else do- val <- lookupEnv' ys- (val ++) <$> resolveVars (drop 1 zs)- resolveVars (c:cs) = (c:) <$> resolveVars cs- lookupEnv' :: String -> StateT DefaultsState m String- lookupEnv' "." = do+ val <- expandEnv mbDataDir ys+ (val ++) <$> expandVars mbDataDir (drop 1 zs)+expandVars mbDataDir (c:cs) = (c:) <$> expandVars mbDataDir cs++expandEnv :: (PandocMonad m, MonadIO m)+ => Maybe FilePath+ -> String+ -> StateT DefaultsState m String+expandEnv _ "." = do mbCurDefaults <- gets curDefaults maybe (return "") (fmap takeDirectory . liftIO . canonicalizePath) mbCurDefaults- lookupEnv' "USERDATA" = do- mbodatadir <- mapM resolveVars oDataDir- mbdatadir <- getUserDataDir+expandEnv mbDataDir "USERDATA" = do+ mbodatadir <- mapM (expandVars mbDataDir) mbDataDir+ mbdatadir' <- getUserDataDir defdatadir <- liftIO defaultUserDataDir- return $ fromMaybe defdatadir (mbodatadir <|> mbdatadir)- lookupEnv' v = do+ return $ fromMaybe defdatadir (mbodatadir <|> mbdatadir')+expandEnv _ v = do mbval <- fmap T.unpack <$> lookupEnv (T.pack v) case mbval of Nothing -> do report $ EnvironmentVariableUndefined (T.pack v) return mempty Just x -> return x- resolveVarsInFilter (JSONFilter fp) =- JSONFilter <$> resolveVars fp- resolveVarsInFilter (LuaFilter fp) =- LuaFilter <$> resolveVars fp- resolveVarsInFilter CiteprocFilter = return CiteprocFilter @@ -438,8 +450,9 @@ parseDefaults n dataDir = parseDefsNames n >>= \ds -> return $ \o -> do -- get parent defaults: defsParent <- gets $ fromMaybe "" . curDefaults+ expandedDataDir <- mapM (expandVars dataDir) dataDir -- get child defaults:- defsChildren <- mapM (fullDefaultsPath dataDir) ds+ defsChildren <- mapM (\d -> expandVars expandedDataDir d >>= lift . fullDefaultsPath expandedDataDir) ds -- expand parent in defaults inheritance graph by children: defsGraph <- gets inheritanceGraph let defsGraphExp = expand defsGraph defsChildren defsParent@@ -837,6 +850,7 @@ , optBibliography = [] , optCitationAbbreviations = Nothing , optSandbox = False+ , optTypstInputs = [] } yamlToMeta :: Value -> Parser Meta@@ -858,11 +872,19 @@ setVerbosity $ optVerbosity opt modify $ \defsState -> defsState{ curDefaults = Just file } inp <- readFileStrict file- case decodeEither' (B8.unlines . takeWhile (/= "...") . B8.lines $ inp) of- Right f -> f opt- Left err' -> throwError $- PandocParseError- $ T.pack $ Data.Yaml.prettyPrintParseException err'+ let isJSON = B8.take 1 (B8.dropWhile isSpace inp) == "{"+ if isJSON+ then+ case eitherDecodeStrict inp of+ Right f -> f opt+ Left err' -> throwError $ PandocParseError $ T.pack $+ "Error parsing " <> file <> ":\n" <> err'+ else+ case decodeEither' (B8.unlines . takeWhile (/= "...") . B8.lines $ inp) of+ Right f -> f opt+ Left err' -> throwError $ PandocParseError $ T.pack $+ "Error parsing " <> file <> ":\n" <>+ Data.Yaml.prettyPrintParseException err' fullDefaultsPath :: (PandocMonad m, MonadIO m) => Maybe FilePath
src/Text/Pandoc/Citeproc.hs view
@@ -30,7 +30,7 @@ import Text.Pandoc.Extensions (pandocExtensions) import Text.Pandoc.Logging (LogMessage(..)) import Text.Pandoc.Options (ReaderOptions(..))-import Text.Pandoc.Shared (stringify, tshow)+import Text.Pandoc.Shared (stringify, tshow, makeSections) import Data.Containers.ListUtils (nubOrd) import Text.Pandoc.Walk (query, walk, walkM) import Control.Applicative ((<|>))@@ -295,10 +295,22 @@ -> M.Map Text ItemId -> Pandoc -> [Citeproc.Citation Inlines]-getCitations locale otherIdsMap = Foldable.toList . query getCitation+getCitations locale otherIdsMap (Pandoc meta blocks) =+ Foldable.toList (query getCitation meta <>+ foldMap handleBlock (makeSections False Nothing blocks)) where+ handleBlock :: Block -> Seq.Seq (Citeproc.Citation Inlines)+ handleBlock b@(Div (_,cls,_) _)+ | "section" `elem` cls+ , "reset-citation-positions" `elem` cls =+ case Seq.viewl (query getCitation b) of+ x Seq.:< xs -> addResetTo x Seq.<| xs+ Seq.EmptyL -> mempty+ handleBlock b = query getCitation b+ addResetTo citation = citation{ Citeproc.citationResetPosition = True } getCitation (Cite cs _fallback) = Seq.singleton $ Citeproc.Citation { Citeproc.citationId = Nothing+ , Citeproc.citationResetPosition = False , Citeproc.citationPrefix = Nothing , Citeproc.citationSuffix = Nothing , Citeproc.citationNoteNumber =@@ -580,7 +592,8 @@ = Cite (c:cs) (addCommas (needsPeriod zs) ils) : addParens zs | otherwise- = Cite (c:cs) (concatMap noteInParens ils) : addParens zs+ = Cite (c:cs) (dropWhile (== Space) (concatMap noteInParens ils))+ : addParens zs addParens (x:xs) = x : addParens xs removeNotes (Span ("",["csl-note"],[]) ils) = Span ("",[],[]) ils
src/Text/Pandoc/Citeproc/BibTeX.hs view
@@ -52,7 +52,8 @@ import Data.Char (isAlphaNum, isDigit, isLetter, isUpper, toLower, toUpper, isLower, isPunctuation, isSpace)-import Data.List (foldl', intercalate, intersperse)+import Data.List (intercalate, intersperse)+import qualified Data.List as L import Safe (readMay) import Text.Printf (printf) import Text.DocLayout (literal, hsep, nest, hang, Doc(..),@@ -117,7 +118,7 @@ "manuscript" -> "unpublished" "graphic" | variant == Biblatex -> "artwork" "song" | variant == Biblatex -> "music"- "legal_case" | variant == Biblatex -> "jurisdictionN"+ "legal_case" | variant == Biblatex -> "jurisdiction" "legislation" | variant == Biblatex -> "legislation" "treaty" | variant == Biblatex -> "legal" "personal_communication" | variant == Biblatex -> "letter"@@ -187,6 +188,7 @@ , "annote" , "url" -- not officially supported, but supported by -- some styles (#8287)+ , "doi" ] valToInlines (TextVal t) = B.text t@@ -475,12 +477,12 @@ subtitle' <- (guard isPeriodical >> getTitle "issuesubtitle") <|> (guard hasMaintitle >> guard (not isChapterlike) >>- getTitle "mainsubtitle")+ getTitle "mainsubtitle" <|> return mempty) <|> getTitle "subtitle" <|> return mempty titleaddon' <- (guard hasMaintitle >> guard (not isChapterlike) >>- getTitle "maintitleaddon")+ getTitle "maintitleaddon" <|> return mempty) <|> getTitle "titleaddon" <|> return mempty @@ -821,7 +823,7 @@ bibComment = do cistring "comment" spaces'- void inBraces <|> bibSkip <|> return ()+ void inBraces bibPreamble :: BibParser () bibPreamble = do@@ -1115,7 +1117,7 @@ toLiteralList _ = mzero concatWith :: Char -> [Inlines] -> Inlines-concatWith sep = foldl' go mempty+concatWith sep = L.foldl' go mempty where go :: Inlines -> Inlines -> Inlines go accum s | s == mempty = accum@@ -1208,7 +1210,7 @@ | otherwise -> "article-journal" "book" -> "book" "booklet" -> "pamphlet"- "bookinbook" -> "chapter"+ "bookinbook" -> "book" "collection" -> "book" "dataset" -> "dataset" "electronic" -> "webpage"
src/Text/Pandoc/Citeproc/Locator.hs view
@@ -11,7 +11,7 @@ import Text.Pandoc.Citeproc.Util (splitStrWhen) import Data.Text (Text) import qualified Data.Text as T-import Data.List (foldl')+import qualified Data.List as L import Text.Pandoc.Definition import Text.Pandoc.Parsing import Text.Pandoc.Shared (stringify)@@ -196,7 +196,7 @@ where except = notFollowedBy pBraces >> p -- outer and inner- surround = foldl' (\a (open, close) -> sur open close except <|> a)+ surround = L.foldl' (\a (open, close) -> sur open close except <|> a) except braces
src/Text/Pandoc/Citeproc/Name.hs view
@@ -30,7 +30,7 @@ import qualified Data.Text as T import Data.List.Split (splitWhen, wordsBy) import Data.Char (isUpper, isDigit)-import Data.List (foldl')+import qualified Data.List as L emptyName :: Name emptyName =@@ -83,7 +83,7 @@ ag{ nameSuffix = Just $ stringify xs } addPart ag (Space : xs) = addPart ag xs addPart ag _ = ag- return $ foldl' addPart emptyName commaParts+ return $ L.foldl' addPart emptyName commaParts -- First von Last -- von Last, First -- von Last, Jr ,First
src/Text/Pandoc/Class/CommonState.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {- | Module : Text.Pandoc.Class.CommonState Copyright : Copyright (C) 2016-2020 Jesse Rosenthal, John MacFarlane@@ -23,7 +24,9 @@ import Text.Pandoc.MediaBag (MediaBag) import Text.Pandoc.Logging (LogMessage, Verbosity (WARNING)) import Text.Pandoc.Translations.Types (Translations)+#ifdef PANDOC_HTTP_SUPPORT import Network.HTTP.Client (Manager)+#endif -- | 'CommonState' represents state that is used by all -- instances of 'PandocMonad'. Normally users should not@@ -51,9 +54,11 @@ , stResourcePath :: [FilePath] -- ^ Path to search for resources like -- included images+#ifdef PANDOC_HTTP_SUPPORT , stManager :: Maybe Manager -- ^ Manager for HTTP client; this needs to persist across many requests -- for efficiency.+#endif , stVerbosity :: Verbosity -- ^ Verbosity level , stTrace :: Bool@@ -79,7 +84,9 @@ , stInputFiles = [] , stOutputFile = Nothing , stResourcePath = ["."]+#ifdef PANDOC_HTTP_SUPPORT , stManager = Nothing+#endif , stVerbosity = WARNING , stTrace = False }
src/Text/Pandoc/Class/IO.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-} {- | Module : Text.Pandoc.Class.IO@@ -37,31 +38,37 @@ import Control.Monad.Except (throwError) import Control.Monad.IO.Class (MonadIO, liftIO)-import Data.ByteString.Lazy (toChunks) import Data.Text (Text, pack, unpack) import Data.Time (TimeZone, UTCTime) import Data.Unique (hashUnique)+#ifdef PANDOC_HTTP_SUPPORT+import Data.ByteString.Lazy (toChunks)+import System.Environment (getEnv)+import Data.Default (def) import Network.Connection (TLSSettings(..)) import qualified Network.TLS as TLS import qualified Network.TLS.Extra as TLS+import System.X509 (getSystemCertificateStore) import Network.HTTP.Client (httpLbs, Manager, responseBody, responseHeaders,- Request(port, host, requestHeaders), parseUrlThrow, newManager)+ Request(port, host, requestHeaders), parseUrlThrow, newManager, HttpException) import Network.HTTP.Client.Internal (addProxy) import Network.HTTP.Client.TLS (mkManagerSettings) import Network.HTTP.Types.Header ( hContentType ) import Network.Socket (withSocketsDo)+import Text.Pandoc.Class.CommonState (CommonState (..))+import Text.Pandoc.Class.PandocMonad ( getsCommonState, modifyCommonState )+import qualified Data.CaseInsensitive as CI+#endif import Network.URI (URI(..), parseURI, unEscapeString) import System.Directory (createDirectoryIfMissing)-import System.Environment (getEnv)-import System.FilePath ((</>), takeDirectory, normalise)+import System.FilePath ((</>), takeDirectory, takeFileName, normalise, takeExtension) import qualified System.FilePath.Posix as Posix import System.IO (stderr) import System.IO.Error import System.Random (StdGen)-import Text.Pandoc.Class.CommonState (CommonState (..)) import Text.Pandoc.Class.PandocMonad- (PandocMonad, getsCommonState, modifyCommonState,+ (PandocMonad, getMediaBag, report, extractURIData) import Text.Pandoc.Definition (Pandoc, Inline (Image)) import Text.Pandoc.Error (PandocError (..))@@ -72,7 +79,6 @@ import qualified Control.Exception as E import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL-import qualified Data.CaseInsensitive as CI import qualified Data.Text as T import qualified Data.Time import qualified Data.Time.LocalTime@@ -82,8 +88,7 @@ import qualified System.FilePath.Glob import qualified System.Random import qualified Text.Pandoc.UTF8 as UTF8-import Data.Default (def)-import System.X509 (getSystemCertificateStore)+import Codec.Archive.Zip #ifndef EMBED_DATA_FILES import qualified Paths_pandoc as Paths #endif@@ -124,6 +129,7 @@ newUniqueHash :: MonadIO m => m Int newUniqueHash = hashUnique <$> liftIO Data.Unique.newUnique +#ifdef PANDOC_HTTP_SUPPORT getManager :: (PandocMonad m, MonadIO m) => m Manager getManager = do mbManager <- getsCommonState stManager@@ -153,12 +159,14 @@ newManager tlsManagerSettings modifyCommonState $ \st -> st{ stManager = Just manager } pure manager+#endif openURL :: (PandocMonad m, MonadIO m) => Text -> m (B.ByteString, Maybe MimeType) openURL u | Just (URI{ uriScheme = "data:", uriPath = upath }) <- parseURI (T.unpack u) = pure $ extractURIData upath+#ifdef PANDOC_HTTP_SUPPORT | otherwise = do let toReqHeader (n, v) = (CI.mk (UTF8.fromText n), UTF8.fromText v) customHeaders <- map toReqHeader <$> getsCommonState stRequestHeaders@@ -178,7 +186,12 @@ case res of Right r -> return r- Left e -> throwError $ PandocHttpError u e+ Left (e :: HttpException)+ -> throwError $ PandocHttpError u (T.pack (show e))+#else+ | otherwise =+ throwError $ PandocHttpError u "pandoc was compiled without HTTP support"+#endif -- | Read the lazy ByteString contents from a file path, raising an error on -- failure.@@ -233,16 +246,26 @@ where go l' = do UTF8.hPutStr stderr " " UTF8.hPutStrLn stderr l' --- | Extract media from the mediabag into a directory.+-- | Extract media from the mediabag into a directory (or a zip archive if the+-- path supplied ends in @.zip@. extractMedia :: (PandocMonad m, MonadIO m) => FilePath -> Pandoc -> m Pandoc-extractMedia dir d = do+extractMedia path d = do media <- getMediaBag let items = mediaItems media+ let (dir, mbZip) = case takeExtension path of+ ".zip" -> (takeDirectory path, Just (takeFileName path))+ _ -> (path, Nothing) if null items then return d else do- mapM_ (writeMedia dir) items+ let archive = foldr addEntry emptyArchive items+ case mbZip of+ Just fname -> writeMedia dir+ (fname, "application/zip", fromArchive archive)+ Nothing -> mapM_ (writeMedia dir) items return $ walk (adjustImagePath dir media) d+ where+ addEntry (fp, _mime, content) = addEntryToArchive (toEntry fp 0 content) -- | Write the contents of a media bag to a path. -- If the path contains URI escape sequences (percent-encoding),
src/Text/Pandoc/Class/PandocMonad.hs view
@@ -534,7 +534,7 @@ return $ replacementSpan attr src tit lab PandocHttpError u er -> do report $ CouldNotFetchResource u- (T.pack $ show er ++ "\rReplacing image with description.")+ (er <> "\nReplacing image with description.") -- emit alt text return $ replacementSpan attr src tit lab _ -> throwError e)
src/Text/Pandoc/Error.hs view
@@ -25,7 +25,6 @@ import Data.Text (Text) import qualified Data.Text as T import GHC.Generics (Generic)-import Network.HTTP.Client (HttpException) import System.Exit (ExitCode (..), exitWith) import System.IO (stderr) import qualified Text.Pandoc.UTF8 as UTF8@@ -34,7 +33,7 @@ import Citeproc (CiteprocError, prettyCiteprocError) data PandocError = PandocIOError Text IOError- | PandocHttpError Text HttpException+ | PandocHttpError Text Text | PandocShouldNeverHappenError Text | PandocSomeError Text | PandocParseError Text@@ -69,13 +68,14 @@ deriving (Show, Typeable, Generic) instance Exception PandocError+ where+ displayException = T.unpack . renderError renderError :: PandocError -> Text renderError e = case e of PandocIOError _ err' -> T.pack $ displayException err'- PandocHttpError u err' ->- "Could not fetch " <> u <> "\n" <> tshow err'+ PandocHttpError u err' -> "Could not fetch " <> u <> "\n" <> err' PandocShouldNeverHappenError s -> "Something we thought was impossible happened!\n" <> "Please report this to pandoc's developers: " <> s@@ -86,49 +86,49 @@ PandocSyntaxMapError s -> s PandocFailOnWarningError -> "Failing because there were warnings." PandocPDFProgramNotFoundError pdfprog ->- pdfprog <> " not found. Please select a different --pdf-engine or install " <> pdfprog+ quote pdfprog <> " not found. Please select a different --pdf-engine or install "+ <> quote pdfprog PandocPDFError logmsg -> "Error producing PDF.\n" <> logmsg PandocXMLError fp logmsg -> "Invalid XML" <>- (if T.null fp then "" else " in " <> fp) <> ":\n" <> logmsg+ (if T.null fp then "" else " in " <> quote fp) <> ":\n" <> logmsg PandocFilterError filtername msg -> "Error running filter " <>- filtername <> ":\n" <> msg+ quote filtername <> ":\n" <> msg PandocLuaError msg -> "Error running Lua:\n" <> msg PandocNoScriptingEngine -> "This version of pandoc has been compiled " <> "without Lua support." PandocCouldNotFindDataFileError fn ->- "Could not find data file " <> fn+ "Could not find data file " <> quote fn PandocCouldNotFindMetadataFileError fn ->- "Could not find metadata file " <> fn+ "Could not find metadata file " <> quote fn PandocResourceNotFound fn ->- "File " <> fn <> " not found in resource path"- PandocTemplateError s -> "Error compiling template " <> s- PandocNoTemplateError fp -> "No template defined in " <> fp+ "File " <> quote fn <> " not found in resource path"+ PandocTemplateError s -> "Error compiling template " <> quote s+ PandocNoTemplateError fp -> "No template defined in " <> quote fp PandocAppError s -> s PandocEpubSubdirectoryError s ->- "EPUB subdirectory name '" <> s <> "' contains illegal characters"+ "EPUB subdirectory name " <> quote s <> " contains illegal characters" PandocMacroLoop s -> "Loop encountered in expanding macro " <> s PandocUTF8DecodingError f offset w ->- "UTF-8 decoding error in " <> f <> " at byte offset " <> tshow offset <>- " (" <> T.pack (printf "%2x" w) <> ").\n" <>- "The input must be a UTF-8 encoded text."+ "UTF-8 decoding error in " <> quote f <> " at byte offset "+ <> tshow offset <> " (" <> T.pack (printf "%2x" w) <> ").\n"+ <> "The input must be a UTF-8 encoded text." PandocIpynbDecodingError w -> "ipynb decoding error: " <> w PandocUnsupportedCharsetError charset ->- "Unsupported charset " <> charset+ "Unsupported charset " <> quote charset PandocFormatError format s ->- "Error parsing format " <> tshow format <> ": " <> s+ "Error parsing format " <> quote format <> ": " <> s PandocUnknownReaderError r ->- "Unknown input format " <> r <>+ "Unknown input format " <> quote r <> case r of "doc" -> "\nPandoc can convert from DOCX, but not from DOC." <> "\nTry using Word to save your DOC file as DOCX," <> " and convert that with pandoc." "pdf" -> "\nPandoc can convert to PDF, but not from PDF."- "asciidoc" -> "\nPandoc can convert to asciidoc, but not from asciidoc." _ -> "" PandocUnknownWriterError w ->- "Unknown output format " <> w <>+ "Unknown output format " <> quote w <> case w of "pdf" -> "To create a pdf using pandoc, use" <> " -t latex|beamer|context|ms|html5|typst" <>@@ -137,28 +137,32 @@ "doc" -> "\nPandoc can convert to DOCX, but not to DOC." _ -> "" PandocUnsupportedExtensionError ext f ->- "The extension " <> ext <> " is not supported " <>+ "The extension " <> quote ext <> " is not supported " <> "for " <> f <> ".\nUse --list-extensions=" <> f <> " to " <> "list supported extensions." PandocCiteprocError e' -> prettyCiteprocError e' PandocBibliographyError fp msg ->- "Error reading bibliography file " <> fp <> ":\n" <> msg+ "Error reading bibliography file " <> quote fp <> ":\n" <> msg PandocInputNotTextError fp -> "Expected text as an input, but received binary data from " <> (if T.null fp then "stdin"- else "file " <> fp) <>+ else "file " <> quote fp) <> ".\nIf you intended to convert from binary format, verify that it's " <> "supported and use\nexplicit -f FORMAT." +quote :: Text -> Text+quote s = "'" <> s <> "'" -- | Handle PandocError by exiting with an error message. handleError :: Either PandocError a -> IO a handleError (Right r) = return r handleError (Left e) = case e of- PandocIOError _ err' -> ioError err'+ PandocIOError _ err' -> do+ putStrLn $ displayException err'+ exitWith (ExitFailure 1) _ -> err exitCode (renderError e) where exitCode =
src/Text/Pandoc/Extensions.hs view
@@ -521,6 +521,7 @@ , Ext_rebase_relative_paths , Ext_wikilinks_title_after_pipe , Ext_wikilinks_title_before_pipe+ , Ext_alerts ] getAll "markdown_strict" = allMarkdownExtensions getAll "markdown_phpextra" = allMarkdownExtensions@@ -663,4 +664,5 @@ [ Ext_smart ] getAll "typst" = extensionsFromList [Ext_citations, Ext_smart] getAll "djot" = extensionsFromList [Ext_sourcepos]+ getAll "man" = autoIdExtensions getAll _ = mempty
src/Text/Pandoc/Format.hs view
@@ -22,7 +22,7 @@ import Control.Monad.Except (throwError) import Data.Char (toLower) import Data.Foldable (asum)-import Data.List (foldl')+import qualified Data.List as L import System.FilePath (splitExtension, takeExtension) import Text.Pandoc.Class (PandocMonad) import Text.Pandoc.Error (PandocError (..))@@ -142,7 +142,7 @@ pExtensionsDiff :: (UpdateSourcePos s Char, Stream s m Char) => ParsecT s u m ExtensionsDiff-pExtensionsDiff = foldl' (flip ($)) mempty <$> many extMod+pExtensionsDiff = L.foldl' (flip ($)) mempty <$> many extMod where extMod = do polarity <- oneOf "-+"
src/Text/Pandoc/ImageSize.hs view
@@ -374,7 +374,9 @@ let dpi = fromIntegral $ writerDpi opts let dirToInt dir = do dim <- findAttrBy (== QName dir Nothing Nothing) doc >>= lengthToDim- return $ inPixel opts dim+ case dim of+ Percent _ -> mzero+ _ -> pure $ inPixel opts dim w <- dirToInt "width" <|> (fst <$> viewboxSize) h <- dirToInt "height" <|> (snd <$> viewboxSize) return ImageSize {
src/Text/Pandoc/Logging.hs view
@@ -105,12 +105,14 @@ | UnclosedDiv SourcePos SourcePos | UnsupportedCodePage Int | YamlWarning SourcePos Text+ | UnsupportedPdfStandard Text deriving (Show, Eq, Data, Ord, Typeable, Generic) instance ToJSON LogMessage where toJSON x = object $ "verbosity" .= toJSON (messageVerbosity x) : "type" .= toJSON (show $ toConstr x) :+ "pretty" .= toJSON (showLogMessage x) : case x of SkippedContent s pos -> ["contents" .= s,@@ -290,6 +292,8 @@ , "column" .= toJSON (sourceColumn pos) , "message" .= msg ]+ UnsupportedPdfStandard s ->+ ["contents" .= s] showPos :: SourcePos -> Text showPos pos = Text.pack $ sn ++ "line " ++@@ -437,6 +441,8 @@ UnsupportedCodePage cpg -> "Unsupported code page " <> tshow cpg <> ". Text will likely be garbled." YamlWarning pos m -> "YAML warning (" <> showPos pos <> "): " <> m+ UnsupportedPdfStandard s ->+ "PDF standard '" <> s <> "' is not supported by LaTeX and will be ignored." messageVerbosity :: LogMessage -> Verbosity messageVerbosity msg =@@ -496,3 +502,4 @@ UnclosedDiv{} -> WARNING UnsupportedCodePage{} -> WARNING YamlWarning{} -> WARNING+ UnsupportedPdfStandard{} -> WARNING
src/Text/Pandoc/Options.hs view
@@ -74,6 +74,7 @@ , readerTrackChanges :: TrackChanges -- ^ Track changes setting for docx , readerStripComments :: Bool -- ^ Strip HTML comments instead of parsing as raw HTML -- (only implemented in commonmark)+ , readerTypstInputs :: [(Text, Text)] -- ^ parameters specified using --typst-input } deriving (Show, Read, Data, Typeable, Generic) instance HasSyntaxExtensions ReaderOptions where@@ -90,6 +91,7 @@ , readerDefaultImageExtension = "" , readerTrackChanges = AcceptChanges , readerStripComments = False+ , readerTypstInputs = [] } defaultAbbrevs :: Set.Set Text@@ -442,7 +444,7 @@ isEnabled ext opts = ext `extensionEnabled` getExtensions opts defaultMathJaxURL :: Text-defaultMathJaxURL = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js"+defaultMathJaxURL = "https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js" defaultWebTeXURL :: Text defaultWebTeXURL = "https://latex.codecogs.com/png.latex?"
src/Text/Pandoc/PDF.hs view
@@ -218,7 +218,7 @@ verbosity <- getVerbosity liftIO $ toPdfViaTempFile verbosity program args (:[]) ".html" source --- convert SVG to PDF, and pixel formatst to PNG or JPEG, for TeX formats+-- convert SVG to PDF, and pixel formats to PNG or JPEG, for TeX formats convertImages :: (PandocMonad m, MonadIO m) => WriterOptions -> FilePath -> Inline -> m Inline convertImages opts tmpdir (Image attr ils (src, tit)) = do@@ -628,6 +628,7 @@ , "SELFAUTOPARENT" , "SFDFONTS" , "SHELL"+ , "SOURCE_DATE_EPOCH" , "T1FONTS" , "T1INPUTS" , "T42FONTS"
src/Text/Pandoc/Parsing/General.hs view
@@ -284,7 +284,7 @@ => (Char -> Char -> Bool) -> [Text] -> ParsecT s st m Text oneOfStrings' _ [] = Prelude.fail "no strings to match" oneOfStrings' matches strs =- TL.toStrict . TB.toLazyText <$> try (go (TB.fromText mempty) strs)+ TL.toStrict . TB.toLazyText <$> try (go mempty strs) where go acc strs' = do c <- anyChar@@ -400,15 +400,13 @@ -- | Parse string, case insensitive. stringAnyCase :: (Stream s m Char, UpdateSourcePos s Char) => Text -> ParsecT s st m Text-stringAnyCase = fmap T.pack . stringAnyCase' . T.unpack--stringAnyCase' :: (Stream s m Char, UpdateSourcePos s Char)- => String -> ParsecT s st m String-stringAnyCase' [] = string ""-stringAnyCase' (x:xs) = do- firstChar <- char (toUpper x) <|> char (toLower x)- rest <- stringAnyCase' xs- return (firstChar:rest)+stringAnyCase t = TL.toStrict . TB.toLazyText <$> go (T.unpack t)+ where+ go [] = string "" $> mempty+ go (x:xs) = do+ c <- char (toUpper x) <|> char (toLower x)+ rest <- go xs+ pure $ TB.singleton c <> rest -- TODO rewrite by just adding to Sources stream? -- | Parse contents of 'str' using 'parser' and return result.@@ -484,8 +482,10 @@ xs <- many (satisfy isEmailChar) return (x:xs) isEmailChar c = isAlphaNum c || isEmailPunct c- isEmailPunct c = T.any (== c) "!\"#$%&'*+-/=?^_{|}~;"+ isEmailPunct c = c `Set.member` emailPunctChars +emailPunctChars :: Set.Set Char+emailPunctChars = Set.fromList "!\"#$%&'*+-/=?^_{|}~;" uriScheme :: (Stream s m Char, UpdateSourcePos s Char) => ParsecT s st m Text uriScheme = oneOfStringsCI (Set.toList schemes)@@ -532,7 +532,7 @@ <|> entity <|> try (punct <* lookAhead (void wordChar <|> void percentEscaped)) uriChunkBetween l r = try $ do chunk <- between (char l) (char r) uriChunk- return (T.pack $ [l] ++ chunk ++ [r])+ return $ T.singleton l <> T.pack chunk <> T.singleton r -- | Applies a parser, returns tuple of its results and its horizontal -- displacement (the difference between the source column at the end@@ -688,7 +688,7 @@ where ident' = fromMaybe ident (lookup "id" kvs) cls' = maybe cls T.words $ lookup "class" kvs- kvs' = filter (\(k,_) -> k /= "id" || k /= "class") kvs+ kvs' = filter (\(k,_) -> k /= "id" && k /= "class") kvs insertIncludedFile :: (PandocMonad m, HasIncludeFiles st) => ParsecT a st m b -- ^ parser to apply@@ -755,8 +755,9 @@ ((pos,txt):_) -> let ls = T.lines txt <> [""] ln = (errLine - sourceLine pos) + 1- in if length ls > ln && ln >= 1- then T.concat ["\n", ls !! (ln - 1)- ,"\n", T.replicate (errColumn - 1) " "- ,"^"]- else ""+ in case drop (ln - 1) ls of+ (l:_) | ln >= 1 ->+ T.concat ["\n", l+ ,"\n", T.replicate (errColumn - 1) " "+ ,"^"]+ _ -> ""
src/Text/Pandoc/Parsing/Lists.hs view
@@ -113,7 +113,7 @@ => ParsecT s ParserState m (ListNumberStyle, Int) exampleNum = do char '@'- lab <- mconcat . map T.pack <$>+ lab <- T.pack . concat <$> many (many1 alphaNum <|> try (do c <- char '_' <|> char '-' cs <- many1 alphaNum
src/Text/Pandoc/Parsing/Math.hs view
@@ -28,6 +28,8 @@ (UpdateSourcePos, anyChar, char, digit, newline, satisfy, space, string) import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Builder as TB mathInlineWith :: (Stream s m Char, UpdateSourcePos s Char) => Text -> Text -> ParsecT s st m Text mathInlineWith op cl = try $ do@@ -42,31 +44,38 @@ (try (string "text" >> (("\\text" <>) <$> inBalancedBraces 0 "")) <|> (\c -> T.pack ['\\',c]) <$> anyChar))- <|> ("\n" <$ blankline <* notFollowedBy' blankline)+ <|> ("\n" <$ blankline <* notFollowedBy' blankline <* notFollowedBy (char '$')) <|> (T.pack <$> many1 spaceChar <* notFollowedBy (char '$')) ) (try $ textStr cl) notFollowedBy digit -- to prevent capture of $5 return $ trimMath $ T.concat words' where- inBalancedBraces :: (Stream s m Char, UpdateSourcePos s Char) => Int -> Text -> ParsecT s st m Text- inBalancedBraces n = fmap T.pack . inBalancedBraces' n . T.unpack+ inBalancedBraces :: (Stream s m Char, UpdateSourcePos s Char)+ => Int -> Text -> ParsecT s st m Text+ inBalancedBraces n t =+ TL.toStrict . TB.toLazyText <$>+ go n False (TB.fromText t) (not (T.null t)) - inBalancedBraces' :: (Stream s m Char, UpdateSourcePos s Char) => Int -> String -> ParsecT s st m String- inBalancedBraces' 0 "" = do+ -- go depth lastWasBackslash accumulator started+ go :: (Stream s m Char, UpdateSourcePos s Char)+ => Int -> Bool -> TB.Builder -> Bool -> ParsecT s st m TB.Builder+ go 0 _ acc False = do c <- anyChar if c == '{'- then inBalancedBraces' 1 "{"+ then go 1 False (acc <> TB.singleton '{') True else mzero- inBalancedBraces' 0 s = return $ reverse s- inBalancedBraces' numOpen ('\\':xs) = do+ go 0 _ acc True = return acc+ go depth True acc _ = do c <- anyChar- inBalancedBraces' numOpen (c:'\\':xs)- inBalancedBraces' numOpen xs = do+ go depth False (acc <> TB.singleton c) True+ go depth False acc _ = do c <- anyChar+ let acc' = acc <> TB.singleton c case c of- '}' -> inBalancedBraces' (numOpen - 1) (c:xs)- '{' -> inBalancedBraces' (numOpen + 1) (c:xs)- _ -> inBalancedBraces' numOpen (c:xs)+ '\\' -> go depth True acc' True+ '}' -> go (depth - 1) False acc' True+ '{' -> go (depth + 1) False acc' True+ _ -> go depth False acc' True mathDisplayWith :: (Stream s m Char, UpdateSourcePos s Char) => Text -> Text -> ParsecT s st m Text mathDisplayWith op cl = try $ fmap T.pack $ do
src/Text/Pandoc/Readers/AsciiDoc.hs view
@@ -37,7 +37,7 @@ import Text.Pandoc.Logging import Text.Pandoc.Sources import Control.Monad.State-import Data.List (intersperse, foldl')+import qualified Data.List as L import Data.Char (chr, ord) import qualified Data.Text as T import qualified Data.Map as M@@ -148,7 +148,7 @@ B.setMeta "version" vers . maybe id (B.setMeta "date") mbdate . maybe id (B.setMeta "remark") mbremark) .- flip (foldl' (\m (k,v) ->+ flip (L.foldl' (\m (k,v) -> -- leave out flags that are set just for processing if k == "sectids" || k == "stem" then m@@ -363,7 +363,7 @@ (B.str ("[" <> t <> "]")) A.Button t -> pure $ B.spanWith ("",["button"],[]) (B.strong $ B.str ("[" <> t <> "]"))- A.Kbd ts -> pure $ mconcat $ intersperse (B.str "+") $+ A.Kbd ts -> pure $ mconcat $ L.intersperse (B.str "+") $ map (B.spanWith ("",["kbd"],[]) . B.strong . B.str) ts A.Menu ts -> pure $ B.spanWith ("",["menu"],[]) $ B.strong $ B.text $ T.intercalate " › " ts
src/Text/Pandoc/Readers/Djot.hs view
@@ -37,7 +37,6 @@ import Text.Pandoc.Emoji (emojiToInline) import Control.Monad.Reader import qualified Data.Foldable as F-import Data.List (foldl') import Data.ByteString (ByteString) -- import Debug.Trace @@ -141,7 +140,7 @@ (hs,bs):rs -> (hs,row:bs):rs [] -> [([],[row])] let reverseSnd (as,bs) = (as,reverse bs)- let bodies = reverse $ map reverseSnd $ foldl' getBody [] rest+ let bodies = reverse $ map reverseSnd $ F.foldl' getBody [] rest let toCell (D.Cell _ al ils) = Cell nullAttr (toAlign al) (RowSpan 1) (ColSpan 1) . (\is -> [Para $ toList is]) <$> convertInlines ils
src/Text/Pandoc/Readers/DocBook.hs view
@@ -46,7 +46,7 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad, report) import Text.Pandoc.Options import Text.Pandoc.Logging (LogMessage(..))-import Text.Pandoc.Shared (safeRead, extractSpaces)+import Text.Pandoc.Shared (safeRead, addPandocAttributes) import Text.Pandoc.Sources (ToSources(..), sourcesToText) import Text.Pandoc.Transforms (headerShift) import Text.TeXMath (readMathML, writeTeX)@@ -173,7 +173,7 @@ [ ] errorname - An error name [ ] errortext - An error message. [ ] errortype - The classification of an error message-[ ] example - A formal example, with a title+[x] example - A formal example, with a title [ ] exceptionname - The name of an exception [ ] fax - A fax number [ ] fieldsynopsis - The name of a field in a class definition@@ -438,7 +438,7 @@ [ ] shortaffil - A brief description of an affiliation [ ] shortcut - A key combination for an action that is also accessible through a menu-[ ] sidebar - A portion of a document that is isolated from the main+[x] sidebar - A portion of a document that is isolated from the main narrative flow [ ] sidebarinfo - Meta-information for a Sidebar [x] simpara - A paragraph that contains only text and inline markup, no block@@ -548,6 +548,7 @@ , dbBook :: Bool , dbContent :: [Content] , dbLiteralLayout :: Bool+ , dbElementStack :: [Text] } deriving Show instance Default DBState where@@ -556,7 +557,9 @@ , dbMeta = mempty , dbBook = False , dbContent = []- , dbLiteralLayout = False }+ , dbLiteralLayout = False+ , dbElementStack = []+ } readDocBook :: (PandocMonad m, ToSources a)@@ -621,9 +624,13 @@ -- addMetadataFromElement :: PandocMonad m => Element -> DB m Blocks-addMetadataFromElement e =- mempty <$ mapM_ handleMetadataElement+addMetadataFromElement e = do+ -- Add metadata if at root or appropriate parent element+ elementStack <- gets dbElementStack+ if take 1 elementStack `elem` [[], ["book"], ["article"]]+ then mempty <$ mapM_ handleMetadataElement (filterChildren ((isMetadataField . qName . elName)) e)+ else return mempty where handleMetadataElement elt = case qName (elName elt) of@@ -724,9 +731,7 @@ , "articleinfo" , "attribution" , "authorinitials"- , "bibliodiv" , "biblioentry"- , "bibliography" , "bibliomisc" , "bibliomixed" , "blockquote"@@ -765,31 +770,19 @@ , "preface" , "procedure" , "programlisting"- , "qandadiv" , "question"- , "refsect1" , "refsect1info"- , "refsect2" , "refsect2info"- , "refsect3" , "refsect3info"- , "refsection" , "refsectioninfo" , "screen"- , "sect1" , "sect1info"- , "sect2" , "sect2info"- , "sect3" , "sect3info"- , "sect4" , "sect4info"- , "sect5" , "sect5info"- , "section" , "sectioninfo" , "simpara"- , "simplesect" , "substeps" , "subtitle" , "table"@@ -797,8 +790,14 @@ , "titleabbrev" , "toc" , "variablelist"- ] ++ admonitionTags+ ] ++ sectionTags ++ admonitionTags +sectionTags :: [Text]+sectionTags = ["bibliography", "bibliodiv"+ , "sect1", "sect2", "sect3", "sect4", "sect5", "section", "simplesect"+ , "refsect1", "refsect2", "refsect3", "refsection", "qandadiv"+ ]+ admonitionTags :: [Text] admonitionTags = ["caution","danger","important","note","tip","warning"] @@ -853,9 +852,16 @@ fmap (imageWith attr imageUrl tit) capt getBlocks :: PandocMonad m => Element -> DB m Blocks-getBlocks e = mconcat <$>- mapM parseBlock (elContent e)+getBlocks e = do+ modify (\st -> st{ dbElementStack = qName (elName e) : dbElementStack st })+ blocks <- mconcat <$> mapM parseBlock (elContent e)+ modify (\st -> st{ dbElementStack = drop 1 $ dbElementStack st })+ return blocks +getRoleAttr :: Element -> [(Text, Text)] -- extract role attribute and add it to the attribute list+getRoleAttr e = case attrValue "role" e of+ "" -> []+ r -> [("role", r)] parseBlock :: PandocMonad m => Content -> DB m Blocks parseBlock (Text (CData CDataRaw _ _)) = return mempty -- DOCTYPE@@ -863,8 +869,8 @@ then return mempty else return $ plain $ trimInlines $ text s parseBlock (CRef x) = return $ plain $ str $ T.toUpper x-parseBlock (Elem e) =- case qName (elName e) of+parseBlock (Elem e) = do+ parsedBlock <- case qName (elName e) of "toc" -> skip -- skip TOC, since in pandoc it's autogenerated "index" -> skip -- skip index, since page numbers meaningless "para" -> parseMixed para (elContent e)@@ -913,8 +919,8 @@ "refsect2" -> sect 2 "refsect3" -> sect 3 "refsection" -> gets dbSectionLevel >>= sect . (+1)- l | l `elem` titledBlockElements -> parseAdmonition l- l | l `elem` admonitionTags -> parseAdmonition l+ l | l `elem` titledBlockElements -> parseAdmonition False l+ l | l `elem` admonitionTags -> parseAdmonition True l "area" -> skip "areaset" -> skip "areaspec" -> skip@@ -976,6 +982,9 @@ "title" -> return mempty -- handled in parent element "subtitle" -> return mempty -- handled in parent element _ -> skip >> getBlocks e+ if qName (elName e) `elem` sectionTags+ then return parsedBlock+ else return $ addPandocAttributes (getRoleAttr e) parsedBlock where skip = do let qn = qName $ elName e let name = if "pi-" `T.isPrefixOf` qn@@ -1111,7 +1120,10 @@ modify $ \st -> st{ dbSectionLevel = n } b <- getBlocks e modify $ \st -> st{ dbSectionLevel = n - 1 }- return $ headerWith (elId, classes, maybeToList titleabbrevElAsAttr++attrs) n' headerText <> b+ let hdr = addPandocAttributes (getRoleAttr e)+ $ headerWith (elId, classes, maybeToList titleabbrevElAsAttr ++ attrs)+ n' headerText+ return $ hdr <> b titleabbrevElAsAttr = case filterChild (named "titleabbrev") e `mplus` (filterChild (named "info") e >>=@@ -1134,17 +1146,20 @@ b <- p case mbt of Nothing -> return b- Just t -> return $ divWith (attrValue "id" e,[],[])+ Just t -> return $ divWith (attrValue "id" e, [], getRoleAttr e) (divWith ("", ["title"], []) (plain t) <> b) -- Admonitions are parsed into a div. Following other Docbook tools that output HTML, -- we parse the optional title as a div with the @title@ class, and give the -- block itself a class corresponding to the admonition name.- parseAdmonition label = do+ parseAdmonition alwaysIncludeTitle label = do mbt <- getTitle -- this will ignore the title element if it is present: b <- getBlocks e- let t = divWith ("", ["title"], []) (plain $ fromMaybe mempty mbt)+ let t = maybe mempty (divWith ("", ["title"], []) . plain)+ (case mbt of+ Nothing | alwaysIncludeTitle -> Just mempty+ _ -> mbt) -- we also attach the label as a class, so it can be styled properly return $ divWith (attrValue "id" e,[label],[]) (t <> b) @@ -1234,8 +1249,8 @@ else return $ text s parseInline (CRef ref) = return $ text $ fromMaybe (T.toUpper ref) $ lookupEntity ref-parseInline (Elem e) =- case qName (elName e) of+parseInline (Elem e) = do+ parsedInline <- case qName (elName e) of "anchor" -> do return $ spanWith (attrValue "id" e, [], []) mempty "phrase" -> do@@ -1357,6 +1372,9 @@ -- <?asciidor-br?> to in handleInstructions, above. "pi-asciidoc-br" -> return linebreak _ -> skip >> innerInlines id+ return $ case qName (elName e) of+ "emphasis" -> parsedInline+ _ -> addPandocAttributes (getRoleAttr e) parsedInline where skip = do let qn = qName $ elName e let name = if "pi-" `T.isPrefixOf` qn@@ -1365,8 +1383,7 @@ lift $ report $ IgnoredElement name return mempty - innerInlines f = extractSpaces f . mconcat <$>- mapM parseInline (elContent e)+ innerInlines f = f . mconcat <$> mapM parseInline (elContent e) codeWithLang = do let classes' = case attrValue "language" e of "" -> []
src/Text/Pandoc/Readers/Docx.hs view
@@ -74,7 +74,8 @@ import Data.Bifunctor (bimap, first) import qualified Data.ByteString.Lazy as B import Data.Default (Default)-import Data.List (delete, intersect, foldl')+import Data.List (delete, intersect)+import qualified Data.List as L import Data.Char (isSpace) import qualified Data.Map as M import qualified Data.Text as T@@ -82,7 +83,7 @@ import Data.Sequence (ViewL (..), viewl) import qualified Data.Sequence as Seq import qualified Data.Set as Set-import Citeproc (ItemId(..), Reference(..), CitationItem(..))+import Citeproc (ItemId(..), Val(TextVal,FancyVal), Reference(..), CitationItem(..)) import qualified Citeproc import Text.Pandoc.Builder as Pandoc import Text.Pandoc.MediaBag (MediaBag)@@ -535,8 +536,13 @@ => Citeproc.Citation T.Text -> DocxContext m [Citation] handleCitation citation = do+ let getItemId item =+ case citationItemData item >>= M.lookup "citation-key" . referenceVariables of+ Just (TextVal k) -> ItemId k+ Just (FancyVal k) -> ItemId k+ _ -> citationItemId item let toPandocCitation item =- Citation{ citationId = unItemId (Citeproc.citationItemId item)+ Citation{ citationId = unItemId (getItemId item) , citationPrefix = maybe [] (toList . text) $ Citeproc.citationItemPrefix item , citationSuffix = (toList . text) $@@ -553,8 +559,7 @@ let refs = mapMaybe (\item -> fmap (\itemData -> text <$> -- see #10366, sometimes itemData has a different -- id and we need to use the same one:- itemData{ referenceId =- Citeproc.citationItemId item })+ itemData{ referenceId = getItemId item }) (Citeproc.citationItemData item)) items modify $ \st -> st{ docxReferences = foldr@@ -625,8 +630,8 @@ splitHeaderRows :: Bool -> [Docx.Row] -> ([Docx.Row], [Docx.Row]) splitHeaderRows hasFirstRowFormatting rs = bimap reverse reverse $ fst $ if hasFirstRowFormatting- then foldl' f ((take 1 rs, []), True) (drop 1 rs)- else foldl' f (([], []), False) rs+ then L.foldl' f ((take 1 rs, []), True) (drop 1 rs)+ else L.foldl' f (([], []), False) rs where f ((headerRows, bodyRows), previousRowWasHeader) r@(Docx.Row h cs) | h == HasTblHeader || (previousRowWasHeader && any isContinuationCell cs)@@ -836,7 +841,9 @@ alignments = case rows of [] -> replicate width Pandoc.AlignDefault Docx.Row _ cs : _ -> concatMap getAlignment cs- widths = map ColWidth grid+ widths = map (\n -> if n == 0+ then ColWidthDefault+ else ColWidth n) grid extStylesEnabled <- asks (isEnabled Ext_styles . docxOptions) let attr = case mbsty of
src/Text/Pandoc/Readers/Docx/Combine.hs view
@@ -52,12 +52,13 @@ -} -module Text.Pandoc.Readers.Docx.Combine ( smushInlines+module Text.Pandoc.Readers.Docx.Combine ( combineBlocks+ , smushInlines , smushBlocks ) where -import Data.List+import qualified Data.List as L import Data.Bifunctor import Data.Sequence ( ViewL (..), ViewR (..), viewl, viewr, spanr, spanl , (><), (|>) )@@ -135,9 +136,9 @@ combineSingletonInlines x y = let (xfs, xs) = unstackInlines x (yfs, ys) = unstackInlines y- shared = xfs `intersect` yfs- x_remaining = xfs \\ shared- y_remaining = yfs \\ shared+ shared = xfs `L.intersect` yfs+ x_remaining = xfs L.\\ shared+ y_remaining = yfs L.\\ shared x_rem_attr = filter isAttrModifier x_remaining y_rem_attr = filter isAttrModifier y_remaining in@@ -182,7 +183,7 @@ smushInlines :: [Inlines] -> Inlines smushInlines xs = combineInlines xs' mempty- where xs' = foldl' combineInlines mempty xs+ where xs' = L.foldl' combineInlines mempty xs smushBlocks :: [Blocks] -> Blocks-smushBlocks xs = foldl' combineBlocks mempty xs+smushBlocks xs = L.foldl' combineBlocks mempty xs
src/Text/Pandoc/Readers/Docx/Parse.hs view
@@ -67,7 +67,7 @@ import Control.Monad.Except import Control.Monad.Reader import Control.Monad.State.Strict-import Data.Bits ((.|.))+import Data.Bits ((.&.)) import qualified Data.ByteString.Lazy as B import Data.Char (chr, ord, readLitChar) import Data.List@@ -160,20 +160,54 @@ | isElem ns "w" "smartTag" element = concatMap (unwrapElement ns) (elChildren element) | isElem ns "w" "p" element- , textboxes@(_:_) <- findChildrenByName ns "w" "r" element >>=- findChildrenByName ns "mc" "AlternateContent" >>=- findChildrenByName ns "mc" "Fallback" >>=- findChildrenByName ns "w" "pict" >>=- findChildrenByName ns "v" "shape" >>=- findChildrenByName ns "v" "textbox" >>=- findChildrenByName ns "w" "txbxContent"- = concatMap (unwrapElement ns) (concatMap elChildren textboxes) -- handle #9214+ , _:_ <- findChildrenByName ns "w" "r" element >>= findTextboxes+ = let result = splitP (elContent element) [] -- handle #9214, #11053+ in [element{ elName = QName "textbox-image" Nothing Nothing+ , elContent = map Elem result }] | isElem ns "w" "r" element , Just fallback <- findChildByName ns "mc" "AlternateContent" element >>= findChildByName ns "mc" "Fallback" = [element{ elContent = concatMap (unwrapContent ns) (elContent fallback) }] | otherwise = [element{ elContent = concatMap (unwrapContent ns) (elContent element) }]+ where+ -- Split a w:p's children around textbox-bearing runs, preserving order.+ -- Non-textbox content is grouped into a copy of the original w:p;+ -- textbox content is unwrapped into sibling elements in place.+ splitP [] acc = [wrapP acc | hasContent acc]+ splitP (c:cs) acc+ | Elem el <- c+ , isElem ns "w" "r" el+ , tbs@(_:_) <- findTextboxes el+ = [wrapP acc | hasContent acc]+ ++ concatMap (unwrapElement ns) (concatMap elChildren tbs)+ ++ splitP cs []+ | otherwise+ = splitP cs (acc ++ [c])+ wrapP cs = element{ elContent = concatMap (unwrapContent ns) cs }+ hasContent = any (\case Elem el -> isElem ns "w" "r" el+ && any (isContentElem . elName)+ (elChildren el)+ _ -> False)+ isContentElem n = qName n `elem`+ ["t", "drawing", "pict", "br", "tab", "sym", "fldChar", "instrText"]+ -- Search textbox content in the run's effective children.+ -- If AlternateContent is present, use only the fallback branch,+ -- matching the w:r unwrapping logic and avoiding duplicate textbox+ -- extraction when both direct and fallback encodings are present.+ findRunFallback run =+ findChildByName ns "mc" "AlternateContent" run >>=+ findChildByName ns "mc" "Fallback"+ findTextboxes run =+ findTextboxContent =<<+ case findRunFallback run of+ Just fallback -> findChildrenByName ns "w" "pict" fallback+ Nothing -> findChildrenByName ns "w" "pict" run+ findTextboxContent pict =+ (findChildrenByName ns "v" "shape" pict <>+ findChildrenByName ns "v" "rect" pict) >>=+ findChildrenByName ns "v" "textbox" >>=+ findChildrenByName ns "w" "txbxContent" unwrapContent :: NameSpaces -> Content -> [Content] unwrapContent ns (Elem element) = map Elem $ unwrapElement ns element@@ -291,6 +325,9 @@ data Cell = Cell Align GridSpan VMerge [BodyPart] deriving Show +emptyCell :: Cell+emptyCell = Cell AlignDefault 1 Restart []+ type GridSpan = Integer data VMerge = Continue@@ -460,9 +497,17 @@ return $ Document namespaces body elemToBody :: NameSpaces -> Element -> D Body-elemToBody ns element | isElem ns "w" "body" element =- Body . addCaptioned <$> mapD (elemToBodyPart ns) (elChildren element)-elemToBody _ _ = throwError WrongElem+elemToBody ns element+ | isElem ns "w" "body" element =+ Body . addCaptioned <$> concatMapM (elemToBodyParts ns) (elChildren element)+ | otherwise = throwError WrongElem+ where+ elemToBodyParts ns' el+ | qName (elName el) == "textbox-image"+ = addSplitGroupCaptioned . splitMixedParagraphs+ <$> mapD (elemToBodyPart ns') (elChildren el)+ | otherwise+ = ((:[]) <$> elemToBodyPart ns' el) `catchError` (\_ -> return []) archiveToStyles :: Archive -> (CharStyleMap, ParStyleMap) archiveToStyles = archiveToStyles' getStyleId getStyleId@@ -525,22 +570,18 @@ then Just InDocument else Nothing -relElemToRelationship :: FilePath -> DocumentLocation -> Element+relElemToRelationship :: DocumentLocation -> Element -> Maybe Relationship-relElemToRelationship fp relType element | qName (elName element) == "Relationship" =+relElemToRelationship relType element | qName (elName element) == "Relationship" = do relId <- findAttr (QName "Id" Nothing Nothing) element target <- findAttr (QName "Target" Nothing Nothing) element- -- target may be relative (media/image1.jpeg) or absolute- -- (/word/media/image1.jpeg); we need to relativize it (see #7374)- let frontOfFp = T.pack $ takeWhile (/= '_') fp- let target' = fromMaybe target $- T.stripPrefix frontOfFp $ T.dropWhile (== '/') target- return $ Relationship relType relId target'-relElemToRelationship _ _ _ = Nothing+ -- target may be relative (media/image1.jpeg) or absolute (/word/media/image1.jpg)+ return $ Relationship relType relId target+relElemToRelationship _ _ = Nothing extractTarget :: Element -> Maybe Target-extractTarget element = do (Relationship _ _ target) <- relElemToRelationship "word/" InDocument element+extractTarget element = do (Relationship _ _ target) <- relElemToRelationship InDocument element return target filePathToRelationships :: Archive -> FilePath -> FilePath -> [Relationship]@@ -548,7 +589,7 @@ | Just relType <- filePathToRelType fp docXmlPath , Just entry <- findEntryByPath fp ar , Just relElems <- parseXMLFromEntry entry =- mapMaybe (relElemToRelationship fp relType) $ elChildren relElems+ mapMaybe (relElemToRelationship relType) $ elChildren relElems filePathToRelationships _ _ _ = [] archiveToRelationships :: Archive -> FilePath -> [Relationship]@@ -715,12 +756,21 @@ elemToRow :: NameSpaces -> Element -> D Row elemToRow ns element | isElem ns "w" "tr" element = do+ let properties = findChildByName ns "w" "trPr" element+ let gridBefore = properties+ >>= findChildByName ns "w" "gridBefore"+ >>= findAttrByName ns "w" "val"+ >>= stringToInteger let cellElems = findChildrenByName ns "w" "tc" element+ let beforeCells = genericReplicate (fromMaybe 0 gridBefore) emptyCell cells <- mapD (elemToCell ns) cellElems- let hasTblHeader = maybe NoTblHeader (const HasTblHeader)- (findChildByName ns "w" "trPr" element- >>= findChildByName ns "w" "tblHeader")- return $ Row hasTblHeader cells+ let hasTblHeader =+ case (properties >>= findChildByName ns "w" "tblHeader") of+ Nothing -> NoTblHeader+ Just he -> case findAttrByName ns "w" "val" he of+ Just "0" -> NoTblHeader+ _ -> HasTblHeader+ return $ Row hasTblHeader (beforeCells ++ cells) elemToRow _ _ = throwError WrongElem elemToCell :: NameSpaces -> Element -> D Cell@@ -757,7 +807,7 @@ testBitMask bitMaskS n = case (reads ("0x" ++ T.unpack bitMaskS) :: [(Int, String)]) of [] -> False- ((n', _) : _) -> (n' .|. n) /= 0+ ((n', _) : _) -> (n' .&. n) /= 0 pHeading :: ParagraphStyle -> Maybe (ParaStyleName, Int) pHeading = getParStyleField headingLev . pStyle@@ -786,6 +836,28 @@ = Captioned parstyle parparts x : addCaptioned xs addCaptioned (x:xs) = x : addCaptioned xs +-- Split paragraphs that contain both a Drawing and text into two body parts,+-- so that the captioning logic can combine them.+splitMixedParagraphs :: [BodyPart] -> [BodyPart]+splitMixedParagraphs [] = []+splitMixedParagraphs (Paragraph ps parts : rest)+ | (drawings@(_:_), texts@(_:_)) <- partition isDrawingPart parts+ = Paragraph ps drawings : Paragraph ps texts : splitMixedParagraphs rest+ where isDrawingPart Drawing{} = True+ isDrawingPart _ = False+splitMixedParagraphs (x:xs) = x : splitMixedParagraphs xs++-- For textbox-image groups: combine image + any adjacent text into Captioned+addSplitGroupCaptioned :: [BodyPart] -> [BodyPart]+addSplitGroupCaptioned [] = []+addSplitGroupCaptioned (Paragraph parstyle parparts : x : xs)+ | isCaptionable x+ = Captioned parstyle parparts x : addSplitGroupCaptioned xs+addSplitGroupCaptioned (x : Paragraph parstyle parparts : xs)+ | isCaptionable x+ = Captioned parstyle parparts x : addSplitGroupCaptioned xs+addSplitGroupCaptioned (x:xs) = x : addSplitGroupCaptioned xs+ isCaptionable :: BodyPart -> Bool isCaptionable (Paragraph _ [Drawing{}]) = True isCaptionable (Tbl{}) = True@@ -875,9 +947,15 @@ Just l -> elemToTblLook ns l Nothing -> return defaultTblLook - grid <- grid'+ grid'' <- grid' tblLook <- tblLook' rows <- mapD (elemToRow ns) (elChildren element)+ let grid = if null grid''+ then let numcols = case rowsToRowspans rows of+ (cs@(_:_):_) -> sum (map fst cs)+ _ -> 0+ in replicate numcols 0.0+ else grid'' return $ Tbl mbstyle (caption <> description) grid tblLook rows elemToBodyPart _ _ = throwError WrongElem @@ -907,11 +985,23 @@ case target of Just filepath -> do media <- asks envMedia- let filepath' = case filepath of- ('/':rest) -> rest- _ -> "word/" ++ filepath+ -- the mediaName is the name we store it under in the mediabag.+ -- This is derived from the path, which might be absolute, e.g. /media/foo.jpg,+ -- or relative, media/foo.jpg (interpreted as /word/media/foo.jpg).+ -- The mediaName will strip off any leading `/` or `word/`.+ -- We assume here that the media will not be stored *both* in+ -- /media and in /word/media, which would lead to a name conflict+ -- given the scheme here for generating a mediaName.+ let (filepath', mediaName) =+ case filepath of+ ('/':rest) -- absolute path e.g. /media/foo.jpg+ -> (rest, case stripPrefix "word/" rest of+ Just rest' -> rest'+ Nothing -> rest)+ _ -- rel path to word, e.g. media/foo.jpg+ -> ("word/" ++ filepath, filepath) case lookup filepath' media of- Just bs -> return (filepath, bs)+ Just bs -> return (mediaName, bs) Nothing -> throwError DocxError Nothing -> throwError DocxError @@ -1147,7 +1237,7 @@ (Just w, Just h) -> Just (w, h) _ -> Nothing where- getDim at = filterElementName (\n -> qName n `elem` ["extent", "ext"]) el+ getDim at = filterElementName (\n -> qName n == "extent") el >>= findAttr (QName at Nothing Nothing) >>= safeRead
src/Text/Pandoc/Readers/EndNote.hs view
@@ -81,6 +81,7 @@ let items = map toCitationItem $ filterElementsName (name "Cite") tree return $ Citeproc.Citation{ Citeproc.citationId = Nothing+ , Citeproc.citationResetPosition = False , Citeproc.citationPrefix = Nothing , Citeproc.citationSuffix = Nothing , Citeproc.citationNoteNumber = Nothing
src/Text/Pandoc/Readers/HTML.hs view
@@ -33,9 +33,8 @@ import Data.Default (Default (..), def) import Data.Foldable (for_) import Data.List.Split (splitWhen)-import Data.List (foldl')+import qualified Data.List as L import qualified Data.Map as M-import Data.Maybe (fromMaybe, isJust, isNothing) import Data.Either (partitionEithers) import Data.Monoid (First (..)) import qualified Data.Set as Set@@ -70,6 +69,7 @@ import Text.Pandoc.Walk import Text.TeXMath (readMathML, writeTeX) import qualified Data.Sequence as Seq+import Data.Maybe (fromMaybe, isJust) -- | Convert HTML-formatted string to 'Pandoc' document. readHtml :: (PandocMonad m, ToSources a)@@ -237,12 +237,13 @@ -> pLineBlock | otherwise -> pDiv+ "aside" -> pDiv "section" -> pDiv "header" -> pDiv "main" -> pDiv "figure" -> pFigure "iframe" -> pIframe- "style" -> mempty <$ pHtmlBlock "style" -- see #10643+ "style" -> pRawHtmlBlock "textarea" -> pRawHtmlBlock "switch" | epubExts@@ -444,9 +445,9 @@ terms <- many1 (try $ skipMany nonItem >> pInTags "dt" inline) defs <- many1 (try $ skipMany nonItem >> pInTags "dd" block) skipMany nonItem- let term = foldl' (\x y -> if null x- then trimInlines y- else x <> B.linebreak <> trimInlines y)+ let term = L.foldl' (\x y -> if null x+ then trimInlines y+ else x <> B.linebreak <> trimInlines y) mempty terms return (term, map (fixPlains True) defs) @@ -489,6 +490,7 @@ isDivLike "section" = True isDivLike "header" = True isDivLike "main" = True+isDivLike "aside" = True isDivLike _ = False pDiv :: PandocMonad m => TagParser m Blocks@@ -502,12 +504,13 @@ | hident == ident -> B.Many $ Header lev ("",hclasses,hkvs) ils Seq.<| rest _ -> contents- let classes' = if tag == "section"- then "section":classes- else classes- kvs' = if tag == "main" && isNothing (lookup "role" kvs)- then ("role", "main"):kvs- else kvs+ let (classes', kvs') =+ case tag of+ "section" -> ("section":classes, kvs)+ "aside" -> ("aside":classes, kvs)+ "header" -> ("header":classes, kvs)+ "main" | Nothing <- lookup "role" kvs -> (classes, ("role", "main"):kvs)+ _ -> (classes, kvs) return $ B.divWith (ident, classes', kvs') contents' pIframe :: PandocMonad m => TagParser m Blocks@@ -538,7 +541,7 @@ pRawHtmlBlock :: PandocMonad m => TagParser m Blocks pRawHtmlBlock = do- raw <- pHtmlBlock "script" <|> pHtmlBlock "textarea"+ raw <- pHtmlBlock "script" <|> pHtmlBlock "style" <|> pHtmlBlock "textarea" <|> pRawTag exts <- getOption readerExtensions if extensionEnabled Ext_raw_html exts && not (T.null raw)@@ -713,7 +716,7 @@ "input" | lookup "type" attr == Just "checkbox" -> asks inListItem >>= guard >> pCheckbox- "style" -> mempty <$ pHtmlBlock "style" -- see #10643+ "style" -> B.rawInline "html" <$> pHtmlBlock "style" "script" | Just x <- lookup "type" attr , "math/tex" `T.isPrefixOf` x -> pScriptMath
src/Text/Pandoc/Readers/HTML/Table.hs view
@@ -20,7 +20,7 @@ import Data.Maybe (fromMaybe, isJust) import Data.Either (lefts, rights) import Data.List.NonEmpty (nonEmpty)-import Data.List (foldl')+import qualified Data.List as L import Data.Text (Text) import Text.HTML.TagSoup import Text.Pandoc.Builder (Blocks)@@ -204,9 +204,9 @@ let adjustRowHeadCols headcolsv (currentrow, (numheads, Row _ cells)) =- foldl' (adjustRowHeadColsForCell currentrow) headcolsv+ L.foldl' (adjustRowHeadColsForCell currentrow) headcolsv (take numheads cells)- let headcols = foldl' adjustRowHeadCols+ let headcols = L.foldl' adjustRowHeadCols (V.replicate numrows (0 :: Int)) (zip [(0 :: Int)..] rows) let rowHeadCols = case V.uncons headcols of
src/Text/Pandoc/Readers/JATS.hs view
@@ -21,7 +21,7 @@ import Data.Char (isDigit, isSpace) import Data.Default import Data.Generics-import Data.List (foldl', intersperse)+import qualified Data.List as L import qualified Data.Map as Map import Data.Maybe (maybeToList, fromMaybe, catMaybes) import Data.Text (Text)@@ -31,7 +31,7 @@ import Text.Pandoc.Builder import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Options-import Text.Pandoc.Shared (safeRead, extractSpaces)+import Text.Pandoc.Shared (safeRead) import Text.Pandoc.Walk (walk) import Text.Pandoc.XML.Light import Text.TeXMath (readMathML, writeTeX)@@ -290,11 +290,11 @@ let items = filterChildren (named "def") e' terms' <- mapM getInlines terms items' <- mapM getBlocks items- return (mconcat $ intersperse (str "; ") terms', items')+ return (mconcat $ L.intersperse (str "; ") terms', items') parseFigure = do modify $ \st -> st{ jatsInFigure = True } capt <- case filterChild (named "caption") e of- Just t -> mconcat . intersperse linebreak <$>+ Just t -> mconcat . L.intersperse linebreak <$> mapM getInlines (filterChildren (const True) t) Nothing -> return mempty contents <- getBlocks e@@ -350,7 +350,7 @@ n <- safeRead $ "0" <> T.filter (\x -> isDigit x || x == '.') w if n > 0 then Just n else Nothing let firstBody = fromMaybe [] (headMay multipleBodyRowElements)- let numrows = foldl' max 0 $ map length firstBody+ let numrows = L.foldl' max 0 $ map length firstBody let aligns = case colspecs of [] -> replicate numrows AlignDefault cs -> map toAlignment cs@@ -733,8 +733,7 @@ "fn" -> note . mconcat <$> mapM parseBlock (elContent e) _ -> innerInlines id- where innerInlines f = extractSpaces f . mconcat <$>- mapM parseInline (elContent e)+ where innerInlines f = f . mconcat <$> mapM parseInline (elContent e) codeWithLang = do let classes' = case attrValue "language" e of "" -> []
src/Text/Pandoc/Readers/LaTeX.hs view
@@ -110,6 +110,7 @@ (if bottomLevel < 1 then walk (adjustHeaders (1 - bottomLevel)) else id) $+ walk (resolveFootnoteMarks (sFootnoteTexts st)) $ walk (resolveRefs (sLabels st)) doc' return $ Pandoc meta bs' @@ -124,7 +125,19 @@ _ -> x resolveRefs _ x = x +-- | Resolve footnote marks (\footnotemark) to actual notes using+-- the footnote texts collected from \footnotetext commands.+resolveFootnoteMarks :: M.Map Int Blocks -> Inline -> Inline+resolveFootnoteMarks fnTexts (Span (_, classes, kvs) _)+ | "footnote-mark" `elem` classes+ , Just numText <- lookup "note-num" kvs+ , [(n, "")] <- reads (T.unpack numText)+ = case M.lookup n fnTexts of+ Just contents -> Note (toList contents)+ Nothing -> Str "" -- No matching footnotetext found+resolveFootnoteMarks _ x = x + -- testParser :: LP PandocIO a -> Text -> IO a -- testParser p t = do -- res <- runIOorExplode (runParserT p defaultLaTeXState{@@ -407,6 +420,8 @@ , ("lowercase", makeLowercase <$> tok) , ("thanks", skipopts >> note <$> grouped block) , ("footnote", skipopts >> footnote)+ , ("footnotemark", footnotemark)+ , ("footnotetext", footnotetext) , ("newline", pure B.linebreak) , ("passthrough", fixPassthroughEscapes <$> tok) -- \passthrough macro used by latex writer@@ -477,6 +492,39 @@ contents <- grouped block >>= walkM resolveNoteLabel return $ note contents +-- | Parse \footnotemark[n]. If n is not given, increment the counter.+-- Returns a span marker that will be resolved to a Note later.+footnotemark :: PandocMonad m => LP m Inlines+footnotemark = do+ mbNum <- optionalFootnoteNum+ noteNum <- case mbNum of+ Just n -> return n+ Nothing -> do+ updateState $ \st -> st{ sLastNoteNum = sLastNoteNum st + 1 }+ sLastNoteNum <$> getState+ return $ B.spanWith ("", ["footnote-mark"], [("note-num", tshow noteNum)]) mempty++-- | Parse \footnotetext[n]{text}. If n is not given, use current counter.+-- Stores the text in state to be resolved later.+footnotetext :: PandocMonad m => LP m Inlines+footnotetext = do+ mbNum <- optionalFootnoteNum+ noteNum <- case mbNum of+ Just n -> return n+ Nothing -> sLastNoteNum <$> getState+ contents <- grouped block >>= walkM resolveNoteLabel+ updateState $ \st -> st{+ sFootnoteTexts = M.insert noteNum contents (sFootnoteTexts st) }+ return mempty++-- | Parse optional footnote number argument [n]+optionalFootnoteNum :: PandocMonad m => LP m (Maybe Int)+optionalFootnoteNum = option Nothing $ do+ t <- bracketedToks+ case reads (T.unpack $ untokenize t) of+ [(n, "")] -> return $ Just n+ _ -> return Nothing+ resolveNoteLabel :: PandocMonad m => Inline -> LP m Inline resolveNoteLabel (Span (_,cls,kvs) _) | Just lab <- lookup "label" kvs = do@@ -937,7 +985,7 @@ , ("address", mempty <$ (skipopts *> tok >>= addMeta "address")) , ("signature", mempty <$ (skipopts *> authors)) , ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))- , ("newtheorem", newtheorem inline)+ , ("newtheorem", newtheorem) , ("theoremstyle", theoremstyle) -- KOMA-Script metadata commands , ("extratitle", mempty <$ (skipopts *> tok >>= addMeta "extratitle"))@@ -1108,7 +1156,7 @@ name <- untokenize <$> braced M.findWithDefault mzero name environments <|> langEnvironment name <|>- theoremEnvironment blocks opt name <|>+ theoremEnvironment blocks inlines opt name <|> if M.member name (inlineEnvironments :: M.Map Text (LP PandocPure Inlines)) then mzero
src/Text/Pandoc/Readers/LaTeX/Inline.hs view
@@ -315,6 +315,26 @@ , ("dothyp", lit ".\173") , ("colonhyp", lit ":\173") , ("hyp", lit "-")+ -- ngerman (babel)+ , ("glq", lit "‚")+ , ("grq", lit "‘")+ , ("glqq", lit "„")+ , ("grqq", lit "“")+ , ("flq", lit "‹")+ , ("frq", lit "›")+ , ("flqq", lit "«")+ , ("frqq", lit "»")+ , ("dq", lit "\"")+ -- fontspec+ , ("guillemetleft", lit "«")+ , ("guillemotleft", lit "«")+ , ("guillemetright", lit "»")+ , ("guillemotright", lit "»")+ , ("guilsinglleft", lit "‹")+ , ("guilsinglright", lit "›")+ , ("quotedblbase", lit "„")+ , ("quotesinglbase", lit ",")+ , ("textquotedbl", lit "\"") ] biblatexInlineCommands :: PandocMonad m
src/Text/Pandoc/Readers/LaTeX/Math.hs view
@@ -14,7 +14,7 @@ ) where import Data.Maybe (fromMaybe, mapMaybe, listToMaybe)-import Data.List (foldl')+import qualified Data.List as L import Text.Pandoc.Walk (walk) import Text.Pandoc.Builder as B import qualified Data.Sequence as Seq@@ -135,14 +135,14 @@ Just sty -> updateState $ \s -> s{ sLastTheoremStyle = sty } return mempty -newtheorem :: PandocMonad m => LP m Inlines -> LP m Blocks-newtheorem inline = do+newtheorem :: PandocMonad m => LP m Blocks+newtheorem = do number <- option True (False <$ symbol '*' <* sp) name <- untokenize <$> braced sp series <- option Nothing $ Just . untokenize <$> bracketedToks sp- showName <- tokWith inline+ showName <- braced <|> ((:[]) <$> anyTok) sp syncTo <- option Nothing $ Just . untokenize <$> bracketedToks sty <- sLastTheoremStyle <$> getState@@ -160,7 +160,7 @@ extractLabelFromBlock :: Block -> Maybe Text extractLabelFromBlock (Para inlines) = extractLabel Nothing inlines where- extractLabel = foldl' go+ extractLabel = L.foldl' go go :: Maybe Text -> Inline -> Maybe Text go (Just t) _ = Just t go Nothing (Span (_, _, attrs) _) = lookup "label" attrs@@ -168,8 +168,12 @@ extractLabelFromBlock _ = Nothing theoremEnvironment :: PandocMonad m- => LP m Blocks -> LP m Inlines -> Text -> LP m Blocks-theoremEnvironment blocks opt name = do+ => LP m Blocks+ -> LP m Inlines+ -> LP m Inlines+ -> Text+ -> LP m Blocks+theoremEnvironment blocks inlines opt name = do resetCaption tmap <- sTheoremMap <$> getState case M.lookup name tmap of@@ -206,7 +210,8 @@ PlainStyle -> B.strong DefinitionStyle -> B.strong RemarkStyle -> B.emph- let title = titleEmph (theoremName tspec <> number)+ tname <- parseFromToks inlines (theoremName tspec)+ let title = titleEmph (tname <> number) <> optTitle <> "." <> space return $ divWith (fromMaybe "" mblabel, [name], []) $ addTitle title
src/Text/Pandoc/Readers/LaTeX/Parsing.hs view
@@ -141,7 +141,7 @@ data TheoremSpec = TheoremSpec- { theoremName :: Inlines+ { theoremName :: [Tok] , theoremStyle :: TheoremStyle , theoremSeries :: Maybe Text , theoremSyncTo :: Maybe Text@@ -165,6 +165,7 @@ , sLastFigureNum :: DottedNum , sLastTableNum :: DottedNum , sLastNoteNum :: Int+ , sFootnoteTexts :: M.Map Int Blocks , sTheoremMap :: M.Map Text TheoremSpec , sLastTheoremStyle :: TheoremStyle , sLastLabel :: Maybe Text@@ -195,6 +196,7 @@ , sLastFigureNum = DottedNum [] , sLastTableNum = DottedNum [] , sLastNoteNum = 0+ , sFootnoteTexts = M.empty , sTheoremMap = M.empty , sLastTheoremStyle = PlainStyle , sLastLabel = Nothing
src/Text/Pandoc/Readers/LaTeX/Table.hs view
@@ -35,6 +35,8 @@ , ("tabular*", env "tabular*" $ simpTable block inline "tabular*" True) , ("tabularx", env "tabularx" $ simpTable block inline "tabularx" True) , ("tabular", env "tabular" $ simpTable block inline "tabular" False)+ , ("supertabular", env "supertabular" $ simpTable block inline "supertabular" False)+ , ("supertabular*", env "supertabular*" $ simpTable block inline "supertabular*" False) ] where blocks = mconcat <$> many block@@ -377,14 +379,6 @@ ((_,classes,kvs), Just ident) -> (ident,classes,kvs) _ -> attr- return $ addAttrDiv attr'- $ maybe id removeLabel mblabel- $ Table nullAttr capt spec th tb tf+ return $ maybe id removeLabel mblabel+ $ Table attr' capt spec th tb tf go x = return x---- TODO: For now we add a Div to contain table attributes, since--- most writers don't do anything yet with attributes on Table.--- This can be removed when that changes.-addAttrDiv :: Attr -> Block -> Block-addAttrDiv ("",[],[]) b = b-addAttrDiv attr b = Div attr [b]
src/Text/Pandoc/Readers/Man.hs view
@@ -26,23 +26,40 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad(..), report) import Text.Pandoc.Logging (LogMessage(..)) import Text.Pandoc.Options+import Text.Pandoc.Parsing.Capabilities import Text.Pandoc.Parsing import Text.Pandoc.Walk (query) import Text.Pandoc.Readers.Roff -- TODO explicit imports import qualified Text.Pandoc.Parsing as P import qualified Data.Foldable as Foldable+import qualified Data.Set as Set import Text.Pandoc.Shared (extractSpaces) data ManState = ManState { readerOptions :: ReaderOptions+ , manLogMessages :: []LogMessage+ , manIdentifiers :: Set.Set T.Text , metadata :: Meta , tableCellsPlain :: Bool } deriving Show instance Default ManState where def = ManState { readerOptions = def+ , manLogMessages = []+ , manIdentifiers = Set.empty , metadata = nullMeta , tableCellsPlain = True } +instance HasReaderOptions ManState where+ extractReaderOptions = readerOptions++instance HasLogMessages ManState where+ addLogMessage msg st = st{ manLogMessages = msg : manLogMessages st }+ getLogMessages st = reverse $ manLogMessages st++instance HasIdentifierList ManState where+ extractIdentifierList = manIdentifiers+ updateIdentifierList f st = st{ manIdentifiers = f $ manIdentifiers st }+ type ManParser m = P.ParsecT [RoffToken] ManState m @@ -74,6 +91,7 @@ bs <- many parseBlock <* eof meta <- metadata <$> getState let (Pandoc _ blocks) = doc $ mconcat bs+ reportLogMessages return $ Pandoc meta blocks parseBlock :: PandocMonad m => ManParser m Blocks@@ -200,9 +218,11 @@ isEmptyLine _ = False mmacro :: PandocMonad m => T.Text -> ManParser m RoffToken-mmacro mk = msatisfy isControlLine where- isControlLine (ControlLine mk' _ _) | mk == mk' = True- | otherwise = False+mmacro mk = mmacroMatching (== mk)++mmacroMatching :: PandocMonad m => (T.Text -> Bool) -> ManParser m RoffToken+mmacroMatching f = msatisfy isControlLine where+ isControlLine (ControlLine mk _ _) = f mk isControlLine _ = False mmacroAny :: PandocMonad m => ManParser m RoffToken@@ -415,8 +435,10 @@ else return $ mconcat $ intersperse B.space $ map linePartsToInlines args let lvl = if name == "SH" then 1 else 2- return $ header lvl contents+ attr <- registerHeader nullAttr contents + return $ B.headerWith attr lvl contents+ parseBlockQuote :: PandocMonad m => ManParser m Blocks parseBlockQuote = blockQuote <$> ( (mmacro "RS" *> (mconcat <$> manyTill parseBlock (endmacro "RE")))@@ -479,7 +501,12 @@ continuation :: PandocMonad m => ManParser m Blocks continuation = (mmacro "RS" *> (mconcat <$> manyTill parseBlock (endmacro "RE")))- <|> try ((memptyLine <|> bareIP) *> (parsePara <|> parseCodeBlock))+ <|> (bareIP *> parsePara)+ <|> (notFollowedBy (mmacroMatching+ (`elem` ["TP","IP","LP","P","PP","HP",+ "RE","RS","SH","SS","SV","YS","TH",+ "TQ","YS","AT","DT","OP","PD","UC"]))+ *> parseBlock) definitionListItem :: PandocMonad m => ManParser m (Inlines, [Blocks])
src/Text/Pandoc/Readers/Markdown.hs view
@@ -24,7 +24,8 @@ import Control.Monad.Except (throwError) import qualified Data.Bifunctor as Bifunctor import Data.Char (isAlphaNum, isPunctuation, isSpace)-import Data.List (transpose, elemIndex, sortOn, foldl')+import Data.List (transpose, elemIndex, sortOn)+import qualified Data.List as L import qualified Data.Map as M import Data.Maybe import qualified Data.Set as Set@@ -42,7 +43,6 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad (..), report) import Text.Pandoc.Definition as Pandoc import Text.Pandoc.Emoji (emojiToInline)-import Text.Pandoc.Error import Safe.Foldable (maximumBounded) import Text.Pandoc.Logging import Text.Pandoc.Options@@ -198,6 +198,7 @@ litCharNoSpace :: PandocMonad m => MarkdownParser m Text litCharNoSpace = T.singleton <$> escapedChar'' <|> characterReference+ <|> (snd <$> withRaw attributes) <|> T.singleton <$> noneOf "\n \r\t" where escapedChar'' = do@@ -351,13 +352,9 @@ checkNotes = do st <- getState let notesUsed = stateNoteRefs st- let notesDefined = M.keys (stateNotes' st)- mapM_ (\n -> unless (n `Set.member` notesUsed) $- case M.lookup n (stateNotes' st) of- Just (pos, _) -> report (NoteDefinedButNotUsed n pos)- Nothing -> throwError $- PandocShouldNeverHappenError "note not found")- notesDefined+ forM_ (M.toList (stateNotes' st)) $ \(n, (pos, _)) ->+ unless (n `Set.member` notesUsed) $+ report (NoteDefinedButNotUsed n pos) referenceKey :: PandocMonad m => MarkdownParser m (F Blocks)@@ -388,7 +385,7 @@ addKvs <- option [] $ guardEnabled Ext_mmd_link_attributes >> many (try $ spnl >> keyValAttr) blanklines- let attr' = extractIdClass $ foldl' (\x f -> f x) attr addKvs+ let attr' = extractIdClass $ L.foldl' (\x f -> f x) attr addKvs target = (escapeURI $ trimr src, tit) st <- getState let oldkeys = stateKeys st@@ -648,7 +645,7 @@ spnl attrs <- many (attribute <* spnl) char '}'- return $ foldl' (\x f -> f x) nullAttr attrs+ return $ L.foldl' (\x f -> f x) nullAttr attrs attribute :: PandocMonad m => MarkdownParser m (Attr -> Attr) attribute = identifierAttr <|> classAttr <|> keyValAttr <|> specialAttr@@ -780,7 +777,7 @@ when (sourceColumn pos /= 1) $ Prelude.fail "Not in first column" lns <- many1 $ birdTrackLine c -- if (as is normal) there is always a space after >, drop it- let lns' = if all (\ln -> T.null ln || T.take 1 ln == " ") lns+ let lns' = if all (\ln -> T.null ln || T.head ln == ' ') lns then map (T.drop 1) lns else lns blanklines@@ -817,9 +814,28 @@ blockQuote :: PandocMonad m => MarkdownParser m (F Blocks) blockQuote = do raw <- emailBlockQuote+ (mbAlert, raw') <-+ (do guardEnabled Ext_alerts+ case raw of+ (t:ts) | "[!" `T.isPrefixOf` t ->+ case T.strip t of+ "[!TIP]" -> pure (Just "tip", ts)+ "[!WARNING]" -> pure (Just "warning", ts)+ "[!IMPORTANT]" -> pure (Just "important", ts)+ "[!CAUTION]" -> pure (Just "caution", ts)+ "[!NOTE]" -> pure (Just "note", ts)+ _ -> pure (Nothing, raw)+ _ -> pure (Nothing, raw))+ <|> pure (Nothing, raw) -- parse the extracted block, which may contain various block elements:- contents <- parseFromString' parseBlocks $ T.intercalate "\n" raw <> "\n\n"- return $ B.blockQuote <$> contents+ contents <- parseFromString' parseBlocks $ T.intercalate "\n" raw' <> "\n\n"+ return $+ case mbAlert of+ Nothing -> B.blockQuote <$> contents+ Just alert ->+ (B.divWith ("", [alert], [])+ . (B.divWith ("", ["title"], []) (B.para (B.str (T.toTitle alert))) <>))+ <$> contents -- -- list blocks@@ -1053,8 +1069,7 @@ <* lookAhead header) <|> (guardEnabled Ext_lists_without_preceding_blankline -- Avoid creating a paragraph in a nested list.- <* notFollowedBy' inList- <* lookAhead listStart)+ <* notFollowedBy' (inList <* listStart)) <|> do guardEnabled Ext_native_divs inHtmlBlock <- stateInHtmlBlock <$> getState case inHtmlBlock of@@ -1148,7 +1163,7 @@ many1 ((<>) <$> rawLaTeXBlock <*> spnl')) return $ case B.toList result of [RawBlock _ cs]- | T.all (`elem` [' ','\t','\n']) cs -> return mempty+ | T.all (\c -> c == ' ' || c == '\t' || c == '\n') cs -> return mempty -- don't create a raw block for suppressed macro defs _ -> return result @@ -1184,7 +1199,9 @@ return (return (B.rawBlock "html" $ stripMarkdownAttribute raw) <> contents <> return (B.rawBlock "html" rawcloser)))- <|> return (return (B.rawBlock "html" raw) <> contents)+ <|> if T.all isSpace raw+ then return mempty+ else return (return (B.rawBlock "html" raw) <> contents) updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock } return result @@ -1386,7 +1403,20 @@ -- ending with a footer (dashed line followed by blank line). gridTable :: PandocMonad m => MarkdownParser m (F TableComponents)-gridTable = gridTableWith' NormalizeHeader parseBlocks+gridTable = try $ do+ -- Like other block-level constructs, a grid table may be indented by+ -- up to three spaces. The underlying grid-table parser expects the+ -- table to begin at the left margin, so strip a uniform indentation+ -- from every line before handing it off.+ indent <- T.length <$> lookAhead nonindentSpaces+ if indent == 0+ then gridTableWith' NormalizeHeader parseBlocks+ else do+ let gridLine = try $ count indent (char ' ')+ *> lookAhead (oneOf "+|")+ *> anyLineNewline+ rawTable <- T.concat <$> many1 gridLine+ parseFromString' (gridTableWith' NormalizeHeader parseBlocks) rawTable pipeBreak :: PandocMonad m => MarkdownParser m ([Alignment], [Int]) pipeBreak = try $ do@@ -1588,7 +1618,7 @@ guardEnabled Ext_example_lists try $ do char '@'- lab <- mconcat . map T.pack <$>+ lab <- T.pack . concat <$> many (many1 alphaNum <|> try (do c <- char '_' <|> char '-' cs <- many1 alphaNum@@ -1867,7 +1897,7 @@ (before, after) | titleAfter -> (T.drop 1 after, before) | otherwise -> (before, T.drop 1 after)- guard $ T.all (`notElem` ['\n','\r','\f','\t']) url+ guard $ T.all (\c -> c /= '\n' && c /= '\r' && c /= '\f' && c /= '\t') url return . pure . constructor attr url "" $ B.text $ fromEntities title @@ -1912,7 +1942,7 @@ isSmallCapsFontVariant :: Text -> Bool isSmallCapsFontVariant s =- T.toLower (T.filter (`notElem` [' ', '\t', ';']) s) ==+ T.toLower (T.filter (\c -> c /= ' ' && c /= '\t' && c /= ';') s) == "font-variant:small-caps" regLink :: PandocMonad m@@ -2071,8 +2101,9 @@ char '^' updateState $ \st -> st{ stateInNote = True , stateNoteNumber = stateNoteNumber st + 1 }- contents <- inBalancedBrackets inlines- notFollowedBy (char '(' <|> char '[') -- ^[link](foo)^ is superscript+ contents <- withQuoteContext NoQuote $ inBalancedBrackets inlines+ notFollowedBy (char '(' <|> char '[' <|> ('{' <$ attributes))+ -- ^[link](foo)^ is superscript updateState $ \st -> st{ stateInNote = False } return $ B.note . B.para <$> contents @@ -2174,7 +2205,9 @@ then (\x -> isInlineTag x && not (isCloseBlockTag x)) else not . isTextTag- return $ return $ B.rawInline "html" result+ return $ if T.all isSpace result+ then return mempty+ else return $ B.rawInline "html" result -- Emoji
src/Text/Pandoc/Readers/MediaWiki.hs view
@@ -13,7 +13,7 @@ {- TODO: _ correctly handle tables within tables-_ parse templates?+_ parse templates(?) and built-in magic words -} module Text.Pandoc.Readers.MediaWiki ( readMediaWiki ) where @@ -28,17 +28,17 @@ import Data.Text (Text) import qualified Data.Text as T import Text.HTML.TagSoup-import Text.Pandoc.Builder (Blocks, Inlines, trimInlines) import qualified Text.Pandoc.Builder as B+import Text.Pandoc.Builder (Blocks, Inlines, trimInlines)+import Text.Pandoc.Char (isCJK) import Text.Pandoc.Class.PandocMonad (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Logging import Text.Pandoc.Options import Text.Pandoc.Parsing hiding (tableCaption)-import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isCommentTag, toAttr)-import Text.Pandoc.Shared (safeRead, stringify, stripTrailingNewlines,- trim, splitTextBy, tshow, formatCode)-import Text.Pandoc.Char (isCJK)+import Text.Pandoc.Readers.HTML (htmlTag, isCommentTag, toAttr)+import Text.Pandoc.Shared (formatCode, safeRead, splitTextBy, stringify,+ stripTrailingNewlines, trim, tshow) import Text.Pandoc.XML (fromEntities) -- | Read mediawiki from an input string and return a Pandoc document.@@ -56,6 +56,7 @@ , mwLogMessages = [] , mwInTT = False , mwAllowNewlines = True+ , mwMeta = nullMeta } sources case parsed of@@ -70,6 +71,7 @@ , mwLogMessages :: [LogMessage] , mwInTT :: Bool , mwAllowNewlines :: Bool+ , mwMeta :: Meta } type MWParser m = ParsecT Sources MWState m@@ -90,7 +92,7 @@ -- specialChars :: [Char]-specialChars = "'[]<=&*{}|\":\\"+specialChars = "'[]<=&*{}|\":\\_" spaceChars :: [Char] spaceChars = " \n\t"@@ -102,21 +104,86 @@ newBlockTags = ["haskell","syntaxhighlight","source","gallery","references"] isBlockTag' :: Tag Text -> Bool-isBlockTag' tag@(TagOpen t _) = (isBlockTag tag || t `elem` newBlockTags) &&- t `notElem` eitherBlockOrInline-isBlockTag' (TagClose "ref") = True -- needed so 'special' doesn't parse it-isBlockTag' tag@(TagClose t) = (isBlockTag tag || t `elem` newBlockTags) &&- t `notElem` eitherBlockOrInline-isBlockTag' tag = isBlockTag tag+isBlockTag' (TagOpen t _) = isBlockTagName t+isBlockTag' (TagClose t) = isBlockTagName t+isBlockTag' _ = False +isBlockTagName :: Text -> Bool+isBlockTagName t =+ t `elem` [ "blockquote"+ , "caption"+ , "col"+ , "colgroup"+ , "dd"+ , "div"+ , "dl"+ , "dt"+ , "h1"+ , "h2"+ , "h3"+ , "h4"+ , "h5"+ , "h6"+ , "hr"+ , "li"+ , "meta"+ , "ol"+ , "p"+ , "pre"+ , "rp"+ , "table"+ , "td"+ , "th"+ , "time"+ , "tr"+ , "ul"+ , "center"+ ] || t `elem` newBlockTags+ isInlineTag' :: Tag Text -> Bool isInlineTag' (TagComment _) = True-isInlineTag' (TagClose "ref") = False -- see below inlineTag-isInlineTag' t = not (isBlockTag' t)+isInlineTag' (TagOpen t _) = isInlineTagName t+isInlineTag' (TagClose t) = isInlineTagName t+isInlineTag' _ = False -eitherBlockOrInline :: [Text]-eitherBlockOrInline = ["applet", "button", "del", "iframe", "ins",- "map", "area", "object"]+isInlineTagName :: Text -> Bool+isInlineTagName t =+ t `elem` [ "abbr"+ , "b"+ , "bdi"+ , "bdo"+ , "big"+ , "br"+ , "cite"+ , "code"+ , "data"+ , "del"+ , "dfn"+ , "em"+ , "i"+ , "ins"+ , "kbd"+ , "link"+ , "mark"+ , "q"+ , "rt"+ , "ruby"+ , "s"+ , "samp"+ , "small"+ , "span"+ , "strong"+ , "sub"+ , "sup"+ , "u"+ , "var"+ , "wbr"+ , "font"+ , "rb"+ , "rtc"+ , "strike"+ , "tt"+ ] htmlComment :: PandocMonad m => MWParser m () htmlComment = () <$ htmlTag isCommentTag@@ -160,11 +227,12 @@ spaces eof categoryLinks <- reverse . mwCategoryLinks <$> getState+ meta <- mwMeta <$> getState let categories = if null categoryLinks then mempty else B.para $ mconcat $ intersperse B.space categoryLinks reportLogMessages- return $ B.doc $ bs <> categories+ return $ Pandoc meta (B.toList bs <> B.toList categories) -- -- block parsers@@ -533,6 +601,7 @@ <|> doubleQuotes <|> strong <|> emph+ <|> behaviorSwitch <|> image <|> internalLink <|> externalLink@@ -571,7 +640,11 @@ inlineTag :: PandocMonad m => MWParser m Inlines inlineTag = do- (tag, _) <- lookAhead $ htmlTag isInlineTag'+ (tag, _) <- lookAhead $ htmlTag (\tag -> case tag of+ TagOpen "hask" _ -> True+ TagOpen "ref" _ -> True+ TagOpen "nowiki" _ -> True+ _ -> isInlineTag' tag) case tag of TagOpen "ref" _ -> B.note . singleParaToPlain <$> blocksInTags "ref" TagOpen "nowiki" _ -> try $ do@@ -586,6 +659,10 @@ TagOpen "del" _ -> B.strikeout <$> inlinesInTags "del" TagOpen "sub" _ -> B.subscript <$> inlinesInTags "sub" TagOpen "sup" _ -> B.superscript <$> inlinesInTags "sup"+ TagOpen "var" _ -> B.codeWith ("",["variable"],[]) <$> textInTags "var"+ TagOpen "samp" _ -> B.codeWith ("",["sample"],[]) <$> textInTags "samp"+ TagOpen "kbd" _ -> B.spanWith ("",["kbd"],[]) <$> inlinesInTags "kbd"+ TagOpen "mark" _ -> B.spanWith ("",["mark"],[]) <$> inlinesInTags "mark" TagOpen "code" _ -> encode <$> inlinesInTags "code" TagOpen "tt" _ -> do inTT <- mwInTT <$> getState@@ -597,8 +674,15 @@ _ -> B.rawInline "html" . snd <$> htmlTag (~== tag) special :: PandocMonad m => MWParser m Inlines-special = B.str <$> countChar 1 (notFollowedBy' (htmlTag isBlockTag') *>- oneOf specialChars)+special = B.str . T.singleton <$>+ (notFollowedBy' (htmlTag (\t -> isInlineTag' t ||+ isBlockTag' t ||+ case t of+ TagClose "ref" -> True+ TagClose "hask" -> True+ TagClose "nowiki" -> True+ _ -> False)+ ) *> oneOf specialChars) inlineHtml :: PandocMonad m => MWParser m Inlines inlineHtml = B.rawInline "html" . snd <$> htmlTag isInlineTag'@@ -716,3 +800,37 @@ B.doubleQuoted <$> inlinesBetween openDoubleQuote closeDoubleQuote where openDoubleQuote = sym "\"" >> lookAhead nonspaceChar closeDoubleQuote = try $ sym "\""++behaviorSwitch :: PandocMonad m => MWParser m Inlines+behaviorSwitch = try $ do+ let reservedMagicWords = [ "NOTOC"+ , "FORCETOC"+ , "TOC"+ , "NOEDITSECTION"+ , "NEWSECTIONLINK"+ , "NONEWSECTIONLINK"+ , "NOGALLERY"+ , "HIDDENCAT"+ , "EXPECTUNUSEDCATEGORY"+ , "NOCONTENTCONVERT"+ , "NOCC"+ , "NOTITLECONVERT"+ , "NOTC"+ , "INDEX"+ , "NOINDEX"+ , "STATICREDIRECT"+ , "EXPECTUNUSEDTEMPLATE"+ -- From popular extensions+ , "NOGLOBAL"+ , "DISAMBIG"+ , "ARCHIVEDTALK"+ , "NOTALK"+ ]+ string "__"+ name <- many1 alphaNum+ string "__"+ case name `elem` reservedMagicWords of+ True -> do+ updateState $ \st -> st{ mwMeta = B.setMeta (T.toLower $ T.pack name) True (mwMeta st) }+ return mempty+ False -> return $ B.str $ "__" <> T.pack name <> "__"
src/Text/Pandoc/Readers/ODT/Arrows/State.hs view
@@ -33,10 +33,10 @@ , iterateS' ) where +import qualified Data.List as L import Control.Arrow import qualified Control.Category as Cat import Control.Monad-import Data.List (foldl') import Text.Pandoc.Readers.ODT.Arrows.Utils import Text.Pandoc.Readers.ODT.Generic.Fallible @@ -136,7 +136,7 @@ iterateSL :: (Foldable f, MonadPlus m) => ArrowState s x y -> ArrowState s (f x) (m y)-iterateSL a = ArrowState $ \(s,f) -> foldl' a' (s,mzero) f+iterateSL a = ArrowState $ \(s,f) -> L.foldl' a' (s,mzero) f where a' (s',m) x = second (mplus m.return) $ runArrowState a (s',x)
src/Text/Pandoc/Readers/ODT/ContentReader.hs view
@@ -46,6 +46,8 @@ import Text.Pandoc.Extensions (extensionsFromList, Extension(..)) import qualified Text.Pandoc.UTF8 as UTF8 +import Text.Pandoc.Readers.Docx.Combine (combineBlocks)+ import Text.Pandoc.Readers.ODT.Base import Text.Pandoc.Readers.ODT.Namespaces import Text.Pandoc.Readers.ODT.StyleReader@@ -205,11 +207,11 @@ >>^ fst ---getCurrentListLevel :: ODTReaderSafe _x ListLevel+getCurrentListLevel :: ODTReaderSafe a ListLevel getCurrentListLevel = getExtraState >>^ currentListLevel ---getListContinuationStartCounters :: ODTReaderSafe _x (M.Map ListLevel Int)+getListContinuationStartCounters :: ODTReaderSafe a (M.Map ListLevel Int) getListContinuationStartCounters = getExtraState >>^ listContinuationStartCounters @@ -278,7 +280,7 @@ -------------------------------------------------------------------------------- ---readStyleByName :: ODTReader _x (StyleName, Style)+readStyleByName :: ODTReader a (StyleName, Style) readStyleByName = findAttr NsText "style-name" >>? keepingTheValue getStyleByName >>^ liftE where@@ -327,6 +329,7 @@ where isCodeStyle :: StyleName -> Bool isCodeStyle "Source_Text" = True+ isCodeStyle "Source_20_Text" = True isCodeStyle _ = False inlineCode :: Inlines -> Inlines@@ -415,7 +418,7 @@ = False ---constructPara :: ODTReaderSafe Blocks Blocks -> ODTReaderSafe Blocks Blocks+constructPara :: ODTReaderSafe a Blocks -> ODTReaderSafe a Blocks constructPara reader = proc blocks -> do fStyle <- readStyleByName -< blocks case fStyle of@@ -546,6 +549,14 @@ firstMatch :: a -> FirstMatch a firstMatch = FirstMatch . Alt . Just +newtype CombiningBlocks = CombiningBlocks { unCombiningBlocks :: Blocks }++instance Semigroup CombiningBlocks where+ CombiningBlocks l <> CombiningBlocks r = CombiningBlocks (combineBlocks l r)++instance Monoid CombiningBlocks where+ mempty = CombiningBlocks mempty+ -- matchingElement :: (Monoid e) => Namespace -> ElementName@@ -559,14 +570,20 @@ -- matchChildContent' :: (Monoid result) => [ElementMatcher result]- -> ODTReaderSafe _x result+ -> ODTReaderSafe a result matchChildContent' ls = returnV mempty >>> matchContent' ls --+matchSmushedChildBlocks' :: [ElementMatcher CombiningBlocks] -> ODTReaderSafe a Blocks+matchSmushedChildBlocks' ls = liftA unCombiningBlocks+ $ returnV mempty+ >>> matchContent' ls++-- matchChildContent :: (Monoid result) => [ElementMatcher result] -> ODTReaderSafe (result, XML.Content) result- -> ODTReaderSafe _x result+ -> ODTReaderSafe a result matchChildContent ls fallback = returnV mempty >>> matchContent ls fallback --------------------------------------------@@ -634,34 +651,46 @@ ] read_plain_text ---read_paragraph :: BlockMatcher-read_paragraph = matchingElement NsText "p"- $ constructPara- $ liftA para- $ withNewStyle- $ matchChildContent [ read_span- , read_spaces- , read_line_break- , read_tab- , read_link- , read_note- , read_citation- , read_bookmark- , read_bookmark_start- , read_reference_start- , read_bookmark_ref- , read_reference_ref- , read_frame- , read_text_seq- ] read_plain_text+read_paragraph :: ElementMatcher CombiningBlocks+read_paragraph = matchingElement NsText "p" $+ liftA CombiningBlocks $ proc blocks -> do+ fStyle <- readStyleByName -< blocks+ case fStyle of+ Right style | isPreformattedStyle style -> do+ liftA (codeBlock . stringify) $ matchParagraphContent -< blocks+ _ ->+ constructPara $ liftA para $ withNewStyle matchParagraphContent -< blocks+ where+ isPreformattedStyle :: (StyleName, Style) -> Bool+ isPreformattedStyle ("Preformatted_20_Text", _) = True+ isPreformattedStyle (_, Style { styleParentName = Just "Preformatted_20_Text" }) = True+ isPreformattedStyle _ = False +matchParagraphContent :: ODTReaderSafe a Inlines+matchParagraphContent = matchChildContent [ read_span+ , read_spaces+ , read_line_break+ , read_tab+ , read_link+ , read_note+ , read_citation+ , read_bookmark+ , read_bookmark_start+ , read_reference_start+ , read_bookmark_ref+ , read_reference_ref+ , read_frame+ , read_text_seq+ ] read_plain_text++ ---------------------- -- Headers ---------------------- ---read_header :: BlockMatcher+read_header :: ElementMatcher CombiningBlocks read_header = matchingElement NsText "h" $ proc blocks -> do level <- ( readAttrWithDefault NsText "outline-level" 1@@ -683,15 +712,16 @@ ) -< blocks anchor <- getHeaderAnchor -< children let idAttr = (anchor, [], []) -- no classes, no key-value pairs- arr (uncurry3 headerWith) -< (idAttr, level, children)+ arr (CombiningBlocks . uncurry3 headerWith) -< (idAttr, level, children) ---------------------- -- Lists ---------------------- ---read_list :: BlockMatcher+read_list :: ElementMatcher CombiningBlocks read_list = matchingElement NsText "list"+ $ liftA CombiningBlocks $ constructList $ matchChildContent' [ read_list_item , read_list_header@@ -706,26 +736,26 @@ read_list_element :: ElementName -> ElementMatcher [Blocks] read_list_element listElement = matchingElement NsText listElement $ liftA (compactify.(:[]))- ( matchChildContent' [ read_paragraph- , read_header- , read_list- , read_section- ]+ ( matchSmushedChildBlocks' [ read_paragraph+ , read_header+ , read_list+ , read_section+ ] ) ---------------------- -- Sections ---------------------- -read_section :: ElementMatcher Blocks+read_section :: ElementMatcher CombiningBlocks read_section = matchingElement NsText "section"- $ liftA (divWith nullAttr)- $ matchChildContent' [ read_paragraph- , read_header- , read_list- , read_table- , read_section- ]+ $ liftA (CombiningBlocks . divWith nullAttr)+ $ matchSmushedChildBlocks' [ read_paragraph+ , read_header+ , read_list+ , read_table+ , read_section+ ] ----------------------@@ -768,7 +798,7 @@ read_note_body :: BlockMatcher read_note_body = matchingElement NsText "note-body"- $ matchChildContent' [ read_paragraph ]+ $ matchSmushedChildBlocks' [ read_paragraph ] ------------------------- -- Citations@@ -792,44 +822,48 @@ ---------------------- ---read_table :: BlockMatcher+read_table :: ElementMatcher CombiningBlocks read_table = matchingElement NsTable "table"- $ liftA simpleTable'+ $ liftA (CombiningBlocks . table') $ (matchChildContent' [read_table_header]) &&&- (matchChildContent' [read_table_row])+ (matchChildContent' [read_table_row]) --- | A simple table without a caption.-simpleTable' :: ([[Blocks]], [[Blocks]]) -> Blocks-simpleTable' (headers, rows) =+-- | A table without a caption.+table' :: ([[Cell]], [[Cell]]) -> Blocks+table' (headers, rows) = table emptyCaption (replicate numcols defaults) th [tb] tf where defaults = (AlignDefault, ColWidthDefault) numcols = maximum $ map length $ headers ++ rows- toRow = Row nullAttr . map simpleCell+ toRow = Row nullAttr th = TableHead nullAttr $ map toRow headers tb = TableBody nullAttr 0 [] $ map toRow rows tf = TableFoot nullAttr [] ---read_table_header :: ElementMatcher [[Blocks]]+read_table_header :: ElementMatcher [[Cell]] read_table_header = matchingElement NsTable "table-header-rows" $ matchChildContent' [ read_table_row ] ---read_table_row :: ElementMatcher [[Blocks]]+read_table_row :: ElementMatcher [[Cell]] read_table_row = matchingElement NsTable "table-row" $ liftA (:[]) $ matchChildContent' [ read_table_cell ] ---read_table_cell :: ElementMatcher [Blocks]+read_table_cell :: ElementMatcher [Cell] read_table_cell = matchingElement NsTable "table-cell"- $ liftA (compactify.(:[]))- $ matchChildContent' [ read_paragraph- , read_list- ]+ $ liftA3 cell'+ (readAttrWithDefault NsTable "number-rows-spanned" 1 >>^ RowSpan)+ (readAttrWithDefault NsTable "number-columns-spanned" 1 >>^ ColSpan)+ $ matchSmushedChildBlocks' [ read_paragraph+ , read_list+ ]+ where+ cell' rowSpan colSpan blocks = map (cell AlignDefault rowSpan colSpan) $ compactify [blocks] ---------------------- -- Frames@@ -858,14 +892,15 @@ "" -> returnV mempty -< () src' -> do let exts = extensionsFromList [Ext_auto_identifiers]- resource <- lookupResource -< T.unpack src'+ src'' = fixRelativeLink src'+ resource <- lookupResource -< T.unpack src'' _ <- updateMediaWithResource -< resource w <- findAttrText' NsSVG "width" -< () h <- findAttrText' NsSVG "height" -< () titleNodes <- matchChildContent' [ read_frame_title ] -< () alt <- matchChildContent [] read_plain_text -< () arr (firstMatch . uncurry4 imageWith) -<- (image_attributes w h, src', inlineListToIdentifier exts (toList titleNodes), alt)+ (image_attributes w h, src'', inlineListToIdentifier exts (toList titleNodes), alt) read_frame_title :: InlineMatcher read_frame_title = matchingElement NsSVG "title" (matchChildContent [] read_plain_text)@@ -894,7 +929,7 @@ read_frame_text_box :: ODTReaderSafe XML.Element (FirstMatch Inlines) read_frame_text_box = proc box -> do- paragraphs <- executeIn (matchChildContent' [ read_paragraph ]) -< box+ paragraphs <- executeIn (matchSmushedChildBlocks' [ read_paragraph ]) -< box arr read_img_with_caption -< toList paragraphs read_img_with_caption :: [Block] -> FirstMatch Inlines@@ -915,7 +950,7 @@ _ANCHOR_PREFIX_ = "anchor" ---readAnchorAttr :: ODTReader _x Anchor+readAnchorAttr :: ODTReader a Anchor readAnchorAttr = findAttrText NsText "name" -- | Beware: may fail@@ -956,7 +991,7 @@ $ maybeAddAnchorFrom readAnchorAttr -- | Beware: may fail-findAnchorRef :: ODTReader _x Anchor+findAnchorRef :: ODTReader a Anchor findAnchorRef = ( findAttrText NsText "ref-name" >>?^ (_ANCHOR_PREFIX_,) ) >>?! getPrettyAnchor@@ -991,13 +1026,13 @@ -- Entry point ---------------------- -read_text :: ODTReaderSafe _x Pandoc-read_text = matchChildContent' [ read_header- , read_paragraph- , read_list- , read_section- , read_table- ]+read_text :: ODTReaderSafe a Pandoc+read_text = matchSmushedChildBlocks' [ read_header+ , read_paragraph+ , read_list+ , read_section+ , read_table+ ] >>^ doc post_process :: Pandoc -> Pandoc@@ -1009,7 +1044,7 @@ = Table attr (Caption Nothing blks) specs th tb tf : post_process' xs post_process' bs = bs -read_body :: ODTReader _x (Pandoc, MediaBag)+read_body :: ODTReader a (Pandoc, MediaBag) read_body = executeInSub NsOffice "body" $ executeInSub NsOffice "text" $ liftAsSuccess
src/Text/Pandoc/Readers/ODT/Generic/XMLConverter.hs view
@@ -64,7 +64,7 @@ import Data.Text (Text) import Data.Default import Data.Maybe-import Data.List (foldl')+import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import Data.List.NonEmpty (NonEmpty(..)) @@ -298,7 +298,7 @@ => XMLConverterState nsID extraState -> Maybe (XMLConverterState nsID extraState) extractNSAttrs startState- = foldl' (\state d -> state >>= addNS d)+ = L.foldl' (\state d -> state >>= addNS d) (Just startState) nsAttribs where nsAttribs = mapMaybe readNSattr (XML.elAttribs element)
src/Text/Pandoc/Readers/ODT/StyleReader.hs view
@@ -45,7 +45,7 @@ import Data.Default import qualified Data.Foldable as F-import Data.List (unfoldr, foldl')+import qualified Data.List as L import qualified Data.Map as M import Data.Maybe import Data.Text (Text)@@ -114,14 +114,14 @@ -- the fonts: -- | A reader for font pitches-fontPitchReader :: XMLReader _s _x FontPitches+fontPitchReader :: XMLReader s a FontPitches fontPitchReader = executeInSub NsOffice "font-face-decls" ( withEveryL NsStyle "font-face" (liftAsSuccess ( findAttr' NsStyle "name" &&& lookupDefaultingAttr NsStyle "font-pitch" ))- >>?^ ( M.fromList . foldl' accumLegalPitches [] )+ >>?^ ( M.fromList . L.foldl' accumLegalPitches [] ) ) `ifFailedDo` returnV (Right M.empty) where accumLegalPitches ls (Nothing,_) = ls accumLegalPitches ls (Just n,p) = (n,p):ls@@ -129,7 +129,7 @@ -- | A wrapper around the font pitch reader that lifts the result into the -- state.-readFontPitches :: StyleReader x x+readFontPitches :: StyleReader a a readFontPitches = producingExtraState () () fontPitchReader @@ -141,7 +141,7 @@ -- and use the pitch from there. -- * Return the result in a Maybe ---findPitch :: XMLReaderSafe FontPitches _x (Maybe FontPitch)+findPitch :: XMLReaderSafe FontPitches a (Maybe FontPitch) findPitch = ( lookupAttr NsStyle "font-pitch" `ifFailedDo` findAttr NsStyle "font-name" >>? ( keepingTheValue getExtraState@@ -416,7 +416,7 @@ -------------------------------------------------------------------------------- ---readAllStyles :: StyleReader _x Styles+readAllStyles :: StyleReader a Styles readAllStyles = ( readFontPitches >>?! ( readAutomaticStyles &&& readStyles ))@@ -424,7 +424,7 @@ -- all top elements are always on the same hierarchy level ---readStyles :: StyleReader _x Styles+readStyles :: StyleReader a Styles readStyles = executeInSub NsOffice "styles" $ liftAsSuccess $ liftA3 Styles ( tryAll NsStyle "style" readStyle >>^ M.fromList )@@ -432,7 +432,7 @@ ( tryAll NsStyle "default-style" readDefaultStyle >>^ M.fromList ) ---readAutomaticStyles :: StyleReader _x Styles+readAutomaticStyles :: StyleReader a Styles readAutomaticStyles = executeInSub NsOffice "automatic-styles" $ liftAsSuccess $ liftA3 Styles ( tryAll NsStyle "style" readStyle >>^ M.fromList )@@ -440,12 +440,12 @@ ( returnV M.empty ) ---readDefaultStyle :: StyleReader _x (StyleFamily, StyleProperties)+readDefaultStyle :: StyleReader a (StyleFamily, StyleProperties) readDefaultStyle = lookupAttr NsStyle "family" >>?! keepingTheValue readStyleProperties ---readStyle :: StyleReader _x (StyleName,Style)+readStyle :: StyleReader a (StyleName,Style) readStyle = findAttr NsStyle "name" >>?! keepingTheValue ( liftA4 Style@@ -456,13 +456,13 @@ ) ---readStyleProperties :: StyleReaderSafe _x StyleProperties+readStyleProperties :: StyleReaderSafe a StyleProperties readStyleProperties = liftA2 SProps ( readTextProperties >>> choiceToMaybe ) ( readParaProperties >>> choiceToMaybe ) ---readTextProperties :: StyleReader _x TextProperties+readTextProperties :: StyleReader a TextProperties readTextProperties = executeInSub NsStyle "text-properties" $ liftAsSuccess ( liftA6 PropT@@ -477,15 +477,15 @@ isFontBold = ("normal",False):("bold",True) :map ((,True) . tshow) ([100,200..900]::[Int]) -readUnderlineMode :: StyleReaderSafe _x (Maybe UnderlineMode)+readUnderlineMode :: StyleReaderSafe a (Maybe UnderlineMode) readUnderlineMode = readLineMode "text-underline-mode" "text-underline-style" -readStrikeThroughMode :: StyleReaderSafe _x (Maybe UnderlineMode)+readStrikeThroughMode :: StyleReaderSafe a (Maybe UnderlineMode) readStrikeThroughMode = readLineMode "text-line-through-mode" "text-line-through-style" -readLineMode :: Text -> Text -> StyleReaderSafe _x (Maybe UnderlineMode)+readLineMode :: Text -> Text -> StyleReaderSafe a (Maybe UnderlineMode) readLineMode modeAttr styleAttr = proc x -> do isUL <- searchAttr NsStyle styleAttr False isLinePresent -< x mode <- lookupAttr' NsStyle modeAttr -< x@@ -501,7 +501,7 @@ ] ---readParaProperties :: StyleReader _x ParaProperties+readParaProperties :: StyleReader a ParaProperties readParaProperties = executeInSub NsStyle "paragraph-properties" $ liftAsSuccess ( liftA3 PropP@@ -527,7 +527,7 @@ ---- ---readListStyle :: StyleReader _x (StyleName, ListStyle)+readListStyle :: StyleReader a (StyleName, ListStyle) readListStyle = findAttr NsStyle "name" >>?! keepingTheValue@@ -540,13 +540,13 @@ -- readListLevelStyles :: Namespace -> ElementName -> ListLevelType- -> StyleReaderSafe _x (SM.SetMap Int ListLevelStyle)+ -> StyleReaderSafe a (SM.SetMap Int ListLevelStyle) readListLevelStyles namespace elementName levelType = tryAll namespace elementName (readListLevelStyle levelType) >>^ SM.fromList ---readListLevelStyle :: ListLevelType -> StyleReader _x (Int, ListLevelStyle)+readListLevelStyle :: ListLevelType -> StyleReader a (Int, ListLevelStyle) readListLevelStyle levelType = readAttr NsText "level" >>?! keepingTheValue ( liftA5 toListLevelStyle@@ -603,7 +603,7 @@ -- be the first element of the list, followed by its parent and so on. -- The current style is not in the list. parents :: Style -> Styles -> [Style]-parents style styles = unfoldr findNextParent style -- Ha!+parents style styles = L.unfoldr findNextParent style -- Ha! where findNextParent Style{..} = fmap duplicate $ (`lookupStyle` styles) =<< styleParentName
src/Text/Pandoc/Readers/Org/Blocks.hs view
@@ -38,7 +38,7 @@ import Data.Char (isSpace) import Data.Default (Default) import Data.Functor (($>))-import Data.List (find, foldl')+import qualified Data.List as L import Data.Maybe (fromMaybe, isJust, isNothing) import Data.Text (Text) import Data.List.NonEmpty (nonEmpty)@@ -130,9 +130,9 @@ blockAttributes = try $ do kv <- many stringyMetaAttribute guard $ all (isBlockAttr . fst) kv- let caption = foldl' (appendValues "caption") Nothing kv- let kvAttrs = foldl' (appendValues "attr_html") Nothing kv- let name = snd <$> find ((`elem` ["name", "label"]) . fst) (reverse kv)+ let caption = L.foldl' (appendValues "caption") Nothing kv+ let kvAttrs = L.foldl' (appendValues "attr_html") Nothing kv+ let name = snd <$> L.find ((`elem` ["name", "label"]) . fst) (reverse kv) caption' <- traverse (parseFromString inlines . (<> "\n")) caption kvAttrs' <- parseFromString keyValues . (<> "\n") $ fromMaybe mempty kvAttrs return BlockAttributes@@ -231,7 +231,7 @@ newline content <- rawBlockContent "example" let id' = fromMaybe mempty $ blockAttrName blockAttrs- let codeBlck = B.codeBlockWith (id', "example":classes, kv) content+ let codeBlck = B.codeBlockWith (id', classes, kv) content return . return $ codeBlck rawBlockLines :: Monad m => (Text -> F Blocks) -> Text -> OrgParser m (F Blocks)@@ -558,7 +558,7 @@ exampleLine = try $ exampleLineStart *> anyLine exampleCode :: Text -> Blocks-exampleCode = B.codeBlockWith ("", ["example"], [])+exampleCode = B.codeBlockWith ("", [], []) --
src/Text/Pandoc/Readers/RIS.hs view
@@ -23,7 +23,7 @@ import Text.Pandoc.Definition import Text.Pandoc.Parsing import Data.Char (isAsciiUpper, isDigit, isSpace, ord, chr)-import Data.List (foldl')+import qualified Data.List as L import Citeproc (Reference(..), ItemId(..), Val(..), Date(..), DateParts(..), toVariable) import Text.Pandoc.Builder as B@@ -185,7 +185,7 @@ return $ fixDuplicateIds $ map risRecordToReference recs fixDuplicateIds :: [Reference Text] -> [Reference Text]-fixDuplicateIds = reverse . snd . foldl' go (mempty, [])+fixDuplicateIds = reverse . snd . L.foldl' go (mempty, []) where go (ids_seen, refs) ref = case M.lookup (referenceId ref) ids_seen of
src/Text/Pandoc/Readers/RST.hs view
@@ -1520,19 +1520,11 @@ , str , endline , smart- , hyphens , escapedChar , symbol ] <?> "inline content" parseInlineFromText :: PandocMonad m => Text -> RSTParser m Inlines parseInlineFromText = parseFromString' (trimInlines . mconcat <$> many inline)--hyphens :: Monad m => RSTParser m Inlines-hyphens = do- result <- many1Char (char '-')- optional endline- -- don't want to treat endline after hyphen or dash as a space- return $ B.str result escapedChar :: Monad m => RSTParser m Inlines escapedChar = do c <- escaped anyChar
src/Text/Pandoc/Readers/RTF.hs view
@@ -20,7 +20,7 @@ import Control.Monad import Control.Monad.Except (throwError) import Crypto.Hash (hashWith, SHA1(SHA1))-import Data.List (find, foldl')+import qualified Data.List as L import Data.Word (Word8, Word16) import Data.Default import Data.Text (Text)@@ -305,6 +305,26 @@ [] -> [] (x:xs) -> f x : xs } +-- | @\\plain@ resets character formatting to default values. Unlike a+-- full reset to 'def', it must leave paragraph-level properties (such as+-- whether we are inside a table, the list level, or the outline level)+-- intact, as well as contextual properties like the current hyperlink or+-- anchor. Resetting these caused tables to be parsed as deeply nested+-- structures when cell paragraphs used @\\plain@ after @\\intbl@.+resetCharProps :: Properties -> Properties+resetCharProps g =+ g{ gBold = False+ , gItalic = False+ , gCaps = False+ , gDeleted = False+ , gSub = False+ , gSuper = False+ , gSmallCaps = False+ , gUnderline = False+ , gFontFamily = Nothing+ , gHidden = False+ }+ addFormatting :: (Properties, Text) -> Inlines addFormatting (_, "\n") = B.linebreak addFormatting (props, _) | gHidden props = mempty@@ -546,9 +566,8 @@ ControlSymbol '~' -> bs <$ addText "\x00a0" ControlSymbol '-' -> bs <$ addText "\x00ad" ControlSymbol '_' -> bs <$ addText "\x2011"- ControlWord "trowd" _ -> bs <$ do -- add new row- updateState $ \s -> s{ sTableRows = TableRow [] : sTableRows s- , sCurrentCell = mempty }+ ControlWord "trowd" _ -> bs <$ beginTableRow -- begin new row+ ControlWord "row" _ -> bs <$ beginTableRow -- end current row ControlWord "cell" _ -> bs <$ do new <- emitBlocks mempty curCell <- (<> new) . sCurrentCell <$> getState@@ -558,9 +577,10 @@ TableRow (curCell : cs) : rs [] -> [TableRow [curCell]] -- shouldn't happen , sCurrentCell = mempty }- ControlWord "intbl" _ ->- emitBlocks bs <* modifyGroup (\g -> g{ gInTable = True })- ControlWord "plain" _ -> bs <$ modifyGroup (const def)+ ControlWord "intbl" _ -> do+ ls <- closeLists 0 -- see #11364+ ((ls <>) <$> emitBlocks bs) <* modifyGroup (\g -> g{ gInTable = True })+ ControlWord "plain" _ -> bs <$ modifyGroup resetCharProps ControlWord "lquote" _ -> bs <$ addText "\x2018" ControlWord "rquote" _ -> bs <$ addText "\x2019" ControlWord "ldblquote" _ -> bs <$ addText "\x201C"@@ -627,9 +647,10 @@ modifyGroup (\g -> g{ gUnderline = boolParam mbp }) ControlWord "ulnone" _ -> bs <$ modifyGroup (\g -> g{ gUnderline = False })- ControlWord "pard" _ -> bs <$ do+ ControlWord "pard" _ -> do+ newbs <- emitBlocks bs modifyGroup (const def)- getStyleFormatting 0 >>= foldM processTok bs+ getStyleFormatting 0 >>= foldM processTok newbs ControlWord "par" _ -> emitBlocks bs _ -> pure bs @@ -671,6 +692,19 @@ closeLists lvl _ -> pure mempty +-- Begin a new table row. Both @\\trowd@ (which sets row defaults) and+-- @\\row@ (which ends a row) start a fresh row to be filled by subsequent+-- @\\cell@s. We only push a new empty row when the current one already has+-- cells, so that documents repeating @\\trowd@ after @\\row@ (or omitting+-- @\\trowd@ between rows) both produce the same flat structure.+beginTableRow :: PandocMonad m => RTFParser m ()+beginTableRow =+ updateState $ \s ->+ s{ sTableRows = case sTableRows s of+ TableRow [] : _ -> sTableRows s+ rs -> TableRow [] : rs+ , sCurrentCell = mempty }+ closeTable :: PandocMonad m => RTFParser m Blocks closeTable = do rawrows <- sTableRows <$> getState@@ -678,10 +712,13 @@ then return mempty else do let getCells (TableRow cs) = reverse cs- let rows = map getCells . reverse $ rawrows+ -- drop empty rows produced by row terminators+ let rows = filter (not . null) . map getCells . reverse $ rawrows updateState $ \s -> s{ sCurrentCell = mempty , sTableRows = [] }- return $ B.simpleTable [] rows+ if null rows+ then return mempty+ else return $ B.simpleTable [] rows closeContainers :: PandocMonad m => RTFParser m Blocks closeContainers = do@@ -788,22 +825,29 @@ let isFieldMod (Tok _ (ControlWord w _)) = w `elem` ["flddirty", "fldedit", "fldlock", "fldpriv"] isFieldMod _ = False++ let instructionTokens (Tok _ (Grouped toks)) = Just toks+ instructionTokens unformattedTok@(Tok _ (UnformattedText _)) = Just [unformattedTok]+ instructionTokens _ = Nothing case dropWhile isFieldMod ts of [Tok _ (Grouped (Tok _ (ControlSymbol '*') :Tok _ (ControlWord "fldinst" Nothing)- :Tok _ (Grouped instrtoks)+ :instrtoks :_)), Tok _ (Grouped (Tok _ (ControlWord "fldrslt" Nothing)- :Tok _ (Grouped resulttoks) : _))] -> do- case getHyperlink instrtoks of- Just linkdest -> do- modifyGroup $ \g -> g{ gHyperlink = Just linkdest }- result <- foldM processTok bs resulttoks- modifyGroup $ \g -> g{ gHyperlink = Nothing }- return result- Nothing -> foldM processTok bs resulttoks+ :resulttoks))] -> do+ case instructionTokens instrtoks of+ Nothing -> pure bs+ Just instrtoks' ->+ case getHyperlink instrtoks' of+ Just linkdest -> do+ modifyGroup $ \g -> g{ gHyperlink = Just linkdest }+ result <- foldM processTok bs resulttoks+ modifyGroup $ \g -> g{ gHyperlink = Nothing }+ return result+ Nothing -> foldM processTok bs resulttoks _ -> pure bs getHyperlink :: [Tok] -> Maybe Text@@ -895,7 +939,7 @@ _ -> mempty let isBasedOn (Tok _ (ControlWord "sbasedon" (Just _))) = True isBasedOn _ = False- let styBasedOn = case find isBasedOn toks of+ let styBasedOn = case L.find isBasedOn toks of Just (Tok _ (ControlWord "sbasedon" (Just i))) -> Just i _ -> Nothing let isStyleControl (Tok _ (ControlWord x _)) =@@ -920,7 +964,7 @@ handlePict :: PandocMonad m => [Tok] -> RTFParser m () handlePict toks = do- let pict = foldl' getPictData def toks+ let pict = L.foldl' getPictData def toks let altText = "image" let bytes = if picBinary pict@@ -959,7 +1003,7 @@ processFontTable :: [Tok] -> FontTable-processFontTable = snd . foldl' go (0, mempty)+processFontTable = snd . L.foldl' go (0, mempty) where go (fontnum, tbl) (Tok _ tok') = case tok' of@@ -972,7 +1016,7 @@ (ControlWord "fdecor" _) -> (fontnum, IntMap.insert fontnum Decor tbl) (ControlWord "ftech" _) -> (fontnum, IntMap.insert fontnum Tech tbl) (ControlWord "fbidi" _) -> (fontnum, IntMap.insert fontnum Bidi tbl)- (Grouped ts) -> foldl' go (fontnum, tbl) ts+ (Grouped ts) -> L.foldl' go (fontnum, tbl) ts _ -> (fontnum, tbl) defaultAnsiWordToChar :: Word8 -> Char
src/Text/Pandoc/Readers/Roff.hs view
@@ -268,7 +268,8 @@ manyTill anyChar (try (string "T}")) simpleCell = do tabChar <- tableTabChar <$> getState- many (notFollowedBy (char tabChar <|> newline) >> anyChar)+ many $ (char '\\' >> anyChar)+ <|> (notFollowedBy (char tabChar <|> newline) >> anyChar) tableRow :: PandocMonad m => RoffLexer m [RoffTokens] tableRow = do
src/Text/Pandoc/Readers/Textile.hs view
@@ -38,7 +38,8 @@ import Control.Monad (guard, liftM) import Control.Monad.Except (throwError) import Data.Char (digitToInt, isUpper)-import Data.List (intersperse, transpose, foldl')+import Data.List (intersperse, transpose)+import qualified Data.List as L import Data.List.NonEmpty (NonEmpty(..), nonEmpty) import qualified Data.Map as M import Data.Text (Text)@@ -412,8 +413,12 @@ notFollowedBy blankline raw <- trim . T.pack <$> many (noneOf "|\n" <|> try (char '\n' <* notFollowedBy blankline))- content <- mconcat <$> parseFromString' (many inline) raw- return ((isHeader, alignment), B.plain content)+ content <- parseFromString' parseBlocks (raw <> "\n\n")+ -- Convert lone Para to Plain for backward compatibility+ let content' = case B.toList content of+ [Para ils] -> B.plain (B.fromList ils)+ _ -> content+ return ((isHeader, alignment), content') -- | A table row is made of many table cells tableRow :: PandocMonad m => TextileParser m [((Bool, Alignment), Blocks)]@@ -732,7 +737,7 @@ -- | Html / CSS attributes attributes :: PandocMonad m => TextileParser m Attr-attributes = foldl' (flip ($)) ("",[],[]) <$>+attributes = L.foldl' (flip ($)) ("",[],[]) <$> try (do special <- option id specialAttribute attrs <- many attribute return (special : attrs))
src/Text/Pandoc/Readers/Typst.hs view
@@ -29,9 +29,11 @@ import Text.Pandoc.Definition import Typst ( parseTypst, evaluateTypst ) import Text.Pandoc.Error (PandocError(..))+import Text.Pandoc.Translations (Term(References), translateTerm) import Text.Pandoc.Shared (tshow, blocksToInlines) import Control.Monad.Except (throwError) import Control.Monad (MonadPlus (mplus), void, guard, foldM)+import Control.Monad.Trans (lift) import qualified Data.Foldable as F import qualified Data.Map as M import Data.Maybe (catMaybes, fromMaybe, isJust)@@ -58,7 +60,7 @@ -- | Read Typst from an input string and return a Pandoc document. readTypst :: (PandocMonad m, ToSources a) => ReaderOptions -> a -> m Pandoc-readTypst _opts inp = do+readTypst opts inp = do let sources = toSources inp let inputName = case sources of Sources ((pos, _):_) -> sourceName pos@@ -71,7 +73,7 @@ currentUTCTime = getCurrentTime, lookupEnvVar = fmap (fmap T.unpack) . lookupEnv . T.pack, checkExistence = fileExists }- res <- evaluateTypst ops inputName parsed+ res <- evaluateTypst ops (readerTypstInputs opts) inputName parsed case res of Left e -> throwError $ PandocParseError $ tshow e Right content -> do@@ -140,8 +142,9 @@ | Just (VContent elts) <- M.lookup "body" fields = let elts' = fmap fixNesting elts fields' = M.insert "body" (VContent elts') fields- in if isInline el- then case getField "body" fields' of+ in if isBlock el+ then Elt name pos fields'+ else case getField "body" fields' of Just ([el'@(Elt name' pos' fields'')] :: Seq Content) | isBlock el' , not (isInline el')@@ -152,7 +155,6 @@ (Elt name pos fields''))) fields' _ -> Elt name pos fields'- else Elt name pos fields' fixNesting x = x pPandoc :: PandocMonad m => P m B.Pandoc@@ -401,6 +403,31 @@ ,("pad", \_ _ fields -> -- ignore paddingy getField "body" fields >>= pWithContents pBlocks) ,("pagebreak", \_ _ _ -> pure $ B.divWith ("", ["page-break"], [("wrapper", "1")]) B.horizontalRule)+ ,("bibliography", \_ _ fields -> do+ let getSources v = case v of+ VString t -> MetaString t+ VArray xs -> MetaList $ map getSources $ V.toList xs+ _ -> MetaBool True -- should not occur+ let mbSources = getSources <$> M.lookup "sources" fields++ let updateBibliography x = updateState $ \s ->+ s{ sMeta = B.setMeta "bibliography" x (sMeta s) }+ maybe (pure ()) updateBibliography mbSources++ let title' = M.lookup "title" fields+ mbTitle <- case title' of+ Just VNone -> pure Nothing+ Just (VContent cs) -> Just <$> pWithContents pInlines cs+ Just (VString t) -> pure $ Just $ B.text t+ _ -> Just . B.text <$> lift (translateTerm References)+ let hdr = maybe mempty (B.header 1) mbTitle+ pure $ hdr <> B.divWith ("refs", [], []) mempty)+ ,("rotate", \_ _ fields -> do+ body <- getField "body" fields >>= pWithContents pBlocks+ let kvs = case M.lookup "angle" fields of+ Just (VAngle ang) -> [("angle", T.pack $ show ang)]+ _ -> []+ pure $ B.divWith ("", ["rotate"], kvs) body) ] inlineHandlers :: PandocMonad m =>@@ -547,6 +574,12 @@ ,("block", \_ mbident fields -> maybe id (\ident -> B.spanWith (ident, [], [])) mbident <$> (getField "body" fields >>= pWithContents pInlines))+ ,("rotate", \_ _ fields -> do+ body <- getField "body" fields >>= pWithContents pInlines+ let kvs = case M.lookup "angle" fields of+ Just (VAngle ang) -> [("angle", T.pack $ show ang)]+ _ -> []+ pure $ B.spanWith ("", ["rotate"], kvs) body) ] getInlineBody :: PandocMonad m => M.Map Identifier Val -> P m (Seq Content)
src/Text/Pandoc/SelfContained.hs view
@@ -431,7 +431,7 @@ report $ CouldNotFetchResource r "" return $ CouldNotFetch e PandocHttpError u er -> do- report $ CouldNotFetchResource u (tshow er)+ report $ CouldNotFetchResource u er return $ CouldNotFetch e _ -> throwError e removeQueryAndFragment = T.takeWhile (\c -> c /= '#' && c /= '?')
@@ -1,3 +1,4 @@+{-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -56,6 +57,7 @@ inlineListToIdentifier, textToIdentifier, isHeaderBlock,+ hasLineBreaks, onlySimpleTableCells, isTightList, taskListItemFromAscii,@@ -90,7 +92,8 @@ import Data.Char (isAlpha, isLower, isSpace, isUpper, toLower, isAlphaNum, generalCategory, GeneralCategory(NonSpacingMark, SpacingCombiningMark, EnclosingMark, ConnectorPunctuation))-import Data.List (find, foldl', groupBy, intercalate, intersperse, union)+import Data.List (find, groupBy, intercalate, intersperse, union)+import qualified Data.List as L import qualified Data.Map as M import Data.Maybe (mapMaybe) import Data.Monoid (Any (..) )@@ -138,23 +141,27 @@ -- /not/ indices but text widths, which will be different for East Asian -- characters, emojis, etc. splitTextByIndices :: [Int] -> T.Text -> [T.Text]-splitTextByIndices ns = splitTextByRelIndices (zipWith (-) ns (0:ns)) . T.unpack+splitTextByIndices ns = splitByRelWidths (zipWith (-) ns (0:ns)) where- splitTextByRelIndices [] cs = [T.pack cs]- splitTextByRelIndices (x:xs) cs =- let (first, rest) = splitAt' x cs- in T.pack first : splitTextByRelIndices xs rest+ splitByRelWidths [] t = [t]+ splitByRelWidths (w:ws) t =+ let (first, rest) = splitAtWidth w t+ in first : splitByRelWidths ws rest --- | Returns a pair whose first element is a prefix of @t@ and that has--- width @n@, and whose second is the remainder of the string.+-- | Split a @Text@ at a given display width, where width is determined+-- by 'charWidth' (East Asian characters, emojis, etc. count as 2). -- -- Note: Do *not* replace this with 'T.splitAt', which is not sensitive -- to character widths!-splitAt' :: Int {-^ n -} -> [Char] {-^ t -} -> ([Char],[Char])-splitAt' _ [] = ([],[])-splitAt' n xs | n <= 0 = ([],xs)-splitAt' n (x:xs) = (x:ys,zs)- where (ys,zs) = splitAt' (n - charWidth x) xs+splitAtWidth :: Int -> T.Text -> (T.Text, T.Text)+splitAtWidth n t+ | n <= 0 = (T.empty, t)+ | otherwise = T.splitAt (go 0 0 t) t+ where+ go !idx !w t'+ | w >= n = idx+ | T.null t' = idx+ | otherwise = go (idx + 1) (w + charWidth (T.head t')) (T.tail t') -- -- Text processing@@ -235,20 +242,23 @@ toRomanNumeral :: Int -> T.Text toRomanNumeral x | x >= 4000 || x < 0 = "?"- | x >= 1000 = "M" <> toRomanNumeral (x - 1000)- | x >= 900 = "CM" <> toRomanNumeral (x - 900)- | x >= 500 = "D" <> toRomanNumeral (x - 500)- | x >= 400 = "CD" <> toRomanNumeral (x - 400)- | x >= 100 = "C" <> toRomanNumeral (x - 100)- | x >= 90 = "XC" <> toRomanNumeral (x - 90)- | x >= 50 = "L" <> toRomanNumeral (x - 50)- | x >= 40 = "XL" <> toRomanNumeral (x - 40)- | x >= 10 = "X" <> toRomanNumeral (x - 10)- | x == 9 = "IX"- | x >= 5 = "V" <> toRomanNumeral (x - 5)- | x == 4 = "IV"- | x >= 1 = "I" <> toRomanNumeral (x - 1)- | otherwise = ""+ | otherwise = T.pack (go x)+ where+ go n+ | n >= 1000 = 'M' : go (n - 1000)+ | n >= 900 = 'C' : 'M' : go (n - 900)+ | n >= 500 = 'D' : go (n - 500)+ | n >= 400 = 'C' : 'D' : go (n - 400)+ | n >= 100 = 'C' : go (n - 100)+ | n >= 90 = 'X' : 'C' : go (n - 90)+ | n >= 50 = 'L' : go (n - 50)+ | n >= 40 = 'X' : 'L' : go (n - 40)+ | n >= 10 = 'X' : go (n - 10)+ | n == 9 = "IX"+ | n >= 5 = 'V' : go (n - 5)+ | n == 4 = "IV"+ | n >= 1 = 'I' : go (n - 1)+ | otherwise = [] -- | Convert tabs to spaces. Tabs will be preserved if tab stop is set to 0. tabFilter :: Int -- ^ Tab stop@@ -261,7 +271,7 @@ in if T.null s2 then s1 else s1 <> T.replicate- (tabStop - (T.length s1 `mod` tabStop)) (T.pack " ")+ (tabStop - (T.length s1 `mod` tabStop)) " " <> go (T.drop 1 s2) --@@ -407,9 +417,9 @@ let (others, final) = (init items, last items) in case reverse (B.toList final) of (Para a:xs)- | null [Para x | Para x <- xs ++ concatMap B.toList others]+ | not (any isPara xs || any (any isPara . B.toList) others) -> others ++ [B.fromList (reverse (Plain a : xs))]- _ | null [Para x | Para x <- concatMap B.toList items]+ _ | not (any (any isPara . B.toList) items) -> items _ -> map (fmap plainToPara) items @@ -607,6 +617,18 @@ x -> x numIdent n = baseIdent <> "-" <> tshow n +-- | True if inlines include a LineBreak (possibly embedded), with the exception+-- of line breaks in Notes.+hasLineBreaks :: [Inline] -> Bool+hasLineBreaks = getAny . query isLineBreak . walk removeNote+ where+ removeNote :: Inline -> Inline+ removeNote (Note _) = Str ""+ removeNote x = x+ isLineBreak :: Inline -> Any+ isLineBreak LineBreak = Any True+ isLineBreak _ = Any False+ -- | True if block is a Header block. isHeaderBlock :: Block -> Bool isHeaderBlock Header{} = True@@ -713,11 +735,12 @@ -- | Render HTML tags. renderTags' :: [Tag T.Text] -> T.Text renderTags' = renderTagsOptions- renderOptions{ optMinimize = matchTags ["hr", "br", "img",- "meta", "link", "col",- "use", "path", "rect"]- , optRawTag = matchTags ["script", "style"] }- where matchTags tags = flip elem tags . T.toLower+ renderOptions{ optMinimize = \t -> T.toLower t `Set.member` minimizeTags+ , optRawTag = \t -> T.toLower t `Set.member` rawTags }+ where+ minimizeTags = Set.fromList ["hr","br","img","meta","link","col",+ "use","path","rect"]+ rawTags = Set.fromList ["script","style"] -- -- File handling@@ -733,7 +756,7 @@ -- | Canonicalizes a file path by removing redundant @.@ and @..@. makeCanonical :: FilePath -> FilePath makeCanonical = Posix.joinPath . transformPathParts . splitDirectories- where transformPathParts = reverse . foldl' go []+ where transformPathParts = reverse . L.foldl' go [] go as "." = as go ("..":as) ".." = ["..", ".."] <> as go (_:as) ".." = as@@ -749,7 +772,7 @@ -- > collapseFilePath "parent/foo/.." == "parent" -- > collapseFilePath "/parent/foo/../../bar" == "/bar" collapseFilePath :: FilePath -> FilePath-collapseFilePath = Posix.joinPath . reverse . foldl' go [] . splitDirectories+collapseFilePath = Posix.joinPath . reverse . L.foldl' go [] . splitDirectories where go rs "." = rs go r@(p:rs) ".." = case p of
src/Text/Pandoc/Translations.hs view
@@ -23,7 +23,7 @@ import Text.Pandoc.Class (PandocMonad(..), toTextM, report) import Text.Pandoc.Class.CommonState (CommonState(..)) import Text.Pandoc.Data (readDataFile)-import Text.Pandoc.Error (PandocError(..))+import Data.Containers.ListUtils (nubOrd) import Text.Pandoc.Logging (LogMessage(..)) import Control.Monad.Except (catchError) import qualified Data.Text as T@@ -56,34 +56,29 @@ Nothing -> return mempty -- no language defined Just (_, Just t) -> return t Just (lang, Nothing) -> do -- read from file- let translationFile = "translations/" <> renderLang lang <> ".yaml"- let fallbackFile = "translations/" <> langLanguage lang <> ".yaml"- let getTrans fp = do- txt <- readDataFile fp >>= toTextM fp- case readTranslations txt of- Left e -> do+ let translationFiles = map (\x -> "translations/" <> T.unpack x <> ".yaml")+ (nubOrd [renderLang lang,+ langLanguage lang <> maybe "" ("-" <>) (langScript lang),+ langLanguage lang])+ let getTrans [] = return mempty+ getTrans (fp:fps) = do+ result <- catchError (Right <$> (readDataFile fp >>= toTextM fp))+ (\_ -> pure (Left ""))+ case result >>= readTranslations of+ Left e+ | null fps -> do report $ CouldNotLoadTranslations (renderLang lang)- (T.pack fp <> ": " <> e)+ (T.pack fp <> ": " <> e) -- make sure we don't try again... modifyCommonState $ \st -> st{ stTranslations = Nothing } return mempty- Right t -> do- modifyCommonState $ \st ->- st{ stTranslations = Just (lang, Just t) }- return t- catchError (getTrans $ T.unpack translationFile)- (\_ ->- catchError (getTrans $ T.unpack fallbackFile)- (\e -> do- report $ CouldNotLoadTranslations (renderLang lang)- $ case e of- PandocCouldNotFindDataFileError _ ->- "data file " <> fallbackFile <> " not found"- _ -> ""- -- make sure we don't try again...- modifyCommonState $ \st -> st{ stTranslations = Nothing }- return mempty))+ | otherwise -> getTrans fps+ Right t -> do+ modifyCommonState $ \st ->+ st{ stTranslations = Just (lang, Just t) }+ return t+ getTrans translationFiles -- | Get a translation from the current term map. -- Issue a warning if the term is not defined.
src/Text/Pandoc/UTF8.hs view
@@ -8,7 +8,7 @@ Stability : alpha Portability : portable -UTF-8 aware string IO functions that will work with GHC 6.10, 6.12, or 7.+UTF-8 aware string IO functions. -} module Text.Pandoc.UTF8 ( readFile , getContents
src/Text/Pandoc/Writers/AsciiDoc.hs view
@@ -163,6 +163,7 @@ needsEscape '+' = True needsEscape '`' = True needsEscape '*' = True+ needsEscape '#' = True needsEscape '_' = True needsEscape '<' = True needsEscape '>' = True@@ -593,7 +594,9 @@ _ -> False isSpacy Start (Str xs) | Just (c, _) <- T.uncons xs = isPunctuation c || isSpace c- isSpacy _ _ = True+ isSpacy End (Link{}) = True+ isSpacy End (Image{}) = True+ isSpacy _ _ = False setIntraword :: PandocMonad m => Bool -> ADW m () setIntraword b = modify $ \st -> st{ intraword = b }@@ -609,25 +612,27 @@ contents <- inlineListToAsciiDoc opts lst isIntraword <- gets intraword let marker = if isIntraword then "__" else "_"- return $ marker <> contents <> marker+ return $ delimited marker marker contents inlineToAsciiDoc opts (Underline lst) = do contents <- inlineListToAsciiDoc opts lst- return $ "[.underline]#" <> contents <> "#"+ return $ delimited "[.underline]#" "#" contents inlineToAsciiDoc opts (Strong lst) = do contents <- inlineListToAsciiDoc opts lst isIntraword <- gets intraword let marker = if isIntraword then "**" else "*"- return $ marker <> contents <> marker+ return $ delimited marker marker contents inlineToAsciiDoc opts (Strikeout lst) = do contents <- inlineListToAsciiDoc opts lst- return $ "[line-through]#" <> contents <> "#"+ return $ delimited "[line-through]#" "#" contents inlineToAsciiDoc opts (Superscript lst) = do contents <- inlineListToAsciiDoc opts lst- return $ "^" <> contents <> "^"+ return $ delimited "^" "^" contents inlineToAsciiDoc opts (Subscript lst) = do contents <- inlineListToAsciiDoc opts lst- return $ "~" <> contents <> "~"-inlineToAsciiDoc opts (SmallCaps lst) = inlineListToAsciiDoc opts lst+ return $ delimited "~" "~" contents+inlineToAsciiDoc opts (SmallCaps lst) = do+ contents <- inlineListToAsciiDoc opts lst+ return $ delimited "[smallcaps]#" "#" contents inlineToAsciiDoc opts (Quoted qt lst) = do isLegacy <- gets legacy contents <- inlineListToAsciiDoc opts lst
src/Text/Pandoc/Writers/DocBook.hs view
@@ -17,7 +17,7 @@ import Data.Generics (everywhere, mkT) import Data.List (nub, partition) import Data.Maybe (isNothing)-import Data.Monoid (All (..), Any (..))+import Data.Monoid (All (..)) import Data.Text (Text) import qualified Data.Text as T import qualified Text.Pandoc.Builder as B@@ -343,16 +343,6 @@ else inTagsIndented "figure" $ inTagsSimple "title" title $$ mconcat mediaobjects--hasLineBreaks :: [Inline] -> Bool-hasLineBreaks = getAny . query isLineBreak . walk removeNote- where- removeNote :: Inline -> Inline- removeNote (Note _) = Str ""- removeNote x = x- isLineBreak :: Inline -> Any- isLineBreak LineBreak = Any True- isLineBreak _ = Any False alignmentToString :: Alignment -> Text alignmentToString alignment = case alignment of
src/Text/Pandoc/Writers/Docx.hs view
@@ -29,726 +29,827 @@ import Control.Monad.Except (throwError) import Control.Monad.Reader ( ReaderT(runReaderT) ) import Control.Monad.State.Strict ( StateT(runStateT) )-import qualified Data.ByteString.Lazy as BL-import Data.Containers.ListUtils (nubOrd)-import Data.Char (isSpace)-import Data.List (isPrefixOf, isSuffixOf)-import Data.String (fromString)-import qualified Data.Map as M-import Data.Maybe (fromMaybe, mapMaybe, maybeToList)-import qualified Data.Set as Set-import qualified Data.Text as T-import Data.Text (Text)-import Data.Time.Clock.POSIX-import Skylighting-import Text.Pandoc.Class (PandocMonad, toLang)-import qualified Text.Pandoc.Class.PandocMonad as P-import Text.Pandoc.Data (readDataFile, readDefaultDataFile)-import Data.Time-import qualified Text.Pandoc.UTF8 as UTF8-import Text.Pandoc.Definition-import Text.Pandoc.Error-import Text.Pandoc.Highlighting (defaultStyle)-import Text.Pandoc.MIME (getMimeTypeDef)-import Text.Pandoc.Options-import Text.Pandoc.Readers.Docx.Parse (extractTarget)-import Text.Pandoc.Writers.Docx.StyleMap-import Text.Pandoc.Writers.Docx.Types-import Text.Pandoc.Writers.Docx.OpenXML (writeOpenXML, maxListLevel)-import Text.Pandoc.Shared-import Text.Pandoc.Walk-import Text.Pandoc.Writers.Shared-import Text.Pandoc.Writers.OOXML-import Text.Pandoc.XML.Light as XML-import Data.Generics (mkT, everywhere)-import Text.Collate.Lang (renderLang, Lang(..))--writeDocx :: (PandocMonad m)- => WriterOptions -- ^ Writer options- -> Pandoc -- ^ Document to convert- -> m BL.ByteString-writeDocx opts doc = do- let Pandoc meta blocks = walk fixDisplayMath doc- setupTranslations meta- let blocks' = makeSectionsWithOffsets (writerNumberOffset opts)- True Nothing blocks- let doc' = Pandoc meta blocks'-- username <- P.lookupEnv "USERNAME"- utctime <- P.getTimestamp- oldUserDataDir <- P.getUserDataDir- P.setUserDataDir Nothing- res <- readDefaultDataFile "reference.docx"- P.setUserDataDir oldUserDataDir- let distArchive = toArchive $ BL.fromStrict res- refArchive <- case writerReferenceDoc opts of- Just f -> toArchive . BL.fromStrict . fst- <$> P.fetchItem (T.pack f)- Nothing -> toArchive . BL.fromStrict <$>- readDataFile "reference.docx"-- parsedDoc <- parseXml refArchive distArchive "word/document.xml"- let wname f qn = qPrefix qn == Just "w" && f (qName qn)- let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc-- -- Gets the template size- let mbpgsz = mbsectpr >>= filterElementName (wname (=="pgSz"))- let mbAttrSzWidth = mbpgsz >>= lookupAttrBy ((=="w") . qName) . elAttribs-- let mbpgmar = mbsectpr >>= filterElementName (wname (=="pgMar"))- let mbAttrMarLeft = mbpgmar >>= lookupAttrBy ((=="left") . qName) . elAttribs- let mbAttrMarRight = mbpgmar >>= lookupAttrBy ((=="right") . qName) . elAttribs-- -- Get the available area (converting the size and the margins to int and- -- doing the difference- let pgContentWidth = do- w <- mbAttrSzWidth >>= safeRead- r <- mbAttrMarRight >>= safeRead- l <- mbAttrMarLeft >>= safeRead- pure $ w - r - l-- -- styles- mblang <- toLang $ getLang opts meta- -- TODO FIXME avoid this generic traversal!- -- lang is in w:docDefaults / w:rPr / w:lang- let addLang :: Element -> Element- addLang = case mblang of- Nothing -> id- Just l -> everywhere (mkT (go l))- where- go :: Lang -> Element -> Element- go lang e'- | qName (elName e') == "lang"- = if isEastAsianLang lang- then e'{ elAttribs =- map (setattr "eastAsia" (renderLang lang)) $- elAttribs e' }- else- if isBidiLang lang- then e'{ elAttribs =- map (setattr "bidi" (renderLang lang)) $- elAttribs e' }- else e'{ elAttribs =- map (setattr "val" (renderLang lang)) $- elAttribs e' }- | otherwise = e'-- setattr attrname l (XML.Attr qn@(QName s _ _) _)- | s == attrname = XML.Attr qn l- setattr _ _ x = x-- isEastAsianLang Lang{ langLanguage = lang } =- lang == "zh" || lang == "ja" || lang == "ko"- isBidiLang Lang{ langLanguage = lang } =- lang == "he" || lang == "ar"-- let stylepath = "word/styles.xml"- styledoc <- addLang <$> parseXml refArchive distArchive stylepath-- -- parse styledoc for heading styles- let styleMaps = getStyleMaps refArchive-- let tocTitle = case lookupMetaInlines "toc-title" meta of- [] -> stTocTitle defaultWriterState- ls -> ls-- let isRTLmeta = case lookupMeta "dir" meta of- Just (MetaString "rtl") -> True- Just (MetaInlines [Str "rtl"]) -> True- _ -> False-- let env = defaultWriterEnv {- envRTL = isRTLmeta- , envChangesAuthor = fromMaybe "unknown" username- , envChangesDate = T.pack $ formatTime defaultTimeLocale "%FT%XZ" utctime- , envPrintWidth = maybe 420 (`quot` 20) pgContentWidth- }-- let isImageNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"- let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"- let isFooterNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"- parsedRels <- filterElements- (\e -> isImageNode e || isHeaderNode e || isFooterNode e)- <$> parseXml refArchive distArchive "word/_rels/document.xml.rels"- let getRelId e =- case findAttr (QName "Id" Nothing Nothing) e of- Just ident -> T.stripPrefix "rId" ident >>= safeRead- Nothing -> Nothing- let relIds = mapMaybe getRelId parsedRels- let maxRelId = if null relIds then 0 else maximum relIds-- let headers = filter isHeaderNode parsedRels- let footers = filter isFooterNode parsedRels- -- word/_rels/document.xml.rels- let addBaseRel (url', target') (maxId, rels) =- case [e | e <- rels- , findAttr (QName "Target" Nothing Nothing) e ==- Just target'] of- [] -> (maxId + 1, mknode "Relationship"- [("Type",url')- ,("Id","rId" <> tshow (maxId + 1))- ,("Target",target')] () : rels)- _ -> (maxId, rels)-- let (newMaxRelId, baserels) = foldr addBaseRel (maxRelId, parsedRels)- [("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",- "numbering.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",- "styles.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",- "settings.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",- "webSettings.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",- "fontTable.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",- "theme/theme1.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",- "footnotes.xml")- ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",- "comments.xml")- ]-- let initialSt = defaultWriterState {- stStyleMaps = styleMaps- , stTocTitle = tocTitle- , stCurId = newMaxRelId + 1- }-- -- adjust contents to add sectPr from reference.docx- let sectpr = case mbsectpr of- Just sectpr' -> add_attrs (elAttribs sectpr') $ mknode "w:sectPr" []- (elChildren sectpr')- Nothing -> mknode "w:sectPr" []- [ mknode "w:footnotePr" []- [ mknode "w:numRestart" [("w:val","eachSect")] () ]- ]-- ((contents, footnotes, comments), st) <- runStateT- (runReaderT- (writeOpenXML opts{ writerWrapText = WrapNone }- doc')- env{ envSectPr = Just sectpr })- initialSt- let epochtime = floor $ utcTimeToPOSIXSeconds utctime- let imgs = M.elems $ stImages st-- -- create entries for images in word/media/...- let toImageEntry (_,path,_,img) = toEntry ("word/" ++ path) epochtime $ toLazy img- let imageEntries = map toImageEntry imgs-- let stdAttributes =- [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")- ,("xmlns:m","http://schemas.openxmlformats.org/officeDocument/2006/math")- ,("xmlns:r","http://schemas.openxmlformats.org/officeDocument/2006/relationships")- ,("xmlns:o","urn:schemas-microsoft-com:office:office")- ,("xmlns:v","urn:schemas-microsoft-com:vml")- ,("xmlns:w10","urn:schemas-microsoft-com:office:word")- ,("xmlns:a","http://schemas.openxmlformats.org/drawingml/2006/main")- ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")- ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]--- -- we create [Content_Types].xml and word/_rels/document.xml.rels- -- from scratch rather than reading from reference.docx,- -- because Word sometimes changes these files when a reference.docx is modified,- -- e.g. deleting the reference to footnotes.xml or removing default entries- -- for image content types.-- -- [Content_Types].xml- let mkOverrideNode (part', contentType') = mknode "Override"- [("PartName", T.pack part')- ,("ContentType", contentType')] ()- let mkImageOverride (_, imgpath, mbMimeType, _) =- mkOverrideNode ("/word/" <> imgpath,- fromMaybe "application/octet-stream" mbMimeType)- let mkMediaOverride imgpath =- mkOverrideNode ("/" <> imgpath, getMimeTypeDef imgpath)- let overrides = map mkOverrideNode (- [("/word/webSettings.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml")- ,("/word/numbering.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml")- ,("/word/settings.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml")- ,("/word/theme/theme1.xml",- "application/vnd.openxmlformats-officedocument.theme+xml")- ,("/word/fontTable.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml")- ,("/docProps/app.xml",- "application/vnd.openxmlformats-officedocument.extended-properties+xml")- ,("/docProps/core.xml",- "application/vnd.openxmlformats-package.core-properties+xml")- ,("/docProps/custom.xml",- "application/vnd.openxmlformats-officedocument.custom-properties+xml")- ,("/word/styles.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml")- ,("/word/document.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")- ,("/word/comments.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml")- ,("/word/footnotes.xml",- "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml")- ] ++- map (\x -> (maybe "" (T.unpack . ("/word/" <>)) (extractTarget x),- "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml")) headers ++- map (\x -> (maybe "" (T.unpack . ("/word/" <>)) (extractTarget x),- "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml")) footers) ++- map mkImageOverride imgs ++- [ mkMediaOverride (eRelativePath e)- | e <- zEntries refArchive- , "word/media/" `isPrefixOf` eRelativePath e ]-- let mkDefaultNode (ext, mt) =- mknode "Default" [("Extension",ext),("ContentType",mt)] ()- let defaultnodes = map mkDefaultNode- [("xml", "application/xml"),- ("rels", "application/vnd.openxmlformats-package.relationships+xml"),- ("odttf",- "application/vnd.openxmlformats-officedocument.obfuscatedFont")]- let contentTypesDoc = mknode "Types" [("xmlns","http://schemas.openxmlformats.org/package/2006/content-types")] $ defaultnodes ++ overrides- let contentTypesEntry = toEntry "[Content_Types].xml" epochtime- $ renderXml contentTypesDoc-- let toImgRel (ident,path,_,_) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",T.pack ident),("Target",T.pack path)] ()- let imgrels = map toImgRel imgs- let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()- let linkrels = map toLinkRel $ M.toList $ stExternalLinks st- let reldoc = mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")] $ baserels ++ imgrels ++ linkrels- let relEntry = toEntry "word/_rels/document.xml.rels" epochtime- $ renderXml reldoc-- let contents' = BL.fromStrict $ UTF8.fromText contents-- -- word/document.xml- let contentEntry = toEntry "word/document.xml" epochtime contents'-- -- footnotes- let notes = mknode "w:footnotes" stdAttributes footnotes- let footnotesEntry = toEntry "word/footnotes.xml" epochtime $ renderXml notes-- -- footnote rels- let footnoteRelEntry = toEntry "word/_rels/footnotes.xml.rels" epochtime- $ renderXml $ mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]- linkrels-- -- comments- let commentsEntry = toEntry "word/comments.xml" epochtime- $ renderXml $ mknode "w:comments" stdAttributes comments-- -- styles-- -- We only want to inject paragraph and text properties that- -- are not already in the style map. Note that keys in the stylemap- -- are normalized as lowercase.- let newDynamicParaProps = filter- (\sty -> not $ hasStyleName sty $ smParaStyle styleMaps)- (Set.toList $ stDynamicParaProps st)-- newDynamicTextProps = filter- (\sty -> not $ hasStyleName sty $ smCharStyle styleMaps)- (Set.toList $ stDynamicTextProps st)-- let newstyles = map newParaPropToOpenXml newDynamicParaProps ++- map newTextPropToOpenXml newDynamicTextProps ++- (case writerHighlightMethod opts of- Skylighting sty -> styleToOpenXml styleMaps sty- DefaultHighlighting -> styleToOpenXml styleMaps- defaultStyle- _ -> [])- let styledoc' = styledoc{ elContent = elContent styledoc ++- map Elem newstyles }- let styleEntry = toEntry stylepath epochtime $ renderXml styledoc'-- -- construct word/numbering.xml- let numpath = "word/numbering.xml"- numbering <- parseXml refArchive distArchive numpath- let newNumElts = mkNumbering (stLists st)- let pandocAdded e =- case findAttrBy ((== "abstractNumId") . qName) e >>= safeRead of- Just numid -> numid >= (990 :: Int)- Nothing ->- case findAttrBy ((== "numId") . qName) e >>= safeRead of- Just numid -> numid >= (1000 :: Int)- Nothing -> False- let oldElts = filter (not . pandocAdded) $ onlyElems (elContent numbering)- let allElts = oldElts ++ newNumElts- let numEntry = toEntry numpath epochtime $ renderXml numbering{ elContent =- -- we want all the abstractNums first, then the nums,- -- otherwise things break:- [Elem e | e <- allElts- , qName (elName e) == "abstractNum" ] ++- [Elem e | e <- allElts- , qName (elName e) == "num" ] }-- let keywords = case lookupMeta "keywords" meta of- Just (MetaList xs) -> map stringify xs- _ -> []-- -- docProps/core.xml- let docPropsPath = "docProps/core.xml"- let extraCoreProps = ["subject","lang","category","description"]- let extraCorePropsMap = M.fromList $ zip extraCoreProps- ["dc:subject","dc:language","cp:category","dc:description"]- let lookupMetaString' :: Text -> Meta -> Text- lookupMetaString' key' meta' =- case key' of- "description" -> T.intercalate "_x000d_\n" (map stringify $ lookupMetaBlocks "description" meta')- key'' -> lookupMetaString key'' meta'-- let docProps = mknode "cp:coreProperties"- [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")- ,("xmlns:dc","http://purl.org/dc/elements/1.1/")- ,("xmlns:dcterms","http://purl.org/dc/terms/")- ,("xmlns:dcmitype","http://purl.org/dc/dcmitype/")- ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]- $ mktnode "dc:title" [] (stringify $ docTitle meta)- : mktnode "dc:creator" [] (T.intercalate "; " (map stringify $ docAuthors meta))- : [ mktnode (M.findWithDefault "" k extraCorePropsMap) [] (lookupMetaString' k meta)- | k <- M.keys (unMeta meta), k `elem` extraCoreProps]- ++ mknode "cp:keywords" [] (T.intercalate ", " keywords)- : (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x- , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x- ]) (T.pack $ formatTime defaultTimeLocale "%FT%XZ" utctime)- let docPropsEntry = toEntry docPropsPath epochtime $ renderXml docProps-- -- docProps/custom.xml- let customProperties :: [(Text, Text)]- customProperties = [ (k, lookupMetaString k meta)- | k <- M.keys (unMeta meta)- , k `notElem` (["title", "author", "keywords"]- ++ extraCoreProps)]- let mkCustomProp (k, v) pid = mknode "property"- [("fmtid","{D5CDD505-2E9C-101B-9397-08002B2CF9AE}")- ,("pid", tshow pid)- ,("name", k)] $ mknode "vt:lpwstr" [] v- let customPropsPath = "docProps/custom.xml"- let customProps = mknode "Properties"- [("xmlns","http://schemas.openxmlformats.org/officeDocument/2006/custom-properties")- ,("xmlns:vt","http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes")- ] $ zipWith mkCustomProp customProperties [(2 :: Int)..]- let customPropsEntry = toEntry customPropsPath epochtime $ renderXml customProps-- let relsPath = "_rels/.rels"- let rels = mknode "Relationships" [("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships")]- $ map (\attrs -> mknode "Relationship" attrs ())- [ [("Id","rId1")- ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")- ,("Target","word/document.xml")]- , [("Id","rId4")- ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties")- ,("Target","docProps/app.xml")]- , [("Id","rId3")- ,("Type","http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties")- ,("Target","docProps/core.xml")]- , [("Id","rId5")- ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties")- ,("Target","docProps/custom.xml")]- ]- let relsEntry = toEntry relsPath epochtime $ renderXml rels-- -- we use dist archive for settings.xml, because Word sometimes- -- adds references to footnotes or endnotes we don't have...- -- we do, however, copy some settings over from reference- let settingsPath = "word/settings.xml"-- settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime- -- note: these must go in the following order:- [ "writeProtection"- , "view"- , "zoom"- , "removePersonalInformation"- , "removeDateAndTime"- , "doNotDisplayPageBoundaries"- , "displayBackgroundShape"- , "printPostScriptOverText"- , "printFractionalCharacterWidth"- , "printFormsData"- , "embedTrueTypeFonts"- , "embedSystemFonts"- , "saveSubsetFonts"- , "saveFormsData"- , "mirrorMargins"- , "alignBordersAndEdges"- , "bordersDoNotSurroundHeader"- , "bordersDoNotSurroundFooter"- , "gutterAtTop"- , "hideSpellingErrors"- , "hideGrammaticalErrors"- , "activeWritingStyle"- , "proofState"- , "formsDesign"- , "attachedTemplate"- , "linkStyles"- , "stylePaneFormatFilter"- , "stylePaneSortMethod"- , "documentType"- , "mailMerge"- , "revisionView"- , "trackRevisions"- , "doNotTrackMoves"- , "doNotTrackFormatting"- , "documentProtection"- , "autoFormatOverride"- , "styleLockTheme"- , "styleLockQFSet"- , "defaultTabStop"- , "autoHyphenation"- , "consecutiveHyphenLimit"- , "hyphenationZone"- , "doNotHyphenateCaps"- , "showEnvelope"- , "summaryLength"- , "clickAndTypeStyle"- , "defaultTableStyle"- , "evenAndOddHeaders"- , "bookFoldRevPrinting"- , "bookFoldPrinting"- , "bookFoldPrintingSheets"- , "drawingGridHorizontalSpacing"- , "drawingGridVerticalSpacing"- , "displayHorizontalDrawingGridEvery"- , "displayVerticalDrawingGridEvery"- , "doNotUseMarginsForDrawingGridOrigin"- , "drawingGridHorizontalOrigin"- , "drawingGridVerticalOrigin"- , "doNotShadeFormData"- , "noPunctuationKerning"- , "characterSpacingControl"- , "printTwoOnOne"- , "strictFirstAndLastChars"- , "noLineBreaksAfter"- , "noLineBreaksBefore"- , "savePreviewPicture"- , "doNotValidateAgainstSchema"- , "saveInvalidXml"- , "ignoreMixedContent"- , "alwaysShowPlaceholderText"- , "doNotDemarcateInvalidXml"- , "saveXmlDataOnly"- , "useXSLTWhenSaving"- , "saveThroughXslt"- , "showXMLTags"- , "alwaysMergeEmptyNamespace"- , "updateFields"- , "hdrShapeDefaults"- -- , "footnotePr" -- this can cause problems, see #9522- -- , "endnotePr"- , "compat"- , "docVars"- , "rsids"- , "attachedSchema"- , "themeFontLang"- , "clrSchemeMapping"- , "doNotIncludeSubdocsInStats"- , "doNotAutoCompressPictures"- , "forceUpgrade"- , "captions"- , "readModeInkLockDown"- , "smartTagType"- , "shapeDefaults"- , "doNotEmbedSmartTags"- , "decimalSymbol"- , "listSeparator" ]-- let entryFromArchive arch path =- maybe (throwError $ PandocSomeError- $ T.pack $ path ++ " missing in reference docx")- return- (findEntryByPath path arch `mplus` findEntryByPath path distArchive)- docPropsAppEntry <- entryFromArchive refArchive "docProps/app.xml"- themeEntry <- entryFromArchive refArchive "word/theme/theme1.xml"- fontTableEntry <- entryFromArchive refArchive "word/fontTable.xml"- let fontTableRelsEntries = maybeToList $- findEntryByPath "word/_rels/fontTable.xml.rels" refArchive- let fontEntries = [entry | entry <- zEntries refArchive- , "word/fonts/" `isPrefixOf` (eRelativePath entry)]- -- or parse fontTable.xml.rels?- webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"- headerFooterEntries <- mapM (entryFromArchive refArchive . ("word/" ++)) $- mapMaybe (fmap T.unpack . extractTarget)- (headers ++ footers)- let miscRelEntries = [ e | e <- zEntries refArchive- , "word/_rels/" `isPrefixOf` eRelativePath e- , ".xml.rels" `isSuffixOf` eRelativePath e- , eRelativePath e /= "word/_rels/document.xml.rels"- , eRelativePath e /= "word/_rels/footnotes.xml.rels" ]- let otherMediaEntries = [ e | e <- zEntries refArchive- , "word/media/" `isPrefixOf` eRelativePath e ]-- -- Create archive- let archive = foldr addEntryToArchive emptyArchive $- contentTypesEntry : relsEntry : contentEntry : relEntry :- footnoteRelEntry : numEntry : styleEntry : footnotesEntry :- commentsEntry :- docPropsEntry : docPropsAppEntry : customPropsEntry :- themeEntry :- settingsEntry : webSettingsEntry :- fontTableEntry :- fontTableRelsEntries ++ fontEntries ++- imageEntries ++ headerFooterEntries ++- miscRelEntries ++ otherMediaEntries- return $ fromArchive archive--newParaPropToOpenXml :: ParaStyleName -> Element-newParaPropToOpenXml (fromStyleName -> s) =- let styleId = T.filter (not . isSpace) s- in mknode "w:style" [ ("w:type", "paragraph")- , ("w:customStyle", "1")- , ("w:styleId", styleId)]- [ mknode "w:name" [("w:val", s)] ()- , mknode "w:basedOn" [("w:val","BodyText")] ()- , mknode "w:qFormat" [] ()- ]--newTextPropToOpenXml :: CharStyleName -> Element-newTextPropToOpenXml (fromStyleName -> s) =- let styleId = T.filter (not . isSpace) s- in mknode "w:style" [ ("w:type", "character")- , ("w:customStyle", "1")- , ("w:styleId", styleId)]- [ mknode "w:name" [("w:val", s)] ()- , mknode "w:basedOn" [("w:val","BodyTextChar")] ()- ]--styleToOpenXml :: StyleMaps -> Style -> [Element]-styleToOpenXml sm style =- maybeToList parStyle ++ mapMaybe toStyle alltoktypes- where alltoktypes = enumFromTo KeywordTok NormalTok- toStyle toktype | hasStyleName (fromString $ show toktype) (smCharStyle sm) = Nothing- | otherwise = Just $- mknode "w:style" [("w:type","character"),- ("w:customStyle","1"),("w:styleId", tshow toktype)]- [ mknode "w:name" [("w:val", tshow toktype)] ()- , mknode "w:basedOn" [("w:val","VerbatimChar")] ()- , mknode "w:rPr" [] $- [ mknode "w:b" [] () | tokFeature tokenBold toktype ] ++- [ mknode "w:i" [] () | tokFeature tokenItalic toktype ] ++- [ mknode "w:color" [("w:val", tokCol toktype)] ()- | tokCol toktype /= "auto" ] ++- [ mknode "w:u" [] () | tokFeature tokenUnderline toktype ] ++- [ mknode "w:shd" [("w:val","clear")- ,("w:fill",tokBg toktype)] ()- | tokBg toktype /= "auto" ]- ]- tokStyles = tokenStyles style- tokFeature f toktype = maybe False f $ M.lookup toktype tokStyles- tokCol toktype = maybe "auto" (T.pack . drop 1 . fromColor)- $ (tokenColor =<< M.lookup toktype tokStyles)- `mplus` defaultColor style- tokBg toktype = maybe "auto" (T.pack . drop 1 . fromColor)- $ (tokenBackground =<< M.lookup toktype tokStyles)- `mplus` backgroundColor style- parStyle | hasStyleName "Source Code" (smParaStyle sm) = Nothing- | otherwise = Just $- mknode "w:style" [("w:type","paragraph"),- ("w:customStyle","1"),("w:styleId","SourceCode")]- [ mknode "w:name" [("w:val","Source Code")] ()- , mknode "w:basedOn" [("w:val","Normal")] ()- , mknode "w:link" [("w:val","VerbatimChar")] ()- , mknode "w:pPr" []- $ mknode "w:wordWrap" [("w:val","off")] ()- :- maybe [] (\col -> [mknode "w:shd" [("w:val","clear"),("w:fill", T.pack $ drop 1 $ fromColor col)] ()]) (backgroundColor style)- ]--copyChildren :: (PandocMonad m)- => Archive -> Archive -> String -> Integer -> [Text] -> m Entry-copyChildren refArchive distArchive path timestamp elNames = do- ref <- parseXml refArchive distArchive path- dist <- parseXml distArchive distArchive path- els <- foldM (addEl ref dist) [] (reverse elNames)- return $ toEntry path timestamp- $ renderXml dist{ elContent = map cleanElem els }- where- addEl ref dist els name =- case filterChildName (hasName name) ref `mplus`- filterChildName (hasName name) dist of- Just el -> pure (el : els)- Nothing -> pure els- hasName name = (== name) . qName- cleanElem el@Element{elName=name} = Elem el{elName=name{qURI=Nothing}}---- this is the lowest number used for a list numId-baseListId :: Int-baseListId = 1000--mkNumbering :: [ListMarker] -> [Element]-mkNumbering lists =- elts ++ zipWith mkNum lists [baseListId..(baseListId + length lists - 1)]- where elts = map mkAbstractNum (nubOrd lists)--mkNum :: ListMarker -> Int -> Element-mkNum marker numid =- mknode "w:num" [("w:numId",tshow numid)]- $ mknode "w:abstractNumId" [("w:val",listMarkerToId marker)] ()- : case marker of- NoMarker -> []- BulletMarker -> []- CheckboxMarker _ -> []- NumberMarker _ _ start ->- map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",tshow (lvl :: Int))]- $ mknode "w:startOverride" [("w:val",tshow start)] ())- [0..maxListLevel]--mkAbstractNum :: ListMarker -> Element-mkAbstractNum marker =- mknode "w:abstractNum" [("w:abstractNumId",listMarkerToId marker)]- $ mknode "w:nsid" [("w:val", T.justifyRight 8 '0' ("A" <> listMarkerToId marker))] ()- : mknode "w:multiLevelType" [("w:val","multilevel")] ()- : map (mkLvl marker)- [0..maxListLevel]--mkLvl :: ListMarker -> Int -> Element-mkLvl marker lvl =- mknode "w:lvl" [("w:ilvl",tshow lvl)] $- (case marker of- NumberMarker{} -> [mknode "w:start" [("w:val",start)] ()]- _ -> []) ++- [ mknode "w:numFmt" [("w:val",fmt)] ()- , mknode "w:lvlText" [("w:val", lvltxt)] ()- , mknode "w:lvlJc" [("w:val","left")] ()- , mknode "w:pPr" [] $- mknode "w:ind" [ ("w:left",tshow $ lvl * step + step)- , ("w:hanging",tshow hang)- ] ()- ] ++- maybe [] (\font ->- [ mknode "w:rPr" []- [ mknode "w:rFonts" [ ("w:ascii", font)- , ("w:hAnsi", font)- , ("w:cs", font)- , ("w:hint", "default") ] () ]]) mbfont- where (fmt, lvltxt, mbfont, start) =- case marker of- NoMarker -> ("bullet"," ", Nothing, "1")- BulletMarker -> bulletFor lvl- CheckboxMarker False -> ("bullet","\9744", Nothing, "1")- CheckboxMarker True -> ("bullet","\9746", Nothing, "1")- NumberMarker st de n -> (styleFor st lvl- ,patternFor de ("%" <> tshow (lvl + 1))- ,Nothing- ,tshow n)- step = 720- hang :: Int- hang = 360- bulletFor 0 = ("bullet", "\xf0b7", Just "Symbol", "1") -- filled circle- bulletFor 1 = ("bullet", "o", Just "Courier New", "1") -- open o- bulletFor 2 = ("bullet", "\xf0a7", Just "Wingdings", "1") -- closed box- bulletFor x = bulletFor (x `mod` 3)- styleFor UpperAlpha _ = "upperLetter"- styleFor LowerAlpha _ = "lowerLetter"- styleFor UpperRoman _ = "upperRoman"- styleFor LowerRoman _ = "lowerRoman"- styleFor Decimal _ = "decimal"- styleFor DefaultStyle 0 = "decimal"- styleFor DefaultStyle 1 = "lowerLetter"- styleFor DefaultStyle 2 = "lowerRoman"- styleFor DefaultStyle 3 = "decimal"- styleFor DefaultStyle 4 = "lowerLetter"- styleFor DefaultStyle 5 = "lowerRoman"- styleFor DefaultStyle x = styleFor DefaultStyle (x `mod` 6)- styleFor _ _ = "decimal"- patternFor OneParen s = s <> ")"- patternFor TwoParens s = "(" <> s <> ")"- patternFor _ s = s <> "."+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import Data.Containers.ListUtils (nubOrd)+import Data.Char (isSpace)+import Data.List (isPrefixOf, isSuffixOf)+import Data.String (fromString)+import qualified Data.Map as M+import Data.Maybe (fromMaybe, mapMaybe, maybeToList)+import qualified Data.Set as Set+import qualified Data.Text as T+import Data.Text (Text)+import Data.Time.Clock.POSIX+import Skylighting+import Text.Pandoc.Class (PandocMonad, toLang)+import qualified Text.Pandoc.Class.PandocMonad as P+import Text.Pandoc.Data (readDataFile, readDefaultDataFile)+import Data.Time+import qualified Text.Pandoc.UTF8 as UTF8+import Text.Pandoc.Definition+import Text.Pandoc.Error+import Text.Pandoc.Highlighting (defaultStyle)+import Text.Pandoc.MIME (MimeType, getMimeTypeDef)+import Text.Pandoc.Options+import Text.Pandoc.Writers.Docx.StyleMap+import Text.Pandoc.Writers.Docx.Types+import Text.Pandoc.Writers.Docx.OpenXML (writeOpenXML, maxListLevel)+import Text.Pandoc.Shared+import Text.Pandoc.Walk+import Text.Pandoc.Writers.Shared+import Text.Pandoc.Writers.OOXML+import Text.Pandoc.XML.Light as XML+import Text.Collate.Lang (renderLang, Lang(..))++writeDocx :: (PandocMonad m)+ => WriterOptions -- ^ Writer options+ -> Pandoc -- ^ Document to convert+ -> m BL.ByteString+writeDocx opts doc = do+ -- Phase 1: Document preprocessing+ let Pandoc meta blocks = walk fixDisplayMath doc+ setupTranslations meta+ let blocks' = makeSectionsWithOffsets (writerNumberOffset opts)+ True Nothing blocks+ let doc' = Pandoc meta blocks'++ -- Phase 2: Archive loading+ (refArchive, distArchive, username, utctime) <- loadArchives opts+ let epochtime = floor $ utcTimeToPOSIXSeconds utctime++ -- Phase 3: Page layout extraction+ (mbsectpr, pgContentWidth) <- extractPageLayout refArchive distArchive++ -- Phase 4: Language & style setup+ mblang <- toLang $ getLang opts meta+ let addLang = mkLangTransformer mblang+ styledoc <- addLang <$> parseXml refArchive distArchive "word/styles.xml"+ let styleMaps = getStyleMaps refArchive++ let tocTitle = case lookupMetaInlines "toc-title" meta of+ [] -> stTocTitle defaultWriterState+ ls -> ls++ let isRTLmeta = case lookupMeta "dir" meta of+ Just (MetaString "rtl") -> True+ Just (MetaInlines [Str "rtl"]) -> True+ _ -> False++ let env = defaultWriterEnv {+ envRTL = isRTLmeta+ , envChangesAuthor = fromMaybe "unknown" username+ , envChangesDate = T.pack $ formatTime defaultTimeLocale "%FT%XZ" utctime+ , envPrintWidth = maybe 420 (`quot` 20) pgContentWidth+ }++ -- Phase 5: Relationship extraction+ (baserels, headers, footers, newMaxRelId) <- extractRelationships refArchive distArchive++ let initialSt = defaultWriterState {+ stStyleMaps = styleMaps+ , stTocTitle = tocTitle+ , stCurId = newMaxRelId + 1+ }++ -- Phase 6: Core content generation+ -- adjust contents to add sectPr from reference.docx+ let sectpr = case mbsectpr of+ Just sectpr' -> add_attrs (elAttribs sectpr') $ mknode "w:sectPr" []+ (elChildren sectpr')+ Nothing -> mknode "w:sectPr" []+ [ mknode "w:footnotePr" []+ [ mknode "w:numRestart" [("w:val","eachSect")] () ]+ ]++ ((contents, footnotes, comments), st) <- runStateT+ (runReaderT+ (writeOpenXML opts{ writerWrapText = WrapNone }+ doc')+ env{ envSectPr = Just sectpr })+ initialSt+ let imgs = M.elems $ stImages st++ -- Phase 7: XML document construction+ -- We create [Content_Types].xml and word/_rels/document.xml.rels+ -- from scratch rather than reading from reference.docx,+ -- because Word sometimes changes these files when a reference.docx is modified,+ -- e.g. deleting the reference to footnotes.xml or removing default entries+ -- for image content types.+ let contentTypesEntry = mkContentTypesEntry epochtime imgs headers footers refArchive+ let relEntry = mkDocumentRelsEntry epochtime baserels imgs (stExternalLinks st)+ let contentEntry = toEntry "word/document.xml" epochtime+ (BL.fromStrict $ UTF8.fromText contents)+ let footnotesEntry = mkFootnotesEntry epochtime footnotes+ let footnoteRelEntry = mkFootnoteRelsEntry epochtime (stExternalLinks st)+ let commentsEntry = mkCommentsEntry epochtime comments+ let styleEntry = mkStylesEntry epochtime styledoc styleMaps st opts+ numEntry <- mkNumberingEntry refArchive distArchive epochtime (stLists st)+ let docPropsEntry = mkCorePropsEntry epochtime utctime meta+ let customPropsEntry = mkCustomPropsEntry epochtime meta+ let relsEntry = mkPackageRelsEntry epochtime++ -- we use dist archive for settings.xml, because Word sometimes+ -- adds references to footnotes or endnotes we don't have...+ -- we do, however, copy some settings over from reference+ settingsEntry <- copyChildren refArchive distArchive "word/settings.xml"+ epochtime settingsElementNames++ -- Phase 8: Archive assembly+ let toImageEntry (_, path, _, img) = toEntry ("word/" ++ path) epochtime $ toLazy img+ let imageEntries = map toImageEntry imgs++ refEntries <- collectReferenceEntries refArchive distArchive headers footers++ let archive = foldr addEntryToArchive emptyArchive $+ contentTypesEntry : relsEntry : contentEntry : relEntry :+ footnoteRelEntry : numEntry : styleEntry : footnotesEntry :+ commentsEntry :+ docPropsEntry : customPropsEntry :+ settingsEntry :+ imageEntries ++ refEntries+ return $ fromArchive archive++newParaPropToOpenXml :: ParaStyleName -> Element+newParaPropToOpenXml (fromStyleName -> s) =+ let styleId = T.filter (not . isSpace) s+ in mknode "w:style" [ ("w:type", "paragraph")+ , ("w:customStyle", "1")+ , ("w:styleId", styleId)]+ [ mknode "w:name" [("w:val", s)] ()+ , mknode "w:basedOn" [("w:val","BodyText")] ()+ , mknode "w:qFormat" [] ()+ ]++newTextPropToOpenXml :: CharStyleName -> Element+newTextPropToOpenXml (fromStyleName -> s) =+ let styleId = T.filter (not . isSpace) s+ in mknode "w:style" [ ("w:type", "character")+ , ("w:customStyle", "1")+ , ("w:styleId", styleId)]+ [ mknode "w:name" [("w:val", s)] ()+ , mknode "w:basedOn" [("w:val","BodyTextChar")] ()+ ]++styleToOpenXml :: StyleMaps -> Style -> [Element]+styleToOpenXml sm style =+ maybeToList parStyle ++ mapMaybe toStyle alltoktypes+ where alltoktypes = enumFromTo KeywordTok NormalTok+ toStyle toktype | hasStyleName (fromString $ show toktype) (smCharStyle sm) = Nothing+ | otherwise = Just $+ mknode "w:style" [("w:type","character"),+ ("w:customStyle","1"),("w:styleId", tshow toktype)]+ [ mknode "w:name" [("w:val", tshow toktype)] ()+ , mknode "w:basedOn" [("w:val","VerbatimChar")] ()+ , mknode "w:rPr" [] $+ [ mknode "w:b" [] () | tokFeature tokenBold toktype ] +++ [ mknode "w:i" [] () | tokFeature tokenItalic toktype ] +++ [ mknode "w:color" [("w:val", tokCol toktype)] ()+ | tokCol toktype /= "auto" ] +++ [ mknode "w:u" [] () | tokFeature tokenUnderline toktype ] +++ [ mknode "w:shd" [("w:val","clear")+ ,("w:fill",tokBg toktype)] ()+ | tokBg toktype /= "auto" ]+ ]+ tokStyles = tokenStyles style+ tokFeature f toktype = maybe False f $ M.lookup toktype tokStyles+ tokCol toktype = maybe "auto" (T.pack . drop 1 . fromColor)+ $ (tokenColor =<< M.lookup toktype tokStyles)+ `mplus` defaultColor style+ tokBg toktype = maybe "auto" (T.pack . drop 1 . fromColor)+ $ (tokenBackground =<< M.lookup toktype tokStyles)+ `mplus` backgroundColor style+ parStyle | hasStyleName "Source Code" (smParaStyle sm) = Nothing+ | otherwise = Just $+ mknode "w:style" [("w:type","paragraph"),+ ("w:customStyle","1"),("w:styleId","SourceCode")]+ [ mknode "w:name" [("w:val","Source Code")] ()+ , mknode "w:basedOn" [("w:val","Normal")] ()+ , mknode "w:link" [("w:val","VerbatimChar")] ()+ , mknode "w:pPr" []+ $ mknode "w:wordWrap" [("w:val","off")] ()+ :+ maybe [] (\col -> [mknode "w:shd" [("w:val","clear"),("w:fill", T.pack $ drop 1 $ fromColor col)] ()]) (backgroundColor style)+ ]++copyChildren :: (PandocMonad m)+ => Archive -> Archive -> String -> Integer -> [Text] -> m Entry+copyChildren refArchive distArchive path timestamp elNames = do+ ref <- parseXml refArchive distArchive path+ dist <- parseXml distArchive distArchive path+ els <- foldM (addEl ref dist) [] (reverse elNames)+ return $ toEntry path timestamp+ $ renderXml dist{ elContent = map cleanElem els }+ where+ addEl ref dist els name =+ case filterChildName (hasName name) ref `mplus`+ filterChildName (hasName name) dist of+ Just el -> pure (el : els)+ Nothing -> pure els+ hasName name = (== name) . qName+ cleanElem el@Element{elName=name} = Elem el{elName=name{qURI=Nothing}}++-- this is the lowest number used for a list numId+baseListId :: Int+baseListId = 1000++-- | Standard XML namespace attributes for docx elements+stdAttributes :: [(Text, Text)]+stdAttributes =+ [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")+ ,("xmlns:m","http://schemas.openxmlformats.org/officeDocument/2006/math")+ ,("xmlns:r","http://schemas.openxmlformats.org/officeDocument/2006/relationships")+ ,("xmlns:o","urn:schemas-microsoft-com:office:office")+ ,("xmlns:v","urn:schemas-microsoft-com:vml")+ ,("xmlns:w10","urn:schemas-microsoft-com:office:word")+ ,("xmlns:a","http://schemas.openxmlformats.org/drawingml/2006/main")+ ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")+ ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]++-- | Settings elements to copy from reference.docx (order matters)+settingsElementNames :: [Text]+settingsElementNames =+ [ "writeProtection"+ , "view"+ , "zoom"+ , "removePersonalInformation"+ , "removeDateAndTime"+ , "doNotDisplayPageBoundaries"+ , "displayBackgroundShape"+ , "printPostScriptOverText"+ , "printFractionalCharacterWidth"+ , "printFormsData"+ , "embedTrueTypeFonts"+ , "embedSystemFonts"+ , "saveSubsetFonts"+ , "saveFormsData"+ , "mirrorMargins"+ , "alignBordersAndEdges"+ , "bordersDoNotSurroundHeader"+ , "bordersDoNotSurroundFooter"+ , "gutterAtTop"+ , "hideSpellingErrors"+ , "hideGrammaticalErrors"+ , "activeWritingStyle"+ , "proofState"+ , "formsDesign"+ , "attachedTemplate"+ , "linkStyles"+ , "stylePaneFormatFilter"+ , "stylePaneSortMethod"+ , "documentType"+ , "mailMerge"+ , "revisionView"+ , "trackRevisions"+ , "doNotTrackMoves"+ , "doNotTrackFormatting"+ , "documentProtection"+ , "autoFormatOverride"+ , "styleLockTheme"+ , "styleLockQFSet"+ , "defaultTabStop"+ , "autoHyphenation"+ , "consecutiveHyphenLimit"+ , "hyphenationZone"+ , "doNotHyphenateCaps"+ , "showEnvelope"+ , "summaryLength"+ , "clickAndTypeStyle"+ , "defaultTableStyle"+ , "evenAndOddHeaders"+ , "bookFoldRevPrinting"+ , "bookFoldPrinting"+ , "bookFoldPrintingSheets"+ , "drawingGridHorizontalSpacing"+ , "drawingGridVerticalSpacing"+ , "displayHorizontalDrawingGridEvery"+ , "displayVerticalDrawingGridEvery"+ , "doNotUseMarginsForDrawingGridOrigin"+ , "drawingGridHorizontalOrigin"+ , "drawingGridVerticalOrigin"+ , "doNotShadeFormData"+ , "noPunctuationKerning"+ , "characterSpacingControl"+ , "printTwoOnOne"+ , "strictFirstAndLastChars"+ , "noLineBreaksAfter"+ , "noLineBreaksBefore"+ , "savePreviewPicture"+ , "doNotValidateAgainstSchema"+ , "saveInvalidXml"+ , "ignoreMixedContent"+ , "alwaysShowPlaceholderText"+ , "doNotDemarcateInvalidXml"+ , "saveXmlDataOnly"+ , "useXSLTWhenSaving"+ , "saveThroughXslt"+ , "showXMLTags"+ , "alwaysMergeEmptyNamespace"+ , "updateFields"+ , "hdrShapeDefaults"+ -- , "footnotePr" -- this can cause problems, see #9522+ -- , "endnotePr"+ , "compat"+ , "docVars"+ , "rsids"+ , "attachedSchema"+ , "themeFontLang"+ , "clrSchemeMapping"+ , "doNotIncludeSubdocsInStats"+ , "doNotAutoCompressPictures"+ , "forceUpgrade"+ , "captions"+ , "readModeInkLockDown"+ , "smartTagType"+ , "shapeDefaults"+ , "doNotEmbedSmartTags"+ , "decimalSymbol"+ , "listSeparator" ]++mkNumbering :: [ListMarker] -> [Element]+mkNumbering lists =+ elts ++ zipWith mkNum lists [baseListId..(baseListId + length lists - 1)]+ where elts = map mkAbstractNum (nubOrd lists)++mkNum :: ListMarker -> Int -> Element+mkNum marker numid =+ mknode "w:num" [("w:numId",tshow numid)]+ $ mknode "w:abstractNumId" [("w:val",listMarkerToId marker)] ()+ : case marker of+ NoMarker -> []+ BulletMarker -> []+ CheckboxMarker _ -> []+ NumberMarker _ _ start ->+ map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",tshow (lvl :: Int))]+ $ mknode "w:startOverride" [("w:val",tshow start)] ())+ [0..maxListLevel]++mkAbstractNum :: ListMarker -> Element+mkAbstractNum marker =+ mknode "w:abstractNum" [("w:abstractNumId",listMarkerToId marker)]+ $ mknode "w:nsid" [("w:val", T.justifyRight 8 '0' ("A" <> listMarkerToId marker))] ()+ : mknode "w:multiLevelType" [("w:val","multilevel")] ()+ : map (mkLvl marker)+ [0..maxListLevel]++mkLvl :: ListMarker -> Int -> Element+mkLvl marker lvl =+ mknode "w:lvl" [("w:ilvl",tshow lvl)] $+ (case marker of+ NumberMarker{} -> [mknode "w:start" [("w:val",start)] ()]+ _ -> []) +++ [ mknode "w:numFmt" [("w:val",fmt)] ()+ , mknode "w:lvlText" [("w:val", lvltxt)] ()+ , mknode "w:lvlJc" [("w:val","left")] ()+ , mknode "w:pPr" [] $+ mknode "w:ind" [ ("w:left",tshow $ lvl * step + step)+ , ("w:hanging",tshow hang)+ ] ()+ ] +++ maybe [] (\font ->+ [ mknode "w:rPr" []+ [ mknode "w:rFonts" [ ("w:ascii", font)+ , ("w:hAnsi", font)+ , ("w:cs", font)+ , ("w:hint", "default") ] () ]]) mbfont+ where (fmt, lvltxt, mbfont, start) =+ case marker of+ NoMarker -> ("bullet"," ", Nothing, "1")+ BulletMarker -> bulletFor lvl+ CheckboxMarker False -> ("bullet","\9744", Nothing, "1")+ CheckboxMarker True -> ("bullet","\9746", Nothing, "1")+ NumberMarker st de n -> (styleFor st lvl+ ,patternFor de ("%" <> tshow (lvl + 1))+ ,Nothing+ ,tshow n)+ step = 720+ hang :: Int+ hang = 360+ bulletFor 0 = ("bullet", "\xf0b7", Just "Symbol", "1") -- filled circle+ bulletFor 1 = ("bullet", "o", Just "Courier New", "1") -- open o+ bulletFor 2 = ("bullet", "\xf0a7", Just "Wingdings", "1") -- closed box+ bulletFor x = bulletFor (x `mod` 3)+ styleFor UpperAlpha _ = "upperLetter"+ styleFor LowerAlpha _ = "lowerLetter"+ styleFor UpperRoman _ = "upperRoman"+ styleFor LowerRoman _ = "lowerRoman"+ styleFor Decimal _ = "decimal"+ styleFor DefaultStyle 0 = "decimal"+ styleFor DefaultStyle 1 = "lowerLetter"+ styleFor DefaultStyle 2 = "lowerRoman"+ styleFor DefaultStyle 3 = "decimal"+ styleFor DefaultStyle 4 = "lowerLetter"+ styleFor DefaultStyle 5 = "lowerRoman"+ styleFor DefaultStyle x = styleFor DefaultStyle (x `mod` 6)+ styleFor _ _ = "decimal"+ patternFor OneParen s = s <> ")"+ patternFor TwoParens s = "(" <> s <> ")"+ patternFor _ s = s <> "."++-- | Build language transformer function for modifying XML elements.+-- Navigates directly to w:docDefaults/w:rPr/w:lang instead of generic traversal.+mkLangTransformer :: Maybe Lang -> (Element -> Element)+mkLangTransformer Nothing = id+mkLangTransformer (Just lang) = modifyAtPath path updateLangAttrs+ where+ -- Path is: w:docDefaults / w:rPrDefault / w:rPr / w:lang+ path = [named "docDefaults", named "rPrDefault", named "rPr", named "lang"]+ named n = (== n) . qName++ updateLangAttrs e+ | isEastAsianLang lang = e{ elAttribs = map (setattr "eastAsia") $ elAttribs e }+ | isBidiLang lang = e{ elAttribs = map (setattr "bidi") $ elAttribs e }+ | otherwise = e{ elAttribs = map (setattr "val") $ elAttribs e }++ setattr attrname (XML.Attr qn@(QName s _ _) _)+ | s == attrname = XML.Attr qn (renderLang lang)+ setattr _ x = x++ isEastAsianLang Lang{ langLanguage = l } = l == "zh" || l == "ja" || l == "ko"+ isBidiLang Lang{ langLanguage = l } = l == "he" || l == "ar"++-- | Modify an element at a specific path in the XML tree.+-- The path is a list of predicates that match element names at each level.+modifyAtPath :: [(QName -> Bool)] -> (Element -> Element) -> Element -> Element+modifyAtPath [] f e = f e+modifyAtPath (p:ps) f e = e{ elContent = map go (elContent e) }+ where+ go (Elem el) | p (elName el) = Elem (modifyAtPath ps f el)+ go c = c++-- | Load reference and distribution archives+loadArchives :: PandocMonad m+ => WriterOptions+ -> m (Archive, Archive, Maybe Text, UTCTime)+loadArchives opts = do+ username <- P.lookupEnv "USERNAME"+ utctime <- P.getTimestamp+ oldUserDataDir <- P.getUserDataDir+ P.setUserDataDir Nothing+ res <- readDefaultDataFile "reference.docx"+ P.setUserDataDir oldUserDataDir+ let distArchive = toArchive $ BL.fromStrict res+ refArchive <- case writerReferenceDoc opts of+ Just f -> toArchive . BL.fromStrict . fst+ <$> P.fetchItem (T.pack f)+ Nothing -> toArchive . BL.fromStrict <$>+ readDataFile "reference.docx"+ return (refArchive, distArchive, username, utctime)++-- | Extract page dimensions from template+extractPageLayout :: PandocMonad m+ => Archive -> Archive -> m (Maybe Element, Maybe Integer)+extractPageLayout refArchive distArchive = do+ parsedDoc <- parseXml refArchive distArchive "word/document.xml"+ let wname f qn = qPrefix qn == Just "w" && f (qName qn)+ let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc++ -- Gets the template size+ let mbpgsz = mbsectpr >>= filterElementName (wname (=="pgSz"))+ let mbAttrSzWidth = mbpgsz >>= lookupAttrBy ((=="w") . qName) . elAttribs++ let mbpgmar = mbsectpr >>= filterElementName (wname (=="pgMar"))+ let mbAttrMarLeft = mbpgmar >>= lookupAttrBy ((=="left") . qName) . elAttribs+ let mbAttrMarRight = mbpgmar >>= lookupAttrBy ((=="right") . qName) . elAttribs++ -- Get the available area (converting the size and the margins to int and+ -- doing the difference+ let pgContentWidth = do+ w <- mbAttrSzWidth >>= safeRead+ r <- mbAttrMarRight >>= safeRead+ l <- mbAttrMarLeft >>= safeRead+ pure $ w - r - l++ return (mbsectpr, pgContentWidth)++-- | Parse and augment relationships from reference.docx+extractRelationships :: PandocMonad m+ => Archive -> Archive+ -> m ([Element], [Element], [Element], Int)+extractRelationships refArchive distArchive = do+ let isImageNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"+ let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"+ let isFooterNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"+ parsedRels <- filterElements+ (\e -> isImageNode e || isHeaderNode e || isFooterNode e)+ <$> parseXml refArchive distArchive "word/_rels/document.xml.rels"+ let getRelId e =+ case findAttr (QName "Id" Nothing Nothing) e of+ Just ident -> T.stripPrefix "rId" ident >>= safeRead+ Nothing -> Nothing+ let relIds = mapMaybe getRelId parsedRels+ let maxRelId = if null relIds then 0 else maximum relIds++ let headers = filter isHeaderNode parsedRels+ let footers = filter isFooterNode parsedRels+ -- word/_rels/document.xml.rels+ let addBaseRel (url', target') (maxId, rels) =+ case [e | e <- rels+ , findAttr (QName "Target" Nothing Nothing) e ==+ Just target'] of+ [] -> (maxId + 1, mknode "Relationship"+ [("Type",url')+ ,("Id","rId" <> tshow (maxId + 1))+ ,("Target",target')] () : rels)+ _ -> (maxId, rels)++ let (newMaxRelId, baserels) = foldr addBaseRel (maxRelId, parsedRels)+ [("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",+ "numbering.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",+ "styles.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",+ "settings.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",+ "webSettings.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",+ "fontTable.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",+ "theme/theme1.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",+ "footnotes.xml")+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",+ "comments.xml")+ ]++ return (baserels, headers, footers, newMaxRelId)++-- | Create footnotes XML entry+mkFootnotesEntry :: Integer -> [Element] -> Entry+mkFootnotesEntry epochtime footnotes =+ let notes = mknode "w:footnotes" stdAttributes footnotes+ in toEntry "word/footnotes.xml" epochtime $ renderXml notes++-- | Create footnote relationships entry+mkFootnoteRelsEntry :: Integer -> M.Map Text Text -> Entry+mkFootnoteRelsEntry epochtime externalLinks =+ let linkrels = map toLinkRel $ M.toList externalLinks+ toLinkRel (src, ident) = mknode "Relationship"+ [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")+ ,("Id",ident)+ ,("Target",src)+ ,("TargetMode","External")] ()+ in toEntry "word/_rels/footnotes.xml.rels" epochtime+ $ renderXml $ mknode "Relationships"+ [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]+ linkrels++-- | Create comments XML entry+mkCommentsEntry :: Integer -> [Element] -> Entry+mkCommentsEntry epochtime comments =+ toEntry "word/comments.xml" epochtime+ $ renderXml $ mknode "w:comments" stdAttributes comments++-- | Create package-level relationships entry+mkPackageRelsEntry :: Integer -> Entry+mkPackageRelsEntry epochtime =+ let rels = mknode "Relationships"+ [("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships")]+ $ map (\attrs -> mknode "Relationship" attrs ())+ [ [("Id","rId1")+ ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")+ ,("Target","word/document.xml")]+ , [("Id","rId4")+ ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties")+ ,("Target","docProps/app.xml")]+ , [("Id","rId3")+ ,("Type","http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties")+ ,("Target","docProps/core.xml")]+ , [("Id","rId5")+ ,("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties")+ ,("Target","docProps/custom.xml")]+ ]+ in toEntry "_rels/.rels" epochtime $ renderXml rels++-- | Create content types manifest entry+mkContentTypesEntry :: Integer+ -> [(String, String, Maybe MimeType, B.ByteString)] -- imgs+ -> [Element] -- headers+ -> [Element] -- footers+ -> Archive -- refArchive+ -> Entry+mkContentTypesEntry epochtime imgs headers footers refArchive =+ let mkOverrideNode (part', contentType') = mknode "Override"+ [("PartName", T.pack part')+ ,("ContentType", contentType')] ()+ mkImageOverride (_, imgpath, mbMimeType, _) =+ mkOverrideNode ("/word/" <> imgpath,+ fromMaybe "application/octet-stream" mbMimeType)+ mkMediaOverride imgpath =+ mkOverrideNode ("/" <> imgpath, getMimeTypeDef imgpath)+ unrelativize ('/':xs) = '/':xs+ unrelativize xs = "/word/" ++ xs+ overrides = map mkOverrideNode (+ [("/word/webSettings.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml")+ ,("/word/numbering.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml")+ ,("/word/settings.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml")+ ,("/word/theme/theme1.xml",+ "application/vnd.openxmlformats-officedocument.theme+xml")+ ,("/word/fontTable.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml")+ ,("/docProps/app.xml",+ "application/vnd.openxmlformats-officedocument.extended-properties+xml")+ ,("/docProps/core.xml",+ "application/vnd.openxmlformats-package.core-properties+xml")+ ,("/docProps/custom.xml",+ "application/vnd.openxmlformats-officedocument.custom-properties+xml")+ ,("/word/styles.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml")+ ,("/word/document.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")+ ,("/word/comments.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml")+ ,("/word/footnotes.xml",+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml")+ ] +++ map (\x -> (maybe "" (unrelativize . T.unpack) (extractTarget x),+ "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml")) headers +++ map (\x -> (maybe "" (unrelativize . T.unpack) (extractTarget x),+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml")) footers) +++ map mkImageOverride imgs +++ [ mkMediaOverride (eRelativePath e)+ | e <- zEntries refArchive+ , "word/media/" `isPrefixOf` eRelativePath e+ , not ("/" `isSuffixOf` eRelativePath e) ]+ mkDefaultNode (ext, mt) =+ mknode "Default" [("Extension",ext),("ContentType",mt)] ()+ defaultnodes = map mkDefaultNode+ [("xml", "application/xml"),+ ("rels", "application/vnd.openxmlformats-package.relationships+xml"),+ ("odttf",+ "application/vnd.openxmlformats-officedocument.obfuscatedFont")]+ contentTypesDoc = mknode "Types"+ [("xmlns","http://schemas.openxmlformats.org/package/2006/content-types")]+ $ defaultnodes ++ overrides+ in toEntry "[Content_Types].xml" epochtime $ renderXml contentTypesDoc++-- | Create document relationships entry+mkDocumentRelsEntry :: Integer+ -> [Element] -- baserels+ -> [(String, String, Maybe MimeType, B.ByteString)] -- imgs+ -> M.Map Text Text -- externalLinks+ -> Entry+mkDocumentRelsEntry epochtime baserels imgs externalLinks =+ let toImgRel (ident, path, _, _) = mknode "Relationship"+ [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")+ ,("Id",T.pack ident)+ ,("Target",T.pack path)] ()+ imgrels = map toImgRel imgs+ toLinkRel (src, ident) = mknode "Relationship"+ [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")+ ,("Id",ident)+ ,("Target",src)+ ,("TargetMode","External")] ()+ linkrels = map toLinkRel $ M.toList externalLinks+ reldoc = mknode "Relationships"+ [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]+ $ baserels ++ imgrels ++ linkrels+ in toEntry "word/_rels/document.xml.rels" epochtime $ renderXml reldoc++-- | Create styles entry with dynamic additions+mkStylesEntry :: Integer -> Element -> StyleMaps -> WriterState -> WriterOptions -> Entry+mkStylesEntry epochtime styledoc styleMaps st opts =+ let stylepath = "word/styles.xml"+ -- We only want to inject paragraph and text properties that+ -- are not already in the style map. Note that keys in the stylemap+ -- are normalized as lowercase.+ newDynamicParaProps = filter+ (\sty -> not $ hasStyleName sty $ smParaStyle styleMaps)+ (Set.toList $ stDynamicParaProps st)++ newDynamicTextProps = filter+ (\sty -> not $ hasStyleName sty $ smCharStyle styleMaps)+ (Set.toList $ stDynamicTextProps st)++ newstyles = map newParaPropToOpenXml newDynamicParaProps +++ map newTextPropToOpenXml newDynamicTextProps +++ (case writerHighlightMethod opts of+ Skylighting sty -> styleToOpenXml styleMaps sty+ DefaultHighlighting -> styleToOpenXml styleMaps+ defaultStyle+ _ -> [])+ styledoc' = styledoc{ elContent = elContent styledoc +++ map Elem newstyles }+ in toEntry stylepath epochtime $ renderXml styledoc'++-- | Create core document properties entry+mkCorePropsEntry :: Integer -> UTCTime -> Meta -> Entry+mkCorePropsEntry epochtime utctime meta =+ let metaValueToText (MetaString s) = s+ metaValueToText (MetaInlines ils) = stringify ils+ metaValueToText (MetaBlocks bs) = stringify bs+ metaValueToText (MetaBool b) = T.pack (show b)+ metaValueToText _ = ""+ keywords = case lookupMeta "keywords" meta of+ Just (MetaList xs) -> map metaValueToText xs+ _ -> []+ docPropsPath = "docProps/core.xml"+ extraCoreProps = ["subject","lang","category","description"]+ extraCorePropsMap = M.fromList $ zip extraCoreProps+ ["dc:subject","dc:language","cp:category","dc:description"]+ lookupMetaString' :: Text -> Meta -> Text+ lookupMetaString' key' meta' =+ case key' of+ "description" -> T.intercalate "_x000d_\n"+ (map stringify $ lookupMetaBlocks "description" meta')+ key'' -> lookupMetaString key'' meta'++ docProps = mknode "cp:coreProperties"+ [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")+ ,("xmlns:dc","http://purl.org/dc/elements/1.1/")+ ,("xmlns:dcterms","http://purl.org/dc/terms/")+ ,("xmlns:dcmitype","http://purl.org/dc/dcmitype/")+ ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]+ $ mktnode "dc:title" [] (stringify $ docTitle meta)+ : mktnode "dc:creator" [] (T.intercalate "; " (map stringify $ docAuthors meta))+ : [ mktnode (M.findWithDefault "" k extraCorePropsMap) [] (lookupMetaString' k meta)+ | k <- M.keys (unMeta meta), k `elem` extraCoreProps]+ ++ mknode "cp:keywords" [] (T.intercalate ", " keywords)+ : (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x+ , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x+ ]) (T.pack $ formatTime defaultTimeLocale "%FT%XZ" utctime)+ in toEntry docPropsPath epochtime $ renderXml docProps++-- | Create custom document properties entry+mkCustomPropsEntry :: Integer -> Meta -> Entry+mkCustomPropsEntry epochtime meta =+ let extraCoreProps = ["subject","lang","category","description"]+ customProperties :: [(Text, Text)]+ customProperties = [ (k, lookupMetaString k meta)+ | k <- M.keys (unMeta meta)+ , k `notElem` (["title", "author", "keywords"]+ ++ extraCoreProps)]+ mkCustomProp (k, v) pid = mknode "property"+ [("fmtid","{D5CDD505-2E9C-101B-9397-08002B2CF9AE}")+ ,("pid", tshow pid)+ ,("name", k)] $ mknode "vt:lpwstr" [] v+ customPropsPath = "docProps/custom.xml"+ customProps = mknode "Properties"+ [("xmlns","http://schemas.openxmlformats.org/officeDocument/2006/custom-properties")+ ,("xmlns:vt","http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes")+ ] $ zipWith mkCustomProp customProperties [(2 :: Int)..]+ in toEntry customPropsPath epochtime $ renderXml customProps++-- | Create numbering entry+mkNumberingEntry :: PandocMonad m+ => Archive -> Archive -> Integer -> [ListMarker] -> m Entry+mkNumberingEntry refArchive distArchive epochtime lists = do+ let numpath = "word/numbering.xml"+ numbering <- parseXml refArchive distArchive numpath+ let newNumElts = mkNumbering lists+ let pandocAdded e =+ case findAttrBy ((== "abstractNumId") . qName) e >>= safeRead of+ Just numid -> numid >= (990 :: Int)+ Nothing ->+ case findAttrBy ((== "numId") . qName) e >>= safeRead of+ Just numid -> numid >= (1000 :: Int)+ Nothing -> False+ let oldElts = filter (not . pandocAdded) $ onlyElems (elContent numbering)+ let allElts = oldElts ++ newNumElts+ return $ toEntry numpath epochtime $ renderXml numbering{ elContent =+ -- we want all the abstractNums first, then the nums,+ -- otherwise things break:+ [Elem e | e <- allElts+ , qName (elName e) == "abstractNum" ] +++ [Elem e | e <- allElts+ , qName (elName e) == "num" ] }++-- | Collect auxiliary entries from reference archive+collectReferenceEntries :: PandocMonad m+ => Archive -> Archive -> [Element] -> [Element]+ -> m [Entry]+collectReferenceEntries refArchive distArchive headers footers = do+ let entryFromArchive arch path =+ maybe (throwError $ PandocSomeError+ $ T.pack $ path ++ " missing in reference docx")+ return+ (findEntryByPath path arch `mplus` findEntryByPath path distArchive)+ docPropsAppEntry <- entryFromArchive refArchive "docProps/app.xml"+ themeEntry <- entryFromArchive refArchive "word/theme/theme1.xml"+ fontTableEntry <- entryFromArchive refArchive "word/fontTable.xml"+ let fontTableRelsEntries = maybeToList $+ findEntryByPath "word/_rels/fontTable.xml.rels" refArchive+ let fontEntries = [entry | entry <- zEntries refArchive+ , "word/fonts/" `isPrefixOf` (eRelativePath entry)]+ webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"+ let unrelativize ('/':xs) = xs+ unrelativize xs = "word/" ++ xs+ headerFooterEntries <- mapM (entryFromArchive refArchive . unrelativize) $+ mapMaybe (fmap T.unpack . extractTarget)+ (headers ++ footers)+ let miscRelEntries = [ e | e <- zEntries refArchive+ , "word/_rels/" `isPrefixOf` eRelativePath e+ , ".xml.rels" `isSuffixOf` eRelativePath e+ , eRelativePath e /= "word/_rels/document.xml.rels"+ , eRelativePath e /= "word/_rels/footnotes.xml.rels" ]+ let otherMediaEntries = [ e | e <- zEntries refArchive+ , "word/media/" `isPrefixOf` eRelativePath e ]+ return $ docPropsAppEntry : themeEntry : fontTableEntry : webSettingsEntry+ : fontTableRelsEntries ++ fontEntries ++ headerFooterEntries+ ++ miscRelEntries ++ otherMediaEntries++extractTarget :: Element -> Maybe Text+extractTarget = findAttr (QName "Target" Nothing Nothing)
src/Text/Pandoc/Writers/Docx/OpenXML.hs view
@@ -20,7 +20,7 @@ -} module Text.Pandoc.Writers.Docx.OpenXML ( writeOpenXML, maxListLevel ) where -import Control.Monad ((>=>), when, unless)+import Control.Monad (when, unless) import Control.Applicative ((<|>)) import Control.Monad.Except (catchError) import Crypto.Hash (hashWith, SHA1(SHA1))@@ -329,14 +329,6 @@ blocksToOpenXML opts = fmap concat . mapM (blockToOpenXML opts) . separateTables . filter (not . isForeignRawBlock)- >=>- \case- a@(x:xs) -> do- sep <- sectionSeparator- if Just x == sep- then pure xs- else pure a- [] -> pure [] isForeignRawBlock :: Block -> Bool isForeignRawBlock (RawBlock format _) = format /= "openxml"@@ -414,9 +406,19 @@ Nothing -> return [] else return [] contents <- (number ++) <$> inlinesToOpenXML opts lst- addSectionBreak <- sectionSeparator >>= \case- Just sep | isSection -> pure (sep:)- _ -> pure id+ -- Add section break before section-level headers, but not for the first one+ -- to avoid a blank first page (#10578, #11482).+ addSectionBreak <- if isSection+ then do+ isFirst <- gets stFirstSectionHeader+ if isFirst+ then do+ modify $ \s -> s { stFirstSectionHeader = False }+ pure id+ else sectionSeparator >>= \case+ Just sep -> pure (sep:)+ Nothing -> pure id+ else pure id addSectionBreak <$> if T.null ident then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)]@@ -436,6 +438,10 @@ else block blockToOpenXML' opts (Para lst) | null lst && not (isEnabled Ext_empty_paragraphs opts) = return []+ | [Math InlineMath _] <- lst+ = blockToOpenXML' opts (Para (lst ++ [Str "\x200B"])) -- see #11674+ -- we add a space to prevent Word from displaying the single+ -- inline math element with display math style | otherwise = do isFirstPara <- gets stFirstPara let displayMathPara = case lst of@@ -905,6 +911,7 @@ inlineToOpenXML' opts (Note bs) = do notes <- gets stFootnotes notenum <- getUniqueId+ oldFirstPara <- gets stFirstPara footnoteStyle <- rStyleM "Footnote Reference" let notemarker = mknode "w:r" [] [ mknode "w:rPr" [] footnoteStyle@@ -920,6 +927,7 @@ , envInNote = True }) (withParaPropM (pStyleM "Footnote Text") $ blocksToOpenXML opts $ insertNoteRef bs)+ modify $ \s -> s{ stFirstPara = oldFirstPara } let newnote = mknode "w:footnote" [("w:id", notenum)] contents modify $ \s -> s{ stFootnotes = newnote : notes } return [ Elem $ mknode "w:r" []
src/Text/Pandoc/Writers/Docx/Types.hs view
@@ -121,6 +121,7 @@ , stDelId :: Int , stStyleMaps :: StyleMaps , stFirstPara :: Bool+ , stFirstSectionHeader :: Bool -- ^ True until first section header is processed , stNumIdUsed :: Bool -- ^ True if the current numId (envListNumId) has been used. -- Should only be used once, for the first paragraph. , stInTable :: Bool@@ -146,6 +147,7 @@ , stDelId = 1 , stStyleMaps = StyleMaps M.empty M.empty , stFirstPara = False+ , stFirstSectionHeader = True , stNumIdUsed = False , stInTable = False , stInList = False
src/Text/Pandoc/Writers/EPUB.hs view
@@ -466,8 +466,8 @@ pandocToEPUB version opts doc = do let doc' = ensureValidXmlIdentifiers doc -- handle pictures- Pandoc meta blocks <- walkM (transformInline opts) doc' >>=- walkM transformBlock+ Pandoc meta blocks <- walkM (transformInline version opts) doc' >>=+ walkM (transformBlock version) picEntries <- mapMaybe (snd . snd) <$> gets stMediaPaths epubSubdir <- gets stEpubSubdir@@ -1048,10 +1048,9 @@ coverageNodes = maybe [] (dcTag' "coverage") $ epubCoverage md rightsNodes = maybe [] (dcTag' "rights") $ epubRights md coverImageNodes = maybe []- (\img -> [unode "meta" ! [(metaprop,"cover"),- ("content",toId img)] $ ()- | version == EPUB2])- $ mbCoverImage+ (\img -> [unode "meta" ! [("name","cover"),+ ("content",toId img)] $ ()])+ mbCoverImage modifiedNodes = [ unode "meta" ! [(metaprop, "dcterms:modified")] $ showDateTimeISO8601 currentTime | version == EPUB3 ] belongsToCollectionNodes =@@ -1141,11 +1140,18 @@ schemeToOnix "ISBN-13" = "15" schemeToOnix "Legal deposit number" = "17" schemeToOnix "URN" = "22"- schemeToOnix "OCLC" = "23"+ schemeToOnix "OCLC number" = "23"+ schemeToOnix "Co-publisher’s ISBN-13" = "24" schemeToOnix "ISMN-13" = "25" schemeToOnix "ISBN-A" = "26"- schemeToOnix "JP" = "27"- schemeToOnix "OLCC" = "28"+ schemeToOnix "JP e-code" = "27"+ schemeToOnix "OLCC number" = "28"+ schemeToOnix "JP Magazine ID" = "29"+ schemeToOnix "UPC-12+5" = "30"+ schemeToOnix "BNF Control number" = "31"+ schemeToOnix "ISSN-13" = "34"+ schemeToOnix "ARK" = "35"+ schemeToOnix "Digital file internal version number" = "36" schemeToOnix _ = "01" showDateTimeISO8601 :: UTCTime -> Text@@ -1197,42 +1203,47 @@ modify $ \st -> st { stMediaNextId = nextId + 1 } return $ "file" ++ show nextId ++ ext -isHtmlFormat :: Format -> Bool-isHtmlFormat (Format "html") = True-isHtmlFormat (Format "html4") = True-isHtmlFormat (Format "html5") = True-isHtmlFormat _ = False+isHtmlFormat :: EPUBVersion -> Format -> Bool+isHtmlFormat _ (Format "html") = True+isHtmlFormat _ (Format "html4") = True+isHtmlFormat _ (Format "html5") = True+isHtmlFormat _ (Format "epub") = True+isHtmlFormat EPUB2 (Format "epub2") = True+isHtmlFormat EPUB3 (Format "epub3") = True+isHtmlFormat _ _ = False transformBlock :: PandocMonad m- => Block+ => EPUBVersion+ -> Block -> E m Block-transformBlock (RawBlock fmt raw)- | isHtmlFormat fmt = do+transformBlock version (RawBlock fmt raw)+ | isHtmlFormat version fmt = do let tags = parseTags raw tags' <- mapM transformTag tags return $ RawBlock fmt (renderTags' tags')-transformBlock b = return b+transformBlock _ b = return b transformInline :: PandocMonad m- => WriterOptions+ => EPUBVersion+ -> WriterOptions -> Inline -> E m Inline-transformInline _opts (Image attr@(_,_,kvs) lab (src,tit))+transformInline _ _opts (Image attr@(_,_,kvs) lab (src,tit)) | isNothing (lookup "external" kvs) = do newsrc <- modifyMediaRef $ T.unpack src return $ Image attr lab ("../" <> newsrc, tit)-transformInline opts x@(Math t m)+transformInline _ opts x@(Math t m) | WebTeX url <- writerHTMLMathMethod opts = do newsrc <- modifyMediaRef (T.unpack (url <> urlEncode m)) let mathclass = if t == DisplayMath then "display" else "inline" return $ Span ("",["math",mathclass],[]) [Image nullAttr [x] ("../" <> newsrc, "")]-transformInline _opts (RawInline fmt raw)- | isHtmlFormat fmt = do+transformInline version _opts (RawInline fmt raw)+ | isHtmlFormat version fmt = do let tags = parseTags raw tags' <- mapM transformTag tags return $ RawInline fmt (renderTags' tags')-transformInline _ x = return x+transformInline _ _ x = return x (!) :: (t -> Element) -> [(Text, Text)] -> t -> Element (!) f attrs n = add_attrs (map (\(k,v) -> Attr (unqual k) v) attrs) (f n)
src/Text/Pandoc/Writers/GridTable.hs view
@@ -82,10 +82,15 @@ -> [B.TableBody] -> B.TableFoot -> Table-toTable attr caption colSpecs thead tbodies tfoot =+toTable attr caption colSpecs thead' tbodies' tfoot' = Table attr caption colSpecs' rowHeads thGrid tbGrids tfGrid where- colSpecs' = listArray (ColIndex 1, ColIndex $ length colSpecs) colSpecs+ -- normalize in case it's invalid shape:+ thead = B.normalizeTableHead numcols thead'+ tbodies = map (B.normalizeTableBody numcols) tbodies'+ tfoot = B.normalizeTableFoot numcols tfoot'+ numcols = length colSpecs+ colSpecs' = listArray (ColIndex 1, ColIndex numcols) colSpecs rowHeads = case listToMaybe tbodies of Nothing -> RowHeadColumns 0 Just (TableBody _attr rowHeadCols _headerRows _rows) -> rowHeadCols
src/Text/Pandoc/Writers/HTML.hs view
@@ -35,7 +35,8 @@ import Control.Monad ( liftM, when, foldM, unless ) import Control.Monad.Trans ( MonadTrans(lift) ) import Data.Char (ord, isSpace, isAscii)-import Data.List (intercalate, intersperse, partition, delete, (\\), foldl')+import Data.List (intercalate, intersperse, partition, delete, (\\))+import qualified Data.List as L import Data.List.NonEmpty (NonEmpty((:|))) import Data.Containers.ListUtils (nubOrd) import Data.Maybe (fromMaybe, isJust, isNothing)@@ -48,7 +49,7 @@ import Numeric (showHex) import Text.DocLayout (render, literal, Doc) import Text.Blaze.Internal (MarkupM (Empty), customLeaf, customParent)-import Text.DocTemplates (FromContext (lookupContext), Context (..))+import Text.DocTemplates (FromContext (lookupContext), Context (..), Val(..)) import qualified Text.DocTemplates.Internal as DT import Text.Blaze.Html hiding (contents) import Text.Pandoc.Definition@@ -125,7 +126,7 @@ strToHtml :: Text -> Html strToHtml t | T.any isSpecial t =- let !x = foldl' go mempty $ T.groupBy samegroup t+ let !x = L.foldl' go mempty $ T.groupBy samegroup t in x | otherwise = toHtml t where@@ -433,10 +434,20 @@ defField "backgroundTransition" ("fade" :: Doc Text) . defField "viewDistance" ("3" :: Doc Text) . defField "mobileViewDistance" ("2" :: Doc Text) .- defField "scrollProgress" True .+ (case (lookupContext "scrollProgress" metadata+ :: Maybe (Val Text)) of+ Just (BoolVal False) -> id+ Just (BoolVal True) -> defField "scrollProgress" True+ _ -> defField "scrollProgressAuto" True) . defField "scrollActivationWidth" ("0" :: Doc Text) . defField "scrollSnap" ("mandatory" :: Doc Text) .- defField "scrollLayout" ("full" :: Doc Text)+ defField "scrollLayout" ("full" :: Doc Text) .+ (case writerHighlightMethod opts of+ IdiomaticHighlighting+ | slideVariant == RevealJsSlides ->+ defField "highlight-js" True .+ defField "highlightjs-theme" ("monokai" :: Doc Text)+ _ -> id) else id) . defField "document-css" (isNothing mCss && slideVariant == NoSlides) . defField "quotes" (stQuotes st) .@@ -674,7 +685,7 @@ addAttrs :: PandocMonad m => WriterOptions -> Attr -> Html -> StateT WriterState m Html-addAttrs opts attr h = foldl' (!) h <$> attrsToHtml opts attr+addAttrs opts attr h = L.foldl' (!) h <$> attrsToHtml opts attr toAttrs :: PandocMonad m => [(Text, Text)] -> StateT WriterState m [Attribute]@@ -794,8 +805,8 @@ if titleSlide -- title slides have no content of their own then let (as, bs) = break isSec xs- in (breakOnPauses as, bs)- else ([], breakOnPauses xs)+ in (walk breakOnPauses as, bs)+ else ([], walk breakOnPauses xs) let secttag = if html5 then H5.section else H.div@@ -940,6 +951,7 @@ return $ if html5 then H5.hr else H.hr blockToHtmlInner opts (CodeBlock (id',classes,keyvals) rawCode) = do html5 <- gets stHtml5+ slideVariant <- gets stSlideVariant id'' <- if T.null id' then do modify $ \st -> st{ stCodeBlockNum = stCodeBlockNum st + 1 }@@ -957,23 +969,37 @@ adjCode = if tolhs then T.unlines . map ("> " <>) . T.lines $ rawCode else rawCode- highlighted = highlight (writerSyntaxMap opts)- (if html5 then formatHtmlBlock else formatHtml4Block)- (id'',classes',keyvals) adjCode- hlCode = case writerHighlightMethod opts of- Skylighting _ -> highlighted- DefaultHighlighting -> highlighted- _ -> Left ""- case hlCode of- Left msg -> do- unless (T.null msg) $- report $ CouldNotHighlight msg- addAttrs opts (id',classes,keyvals)- $ H.pre $ H.code $ toHtml adjCode- Right h -> modify (\st -> st{ stHighlighting = True }) >>- -- we set writerIdentifierPrefix to "" since id'' already- -- includes it:- addAttrs opts{writerIdentifierPrefix = ""} (id'',[],keyvals) h+ isIdiomaticRevealJs = slideVariant == RevealJsSlides &&+ writerHighlightMethod opts == IdiomaticHighlighting+ if isIdiomaticRevealJs+ then do+ -- For idiomatic reveal.js highlighting, put attributes on <code>+ -- with language- prefix, and let highlight.js do the highlighting.+ modify (\st -> st{ stHighlighting = True })+ let (langClasses, otherClasses) = case classes' of+ (lang:rest) -> (["language-" <> lang], rest)+ [] -> ([], [])+ codeAttrs = (id', langClasses ++ otherClasses, keyvals)+ codeTag <- addAttrs opts codeAttrs $ H.code $ toHtml adjCode+ return $ H.pre codeTag+ else do+ let highlighted = highlight (writerSyntaxMap opts)+ (if html5 then formatHtmlBlock else formatHtml4Block)+ (id'',classes',keyvals) adjCode+ hlCode = case writerHighlightMethod opts of+ Skylighting _ -> highlighted+ DefaultHighlighting -> highlighted+ _ -> Left ""+ case hlCode of+ Left msg -> do+ unless (T.null msg) $+ report $ CouldNotHighlight msg+ addAttrs opts (id',classes,keyvals)+ $ H.pre $ H.code $ toHtml adjCode+ Right h -> modify (\st -> st{ stHighlighting = True }) >>+ -- we set writerIdentifierPrefix to "" since id'' already+ -- includes it:+ addAttrs opts{writerIdentifierPrefix = ""} (id'',[],keyvals) h blockToHtmlInner opts (BlockQuote blocks) = do -- in S5, treat list in blockquote specially -- if default is incremental, make it nonincremental;@@ -1046,7 +1072,7 @@ numstyle'] else []) l <- ordList opts contents- return $ foldl' (!) l attribs+ return $ L.foldl' (!) l attribs blockToHtmlInner opts (DefinitionList lst) = do contents <- mapM (\(term, defs) -> do term' <- liftM H.dt $ inlineListToHtml opts term@@ -1413,7 +1439,7 @@ = Just (t . H.u, cs) | otherwise = Just (t, c:cs)- spanLikeTags = foldl' go Nothing+ spanLikeTags = L.foldl' go Nothing in case spanLikeTags classes of Just (tag, cs) -> do h <- inlineListToHtml opts ils@@ -1610,7 +1636,7 @@ Just "audio" -> mediaTag H5.audio "Audio" Just _ -> (H5.embed, []) _ -> imageTag- return $ foldl' (!) tag $ attributes ++ specAttrs+ return $ L.foldl' (!) tag $ attributes ++ specAttrs -- note: null title included, as in Markdown.pl (Note contents) -> do notes <- gets stNotes@@ -1688,14 +1714,16 @@ let kvs = [("role","doc-backlink") | html5] let backlink = Link ("",["footnote-back"],kvs) [Str ref] ("#" <> "fnref" <> ref,"")- let blocks' =- case blocks of- (Para ils : rest) ->- Para (backlink : Str "." : Space : ils) : rest- (Plain ils : rest) ->- Plain (backlink : Str "." : Space : ils) : rest- _ -> Para [backlink , Str "."] : blocks- contents <- blockListToHtml opts blocks'+ let addBacklinkInlines bs+ | epubv == EPUB3 = bs+ | otherwise =+ case bs of+ (Para ils : rest) ->+ Para (backlink : Str "." : Space : ils) : rest+ (Plain ils : rest) ->+ Plain (backlink : Str "." : Space : ils) : rest+ _ -> Para [backlink , Str "."] : blocks+ contents <- blockListToHtml opts (addBacklinkInlines blocks) let noteItem = (if epubv == EPUB3 then H5.aside ! customAttribute "epub:type" "footnote" ! customAttribute "role" "doc-footnote" else H.div) ! prefixedId opts ("fn" <> ref)@@ -1767,9 +1795,19 @@ isRawHtml :: PandocMonad m => Format -> StateT WriterState m Bool isRawHtml f = do html5 <- gets stHtml5+ epubVersion <- gets stEPUBVersion return $ f == Format "html" || ((html5 && f == Format "html5") || f == Format "html4") ||+ isEpubFormat epubVersion f || isSlideVariant f++-- | Check to see if Format matches with an EPUB variant+isEpubFormat :: Maybe EPUBVersion -> Format -> Bool+isEpubFormat Nothing _ = False+isEpubFormat (Just EPUB2) f =+ f == Format "epub" || f == Format "epub2"+isEpubFormat (Just EPUB3) f =+ f == Format "epub" || f == Format "epub3" -- | Check to see if Format matches with an HTML slide variant isSlideVariant :: Format -> Bool
src/Text/Pandoc/Writers/ICML.hs view
@@ -44,6 +44,7 @@ data WriterState = WriterState{ blockStyles :: Set.Set Text , inlineStyles :: Set.Set Text+ , objectStyles :: Set.Set Text , links :: Hyperlink , listDepth :: Int , maxListDepth :: Int@@ -55,6 +56,7 @@ defaultWriterState = WriterState{ blockStyles = Set.empty , inlineStyles = Set.empty+ , objectStyles = Set.empty , links = [] , listDepth = 1 , maxListDepth = 0@@ -147,9 +149,10 @@ meta (main, st) <- runStateT (blocksToICML opts [] blocks) defaultWriterState let context = defField "body" main- $ defField "charStyles" (charStylesToDoc st)- $ defField "parStyles" (parStylesToDoc st)- $ defField "hyperlinks" (hyperlinksToDoc $ links st) metadata+ $ defField "charStyles" (charStylesToDoc st)+ $ defField "parStyles" (parStylesToDoc st)+ $ defField "objectStyles" (objectStylesToDoc st)+ $ defField "hyperlinks" (hyperlinksToDoc $ links st) metadata return $ render colwidth $ (if writerPreferAscii opts then fmap toEntities else id) $ case writerTemplate opts of@@ -272,6 +275,16 @@ else empty in inTags True "CharacterStyle" ([("Self", "CharacterStyle/"<>s), ("Name", s)] ++ attrs') props +-- | Convert a WriterState with its object styles to the ICML listing of Object Styles.+objectStylesToDoc :: WriterState -> Doc Text+objectStylesToDoc st = vcat $ map makeStyle $ Set.toAscList $ objectStyles st+ where+ makeStyle s =+ let attrs = []+ props = inTags True "Properties" [] $+ inTags False "BasedOn" [("type", "string")] (text "$ID/None")+ in inTags True "ObjectStyle" ([("Self", "ObjectStyle/"<>s), ("Name", s)] ++ attrs) props+ -- | Escape colon characters as %3a escapeColons :: Text -> Text escapeColons txt = Text.replace ":" "%3a" txt@@ -601,6 +614,10 @@ attrs = [("AppliedCharacterStyle", stl)] in (stlStr, attrs) +-- | Key for specifying user-defined object (image) styles+objectStyleKey :: Text+objectStyleKey = "object-style"+ -- | Assemble an ICML Image. imageICML :: PandocMonad m => WriterOptions -> Style -> Attr -> Target -> WS m (Doc Text) imageICML opts style attr (src, _) = do@@ -647,19 +664,31 @@ then mempty else selfClosingTag "Link" [("Self", "ueb"), ("LinkResourceURI", src')]- image = inTags True "Image"- [("Self","ue6"), ("ItemTransform", scale<>" -"<>hw<>" -"<>hh)]- $ vcat [- inTags True "Properties" [] $ vcat [- inTags True "Profile" [("type","string")] $ text "$ID/Embedded"- , selfClosingTag "GraphicBounds" [("Left","0"), ("Top","0")- , ("Right", showFl $ ow*ow / imgWidth)- , ("Bottom", showFl $ oh*oh / imgHeight)]- , contents- ]- , link- ]- doc = inTags True "CharacterStyleRange" attrs- $ inTags True "Rectangle" [("Self","uec"), ("StrokeWeight", "0"),- ("ItemTransform", scale<>" "<>hw<>" -"<>hh)] (props $$ image)- state $ \st -> (doc, st{ inlineStyles = Set.insert stlStr $ inlineStyles st } )+ (_,_,kvs) = attr+ applyObjectStyle = lookup objectStyleKey kvs+ image = inTags True "Image"+ [("Self","ue6"), ("ItemTransform", scale <> " -" <> hw <> " -" <> hh)]+ $ vcat [+ inTags True "Properties" [] $ vcat [+ inTags True "Profile" [("type","string")] $ text "$ID/Embedded",+ selfClosingTag "GraphicBounds" [("Left","0"), ("Top","0"),+ ("Right", showFl $ ow * ow / imgWidth),+ ("Bottom", showFl $ oh * oh / imgHeight)],+ contents+ ],+ link+ ]+ doc = inTags True "CharacterStyleRange" attrs+ $ inTags True "Rectangle"+ ([("Self","uec"),+ ("StrokeWeight", "0"),+ ("ItemTransform", scale <> " " <> hw <> " -" <> hh)] +++ maybe [] (\aos -> [("AppliedObjectStyle", "ObjectStyle/" <> aos)]) applyObjectStyle+ )+ (props $$ image)+ state $ \st -> (doc, st{+ inlineStyles = Set.insert stlStr $ inlineStyles st,+ objectStyles = case applyObjectStyle of+ Just styleName -> Set.insert styleName $ objectStyles st+ Nothing -> objectStyles st+ })
src/Text/Pandoc/Writers/JATS.hs view
@@ -360,11 +360,21 @@ return $ inTags True cls attr contents blockToJATS opts (Div (ident,_,kvs) bs) = do contents <- blocksToJATS opts bs- let attr = [("id", escapeNCName ident) | not (T.null ident)] ++- [("xml:lang",l) | ("lang",l) <- kvs] ++- [(k,v) | (k,v) <- kvs, k `elem` ["specific-use",- "content-type", "orientation", "position"]]- return $ inTags True "boxed-text" attr contents+ -- Attributes that are allowed on both @<p>@ and @<boxed-text>@ elements+ let generic_attr = [("id", escapeNCName ident) | not (T.null ident)] +++ [("xml:lang",l) | ("lang",l) <- kvs] +++ [(k,v) | (k,v) <- kvs, k `elem` ["specific-use",+ "content-type"]]+ let boxed_attr = [(k,v) | (k,v) <- kvs, k `elem` ["orientation", "position"]]+ let attr = generic_attr <> boxed_attr+ return $+ if null attr+ then contents+ else -- The contents must be wrapped in an appropriate element.+ let element = if null boxed_attr+ then "p"+ else "boxed-text"+ in inTags True element (generic_attr <> boxed_attr) contents blockToJATS opts (Header _ _ title) = do title' <- inlinesToJATS opts (map fixLineBreak title) return $ inTagsSimple "title" title'@@ -439,12 +449,36 @@ capt <- if null longcapt then pure empty else inTagsSimple "caption" <$> blocksToJATS opts longcapt- figbod <- blocksToJATS opts $ walk unsetAltIfDupl body- let figattr = [("id", escapeNCName ident) | not (T.null ident)] ++- [(k,v) | (k,v) <- kvs- , k `elem` [ "fig-type", "orientation"- , "position", "specific-use"]]- return $ inTags True "fig" figattr $ capt $$ figbod++ -- We handle the element specially if it's a figure with subfigures, i.e., if+ -- all immediate children are figures themselves.+ let hasSubfigures = all (\case { Figure{} -> True; _ -> False}) body+ needsWrapping = if hasSubfigures+ then (const False)+ else \case+ -- Wrap all figure content elements, except for those+ -- allowed as direct subelements.+ BlockQuote{} -> False+ CodeBlock{} -> False+ Para{} -> False+ Plain [Image{}] -> False+ Plain [Math{}] -> False+ Table{} -> False+ _ -> True++ children <- wrappedBlocksToJATS needsWrapping opts $ walk unsetAltIfDupl body+ let (tag, allowedAttributes) =+ if hasSubfigures+ then ( "fig-group"+ , ["content-type", "orientation", "position", "specific-use"]+ )+ else ("fig"+ , ["fig-type", "orientation", "position", "specific-use"]+ )+ let xmlattr = [("id", escapeNCName ident) | not (T.null ident)] +++ [(k,v) | (k,v) <- kvs+ , k `elem` allowedAttributes]+ return $ inTags True tag xmlattr $ capt $$ children -- | Convert a list of inline elements to JATS. inlinesToJATS :: PandocMonad m => WriterOptions -> [Inline] -> JATS m (Doc Text)
src/Text/Pandoc/Writers/LaTeX.hs view
@@ -33,13 +33,15 @@ import Crypto.Hash (hashWith, MD5(MD5)) import Data.Containers.ListUtils (nubOrd) import Data.Char (isDigit, isAscii, isLetter)-import Data.List (intersperse, (\\))-import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe, isNothing)+import Data.List (intersperse, partition, (\\))+import qualified Data.Set as Set+import Data.Maybe (catMaybes, fromMaybe, isJust, listToMaybe, mapMaybe, isNothing) import Data.Monoid (Any (..)) import Data.Text (Text) import qualified Data.Text as T import Network.URI (unEscapeString)-import Text.DocTemplates (FromContext(lookupContext), Val(..), renderTemplate)+import Text.DocTemplates (Context(..), FromContext(lookupContext), Val(..), renderTemplate)+import qualified Data.Map as M import Text.Collate.Lang (renderLang) import Text.Pandoc.Class.PandocMonad (PandocMonad, getPOSIXTime, lookupEnv, report, toLang)@@ -58,7 +60,8 @@ import Text.Pandoc.Writers.LaTeX.Table (tableToLaTeX) import Text.Pandoc.Writers.LaTeX.Citation (citationsToNatbib, citationsToBiblatex)-import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState)+import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState,+ PdfStandard (..)) import Text.Pandoc.Writers.LaTeX.Lang (toBabel) import Text.Pandoc.Writers.LaTeX.Util (stringToLaTeX, StringContext(..), toLabel, inCmd,@@ -221,6 +224,9 @@ let bibliography' = map unescapeUnderscore <$> getField "bibliography" metadata + -- Process PDF standard metadata for DocumentMetadata+ pdfStd <- processPdfStandard metadata+ let context = (case bibliography' of Nothing -> id Just xs -> resetField "bibliography" xs) $@@ -293,6 +299,13 @@ (if reproduciblePDF then defField "pdf-trailer-id" trailerID else id) $+ (if not (null (pdfStandards pdfStd)) || isJust (pdfVersion pdfStd)+ then resetField "pdfstandard" $ MapVal $ Context $ M.fromList+ [ ("standards", ListVal $ map (SimpleVal . literal) (pdfStandards pdfStd))+ , ("version", maybe NullVal (SimpleVal . literal) (pdfVersion pdfStd))+ , ("tagging", BoolVal (pdfTagging pdfStd))+ ]+ else id) $ metadata let babelLang = mblang >>= toBabel let context' =@@ -1414,3 +1427,85 @@ then return True else pCancel _ -> pCancel++-- PDF standard support for DocumentMetadata++-- | PDF standards supported by LaTeX's DocumentMetadata+-- See: https://github.com/latex3/latex2e documentmetadata-support.dtx+latexSupportedStandards :: Set.Set Text+latexSupportedStandards = Set.fromList+ [ -- PDF/A standards (note: a-1a is NOT supported by LaTeX, only a-1b)+ "a-1b", "a-2a", "a-2b", "a-2u", "a-3a", "a-3b", "a-3u"+ , "a-4", "a-4e", "a-4f"+ -- PDF/X standards+ , "x-4", "x-4p", "x-5g", "x-5n", "x-5pg", "x-6", "x-6n", "x-6p"+ -- PDF/UA standards+ , "ua-1", "ua-2"+ ]++-- | Standards that require PDF tagging (document structure)+-- PDF/A level "a" variants and PDF/UA require tagged structure+taggingRequiredStandards :: Set.Set Text+taggingRequiredStandards = Set.fromList+ ["a-2a", "a-3a", "ua-1", "ua-2"]++-- | Valid PDF versions for DocumentMetadata+validPdfVersions :: Set.Set Text+validPdfVersions = Set.fromList+ ["1.4", "1.5", "1.6", "1.7", "2.0"]++-- | PDF version required by each standard+-- LaTeX defaults to PDF 2.0 with \DocumentMetadata, but some standards+-- have maximum version requirements that are incompatible with 2.0+standardRequiredVersion :: M.Map Text Text+standardRequiredVersion = M.fromList+ [ ("a-1b", "1.4") -- PDF/A-1 requires exactly PDF 1.4+ -- PDF/A-2 and PDF/A-3 require 1.7; must set explicitly since LaTeX defaults to 2.0+ , ("a-2a", "1.7"), ("a-2b", "1.7"), ("a-2u", "1.7")+ , ("a-3a", "1.7"), ("a-3b", "1.7"), ("a-3u", "1.7")+ -- PDF/A-4, PDF/UA-1, PDF/UA-2 work with PDF 2.0 (the default)+ ]++-- | Normalize a PDF standard string: lowercase, strip "pdf" prefix+normalizePdfStandard :: Text -> Text+normalizePdfStandard t =+ let lower = T.toLower t+ in case T.stripPrefix "pdf" lower of+ Just rest -> T.dropWhile (`elem` ['-', '/']) rest+ Nothing -> lower++-- | Normalize a PDF version string+-- Handles YAML parsing quirk where 2.0 becomes integer 2, then string "2"+normalizeVersion :: Text -> Text+normalizeVersion t+ | t == "2" = "2.0"+ | otherwise = t++-- | Check if text is a valid PDF version (after normalization)+isPdfVersion :: Text -> Bool+isPdfVersion t = Set.member (normalizeVersion t) validPdfVersions++-- | Process pdfstandard metadata, returning PDF standard settings+processPdfStandard :: PandocMonad m+ => Context Text+ -> m PdfStandard+processPdfStandard ctx = do+ let standards = fromMaybe [] $ getField "pdfstandard" ctx+ normalized = map normalizePdfStandard standards+ (versions, pdfStds) = partition isPdfVersion normalized+ validStandards = filter (`Set.member` latexSupportedStandards) pdfStds+ invalidStandards = filter (\s -> not (Set.member s latexSupportedStandards)+ && not (isPdfVersion s)) pdfStds+ needsTagging = any (`Set.member` taggingRequiredStandards) validStandards+ -- Use explicit version if provided, otherwise infer from standards+ -- Apply normalizeVersion to handle YAML parsing "2" -> "2.0"+ explicitVersion = normalizeVersion <$> listToMaybe versions+ inferredVersion = listToMaybe $ mapMaybe (`M.lookup` standardRequiredVersion) validStandards+ version = explicitVersion <|> inferredVersion+ -- Warn about unsupported standards+ mapM_ (report . UnsupportedPdfStandard) invalidStandards+ return PdfStandard+ { pdfStandards = validStandards+ , pdfVersion = version+ , pdfTagging = needsTagging+ }
src/Text/Pandoc/Writers/LaTeX/Citation.hs view
@@ -21,7 +21,7 @@ import Text.Pandoc.Options import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Definition-import Data.List (foldl')+import qualified Data.List as L import Text.DocLayout (Doc, brackets, empty, (<+>), text, isEmpty, literal, braces) import Text.Pandoc.Walk@@ -73,7 +73,7 @@ citationsToNatbib inlineListToLaTeX cits = do cits' <- mapM convertOne cits- return $ text "\\citetext{" <> foldl' combineTwo empty cits' <> text "}"+ return $ text "\\citetext{" <> L.foldl' combineTwo empty cits' <> text "}" where citeCommand' = citeCommand inlineListToLaTeX combineTwo a b | isEmpty a = b@@ -182,7 +182,7 @@ NormalCitation -> "\\autocites" groups <- mapM (citeArgumentsList inlineListToLaTeX)- (reverse (foldl' grouper [] (c:cs)))+ (reverse (L.foldl' grouper [] (c:cs))) return $ text cmd <> mconcat groups
src/Text/Pandoc/Writers/LaTeX/Lang.hs view
@@ -40,7 +40,7 @@ toBabel (Lang "en" _ (Just "NZ") _ _ _) = Just "newzealand" toBabel (Lang "en" _ (Just "UK") _ _ _) = Just "british" toBabel (Lang "en" _ (Just "US") _ _ _) = Just "american"-toBabel (Lang "fr" _ (Just "CA") _ _ _) = Just "canadien"+toBabel (Lang "fr" _ (Just "CA") _ _ _) = Just "french" toBabel (Lang "fra" _ _ vars _ _) | "aca" `elem` vars = Just "acadian" toBabel (Lang "grc" _ _ _ _ _) = Just "ancientgreek"
src/Text/Pandoc/Writers/LaTeX/Types.hs view
@@ -2,6 +2,7 @@ ( LW , WriterState (..) , startingState+ , PdfStandard (..) ) where import Control.Monad.State.Strict (StateT)@@ -55,6 +56,13 @@ , stInSoulCommand :: Bool -- ^ in a soul command like ul , stCancel :: Bool -- ^ true if document uses \cancel , stInCaption :: Bool -- ^ true if in a caption+ }++-- | PDF standard settings for DocumentMetadata+data PdfStandard = PdfStandard+ { pdfStandards :: [Text] -- ^ list of standards (e.g., ["a-2b", "ua-1"])+ , pdfVersion :: Maybe Text -- ^ PDF version (e.g., "1.7", "2.0")+ , pdfTagging :: Bool -- ^ whether tagging is required } startingState :: WriterOptions -> WriterState
src/Text/Pandoc/Writers/Man.hs view
@@ -14,7 +14,7 @@ -} module Text.Pandoc.Writers.Man ( writeMan ) where-import Control.Monad ( liftM, zipWithM, forM, unless )+import Control.Monad ( liftM, zipWithM, unless ) import Control.Monad.State.Strict ( StateT, gets, modify, evalStateT ) import Control.Monad.Trans (MonadTrans(lift)) import Data.List (intersperse)@@ -241,7 +241,7 @@ labelText <- inlineListToMan opts label contents <- if null defs then return empty- else liftM vcat $ forM defs $ \case+ else case mconcat defs of (x:xs) -> do first' <- blockToMan opts $ case x of
src/Text/Pandoc/Writers/Markdown.hs view
@@ -376,15 +376,10 @@ | isEnabled Ext_alerts opts , (cls:_) <- classes , cls `elem` ["note", "tip", "warning", "caution", "important"]- , (Div ("", ["title"], []) _ : Para ils : bs') <- bs- = blockToMarkdown' opts $ BlockQuote $- (Para (RawInline (Format "markdown") (case cls of- "note" -> "[!NOTE]\n"- "tip" -> "[!TIP]\n"- "warning" -> "[!WARNING]\n"- "caution" -> "[!CAUTION]\n"- "important" -> "[!IMPORTANT]\n"- _ -> "[!NOTE]\n") : ils)) : bs'+ , (Div ("", ["title"], []) _ : bs') <- bs = do+ contents <- blockListToMarkdown opts bs'+ let alertLabel = literal $ "[!" <> T.toUpper cls <> "]"+ pure $ text "> " <> alertLabel $$ prefixed "> " contents $$ blankline | otherwise = do contents <- blockListToMarkdown opts bs variant <- asks envVariant@@ -529,15 +524,19 @@ isEnabled Ext_attributes opts -> space <> attrsToMarkdown opts attr | otherwise -> empty+ let setext = level <= 2 && writerSetextHeaders opts ||+ (variant == Commonmark &&+ hasLineBreaks inlines) -- #11341 contents <- inlineListToMarkdown opts $- -- ensure no newlines; see #3736- walk lineBreakToSpace $+ (if variant == Commonmark && setext+ then id+ else -- ensure no newlines; see #3736+ walk lineBreakToSpace) $ if level == 1 && variant == PlainText && isEnabled Ext_gutenberg opts then capitalize inlines else inlines - let setext = writerSetextHeaders opts when (not setext && isEnabled Ext_literate_haskell opts) $ report $ ATXHeadingInLHS level (render Nothing contents) @@ -579,7 +578,10 @@ tildes <> attrs <> cr <> literal str <> cr <> tildes <> blankline _ | variant == Markua -> blankline <> attrsToMarkua opts attribs <> cr <> backticks <> cr <> literal str <> cr <> backticks <> cr <> blankline- | otherwise -> nest (writerTabStop opts) (literal str) <> blankline+ | otherwise -> -- don't use nest: see #11542+ let addIndent "" = "\n"+ addIndent x = (T.replicate (writerTabStop opts) " ") <> x <> "\n"+ in literal (mconcat $ map addIndent (T.lines str)) $$ blankline where endlineLen c = maybe 3 ((+1) . maximum) $ nonEmpty [T.length ln@@ -611,6 +613,9 @@ let (caption, aligns, widths, headers, rows) = toLegacyTable blkCapt specs thead tbody tfoot let isColRowSpans (Cell _ _ rs cs _) = rs > 1 || cs > 1 let rowHasColRowSpans (Row _ cs) = any isColRowSpans cs+ let hasFooter = case tfoot of+ TableFoot _ [] -> False+ _ -> True let tbodyHasColRowSpans (TableBody _ _ rhs rs) = any rowHasColRowSpans rhs || any rowHasColRowSpans rs let theadHasColRowSpans (TableHead _ rs) = any rowHasColRowSpans rs@@ -630,7 +635,8 @@ = blankline $$ (": " <> caption'') $$ blankline | otherwise = blankline $$ caption'' $$ blankline let hasSimpleCells = onlySimpleTableCells $ headers : rows- let isSimple = hasSimpleCells && all (==0) widths && not hasColRowSpans+ let isSimple = hasSimpleCells && not hasFooter &&+ all (==0) widths && not hasColRowSpans let isPlainBlock (Plain _) = True isPlainBlock _ = False let hasBlocks = not (all (all (all isPlainBlock)) $ headers:rows)@@ -656,12 +662,13 @@ isEnabled Ext_pipe_tables opts -> do tbl <- mkTable (pipeTable opts) return $ (tbl $$ caption''') $$ blankline- | not (hasBlocks || hasColRowSpans) &&+ | not (hasBlocks || hasColRowSpans || hasFooter) && isEnabled Ext_multiline_tables opts -> do tbl <- mkTable (pandocTable opts True) return $ nest 2 (tbl $$ caption''') $$ blankline | isEnabled Ext_grid_tables opts &&- (hasColRowSpans || writerColumns opts >= 8 * numcols) -> do+ (hasColRowSpans || writerColumns opts >= 8 * numcols+ || hasFooter) -> do tbl <- gridTable opts blockListToMarkdown specs thead tbody tfoot return $ (tbl $$ caption''') $$ blankline@@ -858,8 +865,10 @@ _ -> ":" let leadingChars = case tabStop of -- Always use two leading characters for Markua- n | n >= 2 && variant /= Markua -> n- _ -> 2+ n | variant == Markua -> 2+ | isEnabled Ext_four_space_rule opts+ , n >= 2 -> n+ | otherwise -> 2 let sps = literal $ T.replicate (leadingChars - 1) " " let isTight = case defs of ((Plain _ : _): _) -> True
src/Text/Pandoc/Writers/Markdown/Inline.hs view
@@ -74,6 +74,9 @@ | isEnabled Ext_smart opts = '\\':'-':go('-':cs) go ('.':'.':'.':cs) | isEnabled Ext_smart opts = '\\':'.':'.':'.':go cs+ go (':':':':':':cs)+ | isEnabled Ext_fenced_divs opts -- see #11571+ = '\\':':':':':':': (takeWhile (==':') cs ++ go cs) go (c:'_':d:cs) | isAlphaNum c , isAlphaNum d =@@ -89,6 +92,9 @@ | isEnabled Ext_mark opts = '\\':'=':go ('=':cs) go ('~':'~':cs) | isEnabled Ext_strikeout opts = '\\':'~':go ('~':cs)+ go ('&':cs)+ | Right _ <- parse characterReference "" ('&':cs)+ = '\\':'&': go cs go (c:cs) = case c of '[' -> '\\':c:go cs@@ -500,24 +506,24 @@ else escapeText opts) $ str return $ literal str' inlineToMarkdown opts (Math InlineMath str) = do+ let str' = T.strip str variant <- asks envVariant case () of _ | variant == Markua -> return $ "`" <> literal str <> "`" <> "$" | otherwise -> case writerHTMLMathMethod opts of WebTeX url ->- let str' = T.strip str- in inlineToMarkdown opts+ inlineToMarkdown opts (Image nullAttr [Str str'] (url <> urlEncode str', str')) _ | isEnabled Ext_tex_math_gfm opts ->- return $ "$`" <> literal str <> "`$"+ return $ "$`" <> literal str' <> "`$" | isEnabled Ext_tex_math_dollars opts ->- return $ delimited "$" "$" (literal str)+ return $ "$" <> literal str' <> "$" | isEnabled Ext_tex_math_single_backslash opts ->- return $ "\\(" <> literal str <> "\\)"+ return $ "\\(" <> literal str' <> "\\)" | isEnabled Ext_tex_math_double_backslash opts ->- return $ "\\\\(" <> literal str <> "\\\\)"+ return $ "\\\\(" <> literal str' <> "\\\\)" | otherwise ->- texMathToInlines InlineMath str >>=+ texMathToInlines InlineMath str' >>= inlineListToMarkdown opts . (if variant == PlainText then makeMathPlainer else id) @@ -540,7 +546,7 @@ $$ literal (T.dropAround (=='\n') str) $$ literal "```") <> cr | isEnabled Ext_tex_math_dollars opts ->- return $ delimited "$$" "$$" (literal str)+ return $ "$$" <> literal str <> "$$" | isEnabled Ext_tex_math_single_backslash opts -> return $ "\\[" <> literal str <> "\\]" | isEnabled Ext_tex_math_double_backslash opts ->@@ -583,7 +589,7 @@ if variant == PlainText || isEnabled Ext_hard_line_breaks opts then return cr else return $- if isEnabled Ext_escaped_line_breaks opts+ if variant == Commonmark || isEnabled Ext_escaped_line_breaks opts then "\\" <> cr else " " <> cr inlineToMarkdown _ Space = do
src/Text/Pandoc/Writers/MediaWiki.hs view
@@ -26,7 +26,7 @@ import Text.Pandoc.ImageSize import Text.Pandoc.Logging import Text.Pandoc.Options-import Text.DocLayout (render, literal)+import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI import Text.Pandoc.Templates (renderTemplate)@@ -61,21 +61,21 @@ pandocToMediaWiki (Pandoc meta blocks) = do opts <- asks options metadata <- metaToContext opts- (fmap (literal . trimr) . blockListToMediaWiki)- (fmap (literal . trimr) . inlineListToMediaWiki)+ (fmap chomp . blockListToMediaWiki)+ (fmap chomp . inlineListToMediaWiki) meta body <- blockListToMediaWiki blocks notesExist <- gets stNotes let notes = if notesExist- then "\n<references />"- else ""+ then cr <> literal "<references />"+ else mempty let main = body <> notes let context = defField "body" main $ defField "toc" (writerTableOfContents opts) metadata- return $+ return $ render Nothing $ case writerTemplate opts of Nothing -> main- Just tpl -> render Nothing $ renderTemplate tpl context+ Just tpl -> renderTemplate tpl context -- | Escape special characters for MediaWiki. escapeText :: Text -> Text@@ -84,12 +84,14 @@ -- | Convert Pandoc block element to MediaWiki. blockToMediaWiki :: PandocMonad m => Block -- ^ Block element- -> MediaWikiWriter m Text+ -> MediaWikiWriter m (Doc Text) blockToMediaWiki (Div attrs bs) = do contents <- blockListToMediaWiki bs- return $ render Nothing (tagWithAttrs "div" attrs) <> "\n\n" <>- contents <> "\n\n" <> "</div>"+ return $ tagWithAttrs "div" attrs $$+ contents $$+ literal "</div>" $$+ blankline blockToMediaWiki (Plain inlines) = inlineListToMediaWiki inlines@@ -97,60 +99,69 @@ blockToMediaWiki (SimpleFigure attr txt (src, tit)) = do capt <- inlineListToMediaWiki txt img <- imageToMediaWiki attr+ let capt' = render Nothing capt let opt = if T.null tit then- if T.null capt+ if T.null capt' then ""- else "alt=" <> capt+ else "alt=" <> capt' else "alt=" <> tit- return $ "[[" <>- T.intercalate "|"- (filter (not . T.null) ["File:" <> src- , "thumb"- , "none"- , img- , opt- , capt- ]) <>- "]]\n"+ let separator = "<nowiki></nowiki>"+ -- External images (URIs) cannot use [[File:...]] syntax;+ -- they must be rendered as bare URLs. MediaWiki will auto-embed+ -- them when $wgAllowExternalImages is enabled.+ return $ if isURI src+ then literal (separator <> src <> separator) <> cr+ else literal ("[[" <>+ T.intercalate "|"+ (filter (not . T.null) ["File:" <> src+ , "thumb"+ , "none"+ , img+ , opt+ , capt'+ ]) <>+ "]]") <> cr blockToMediaWiki (Para inlines) = do tags <- asks useTags lev <- asks listLevel contents <- inlineListToMediaWiki inlines- let initEsc = if startsWithListMarker contents -- #9700- then "\\"- else ""+ let contents' = render Nothing contents+ let initEsc = if startsWithListMarker contents'+ then literal "<nowiki></nowiki>"+ else mempty return $ if tags- then "<p>" <> contents <> "</p>"- else initEsc <> contents <> if null lev then "\n" else ""+ then literal "<p>" <> contents <> literal "</p>"+ else initEsc <> contents $$+ if null lev then blankline else mempty blockToMediaWiki (LineBlock lns) = blockToMediaWiki $ linesToPara lns blockToMediaWiki b@(RawBlock f str)- | f == Format "mediawiki" = return str- | f == Format "html" = return str- | otherwise = "" <$ report (BlockNotRendered b)+ | f == Format "mediawiki" = return $ literal str+ | f == Format "html" = return $ literal str+ | otherwise = mempty <$ report (BlockNotRendered b) -blockToMediaWiki HorizontalRule = return "\n-----\n"+blockToMediaWiki HorizontalRule = return $ blankline <> literal "-----" <> blankline blockToMediaWiki (Header level (ident,_,_) inlines) = do let autoId = T.replace " " "_" $ stringify inlines contents <- inlineListToMediaWiki inlines- let eqs = T.replicate level "="+ let eqs = literal $ T.replicate level "=" return $ (if T.null ident || autoId == ident- then ""- else "<span id=\"" <> ident <> "\"></span>\n")- <> eqs <> " " <> contents <> " " <> eqs <> "\n"+ then mempty+ else literal ("<span id=\"" <> ident <> "\"></span>") <> cr)+ <> eqs <> space <> contents <> space <> eqs <> blankline blockToMediaWiki (CodeBlock (_,classes,keyvals) str) = do let at = Set.fromList classes `Set.intersection` highlightingLangs let numberLines = any (`elem` ["number","numberLines", "number-lines"]) classes let start = lookup "startFrom" keyvals- return $+ return $ literal $ case Set.toList at of [] -> "<pre" <> (if null classes then ">"@@ -165,7 +176,7 @@ blockToMediaWiki (BlockQuote blocks) = do contents <- blockListToMediaWiki blocks- return $ "<blockquote>" <> contents <> "</blockquote>"+ return $ literal "<blockquote>" <> chomp contents <> cr <> literal "</blockquote>" blockToMediaWiki (Table attr capt colSpecs thead tbody tfoot) = do tableToMediaWiki (Ann.toTable attr capt colSpecs thead tbody tfoot)@@ -176,11 +187,11 @@ if tags then do contents <- local (\ s -> s { useTags = True }) $ mapM listItemToMediaWiki items- return $ "<ul>\n" <> vcat contents <> "</ul>\n"+ return $ literal "<ul>" <> cr <> vcat contents <> literal "</ul>" <> blankline else do lev <- asks listLevel contents <- local (\s -> s { listLevel = listLevel s <> "*" }) $ mapM listItemToMediaWiki items- return $ vcat contents <> if null lev then "\n" else ""+ return $ vcat contents <> if null lev then blankline else mempty blockToMediaWiki x@(OrderedList attribs items) = do tags <-@@ -188,11 +199,11 @@ if tags then do contents <- local (\s -> s { useTags = True }) $ mapM listItemToMediaWiki items- return $ "<ol" <> listAttribsToText attribs <> ">\n" <> vcat contents <> "</ol>\n"+ return $ literal ("<ol" <> listAttribsToText attribs <> ">") <> cr <> vcat contents <> literal "</ol>" <> blankline else do lev <- asks listLevel contents <- local (\s -> s { listLevel = listLevel s <> "#" }) $ mapM listItemToMediaWiki items- return $ vcat contents <> if null lev then "\n" else ""+ return $ vcat contents <> if null lev then blankline else mempty blockToMediaWiki x@(DefinitionList items) = do tags <-@@ -200,11 +211,11 @@ if tags then do contents <- local (\s -> s { useTags = True }) $ mapM definitionListItemToMediaWiki items- return $ "<dl>\n" <> vcat contents <> "</dl>\n"+ return $ literal "<dl>" <> cr <> vcat contents <> literal "</dl>" <> blankline else do lev <- asks listLevel contents <- local (\s -> s { listLevel = listLevel s <> ";" }) $ mapM definitionListItemToMediaWiki items- return $ vcat contents <> if null lev then "\n" else ""+ return $ vcat contents <> if null lev then blankline else mempty blockToMediaWiki (Figure (ident, classes, kvs) _ body) = blockToMediaWiki (Div (ident, ["figure"] `DL.union` classes, kvs) body)@@ -223,20 +234,20 @@ else "") -- | Convert bullet or ordered list item (list of blocks) to MediaWiki.-listItemToMediaWiki :: PandocMonad m => [Block] -> MediaWikiWriter m Text+listItemToMediaWiki :: PandocMonad m => [Block] -> MediaWikiWriter m (Doc Text) listItemToMediaWiki items = do contents <- blockListToMediaWiki items tags <- asks useTags if tags- then return $ "<li>" <> contents <> "</li>"+ then return $ literal "<li>" <> chomp contents <> literal "</li>" else do marker <- asks listLevel- return $ T.pack marker <> " " <> contents+ return $ literal (T.pack marker) <> space <> chomp contents -- | Convert definition list item (label, list of blocks) to MediaWiki. definitionListItemToMediaWiki :: PandocMonad m => ([Inline],[[Block]])- -> MediaWikiWriter m Text+ -> MediaWikiWriter m (Doc Text) definitionListItemToMediaWiki (label, items) = do modify $ \st -> st{ stInDefLabel = True } labelText <- inlineListToMediaWiki label@@ -244,12 +255,12 @@ contents <- mapM blockListToMediaWiki items tags <- asks useTags if tags- then return $ "<dt>" <> labelText <> "</dt>\n" <>- T.intercalate "\n" (map (\d -> "<dd>" <> d <> "</dd>") contents)+ then return $ literal "<dt>" <> chomp labelText <> literal "</dt>" <> cr <>+ vcat (map (\d -> literal "<dd>" <> chomp d <> literal "</dd>") contents) else do marker <- asks listLevel- return $ T.pack marker <> " " <> labelText <> "\n" <>- T.intercalate "\n" (map (\d -> T.pack (init marker) <> ": " <> d) contents)+ return $ literal (T.pack marker) <> space <> chomp labelText <> cr <>+ vcat (map (\d -> literal (T.pack (init marker)) <> literal ": " <> chomp d) contents) -- | True if the list can be handled by simple wiki markup, False if HTML tags will be needed. isSimpleList :: Block -> Bool@@ -286,59 +297,53 @@ isPlainOrPara (Para _) = True isPlainOrPara _ = False --- | Concatenates strings with line breaks between them.-vcat :: [Text] -> Text-vcat = T.intercalate "\n"- -- Auxiliary functions for tables: -tableToMediaWiki :: PandocMonad m => Ann.Table -> MediaWikiWriter m Text+tableToMediaWiki :: PandocMonad m => Ann.Table -> MediaWikiWriter m (Doc Text) tableToMediaWiki (Ann.Table attr capt _ thead tbodies tfoot) = do let (ident,classes,kvs) = attr caption <- case capt of Caption _ [] -> return mempty Caption _ longCapt -> do c <- blockListToMediaWiki longCapt- return [ "|+ " <> trimr c ]+ return $ literal "|+ " <> chomp c <> cr head' <- tableHeadToMW thead- bodies' <- concat <$> mapM tableBodyToMW tbodies+ bodies' <- mconcat <$> mapM tableBodyToMW tbodies foot' <- tableFootToMW tfoot- return $ T.unlines $ [- "{|" <> (render Nothing (htmlAttrs (ident, "wikitable":classes, kvs)))- ] <> caption <> head' <> bodies' <> foot' <> [- "|}"- ]+ return $ literal "{|" <> htmlAttrs (ident, "wikitable":classes, kvs) <> cr+ <> caption <> head' <> bodies' <> foot'+ <> literal "|}" <> blankline -tableHeadToMW :: PandocMonad m => Ann.TableHead -> MediaWikiWriter m [Text]+tableHeadToMW :: PandocMonad m => Ann.TableHead -> MediaWikiWriter m (Doc Text) tableHeadToMW (Ann.TableHead _ rows) = headerRowsToMW rows -tableFootToMW :: PandocMonad m => Ann.TableFoot -> MediaWikiWriter m [Text]+tableFootToMW :: PandocMonad m => Ann.TableFoot -> MediaWikiWriter m (Doc Text) tableFootToMW (Ann.TableFoot _ rows) = headerRowsToMW rows -tableBodyToMW :: PandocMonad m => Ann.TableBody -> MediaWikiWriter m [Text]+tableBodyToMW :: PandocMonad m => Ann.TableBody -> MediaWikiWriter m (Doc Text) tableBodyToMW (Ann.TableBody _ _ headerRows bodyRows) = do headerRows' <- headerRowsToMW headerRows bodyRows' <- bodyRowsToMW bodyRows return $ headerRows' <> bodyRows' -headerRowsToMW :: PandocMonad m => [Ann.HeaderRow] -> MediaWikiWriter m [Text]-headerRowsToMW rows = (\x -> mconcat x) <$> mapM headerRowToMW rows+headerRowsToMW :: PandocMonad m => [Ann.HeaderRow] -> MediaWikiWriter m (Doc Text)+headerRowsToMW rows = mconcat <$> mapM headerRowToMW rows -headerRowToMW :: PandocMonad m => Ann.HeaderRow -> MediaWikiWriter m [Text]+headerRowToMW :: PandocMonad m => Ann.HeaderRow -> MediaWikiWriter m (Doc Text) headerRowToMW (Ann.HeaderRow attr _ cells) = do- cells' <- (\x -> mconcat x) <$> mapM (cellToMW "!") cells- return $ ["|-" <> (render Nothing (htmlAttrs attr))] <> cells'+ cells' <- mconcat <$> mapM (cellToMW "!") cells+ return $ literal "|-" <> htmlAttrs attr <> cr <> cells' -bodyRowsToMW :: PandocMonad m => [Ann.BodyRow] -> MediaWikiWriter m [Text]-bodyRowsToMW rows = (\x -> mconcat x) <$> mapM bodyRowToMW rows+bodyRowsToMW :: PandocMonad m => [Ann.BodyRow] -> MediaWikiWriter m (Doc Text)+bodyRowsToMW rows = mconcat <$> mapM bodyRowToMW rows -bodyRowToMW :: PandocMonad m => Ann.BodyRow -> MediaWikiWriter m [Text]+bodyRowToMW :: PandocMonad m => Ann.BodyRow -> MediaWikiWriter m (Doc Text) bodyRowToMW (Ann.BodyRow attr _ headCells bodyCells) = do- headCells' <- (\x -> mconcat x) <$> mapM (cellToMW "!") headCells- bodyCells' <- (\x -> mconcat x) <$> mapM (cellToMW "|") bodyCells- return $ ["|-" <> (render Nothing (htmlAttrs attr))] <> headCells' <> bodyCells'+ headCells' <- mconcat <$> mapM (cellToMW "!") headCells+ bodyCells' <- mconcat <$> mapM (cellToMW "|") bodyCells+ return $ literal "|-" <> htmlAttrs attr <> cr <> headCells' <> bodyCells' -cellToMW :: PandocMonad m => Text -> Ann.Cell -> MediaWikiWriter m [Text]+cellToMW :: PandocMonad m => Text -> Ann.Cell -> MediaWikiWriter m (Doc Text) cellToMW marker (Ann.Cell (colSpec :| _) _ (Cell attr align rowspan colspan content)) = do content' <- blockListToMediaWiki content let (ident,classes,keyVals) = attr@@ -355,14 +360,12 @@ let colspan' = case colspan of ColSpan 1 -> mempty ColSpan n -> [("colspan", T.pack(show n))]- let attrs' = addPipeIfNotEmpty (render Nothing (htmlAttrs (ident, classes, rowspan' <> colspan' <> keyVals')))- return [marker <> attrs' <> addSpaceIfNotEmpty(content')]--addPipeIfNotEmpty :: Text -> Text-addPipeIfNotEmpty f = if T.null f then f else f <> "|"--addSpaceIfNotEmpty :: Text -> Text-addSpaceIfNotEmpty f = if T.null f then f else " " <> f+ let attrs' = htmlAttrs (ident, classes, rowspan' <> colspan' <> keyVals')+ let attrsRendered = render Nothing attrs'+ let pipeAttr = if T.null attrsRendered then mempty else attrs' <> literal "|"+ let contentRendered = render Nothing content'+ let spaceContent = if T.null contentRendered then mempty else space <> chomp content'+ return $ literal marker <> pipeAttr <> spaceContent <> cr imageToMediaWiki :: PandocMonad m => Attr -> MediaWikiWriter m Text imageToMediaWiki attr = do@@ -384,14 +387,14 @@ -- | Convert list of Pandoc block elements to MediaWiki. blockListToMediaWiki :: PandocMonad m => [Block] -- ^ List of block elements- -> MediaWikiWriter m Text+ -> MediaWikiWriter m (Doc Text) blockListToMediaWiki blocks = vcat <$> mapM blockToMediaWiki blocks -- | Convert list of Pandoc inline elements to MediaWiki.-inlineListToMediaWiki :: PandocMonad m => [Inline] -> MediaWikiWriter m Text+inlineListToMediaWiki :: PandocMonad m => [Inline] -> MediaWikiWriter m (Doc Text) inlineListToMediaWiki lst =- fmap T.concat $ mapM inlineToMediaWiki $ fixup lst+ hcat <$> mapM inlineToMediaWiki (fixup lst) where fixup [] = [] fixup (Str t : x : xs)@@ -404,119 +407,129 @@ isLinkOrImage _ = False -- | Convert Pandoc inline element to MediaWiki.-inlineToMediaWiki :: PandocMonad m => Inline -> MediaWikiWriter m Text+inlineToMediaWiki :: PandocMonad m => Inline -> MediaWikiWriter m (Doc Text) inlineToMediaWiki (Span attrs ils) = do contents <- inlineListToMediaWiki ils- return $ render Nothing (tagWithAttrs "span" attrs) <> contents <> "</span>"+ return $ tagWithAttrs "span" attrs <> contents <> literal "</span>" inlineToMediaWiki (Emph lst) = do contents <- inlineListToMediaWiki lst- return $ "''" <> contents <> "''"+ return $ literal "''" <> contents <> literal "''" inlineToMediaWiki (Underline lst) = do contents <- inlineListToMediaWiki lst- return $ "<u>" <> contents <> "</u>"+ return $ literal "<u>" <> contents <> literal "</u>" inlineToMediaWiki (Strong lst) = do contents <- inlineListToMediaWiki lst- return $ "'''" <> contents <> "'''"+ return $ literal "'''" <> contents <> literal "'''" inlineToMediaWiki (Strikeout lst) = do contents <- inlineListToMediaWiki lst- return $ "<s>" <> contents <> "</s>"+ return $ literal "<s>" <> contents <> literal "</s>" inlineToMediaWiki (Superscript lst) = do contents <- inlineListToMediaWiki lst- return $ "<sup>" <> contents <> "</sup>"+ return $ literal "<sup>" <> contents <> literal "</sup>" inlineToMediaWiki (Subscript lst) = do contents <- inlineListToMediaWiki lst- return $ "<sub>" <> contents <> "</sub>"+ return $ literal "<sub>" <> contents <> literal "</sub>" inlineToMediaWiki (SmallCaps lst) = inlineListToMediaWiki lst inlineToMediaWiki (Quoted SingleQuote lst) = do contents <- inlineListToMediaWiki lst- return $ "\8216" <> contents <> "\8217"+ return $ literal "\8216" <> contents <> literal "\8217" inlineToMediaWiki (Quoted DoubleQuote lst) = do contents <- inlineListToMediaWiki lst- return $ "\8220" <> contents <> "\8221"+ return $ literal "\8220" <> contents <> literal "\8221" inlineToMediaWiki (Cite _ lst) = inlineListToMediaWiki lst inlineToMediaWiki (Code _ str) =- return $ "<code>" <> escapeText str <> "</code>"+ return $ literal $ "<code>" <> escapeText str <> "</code>" inlineToMediaWiki (Str str) = do inDefLabel <- gets stInDefLabel- return $+ return $ literal $ if inDefLabel then T.intercalate "<nowiki>:</nowiki>" $ map escapeText $ T.splitOn ":" str else escapeText str -inlineToMediaWiki (Math mt str) = return $+inlineToMediaWiki (Math mt str) = return $ literal $ "<math display=\"" <> (if mt == DisplayMath then "block" else "inline") <> "\">" <> str <> "</math>" -- note: str should NOT be escaped inlineToMediaWiki il@(RawInline f str)- | f == Format "mediawiki" = return str- | f == Format "html" = return str- | otherwise = "" <$ report (InlineNotRendered il)+ | f == Format "mediawiki" = return $ literal str+ | f == Format "html" = return $ literal str+ | otherwise = mempty <$ report (InlineNotRendered il) -inlineToMediaWiki LineBreak = return "<br />\n"+inlineToMediaWiki LineBreak = return $ literal "<br />" <> cr inlineToMediaWiki SoftBreak = do wrapText <- gets (writerWrapText . stOptions) listlevel <- asks listLevel case wrapText of- WrapAuto -> return " "- WrapNone -> return " "+ WrapAuto -> return space+ WrapNone -> return space WrapPreserve -> if null listlevel- then return "\n"- else return " "+ then return cr+ else return space -inlineToMediaWiki Space = return " "+inlineToMediaWiki Space = return space inlineToMediaWiki (Link _ txt (src, _)) = do -- We need to remove links from link text, because an <a> element is -- not allowed inside another <a> element. label <- inlineListToMediaWiki (removeLinks txt)+ let label' = render Nothing label case txt of- [Str s] | isURI src && escapeURI s == src -> return src- _ -> return $ if isURI src- then "[" <> src <> " " <> label <> "]"+ [Str s] | isURI src && escapeURI s == src -> return $ literal src+ _ -> return $ literal $ if isURI (T.takeWhile (/= '#') src) -- see #11562+ then "[" <> src <> " " <> label' <> "]" else- if src == label+ if src == label' then "[[" <> src' <> "]]"- else "[[" <> src' <> "|" <> label <> "]]"+ else "[[" <> src' <> "|" <> label' <> "]]" -- with leading / it's a link to a help page where src' = fromMaybe src $ T.stripPrefix "/" src inlineToMediaWiki (Image attr alt (source, tit)) = do- img <- imageToMediaWiki attr- alt' <- inlineListToMediaWiki alt- let txt = if T.null alt'- then if T.null tit- then ""- else tit- else alt'- return $ "[[" <>- T.intercalate "|"- (filter (not . T.null)- [ "File:" <> source- , img- , txt- ]) <> "]]"+ let separator = "<nowiki></nowiki>"+ -- External images (URIs) cannot use [[File:...]] syntax;+ -- they must be rendered as bare URLs. MediaWiki will auto-embed+ -- them when $wgAllowExternalImages is enabled.+ if isURI source+ then return $ literal $ separator <> source <> separator+ else do+ img <- imageToMediaWiki attr+ alt' <- inlineListToMediaWiki alt+ let altText = render Nothing alt'+ let txt = if T.null altText+ then if T.null tit+ then ""+ else tit+ else altText+ return $ literal $ "[[" <>+ T.intercalate "|"+ (filter (not . T.null)+ [ "File:" <> source+ , img+ , txt+ ]) <> "]]" inlineToMediaWiki (Note contents) = do contents' <- blockListToMediaWiki contents modify (\s -> s { stNotes = True })- return $ "<ref>" <> stripTrailingNewlines contents' <> "</ref>"+ let rendered = render Nothing contents'+ return $ literal $ "<ref>" <> stripTrailingNewlines rendered <> "</ref>" -- note - does not work for notes with multiple blocks highlightingLangs :: Set.Set Text
src/Text/Pandoc/Writers/ODT.hs view
@@ -212,9 +212,10 @@ . maybe id addLang mbLang . transformElement (\qn -> qName qn == "styles" && qPrefix qn == Just "office" )- (case writerHighlightMethod opts of+ (addListItemStyles .+ (case writerHighlightMethod opts of Skylighting style -> addHlStyles style- _ -> id)+ _ -> id)) $ d ) | otherwise = pure e entries <- mapM goEntry (zEntries arch)@@ -227,6 +228,56 @@ where isHlStyle (Elem e) = "Tok" `T.isSuffixOf` (qName (elName e)) isHlStyle _ = False++-- | Ensure the office:styles element contains paragraph styles for+-- list items used by the OpenDocument writer. This injects only the+-- styles that are missing, so a user-supplied reference.odt may+-- override any of them.+addListItemStyles :: Element -> Element+addListItemStyles el =+ el{ elContent = elContent el ++ map Elem missingStyles }+ where+ existing = [ T.concat [ attrVal a+ | a <- elAttribs e+ , qName (attrKey a) == "name"+ , qPrefix (attrKey a) == Just "style" ]+ | Elem e <- elContent el+ , qName (elName e) == "style"+ , qPrefix (elName e) == Just "style" ]+ missingStyles =+ [ s | s <- listItemStyleElements+ , styleNameOf s `notElem` existing ]+ styleNameOf e = T.concat [ attrVal a+ | a <- elAttribs e+ , qName (attrKey a) == "name"+ , qPrefix (attrKey a) == Just "style" ]++listItemStyleElements :: [Element]+listItemStyleElements =+ [ mkParaStyle "List_20_Bullet" "List Bullet" Nothing+ , mkParaStyle "List_20_Bullet_20_Tight" "List Bullet Tight" (Just tightProps)+ , mkParaStyle "List_20_Number" "List Number" Nothing+ , mkParaStyle "List_20_Number_20_Tight" "List Number Tight" (Just tightProps)+ ]+ where+ styleQN n p = QName n Nothing (Just p)+ mkAttr p n v = Attr (styleQN n p) v+ tightProps =+ Element (styleQN "paragraph-properties" "style")+ [ mkAttr "fo" "margin-top" "0in"+ , mkAttr "fo" "margin-bottom" "0in"+ , mkAttr "style" "contextual-spacing" "false"+ ] [] Nothing+ mkParaStyle name display mbProps =+ Element (styleQN "style" "style")+ [ mkAttr "style" "name" name+ , mkAttr "style" "display-name" display+ , mkAttr "style" "family" "paragraph"+ , mkAttr "style" "parent-style-name" "List"+ , mkAttr "style" "class" "list"+ ]+ (maybe [] (\p -> [Elem p]) mbProps)+ Nothing -- top-down search transformElement :: (QName -> Bool)
src/Text/Pandoc/Writers/OpenDocument.hs view
@@ -19,7 +19,8 @@ import Control.Monad.State.Strict ( StateT(..), modify, gets, lift ) import Data.Char (chr) import Data.Foldable (find)-import Data.List (sortOn, sortBy, foldl')+import Data.List (sortOn, sortBy)+import qualified Data.List as L import qualified Data.Map as Map import Data.Ord (comparing, Down (Down)) import qualified Data.Set as Set@@ -50,6 +51,29 @@ plainToPara (Plain x) = Para x plainToPara x = x +-- Names of predefined styles in the reference.odt; see data/odt/styles.xml.+defaultBulletListStyleName, defaultNumberedListStyleName :: Text+defaultBulletListStyleName = "List_20_1"+defaultNumberedListStyleName = "Numbering_20_1"++bulletItemStyleName, bulletItemTightStyleName,+ numberItemStyleName, numberItemTightStyleName :: Text+bulletItemStyleName = "List_20_Bullet"+bulletItemTightStyleName = "List_20_Bullet_20_Tight"+numberItemStyleName = "List_20_Number"+numberItemTightStyleName = "List_20_Number_20_Tight"++-- | Predefined inline style names for single-style spans.+wellKnownTextStyle :: Set.Set TextStyle -> Maybe Text+wellKnownTextStyle s = case Set.toList s of+ [Italic] -> Just "Emphasis"+ [Bold] -> Just "Strong_20_Emphasis"+ [Strike] -> Just "Strikeout"+ [Sub] -> Just "Subscript"+ [Sup] -> Just "Superscript"+ [Pre] -> Just "Source_20_Text"+ _ -> Nothing+ -- -- OpenDocument writer --@@ -65,7 +89,8 @@ WriterState { stNotes :: [Doc Text] , stTableStyles :: [Doc Text] , stParaStyles :: [Doc Text]- , stListStyles :: [(Int, [Doc Text])]+ , stListOverrides :: Map.Map (ListNumberStyle,ListNumberDelim)+ (Text, Doc Text) , stTextStyles :: Map.Map (Set.Set TextStyle) (Text, Doc Text) , stTextStyleAttr :: Set.Set TextStyle@@ -84,7 +109,7 @@ WriterState { stNotes = [] , stTableStyles = [] , stParaStyles = []- , stListStyles = []+ , stListOverrides = Map.empty , stTextStyles = Map.empty , stTextStyleAttr = Set.empty , stIndentPara = 0@@ -120,10 +145,6 @@ resetIndent :: PandocMonad m => OD m () resetIndent = modify $ \s -> s { stIndentPara = stIndentPara s - 1 } -inTightList :: PandocMonad m => OD m a -> OD m a-inTightList f = modify (\s -> s { stTight = True }) >> f >>= \r ->- modify (\s -> s { stTight = False }) >> return r- setInDefinitionList :: PandocMonad m => Bool -> OD m () setInDefinitionList b = modify $ \s -> s { stInDefinition = b } @@ -162,22 +183,25 @@ at <- gets stTextStyleAttr if Set.null at then return d- else do- styles <- gets stTextStyles- case Map.lookup at styles of- Just (styleName, _) -> return $- inTags False "text:span" [("text:style-name",styleName)] d- Nothing -> do- let styleName = "T" <> tshow (Map.size styles + 1)- addTextStyle at (styleName,- inTags False "style:style"- [("style:name", styleName)- ,("style:family", "text")]- $ selfClosingTag "style:text-properties"- (sortOn fst . Map.toList- $ foldl' textStyleAttr mempty (Set.toList at)))- return $ inTags False- "text:span" [("text:style-name",styleName)] d+ else case wellKnownTextStyle at of+ Just styleName -> return $+ inTags False "text:span" [("text:style-name", styleName)] d+ Nothing -> do+ styles <- gets stTextStyles+ case Map.lookup at styles of+ Just (styleName, _) -> return $+ inTags False "text:span" [("text:style-name",styleName)] d+ Nothing -> do+ let styleName = "T" <> tshow (Map.size styles + 1)+ addTextStyle at (styleName,+ inTags False "style:style"+ [("style:name", styleName)+ ,("style:family", "text")]+ $ selfClosingTag "style:text-properties"+ (sortOn fst . Map.toList+ $ L.foldl' textStyleAttr mempty (Set.toList at)))+ return $ inTags False+ "text:span" [("text:style-name",styleName)] d formulaStyles :: [Doc Text] formulaStyles = [formulaStyle InlineMath, formulaStyle DisplayMath]@@ -262,10 +286,8 @@ let styles = stTableStyles s ++ stParaStyles s ++ formulaStyles ++ map snd (sortBy (comparing (Down . fst)) ( Map.elems (stTextStyles s)))- listStyle (n,l) = inTags True "text:list-style"- [("style:name", "L" <> tshow n)] (vcat l)- let listStyles = map listStyle (stListStyles s)- let automaticStyles = vcat $ reverse $ styles ++ listStyles+ let listStyles = map snd (Map.elems (stListOverrides s))+ let automaticStyles = vcat $ reverse styles ++ listStyles let context = defField "body" body . defField "toc" (writerTableOfContents opts) . defField "toc-depth" (tshow $ writerTOCDepth opts)@@ -285,56 +307,101 @@ withParagraphStyle _ _ [] = return empty inPreformattedTags :: PandocMonad m => [Doc Text] -> OD m (Doc Text)-inPreformattedTags s = do- n <- paraStyle [("style:parent-style-name","Preformatted_20_Text")]- return $ inParagraphTagsWithStyle ("P" <> tshow n) $ hcat s+inPreformattedTags s =+ return $ inParagraphTagsWithStyle "Preformatted_20_Text" $ hcat s +-- | Get the list-style name to use for an ordered list with the given+-- numbering style and delimiter, registering an override automatic style+-- if needed. Lists with default style/delimiter use the predefined+-- @Numbering_20_1@ style and no override is generated.+orderedListStyleName :: PandocMonad m+ => ListNumberStyle -> ListNumberDelim -> OD m Text+orderedListStyleName ns nd+ | (ns == DefaultStyle || ns == Decimal) &&+ (nd == DefaultDelim || nd == Period) =+ return defaultNumberedListStyleName+ | otherwise = do+ overrides <- gets stListOverrides+ case Map.lookup (ns, nd) overrides of+ Just (name, _) -> return name+ Nothing -> do+ let name = "Pandoc_5f_Numbering_5f_" <>+ tshow (Map.size overrides + 1)+ doc = inTags True "text:list-style"+ [("style:name", name)]+ (vcat (map (orderedListLevel ns nd) [1..10]))+ modify $ \s -> s { stListOverrides =+ Map.insert (ns, nd) (name, doc)+ (stListOverrides s) }+ return name++orderedListLevel :: ListNumberStyle -> ListNumberDelim -> Int -> Doc Text+orderedListLevel ns nd lvl =+ let suffix = case nd of+ OneParen -> [("style:num-suffix", ")")]+ TwoParens -> [("style:num-prefix", "(")+ ,("style:num-suffix", ")")]+ _ -> [("style:num-suffix", ".")]+ format = case ns of+ UpperAlpha -> "A"+ LowerAlpha -> "a"+ UpperRoman -> "I"+ LowerRoman -> "i"+ _ -> "1"+ in inTags True "text:list-level-style-number"+ ([ ("text:level" , tshow lvl)+ , ("text:style-name" , "Numbering_20_Symbols")+ , ("style:num-format", format)+ ] ++ suffix)+ (selfClosingTag "style:list-level-properties"+ [ ("text:space-before",+ T.pack (printf "%.4fin" (0.1972 * fromIntegral (lvl - 1) :: Double)))+ , ("text:min-label-width", "0.1965in")+ , ("text:min-label-distance", "0.1in")+ ])+ orderedListToOpenDocument :: PandocMonad m- => WriterOptions -> Int -> [[Block]] -> OD m (Doc Text)-orderedListToOpenDocument o pn bs =+ => WriterOptions -> Text -> [[Block]]+ -> OD m (Doc Text)+orderedListToOpenDocument o paraName bs = vcat . map (inTagsIndented "text:list-item") <$>- mapM (orderedItemToOpenDocument o pn . map plainToPara) bs+ mapM (orderedItemToOpenDocument o paraName . map plainToPara) bs orderedItemToOpenDocument :: PandocMonad m- => WriterOptions -> Int -> [Block] -> OD m (Doc Text)-orderedItemToOpenDocument o n bs = vcat <$> mapM go bs- where go (OrderedList a l) = newLevel a l- go (Para l) = inParagraphTagsWithStyle ("P" <> tshow n) <$>+ => WriterOptions -> Text -> [Block]+ -> OD m (Doc Text)+orderedItemToOpenDocument o paraName bs = vcat <$> mapM go bs+ where go (OrderedList a l) = orderedList a l+ go (Para l) = inParagraphTagsWithStyle paraName <$> inlinesToOpenDocument o l go b = blockToOpenDocument o b- newLevel a l = do- nn <- length <$> gets stParaStyles- liststyles <- gets stListStyles- let ls = case liststyles of- [] -> (1,[]) -- should never happen- (s:_) -> s- modify $ \s -> s { stListStyles = orderedListLevelStyle a ls :- drop 1 (stListStyles s) }- inTagsIndented "text:list" <$> orderedListToOpenDocument o nn l+ orderedList a@(_,ns,nd) l = do+ lstName <- orderedListStyleName ns nd+ let pn = if isTightList l then numberItemTightStyleName+ else numberItemStyleName+ let listAttrs = ("text:style-name", lstName) : startValueAttr a+ inTags True "text:list" listAttrs <$>+ orderedListToOpenDocument o pn l +-- | Generate a @text:start-value@ attribute when the start value is not 1.+startValueAttr :: ListAttributes -> [(Text, Text)]+startValueAttr (s,_,_) | s /= 1 = [("text:start-value", tshow s)]+startValueAttr _ = []+ isTightList :: [[Block]] -> Bool isTightList [] = False isTightList (b:_) | Plain {} : _ <- b = True | otherwise = False -newOrderedListStyle :: PandocMonad m- => Bool -> ListAttributes -> OD m (Int,Int)-newOrderedListStyle b a = do- ln <- (+) 1 . length <$> gets stListStyles- let nbs = orderedListLevelStyle a (ln, [])- pn <- if b then inTightList (paraListStyle ln) else paraListStyle ln- modify $ \s -> s { stListStyles = nbs : stListStyles s }- return (ln,pn)- bulletListToOpenDocument :: PandocMonad m => WriterOptions -> [[Block]] -> OD m (Doc Text) bulletListToOpenDocument o b = do- ln <- (+) 1 . length <$> gets stListStyles- (pn,ns) <- if isTightList b then inTightList (bulletListStyle ln) else bulletListStyle ln- modify $ \s -> s { stListStyles = ns : stListStyles s }- is <- listItemsToOpenDocument ("P" <> tshow pn) o b- return $ inTags True "text:list" [("text:style-name", "L" <> tshow ln)] is+ let pn = if isTightList b then bulletItemTightStyleName+ else bulletItemStyleName+ is <- listItemsToOpenDocument pn o b+ return $ inTags True "text:list"+ [("text:style-name", defaultBulletListStyleName)] is listItemsToOpenDocument :: PandocMonad m => Text -> WriterOptions -> [[Block]] -> OD m (Doc Text)@@ -353,16 +420,18 @@ return $ t' $$ d' inBlockQuote :: PandocMonad m- => WriterOptions -> Int -> [Block] -> OD m (Doc Text)-inBlockQuote o i (b:bs)+ => WriterOptions -> Text -> [Block] -> OD m (Doc Text)+inBlockQuote o sty (b:bs) | BlockQuote l <- b = do increaseIndent ni <- paraStyle [("style:parent-style-name","Quotations")]- go =<< inBlockQuote o ni (map plainToPara l)- | Para l <- b = go =<< inParagraphTagsWithStyle ("P" <> tshow i) <$> inlinesToOpenDocument o l+ inner <- inBlockQuote o ni (map plainToPara l)+ resetIndent+ go inner+ | Para l <- b = go =<< inParagraphTagsWithStyle sty <$> inlinesToOpenDocument o l | otherwise = go =<< blockToOpenDocument o b- where go block = ($$) block <$> inBlockQuote o i bs-inBlockQuote _ _ [] = resetIndent >> return empty+ where go block = ($$) block <$> inBlockQuote o sty bs+inBlockQuote _ _ [] = return empty -- | Convert a list of Pandoc blocks to OpenDocument. blocksToOpenDocument :: PandocMonad m => WriterOptions -> [Block] -> OD m (Doc Text)@@ -424,13 +493,16 @@ if T.null ident then i else fmap mkBookmarkedDiv i- mkBlockQuote b = do increaseIndent- i <- paraStyle- [("style:parent-style-name","Quotations")]- inBlockQuote o i (map plainToPara b)- orderedList a b = do (ln,pn) <- newOrderedListStyle (isTightList b) a- inTags True "text:list" [ ("text:style-name", "L" <> tshow ln)]- <$> orderedListToOpenDocument o pn b+ mkBlockQuote b = do sty <- paraStyle+ [("style:parent-style-name","Quotations")]+ inBlockQuote o sty (map plainToPara b)+ orderedList a@(_,ns,nd) b = do+ lstName <- orderedListStyleName ns nd+ let pn = if isTightList b then numberItemTightStyleName+ else numberItemStyleName+ let listAttrs = ("text:style-name", lstName) : startValueAttr a+ inTags True "text:list" listAttrs <$>+ orderedListToOpenDocument o pn b table :: PandocMonad m => WriterOptions -> Ann.Table -> OD m (Doc Text) table opts (Ann.Table (ident, _, _) (Caption _ c) colspecs thead tbodies tfoot) = do@@ -590,14 +662,9 @@ aa = alignAttrib align a = [ ("table:style-name" , s ) , ("office:value-type", "string" ) ] ++ csa ++ rsa- itemParaStyle <- case aa of- [] -> return 0- _ -> paraStyleFromParent n aa- let itemParaStyle' = case itemParaStyle of- 0 -> n- x -> "P" <> tshow x+ itemParaStyle <- paraStyleFromParent n aa inTags True "table:table-cell" a <$>- withParagraphStyle o itemParaStyle' (map plainToPara i)+ withParagraphStyle o itemParaStyle (map plainToPara i) -- | Convert a list of inline elements to OpenDocument. inlinesToOpenDocument :: PandocMonad m => WriterOptions -> [Inline] -> OD m (Doc Text)@@ -670,7 +737,7 @@ where unhighlighted s = inlinedCode $ preformatted s inlinedCode s = return $ inTags False "text:span"- [("text:style-name", "Source_Text")] s+ [("text:style-name", "Source_20_Text")] s mkImg (_, _, kvs) s _ = do id' <- gets stImageId modify (\st -> st{ stImageId = id' + 1 })@@ -760,55 +827,6 @@ then linkOrReference else link -bulletListStyle :: PandocMonad m => Int -> OD m (Int,(Int,[Doc Text]))-bulletListStyle l = do- let doStyles i = inTags True "text:list-level-style-bullet"- [ ("text:level" , tshow (i + 1))- , ("text:style-name" , "Bullet_20_Symbols" )- , ("style:num-suffix", "." )- , ("text:bullet-char", T.singleton (bulletList !! i))- ] (listLevelStyle (1 + i))- bulletList = map chr $ cycle [8226,9702,9642]- listElStyle = map doStyles [0..9]- pn <- paraListStyle l- return (pn, (l, listElStyle))--orderedListLevelStyle :: ListAttributes -> (Int, [Doc Text]) -> (Int,[Doc Text])-orderedListLevelStyle (s,n, d) (l,ls) =- let suffix = case d of- OneParen -> [("style:num-suffix", ")")]- TwoParens -> [("style:num-prefix", "(")- ,("style:num-suffix", ")")]- _ -> [("style:num-suffix", ".")]- format = case n of- UpperAlpha -> "A"- LowerAlpha -> "a"- UpperRoman -> "I"- LowerRoman -> "i"- _ -> "1"- listStyle = inTags True "text:list-level-style-number"- ([ ("text:level" , tshow $ 1 + length ls )- , ("text:style-name" , "Numbering_20_Symbols")- , ("style:num-format", format )- , ("text:start-value", tshow s )- ] ++ suffix) (listLevelStyle (1 + length ls))- in (l, ls ++ [listStyle])--listLevelStyle :: Int -> Doc Text-listLevelStyle i =- let indent = tshow (0.25 + (0.25 * fromIntegral i :: Double)) in- inTags True "style:list-level-properties"- [ ("text:list-level-position-and-space-mode",- "label-alignment")- , ("fo:text-align", "right")- ] $- selfClosingTag "style:list-level-label-alignment"- [ ("text:label-followed-by", "listtab")- , ("text:list-tab-stop-position", indent <> "in")- , ("fo:text-indent", "-0.25in")- , ("fo:margin-left", indent <> "in")- ]- tableStyle :: Int -> Double -> [(Char,Double)] -> Doc Text tableStyle num textWidth wcs = let tableId = "Table" <> tshow (num + 1)@@ -846,15 +864,17 @@ columnStyles = map colStyle wcs in cellStyles $$ table $$ vcat columnStyles -paraStyle :: PandocMonad m => [(Text,Text)] -> OD m Int+-- | Generate (or reuse) a paragraph style with the given attributes.+-- When the only attribute is @style:parent-style-name@ and no+-- indent/tight overrides are active, the parent name is returned+-- directly (no @Pn@ automatic style is created), so that the+-- predefined style passes through unchanged.+paraStyle :: PandocMonad m => [(Text,Text)] -> OD m Text paraStyle attrs = do- pn <- (+) 1 . length <$> gets stParaStyles i <- (*) (0.5 :: Double) . fromIntegral <$> gets stIndentPara b <- gets stInDefinition t <- gets stTight- let styleAttr = [ ("style:name" , "P" <> tshow pn)- , ("style:family" , "paragraph" )]- indentVal = flip (<>) "in" . tshow $ if b then max 0.5 i else i+ let indentVal = flip (<>) "in" . tshow $ if b then max 0.5 i else i tight = if t then [ ("fo:margin-top" , "0in" ) , ("fo:margin-bottom" , "0in" )] else []@@ -865,31 +885,32 @@ , ("style:auto-text-indent" , "false" )] else [] attributes = indent <> tight- paraProps = if null attributes- then mempty- else selfClosingTag- "style:paragraph-properties" attributes- addParaStyle $ inTags True "style:style" (styleAttr <> attrs) paraProps- return pn--paraStyleFromParent :: PandocMonad m => Text -> [(Text,Text)] -> OD m Int-paraStyleFromParent parent attrs = do- pn <- (+) 1 . length <$> gets stParaStyles- let styleAttr = [ ("style:name" , "P" <> tshow pn)- , ("style:family" , "paragraph")- , ("style:parent-style-name", parent)]- paraProps = if null attrs- then mempty- else selfClosingTag- "style:paragraph-properties" attrs- addParaStyle $ inTags True "style:style" styleAttr paraProps- return pn-+ case (attributes, attrs) of+ ([], [("style:parent-style-name", parent)]) -> return parent+ _ -> do+ pn <- (+) 1 . length <$> gets stParaStyles+ let name = "P" <> tshow pn+ styleAttr = [ ("style:name" , name)+ , ("style:family", "paragraph") ]+ paraProps = if null attributes+ then mempty+ else selfClosingTag+ "style:paragraph-properties" attributes+ addParaStyle $ inTags True "style:style" (styleAttr <> attrs) paraProps+ return name -paraListStyle :: PandocMonad m => Int -> OD m Int-paraListStyle l = paraStyle- [("style:parent-style-name","Text_20_body")- ,("style:list-style-name", "L" <> tshow l)]+paraStyleFromParent :: PandocMonad m => Text -> [(Text,Text)] -> OD m Text+paraStyleFromParent parent attrs+ | null attrs = return parent+ | otherwise = do+ pn <- (+) 1 . length <$> gets stParaStyles+ let name = "P" <> tshow pn+ styleAttr = [ ("style:name" , name)+ , ("style:family" , "paragraph")+ , ("style:parent-style-name", parent)]+ paraProps = selfClosingTag "style:paragraph-properties" attrs+ addParaStyle $ inTags True "style:style" styleAttr paraProps+ return name paraTableStyles :: Text -> Int -> [Alignment] -> [(Text, Doc Text)] paraTableStyles _ _ [] = []
src/Text/Pandoc/Writers/Powerpoint/Output.hs view
@@ -2689,12 +2689,16 @@ mediaInfos <- mconcat . M.elems <$> gets stMediaIds filePaths <- patternsToFilePaths $ inheritedPatterns p let mediaFps = filter (match (compile "ppt/media/image*")) filePaths+ fontFps = filter (match (compile "ppt/fonts/*")) filePaths let defaults = [ DefaultContentType "xml" "application/xml" , DefaultContentType "rels" "application/vnd.openxmlformats-package.relationships+xml" ] mediaDefaults = nub $ mapMaybe mediaContentType mediaInfos <> mapMaybe mediaFileContentType mediaFps+ fontDefaults = [ DefaultContentType "fntdata" "application/x-fontdata"+ | any (\fp -> takeExtension fp == ".fntdata") fontFps+ ] inheritedOverrides = mapMaybe pathToOverride filePaths createdOverrides = mapMaybe pathToOverride [ "docProps/core.xml"@@ -2708,7 +2712,7 @@ relativePaths speakerNotesOverrides <- mapMaybe pathToOverride <$> getSpeakerNotesFilePaths return $ ContentTypes- (defaults <> mediaDefaults)+ (defaults <> mediaDefaults <> fontDefaults) (inheritedOverrides <> createdOverrides <> slideOverrides <> speakerNotesOverrides) presML :: T.Text
src/Text/Pandoc/Writers/Powerpoint/Presentation.hs view
@@ -176,11 +176,6 @@ runPres env st p = (pres, reverse $ stLog finalSt) where (pres, finalSt) = runState (runReaderT p env) st --- GHC 7.8 will still complain about concat <$> mapM unless we specify--- Functor. We can get rid of this when we stop supporting GHC 7.8.-concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b]-concatMapM f xs = liftM concat (mapM f xs)- type Pixels = Integer data Presentation = Presentation DocProps [Slide]@@ -348,7 +343,7 @@ -------------------------------------------------- inlinesToParElems :: [Inline] -> Pres [ParaElem]-inlinesToParElems = concatMapM inlineToParElems+inlinesToParElems = fmap mconcat . mapM inlineToParElems inlineToParElems :: Inline -> Pres [ParaElem] inlineToParElems (Str s) = do@@ -484,7 +479,7 @@ , pPropIndent = Just 0 } , envRunProps = (envRunProps r){rPropForceSize = Just blockQuoteSize}})$- concatMapM blockToParagraphs blks+ mconcat <$> mapM blockToParagraphs blks -- TODO: work out the format blockToParagraphs blk@(RawBlock _ _) = do addLogMessage $ BlockNotRendered blk return []@@ -508,7 +503,7 @@ , pPropIndent = Nothing , pPropIncremental = incremental }}) $- concatMapM multiParList blksLst+ mconcat <$> mapM multiParList blksLst blockToParagraphs (OrderedList listAttr blksLst) = do pProps <- asks envParaProps incremental <- listShouldBeIncremental@@ -518,7 +513,7 @@ , pPropIndent = Nothing , pPropIncremental = incremental }}) $- concatMapM multiParList blksLst+ mconcat <$> mapM multiParList blksLst blockToParagraphs (DefinitionList entries) = do incremental <- listShouldBeIncremental let go :: ([Inline], [[Block]]) -> Pres [Paragraph]@@ -526,11 +521,12 @@ term <-blockToParagraphs $ Para [Strong ils] -- For now, we'll treat each definition term as a -- blockquote. We can extend this further later.- definition <- concatMapM (blockToParagraphs . BlockQuote) blksLst+ definition <-+ mconcat <$> mapM (blockToParagraphs . BlockQuote) blksLst return $ term ++ definition local (\env -> env {envParaProps = (envParaProps env) {pPropIncremental = incremental}})- $ concatMapM go entries+ $ mconcat <$> mapM go entries blockToParagraphs (Div (_, classes, _) blks) = let hasIncremental = "incremental" `elem` classes hasNonIncremental = "nonincremental" `elem` classes@@ -538,7 +534,7 @@ | hasNonIncremental -> Just InNonIncremental | otherwise -> Nothing addIncremental env = env { envInIncrementalDiv = incremental }- in local addIncremental (concatMapM blockToParagraphs blks)+ in local addIncremental (mconcat <$> mapM blockToParagraphs blks) blockToParagraphs (Figure attr capt blks) = -- This never seems to be used: blockToParagraphs (Shared.figureDiv attr capt blks) blockToParagraphs hr@HorizontalRule = notRendered hr@@ -563,7 +559,7 @@ , pPropLevel = level + 1 } })- $ concatMapM blockToParagraphs bs+ $ mconcat <$> mapM blockToParagraphs bs return $ p ++ ps cellToParagraphs :: Alignment -> SimpleCell -> Pres [Paragraph]@@ -824,7 +820,7 @@ blockToSpeakerNotes :: Block -> Pres SpeakerNotes blockToSpeakerNotes (Div (_, ["notes"], _) blks) = local (\env -> env{envInSpeakerNotes=True}) $- SpeakerNotes <$> concatMapM blockToParagraphs blks+ SpeakerNotes . mconcat <$> mapM blockToParagraphs blks blockToSpeakerNotes _ = return mempty handleSpeakerNotes :: Block -> Pres ()@@ -891,6 +887,12 @@ subtitle <- inlinesToParElems $ lookupMetaInlines "subtitle" meta authors <- mapM inlinesToParElems $ docAuthors meta date <- inlinesToParElems $ docDate meta+ -- Get speaker notes from metadata "notes" field+ let notesBlocks = lookupMetaBlocks "notes" meta+ speakerNotes <- if null notesBlocks+ then return mempty+ else local (\env -> env{envInSpeakerNotes=True}) $+ SpeakerNotes . mconcat <$> mapM blockToParagraphs notesBlocks if null title && null subtitle && null authors && null date then return Nothing else return $@@ -898,7 +900,7 @@ Slide metadataSlideId (MetadataSlide title subtitle authors date)- mempty+ speakerNotes Nothing addSpeakerNotesToMetaSlide :: Slide -> [Block] -> Pres (Slide, [Block])
src/Text/Pandoc/Writers/RST.hs view
@@ -20,7 +20,8 @@ GeneralCategory( ClosePunctuation, OpenPunctuation, InitialQuote, FinalQuote, DashPunctuation, OtherPunctuation))-import Data.List (transpose, intersperse, foldl')+import Data.List (transpose, intersperse)+import qualified Data.List as L import qualified Data.List.NonEmpty as NE import Data.Maybe (fromMaybe) import qualified Data.Text as T@@ -674,7 +675,7 @@ | null contents = [outer] | otherwise = combineAll contents where contents = dropInlineParent outer- combineAll = foldl' combine []+ combineAll = L.foldl' combine [] combine :: [Inline] -> Inline -> [Inline] combine f i =
@@ -63,7 +63,8 @@ import Data.Either (isRight) import Data.Aeson (ToJSON (..), encode) import Data.Char (chr, ord, isSpace, isLetter, isUpper)-import Data.List (groupBy, intersperse, foldl', transpose)+import Data.List (groupBy, intersperse, transpose, zipWith4)+import qualified Data.List as L import Data.List.NonEmpty (NonEmpty((:|))) import Data.Text.Conversions (FromText(..)) import qualified Data.Map as M@@ -79,7 +80,7 @@ import Text.Pandoc.Shared (stringify, makeSections, blocksToInlines) import Text.Pandoc.Walk (Walkable(..)) import qualified Text.Pandoc.UTF8 as UTF8-import Text.Pandoc.XML (escapeStringForXML)+import Text.Pandoc.XML (escapeStringForXML, rdfaAttributes, html5Attributes) import Text.DocTemplates (Context(..), Val(..), TemplateTarget, ToContext(..), FromContext(..)) import Text.Pandoc.Chunks (tocToList, toTOCTree)@@ -88,6 +89,7 @@ import Text.Pandoc.Translations (setTranslations) import Data.Maybe (fromMaybe) import qualified Text.Pandoc.Writers.AnnotatedTable as Ann+import qualified Data.Set as Set -- import Debug.Trace @@ -205,9 +207,18 @@ ,if null classes then empty else "class=" <> doubleQuotes (text $ T.unpack (T.unwords classes))- ,hsep (map (\(k,v) -> text (T.unpack k) <> "=" <>+ ,hsep (map (\(k,v) -> formatKey k <> "=" <> doubleQuotes (text $ T.unpack (escapeStringForXML v))) kvs) ])+ where+ formatKey x = text . T.unpack $+ if (x `Set.member` (html5Attributes <> rdfaAttributes)+ && x /= "label") -- #10048+ || T.any (== ':') x -- e.g. epub: namespace+ || "data-" `T.isPrefixOf` x+ || "aria-" `T.isPrefixOf` x+ then x+ else "data-" <> x addSpaceIfNotEmpty :: HasChars a => Doc a -> Doc a addSpaceIfNotEmpty f = if isEmpty f then f else " " <> f@@ -321,9 +332,18 @@ (setTopBorder DoubleLine . setBottomBorder DoubleLine) footCells pure $ gridRows $ redoWidths opts colspecs rows +data ColWidthInfo =+ ColWidthInfo+ { colWidthSpecified :: Int+ , colWidthFull :: Int+ , colWidthMin :: Int+ , colWidthUsed :: Int }+ deriving (Show, Ord, Eq)+ -- Returns (current widths, full widths, min widths)-extractColWidths :: WriterOptions -> [[RenderedCell Text]] -> ([Int], [Int], [Int])-extractColWidths opts rows = (currentwidths, fullwidths, minwidths)+extractColWidths :: WriterOptions -> [[RenderedCell Text]] -> [ColWidthInfo]+extractColWidths opts rows =+ zipWith4 ColWidthInfo specifiedwidths fullwidths minwidths currentwidths where getWidths calcOffset = map (fromMaybe 0 . maximumMay) (transpose (map (concatMap (getCellWidths calcOffset)) rows))@@ -331,11 +351,15 @@ (calcOffset c `div` (cellColSpan c) + calcOffset c `rem` (cellColSpan c)) fullwidths = getWidths (max 1 . offset . cellContents)- currentwidths = getWidths cellWidth minwidths = case writerWrapText opts of WrapNone -> fullwidths _ -> getWidths (minOffset . cellContents)+ specifiedwidths = getWidths cellWidth+ currentwidths = zipWith (\specw minw -> if specw == 0+ then 0+ else max specw minw)+ specifiedwidths minwidths resetWidths :: [Int] -> [RenderedCell Text] -> [RenderedCell Text] resetWidths _ [] = []@@ -352,21 +376,37 @@ redoWidths opts colspecs rows = map (resetWidths newwidths) rows where numcols = length colspecs- isSimple = all ((== ColWidthDefault) . snd) colspecs- (actualwidths, fullwidths, minwidths) = extractColWidths opts rows- totwidth = writerColumns opts - (3 * numcols) - 1- evenwidth = totwidth `div` numcols + totwidth `rem` numcols- keepwidths = filter (< evenwidth) fullwidths- evenwidth' = (totwidth - sum keepwidths) `div`- (numcols - length keepwidths)- ensureMinWidths = zipWith max minwidths- newwidths = ensureMinWidths $- case isSimple of- True | sum fullwidths <= totwidth -> fullwidths- | otherwise -> map (\w -> if w < evenwidth- then w- else evenwidth') fullwidths- False -> actualwidths+ widthInfos = extractColWidths opts rows+ colsAvailable = writerColumns opts - (3 * numcols) - 1+ -- now, we need to change colWidthUsed 0 to an appropriate number;+ -- either the full width if it fits easily, or an appropriate fraction+ -- of the remaining width. This must be done recursively, because+ -- once we decide that the full width can fit, that may leave less+ -- space for the remaining columns with default width to fill.+ recalculateWidths finalRun numRuns infos =+ let numUnassigned = length (filter ((== 0) . colWidthUsed) infos)+ unusedCols = colsAvailable - sum (map colWidthUsed infos)+ defwidth = if numUnassigned == 0+ then 0+ else unusedCols `div` numUnassigned+ infos' = map (\info -> if colWidthUsed info == 0+ then if finalRun+ then info{ colWidthUsed =+ max (colWidthMin info) defwidth }+ else if colWidthFull info <= defwidth+ then info{ colWidthUsed = colWidthFull info }+ else info+ else info) infos+ in if finalRun || numRuns > 4+ then infos'+ else if infos == infos'+ then recalculateWidths True (numRuns + 1) infos+ -- run again, filling in unassigned widths with a fraction of the+ -- remaining width+ else recalculateWidths False (numRuns + 1) infos'+ -- run again, filling in unassigned widths only if the full with+ -- would be less than the fraction of remaining width+ newwidths = map colWidthUsed $ recalculateWidths False (1 :: Int) widthInfos makeDummy :: RenderedCell Text -> RenderedCell Text makeDummy c =@@ -381,7 +421,7 @@ cellTopBorder = NoLine } addDummies :: [[RenderedCell Text]] -> [[RenderedCell Text]]-addDummies = reverse . foldl' go []+addDummies = reverse . L.foldl' go [] where go [] cs = [cs] go (prevRow:rs) cs = addDummiesToRow prevRow cs : prevRow : rs@@ -468,7 +508,7 @@ formatHeaderLine :: Show a => LineStyle -> [[RenderedCell a]] -> Doc Text formatHeaderLine lineStyle rows =- literal $ foldl'+ literal $ L.foldl' (\t row -> combineBorders t (render Nothing $ formatBorder (const lineStyle) True row)) mempty rows @@ -479,7 +519,7 @@ then char '|' else char '+' where- (lastBorderStyle, borderParts) = foldl' addBorder (NoLine, mempty) cs+ (lastBorderStyle, borderParts) = L.foldl' addBorder (NoLine, mempty) cs addBorder (prevBorderStyle, accum) c = (borderStyle c, accum <> char junctionChar <> toBorderSection c) where junctionChar = case (borderStyle c, prevBorderStyle) of@@ -533,7 +573,7 @@ toCharWidth :: WriterOptions -> Double -> Int toCharWidth opts width =- max 1 (floor (width * fromIntegral (writerColumns opts)) - 3)+ max 0 (floor (width * fromIntegral (writerColumns opts)) - 3) gridRow :: (Monad m, HasChars a) => WriterOptions
src/Text/Pandoc/Writers/Texinfo.hs view
@@ -17,7 +17,8 @@ import Control.Monad.State.Strict ( StateT, MonadState(get), gets, modify, evalStateT ) import Data.Char (chr, ord, isAlphaNum)-import Data.List (maximumBy, transpose, foldl')+import Data.List (maximumBy, transpose)+import qualified Data.List as L import Data.List.NonEmpty (nonEmpty) import Data.Ord (comparing) import qualified Data.Map as M@@ -148,6 +149,19 @@ inCmd :: Text -> Doc Text -> Doc Text inCmd cmd contents = char '@' <> literal cmd <> braces contents +isCodeOrBreak :: Inline -> Bool+isCodeOrBreak (Code{}) = True+isCodeOrBreak LineBreak = True+isCodeOrBreak _ = False++isCode :: Inline -> Bool+isCode (Code{}) = True+isCode _ = False++codeToStr :: Inline -> Inline+codeToStr (Code _ s) = Str s+codeToStr x = x+ -- | Convert Pandoc block element to Texinfo. blockToTexinfo :: PandocMonad m => Block -- ^ Block to convert@@ -158,8 +172,12 @@ blockToTexinfo (Plain lst) = inlineListToTexinfo lst -blockToTexinfo (Para lst) =- inlineListToTexinfo lst -- this is handled differently from Plain in blockListToTexinfo+-- this is handled differently from Plain in blockListToTexinfo+blockToTexinfo (Para lst)+ | all isCodeOrBreak lst+ = (\xs -> "@example" $$ vcat xs $$ "@end example")+ <$> mapM (inlineToTexinfo . codeToStr) (filter isCode lst)+ | otherwise = inlineListToTexinfo lst blockToTexinfo (LineBlock lns) = blockToTexinfo $ linesToPara lns@@ -330,7 +348,7 @@ -> [[Block]] -> TI m (Doc Text) tableAnyRowToTexinfo itemtype aligns cols =- (literal itemtype $$) . foldl' (\row item -> row $$+ (literal itemtype $$) . L.foldl' (\row item -> row $$ (if isEmpty row then empty else text " @tab ") <> item) empty <$> zipWithM alignedBlock aligns cols alignedBlock :: PandocMonad m
src/Text/Pandoc/Writers/Typst.hs view
@@ -18,7 +18,7 @@ writeTypst ) where import Text.Pandoc.Definition-import Text.Pandoc.Class ( PandocMonad, report )+import Text.Pandoc.Class ( PandocMonad, report, runPure, fetchItem ) import Text.Pandoc.ImageSize ( dimension, Dimension(Pixel), Direction(..), showInInch ) import Text.Pandoc.Options ( WriterOptions(..), WrapOption(..), isEnabled,@@ -33,10 +33,11 @@ import Text.Pandoc.Writers.Shared ( lookupMetaInlines, lookupMetaString, metaToContext, defField, resetField, setupTranslations )-import Text.Pandoc.Shared (isTightList, orderedListMarkers, tshow)+import Text.Pandoc.Shared (isTightList, orderedListMarkers, tshow, stringify) import Text.Pandoc.Highlighting (highlight, formatTypstBlock, formatTypstInline, styleToTypst) import Text.Pandoc.Translations (Term(Abstract), translateTerm)+import Text.Pandoc.Error (PandocError(PandocSomeError)) import Text.Pandoc.Walk (query) import Text.Pandoc.Writers.Math (convertMath) import qualified Text.TeXMath as TM@@ -44,11 +45,13 @@ import Text.DocTemplates (renderTemplate) import Text.Pandoc.Extensions (Extension(..)) import Text.Pandoc.Logging (LogMessage(..))+import qualified Text.Pandoc.UTF8 as UTF8 import Text.Collate.Lang (Lang(..), parseLang) import Text.Printf (printf) import Data.Char (isDigit) import Data.Maybe (fromMaybe) import Unicode.Char (isXIDContinue)+import qualified Data.ByteString as B -- | Convert Pandoc to Typst. writeTypst :: PandocMonad m => WriterOptions -> Pandoc -> m Text@@ -161,10 +164,10 @@ toTypstSetText :: [(Text, Text)] -> Doc Text toTypstSetText [] = ""-toTypstSetText typstTextAttrs = "set text" <> parens (toTypstPropsListSep typstTextAttrs) <> "; "+toTypstSetText typstTextAttrs = "set text" <> parens (toTypstPropsListSep typstTextAttrs) <> ";" toTypstPoundSetText :: [(Text, Text)] -> Doc Text-toTypstPoundSetText [] = ""+toTypstPoundSetText [] = mempty toTypstPoundSetText typstTextAttrs = "#" <> toTypstSetText typstTextAttrs toTypstBracesSetText :: [(Text, Text)] -> Doc Text -> Doc Text@@ -310,7 +313,7 @@ ColSpan n -> [ "colspan: " <> tshow n ]) ++ map formatTypstProp typstAttrs2 cellContents <- blocksToTypst bs- let contents2 = brackets (toTypstPoundSetText typstTextAttrs <> cellContents)+ let contents2 = brackets (toTypstPoundSetText typstTextAttrs $$ cellContents) pure $ if null cellattrs then contents2 else "table.cell" <>@@ -363,12 +366,13 @@ Figure (ident,_,_) (Caption _mbshort capt) blocks -> do caption <- blocksToTypst capt opts <- gets stOptions+ let toImage (Image attr inlines (src, _)) =+ Just $ mkImage opts False src attr (getAlt attr inlines)+ toImage _ = Nothing contents <- case blocks of -- don't need #box around block-level image- [Para [Image attr _ (src, _)]]- -> pure $ mkImage opts False src attr- [Plain [Image attr _ (src, _)]]- -> pure $ mkImage opts False src attr+ [Para [img]] | Just i <- toImage img -> pure i+ [Plain [img]] | Just i <- toImage img -> pure i _ -> brackets <$> blocksToTypst blocks let lab = toLabel FreestandingLabel ident return $ "#figure(" <> nest 2 ((contents <> ",")@@ -391,7 +395,8 @@ let allTypstTextAttrs = typstTextAttrs ++ langAttrs contents <- blocksToTypst blocks return $ "#block" <> toTypstPropsListParens typstAttrs <> "["- $$ toTypstPoundSetText allTypstTextAttrs <> contents+ $$ toTypstPoundSetText allTypstTextAttrs+ $$ contents $$ ("]" <+> lab) defListItemToTypst :: PandocMonad m => ([Inline], [[Block]]) -> TW m (Doc Text)@@ -409,6 +414,10 @@ return $ hang ind (marker <> space) contents inlinesToTypst :: PandocMonad m => [Inline] -> TW m (Doc Text)+inlinesToTypst (i@(Span (ident,_,_) _):is) | not (T.null ident) =+ -- insert a zero-width space U+200B before the label+ -- because a typst label refers to preceding element (see #11568)+ ("\x200B" <>) . hcat <$> mapM inlineToTypst (escapeParens (i:is)) inlinesToTypst ils = hcat <$> mapM inlineToTypst (escapeParens ils) -- Add an escape before a parenthesis right after a non-space element.@@ -443,7 +452,7 @@ WrapPreserve -> return cr WrapAuto -> return space WrapNone -> return space- LineBreak -> return (space <> "\\" <> cr)+ LineBreak -> return (space <> "\\" <> space) Math mathType str -> do res <- convertMath TM.writeTypst mathType str case res of@@ -529,16 +538,16 @@ (if inlines == [Str src] then mempty else nowrap $ brackets contents)- Image attr _inlines (src,_tit) -> do+ Image attr inlines (src,_tit) -> do opts <- gets stOptions- pure $ mkImage opts True src attr+ pure $ mkImage opts True src attr (getAlt attr inlines) Note blocks -> do contents <- blocksToTypst blocks return $ "#footnote" <> brackets (chomp contents) -- see #9104; need box or image is treated as block-level-mkImage :: WriterOptions -> Bool -> Text -> Attr -> Doc Text-mkImage opts useBox src attr+mkImage :: WriterOptions -> Bool -> Text -> Attr -> Maybe Text -> Doc Text+mkImage opts useBox src attr mbAlt | useBox = "#box" <> parens coreImage | otherwise = coreImage where@@ -552,12 +561,34 @@ (case dimension Width attr of Nothing -> mempty Just dim -> ", width: " <> showDim dim)+ altAttr = case mbAlt of+ Just alt -> ", alt: " <> doubleQuoted alt+ Nothing -> mempty isData = "data:" `T.isPrefixOf` src'- dataSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><image xlink:href=\"" <> src' <> "\" /></svg>"- coreImage- | isData = "image.decode" <> parens(doubleQuoted dataSvg <> dimAttrs)- | otherwise = "image" <> parens (doubleQuoted src' <> dimAttrs)+ eitherImageData = if isData+ then runPure (fetchItem src)+ else Left $ PandocSomeError "not a data URI"+ toArray = parens . hcat . intersperse "," . map (literal . tshow) . B.unpack+ attrs = dimAttrs <> altAttr+ coreImage = "image" <> parens+ (case eitherImageData of+ Right (contents, Just "image/svg+xml")+ -> "bytes" <> parens (doubleQuoted (UTF8.toText contents)) <> attrs+ Right (bytes, _mime) -> "bytes" <> parens (toArray bytes) <> attrs+ Left _ -> doubleQuoted src' <> attrs) +-- | Extract alt text from image attributes and inlines.+-- Use explicit alt attribute if present; otherwise use inlines.+-- Empty alt="" means decorative image (no alt text).+getAlt :: Attr -> [Inline] -> Maybe Text+getAlt (_, _, kvs) imgInlines =+ case lookup "alt" kvs of+ Just "" -> Nothing -- decorative+ Just alt -> Just alt+ Nothing -> case imgInlines of+ [] -> Nothing+ _ -> Just (stringify imgInlines)+ textstyle :: PandocMonad m => Doc Text -> [Inline] -> TW m (Doc Text) textstyle s inlines = do (s <>) . brackets . fixInitialAfterBreakEscape@@ -579,25 +610,35 @@ escapeTypst :: Bool -> EscapeContext -> Text -> Doc Text escapeTypst smart context t = (case T.uncons t of- Just (c, _)+ Just (c, rest) | c == ';' -> char '\\' -- see #9252+ | c == '.'+ , not (T.null rest) -> char '\\' -- see #11511 | needsEscapeAtLineStart c || isOrderedListMarker t -> afterBreak "\\" _ -> mempty) <>- (literal (T.replace "//" "\\/\\/"- (if T.any needsEscape t- then T.concatMap escapeChar t- else t)))+ literal (snd $ T.foldl' go ('\n', mempty) t) where+ go (lastc, t') c+ | needsEscape c = (c, t' <> escapeChar c)+ | c == '-', lastc == '-', smart = (c, t' <> T.pack ['\\',c])+ | c == '/', lastc == '/' = (c, t' <> T.pack ['\\',c])+ | otherwise = (c, T.snoc t' c) escapeChar c | c == '\160' = "~"+ | c == '\8216', smart = "'" -- left quote | c == '\8217', smart = "'" -- apostrophe+ | c == '\8220', smart = "\"" -- left double quote+ | c == '\8221', smart = "\"" -- right double quote | c == '\8212', smart = "---" -- em dash | c == '\8211', smart = "--" -- en dash | needsEscape c = "\\" <> T.singleton c | otherwise = T.singleton c needsEscape '\160' = True+ needsEscape '\8216' = smart needsEscape '\8217' = smart+ needsEscape '\8220' = smart+ needsEscape '\8221' = smart needsEscape '\8212' = smart needsEscape '\8211' = smart needsEscape '\'' = smart
test/Tests/MediaBag.hs view
@@ -7,42 +7,50 @@ import Text.Pandoc.Class.IO (extractMedia) import Text.Pandoc.Class (fillMediaBag, runIOorExplode) import System.IO.Temp (withTempDirectory)-import Text.Pandoc.Shared (inDirectory) import System.FilePath import Text.Pandoc.Builder as B-import System.Directory (doesFileExist, copyFile)+import qualified Data.Text as T+import System.Directory (doesFileExist, makeAbsolute) tests :: [TestTree] tests = [ testCase "test fillMediaBag & extractMedia" $- withTempDirectory "." "extractMediaTest" $ \tmpdir -> inDirectory tmpdir $ do- copyFile "../../test/lalune.jpg" "moon.jpg"+ withTempDirectory "." "extractMediaTest" $ \tmpdir -> do+ -- Use absolute paths so the test does not need to change+ -- the process-wide current directory (which is not thread-safe+ -- and breaks other tests running in parallel).+ absTmpdir <- makeAbsolute tmpdir+ absLalune <- makeAbsolute "lalune.jpg" let d = B.doc $- B.para (B.image "../../test/lalune.jpg" "" mempty) <>- B.para (B.image "moon.jpg" "" mempty) <>+ -- simple relative path -> extracted with original name+ B.para (B.image "lalune.jpg" "" mempty) <>+ -- absolute path -> extracted with hashed name+ B.para (B.image (T.pack absLalune) "" mempty) <> B.para (B.image "data:image/png;base64,cHJpbnQgImhlbGxvIgo=;.lua+%2f%2e%2e%2f%2e%2e%2fa%2elua" "" mempty) <> B.para (B.image "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" "" mempty)+ let fooDir = absTmpdir </> "foo" runIOorExplode $ do fillMediaBag d- extractMedia "foo" d- exists1 <- doesFileExist ("foo" </> "moon.jpg")+ extractMedia fooDir d+ exists1 <- doesFileExist (fooDir </> "lalune.jpg") assertBool "file in directory is not extracted with original name" exists1- exists2 <- doesFileExist ("foo" </> "f9d88c3dbe18f6a7f5670e994a947d51216cdf0e.jpg")- assertBool "file above directory is not extracted with hashed name" exists2- exists3 <- doesFileExist ("foo" </> "2a0eaa89f43fada3e6c577beea4f2f8f53ab6a1d.png")- exists4 <- doesFileExist "a.lua"+ exists2 <- doesFileExist (fooDir </> "f9d88c3dbe18f6a7f5670e994a947d51216cdf0e.jpg")+ assertBool "file with absolute path is not extracted with hashed name" exists2+ exists3 <- doesFileExist (fooDir </> "2a0eaa89f43fada3e6c577beea4f2f8f53ab6a1d.png")+ exists4 <- doesFileExist (absTmpdir </> "a.lua") assertBool "data uri with malicious payload gets written outside of destination dir" (exists3 && not exists4)- exists5 <- doesFileExist ("foo" </> "d5fceb6532643d0d84ffe09c40c481ecdf59e15a.gif")+ exists5 <- doesFileExist (fooDir </> "d5fceb6532643d0d84ffe09c40c481ecdf59e15a.gif") assertBool "data uri with gif is not properly decoded" exists5 -- double-encoded version: let e = B.doc $ B.para (B.image "data:image/png;base64,cHJpbnQgInB3bmVkIgo=;.lua+%252f%252e%252e%252f%252e%252e%252fb%252elua" "" mempty)+ let barDir = absTmpdir </> "bar" runIOorExplode $ do fillMediaBag e- extractMedia "bar" e- exists6 <- doesFileExist ("bar" </> "772ceca21a2751863ec46cb23db0e7fc35b9cff8.png")- exists7 <- doesFileExist "b.lua"+ extractMedia barDir e+ exists6 <- doesFileExist (barDir </> "772ceca21a2751863ec46cb23db0e7fc35b9cff8.png")+ exists7 <- doesFileExist (absTmpdir </> "b.lua") assertBool "data uri with double-encoded malicious payload gets written outside of destination dir" (exists6 && not exists7) ]
test/Tests/Old.hs view
@@ -344,7 +344,7 @@ s5WriterTest :: FilePath -> String -> [String] -> String -> TestTree s5WriterTest pandocPath modifier opts format = test pandocPath (format ++ " writer (" ++ modifier ++ ")")- (["-r", "native", "-w", format] ++ opts)+ (["-r", "native", "-w", format] ++ opts ++ ["--variable", "pandoc-version="]) "s5.native" ("s5-" ++ modifier <.> "html") fb2WriterTest :: FilePath -> String -> [String] -> String -> String -> TestTree
test/Tests/Readers/Docx.hs view
@@ -215,6 +215,18 @@ "text in shape format" "docx/text_in_shape_format.docx" "docx/text_in_shape_format.native"+ , testCompare+ "image inside textbox content"+ "docx/textbox_image.docx"+ "docx/textbox_image.native"+ , testCompare+ "image inside textbox content with duplicate encoding"+ "docx/textbox_image_duplicate_encoding.docx"+ "docx/textbox_image_duplicate_encoding.native"+ , testCompare+ "image with textbox caption in same paragraph"+ "docx/image_with_textbox_caption.docx"+ "docx/image_with_textbox_caption.native" ] , testGroup "blocks" [ testCompare@@ -318,6 +330,10 @@ "docx/table_with_list_cell.docx" "docx/table_with_list_cell.native" , testCompare+ "a table with gridBefore"+ "docx/table_gridbefore.docx"+ "docx/table_gridbefore.native"+ , testCompare "a table with a header which contains rowspans greater than 1" "docx/table_header_rowspan.docx" "docx/table_header_rowspan.native"@@ -469,6 +485,15 @@ [ testMediaBag "image extraction" "docx/image.docx"+ , testMediaBag+ "image inside textbox content populates media bag"+ "docx/textbox_image.docx"+ , testMediaBag+ "image inside textbox content with duplicate encoding populates media bag"+ "docx/textbox_image_duplicate_encoding.docx"+ , testMediaBag+ "image with textbox caption in same paragraph populates media bag"+ "docx/image_with_textbox_caption.docx" ] , testGroup "custom styles" [ testCompare
test/Tests/Readers/HTML.hs view
@@ -124,7 +124,7 @@ , testGroup "header" [ test htmlNativeDivs "<header> is parsed as a div" $ "<header id=\"title\">Title</header>" =?>- divWith ("title", mempty, mempty) (plain "Title")+ divWith ("title", ["header"], mempty) (plain "Title") ] , testGroup "code block" [ test html "attributes in pre > code element" $
test/Tests/Readers/Markdown.hs view
@@ -375,6 +375,12 @@ , test markdownSmart "unclosed double quote" ("**this should \"be bold**" =?> para (strong "this should \8220be bold"))+ , test markdownSmart "single quote in inline note within single quotes" $ -- issue #11613+ "'a^['b'.] c.'" =?>+ para (singleQuoted ("a" <> note (para (singleQuoted "b" <> ".")) <> space <> "c."))+ , test markdownSmart "double quote in inline note within double quotes" $ -- issue #11613+ "\"a^[\"b\".] c.\"" =?>+ para (doubleQuoted ("a" <> note (para (doubleQuoted "b" <> ".")) <> space <> "c.")) ] , testGroup "sub- and superscripts" [
test/Tests/Readers/ODT.hs view
@@ -167,6 +167,7 @@ namesOfTestsComparingToNative = [ "blockquote" , "image" , "imageIndex"+ , "imageRelative" , "imageWithCaption" , "inlinedCode" , "listContinueNumbering"@@ -175,6 +176,8 @@ , "orderedListRoman" , "orderedListSimple" , "orderedListHeader"+ , "preformattedText"+ , "preformattedTextParentStyle" , "referenceToChapter" , "referenceToListItem" , "referenceToText"@@ -186,6 +189,7 @@ -- , "table" , "textMixedStyles" , "tableWithContents"+ , "tableWithSpans" , "unicode" , "unorderedList" , "unorderedListHeader"
test/Tests/Readers/Org/Block.hs view
@@ -43,7 +43,7 @@ T.unlines [ ": echo hello" , ": echo dear tester" ] =?>- codeBlockWith ("", ["example"], []) "echo hello\necho dear tester\n"+ codeBlockWith ("", [], []) "echo hello\necho dear tester\n" , "Example block surrounded by text" =: T.unlines [ "Greetings"@@ -52,7 +52,7 @@ , "Bye" ] =?> mconcat [ para "Greetings"- , codeBlockWith ("", ["example"], [])+ , codeBlockWith ("", [], []) "echo hello\necho dear tester\n" , para "Bye" ]
test/Tests/Readers/Org/Block/CodeBlock.hs view
@@ -99,7 +99,7 @@ results' = "65\n" in codeBlockWith ("", classes, params) code' <>- codeBlockWith ("", ["example"], []) results'+ codeBlockWith ("", [], []) results' , "Source block with results and :exports code" =: T.unlines [ "#+begin_src emacs-lisp :exports code"@@ -126,7 +126,7 @@ , "#+RESULTS:" , ": 65" ] =?> let results' = "65\n"- in codeBlockWith ("", ["example"], []) results'+ in codeBlockWith ("", [], []) results' , "Source block with results and :exports none" =: T.unlines [ "#+begin_src emacs-lisp :exports none"@@ -171,7 +171,7 @@ , "a rule." , "#+eND_exAMPle" ] =?>- codeBlockWith ("", ["example"], [])+ codeBlockWith ("", [], []) "A chosen representation of\na rule.\n" , "Code block with caption" =:
test/Tests/Writers/Docx.hs view
@@ -1,10 +1,18 @@+{-# LANGUAGE OverloadedStrings #-} module Tests.Writers.Docx (tests) where -import Text.Pandoc+import Codec.Archive.Zip (findEntryByPath, fromEntry, toArchive)+import qualified Data.ByteString.Lazy as BL+import Data.List (isInfixOf, isPrefixOf)+import qualified Data.Map as M+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.IO as T import Test.Tasty-import Tests.Writers.OOXML import Test.Tasty.HUnit-import Data.List (isPrefixOf)+import Tests.Writers.OOXML+import Text.Pandoc+import Text.XML.Light (QName(QName), findAttr, findElements, parseXMLDoc) -- we add an extra check to make sure that we're not writing in the -- toplevel docx directory. We don't want to accidentally overwrite an@@ -213,5 +221,157 @@ def "docx/document-properties-short-desc.native" "docx/golden/document-properties-short-desc.docx"+ ]+ , testGroup "top-level-division"+ -- Helper to count occurrences of a substring+ -- Note: counts by splitting on "<w:sectPr" which marks section properties+ [ testCase "no section break before first chapter (#10578)" $ do+ -- With --top-level-division=chapter, there should be no section+ -- break before the first chapter (to avoid blank first page)+ let opts = def{ writerTopLevelDivision = TopLevelChapter }+ bs <- runIOorExplode $ do+ setVerbosity ERROR+ let doc = Pandoc mempty+ [ Header 1 ("ch1", [], []) [Str "Chapter", Space, Str "1"]+ , Para [Str "First", Space, Str "chapter."]+ ]+ writeDocx opts doc+ let archive = toArchive bs+ entry <- case findEntryByPath "word/document.xml" archive of+ Nothing -> assertFailure "Missing word/document.xml in output docx"+ Just e -> return e+ let docXml = show (fromEntry entry)+ -- Count occurrences of "<w:sectPr" (opening tag for section properties)+ let countOccurrences needle haystack =+ length (filter (needle `isPrefixOf`) (tails haystack))+ where tails [] = []; tails s@(_:xs) = s : tails xs+ let sectPrCount = countOccurrences "<w:sectPr" docXml+ -- Should have exactly 1 sectPr (the final document section),+ -- not 2 (which would mean one before the chapter heading)+ assertBool ("Expected 1 sectPr (final section only), found " ++ show sectPrCount)+ (sectPrCount == 1)+ , testCase "section breaks between chapters (#11482)" $ do+ -- With --top-level-division=chapter, there should be section+ -- breaks between chapters (but not before the first one)+ let opts = def{ writerTopLevelDivision = TopLevelChapter }+ bs <- runIOorExplode $ do+ setVerbosity ERROR+ let doc = Pandoc mempty+ [ Header 1 ("ch1", [], []) [Str "Chapter", Space, Str "1"]+ , Para [Str "First", Space, Str "chapter."]+ , Header 1 ("ch2", [], []) [Str "Chapter", Space, Str "2"]+ , Para [Str "Second", Space, Str "chapter."]+ , Header 1 ("ch3", [], []) [Str "Chapter", Space, Str "3"]+ , Para [Str "Third", Space, Str "chapter."]+ ]+ writeDocx opts doc+ let archive = toArchive bs+ entry <- case findEntryByPath "word/document.xml" archive of+ Nothing -> assertFailure "Missing word/document.xml in output docx"+ Just e -> return e+ let docXml = show (fromEntry entry)+ -- Count occurrences of "<w:sectPr" (opening tag for section properties)+ let countOccurrences needle haystack =+ length (filter (needle `isPrefixOf`) (tails haystack))+ where tails [] = []; tails s@(_:xs) = s : tails xs+ let sectPrCount = countOccurrences "<w:sectPr" docXml+ -- Should have 3 sectPr elements:+ -- - 1 before chapter 2+ -- - 1 before chapter 3+ -- - 1 final document section+ -- (No section break before chapter 1)+ assertBool ("Expected 3 sectPr elements, found " ++ show sectPrCount)+ (sectPrCount == 3)+ ]+ , testGroup "reference docx"+ [ testCase "no media directory override in content types" $ do+ let opts = def{ writerReferenceDoc = Just "docx/inline_images.docx" }+ txt <- T.readFile "docx/inline_formatting.native"+ bs <- runIOorExplode $ do+ mblang <- toLang (Just (Text.pack "en-US") :: Maybe Text)+ maybe (return ()) setTranslations mblang+ setVerbosity ERROR+ readNative def txt >>= writeDocx opts+ let archive = toArchive bs+ entry <- case findEntryByPath "[Content_Types].xml" archive of+ Nothing -> assertFailure "Missing [Content_Types].xml in output docx"+ Just e -> return e+ doc <- case parseXMLDoc (fromEntry entry) of+ Nothing -> assertFailure "Failed to parse [Content_Types].xml"+ Just d -> return d+ let partNameAttr = QName "PartName" Nothing Nothing+ let overrideName = QName "Override" Nothing Nothing+ let overrides = findElements overrideName doc+ let hasBadOverride =+ any (\el -> findAttr partNameAttr el == Just "/word/media/")+ overrides+ assertBool "Found invalid /word/media/ Override in [Content_Types].xml"+ (not hasBadOverride)+ , testCase "language from reference docx is preserved" $ do+ -- First, verify that the german-reference.docx actually has de-DE+ refBs <- BL.readFile "docx/german-reference.docx"+ let refArchive = toArchive refBs+ refEntry <- case findEntryByPath "word/styles.xml" refArchive of+ Nothing -> assertFailure "Missing word/styles.xml in german-reference.docx"+ Just e -> return e+ let refStylesXml = show (fromEntry refEntry)+ let getLangLines = filter ("w:lang" `isInfixOf`) . lines+ assertBool ("german-reference.docx w:lang line: " +++ unlines (getLangLines refStylesXml))+ (any ("de-DE" `isInfixOf`) (getLangLines refStylesXml))+ -- Now test that using this reference preserves the language+ let opts = def{ writerReferenceDoc = Just "docx/german-reference.docx" }+ txt <- T.readFile "docx/inline_formatting.native"+ bs <- runIOorExplode $ do+ setVerbosity ERROR+ readNative def txt >>= writeDocx opts+ let archive = toArchive bs+ entry <- case findEntryByPath "word/styles.xml" archive of+ Nothing -> assertFailure "Missing word/styles.xml in output docx"+ Just e -> return e+ let stylesXml = show (fromEntry entry)+ -- Find the w:lang line for debugging+ -- Check that the styles.xml contains the German language+ assertBool ("Language from reference docx not preserved. w:lang lines: " ++ unlines (getLangLines stylesXml))+ (any ("de-DE" `isInfixOf`) (getLangLines stylesXml))+ , testCase "language from metadata overrides reference docx" $ do+ -- Use a reference docx with German language, but specify French in metadata+ let opts = def{ writerReferenceDoc = Just "docx/german-reference.docx" }+ bs <- runIOorExplode $ do+ setVerbosity ERROR+ -- Create a document with French language metadata+ let doc = Pandoc (Meta $ M.fromList [("lang", MetaString "fr-FR")])+ [Para [Str "Test"]]+ writeDocx opts doc+ let archive = toArchive bs+ entry <- case findEntryByPath "word/styles.xml" archive of+ Nothing -> assertFailure "Missing word/styles.xml in output docx"+ Just e -> return e+ let stylesXml = show (fromEntry entry)+ -- Check that the styles.xml contains the French language (not German)+ let getLangLines = filter ("w:lang" `isInfixOf`) . lines+ assertBool "Language from metadata did not override reference docx (expected fr-FR)"+ (any ("fr-FR" `isInfixOf`) (getLangLines stylesXml))+ ]+ , testGroup "paragraph styles"+ [ testCase "FirstParagraph after heading with footnote (#11573)" $ do+ let opts = def+ bs <- runIOorExplode $ do+ setVerbosity ERROR+ let doc = Pandoc mempty+ [ Header 3 ("heading-with-note", [], [])+ [Note [Para [Str "note"]], Str "Heading"]+ , Para [Str "Para", Space, Str "after."]+ ]+ writeDocx opts doc+ let archive = toArchive bs+ entry <- case findEntryByPath "word/document.xml" archive of+ Nothing -> assertFailure "Missing word/document.xml in output docx"+ Just e -> return e+ let docXml = show (fromEntry entry)+ assertBool+ ("Expected FirstParagraph style after heading with footnote, got: "+ ++ docXml)+ ("FirstParagraph" `isInfixOf` docXml) ] ]
test/Tests/Writers/HTML.hs view
@@ -102,13 +102,13 @@ , testGroup "sample with style" [ "samp should wrap highlighted code" =: codeWith ("",["sample","haskell"],[]) ">>="- =?> ("<samp><code class=\"sourceCode haskell\">" +++ =?> ("<samp><code class=\"sourceCode haskell sample\">" ++ "<span class=\"op\">>>=</span></code></samp>") ] , testGroup "variable with style" [ "var should wrap highlighted code" =: codeWith ("",["haskell","variable"],[]) ">>="- =?> ("<var><code class=\"sourceCode haskell\">" +++ =?> ("<var><code class=\"sourceCode haskell variable\">" ++ "<span class=\"op\">>>=</span></code></var>") ] , testGroup "footnotes"
test/Tests/Writers/Powerpoint.hs view
@@ -126,6 +126,10 @@ def "pptx/speaker-notes-after-metadata/input.native" "pptx/speaker-notes-after-metadata/output.pptx"+ , pptxTests "speaker notes from metadata field"+ def+ "pptx/metadata-speaker-notes/input.native"+ "pptx/metadata-speaker-notes/output.pptx" , pptxTests "remove empty slides" def "pptx/remove-empty-slides/input.native"
test/command/10271.md view
@@ -16,7 +16,7 @@ % pandoc -f markdown-smart -t typst+smart "don't do it---" ^D-\"don\'t do it---\"+\"don\'t do it-\-\-\" ``` ```
+ test/command/10643.md view
@@ -0,0 +1,11 @@+```+% pandoc -f html -t native+<p>A<style></style>B</p>+^D+[ Para+ [ Str "A"+ , RawInline (Format "html") "<style></style>"+ , Str "B"+ ]+]+```
test/command/10791.md view
@@ -5,10 +5,11 @@ [^1]: **Heart of the Ocean** (海洋之心) – The Heart of the Ocean ^D <text:p text:style-name="Text_20_body">Aboard-<text:span text:style-name="T1">the luxury cruise ship Heart of the-Ocean</text:span><text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote"><text:span text:style-name="T1">Heart+<text:span text:style-name="Strong_20_Emphasis">the luxury cruise ship+Heart of the+Ocean</text:span><text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote"><text:span text:style-name="Strong_20_Emphasis">Heart of the Ocean</text:span> (海洋之心) – The Heart of the-Ocean</text:p></text:note-body></text:note><text:span text:style-name="T1">+Ocean</text:p></text:note-body></text:note><text:span text:style-name="Strong_20_Emphasis"> in the Atlantic Ocean</text:span>…</text:p> ```
+ test/command/10942.md view
@@ -0,0 +1,97 @@+Ungrouped field instruction:+```+% pandoc -f rtf -t native+{\rtf1\ansi\deff0+{\fonttbl{\f0\froman Times New Roman;}}+{\colortbl;\red0\green0\blue0;}+\deftab720++\trowd\trleft0\cellx2000\cellx4000+\pard\intbl+{{\field{\*\fldinst HYPERLINK "https://example.com" }{\fldrslt {\hich\af0\loch\hich\af0\loch\cf0\f0\cf0\f0\loch+{\*\bkmkstart _dx_frag_StartFragment}{\*\bkmkend _dx_frag_StartFragment}Problem Text}}}}\cell+\pard\intbl Normal Text\cell+\row++\trowd\trleft0\cellx2000\cellx4000+\pard\intbl Simple Text\cell+\pard\intbl More Text\cell+\row+}+^D+[ Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ ]+ (TableHead ( "" , [] , [] ) [])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para+ [ Link+ ( "" , [] , [] )+ [ Str "Problem" , Space , Str "Text" ]+ ( "https://example.com" , "" )+ ]+ ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "Normal" , Space , Str "Text" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "Simple" , Space , Str "Text" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "More" , Space , Str "Text" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+]+```++Additionally, ungrouped field result:+```+% pandoc -f rtf -t native+{\rtf1\ansi\ansicpg1252\cocoartf2867+\cocoatextscaling0\cocoaplatform1{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}+{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;}+\paperw11905\paperh16837\margl1133\margr1133\margb1133\margt1133+\deftab720+\pard\pardeftab720\partightenfactor0+{\field{\*\fldinst{HYPERLINK "https://example.com"}}{\fldrslt +\f0\fs22 \cf2 \up0 \nosupersub \ul \ulc2 link}}}+^D+[ Para+ [ Underline+ [ Link+ ( "" , [] , [] )+ [ Str "link" ]+ ( "https://example.com" , "" )+ ]+ ]+]+```
test/command/10965.md view
@@ -5,7 +5,8 @@ ::: ^D #block[-#set text(lang: "en"); This text should be in English.+#set text(lang: "en");+This text should be in English. ] ```@@ -17,7 +18,8 @@ ::: ^D #block[-#set text(lang: "fr"); Ce texte devrait être en français.+#set text(lang: "fr");+Ce texte devrait être en français. ] ```@@ -29,7 +31,8 @@ ::: ^D #block[-#set text(lang: "de"); Dieser Text sollte auf Deutsch sein.+#set text(lang: "de");+Dieser Text sollte auf Deutsch sein. ] ```
+ test/command/11299.md view
@@ -0,0 +1,28 @@+```+% pandoc -f mediawiki -t native+<foo>++<samp>x</samp>++<kbd>x</kbd>++<var>x</var>++<mark>This is ''highlighted''</mark>+^D+[ Para [ Str "<foo>" ]+, Para [ Code ( "" , [ "sample" ] , [] ) "x" ]+, Para [ Span ( "" , [ "kbd" ] , [] ) [ Str "x" ] ]+, Para [ Code ( "" , [ "variable" ] , [] ) "x" ]+, Para+ [ Span+ ( "" , [ "mark" ] , [] )+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Emph [ Str "highlighted" ]+ ]+ ]+]+```
+ test/command/11300.md view
@@ -0,0 +1,67 @@+```+% pandoc -f docbook -t native -s+<?xml version="1.0"?>+<book xmlns="http://docbook.org/ns/docbook" version="5.0" dir="ltr">+ <info>+ <title>Book title</title>+ <subtitle>Book subtitle</subtitle>+ </info>+ <chapter>+ <info>+ <title>Chapter title</title>+ </info>+ <para>My sentence</para>+ </chapter>+</book>+^D+Pandoc+ Meta+ { unMeta =+ fromList+ [ ( "subtitle"+ , MetaInlines [ Str "Book" , Space , Str "subtitle" ]+ )+ , ( "title"+ , MetaInlines [ Str "Book" , Space , Str "title" ]+ )+ ]+ }+ [ Header+ 1 ( "" , [] , [] ) [ Str "Chapter" , Space , Str "title" ]+ , Para [ Str "My" , Space , Str "sentence" ]+ ]+```++```+% pandoc -f docbook -t native -s+<?xml version="1.0"?>+<book xmlns="http://docbook.org/ns/docbook" version="5.0" dir="ltr">+ <chapter>+ <info>+ <title>Chapter title</title>+ </info>+ <para>My sentence</para>+ </chapter>+ <info>+ <title>Book title</title>+ <subtitle>Book subtitle</subtitle>+ </info>+</book>+^D+Pandoc+ Meta+ { unMeta =+ fromList+ [ ( "subtitle"+ , MetaInlines [ Str "Book" , Space , Str "subtitle" ]+ )+ , ( "title"+ , MetaInlines [ Str "Book" , Space , Str "title" ]+ )+ ]+ }+ [ Header+ 1 ( "" , [] , [] ) [ Str "Chapter" , Space , Str "title" ]+ , Para [ Str "My" , Space , Str "sentence" ]+ ]+```
+ test/command/11312.md view
@@ -0,0 +1,21 @@+```+% pandoc -f mediawiki -t texinfo+foofoo++ bar+ baz++foofoo+^D+@node Top+@top Top++foofoo++@example+bar+baz+@end example++foofoo+```
+ test/command/11323.md view
@@ -0,0 +1,12 @@+```+% pandoc -f rst+foo-+ bar+^D+<dl>+<dt>foo-</dt>+<dd>+<p>bar</p>+</dd>+</dl>+```
+ test/command/11341.md view
@@ -0,0 +1,9 @@+```+% pandoc -t commonmark -f html+<h1>The Hobbit<br>or<br>There and Back Again</h1>+^D+The Hobbit\+or\+There and Back Again+====================+```
+ test/command/11342.md view
@@ -0,0 +1,33 @@+Subfigures should be converted to *fig-group* elements.++```+% pandoc -f latex -t jats+\begin{figure}[H]+ \begin{subfigure}+ \centering+ \includegraphics[height=1.5in]{assets/A.png}+ \caption{Graph for function *A*.}+ \label{fig:A}+ \end{subfigure}+ \begin{subfigure}+ \centering+ \includegraphics[height=1.5in]{assets/B.png}+ \caption{Graph for function *B*.}+ \label{fig:B}+ \end{subfigure}+ \label{fig:graphs}+ \caption{Function graphs.}+\end{figure}+^D+<fig-group id="figU003Agraphs">+ <caption><p>Function graphs.</p></caption>+ <fig id="figU003AA">+ <caption><p>Graph for function *A*.</p></caption>+ <graphic mimetype="image" mime-subtype="png" xlink:href="assets/A.png" />+ </fig>+ <fig id="figU003AB">+ <caption><p>Graph for function *B*.</p></caption>+ <graphic mimetype="image" mime-subtype="png" xlink:href="assets/B.png" />+ </fig>+</fig-group>+```
+ test/command/11348.md view
@@ -0,0 +1,61 @@+```+% pandoc -f markdown -t native+$ invalid opening inline math$++$+invalid opening inline math$++$invalid closing inline math $++$invalid closing inline math+$++$valid inline math$+^D+[ Para+ [ Str "$"+ , Space+ , Str "invalid"+ , Space+ , Str "opening"+ , Space+ , Str "inline"+ , Space+ , Str "math$"+ ]+, Para+ [ Str "$"+ , SoftBreak+ , Str "invalid"+ , Space+ , Str "opening"+ , Space+ , Str "inline"+ , Space+ , Str "math$"+ ]+, Para+ [ Str "$invalid"+ , Space+ , Str "closing"+ , Space+ , Str "inline"+ , Space+ , Str "math"+ , Space+ , Str "$"+ ]+, Para+ [ Str "$invalid"+ , Space+ , Str "closing"+ , Space+ , Str "inline"+ , Space+ , Str "math"+ , SoftBreak+ , Str "$"+ ]+, Para [ Math InlineMath "valid inline math" ]+]+```
+ test/command/11362.md view
@@ -0,0 +1,17 @@+```+% pandoc -f markdown -t asciidoc+This is a _test_[^1].++And yet another **one**[^1].++We can also try to write #hashtags [this]{.test}.++[^1]: Test footnote.+^D+This is a __test__footnote:[Test footnote.].++And yet another **one**footnote:[Test footnote.].++We can also try to write ++#++hashtags [.test]#this#.++```
+ test/command/11364.md view
@@ -0,0 +1,75 @@+```+% pandoc -f rtf -t native+{\rtf1\ansi\deff3\adeflang1025+{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fnil\fprq0\fcharset2 OpenSymbol{\*\falt Arial Unicode MS};}{\f5\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f6\fnil\fprq2\fcharset0 Noto Sans CJK SC;}{\f7\fnil\fprq2\fcharset0 Matangi Light;}{\f8\fnil\fprq0\fcharset128 Matangi Light;}{\f9\fnil\fprq0\fcharset128 OpenSymbol{\*\falt Arial Unicode MS};}}+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}+{\stylesheet{\s0\snext0\widctlpar\hyphpar0\ltrpar\kerning1\cf0\rtlch\af7\afs24\alang1081\ltrch\hich\af3\afs24\alang1033\dbch\af10\langfe2052\loch\f3\fs24\lang1033 Normal;}+{\*\cs15\snext15\rtlch\af4\ltrch\hich\af4\dbch\af4\loch\f4 Bullets;}+{\s16\sbasedon0\snext17\sb240\sa120\keepn\rtlch\af7\afs28\ltrch\hich\af5\afs28\dbch\af6\loch\f5\fs28 Heading;}+{\s17\sbasedon0\snext17\sl276\slmult1\sb0\sa140 Body Text;}+{\s18\sbasedon17\snext18\rtlch\af8\ltrch List;}+{\s19\sbasedon0\snext19\sb120\sa120\noline\rtlch\af8\afs24\ai\ltrch\fs24\i caption;}+{\s20\sbasedon0\snext20\noline\rtlch\af8\ltrch Index;}+{\s21\sbasedon0\snext21\nowidctlpar\noline Table Contents;}+}{\*\listtable{\list\listtemplateid1+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li720}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9702 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li1080}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9642 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li1440}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li1800}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9702 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li2160}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9642 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li2520}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li2880}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9702 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li3240}+{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow0{\leveltext \'01\u9642 ?;}{\levelnumbers;}\f9\rtlch\af4\ltrch\fi-360\li3600}\listid1}+{\list\listtemplateid2+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}+{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid2}+}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}{\*\generator LibreOffice/25.8.4.2$Linux_X86_64 LibreOffice_project/580$Build-2}{\info{\creatim\yr2025\mo12\dy28\hr10\min51}{\revtim\yr2025\mo12\dy28\hr10\min53}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab709+\hyphauto1\viewscale140\formshade\nobrkwrptbl\paperh15840\paperw12240\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sftnnar\saftnnrlc\sectunlocked1\pgwsxn12240\pghsxn15840\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\fet\aftnrstcont\aftnstart1\aftnnrlc+{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\widctlpar\hyphpar0\ltrpar\kerning1\cf0\rtlch\af7\afs24\alang1081\ltrch\hich\af3\afs24\alang1033\dbch\af10\langfe2052\loch\f3\fs24\lang1033{\listtext\pard\plain \rtlch\af4\ltrch\hich\af4\dbch\af4\loch\f4 \u8226\'95\tab}\ilvl0\ls1 \fi-360\li720\lin720\ql\ltrpar{+List item}+\par \trowd\trql\ltrrow\trpaddft3\trpaddt0\trpaddfl3\trpaddl0\trpaddfb3\trpaddb0\trpaddfr3\trpaddr0\clbrdrt\brdrs\brdrw10\brdrcf1\clpadfl3\clpadl55\clbrdrl\brdrs\brdrw10\brdrcf1\clpadft3\clpadt55\clbrdrb\brdrs\brdrw10\brdrcf1\clpadfb3\clpadb55\clpadfr3\clpadr55\cellx4986\clbrdrt\brdrs\brdrw10\brdrcf1\clpadfl3\clpadl55\clbrdrl\brdrs\brdrw10\brdrcf1\clpadft3\clpadt55\clbrdrb\brdrs\brdrw10\brdrcf1\clpadfb3\clpadb55\clbrdrr\brdrs\brdrw10\brdrcf1\clpadfr3\clpadr55\cellx9972\pard\plain \s21\nowidctlpar\noline\intbl\ql\ltrpar{+A}\cell\pard\plain \s21\nowidctlpar\noline\intbl\ql\ltrpar{+B}\cell\row\pard \pard\plain \s0\widctlpar\hyphpar0\ltrpar\kerning1\cf0\rtlch\af7\afs24\alang1081\ltrch\hich\af3\afs24\alang1033\dbch\af10\langfe2052\loch\f3\fs24\lang1033\ql\ltrpar+\par }+^D+[ BulletList+ [ [ Para [ Str "List" , Space , Str "item" ] ] ]+, Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ ]+ (TableHead ( "" , [] , [] ) [])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "A" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "B" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+]+```
+ test/command/11374.md view
@@ -0,0 +1,6 @@+```+% pandoc -f native -t asciidoc+[ Para [ SmallCaps [ Str "foo" ] ] ]+^D+[smallcaps]#foo#+```
+ test/command/11384.md view
@@ -0,0 +1,17 @@+```+% pandoc -t markdown -f native+[ Para [ Math DisplayMath "\ne = mc^2\n" ] ]+^D+$$+e = mc^2+$$+```++But we need to collapse spaces around inline math:++```+% pandoc -t markdown -f native+[ Para [ Math InlineMath "\ne=mc\n" ]]+^D+$e=mc$+```
+ test/command/11409.md view
@@ -0,0 +1,11 @@+```+% pandoc -t native+text^[sup]{.class}^+^D+[ Para+ [ Str "text"+ , Superscript+ [ Span ( "" , [ "class" ] , [] ) [ Str "sup" ] ]+ ]+]+```
+ test/command/11420.md view
@@ -0,0 +1,15 @@+````+% pandoc -t revealjs --syntax-highlighting=idiomatic+# Slide++```python+def hello():+ print("Hello")+```+^D+<section id="slide" class="slide level1">+<h1>Slide</h1>+<pre><code class="language-python">def hello():+ print("Hello")</code></pre>+</section>+````
+ test/command/11422.md view
@@ -0,0 +1,12 @@+```+% pandoc -f docbook -t markdown+<example>+ <para>+ Example without a title.+ </para>+</example>+^D+::: example+Example without a title.+:::+```
+ test/command/11450.md view
@@ -0,0 +1,62 @@+Test for \footnotemark and \footnotetext (issue #11450)++```+% pandoc -f latex -t native+Text\footnotemark{}.+\footnotetext{The footnote content.}+^D+[ Para+ [ Str "Text"+ , Note+ [ Para+ [ Str "The"+ , Space+ , Str "footnote"+ , Space+ , Str "content."+ ]+ ]+ , Str "."+ ]+]+```++With explicit footnote numbers:++```+% pandoc -f latex -t native+First\footnotemark[1] and second\footnotemark[2].+\footnotetext[1]{First note.}+\footnotetext[2]{Second note.}+^D+[ Para+ [ Str "First"+ , Note [ Para [ Str "First" , Space , Str "note." ] ]+ , Space+ , Str "and"+ , Space+ , Str "second"+ , Note [ Para [ Str "Second" , Space , Str "note." ] ]+ , Str "."+ ]+]+```++Mixed with regular footnotes:++```+% pandoc -f latex -t native+Text\footnotemark[1] and more\footnote{Regular footnote.}+\footnotetext[1]{Marked footnote.}+^D+[ Para+ [ Str "Text"+ , Note [ Para [ Str "Marked" , Space , Str "footnote." ] ]+ , Space+ , Str "and"+ , Space+ , Str "more"+ , Note [ Para [ Str "Regular" , Space , Str "footnote." ] ]+ ]+]+```
+ test/command/11455.md view
@@ -0,0 +1,26 @@+```+% pandoc -f textile -t html+| foo | bar |+| table+* item 1+* item 2+* item 3 | xxx |+^D+<table>+<tbody>+<tr>+<td>foo</td>+<td>bar</td>+</tr>+<tr>+<td><p>table</p>+<ul>+<li>item 1</li>+<li>item 2</li>+<li>item 3</li>+</ul></td>+<td>xxx</td>+</tr>+</tbody>+</table>+```
+ test/command/11463.md view
@@ -0,0 +1,13 @@+```+% pandoc -t typst+'hi' and \'+^D+'hi' and \'+```++```+% pandoc -f markdown -t typst | pandoc -f typst -t markdown+"hi" \" 'hi' and \'+^D+"hi" \" 'hi' and \'+```
+ test/command/11479.md view
@@ -0,0 +1,31 @@+```+% pandoc -f docbook -t gfm+<important>+<itemizedlist>+<listitem>+<simpara>Test.</simpara>+</listitem>+<listitem>+<simpara>Test 2.</simpara>+</listitem>+</itemizedlist>+</important>+^D+> [!IMPORTANT]+> - Test.+>+> - Test 2.+```++```+% pandoc -f gfm -t gfm+> [!IMPORTANT]+> - Test.+>+> - Test 2.+^D+> [!IMPORTANT]+> - Test.+>+> - Test 2.+```
+ test/command/11486.md view
@@ -0,0 +1,82 @@+```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+---+^D+ scrollActivationWidth: 0,+ scrollSnap: 'mandatory',+ scrollProgress: 'auto',+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollSnap: false+---+^D+ scrollActivationWidth: 0,+ scrollSnap: false,+ scrollProgress: 'auto',+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollSnap: proximity+---+^D+ scrollActivationWidth: 0,+ scrollSnap: 'proximity',+ scrollProgress: 'auto',+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollActivationWidth: 500+---+^D+ scrollActivationWidth: 500,+ scrollSnap: 'mandatory',+ scrollProgress: 'auto',+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollProgress: true+---+^D+ scrollActivationWidth: 0,+ scrollSnap: 'mandatory',+ scrollProgress: true,+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollProgress: false+---+^D+ scrollActivationWidth: 0,+ scrollSnap: 'mandatory',+ scrollProgress: false,+```++```+% pandoc -t revealjs --template=command/11486/scroll.revealjs+---+view: scroll+scrollProgress: auto+---+^D+ scrollActivationWidth: 0,+ scrollSnap: 'mandatory',+ scrollProgress: 'auto',+```
+ test/command/11486/scroll.revealjs view
@@ -0,0 +1,15 @@+$if(view)$+ scrollActivationWidth: $scrollActivationWidth$,+$if(scrollSnap)$+ scrollSnap: '$scrollSnap/nowrap$',+$else$+ scrollSnap: false,+$endif$+$if(scrollProgressAuto)$+ scrollProgress: 'auto',+$elseif(scrollProgress)$+ scrollProgress: $scrollProgress$,+$else$+ scrollProgress: false,+$endif$+$endif$
+ test/command/11490.md view
@@ -0,0 +1,13 @@+```+% pandoc -t markdown+<&lt;+^D+\<\<+```++```+% pandoc -t markdown+&#xa0;+^D+\ +```
+ test/command/11494.md view
@@ -0,0 +1,73 @@+External images should not use [[File:...]] syntax.++Inline external image:+```+% pandoc -f native -t mediawiki+[Para [Image ("",[],[]) [] ("https://example.org/image.png", "")]]+^D+<nowiki></nowiki>https://example.org/image.png<nowiki></nowiki>+```++Inline local image (should still use [[File:]]):+```+% pandoc -f native -t mediawiki+[Para [Image ("",[],[]) [] ("local.png", "")]]+^D+[[File:local.png]]+```++Figure with external image (from markdown):+```+% pandoc -f markdown -t mediawiki++^D+<nowiki></nowiki>https://example.org/figure.png<nowiki></nowiki>+```++Local image (from markdown, no caption):+```+% pandoc -f markdown -t mediawiki++^D+[[File:local.png]]+```++Figure with caption and external image:+```+% pandoc -f markdown -t mediawiki++^D+<div class="figure">+<nowiki></nowiki>https://example.org/figure.png<nowiki></nowiki>+</div>+```++Figure with caption and local image:+```+% pandoc -f markdown -t mediawiki++^D+<div class="figure">+[[File:local.png|Caption]]+</div>+```++SimpleFigure with external image (native format with fig: title):+```+% pandoc -f native -t mediawiki+[Figure ("",[],[]) (Caption Nothing []) [Para [Image ("",[],[]) [Str "caption"] ("https://example.org/figure.png", "fig:")]]]+^D+<div class="figure">+<nowiki></nowiki>https://example.org/figure.png<nowiki></nowiki>+</div>+```++SimpleFigure with local image (native format with fig: title):+```+% pandoc -f native -t mediawiki+[Figure ("",[],[]) (Caption Nothing []) [Para [Image ("",[],[]) [Str "caption"] ("local.png", "fig:")]]]+^D+<div class="figure">+[[File:local.png|thumb|none|alt=caption|caption]]+</div>+```
+ test/command/11498.md view
@@ -0,0 +1,121 @@+```+% pandoc -f markdown -t icml+{object-style="myStyle"}+^D+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/Paragraph">+ <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">+ <Rectangle Self="uec" StrokeWeight="0" ItemTransform="1 0 0 1 32 -32" AppliedObjectStyle="ObjectStyle/myStyle">+ <Properties>+ <PathGeometry>+ <GeometryPathType PathOpen="false">+ <PathPointArray>+ <PathPointType Anchor="-32 -32" LeftDirection="-32 -32" RightDirection="-32 -32" />+ <PathPointType Anchor="-32 32" LeftDirection="-32 32" RightDirection="-32 32" />+ <PathPointType Anchor="32 32" LeftDirection="32 32" RightDirection="32 32" />+ <PathPointType Anchor="32 -32" LeftDirection="32 -32" RightDirection="32 -32" />+ </PathPointArray>+ </GeometryPathType>+ </PathGeometry>+ </Properties>+ <Image Self="ue6" ItemTransform="1 0 0 1 -32 -32">+ <Properties>+ <Profile type="string">+ $ID/Embedded+ </Profile>+ <GraphicBounds Left="0" Top="0" Right="64" Bottom="64" />+ </Properties>+ <Link Self="ueb" LinkResourceURI="file:command/11498.png" />+ </Image>+ </Rectangle>+ </CharacterStyleRange>+</ParagraphStyleRange>+```+```+% pandoc -s -f markdown -t icml+{object-style="myStyle"}+^D+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>+<?aid style="50" type="snippet" readerVersion="6.0" featureSet="513" product="8.0(370)" ?>+<?aid SnippetType="InCopyInterchange"?>+<Document DOMVersion="8.0" Self="pandoc_doc">+ <RootCharacterStyleGroup Self="pandoc_character_styles">+ <CharacterStyle Self="$ID/NormalCharacterStyle" Name="Default" />+ <CharacterStyle Self="CharacterStyle/" Name="">+ <Properties>+ <BasedOn type="object">$ID/NormalCharacterStyle</BasedOn>+ </Properties>+ </CharacterStyle>+ </RootCharacterStyleGroup>+ <RootParagraphStyleGroup Self="pandoc_paragraph_styles">+ <ParagraphStyle Self="$ID/NormalParagraphStyle" Name="$ID/NormalParagraphStyle"+ SpaceBefore="6" SpaceAfter="6"> <!-- paragraph spacing -->+ <Properties>+ <TabList type="list">+ <ListItem type="record">+ <Alignment type="enumeration">LeftAlign</Alignment>+ <AlignmentCharacter type="string">.</AlignmentCharacter>+ <Leader type="string"></Leader>+ <Position type="unit">10</Position> <!-- first tab stop -->+ </ListItem>+ </TabList>+ </Properties>+ </ParagraphStyle>+ <ParagraphStyle Self="ParagraphStyle/Paragraph" Name="Paragraph" LeftIndent="0">+ <Properties>+ <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn>+ </Properties>+ </ParagraphStyle>+ </RootParagraphStyleGroup>+ <RootTableStyleGroup Self="pandoc_table_styles">+ <TableStyle Self="TableStyle/Table" Name="Table" />+ </RootTableStyleGroup>+ <RootCellStyleGroup Self="pandoc_cell_styles">+ <CellStyle Self="CellStyle/Cell" AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]" Name="Cell" />+ </RootCellStyleGroup>+ <RootObjectStyleGroup Self="pandoc_object_styles">+ <ObjectStyle Self="ObjectStyle/myStyle" Name="myStyle">+ <Properties>+ <BasedOn type="string">$ID/None</BasedOn>+ </Properties>+ </ObjectStyle>+ </RootObjectStyleGroup>+ <Story Self="pandoc_story"+ TrackChanges="false"+ StoryTitle=""+ AppliedTOCStyle="n"+ AppliedNamedGrid="n" >+ <StoryPreference OpticalMarginAlignment="true" OpticalMarginSize="12" />++<!-- body needs to be non-indented, otherwise code blocks are indented too far -->+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/Paragraph">+ <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">+ <Rectangle Self="uec" StrokeWeight="0" ItemTransform="1 0 0 1 32 -32" AppliedObjectStyle="ObjectStyle/myStyle">+ <Properties>+ <PathGeometry>+ <GeometryPathType PathOpen="false">+ <PathPointArray>+ <PathPointType Anchor="-32 -32" LeftDirection="-32 -32" RightDirection="-32 -32" />+ <PathPointType Anchor="-32 32" LeftDirection="-32 32" RightDirection="-32 32" />+ <PathPointType Anchor="32 32" LeftDirection="32 32" RightDirection="32 32" />+ <PathPointType Anchor="32 -32" LeftDirection="32 -32" RightDirection="32 -32" />+ </PathPointArray>+ </GeometryPathType>+ </PathGeometry>+ </Properties>+ <Image Self="ue6" ItemTransform="1 0 0 1 -32 -32">+ <Properties>+ <Profile type="string">+ $ID/Embedded+ </Profile>+ <GraphicBounds Left="0" Top="0" Right="64" Bottom="64" />+ </Properties>+ <Link Self="ueb" LinkResourceURI="file:command/11498.png" />+ </Image>+ </Rectangle>+ </CharacterStyleRange>+</ParagraphStyleRange>++ </Story>+ +</Document>+```
+ test/command/11498.png view
binary file changed (absent → 1306 bytes)
+ test/command/11511.md view
@@ -0,0 +1,6 @@+```+% pandoc -f html -t typst+<p><a href="http://torch.utils.data" rel="noopener noreferrer nofollow" target="_blank">torch.utils.data</a>.Dataset</p>+^D+#link("http://torch.utils.data")[torch.utils.data]\.Dataset+```
+ test/command/11534.md view
@@ -0,0 +1,42 @@+```+% pandoc -f markdown+lists_without_preceding_blankline+alerts -t native+:::: caution+::: title+Caution+:::++Foo bar, wuppie fluppie!+::::+^D+[ Div+ ( "" , [ "caution" ] , [] )+ [ Div ( "" , [ "title" ] , [] ) [ Para [ Str "Caution" ] ]+ , Para+ [ Str "Foo"+ , Space+ , Str "bar,"+ , Space+ , Str "wuppie"+ , Space+ , Str "fluppie!"+ ]+ ]+]+```++```+% pandoc -f markdown+lists_without_preceding_blankline -t native+hello+- a+- b+c+^D+[ Para [ Str "hello" ]+, BulletList+ [ [ Plain [ Str "a" ] ]+ , [ Plain [ Str "b" , SoftBreak , Str "c" ] ]+ ]+]++```+
+ test/command/11542.md view
@@ -0,0 +1,47 @@+```+% pandoc -f native -t markdown+[ DefinitionList+ [ ( [ Str "Input" ]+ , [ [ CodeBlock ( "" , [] , [] ) "Term\n\n : Def" ] ]+ )+ ]+]+^D+Input++: Term++ : Def+```++```+% pandoc -f markdown -t native+Input++: Term++ : Def+^D+[ DefinitionList+ [ ( [ Str "Input" ]+ , [ [ CodeBlock ( "" , [] , [] ) "Term\n\n : Def" ] ]+ )+ ]+]+```++```+% pandoc -f native -t markdown+four_space_rule+[ DefinitionList+ [ ( [ Str "Input" ]+ , [ [ CodeBlock ( "" , [] , [] ) "Term\n\n : Def" ] ]+ )+ ]+]+^D+Input++: Term++ : Def+```
+ test/command/11562.md view
@@ -0,0 +1,10 @@+```+% pandoc -t mediawiki+[example](https://example.com/#/#room)++[example](https://example.com/##)+^D+[https://example.com/#/#room example]++[https://example.com/## example]+```
+ test/command/11571.md view
@@ -0,0 +1,18 @@+```+% pandoc -t markdown+:::+A+:::+^D+\::: A \:::+```++```+% pandoc -t commonmark+fenced_divs+:::+A+:::+^D+\::: A \:::+```+
+ test/command/11583.md view
@@ -0,0 +1,16 @@+```+% pandoc -t typst+::: {lang=en}+1. item+2. item+3. item+:::+^D+#block[+#set text(lang: "en");++ item++ item++ item++]+```
+ test/command/11588.md view
@@ -0,0 +1,10 @@+```+% pandoc --typst-input foo=FOO --typst-input bar="bar bim" -f typst -t plain+#sys.inputs.at("foo");++#sys.inputs.at("bar");+^D+FOO++bar bim+```
+ test/command/11589.md view
@@ -0,0 +1,20 @@+```+% pandoc -f markdown -t native+t^[a]{.cb}\ b^+t^[a]{fg=yellow bg=blue}\ b^+^D+[ Para+ [ Str "t"+ , Superscript+ [ Span ( "" , [ "cb" ] , [] ) [ Str "a" ] , Str "\160b" ]+ , SoftBreak+ , Str "t"+ , Superscript+ [ Span+ ( "" , [] , [ ( "fg" , "yellow" ) , ( "bg" , "blue" ) ] )+ [ Str "a" ]+ , Str "\160b"+ ]+ ]+]+```
+ test/command/11598.md view
@@ -0,0 +1,16 @@+```+% pandoc -f typst --wrap=none+#rotate(90deg, figure(+ [body text here inside rotate],+ caption: "Figure 1: How a caption gets lost when rotating",+ supplement: none,+))+^D+<div class="rotate" data-angle="90.0">+<figure>+<p>body text here inside rotate</p>+<figcaption><p>Figure 1: How a caption gets lost when rotating</p></figcaption>+</figure>+</div>++```
+ test/command/11604.md view
@@ -0,0 +1,22 @@+```+% pandoc -f latex -t typst+\begin{table}+ \caption{Caption}\label{tab}+ \begin{tabular}{cc}+ a & b \\ c & d+ \end{tabular}+\end{table}+^D+#figure(+ align(center)[#table(+ columns: 2,+ align: (center,center,),+ [a], [b],+ [c], [d],+ )]+ , caption: [Caption]+ , kind: table+ )+<tab>++```
+ test/command/11608.md view
@@ -0,0 +1,54 @@+```+% pandoc -f latex -t plain+\documentclass[english]{article}+\usepackage[T1]{fontenc}+\usepackage[utf8]{inputenc}+\usepackage{amsthm}+\theoremstyle{plain}+\newtheorem{thm}{\protect\theoremname}+\newtheorem{prop}[thm]{\protect\propositionname}+\usepackage{babel}+\providecommand{\propositionname}{Proposition}+\providecommand{\theoremname}{Theorem}++\begin{document}+\begin{thm}+first theorem+\end{thm}+\begin{prop}+first proposition+\end{prop}++\end{document}+<div class="thm">+<p><strong>Theorem 1</strong>. <em>first theorem</em></p>+</div>+<div class="prop">+<p><strong>Proposition 2</strong>. <em>first proposition</em></p>+</div>+jgm@Johns-MacBook-Air:~/src/pandoc % `make binpath` -f latex -t plain+\documentclass[english]{article}+\usepackage[T1]{fontenc}+\usepackage[utf8]{inputenc}+\usepackage{amsthm}+\theoremstyle{plain}+\newtheorem{thm}{\protect\theoremname}+\newtheorem{prop}[thm]{\protect\propositionname}+\usepackage{babel}+\providecommand{\propositionname}{Proposition}+\providecommand{\theoremname}{Theorem}++\begin{document}+\begin{thm}+first theorem+\end{thm}+\begin{prop}+first proposition+\end{prop}++\end{document}+^D+Theorem 1. first theorem++Proposition 2. first proposition+```
+ test/command/11635.md view
@@ -0,0 +1,28 @@+```+% pandoc -f man -t html+.TH "TEST" "1" "2026-05-08" "test v1.0.0" "test manual"+.SH HEADING+.TS+tab(;);+l l.+this is a table element \+written in two lines;abcdefg+another \+one;123456+.TE+^D+<h1 id="heading">HEADING</h1>+<table>+<tbody>+<tr>+<td style="text-align: left;">this is a table element written in two+lines</td>+<td style="text-align: left;">abcdefg</td>+</tr>+<tr>+<td style="text-align: left;">another one</td>+<td style="text-align: left;">123456</td>+</tr>+</tbody>+</table>+```
+ test/command/11664.md view
@@ -0,0 +1,35 @@+```+% pandoc -t markdown -f html+<table>+ <colgroup>+ <col width="1%"/>+ <col />+ </colgroup>+ <tbody>+ <tr>+ <td>+ <p>A</p><p>B</p>+ </td>+ <td>+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut+ enim ad minim veniam, quis nostrud exercitation ullamco laboris+ nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor+ in reprehenderit in voluptate velit esse cillum dolore eu fugiat+ nulla pariatur. Excepteur sint occaecat cupidatat non proident,+ sunt in culpa qui officia deserunt mollit anim id est laborum.+ </td>+ </tr>+ </tbody>+</table>+^D++---+------------------------------------------------------------------++| A | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do |+| | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut |+| B | enim ad minim veniam, quis nostrud exercitation ullamco laboris |+| | nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor |+| | in reprehenderit in voluptate velit esse cillum dolore eu fugiat |+| | nulla pariatur. Excepteur sint occaecat cupidatat non proident, |+| | sunt in culpa qui officia deserunt mollit anim id est laborum. |++---+------------------------------------------------------------------++```
+ test/command/11668.md view
@@ -0,0 +1,42 @@+```+% pandoc -f man -t html+TH "TEST" "1" "2026-05-25" "test v1.0.0" "test manual"+.SH HEADING+.TP 4+This is the unindented tag.+This text, along with the table, should be indented.+.TS+tab(;);+l l.+aaa;bbb+ccc;ddd+.TE+This should still be indented, until some other macro is called to change it.+.PP+Like this.+^D+<p>TH "TEST" "1" "2026-05-25" "test v1.0.0" "test manual"</p>+<h1 id="heading">HEADING</h1>+<dl>+<dt>This is the unindented tag.</dt>+<dd>+<p>This text, along with the table, should be indented.</p>+<table>+<tbody>+<tr>+<td style="text-align: left;">aaa</td>+<td style="text-align: left;">bbb</td>+</tr>+<tr>+<td style="text-align: left;">ccc</td>+<td style="text-align: left;">ddd</td>+</tr>+</tbody>+</table>+<p>This should still be indented, until some other macro is called to+change it.</p>+</dd>+</dl>+<p>Like this.</p>++```
+ test/command/11682.md view
@@ -0,0 +1,81 @@+Cell paragraphs that use `\plain` after `\intbl`, together with a single+`\trowd` and `\row` row terminators, should produce a flat table rather+than deeply nested tables.++```+% pandoc -f rtf -t native+{\rtf1\ansi\deff0+{\fonttbl{\f0 Times;}{\f1 Times;}{\f2 Times;}}+\trowd\trgaph60\trleft0+\clvertalt\cellx3245+\clvertalt\cellx6490+\clvertalt\cellx9735+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 A\plain\f1\fs22\cell+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 B\plain\f1\fs22\cell+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 C\plain\f1\fs22\cell+\intbl\row+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 1\plain\f1\fs22\cell+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 2\plain\f1\fs22\cell+\pard\intbl\s0\ql\plain\f0\fs20\plain\f2\fs22 3\plain\f1\fs22\cell+\intbl\row+}+^D+[ Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ ]+ (TableHead ( "" , [] , [] ) [])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "A" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "B" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "C" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "2" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Para [ Str "3" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+]+```
test/command/2434.md view
@@ -6,23 +6,23 @@ 2. beta * gamma ^D-<text:list text:style-name="L1">+<text:list text:style-name="Numbering_20_1"> <text:list-item>- <text:p text:style-name="P1">a</text:p>+ <text:p text:style-name="List_20_Number_20_Tight">a</text:p> </text:list-item> <text:list-item>- <text:p text:style-name="P1">b</text:p>- <text:list>+ <text:p text:style-name="List_20_Number_20_Tight">b</text:p>+ <text:list text:style-name="Numbering_20_1"> <text:list-item>- <text:p text:style-name="P1">alpha</text:p>+ <text:p text:style-name="List_20_Number_20_Tight">alpha</text:p> </text:list-item> <text:list-item>- <text:p text:style-name="P1">beta</text:p>+ <text:p text:style-name="List_20_Number_20_Tight">beta</text:p> </text:list-item> </text:list>- <text:list text:style-name="L2">+ <text:list text:style-name="List_20_1"> <text:list-item>- <text:p text:style-name="P2">gamma</text:p>+ <text:p text:style-name="List_20_Bullet_20_Tight">gamma</text:p> </text:list-item> </text:list> </text:list-item>@@ -40,20 +40,23 @@ more text -- this line is missing in the odt output ^D-<text:list text:style-name="L1">+<text:list text:style-name="Pandoc_5f_Numbering_5f_1"> <text:list-item>- <text:p text:style-name="P1">text</text:p>- <text:p text:style-name="P1">some text</text:p>- <text:list>+ <text:p text:style-name="List_20_Number">text</text:p>+ <text:p text:style-name="List_20_Number">some text</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_2"> <text:list-item>- <text:p text:style-name="P1">sub item 1</text:p>+ <text:p text:style-name="List_20_Number_20_Tight">sub item+ 1</text:p> </text:list-item> <text:list-item>- <text:p text:style-name="P1">sub item 2</text:p>+ <text:p text:style-name="List_20_Number_20_Tight">sub item+ 2</text:p> </text:list-item> </text:list>- <text:p text:style-name="P1">more text – this line is missing in the- odt output</text:p>+ <text:p text:style-name="List_20_Number">more text – this line is+ missing in the odt output</text:p> </text:list-item> </text:list> ```+
test/command/4186.md view
@@ -5,7 +5,7 @@ #+end_example ^D [ CodeBlock- ( "" , [ "example" ] , [] )+ ( "" , [] , [] ) " This should retain the four leading spaces\n" ] ```@@ -40,13 +40,13 @@ ^D <ul> <li><p>depth 1</p>-<pre id="bob" class="example"><code> Vertical alignment is four spaces beyond the appearance of the word "depth".+<pre id="bob"><code> Vertical alignment is four spaces beyond the appearance of the word "depth". </code></pre> <ul> <li><p>depth 2</p>-<pre class="example"><code>Vertically aligned with the second appearance of the word "depth".+<pre><code>Vertically aligned with the second appearance of the word "depth". </code></pre>-<pre class="example"><code> Vertical alignment is four spaces beyond the second+<pre><code> Vertical alignment is four spaces beyond the second appearance of the word "depth". The "begin" portion is a component of this deeper list element, so that guarantees@@ -55,7 +55,7 @@ </code></pre> <p>Still inside the inner list element</p></li> </ul>-<pre id="carrie" class="example"><code>This belongs to the outer list element, and is aligned accordingly, since the NAME attribute is not indented deeply enough. It is not enough for the BEGIN alone to be aligned deeply if the block is meant to have a NAME.+<pre id="carrie"><code>This belongs to the outer list element, and is aligned accordingly, since the NAME attribute is not indented deeply enough. It is not enough for the BEGIN alone to be aligned deeply if the block is meant to have a NAME. </code></pre> <p>Still in the shallower list element since the preceding example block forced the deeper list element to terminate.</p></li>
test/command/5543.md view
@@ -4,5 +4,5 @@ : description ^D 1\. item-: description+: description ```
test/command/5876.md view
@@ -48,13 +48,13 @@ % pandoc -s -t native --data-dir=command/5876 --metadata-file=does-not-exist.yaml Hello ^D-2> Could not find metadata file does-not-exist.yaml+2> Could not find metadata file 'does-not-exist.yaml' => 98 ``` ``` % pandoc -s -t native --metadata-file=does-not-exist.yaml Hello ^D-2> Could not find metadata file does-not-exist.yaml+2> Could not find metadata file 'does-not-exist.yaml' => 98 ```
test/command/6137.md view
@@ -38,79 +38,76 @@ , Space , Str "work." ]-, Div+, Table ( "tbl:label" , [] , [] )- [ Table+ (Caption+ Nothing+ [ Plain+ [ Str "This"+ , Space+ , Str "caption"+ , Space+ , Str "has"+ , Space+ , Str "no"+ , Space+ , Str "number."+ ]+ ])+ [ ( AlignLeft , ColWidthDefault )+ , ( AlignCenter , ColWidthDefault )+ , ( AlignRight , ColWidthDefault )+ ]+ (TableHead ( "" , [] , [] ) [])+ [ TableBody ( "" , [] , [] )- (Caption- Nothing- [ Plain- [ Str "This"- , Space- , Str "caption"- , Space- , Str "has"- , Space- , Str "no"- , Space- , Str "number."- ]- ])- [ ( AlignLeft , ColWidthDefault )- , ( AlignCenter , ColWidthDefault )- , ( AlignRight , ColWidthDefault )- ]- (TableHead ( "" , [] , [] ) [])- [ TableBody+ (RowHeadColumns 0)+ []+ [ Row ( "" , [] , [] )- (RowHeadColumns 0)- []- [ Row+ [ Cell ( "" , [] , [] )- [ Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- , Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- , Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- ]- , Row+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ]+ , Cell ( "" , [] , [] )- [ Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- , Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- , Cell- ( "" , [] , [] )- AlignDefault- (RowSpan 1)- (ColSpan 1)- [ Plain [ Str "\8212\8212\8211" ] ]- ]+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ] ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "\8212\8212\8211" ] ]+ ] ]- (TableFoot ( "" , [] , [] ) []) ]+ (TableFoot ( "" , [] , [] ) []) , Para [ Str "This" , Space
test/command/6719.md view
@@ -4,7 +4,7 @@ <emphasis>emphasized </emphasis>text </para> ^D-[ Para [ Emph [ Str "emphasized" ] , Space , Str "text" ] ]+[ Para [ Emph [ Str "emphasized" , Space ] , Str "text" ] ] ``` ```@@ -13,6 +13,6 @@ <italic> hi </italic>there </p> ^D-[ Para [ Emph [ Str "hi" ] , Space , Str "there" ] ]+[ Para [ Emph [ Space , Str "hi" , Space ] , Str "there" ] ] ```
test/command/6858.md view
@@ -27,13 +27,13 @@ \*FvwmAnimate: Color color -: Tells **FvwmAnimate** what color to draw with. The color is- \"XOR\'ed\" (exclusive ORed) onto the background.+: Tells **FvwmAnimate** what color to draw with. The color is+ \"XOR\'ed\" (exclusive ORed) onto the background. \*FvwmAnimate: Pixmap pixmap -: Tells **FvwmAnimate** to use **pixmap** to draw with. This can be- useful if **\*FvwmAnimate: Color** gives poor results.+: Tells **FvwmAnimate** to use **pixmap** to draw with. This can be+ useful if **\*FvwmAnimate: Color** gives poor results. ``` ```
+ test/command/7201.md view
@@ -0,0 +1,47 @@+```+% pandoc -t revealjs --slide-level=1+# Overview++:::::::::::::: {.columns}+::: {.column width="40%"}++Left column++:::+::: {.column width="60%"}++* First list+ * subitem++. . .++* Second list+ * subitem+:::+::::::::::::::+^D+<section id="overview" class="slide level1">+<h1>Overview</h1>+<div class="columns">+<div class="column" style="width:40%;">+<p>Left column</p>+</div><div class="column" style="width:60%;">+<ul>+<li>First list+<ul>+<li>subitem</li>+</ul></li>+</ul>+<div class="fragment">+<ul>+<li>Second list+<ul>+<li>subitem</li>+</ul></li>+</ul>+</div>+</div>+</div>+</section>++```
test/command/7521.md view
@@ -5,7 +5,7 @@ - two ^D <ul>-<li>one </li>+<li>one</li> <li>two</li> </ul> ```
+ test/command/7582.md view
@@ -0,0 +1,28 @@+```+% pandoc -t revealjs+# Slide++::: columns+:::: column+Left column+::::++. . .++:::: column+Right column+::::+:::+^D+<section id="slide" class="slide level1">+<h1>Slide</h1>+<div class="columns">+<div class="column">+<p>Left column</p>+</div><div class="fragment"><div class="column">+<p>Right column</p>+</div></div>+</div>+</section>++```
test/command/7861.md view
@@ -2,6 +2,6 @@ % pandoc -s -t native --data-dir=command/7861 --metadata-file=../../7861.yaml Hello ^D-2> Could not find metadata file ../../7861.yaml+2> Could not find metadata file '../../7861.yaml' => 98 ```
+ test/command/8024.md view
@@ -0,0 +1,10 @@+```+% pandoc -d command/8024a.yaml -t markdown+Hello, if this works the text should be wrapped.+^D+Hello, if this+works the text+should be+wrapped.++```
+ test/command/8024a.yaml view
@@ -0,0 +1,2 @@+defaults: ${.}/8024b.yaml+
+ test/command/8024b.yaml view
@@ -0,0 +1,3 @@+wrap: auto+columns: 15+
test/command/8256.md view
@@ -16,14 +16,13 @@ <style:font-face style:name="Courier New" style:font-family-generic="modern" style:font-pitch="fixed" svg:font-family="'Courier New'" /> </office:font-face-decls> <office:automatic-styles>- <style:style style:name="T1" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style> <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style> <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style> </office:automatic-styles> <office:body> <office:text> <text:p text:style-name="Title">This-<text:span text:style-name="T1">is</text:span><text:line-break />a+<text:span text:style-name="Emphasis">is</text:span><text:line-break />a test</text:p> <text:p text:style-name="Author">Someone</text:p> <text:p text:style-name="Text_20_body">Testing.</text:p>
test/command/8665.md view
@@ -24,6 +24,6 @@ [cols=",",options="header",] |=== <|h1 <|h2-<|!@#$%^&++*++()++{++}{vbar}~?{plus}-',."++<>[]\`++ <|col 2+<|!@++#++$%^&++*++()++{++}{vbar}~?{plus}-',."++<>[]\`++ <|col 2 |=== ```
+ test/command/8783.md view
@@ -0,0 +1,33 @@+```+% pandoc -f rtf -t native+{\rtf1\ansi\ansicpg1252\cocoartf2867+\cocoatextscaling0\cocoaplatform1{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}+{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;}+{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid1\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid1}+{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}}+{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}+\paperw11905\paperh16837\margl1133\margr1133\margb1133\margt1133+\deftab720+\pard\pardeftab720\partightenfactor0++\f0\fs22 \cf2 \up0 \nosupersub \ulnone First paragraph\+\pard\tx20\tx360\pardeftab720\li360\fi-360\partightenfactor0+\ls1\ilvl0\cf2 \up0 \nosupersub \ulnone {\listtext 1. }\cf2 \up0 \nosupersub \ulnone Numbered item\+\pard\pardeftab720\partightenfactor0+\cf2 Second paragraph\+\pard\tx20\tx180\pardeftab720\li180\fi-180\partightenfactor0+\ls2\ilvl0\cf2 \up0 \nosupersub \ulnone {\listtext \uc0\u8226 }\cf2 \up0 \nosupersub \ulnone Bullet item\+\pard\pardeftab720\partightenfactor0+\cf2 New paragraph}+^D+[ Para [ Str "First" , Space , Str "paragraph" ]+, OrderedList+ ( 1 , Decimal , Period )+ [ [ Para [ Str "Numbered" , Space , Str "item" ] ] ]+, Para [ Str "Second" , Space , Str "paragraph" ]+, BulletList+ [ [ Para [ Str "Bullet" , Space , Str "item" ] ] ]+, Para [ Str "New" , Space , Str "paragraph" ]+]+```
+ test/command/8852.md view
@@ -0,0 +1,43 @@+Github Formatted Markdown Identifiers+```+% pandoc -f man+gfm_auto_identifiers -t html+.TH "TEST" "1" "2026-05-08" "test v1.0.0" "test manual"+.SH 1st HEADING+.SH C++ & Rust+.SH HEADING+.SH HEADING+^D+<h1 id="1st-heading">1st HEADING</h1>+<h1 id="c--rust">C++ & Rust</h1>+<h1 id="heading">HEADING</h1>+<h1 id="heading-1">HEADING</h1>+```++Ascii Identifiers test+```+% pandoc -f man+ascii_identifiers -t html+.TH "TEST" "1" "2026-05-08" "test v1.0.0" "test manual"+.SH Über den Flüssen+^D+<h1 id="uber-den-flussen">Über den Flüssen</h1>+```++Headers without Auto Identifiers test+```+% pandoc -f man-auto_identifiers -t native+.TH "TEST" "1" "2026-05-08" "test v1.0.0" "test manual"+.SS Level 2+.SS different styles:+.SS Ordered+.SS Ordered+^D+[ Header+ 2 ( "" , [] , [] ) [ Str "Level" , Space , Str "2" ]+, Header+ 2+ ( "" , [] , [] )+ [ Str "different" , Space , Str "styles:" ]+, Header 2 ( "" , [] , [] ) [ Str "Ordered" ]+, Header 2 ( "" , [] , [] ) [ Str "Ordered" ]+]+```
+ test/command/8880.md view
@@ -0,0 +1,42 @@+Raw EPUB attributes are rendered in EPUB output.++```+% pandoc -f native -t epub --metadata title=Raw -o - | pandoc -f epub -t html+[ RawBlock (Format "epub") "<p>ok</p>" ]+^D+<p><span id="title_page.xhtml"></span></p>+<p><span id="ch001.xhtml"></span></p>+<section id="ch001.xhtml_raw" class="unnumbered level1">+<h1 class="unnumbered">Raw</h1>+<p>ok</p>+</section>+```++Raw EPUB2 attributes are omitted from EPUB3 output.++```+% pandoc -f markdown -t epub3 --metadata title=Raw -o - | pandoc -f epub -t html+~~~ {=epub2}+<p>ok</p>+~~~+^D+<p><span id="title_page.xhtml"></span></p>+<p><span id="ch001.xhtml"></span></p>+<section id="ch001.xhtml_raw" class="unnumbered level1">+<h1 class="unnumbered">Raw</h1>+</section>+```++```+% pandoc -f markdown -t epub3 --metadata title=Raw -o - | pandoc -f epub -t html+~~~ {=epub3}+<p>ok</p>+~~~+^D+<p><span id="title_page.xhtml"></span></p>+<p><span id="ch001.xhtml"></span></p>+<section id="ch001.xhtml_raw" class="unnumbered level1">+<h1 class="unnumbered">Raw</h1>+<p>ok</p>+</section>+```
test/command/8966.md view
@@ -3,7 +3,7 @@ **Samsonov T.E.** Shape-Adaptive Geometric Simplification of Heterogeneous Line Datasets / T. E. Samsonov, O. P. Yakimova // International Journal of Geographical Information Science. — 2017. — Vol. 31. — № 8. — pp. 1485-1520. ^D #strong[Samsonov T.E.] Shape-Adaptive Geometric Simplification of-Heterogeneous Line Datasets / T. E. Samsonov, O. P. Yakimova \/\/+Heterogeneous Line Datasets / T. E. Samsonov, O. P. Yakimova /\/ International Journal of Geographical Information Science. --- 2017. --- Vol. 31. --- № 8. --- pp.~1485-1520. ```
test/command/8997.md view
@@ -24,7 +24,7 @@ , Space , Str "colon" ]-, CodeBlock ( "" , [ "example" ] , [] ) "aaa\n\nbbb\n"+, CodeBlock ( "" , [] , [] ) "aaa\n\nbbb\n" , Header 1 ( "has-no-space-after-second-colon" , [] , [] )@@ -40,7 +40,7 @@ , Space , Str "colon" ]-, CodeBlock ( "" , [ "example" ] , [] ) "aaa\n\nbbb\n"+, CodeBlock ( "" , [] , [] ) "aaa\n\nbbb\n" ] ``` @@ -56,7 +56,7 @@ 1 ( "only-the-colon" , [] , [] ) [ Str "only" , Space , Str "the" , Space , Str "colon" ]-, CodeBlock ( "" , [ "example" ] , [] ) "\n"+, CodeBlock ( "" , [] , [] ) "\n" , Header 1 ( "only-the-colon-and-a-space" , [] , [] )@@ -72,6 +72,6 @@ , Space , Str "space" ]-, CodeBlock ( "" , [ "example" ] , [] ) "\n"+, CodeBlock ( "" , [] , [] ) "\n" ] ```
+ test/command/9136.md view
@@ -0,0 +1,89 @@+Verify that the OpenDocument writer uses predefined list, paragraph, and+text styles instead of generating per-instance automatic styles.++```+% pandoc -t opendocument+- one+- two++1. ordered one+2. ordered two++Some *italic*, **bold**, ~~strike~~, and `code`.++> A block quote.++Final paragraph.+^D+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">one</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">two</text:p>+ </text:list-item>+</text:list>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">ordered+ one</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">ordered+ two</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Some+<text:span text:style-name="Emphasis">italic</text:span>,+<text:span text:style-name="Strong_20_Emphasis">bold</text:span>,+<text:span text:style-name="Strikeout">strike</text:span>, and+<text:span text:style-name="Source_20_Text">code</text:span>.</text:p>+<text:p text:style-name="Quotations">A block quote.</text:p>+<text:p text:style-name="First_20_paragraph">Final paragraph.</text:p>+```++A non-default ordered list (start value other than 1, or non-decimal+format) generates a single named override style, not one per instance.++```+% pandoc -t opendocument+A) upper-alpha one+B) upper-alpha two++5. start at five+6. and continue+^D+<text:list text:style-name="Pandoc_5f_Numbering_5f_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">upper-alpha+ one</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">upper-alpha+ two</text:p>+ </text:list-item>+</text:list>+<text:list text:style-name="Numbering_20_1" text:start-value="5">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">start at+ five</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">and+ continue</text:p>+ </text:list-item>+</text:list>+```++A nested block quote uses the predefined `Quotations` style for the+outer paragraph, and inherits indent from it for the inner paragraph.++```+% pandoc -t opendocument+> First.+>+> > Nested.+^D+<text:p text:style-name="Quotations">First.</text:p>+<text:p text:style-name="P1">Nested.</text:p>+```
test/command/9201.md view
@@ -12,7 +12,7 @@ **\--help** -: This is line one.+: This is line one. - This is line two.+ This is line two. ```
test/command/9236.md view
@@ -9,25 +9,26 @@ And inline: {height=2in} and . ^D-#figure(image("command/minimal.svg", width: 3in),+#figure(image("command/minimal.svg", width: 3in, alt: "minimal"), caption: [ minimal ] ) -#figure(image("command/minimal.svg", height: 2in, width: 3in),+#figure(image("command/minimal.svg", height: 2in, width: 3in, alt: "minimal"), caption: [ minimal ] ) -#figure(image("command/minimal.svg"),+#figure(image("command/minimal.svg", alt: "minimal"), caption: [ minimal ] ) -And inline: #box(image("command/minimal.svg", height: 2in)) and-#box(image("command/minimal.svg")).+And inline:+#box(image("command/minimal.svg", height: 2in, alt: "minimal")) and+#box(image("command/minimal.svg", alt: "minimal")). ```
test/command/9391.md view
@@ -3,7 +3,7 @@ ^D <p>Lorem ipsum.</p> <figure>-<img src="media/image1.png" style="width:1.10263in;height:1.10263in" />+<img src="media/image1.png" style="width:1.09702in;height:1.09702in" /> <figcaption><p>Blue square.</p></figcaption> </figure> ```
test/command/9472.md view
@@ -62,6 +62,10 @@ \usepackage{bookmark} \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available \urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother \hypersetup{ pdflang={de-DE}, hidelinks,
test/command/9700.md view
@@ -8,7 +8,7 @@ ^D This is a normal sentence with a manual text footnote* -\* The footnote explains why it couldn’t just be inside parentheses+<nowiki></nowiki>* The footnote explains why it couldn’t just be inside parentheses -\#foobar #foobar+<nowiki></nowiki>#foobar #foobar ```
+ test/command/9716.md view
@@ -0,0 +1,13 @@+```+% pandoc -f markdown+alerts -t native+> [!TIP]+> A suggestion.+^D+[ Div+ ( "" , [ "tip" ] , [] )+ [ Div ( "" , [ "title" ] , [] ) [ Para [ Str "Tip" ] ]+ , Para [ Str "A" , Space , Str "suggestion." ]+ ]+]++```
test/command/biblatex-crossref-nested.md view
@@ -53,7 +53,7 @@ publisher: Publisher publisher-place: Location title: Macbeth \[title field of bookinbook-1\]- type: chapter+ type: book volume: 3 volume-title: Tragedies \[title field of book-1\] - author:
test/command/figures-mediawiki.md view
@@ -6,9 +6,6 @@ ^D <div id="fig-id" class="figure">- [[File:foo.png|thumb|none]]-- </div> ```
+ test/command/grid-table-indented.md view
@@ -0,0 +1,65 @@+Like other block-level constructs, grid tables may be indented by up to+three spaces and are still recognized as tables.++```+% pandoc -f markdown -t html+ +---+---++ | a | b |+ +===+===++ | 1 | 2 |+ +---+---++^D+<table style="width:11%;">+<colgroup>+<col style="width: 5%" />+<col style="width: 5%" />+</colgroup>+<thead>+<tr>+<th>a</th>+<th>b</th>+</tr>+</thead>+<tbody>+<tr>+<td>1</td>+<td>2</td>+</tr>+</tbody>+</table>+```++A headerless indented grid table is recognized too.++```+% pandoc -f markdown -t html+ +------+------++ | foo | bar |+ +------+------++^D+<table style="width:19%;">+<colgroup>+<col style="width: 9%" />+<col style="width: 9%" />+</colgroup>+<tbody>+<tr>+<td>foo</td>+<td>bar</td>+</tr>+</tbody>+</table>+```++A grid table indented four spaces is a code block, not a table.++```+% pandoc -f markdown -t html+ +---+---++ | a | b |+ +---+---++^D+<pre><code>+---+---++| a | b |++---+---+</code></pre>+```
+ test/command/mediawiki_behavior_switches.md view
@@ -0,0 +1,16 @@+```+% pandoc -f mediawiki -t native+____INDEX____+__NOINDEX__+__noindex__+__FOOBAR__+^D+[ Para+ [ Str "____"+ , SoftBreak+ , Str "__noindex__"+ , SoftBreak+ , Str "__FOOBAR__"+ ]+]+```
+ test/command/pdfstandard.md view
@@ -0,0 +1,616 @@+PDF standard support: basic PDF/A-2b test (infers version 1.7)+```+% pandoc -t latex -s+---+pdfstandard: a-2b+lang: en-US+---++Test document.+^D+\DocumentMetadata{+ pdfversion=1.7,+ pdfstandard={a-2b},+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++Test document.++\end{document}+```++PDF standard support: PDF/UA-1 with tagging+```+% pandoc -t latex -s+---+pdfstandard: ua-1+lang: en-US+---++Accessible document.+^D+\DocumentMetadata{+ pdfstandard={ua-1},+ tagging=on,+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++Accessible document.++\end{document}+```++PDF standard support: multiple standards with version+```+% pandoc -t latex -s+---+pdfstandard:+ - a-2b+ - ua-1+ - "1.7"+lang: de-DE+---++Multi-standard document.+^D+\DocumentMetadata{+ pdfversion=1.7,+ pdfstandard={a-2b,ua-1},+ tagging=on,+ lang=de-DE,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ ngerman,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={de-DE},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++Multi-standard document.++\end{document}+```++PDF standard support: PDF/A-1b infers version 1.4+```+% pandoc -t latex -s+---+pdfstandard: a-1b+lang: en-US+---++PDF/A-1 document.+^D+\DocumentMetadata{+ pdfversion=1.4,+ pdfstandard={a-1b},+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++PDF/A-1 document.++\end{document}+```++PDF standard support: PDF/A-4 with no version inference (uses default 2.0)+```+% pandoc -t latex -s+---+pdfstandard: a-4+lang: en-US+---++PDF/A-4 document.+^D+\DocumentMetadata{+ pdfstandard={a-4},+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++PDF/A-4 document.++\end{document}+```++PDF standard support: numeric YAML version (2 becomes 2.0)+```+% pandoc -t latex -s+---+pdfstandard:+ - ua-1+ - 2+lang: en-US+---++PDF 2.0 document.+^D+\DocumentMetadata{+ pdfversion=2.0,+ pdfstandard={ua-1},+ tagging=on,+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++PDF 2.0 document.++\end{document}+```++PDF standard support: explicit version overrides inferred version+```+% pandoc -t latex -s+---+pdfstandard:+ - a-2b+ - "1.5"+lang: en-US+---++Explicit version document.+^D+\DocumentMetadata{+ pdfversion=1.5,+ pdfstandard={a-2b},+ lang=en-US,+ xmp=true}+% Options for packages loaded elsewhere+\PassOptionsToPackage{unicode}{hyperref}+\PassOptionsToPackage{hyphens}{url}+\documentclass[+ american,+]{article}+\usepackage{xcolor}+\usepackage{amsmath,amssymb}+\setcounter{secnumdepth}{-\maxdimen} % remove section numbering+\usepackage{iftex}+\ifPDFTeX+ \usepackage[T1]{fontenc}+ \usepackage[utf8]{inputenc}+ \usepackage{textcomp} % provide euro and other symbols+\else % if luatex or xetex+ \usepackage{unicode-math} % this also loads fontspec+ \defaultfontfeatures{Scale=MatchLowercase}+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}+\fi+\usepackage{lmodern}+\ifPDFTeX\else+ % xetex/luatex font selection+\fi+% Use upquote if available, for straight quotes in verbatim environments+\IfFileExists{upquote.sty}{\usepackage{upquote}}{}+\IfFileExists{microtype.sty}{% use microtype if available+ \usepackage[]{microtype}+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts+}{}+\makeatletter+\@ifundefined{KOMAClassName}{% if non-KOMA class+ \IfFileExists{parskip.sty}{%+ \usepackage{parskip}+ }{% else+ \setlength{\parindent}{0pt}+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}+}{% if KOMA class+ \KOMAoptions{parskip=half}}+\makeatother+\ifLuaTeX+\usepackage[bidi=basic,shorthands=off]{babel}+\else+\usepackage[bidi=default,shorthands=off]{babel}+\fi+\ifLuaTeX+ \usepackage{selnolig} % disable illegal ligatures+\fi+\setlength{\emergencystretch}{3em} % prevent overfull lines+\providecommand{\tightlist}{%+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}+\usepackage{bookmark}+\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available+\urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother+\hypersetup{+ pdflang={en-US},+ hidelinks,+ pdfcreator={LaTeX via pandoc}}++\author{}+\date{}++\begin{document}++Explicit version document.++\end{document}+```
+ test/command/reset-citation-positions.md view
@@ -0,0 +1,41 @@+```+% pandoc --citeproc -t plain --csl command/chicago-fullnote-bibliography.csl+---+suppress-bibliography: true+references:+- id: foo+ name: John doe+ title: A Book+ type: book+ publisher: Oxford University Press+ issued: 2010+...++# Chapter one++Blah [@foo, p. 7].++Blah [@foo, p. 8].++# Chapter two {.reset-citation-positions}++Blah [@foo, p. 57].+^D+Chapter one++Blah.[1]++Blah.[2]++Chapter two++Blah.[3]++[1] A Book (Oxford University Press, 2010), 7.++[2] A Book, 8.++[3] A Book (Oxford University Press, 2010), 57.++```+
test/command/table-with-column-span.md view
@@ -315,11 +315,11 @@ <table:table-column table:style-name="Table1.P" /> <table:table-row> <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">- <text:p text:style-name="Table_20_Contents"><text:span text:style-name="T1">Octet+ <text:p text:style-name="Table_20_Contents"><text:span text:style-name="Strong_20_Emphasis">Octet no. 1</text:span></text:p> </table:table-cell> <table:table-cell table:style-name="TableRowCell" office:value-type="string" table:number-columns-spanned="8">- <text:p text:style-name="Table_20_Contents"><text:span text:style-name="T1">Octet+ <text:p text:style-name="Table_20_Contents"><text:span text:style-name="Strong_20_Emphasis">Octet no. 2</text:span></text:p> </table:table-cell> </table:table-row>
+ test/command/typst-image-alt.md view
@@ -0,0 +1,78 @@+```+% pandoc -f markdown-implicit_figures -t typst++^D+#box(image("image.png", alt: "Alt text from inlines"))+```++```+% pandoc -f markdown-implicit_figures -t typst+{alt="Explicit alt attribute"}+^D+#box(image("image.png", alt: "Explicit alt attribute"))+```++```+% pandoc -f markdown-implicit_figures -t typst+{alt="Explicit wins"}+^D+#box(image("image.png", alt: "Explicit wins"))+```++```+% pandoc -f markdown-implicit_figures -t typst++^D+#box(image("image.png"))+```++```+% pandoc -f markdown-implicit_figures -t typst+{alt=""}+^D+#box(image("image.png"))+```++```+% pandoc -t typst+{alt="Alt text describing the image"}++^D+#figure(image("image.png", alt: "Alt text describing the image"),+ caption: [+ Caption text+ ]+)+```++```+% pandoc -t typst+++^D+#figure(image("image.png", alt: "Caption only"),+ caption: [+ Caption only+ ]+)+```++```+% pandoc -f markdown -t typst+{alt="A \"quoted\" phrase and C:\\path\\file"}+^D+#figure(image("test.png", alt: "A \"quoted\" phrase and C:\\path\\file"),+ caption: [+ Caption+ ]+)++```++```+% pandoc -f html -t typst+<img src="data:image/png;base64,iVBORw0KGgo=" alt="A small red dot">+^D+#box(image(bytes((137,80,78,71,13,10,26,10)), alt: "A small red dot"))++```
+ test/command/typst-images.md view
@@ -0,0 +1,32 @@+```+% pandoc -t typst+{width=1in}+^D+#figure(image(bytes((137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,10,0,0,0,10,8,6,0,0,0,141,50,207,189,0,0,0,9,112,72,89,115,0,0,46,35,0,0,46,35,1,120,165,63,118,0,0,0,73,73,68,65,84,24,25,173,206,91,10,0,32,8,4,64,215,251,223,217,52,18,53,66,127,18,130,30,211,42,136,72,116,141,197,163,56,160,64,145,8,207,123,179,5,118,233,255,33,180,93,12,214,244,230,123,232,151,53,179,19,29,3,118,140,202,247,165,181,63,56,205,31,23,32,166,25,1,179,208,168,31,0,0,0,0,73,69,78,68,174,66,96,130)), width: 1in, alt: "dot"),+ caption: [+ dot+ ]+)+```++```+% pandoc -t typst+{width="1in"}+^D+#figure(image("dot.png", width: 1in, alt: "dot"),+ caption: [+ dot+ ]+)+```++```+% pandoc -t typst++^D+#figure(image(bytes("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" aria-label=\"Chicken\"> <path d=\"M76.5 33.3l-8.3-6.6 4-5c-1.3-2-1.3-4.7.1-6.6 3.4-3.8 8.7-2 10.2 2.2 4.5.7 7.5 5.4 4.4 9.4a5.7 5.7 0 01-6.4 1.6zM73 26.2l3 2.4 3.8-4.7c1.3 1 3.5 2 4.5.7 2.1-2.9-1.5-5.4-4.7-3.5 1.2-4.6-2.7-6.2-4.5-3.9-.7 2.2.2 3 1.7 4.2z\"/> <path d=\"M54 72.3a19.1 19.1 0 01-19.2-17.8 21.4 21.4 0 014.7-15.2c3.5-4.3 8.4-7.1 13.7-8l3.1-.1c8.2-.9 12.9-5.5 13-5.6l1-1 8.2 6.5-1 1.3c-3.3 4-2.8 11.3-2.5 14.2a21.5 21.5 0 01-4.4 17.5 21.2 21.2 0 01-16.5 8.2zM70.6 29a27 27 0 01-14 5.5l-3 .2a18 18 0 00-11.3 6.7 18 18 0 00-4 12.8 16 16 0 0015.9 14.7c5.4 0 10.4-2.5 14-6.9A18 18 0 0072 49.4c0-.8-.2-1.6-.3-2.2-.5-4-.7-10.7 2.1-15.5z\"/> <path d=\"M46 87C22.6 87 .5 87 .5 66.8c0-19 20.4-34.6 45.5-34.6 1.2 0 2.5 0 3.7.2 10.1.6 9.7-.1.5 3.2a18.3 18.3 0 00-12 18.6 16 16 0 0015.9 14.7c5.4 0 10.4-2.5 14-6.9A18 18 0 0072 49.4c-.6-4-.4-7.4-.2-11.3a35.8 35.8 0 0119.5 26A11.7 11.7 0 0187.8 87H46zm-2.8-51.3c-22 1-39.4 14.6-39.4 31 0 15.8 16 16.9 42.2 16.9h41.8c4.6 0 8.4-3.8 8.4-8.4-.4-4.8-3.2-7.7-8.1-8.4-.3-10.4-7.4-18.4-13.3-22.7.1 2 .5 4.3.7 6.1 0 5-1.6 10-4.8 14A21.2 21.2 0 0154 72.3a19.1 19.1 0 01-19.3-17.8 21.4 21.4 0 018.4-18.8z\"/> </svg>"), alt: "chicken"),+ caption: [+ chicken+ ]+)+```
test/command/typst-property-output.md view
@@ -26,7 +26,8 @@ <div typst:text:fill="purple">foo</div> ^D #block[-#set text(fill: purple); foo+#set text(fill: purple);+foo ] ``` @@ -63,7 +64,7 @@ </table> ^D #figure(- align(center)[#set text(fill: orange); #table(+ align(center)[#set text(fill: orange);#table( columns: 2, align: (auto,auto,), [A], [B],@@ -98,7 +99,8 @@ align(center)[#table( columns: 2, align: (auto,auto,),- [A], [#set text(fill: fuchsia); B],+ [A], [#set text(fill: fuchsia);+ B], )] , kind: table )@@ -114,7 +116,8 @@ align(center)[#table( columns: 2, align: (auto,center,),- [A], table.cell(align: center)[#set text(fill: maroon); B],+ [A], table.cell(align: center)[#set text(fill: maroon);+ B], )] , kind: table )@@ -169,7 +172,7 @@ ^D Paragraph before. -#{set text(size: 3em); table(+#{set text(size: 3em);table( columns: 3, align: (auto,auto,auto,), [A], [B], [C],@@ -195,7 +198,7 @@ Paragraph before. #figure(- align(center)[#set text(size: 3em); #table(+ align(center)[#set text(size: 3em);#table( columns: 3, align: (auto,auto,auto,), [A], [B], [C],
test/docbook-reader.docbook view
@@ -27,9 +27,9 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite. </para>-<sect1 id="headers">+<sect1 id="headers" role="sect1role"> <title>Headers</title>- <sect2 id="level-2-with-an-embedded-link">+ <sect2 id="level-2-with-an-embedded-link" role="sect2role"> <title>Level 2 with an <ulink url="/url">embedded link</ulink></title> <sect3 id="level-3-with-emphasis"> <title>Level 3 with <emphasis>emphasis</emphasis></title>@@ -74,6 +74,9 @@ <para> Here’s a regular paragraph. </para>+ <para role="pararole">+ And here’s a regular paragraph with a role.+ </para> <para> In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like@@ -93,6 +96,11 @@ This is a block quote. It is pretty short. </para> </blockquote>+ <blockquote role="roleblockquote">+ <para>+ This is a block quote with a role.+ </para>+ </blockquote> <blockquote> <para> Code in a block quote:@@ -234,6 +242,26 @@ </listitem> </orderedlist> <para>+ with role:+ </para>+ <orderedlist role="listrole" numeration="arabic">+ <listitem>+ <para>+ First+ </para>+ </listitem>+ <listitem>+ <para>+ Second+ </para>+ </listitem>+ <listitem>+ <para>+ Third+ </para>+ </listitem>+ </orderedlist>+ <para> and tight: </para> <orderedlist spacing="compact" numeration="arabic">@@ -703,6 +731,12 @@ So is <emphasis role="strong"><emphasis>this</emphasis></emphasis> word. </para> <para>+ So is <emphasis role="emphasisrole"><emphasis>this</emphasis></emphasis> word with a role.+ </para>+ <para>+ So is <phrase role="phraserole"><phrase>this</phrase></phrase> phrase with a role.+ </para>+ <para> This is code: <literal>></literal>, <literal>$</literal>, <literal>\</literal>, <literal>\$</literal>, <literal><html></literal>.@@ -1408,7 +1442,7 @@ <para> Table with attributes </para>- <table xml:id="mytableid1" class="mytableclass1 mytableclass2" tabstyle="mytabstyle1">+ <table xml:id="mytableid1" class="mytableclass1 mytableclass2" tabstyle="mytabstyle1" role="tablerole1"> <title> Attribute table caption </title>@@ -1444,7 +1478,7 @@ <para> Table with attributes, without caption </para>- <informaltable xml:id="mytableid2" class="mytableclass3 mytableclass4" tabstyle="mytabstyle2">+ <informaltable xml:id="mytableid2" class="mytableclass3 mytableclass4" tabstyle="mytabstyle2" role="tablerole2"> <tgroup> <thead> <th>
test/docbook-reader.native view
@@ -62,10 +62,16 @@ , Space , Str "suite." ]- , Header 1 ( "headers" , [] , [] ) [ Str "Headers" ] , Header+ 1+ ( "headers" , [] , [ ( "role" , "sect1role" ) ] )+ [ Str "Headers" ]+ , Header 2- ( "level-2-with-an-embedded-link" , [] , [] )+ ( "level-2-with-an-embedded-link"+ , []+ , [ ( "role" , "sect2role" ) ]+ ) [ Str "Level" , Space , Str "2"@@ -151,6 +157,29 @@ , Space , Str "paragraph." ]+ , Div+ ( ""+ , []+ , [ ( "wrapper" , "1" ) , ( "role" , "pararole" ) ]+ )+ [ Para+ [ Str "And"+ , Space+ , Str "here\8217s"+ , Space+ , Str "a"+ , Space+ , Str "regular"+ , Space+ , Str "paragraph"+ , Space+ , Str "with"+ , Space+ , Str "a"+ , Space+ , Str "role."+ ]+ ] , Para [ Str "In" , Space@@ -251,6 +280,31 @@ , Str "short." ] ]+ , Div+ ( ""+ , []+ , [ ( "wrapper" , "1" ) , ( "role" , "roleblockquote" ) ]+ )+ [ BlockQuote+ [ Para+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "a"+ , Space+ , Str "block"+ , Space+ , Str "quote"+ , Space+ , Str "with"+ , Space+ , Str "a"+ , Space+ , Str "role."+ ]+ ]+ ] , BlockQuote [ Para [ Str "Code"@@ -348,6 +402,19 @@ , [ Para [ Str "Second" ] ] , [ Para [ Str "Third" ] ] ]+ , Para [ Str "with" , Space , Str "role:" ]+ , Div+ ( ""+ , []+ , [ ( "wrapper" , "1" ) , ( "role" , "listrole" ) ]+ )+ [ OrderedList+ ( 1 , Decimal , DefaultDelim )+ [ [ Para [ Str "First" ] ]+ , [ Para [ Str "Second" ] ]+ , [ Para [ Str "Third" ] ]+ ]+ ] , Para [ Str "and" , Space , Str "tight:" ] , OrderedList ( 1 , Decimal , DefaultDelim )@@ -932,6 +999,38 @@ , Str "word." ] , Para+ [ Str "So"+ , Space+ , Str "is"+ , Space+ , Emph [ Emph [ Str "this" ] ]+ , Space+ , Str "word"+ , Space+ , Str "with"+ , Space+ , Str "a"+ , Space+ , Str "role."+ ]+ , Para+ [ Str "So"+ , Space+ , Str "is"+ , Space+ , Span+ ( "" , [ "phraserole" ] , [ ( "role" , "phraserole" ) ] )+ [ Str "this" ]+ , Space+ , Str "phrase"+ , Space+ , Str "with"+ , Space+ , Str "a"+ , Space+ , Str "role."+ ]+ , Para [ Str "This" , Space , Str "is"@@ -2570,7 +2669,9 @@ , Table ( "mytableid1" , [ "mytableclass1" , "mytableclass2" ]- , [ ( "custom-style" , "mytabstyle1" ) ]+ , [ ( "role" , "tablerole1" )+ , ( "custom-style" , "mytabstyle1" )+ ] ) (Caption Nothing@@ -2636,7 +2737,9 @@ , Table ( "mytableid2" , [ "mytableclass3" , "mytableclass4" ]- , [ ( "custom-style" , "mytabstyle2" ) ]+ , [ ( "role" , "tablerole2" )+ , ( "custom-style" , "mytabstyle2" )+ ] ) (Caption Nothing []) [ ( AlignDefault , ColWidthDefault )
+ test/docx/german-reference.docx view
binary file changed (absent → 10405 bytes)
+ test/docx/image_with_textbox_caption.docx view
binary file changed (absent → 19882 bytes)
+ test/docx/image_with_textbox_caption.native view
@@ -0,0 +1,44 @@+[ Figure+ ( "" , [] , [] )+ (Caption+ Nothing+ [ Para+ [ Str "1"+ , Space+ , Str "Daniel"+ , Space+ , Str "Schliebner:"+ , Space+ , Str "Cantor'sches"+ , Space+ , Str "Diagonalverfahren."+ , Space+ , Str "Von"+ , Space+ , Str "Mengen,"+ , Space+ , Str "Unendlichkeiten"+ , Space+ , Str "und"+ , Space+ , Str "Wahnsinn,"+ , Space+ , Str "Pdf:"+ , Space+ , Str+ "https://www2.informatik.hu-berlin.de/~kossahl/Uni/Ma1/Cantor.pdf"+ ]+ ])+ [ Plain+ [ Image+ ( ""+ , []+ , [ ( "width" , "2.3680555555555554in" )+ , ( "height" , "0.9340277777777778in" )+ ]+ )+ []+ ( "media/image1.emf" , "" )+ ]+ ]+]
+ test/docx/table_gridbefore.docx view
binary file changed (absent → 13143 bytes)
+ test/docx/table_gridbefore.native view
@@ -0,0 +1,823 @@+[ Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidth 7.883369330453563e-3 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 3.0669546436285097e-2 )+ , ( AlignDefault , ColWidth 0.42861771058315334 )+ ]+ (TableHead+ ( "" , [] , [] )+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 8)+ [ Plain [ Str "Bits" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ ]+ ])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "8" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "7" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "6" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "5" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "4" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "3" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "2" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "TEXT" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "BINARY" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "HYPERLINKS" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "FILEURL" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "LOCATION" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "ENHANCED" , Space , Str "STATUS" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain+ [ Str "Value"+ , Space+ , Str "allocated"+ , Space+ , Str "for"+ , Space+ , Str "use"+ , Space+ , Str "in"+ , Space+ , Str "interworking"+ , Space+ , Str "(NOTE)"+ ]+ ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "LOCATION" , Space , Str "ALTITUDE" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "LOCATION" , Space , Str "TIMESTAMP" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 2)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "0" ] ]+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "CODED" , Space , Str "TEXT" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 10)+ [ Plain+ [ Str "All"+ , Space+ , Str "other"+ , Space+ , Str "values"+ , Space+ , Str "are"+ , Space+ , Str "reserved."+ ]+ ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] ) AlignDefault (RowSpan 1) (ColSpan 1) []+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 10)+ [ Plain+ [ Str "NOTE:"+ , Space+ , Str "Usage"+ , Space+ , Str "of"+ , Space+ , Str "this"+ , Space+ , Str "value"+ , Space+ , Str "is"+ , Space+ , Str "described"+ , Space+ , Str "in"+ , Space+ , Str "3GPP\160TS\160\&29.582\160[48]."+ ]+ ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+]
+ test/docx/textbox_image.docx view
binary file changed (absent → 40379 bytes)
+ test/docx/textbox_image.native view
@@ -0,0 +1,30 @@+[ Para+ [ Str "The"+ , Space+ , Str "image"+ , Space+ , Str "is"+ , Space+ , Str "below."+ ]+, Para+ [ Image+ ( ""+ , []+ , [ ( "width" , "4.543038057742782in" )+ , ( "height" , "2.9166666666666665in" )+ ]+ )+ []+ ( "media/image1.png" , "" )+ ]+, Para+ [ Str "The"+ , Space+ , Str "image"+ , Space+ , Str "is"+ , Space+ , Str "above."+ ]+]
+ test/docx/textbox_image_duplicate_encoding.docx view
binary file changed (absent → 36750 bytes)
+ test/docx/textbox_image_duplicate_encoding.native view
@@ -0,0 +1,30 @@+[ Para+ [ Str "The"+ , Space+ , Str "image"+ , Space+ , Str "is"+ , Space+ , Str "below."+ ]+, Para+ [ Image+ ( ""+ , []+ , [ ( "width" , "4.543038057742782in" )+ , ( "height" , "2.9166666666666665in" )+ ]+ )+ []+ ( "media/image1.png" , "" )+ ]+, Para+ [ Str "The"+ , Space+ , Str "image"+ , Space+ , Str "is"+ , Space+ , Str "above."+ ]+]
test/man-reader.native view
@@ -42,11 +42,11 @@ , Space , Str "*" ]- , Header 1 ( "" , [] , [] ) [ Str "Headers" ]+ , Header 1 ( "headers" , [] , [] ) [ Str "Headers" ] , Header- 1 ( "" , [] , [] ) [ Str "Level" , Space , Str "1" ]+ 1 ( "level-1" , [] , [] ) [ Str "Level" , Space , Str "1" ] , Header- 2 ( "" , [] , [] ) [ Str "Level" , Space , Str "2" ]+ 2 ( "level-2" , [] , [] ) [ Str "Level" , Space , Str "2" ] , Para [ Str "*" , Space@@ -58,7 +58,7 @@ , Space , Str "*" ]- , Header 1 ( "" , [] , [] ) [ Str "Paragraphs" ]+ , Header 1 ( "paragraphs" , [] , [] ) [ Str "Paragraphs" ] , Para [ Str "Here's" , Space@@ -159,7 +159,9 @@ , Str "*" ] , Header- 1 ( "" , [] , [] ) [ Str "Block" , Space , Str "Quotes" ]+ 1+ ( "block-quotes" , [] , [] )+ [ Str "Block" , Space , Str "Quotes" ] , Para [ Str "Code" , Space@@ -182,7 +184,9 @@ , [ Para [ Str "item" , Space , Str "two" ] ] ] , Header- 1 ( "" , [] , [] ) [ Str "Code" , Space , Str "Blocks" ]+ 1+ ( "code-blocks" , [] , [] )+ [ Str "Code" , Space , Str "Blocks" ] , Para [ Str "Code:" ] , CodeBlock ( "" , [] , [] )@@ -201,22 +205,22 @@ , Space , Str "*" ]- , Header 1 ( "" , [] , [] ) [ Str "Lists" ]- , Header 2 ( "" , [] , [] ) [ Str "Unordered" ]+ , Header 1 ( "lists" , [] , [] ) [ Str "Lists" ]+ , Header 2 ( "unordered" , [] , [] ) [ Str "Unordered" ] , Para [ Str "Asterisks:" ] , BulletList [ [ Para [ Str "asterisk" , Space , Str "1" ] ] , [ Para [ Str "asterisk" , Space , Str "2" ] ] , [ Para [ Str "asterisk" , Space , Str "3" ] ] ]- , Header 2 ( "" , [] , [] ) [ Str "Ordered" ]+ , Header 2 ( "ordered" , [] , [] ) [ Str "Ordered" ] , OrderedList ( 1 , Decimal , Period ) [ [ Para [ Str "First" ] ] , [ Para [ Str "Second" ] ] , [ Para [ Str "Third" ] ] ]- , Header 2 ( "" , [] , [] ) [ Str "Nested" ]+ , Header 2 ( "nested" , [] , [] ) [ Str "Nested" ] , BulletList [ [ Para [ Str "Tab" ] , BulletList@@ -254,7 +258,7 @@ ] , Header 2- ( "" , [] , [] )+ ( "different-styles" , [] , [] ) [ Str "different" , Space , Str "styles:" ] , OrderedList ( 1 , UpperAlpha , Period )@@ -292,7 +296,7 @@ ] ] ]- , Header 2 ( "" , [] , [] ) [ Str "Ordered" ]+ , Header 2 ( "ordered-1" , [] , [] ) [ Str "Ordered" ] , Para [ Str "Definition" , Space , Str "lists" ] , DefinitionList [ ( [ Strong [ Str "term1" ] ]@@ -323,7 +327,7 @@ ] , Header 1- ( "" , [] , [] )+ ( "special-characters" , [] , [] ) [ Str "Special" , Space , Str "Characters" ] , Para [ Str "AT&T"@@ -364,7 +368,7 @@ , Para [ Str "Bang:" , Space , Str "!" ] , Para [ Str "Plus:" , Space , Str "+" ] , Para [ Str "Minus:" , Space , Str "-" ]- , Header 1 ( "" , [] , [] ) [ Str "Links" ]+ , Header 1 ( "links" , [] , [] ) [ Str "Links" ] , Para [ Link ( "" , [] , [] )@@ -379,7 +383,7 @@ ( "mailto:me@example.com" , "" ) , Str "." ]- , Header 1 ( "" , [] , [] ) [ Str "Macros" ]+ , Header 1 ( "macros" , [] , [] ) [ Str "Macros" ] , Para [ Strong [ Str "Me" , Space , Str "Myself" ] , Space@@ -406,7 +410,7 @@ , Strong [ Str "Author" ] , Str "." ]- , Header 1 ( "" , [] , [] ) [ Str "Tables" ]+ , Header 1 ( "tables" , [] , [] ) [ Str "Tables" ] , Table ( "" , [] , [] ) (Caption Nothing [])
+ test/odt/native/imageRelative.native view
@@ -0,0 +1,10 @@+[ Para+ [ Image+ ( ""+ , []+ , [ ( "width" , "5.292cm" ) , ( "height" , "5.292cm" ) ]+ )+ []+ ( "../../lalune.jpg" , "" )+ ]+]
+ test/odt/native/preformattedText.native view
@@ -0,0 +1,4 @@+[ CodeBlock+ ( "" , [] , [] )+ "void main() {\n printf(\"Hello world\");\n}"+]
+ test/odt/native/preformattedTextParentStyle.native view
@@ -0,0 +1,4 @@+[ CodeBlock+ ( "" , [] , [] )+ "void main() {\n printf(\"Hello world\");\n}"+]
+ test/odt/native/sourceText.native view
@@ -0,0 +1,11 @@+[ Header+ 1+ ( "test-foo" , [] , [] )+ [ Span ( "anchor" , [] , [] ) []+ , Str "Test"+ , Space+ , Code ( "" , [] , [] ) "foo"+ ]+, Para+ [ Str "Hello" , Space , Code ( "" , [] , [] ) "world" ]+]
+ test/odt/native/tableWithSpans.native view
@@ -0,0 +1,134 @@+[ Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ ]+ (TableHead+ ( "" , [] , [] )+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 2)+ (ColSpan 1)+ [ Plain+ [ Str "H1"+ , Space+ , Str "Rowspan"+ , Space+ , Str "2"+ ]+ ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "H1-2" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "H1-3" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 2)+ [ Plain [ Str "H2-2/3" ] ]+ ]+ ])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B1-1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B1-2" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 3)+ (ColSpan 1)+ [ Plain [ Str "Rowspan" , Space , Str "3" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B2-1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B2-2" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 2)+ [ Plain [ Str "Columnspan" , Space , Str "2" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B4-1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 2)+ (ColSpan 2)+ [ Plain+ [ Str "Columnspan"+ , Space+ , Str "&"+ , Space+ , Str "Rowspan"+ , Space+ , Str "2"+ ]+ ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B5-1" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+, Para []+]
+ test/odt/odt/imageRelative.odt view
binary file changed (absent → 16213 bytes)
+ test/odt/odt/preformattedText.odt view
binary file changed (absent → 7342 bytes)
+ test/odt/odt/preformattedTextParentStyle.odt view
binary file changed (absent → 7150 bytes)
+ test/odt/odt/sourceText.odt view
binary file changed (absent → 6805 bytes)
+ test/odt/odt/tableWithSpans.odt view
binary file changed (absent → 10695 bytes)
+ test/pptx/metadata-speaker-notes/input.native view
@@ -0,0 +1,3 @@+Pandoc (Meta {unMeta = fromList [("author",MetaInlines [Str "Jesse",Space,Str "Rosenthal"]),("notes",MetaBlocks [Para [Str "These",Space,Str "are",Space,Str "speaker",Space,Str "notes",Space,Str "from",Space,Str "metadata."]]),("title",MetaInlines [Str "Testing"])]})+[Header 1 ("a-header",[],[]) [Str "A",Space,Str "header"]+,Para [Str "And",Space,Str "a",Space,Str "new",Space,Str "slide."]]
+ test/pptx/metadata-speaker-notes/output.pptx view
binary file changed (absent → 31689 bytes)
+ test/pptx/metadata-speaker-notes/templated.pptx view
binary file changed (absent → 44773 bytes)
test/s5-basic.html view
@@ -14,10 +14,13 @@ /* Default styles provided by pandoc. ** See https://pandoc.org/MANUAL.html#variables-for-html for config info. */- code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}- div.columns{display: flex; gap: min(4vw, 1.5em);}- div.column{flex: auto; overflow-x: auto;}+ div.columns{display: flex; gap: 1.5em;}+ div.column{flex: auto;}+ @media screen {+ div.columns{gap: min(4vw, 1.5em);}+ div.column{overflow-x: auto;}+ } div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */
test/s5-fancy.html view
@@ -14,10 +14,13 @@ /* Default styles provided by pandoc. ** See https://pandoc.org/MANUAL.html#variables-for-html for config info. */- code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}- div.columns{display: flex; gap: min(4vw, 1.5em);}- div.column{flex: auto; overflow-x: auto;}+ div.columns{display: flex; gap: 1.5em;}+ div.column{flex: auto;}+ @media screen {+ div.columns{gap: min(4vw, 1.5em);}+ div.column{overflow-x: auto;}+ } div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */@@ -40,7 +43,7 @@ <!-- S5 JS --> <script src="s5/default/slides.js" type="text/javascript"></script> <script defer=""- src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js"+ src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js" type="text/javascript"></script> </head> <body>
test/s5-inserts.html view
@@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" />- <meta name="generator" content="pandoc" />+ <meta name="generator" content="pandoc " /> <meta name="author" content="Sam Smith" /> <meta name="author" content="Jen Jones" /> <meta name="date" content="2006-07-15" />@@ -12,10 +12,13 @@ /* Default styles provided by pandoc. ** See https://pandoc.org/MANUAL.html#variables-for-html for config info. */- code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}- div.columns{display: flex; gap: min(4vw, 1.5em);}- div.column{flex: auto; overflow-x: auto;}+ div.columns{display: flex; gap: 1.5em;}+ div.column{flex: auto;}+ @media screen {+ div.columns{gap: min(4vw, 1.5em);}+ div.column{overflow-x: auto;}+ } div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */
test/tables/nordics.markdown view
@@ -1,18 +1,18 @@- -------------------------------------------------------------------------------- Name Capital Population\ Area\- (in 2018) (in km^2^)- ----------------------- ----------------------- --------------- ---------------- Denmark Copenhagen 5,809,502 43,094-- Finland Helsinki 5,537,364 338,145-- Iceland Reykjavik 343,518 103,000-- Norway Oslo 5,372,191 323,802-- Sweden Stockholm 10,313,447 450,295-- Total 27,376,022 1,258,336- -------------------------------------------------------------------------------++-----------------------+-----------------------+---------------+---------------++| Name | Capital | Population\ | Area\ |+| | | (in 2018) | (in km^2^) |++:=====================:+:======================+:==============+:==============++| Denmark | Copenhagen | 5,809,502 | 43,094 |++-----------------------+-----------------------+---------------+---------------++| Finland | Helsinki | 5,537,364 | 338,145 |++-----------------------+-----------------------+---------------+---------------++| Iceland | Reykjavik | 343,518 | 103,000 |++-----------------------+-----------------------+---------------+---------------++| Norway | Oslo | 5,372,191 | 323,802 |++-----------------------+-----------------------+---------------+---------------++| Sweden | Stockholm | 10,313,447 | 450,295 |++=======================+=======================+===============+===============++| Total | | 27,376,022 | 1,258,336 |++=======================+=======================+===============+===============+ - : States belonging to the *Nordics.* {#nordics source="wikipedia"}+: States belonging to the *Nordics.* {#nordics source="wikipedia"}
test/tables/nordics.mediawiki view
@@ -1,4 +1,4 @@-{| id="nordics" class="wikitable" source="wikipedia"+{| id="nordics" class="wikitable" data-source="wikipedia" |+ States belonging to the ''Nordics.'' |- ! style="text-align: center;"| Name
test/tables/nordics.typst view
@@ -3,9 +3,7 @@ columns: (30%, 30%, 20%, 20%), align: (center,left,left,left,), table.header(table.cell(align: center)[Name], table.cell(align: center)[Capital], table.cell(align: center)[Population- \- (in 2018)], table.cell(align: center)[Area \- (in km#super[2])],),+ \ (in 2018)], table.cell(align: center)[Area \ (in km#super[2])],), table.hline(), [Denmark], [Copenhagen], [5,809,502], [43,094], [Finland], [Helsinki], [5,537,364], [338,145],
test/tables/students.mediawiki view
@@ -1,4 +1,4 @@-{| id="students" class="wikitable" source="mdn"+{| id="students" class="wikitable" data-source="mdn" |+ List of Students |- ! style="text-align: center;"| Student ID
test/typst-reader.native view
@@ -528,8 +528,7 @@ (RowSpan 1) (ColSpan 1) [ CodeBlock- ( "" , [] , [] )- "-- document body here --\n "+ ( "" , [] , [] ) "-- document body here --" ] ] ]@@ -4132,7 +4131,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "lr([sum_(k = 0)^n e^(k^2)], size: #50%)\n "+ "lr([sum_(k = 0)^n e^(k^2)], size: #50%)" ] ] ]@@ -4199,7 +4198,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "lr(angle.l i, 2^(2^i) angle.r)\n "+ "lr(angle.l i, 2^(2^i) angle.r)" ] ] ]@@ -4274,8 +4273,7 @@ AlignDefault (RowSpan 1) (ColSpan 1)- [ CodeBlock- ( "" , [] , [] ) "(1 / n^(alpha))\n "+ [ CodeBlock ( "" , [] , [] ) "(1 / n^(alpha))" ] ] , Row@@ -4297,7 +4295,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "paren.l 1 / n^(alpha) paren.r\n "+ "paren.l 1 / n^(alpha) paren.r" ] ] ]@@ -4362,7 +4360,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "lr(frac(dif f, dif x) |)_(x_0)\n "+ "lr(frac(dif f, dif x) |)_(x_0)" ] ] ]@@ -4431,7 +4429,7 @@ (RowSpan 1) (ColSpan 1) [ CodeBlock- ( "" , [] , [] ) "$ mat(a, b; c, d) $\n "+ ( "" , [] , [] ) "$ mat(a, b; c, d) $" ] ] ]@@ -4576,7 +4574,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "$ f_n = cases(\n a &\"if\" n = 0,\n r dot f_(n - 1) &\"else\"\n ) $\n "+ "$ f_n = cases(\n a &\"if\" n = 0,\n r dot f_(n - 1) &\"else\"\n) $" ] ] ]@@ -4784,7 +4782,7 @@ (RowSpan 1) (ColSpan 1) [ CodeBlock- ( "" , [] , [] ) "$ S = k dot lg W $\n "+ ( "" , [] , [] ) "$ S = k dot lg W $" ] ] ]@@ -4837,7 +4835,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "$ sin(x) = x - x^3 / 3! \\\n + x^5 / 5! - dots.h.c $\n "+ "$ sin(x) = x - x^3 / 3! \\\n + x^5 / 5! - dots.h.c $" ] ] ]@@ -4886,7 +4884,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "$ nabla dot bold(D) &= rho \\\n nabla dot bold(B) &= 0 $\n "+ "$ nabla dot bold(D) &= rho \\\n nabla dot bold(B) &= 0 $" ] ] ]@@ -4977,8 +4975,7 @@ AlignDefault (RowSpan 1) (ColSpan 1)- [ CodeBlock ( "" , [] , [] ) "f: RR -> RR\n "- ]+ [ CodeBlock ( "" , [] , [] ) "f: RR -> RR" ] ] , Row ( "" , [] , [] )@@ -5027,7 +5024,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "lim_(h -> 0) (f(x + h) - f(x)) / h\n "+ "lim_(h -> 0) (f(x + h) - f(x)) / h" ] ] , Row@@ -5050,7 +5047,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "integral x^2 dif x = x^3 \\/ 3 + C\n "+ "integral x^2 dif x = x^3 \\/ 3 + C" ] ] , Row@@ -5073,7 +5070,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "nabla = bold(i) dif / (dif x) + bold(j) dif / (dif y) + bold(k) dif / (dif z)\n "+ "nabla = bold(i) dif / (dif x) + bold(j) dif / (dif y) + bold(k) dif / (dif z)" ] ] ]@@ -5225,7 +5222,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "sigma^2 = sqrt(sum(x_i - mu)^2 \\/ N)\n "+ "sigma^2 = sqrt(sum(x_i - mu)^2 \\/ N)" ] ] , Row@@ -5248,7 +5245,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "E(X) = mu_X = sum(x_i - P(x_i))\n "+ "E(X) = mu_X = sum(x_i - P(x_i))" ] ] ]@@ -5303,7 +5300,7 @@ (ColSpan 1) [ CodeBlock ( "" , [] , [] )- "1 / sqrt(2 sigma^2 pi)\n e^(- (x - mu)^2 / (2 sigma^2))\n "+ "1 / sqrt(2 sigma^2 pi)\n e^(- (x - mu)^2 / (2 sigma^2))" ] ] ]
test/writer.asciidoc view
@@ -529,7 +529,7 @@ Greater-than: ++>++ -Hash: #+Hash: ++#++ Period: .
test/writer.asciidoc_legacy view
@@ -528,7 +528,7 @@ Greater-than: ++>++ -Hash: #+Hash: ++#++ Period: .
test/writer.html4 view
@@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" />- <meta name="generator" content="pandoc" />+ <meta name="generator" content="pandoc " /> <meta name="author" content="John MacFarlane" /> <meta name="author" content="Anonymous" /> <meta name="date" content="2006-07-17" />@@ -94,6 +94,7 @@ color: #606060; } code {+ white-space: pre-wrap; font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace; font-size: 85%; margin: 0;@@ -157,10 +158,13 @@ #TOC a:not(:hover) { text-decoration: none; }- code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}- div.columns{display: flex; gap: min(4vw, 1.5em);}- div.column{flex: auto; overflow-x: auto;}+ div.columns{display: flex; gap: 1.5em;}+ div.column{flex: auto;}+ @media screen {+ div.columns{gap: min(4vw, 1.5em);}+ div.column{overflow-x: auto;}+ } div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */
test/writer.html5 view
@@ -1,8 +1,8 @@ <!DOCTYPE html>-<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">+<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" />- <meta name="generator" content="pandoc" />+ <meta name="generator" content="pandoc " /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <meta name="author" content="John MacFarlane" /> <meta name="author" content="Anonymous" />@@ -94,6 +94,7 @@ color: #606060; } code {+ white-space: pre-wrap; font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace; font-size: 85%; margin: 0;@@ -157,10 +158,13 @@ #TOC a:not(:hover) { text-decoration: none; }- code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;}- div.columns{display: flex; gap: min(4vw, 1.5em);}- div.column{flex: auto; overflow-x: auto;}+ div.columns{display: flex; gap: 1.5em;}+ div.column{flex: auto;}+ @media screen {+ div.columns{gap: min(4vw, 1.5em);}+ div.column{overflow-x: auto;}+ } div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */
test/writer.jats_archiving view
@@ -576,27 +576,15 @@ <sec id="html-blocks"> <title>HTML Blocks</title> <p>Simple block on one line:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>And nested without indentation:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- <boxed-text>- <p>bar</p>- </boxed-text>- </boxed-text>+ <p>foo</p>+ <p>bar</p> <p>Interpreted markdown in a table:</p> <p>This is <italic>emphasized</italic></p> <p>And this is <bold>strong</bold></p> <p>Here’s a simple block:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>This should be a code block, though:</p> <preformat><div> foo@@ -604,13 +592,7 @@ <p>As should this:</p> <preformat><div>foo</div></preformat> <p>Now, nested:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- </boxed-text>+ <p>foo</p> <p>This should just be an HTML comment:</p> <p>Multiline:</p> <p>Code block:</p>
test/writer.jats_articleauthoring view
@@ -573,27 +573,15 @@ <sec id="html-blocks"> <title>HTML Blocks</title> <p>Simple block on one line:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>And nested without indentation:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- <boxed-text>- <p>bar</p>- </boxed-text>- </boxed-text>+ <p>foo</p>+ <p>bar</p> <p>Interpreted markdown in a table:</p> <p>This is <italic>emphasized</italic></p> <p>And this is <bold>strong</bold></p> <p>Here’s a simple block:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>This should be a code block, though:</p> <preformat><div> foo@@ -601,13 +589,7 @@ <p>As should this:</p> <preformat><div>foo</div></preformat> <p>Now, nested:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- </boxed-text>+ <p>foo</p> <p>This should just be an HTML comment:</p> <p>Multiline:</p> <p>Code block:</p>
test/writer.jats_publishing view
@@ -576,27 +576,15 @@ <sec id="html-blocks"> <title>HTML Blocks</title> <p>Simple block on one line:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>And nested without indentation:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- <boxed-text>- <p>bar</p>- </boxed-text>- </boxed-text>+ <p>foo</p>+ <p>bar</p> <p>Interpreted markdown in a table:</p> <p>This is <italic>emphasized</italic></p> <p>And this is <bold>strong</bold></p> <p>Here’s a simple block:</p>- <boxed-text>- <p>foo</p>- </boxed-text>+ <p>foo</p> <p>This should be a code block, though:</p> <preformat><div> foo@@ -604,13 +592,7 @@ <p>As should this:</p> <preformat><div>foo</div></preformat> <p>Now, nested:</p>- <boxed-text>- <boxed-text>- <boxed-text>- <p>foo</p>- </boxed-text>- </boxed-text>- </boxed-text>+ <p>foo</p> <p>This should just be an HTML comment:</p> <p>Multiline:</p> <p>Code block:</p>
test/writer.latex view
@@ -65,6 +65,10 @@ \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available \urlstyle{same} \VerbatimFootnotes % allow verbatim text in footnotes+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother \hypersetup{ pdftitle={Pandoc Test Suite}, pdfauthor={John MacFarlane; Anonymous},
test/writer.man view
@@ -359,27 +359,40 @@ .TP apple red fruit+.RS computer+.RE .TP orange orange fruit+.RS bank+.RE .PP Multiple definitions, loose: .TP apple red fruit+.RS+.PP computer+.RE .TP orange orange fruit+.RS+.PP bank+.RE .PP Blank line after term, indented marker, alternate markers: .TP apple red fruit+.RS+.PP computer+.RE .TP orange orange fruit
test/writer.markdown view
@@ -261,93 +261,93 @@ Tight using spaces: apple-: red fruit+: red fruit orange-: orange fruit+: orange fruit banana-: yellow fruit+: yellow fruit Tight using tabs: apple-: red fruit+: red fruit orange-: orange fruit+: orange fruit banana-: yellow fruit+: yellow fruit Loose: apple -: red fruit+: red fruit orange -: orange fruit+: orange fruit banana -: yellow fruit+: yellow fruit Multiple blocks with italics: *apple* -: red fruit+: red fruit - contains seeds, crisp, pleasant to taste+ contains seeds, crisp, pleasant to taste *orange* -: orange fruit+: orange fruit - { orange code block }+ { orange code block } - > orange block quote+ > orange block quote Multiple definitions, tight: apple-: red fruit-: computer+: red fruit+: computer orange-: orange fruit-: bank+: orange fruit+: bank Multiple definitions, loose: apple -: red fruit+: red fruit -: computer+: computer orange -: orange fruit+: orange fruit -: bank+: bank Blank line after term, indented marker, alternate markers: apple -: red fruit+: red fruit -: computer+: computer orange -: orange fruit+: orange fruit - 1. sublist- 2. sublist+ 1. sublist+ 2. sublist # HTML Blocks
test/writer.mediawiki view
@@ -1,6 +1,5 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite. - ----- <span id="headers"></span>@@ -34,7 +33,6 @@ with no blank line - ----- <span id="paragraphs"></span>@@ -49,7 +47,6 @@ There should be a hard line break<br /> here. - ----- <span id="block-quotes"></span>@@ -74,12 +71,12 @@ <blockquote>nested </blockquote> <blockquote>nested-</blockquote></blockquote>+</blockquote>+</blockquote> This should not be a block quote: 2 > 1. And a following paragraph. - ----- <span id="code-blocks"></span>@@ -224,9 +221,7 @@ <li>more items <ol style="list-style-type: upper-alpha;"> <li>a subsublist</li>-<li>a subsublist</li></ol>-</li></ol>-</li></ol>+<li>a subsublist</li></ol></li></ol></li></ol> Nesting: @@ -237,10 +232,7 @@ <ol start="6" style="list-style-type: decimal;"> <li>Decimal start with 6 <ol start="3" style="list-style-type: lower-alpha;">-<li>Lower alpha with paren</li></ol>-</li></ol>-</li></ol>-</li></ol>+<li>Lower alpha with paren</li></ol></li></ol></li></ol></li></ol> Autonumbering: @@ -254,7 +246,6 @@ B. Williams - ----- <span id="definition-lists"></span>@@ -296,7 +287,8 @@ <dt>''orange''</dt> <dd><p>orange fruit</p> <pre>{ orange code block }</pre>-<blockquote><p>orange block quote</p></blockquote></dd></dl>+<blockquote><p>orange block quote</p>+</blockquote></dd></dl> Multiple definitions, tight: @@ -332,31 +324,26 @@ Simple block on one line: <div>- foo- </div>+ And nested without indentation: <div>- <div>- <div>- foo - </div> </div>-<div> +<div> bar- </div> </div>+ Interpreted markdown in a table: <table>@@ -373,11 +360,10 @@ Here’s a simple block: <div>- foo - </div>+ This should be a code block, though: <pre><div>@@ -389,18 +375,15 @@ Now, nested: <div>- <div>- <div>- foo- </div> </div> </div>+ This should just be an HTML comment: <!-- Comment -->@@ -463,7 +446,6 @@ These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d. - ----- <span id="smart-quotes-ellipses-dashes"></span>@@ -485,13 +467,12 @@ Ellipses…and…and…. - ----- <span id="latex"></span> = LaTeX = -* +* * <math display="inline">2+2=4</math> * <math display="inline">x \in y</math> * <math display="inline">\alpha \wedge \omega</math>@@ -509,8 +490,6 @@ Here’s a LaTeX table: -- ----- <span id="special-characters"></span>@@ -566,7 +545,6 @@ Minus: - - ----- <span id="links"></span>@@ -651,12 +629,10 @@ From “Voyage dans la Lune” by Georges Melies (1902): <div class="figure">- [[File:lalune.jpg|lalune]]- </div>-Here is a movie [[File:movie.jpg|movie]] icon. +Here is a movie [[File:movie.jpg|movie]] icon. -----
test/writer.opendocument view
@@ -4,1908 +4,958 @@ <style:font-face style:name="Courier New" style:font-family-generic="modern" style:font-pitch="fixed" svg:font-family="'Courier New'" /> </office:font-face-decls> <office:automatic-styles>- <text:list-style style:name="L1">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L2">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L3">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L4">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L5">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L6">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L7">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L8">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L9">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L10">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L11">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L12">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L13">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L14">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L15">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L16">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L17">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L18">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L19">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L20">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L21">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L22">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="2" style:num-prefix="(" style:num-suffix=")">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="i" text:start-value="4" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="A" text:start-value="1" style:num-prefix="(" style:num-suffix=")">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L23">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="A" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="I" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="6" style:num-prefix="(" style:num-suffix=")">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="a" text:start-value="3" style:num-suffix=")">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L24">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L25">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <text:list-style style:name="L26">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L27">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L28">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L29">- <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="2" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.75in" fo:text-indent="-0.25in" fo:margin-left="0.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="3" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.0in" fo:text-indent="-0.25in" fo:margin-left="1.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="4" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.25in" fo:text-indent="-0.25in" fo:margin-left="1.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="5" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.5in" fo:text-indent="-0.25in" fo:margin-left="1.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="6" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.75in" fo:text-indent="-0.25in" fo:margin-left="1.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="7" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0in" fo:text-indent="-0.25in" fo:margin-left="2.0in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="8" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="◦">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.25in" fo:text-indent="-0.25in" fo:margin-left="2.25in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="9" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="▪">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.5in" fo:text-indent="-0.25in" fo:margin-left="2.5in" />- </style:list-level-properties>- </text:list-level-style-bullet>- <text:list-level-style-bullet text:level="10" text:style-name="Bullet_20_Symbols" style:num-suffix="." text:bullet-char="•">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.75in" fo:text-indent="-0.25in" fo:margin-left="2.75in" />- </style:list-level-properties>- </text:list-level-style-bullet>- </text:list-style>- <text:list-style style:name="L30">- <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" text:start-value="1" style:num-suffix=".">- <style:list-level-properties text:list-level-position-and-space-mode="label-alignment" fo:text-align="right">- <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.5in" fo:text-indent="-0.25in" fo:margin-left="0.5in" />- </style:list-level-properties>- </text:list-level-style-number>- </text:list-style>- <style:style style:name="T1" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>- <style:style style:name="T2" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>- <style:style style:name="T3" style:family="text"><style:text-properties fo:font-style="italic" fo:font-weight="bold" style:font-style-asian="italic" style:font-style-complex="italic" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>- <style:style style:name="T4" style:family="text"><style:text-properties style:text-line-through-style="solid" /></style:style>- <style:style style:name="T5" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-line-through-style="solid" /></style:style>- <style:style style:name="T6" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>- <style:style style:name="T7" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-position="super 58%" /></style:style>- <style:style style:name="T8" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>- <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>- <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>- <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P4" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P5" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P6" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L1">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P7" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="1.0in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P8" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="1.0in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P9" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P10" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P11" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P12" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P13" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P14" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P15" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P16" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P17" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P18" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P19" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L2">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P20" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L3">- </style:style>- <style:style style:name="P21" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L4">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P22" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L5">- </style:style>- <style:style style:name="P23" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L6">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P24" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L7">- </style:style>- <style:style style:name="P25" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L8">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P26" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L9">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P27" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L10">- </style:style>- <style:style style:name="P28" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L11">- </style:style>- <style:style style:name="P29" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L12">- </style:style>- <style:style style:name="P30" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L13">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P31" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L14">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P32" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L15">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P33" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L16">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P34" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L17">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P35" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L18">- </style:style>- <style:style style:name="P36" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L19">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P37" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L20">- </style:style>- <style:style style:name="P38" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L21">- </style:style>- <style:style style:name="P39" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L22">- </style:style>- <style:style style:name="P40" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L23">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P41" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L24">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P42" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P43" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P44" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L25">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P45" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P46" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P47" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P48" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P49" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P50" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P51" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L26">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P52" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L27">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P53" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L28">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P54" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P55" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L29">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- <style:style style:name="P56" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P57" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P58" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">- </style:style>- <style:style style:name="P59" style:family="paragraph" style:parent-style-name="Quotations">- <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />- </style:style>- <style:style style:name="P60" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="L30">- <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" />- </style:style>- </office:automatic-styles>-<office:body>-<office:text>-<text:p text:style-name="Title">Pandoc Test Suite</text:p>-<text:p text:style-name="Author">John MacFarlane</text:p>-<text:p text:style-name="Author">Anonymous</text:p>-<text:p text:style-name="Date">July 17, 2006</text:p>-<text:p text:style-name="Text_20_body">This is a set of tests for pandoc. Most-of them are adapted from John Gruber’s markdown test suite.</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="headers" />Headers<text:bookmark-end text:name="headers" /></text:h>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-an-embedded-link" />Level-2 with an-<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">embedded-link</text:span></text:a><text:bookmark-end text:name="level-2-with-an-embedded-link" /></text:h>-<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3-with-emphasis" />Level-3 with-<text:span text:style-name="T1">emphasis</text:span><text:bookmark-end text:name="level-3-with-emphasis" /></text:h>-<text:h text:style-name="Heading_20_4" text:outline-level="4"><text:bookmark-start text:name="level-4" />Level-4<text:bookmark-end text:name="level-4" /></text:h>-<text:h text:style-name="Heading_20_5" text:outline-level="5"><text:bookmark-start text:name="level-5" />Level-5<text:bookmark-end text:name="level-5" /></text:h>-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="level-1" />Level-1<text:bookmark-end text:name="level-1" /></text:h>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-emphasis" />Level-2 with-<text:span text:style-name="T1">emphasis</text:span><text:bookmark-end text:name="level-2-with-emphasis" /></text:h>-<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3" />Level-3<text:bookmark-end text:name="level-3" /></text:h>-<text:p text:style-name="First_20_paragraph">with no blank line</text:p>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2" />Level-2<text:bookmark-end text:name="level-2" /></text:h>-<text:p text:style-name="First_20_paragraph">with no blank line</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="paragraphs" />Paragraphs<text:bookmark-end text:name="paragraphs" /></text:h>-<text:p text:style-name="First_20_paragraph">Here’s a regular-paragraph.</text:p>-<text:p text:style-name="Text_20_body">In Markdown 1.0.0 and earlier. Version 8.-This line turns into a list item. Because a hard-wrapped line in the middle of a-paragraph looked like a list item.</text:p>-<text:p text:style-name="Text_20_body">Here’s one with a bullet. *-criminey.</text:p>-<text:p text:style-name="Text_20_body">There should be a hard line-break<text:line-break />here.</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="block-quotes" />Block-Quotes<text:bookmark-end text:name="block-quotes" /></text:h>-<text:p text:style-name="First_20_paragraph">E-mail style:</text:p>-<text:p text:style-name="P1">This is a block quote. It is pretty short.</text:p>-<text:p text:style-name="P2">Code in a block quote:</text:p>-<text:p text:style-name="P3">sub status {</text:p>-<text:p text:style-name="P4"><text:s text:c="4" />print "working";</text:p>-<text:p text:style-name="P5">}</text:p>-<text:p text:style-name="P2">A list:</text:p>-<text:list text:style-name="L1">- <text:list-item>- <text:p text:style-name="P6">item one</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P6">item two</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="P2">Nested block quotes:</text:p>-<text:p text:style-name="P7">nested</text:p>-<text:p text:style-name="P8">nested</text:p>-<text:p text:style-name="First_20_paragraph">This should not be a block quote: 2-> 1.</text:p>-<text:p text:style-name="Text_20_body">And a following paragraph.</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="code-blocks" />Code-Blocks<text:bookmark-end text:name="code-blocks" /></text:h>-<text:p text:style-name="First_20_paragraph">Code:</text:p>-<text:p text:style-name="P9">---- (should be four hyphens)</text:p>-<text:p text:style-name="P10"></text:p>-<text:p text:style-name="P11">sub status {</text:p>-<text:p text:style-name="P12"><text:s text:c="4" />print "working";</text:p>-<text:p text:style-name="P13">}</text:p>-<text:p text:style-name="P14"></text:p>-<text:p text:style-name="P15">this code block is indented by one tab</text:p>-<text:p text:style-name="First_20_paragraph">And:</text:p>-<text:p text:style-name="P16"><text:s text:c="4" />this code block is indented by two tabs</text:p>-<text:p text:style-name="P17"></text:p>-<text:p text:style-name="P18">These should not be escaped: <text:s text:c="1" />\$ \\ \> \[ \{</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="lists" />Lists<text:bookmark-end text:name="lists" /></text:h>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="unordered" />Unordered<text:bookmark-end text:name="unordered" /></text:h>-<text:p text:style-name="First_20_paragraph">Asterisks tight:</text:p>-<text:list text:style-name="L2">- <text:list-item>- <text:p text:style-name="P19">asterisk 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P19">asterisk 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P19">asterisk 3</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Asterisks loose:</text:p>-<text:list text:style-name="L3">- <text:list-item>- <text:p text:style-name="P20">asterisk 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P20">asterisk 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P20">asterisk 3</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Pluses tight:</text:p>-<text:list text:style-name="L4">- <text:list-item>- <text:p text:style-name="P21">Plus 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P21">Plus 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P21">Plus 3</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Pluses loose:</text:p>-<text:list text:style-name="L5">- <text:list-item>- <text:p text:style-name="P22">Plus 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P22">Plus 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P22">Plus 3</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Minuses tight:</text:p>-<text:list text:style-name="L6">- <text:list-item>- <text:p text:style-name="P23">Minus 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P23">Minus 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P23">Minus 3</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Minuses loose:</text:p>-<text:list text:style-name="L7">- <text:list-item>- <text:p text:style-name="P24">Minus 1</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P24">Minus 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P24">Minus 3</text:p>- </text:list-item>-</text:list>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="ordered" />Ordered<text:bookmark-end text:name="ordered" /></text:h>-<text:p text:style-name="First_20_paragraph">Tight:</text:p>-<text:list text:style-name="L8">- <text:list-item>- <text:p text:style-name="P25">First</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P25">Second</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P25">Third</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">and:</text:p>-<text:list text:style-name="L9">- <text:list-item>- <text:p text:style-name="P26">One</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P26">Two</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P26">Three</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Loose using tabs:</text:p>-<text:list text:style-name="L10">- <text:list-item>- <text:p text:style-name="P27">First</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P27">Second</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P27">Third</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">and using spaces:</text:p>-<text:list text:style-name="L11">- <text:list-item>- <text:p text:style-name="P28">One</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P28">Two</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P28">Three</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Multiple paragraphs:</text:p>-<text:list text:style-name="L12">- <text:list-item>- <text:p text:style-name="P29">Item 1, graf one.</text:p>- <text:p text:style-name="P29">Item 1. graf two. The quick brown fox jumped- over the lazy dog’s back.</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P29">Item 2.</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P29">Item 3.</text:p>- </text:list-item>-</text:list>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="nested" />Nested<text:bookmark-end text:name="nested" /></text:h>-<text:list text:style-name="L13">- <text:list-item>- <text:p text:style-name="P30">Tab</text:p><text:list text:style-name="L14">- <text:list-item>- <text:p text:style-name="P31">Tab</text:p><text:list text:style-name="L15">- <text:list-item>- <text:p text:style-name="P32">Tab</text:p>- </text:list-item>- </text:list>- </text:list-item>- </text:list>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Here’s another:</text:p>-<text:list text:style-name="L16">- <text:list-item>- <text:p text:style-name="P33">First</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P33">Second:</text:p>- <text:list text:style-name="L17">- <text:list-item>- <text:p text:style-name="P34">Fee</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P34">Fie</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P34">Foe</text:p>- </text:list-item>- </text:list>- </text:list-item>- <text:list-item>- <text:p text:style-name="P33">Third</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Same thing but with-paragraphs:</text:p>-<text:list text:style-name="L18">- <text:list-item>- <text:p text:style-name="P35">First</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P35">Second:</text:p>- <text:list text:style-name="L19">- <text:list-item>- <text:p text:style-name="P36">Fee</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P36">Fie</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P36">Foe</text:p>- </text:list-item>- </text:list>- </text:list-item>- <text:list-item>- <text:p text:style-name="P35">Third</text:p>- </text:list-item>-</text:list>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="tabs-and-spaces" />Tabs-and spaces<text:bookmark-end text:name="tabs-and-spaces" /></text:h>-<text:list text:style-name="L20">- <text:list-item>- <text:p text:style-name="P37">this is a list item indented with- tabs</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P37">this is a list item indented with- spaces</text:p><text:list text:style-name="L21">- <text:list-item>- <text:p text:style-name="P38">this is an example list item indented with- tabs</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P38">this is an example list item indented with- spaces</text:p>- </text:list-item>- </text:list>- </text:list-item>-</text:list>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="fancy-list-markers" />Fancy-list markers<text:bookmark-end text:name="fancy-list-markers" /></text:h>-<text:list text:style-name="L22">- <text:list-item>- <text:p text:style-name="P39">begins with 2</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P39">and now 3</text:p>- <text:p text:style-name="P39">with a continuation</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P39">sublist with roman numerals, starting with- 4</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P39">more items</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P39">a subsublist</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P39">a subsublist</text:p>- </text:list-item>- </text:list>- </text:list-item>- </text:list>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Nesting:</text:p>-<text:list text:style-name="L23">- <text:list-item>- <text:p text:style-name="P40">Upper Alpha</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P40">Upper Roman.</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P40">Decimal start with 6</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P40">Lower alpha with paren</text:p>- </text:list-item>- </text:list>- </text:list-item>- </text:list>- </text:list-item>- </text:list>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Autonumbering:</text:p>-<text:list text:style-name="L24">- <text:list-item>- <text:p text:style-name="P41">Autonumber.</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P41">More.</text:p>- <text:list>- <text:list-item>- <text:p text:style-name="P41">Nested.</text:p>- </text:list-item>- </text:list>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Should not be a list item:</text:p>-<text:p text:style-name="Text_20_body">M.A. 2007</text:p>-<text:p text:style-name="Text_20_body">B. Williams</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="definition-lists" />Definition-Lists<text:bookmark-end text:name="definition-lists" /></text:h>-<text:p text:style-name="First_20_paragraph">Tight using spaces:</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">orange-fruit</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">banana</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">yellow-fruit</text:p>-<text:p text:style-name="First_20_paragraph">Tight using tabs:</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">orange-fruit</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">banana</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">yellow-fruit</text:p>-<text:p text:style-name="First_20_paragraph">Loose:</text:p>-<text:p text:style-name="Definition_20_Term">apple</text:p>-<text:p text:style-name="Definition_20_Definition">red fruit</text:p>-<text:p text:style-name="Definition_20_Term">orange</text:p>-<text:p text:style-name="Definition_20_Definition">orange fruit</text:p>-<text:p text:style-name="Definition_20_Term">banana</text:p>-<text:p text:style-name="Definition_20_Definition">yellow fruit</text:p>-<text:p text:style-name="First_20_paragraph">Multiple blocks with-italics:</text:p>-<text:p text:style-name="Definition_20_Term"><text:span text:style-name="T1">apple</text:span></text:p>-<text:p text:style-name="Definition_20_Definition">red-fruit</text:p><text:p text:style-name="Definition_20_Definition">contains seeds,-crisp, pleasant to taste</text:p>-<text:p text:style-name="Definition_20_Term"><text:span text:style-name="T1">orange</text:span></text:p>-<text:p text:style-name="Definition_20_Definition">orange-fruit</text:p><text:p text:style-name="P42">{ orange code block }</text:p><text:p text:style-name="P43">orange-block quote</text:p>-<text:p text:style-name="First_20_paragraph">Multiple definitions,-tight:</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">computer</text:p>-<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">orange-fruit</text:p>-<text:p text:style-name="Definition_20_Definition_20_Tight">bank</text:p>-<text:p text:style-name="First_20_paragraph">Multiple definitions,-loose:</text:p>-<text:p text:style-name="Definition_20_Term">apple</text:p>-<text:p text:style-name="Definition_20_Definition">red fruit</text:p>-<text:p text:style-name="Definition_20_Definition">computer</text:p>-<text:p text:style-name="Definition_20_Term">orange</text:p>-<text:p text:style-name="Definition_20_Definition">orange fruit</text:p>-<text:p text:style-name="Definition_20_Definition">bank</text:p>-<text:p text:style-name="First_20_paragraph">Blank line after term, indented-marker, alternate markers:</text:p>-<text:p text:style-name="Definition_20_Term">apple</text:p>-<text:p text:style-name="Definition_20_Definition">red fruit</text:p>-<text:p text:style-name="Definition_20_Definition">computer</text:p>-<text:p text:style-name="Definition_20_Term">orange</text:p>-<text:p text:style-name="Definition_20_Definition">orange-fruit</text:p><text:list text:style-name="L25">- <text:list-item>- <text:p text:style-name="P44">sublist</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P44">sublist</text:p>- </text:list-item>-</text:list>-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="html-blocks" />HTML-Blocks<text:bookmark-end text:name="html-blocks" /></text:h>-<text:p text:style-name="First_20_paragraph">Simple block on one line:</text:p>-<text:p text:style-name="Text_20_body">foo</text:p>-<text:p text:style-name="Text_20_body">And nested without indentation:</text:p>-<text:p text:style-name="Text_20_body">foo</text:p>-<text:p text:style-name="Text_20_body">bar</text:p>-<text:p text:style-name="Text_20_body">Interpreted markdown in a table:</text:p>-<text:p text:style-name="Text_20_body">This is-<text:span text:style-name="T1">emphasized</text:span></text:p>-<text:p text:style-name="Text_20_body">And this is-<text:span text:style-name="T2">strong</text:span></text:p>-<text:p text:style-name="Text_20_body">Here’s a simple block:</text:p>-<text:p text:style-name="Text_20_body">foo</text:p>-<text:p text:style-name="Text_20_body">This should be a code block,-though:</text:p>-<text:p text:style-name="P45"><div></text:p>-<text:p text:style-name="P46"><text:s text:c="4" />foo</text:p>-<text:p text:style-name="P47"></div></text:p>-<text:p text:style-name="First_20_paragraph">As should this:</text:p>-<text:p text:style-name="P48"><div>foo</div></text:p>-<text:p text:style-name="First_20_paragraph">Now, nested:</text:p>-<text:p text:style-name="Text_20_body">foo</text:p>-<text:p text:style-name="Text_20_body">This should just be an HTML-comment:</text:p>-<text:p text:style-name="Text_20_body">Multiline:</text:p>-<text:p text:style-name="Text_20_body">Code block:</text:p>-<text:p text:style-name="P49"><!-- Comment --></text:p>-<text:p text:style-name="First_20_paragraph">Just plain comment, with trailing-spaces on the line:</text:p>-<text:p text:style-name="Text_20_body">Code:</text:p>-<text:p text:style-name="P50"><hr /></text:p>-<text:p text:style-name="First_20_paragraph">Hr’s:</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="inline-markup" />Inline-Markup<text:bookmark-end text:name="inline-markup" /></text:h>-<text:p text:style-name="First_20_paragraph">This is-<text:span text:style-name="T1">emphasized</text:span>, and so-<text:span text:style-name="T1">is this</text:span>.</text:p>-<text:p text:style-name="Text_20_body">This is-<text:span text:style-name="T2">strong</text:span>, and so-<text:span text:style-name="T2">is this</text:span>.</text:p>-<text:p text:style-name="Text_20_body">An-<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition"><text:span text:style-name="T1">emphasized-link</text:span></text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:span text:style-name="T3">This is-strong and em.</text:span></text:p>-<text:p text:style-name="Text_20_body">So is-<text:span text:style-name="T3">this</text:span> word.</text:p>-<text:p text:style-name="Text_20_body"><text:span text:style-name="T3">This is-strong and em.</text:span></text:p>-<text:p text:style-name="Text_20_body">So is-<text:span text:style-name="T3">this</text:span> word.</text:p>-<text:p text:style-name="Text_20_body">This is code:-<text:span text:style-name="Source_Text">></text:span>,-<text:span text:style-name="Source_Text">$</text:span>,-<text:span text:style-name="Source_Text">\</text:span>,-<text:span text:style-name="Source_Text">\$</text:span>,-<text:span text:style-name="Source_Text"><html></text:span>.</text:p>-<text:p text:style-name="Text_20_body"><text:span text:style-name="T4">This is-</text:span><text:span text:style-name="T5">strikeout</text:span><text:span text:style-name="T4">.</text:span></text:p>-<text:p text:style-name="Text_20_body">Superscripts:-a<text:span text:style-name="T6">bc</text:span>d-a<text:span text:style-name="T7">hello</text:span>-a<text:span text:style-name="T6">hello there</text:span>.</text:p>-<text:p text:style-name="Text_20_body">Subscripts:-H<text:span text:style-name="T8">2</text:span>O,-H<text:span text:style-name="T8">23</text:span>O,-H<text:span text:style-name="T8">many of them</text:span>O.</text:p>-<text:p text:style-name="Text_20_body">These should not be superscripts or-subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="smart-quotes-ellipses-dashes" />Smart-quotes, ellipses,-dashes<text:bookmark-end text:name="smart-quotes-ellipses-dashes" /></text:h>-<text:p text:style-name="First_20_paragraph">“Hello,” said the spider. “‘Shelob’-is my name.”</text:p>-<text:p text:style-name="Text_20_body">‘A’, ‘B’, and ‘C’ are letters.</text:p>-<text:p text:style-name="Text_20_body">‘Oak,’ ‘elm,’ and ‘beech’ are names of-trees. So is ‘pine.’</text:p>-<text:p text:style-name="Text_20_body">‘He said, “I want to go.”’ Were you alive-in the 70’s?</text:p>-<text:p text:style-name="Text_20_body">Here is some quoted-‘<text:span text:style-name="Source_Text">code</text:span>’ and a-“<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">quoted-link</text:span></text:a>”.</text:p>-<text:p text:style-name="Text_20_body">Some dashes: one—two — three—four —-five.</text:p>-<text:p text:style-name="Text_20_body">Dashes between numbers: 5–7, 255–66,-1987–1999.</text:p>-<text:p text:style-name="Text_20_body">Ellipses…and…and….</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="latex" />LaTeX<text:bookmark-end text:name="latex" /></text:h>-<text:list text:style-name="L26">- <text:list-item>- <text:p text:style-name="P51"></text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51">2 + 2 = 4</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51"><text:span text:style-name="T1">x</text:span> ∈ <text:span text:style-name="T1">y</text:span></text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51"><text:span text:style-name="T1">α</text:span> ∧ <text:span text:style-name="T1">ω</text:span></text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51">223</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51"><text:span text:style-name="T1">p</text:span>-Tree</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51">Here’s some display math:- $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P51">Here’s one that has a line break in it:- <text:span text:style-name="T1">α</text:span> + <text:span text:style-name="T1">ω</text:span> × <text:span text:style-name="T1">x</text:span><text:span text:style-name="T6">2</text:span>.</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">These shouldn’t be math:</text:p>-<text:list text:style-name="L27">- <text:list-item>- <text:p text:style-name="P52">To get the famous equation, write- <text:span text:style-name="Source_Text">$e = mc^2$</text:span>.</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P52">$22,000 is a- <text:span text:style-name="T1">lot</text:span> of money. So is $34,000. (It- worked if “lot” is emphasized.)</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P52">Shoes ($20) and socks ($5).</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P52">Escaped- <text:span text:style-name="Source_Text">$</text:span>: $73- <text:span text:style-name="T1">this should be emphasized</text:span>- 23$.</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">Here’s a LaTeX table:</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="special-characters" />Special-Characters<text:bookmark-end text:name="special-characters" /></text:h>-<text:p text:style-name="First_20_paragraph">Here is some unicode:</text:p>-<text:list text:style-name="L28">- <text:list-item>- <text:p text:style-name="P53">I hat: Î</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P53">o umlaut: ö</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P53">section: §</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P53">set membership: ∈</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P53">copyright: ©</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">AT&T has an ampersand in their-name.</text:p>-<text:p text:style-name="Text_20_body">AT&T is another way to write-it.</text:p>-<text:p text:style-name="Text_20_body">This & that.</text:p>-<text:p text:style-name="Text_20_body">4 < 5.</text:p>-<text:p text:style-name="Text_20_body">6 > 5.</text:p>-<text:p text:style-name="Text_20_body">Backslash: \</text:p>-<text:p text:style-name="Text_20_body">Backtick: `</text:p>-<text:p text:style-name="Text_20_body">Asterisk: *</text:p>-<text:p text:style-name="Text_20_body">Underscore: _</text:p>-<text:p text:style-name="Text_20_body">Left brace: {</text:p>-<text:p text:style-name="Text_20_body">Right brace: }</text:p>-<text:p text:style-name="Text_20_body">Left bracket: [</text:p>-<text:p text:style-name="Text_20_body">Right bracket: ]</text:p>-<text:p text:style-name="Text_20_body">Left paren: (</text:p>-<text:p text:style-name="Text_20_body">Right paren: )</text:p>-<text:p text:style-name="Text_20_body">Greater-than: ></text:p>-<text:p text:style-name="Text_20_body">Hash: #</text:p>-<text:p text:style-name="Text_20_body">Period: .</text:p>-<text:p text:style-name="Text_20_body">Bang: !</text:p>-<text:p text:style-name="Text_20_body">Plus: +</text:p>-<text:p text:style-name="Text_20_body">Minus: -</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="links" />Links<text:bookmark-end text:name="links" /></text:h>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="explicit" />Explicit<text:bookmark-end text:name="explicit" /></text:h>-<text:p text:style-name="First_20_paragraph">Just a-<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">URL</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title"><text:span text:style-name="Definition">URL-and title</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title preceded by two spaces"><text:span text:style-name="Definition">URL-and title</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title preceded by a tab"><text:span text:style-name="Definition">URL-and title</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title with "quotes" in it"><text:span text:style-name="Definition">URL-and title</text:span></text:a></text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title with single quotes"><text:span text:style-name="Definition">URL-and title</text:span></text:a></text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/with_underscore" office:name=""><text:span text:style-name="Definition">with_underscore</text:span></text:a></text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="mailto:nobody@nowhere.net" office:name=""><text:span text:style-name="Definition">Email-link</text:span></text:a></text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="" office:name=""><text:span text:style-name="Definition">Empty</text:span></text:a>.</text:p>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="reference" />Reference<text:bookmark-end text:name="reference" /></text:h>-<text:p text:style-name="First_20_paragraph">Foo-<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">With-<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">embedded-[brackets]</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">b</text:span></text:a>-by itself should be a link.</text:p>-<text:p text:style-name="Text_20_body">Indented-<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">once</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Indented-<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">twice</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Indented-<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">thrice</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">This should [not][] be a link.</text:p>-<text:p text:style-name="P54">[not]: /url</text:p>-<text:p text:style-name="First_20_paragraph">Foo-<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with "quotes" inside"><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Foo-<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with "quote" inside"><text:span text:style-name="Definition">biz</text:span></text:a>.</text:p>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="with-ampersands" />With-ampersands<text:bookmark-end text:name="with-ampersands" /></text:h>-<text:p text:style-name="First_20_paragraph">Here’s a-<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">link-with an ampersand in the URL</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Here’s a link with an amersand in the-link text:-<text:a xlink:type="simple" xlink:href="http://att.com/" office:name="AT&T"><text:span text:style-name="Definition">AT&T</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Here’s an-<text:a xlink:type="simple" xlink:href="/script?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">inline-link</text:span></text:a>.</text:p>-<text:p text:style-name="Text_20_body">Here’s an-<text:a xlink:type="simple" xlink:href="/script?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">inline-link in pointy braces</text:span></text:a>.</text:p>-<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="autolinks" />Autolinks<text:bookmark-end text:name="autolinks" /></text:h>-<text:p text:style-name="First_20_paragraph">With an ampersand:-<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">http://example.com/?foo=1&bar=2</text:span></text:a></text:p>-<text:list text:style-name="L29">- <text:list-item>- <text:p text:style-name="P55">In a list?</text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P55"><text:a xlink:type="simple" xlink:href="http://example.com/" office:name=""><text:span text:style-name="Definition">http://example.com/</text:span></text:a></text:p>- </text:list-item>- <text:list-item>- <text:p text:style-name="P55">It should.</text:p>- </text:list-item>-</text:list>-<text:p text:style-name="First_20_paragraph">An e-mail address:-<text:a xlink:type="simple" xlink:href="mailto:nobody@nowhere.net" office:name=""><text:span text:style-name="Definition">nobody@nowhere.net</text:span></text:a></text:p>-<text:p text:style-name="P56">Blockquoted:-<text:a xlink:type="simple" xlink:href="http://example.com/" office:name=""><text:span text:style-name="Definition">http://example.com/</text:span></text:a></text:p>-<text:p text:style-name="First_20_paragraph">Auto-links should not occur here:-<text:span text:style-name="Source_Text"><http://example.com/></text:span></text:p>-<text:p text:style-name="P57">or here: <http://example.com/></text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="images" />Images<text:bookmark-end text:name="images" /></text:h>-<text:p text:style-name="First_20_paragraph">From “Voyage dans la Lune” by-Georges Melies (1902):</text:p>-<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>-<text:p text:style-name="FigureCaption">lalune</text:p>-<text:p text:style-name="Text_20_body">Here is a movie-<draw:frame draw:name="img2"><draw:image xlink:href="movie.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame>-icon.</text:p>-<text:p text:style-name="Horizontal_20_Line" />-<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="footnotes" />Footnotes<text:bookmark-end text:name="footnotes" /></text:h>-<text:p text:style-name="First_20_paragraph">Here is a footnote-reference,<text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here-is the footnote. It can go anywhere after the footnote reference. It need not be-placed at the end of the document.</text:p></text:note-body></text:note> and-another.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>2</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here’s-the long note. This one contains multiple-blocks.</text:p><text:p text:style-name="Footnote">Subsequent blocks are-indented to show that they belong to the footnote (as with list-items).</text:p><text:p text:style-name="P58"><text:s text:c="2" />{ <code> }</text:p><text:p text:style-name="Footnote">If-you want, you can indent every line, but you can also be lazy and just indent-the first line of each block.</text:p></text:note-body></text:note> This should-<text:span text:style-name="T1">not</text:span> be a footnote reference, because-it contains a space.[^my note] Here is an inline-note.<text:note text:id="ftn2" text:note-class="footnote"><text:note-citation>3</text:note-citation><text:note-body><text:p text:style-name="Footnote">This-is <text:span text:style-name="T1">easier</text:span> to type. Inline notes may-contain-<text:a xlink:type="simple" xlink:href="http://google.com" office:name=""><text:span text:style-name="Definition">links</text:span></text:a>-and <text:span text:style-name="Source_Text">]</text:span> verbatim characters,-as well as [bracketed text].</text:p></text:note-body></text:note></text:p>-<text:p text:style-name="P59">Notes can go in-quotes.<text:note text:id="ftn3" text:note-class="footnote"><text:note-citation>4</text:note-citation><text:note-body><text:p text:style-name="Footnote">In-quote.</text:p></text:note-body></text:note></text:p>-<text:list text:style-name="L30">- <text:list-item>- <text:p text:style-name="P60">And in list+ <style:style style:name="T1" style:family="text"><style:text-properties fo:font-style="italic" fo:font-weight="bold" style:font-style-asian="italic" style:font-style-complex="italic" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>+ <style:style style:name="T2" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-line-through-style="solid" /></style:style>+ <style:style style:name="T3" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-position="super 58%" /></style:style>+ <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Quotations">+ <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />+ </style:style>+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Quotations">+ <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />+ </style:style>+ <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Quotations">+ <style:paragraph-properties fo:margin-left="0.5in" fo:margin-right="0in" fo:text-indent="0in" style:auto-text-indent="false" />+ </style:style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_1">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="1" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_2">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="i" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_5">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="I" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_6">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="a" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_4">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-suffix=".">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ <text:list-style style:name="Pandoc_5f_Numbering_5f_3">+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.0000in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.1972in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.3944in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.5916in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.7888in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="0.9860in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.1832in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.3804in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.5776in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" style:num-format="A" style:num-prefix="(" style:num-suffix=")">+ <style:list-level-properties text:space-before="1.7748in" text:min-label-width="0.1965in" text:min-label-distance="0.1in" />+ </text:list-level-style-number>+ </text:list-style>+ </office:automatic-styles>+<office:body>+<office:text>+<text:p text:style-name="Title">Pandoc Test Suite</text:p>+<text:p text:style-name="Author">John MacFarlane</text:p>+<text:p text:style-name="Author">Anonymous</text:p>+<text:p text:style-name="Date">July 17, 2006</text:p>+<text:p text:style-name="Text_20_body">This is a set of tests for pandoc. Most+of them are adapted from John Gruber’s markdown test suite.</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="headers" />Headers<text:bookmark-end text:name="headers" /></text:h>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-an-embedded-link" />Level+2 with an+<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">embedded+link</text:span></text:a><text:bookmark-end text:name="level-2-with-an-embedded-link" /></text:h>+<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3-with-emphasis" />Level+3 with+<text:span text:style-name="Emphasis">emphasis</text:span><text:bookmark-end text:name="level-3-with-emphasis" /></text:h>+<text:h text:style-name="Heading_20_4" text:outline-level="4"><text:bookmark-start text:name="level-4" />Level+4<text:bookmark-end text:name="level-4" /></text:h>+<text:h text:style-name="Heading_20_5" text:outline-level="5"><text:bookmark-start text:name="level-5" />Level+5<text:bookmark-end text:name="level-5" /></text:h>+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="level-1" />Level+1<text:bookmark-end text:name="level-1" /></text:h>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2-with-emphasis" />Level+2 with+<text:span text:style-name="Emphasis">emphasis</text:span><text:bookmark-end text:name="level-2-with-emphasis" /></text:h>+<text:h text:style-name="Heading_20_3" text:outline-level="3"><text:bookmark-start text:name="level-3" />Level+3<text:bookmark-end text:name="level-3" /></text:h>+<text:p text:style-name="First_20_paragraph">with no blank line</text:p>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="level-2" />Level+2<text:bookmark-end text:name="level-2" /></text:h>+<text:p text:style-name="First_20_paragraph">with no blank line</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="paragraphs" />Paragraphs<text:bookmark-end text:name="paragraphs" /></text:h>+<text:p text:style-name="First_20_paragraph">Here’s a regular+paragraph.</text:p>+<text:p text:style-name="Text_20_body">In Markdown 1.0.0 and earlier. Version 8.+This line turns into a list item. Because a hard-wrapped line in the middle of a+paragraph looked like a list item.</text:p>+<text:p text:style-name="Text_20_body">Here’s one with a bullet. *+criminey.</text:p>+<text:p text:style-name="Text_20_body">There should be a hard line+break<text:line-break />here.</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="block-quotes" />Block+Quotes<text:bookmark-end text:name="block-quotes" /></text:h>+<text:p text:style-name="First_20_paragraph">E-mail style:</text:p>+<text:p text:style-name="Quotations">This is a block quote. It is pretty+short.</text:p>+<text:p text:style-name="Quotations">Code in a block quote:</text:p>+<text:p text:style-name="Preformatted_20_Text">sub status {</text:p>+<text:p text:style-name="Preformatted_20_Text"><text:s text:c="4" />print "working";</text:p>+<text:p text:style-name="Preformatted_20_Text">}</text:p>+<text:p text:style-name="Quotations">A list:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">item one</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">item two</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="Quotations">Nested block quotes:</text:p>+<text:p text:style-name="P1">nested</text:p>+<text:p text:style-name="P2">nested</text:p>+<text:p text:style-name="First_20_paragraph">This should not be a block quote: 2+> 1.</text:p>+<text:p text:style-name="Text_20_body">And a following paragraph.</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="code-blocks" />Code+Blocks<text:bookmark-end text:name="code-blocks" /></text:h>+<text:p text:style-name="First_20_paragraph">Code:</text:p>+<text:p text:style-name="Preformatted_20_Text">---- (should be four hyphens)</text:p>+<text:p text:style-name="Preformatted_20_Text"></text:p>+<text:p text:style-name="Preformatted_20_Text">sub status {</text:p>+<text:p text:style-name="Preformatted_20_Text"><text:s text:c="4" />print "working";</text:p>+<text:p text:style-name="Preformatted_20_Text">}</text:p>+<text:p text:style-name="Preformatted_20_Text"></text:p>+<text:p text:style-name="Preformatted_20_Text">this code block is indented by one tab</text:p>+<text:p text:style-name="First_20_paragraph">And:</text:p>+<text:p text:style-name="Preformatted_20_Text"><text:s text:c="4" />this code block is indented by two tabs</text:p>+<text:p text:style-name="Preformatted_20_Text"></text:p>+<text:p text:style-name="Preformatted_20_Text">These should not be escaped: <text:s text:c="1" />\$ \\ \> \[ \{</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="lists" />Lists<text:bookmark-end text:name="lists" /></text:h>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="unordered" />Unordered<text:bookmark-end text:name="unordered" /></text:h>+<text:p text:style-name="First_20_paragraph">Asterisks tight:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">asterisk 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">asterisk 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">asterisk 3</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Asterisks loose:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">asterisk 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">asterisk 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">asterisk 3</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Pluses tight:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Plus 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Plus 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Plus 3</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Pluses loose:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Plus 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Plus 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Plus 3</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Minuses tight:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Minus 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Minus 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Minus 3</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Minuses loose:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Minus 1</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Minus 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">Minus 3</text:p>+ </text:list-item>+</text:list>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="ordered" />Ordered<text:bookmark-end text:name="ordered" /></text:h>+<text:p text:style-name="First_20_paragraph">Tight:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">First</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Second</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Third</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">and:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">One</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Two</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Three</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Loose using tabs:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number">First</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Second</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Third</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">and using spaces:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number">One</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Two</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Three</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Multiple paragraphs:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number">Item 1, graf one.</text:p>+ <text:p text:style-name="List_20_Number">Item 1. graf two. The quick brown+ fox jumped over the lazy dog’s back.</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Item 2.</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Item 3.</text:p>+ </text:list-item>+</text:list>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="nested" />Nested<text:bookmark-end text:name="nested" /></text:h>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Tab</text:p><text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Tab</text:p><text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Tab</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+ </text:list>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Here’s another:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">First</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Second:</text:p>+ <text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Fee</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Fie</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Foe</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Third</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Same thing but with+paragraphs:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number">First</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Second:</text:p>+ <text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Fee</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Fie</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Foe</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">Third</text:p>+ </text:list-item>+</text:list>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="tabs-and-spaces" />Tabs+and spaces<text:bookmark-end text:name="tabs-and-spaces" /></text:h>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">this is a list item indented with+ tabs</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">this is a list item indented with+ spaces</text:p><text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">this is an example list item+ indented with tabs</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet">this is an example list item+ indented with spaces</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+</text:list>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="fancy-list-markers" />Fancy+list markers<text:bookmark-end text:name="fancy-list-markers" /></text:h>+<text:list text:style-name="Pandoc_5f_Numbering_5f_1" text:start-value="2">+ <text:list-item>+ <text:p text:style-name="List_20_Number">begins with 2</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number">and now 3</text:p>+ <text:p text:style-name="List_20_Number">with a continuation</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_2" text:start-value="4">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">sublist with roman+ numerals, starting with 4</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">more items</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_3">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">a+ subsublist</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">a+ subsublist</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+ </text:list>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Nesting:</text:p>+<text:list text:style-name="Pandoc_5f_Numbering_5f_4">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Upper Alpha</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_5">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Upper Roman.</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_1" text:start-value="6">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Decimal start with+ 6</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_6" text:start-value="3">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Lower alpha+ with paren</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+ </text:list>+ </text:list-item>+ </text:list>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Autonumbering:</text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Autonumber.</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">More.</text:p>+ <text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">Nested.</text:p>+ </text:list-item>+ </text:list>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Should not be a list item:</text:p>+<text:p text:style-name="Text_20_body">M.A. 2007</text:p>+<text:p text:style-name="Text_20_body">B. Williams</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="definition-lists" />Definition+Lists<text:bookmark-end text:name="definition-lists" /></text:h>+<text:p text:style-name="First_20_paragraph">Tight using spaces:</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">orange+fruit</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">banana</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">yellow+fruit</text:p>+<text:p text:style-name="First_20_paragraph">Tight using tabs:</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">orange+fruit</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">banana</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">yellow+fruit</text:p>+<text:p text:style-name="First_20_paragraph">Loose:</text:p>+<text:p text:style-name="Definition_20_Term">apple</text:p>+<text:p text:style-name="Definition_20_Definition">red fruit</text:p>+<text:p text:style-name="Definition_20_Term">orange</text:p>+<text:p text:style-name="Definition_20_Definition">orange fruit</text:p>+<text:p text:style-name="Definition_20_Term">banana</text:p>+<text:p text:style-name="Definition_20_Definition">yellow fruit</text:p>+<text:p text:style-name="First_20_paragraph">Multiple blocks with+italics:</text:p>+<text:p text:style-name="Definition_20_Term"><text:span text:style-name="Emphasis">apple</text:span></text:p>+<text:p text:style-name="Definition_20_Definition">red+fruit</text:p><text:p text:style-name="Definition_20_Definition">contains seeds,+crisp, pleasant to taste</text:p>+<text:p text:style-name="Definition_20_Term"><text:span text:style-name="Emphasis">orange</text:span></text:p>+<text:p text:style-name="Definition_20_Definition">orange+fruit</text:p><text:p text:style-name="Preformatted_20_Text">{ orange code block }</text:p><text:p text:style-name="P3">orange+block quote</text:p>+<text:p text:style-name="First_20_paragraph">Multiple definitions,+tight:</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">apple</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">red fruit</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">computer</text:p>+<text:p text:style-name="Definition_20_Term_20_Tight">orange</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">orange+fruit</text:p>+<text:p text:style-name="Definition_20_Definition_20_Tight">bank</text:p>+<text:p text:style-name="First_20_paragraph">Multiple definitions,+loose:</text:p>+<text:p text:style-name="Definition_20_Term">apple</text:p>+<text:p text:style-name="Definition_20_Definition">red fruit</text:p>+<text:p text:style-name="Definition_20_Definition">computer</text:p>+<text:p text:style-name="Definition_20_Term">orange</text:p>+<text:p text:style-name="Definition_20_Definition">orange fruit</text:p>+<text:p text:style-name="Definition_20_Definition">bank</text:p>+<text:p text:style-name="First_20_paragraph">Blank line after term, indented+marker, alternate markers:</text:p>+<text:p text:style-name="Definition_20_Term">apple</text:p>+<text:p text:style-name="Definition_20_Definition">red fruit</text:p>+<text:p text:style-name="Definition_20_Definition">computer</text:p>+<text:p text:style-name="Definition_20_Term">orange</text:p>+<text:p text:style-name="Definition_20_Definition">orange+fruit</text:p><text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">sublist</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">sublist</text:p>+ </text:list-item>+</text:list>+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="html-blocks" />HTML+Blocks<text:bookmark-end text:name="html-blocks" /></text:h>+<text:p text:style-name="First_20_paragraph">Simple block on one line:</text:p>+<text:p text:style-name="Text_20_body">foo</text:p>+<text:p text:style-name="Text_20_body">And nested without indentation:</text:p>+<text:p text:style-name="Text_20_body">foo</text:p>+<text:p text:style-name="Text_20_body">bar</text:p>+<text:p text:style-name="Text_20_body">Interpreted markdown in a table:</text:p>+<text:p text:style-name="Text_20_body">This is+<text:span text:style-name="Emphasis">emphasized</text:span></text:p>+<text:p text:style-name="Text_20_body">And this is+<text:span text:style-name="Strong_20_Emphasis">strong</text:span></text:p>+<text:p text:style-name="Text_20_body">Here’s a simple block:</text:p>+<text:p text:style-name="Text_20_body">foo</text:p>+<text:p text:style-name="Text_20_body">This should be a code block,+though:</text:p>+<text:p text:style-name="Preformatted_20_Text"><div></text:p>+<text:p text:style-name="Preformatted_20_Text"><text:s text:c="4" />foo</text:p>+<text:p text:style-name="Preformatted_20_Text"></div></text:p>+<text:p text:style-name="First_20_paragraph">As should this:</text:p>+<text:p text:style-name="Preformatted_20_Text"><div>foo</div></text:p>+<text:p text:style-name="First_20_paragraph">Now, nested:</text:p>+<text:p text:style-name="Text_20_body">foo</text:p>+<text:p text:style-name="Text_20_body">This should just be an HTML+comment:</text:p>+<text:p text:style-name="Text_20_body">Multiline:</text:p>+<text:p text:style-name="Text_20_body">Code block:</text:p>+<text:p text:style-name="Preformatted_20_Text"><!-- Comment --></text:p>+<text:p text:style-name="First_20_paragraph">Just plain comment, with trailing+spaces on the line:</text:p>+<text:p text:style-name="Text_20_body">Code:</text:p>+<text:p text:style-name="Preformatted_20_Text"><hr /></text:p>+<text:p text:style-name="First_20_paragraph">Hr’s:</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="inline-markup" />Inline+Markup<text:bookmark-end text:name="inline-markup" /></text:h>+<text:p text:style-name="First_20_paragraph">This is+<text:span text:style-name="Emphasis">emphasized</text:span>, and so+<text:span text:style-name="Emphasis">is this</text:span>.</text:p>+<text:p text:style-name="Text_20_body">This is+<text:span text:style-name="Strong_20_Emphasis">strong</text:span>, and so+<text:span text:style-name="Strong_20_Emphasis">is this</text:span>.</text:p>+<text:p text:style-name="Text_20_body">An+<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition"><text:span text:style-name="Emphasis">emphasized+link</text:span></text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:span text:style-name="T1">This is+strong and em.</text:span></text:p>+<text:p text:style-name="Text_20_body">So is+<text:span text:style-name="T1">this</text:span> word.</text:p>+<text:p text:style-name="Text_20_body"><text:span text:style-name="T1">This is+strong and em.</text:span></text:p>+<text:p text:style-name="Text_20_body">So is+<text:span text:style-name="T1">this</text:span> word.</text:p>+<text:p text:style-name="Text_20_body">This is code:+<text:span text:style-name="Source_20_Text">></text:span>,+<text:span text:style-name="Source_20_Text">$</text:span>,+<text:span text:style-name="Source_20_Text">\</text:span>,+<text:span text:style-name="Source_20_Text">\$</text:span>,+<text:span text:style-name="Source_20_Text"><html></text:span>.</text:p>+<text:p text:style-name="Text_20_body"><text:span text:style-name="Strikeout">This+is+</text:span><text:span text:style-name="T2">strikeout</text:span><text:span text:style-name="Strikeout">.</text:span></text:p>+<text:p text:style-name="Text_20_body">Superscripts:+a<text:span text:style-name="Superscript">bc</text:span>d+a<text:span text:style-name="T3">hello</text:span>+a<text:span text:style-name="Superscript">hello there</text:span>.</text:p>+<text:p text:style-name="Text_20_body">Subscripts:+H<text:span text:style-name="Subscript">2</text:span>O,+H<text:span text:style-name="Subscript">23</text:span>O,+H<text:span text:style-name="Subscript">many of them</text:span>O.</text:p>+<text:p text:style-name="Text_20_body">These should not be superscripts or+subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="smart-quotes-ellipses-dashes" />Smart+quotes, ellipses,+dashes<text:bookmark-end text:name="smart-quotes-ellipses-dashes" /></text:h>+<text:p text:style-name="First_20_paragraph">“Hello,” said the spider. “‘Shelob’+is my name.”</text:p>+<text:p text:style-name="Text_20_body">‘A’, ‘B’, and ‘C’ are letters.</text:p>+<text:p text:style-name="Text_20_body">‘Oak,’ ‘elm,’ and ‘beech’ are names of+trees. So is ‘pine.’</text:p>+<text:p text:style-name="Text_20_body">‘He said, “I want to go.”’ Were you alive+in the 70’s?</text:p>+<text:p text:style-name="Text_20_body">Here is some quoted+‘<text:span text:style-name="Source_20_Text">code</text:span>’ and a+“<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">quoted+link</text:span></text:a>”.</text:p>+<text:p text:style-name="Text_20_body">Some dashes: one—two — three—four —+five.</text:p>+<text:p text:style-name="Text_20_body">Dashes between numbers: 5–7, 255–66,+1987–1999.</text:p>+<text:p text:style-name="Text_20_body">Ellipses…and…and….</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="latex" />LaTeX<text:bookmark-end text:name="latex" /></text:h>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight"></text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">2 + 2 = 4</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight"><text:span text:style-name="Emphasis">x</text:span> ∈ <text:span text:style-name="Emphasis">y</text:span></text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight"><text:span text:style-name="Emphasis">α</text:span> ∧ <text:span text:style-name="Emphasis">ω</text:span></text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">223</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight"><text:span text:style-name="Emphasis">p</text:span>-Tree</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Here’s some display math:+ $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Here’s one that has a line+ break in it:+ <text:span text:style-name="Emphasis">α</text:span> + <text:span text:style-name="Emphasis">ω</text:span> × <text:span text:style-name="Emphasis">x</text:span><text:span text:style-name="Superscript">2</text:span>.</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">These shouldn’t be math:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">To get the famous+ equation, write+ <text:span text:style-name="Source_20_Text">$e = mc^2$</text:span>.</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">$22,000 is a+ <text:span text:style-name="Emphasis">lot</text:span> of money. So is+ $34,000. (It worked if “lot” is emphasized.)</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Shoes ($20) and socks+ ($5).</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">Escaped+ <text:span text:style-name="Source_20_Text">$</text:span>: $73+ <text:span text:style-name="Emphasis">this should be emphasized</text:span>+ 23$.</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">Here’s a LaTeX table:</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="special-characters" />Special+Characters<text:bookmark-end text:name="special-characters" /></text:h>+<text:p text:style-name="First_20_paragraph">Here is some unicode:</text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">I hat: Î</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">o umlaut: ö</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">section: §</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">set membership: ∈</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">copyright: ©</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">AT&T has an ampersand in their+name.</text:p>+<text:p text:style-name="Text_20_body">AT&T is another way to write+it.</text:p>+<text:p text:style-name="Text_20_body">This & that.</text:p>+<text:p text:style-name="Text_20_body">4 < 5.</text:p>+<text:p text:style-name="Text_20_body">6 > 5.</text:p>+<text:p text:style-name="Text_20_body">Backslash: \</text:p>+<text:p text:style-name="Text_20_body">Backtick: `</text:p>+<text:p text:style-name="Text_20_body">Asterisk: *</text:p>+<text:p text:style-name="Text_20_body">Underscore: _</text:p>+<text:p text:style-name="Text_20_body">Left brace: {</text:p>+<text:p text:style-name="Text_20_body">Right brace: }</text:p>+<text:p text:style-name="Text_20_body">Left bracket: [</text:p>+<text:p text:style-name="Text_20_body">Right bracket: ]</text:p>+<text:p text:style-name="Text_20_body">Left paren: (</text:p>+<text:p text:style-name="Text_20_body">Right paren: )</text:p>+<text:p text:style-name="Text_20_body">Greater-than: ></text:p>+<text:p text:style-name="Text_20_body">Hash: #</text:p>+<text:p text:style-name="Text_20_body">Period: .</text:p>+<text:p text:style-name="Text_20_body">Bang: !</text:p>+<text:p text:style-name="Text_20_body">Plus: +</text:p>+<text:p text:style-name="Text_20_body">Minus: -</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="links" />Links<text:bookmark-end text:name="links" /></text:h>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="explicit" />Explicit<text:bookmark-end text:name="explicit" /></text:h>+<text:p text:style-name="First_20_paragraph">Just a+<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">URL</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title"><text:span text:style-name="Definition">URL+and title</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title preceded by two spaces"><text:span text:style-name="Definition">URL+and title</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title preceded by a tab"><text:span text:style-name="Definition">URL+and title</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title with "quotes" in it"><text:span text:style-name="Definition">URL+and title</text:span></text:a></text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name="title with single quotes"><text:span text:style-name="Definition">URL+and title</text:span></text:a></text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/with_underscore" office:name=""><text:span text:style-name="Definition">with_underscore</text:span></text:a></text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="mailto:nobody@nowhere.net" office:name=""><text:span text:style-name="Definition">Email+link</text:span></text:a></text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="" office:name=""><text:span text:style-name="Definition">Empty</text:span></text:a>.</text:p>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="reference" />Reference<text:bookmark-end text:name="reference" /></text:h>+<text:p text:style-name="First_20_paragraph">Foo+<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">With+<text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">embedded+[brackets]</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body"><text:a xlink:type="simple" xlink:href="/url/" office:name=""><text:span text:style-name="Definition">b</text:span></text:a>+by itself should be a link.</text:p>+<text:p text:style-name="Text_20_body">Indented+<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">once</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Indented+<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">twice</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Indented+<text:a xlink:type="simple" xlink:href="/url" office:name=""><text:span text:style-name="Definition">thrice</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">This should [not][] be a link.</text:p>+<text:p text:style-name="Preformatted_20_Text">[not]: /url</text:p>+<text:p text:style-name="First_20_paragraph">Foo+<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with "quotes" inside"><text:span text:style-name="Definition">bar</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Foo+<text:a xlink:type="simple" xlink:href="/url/" office:name="Title with "quote" inside"><text:span text:style-name="Definition">biz</text:span></text:a>.</text:p>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="with-ampersands" />With+ampersands<text:bookmark-end text:name="with-ampersands" /></text:h>+<text:p text:style-name="First_20_paragraph">Here’s a+<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">link+with an ampersand in the URL</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Here’s a link with an amersand in the+link text:+<text:a xlink:type="simple" xlink:href="http://att.com/" office:name="AT&T"><text:span text:style-name="Definition">AT&T</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Here’s an+<text:a xlink:type="simple" xlink:href="/script?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">inline+link</text:span></text:a>.</text:p>+<text:p text:style-name="Text_20_body">Here’s an+<text:a xlink:type="simple" xlink:href="/script?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">inline+link in pointy braces</text:span></text:a>.</text:p>+<text:h text:style-name="Heading_20_2" text:outline-level="2"><text:bookmark-start text:name="autolinks" />Autolinks<text:bookmark-end text:name="autolinks" /></text:h>+<text:p text:style-name="First_20_paragraph">With an ampersand:+<text:a xlink:type="simple" xlink:href="http://example.com/?foo=1&bar=2" office:name=""><text:span text:style-name="Definition">http://example.com/?foo=1&bar=2</text:span></text:a></text:p>+<text:list text:style-name="List_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">In a list?</text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight"><text:a xlink:type="simple" xlink:href="http://example.com/" office:name=""><text:span text:style-name="Definition">http://example.com/</text:span></text:a></text:p>+ </text:list-item>+ <text:list-item>+ <text:p text:style-name="List_20_Bullet_20_Tight">It should.</text:p>+ </text:list-item>+</text:list>+<text:p text:style-name="First_20_paragraph">An e-mail address:+<text:a xlink:type="simple" xlink:href="mailto:nobody@nowhere.net" office:name=""><text:span text:style-name="Definition">nobody@nowhere.net</text:span></text:a></text:p>+<text:p text:style-name="Quotations">Blockquoted:+<text:a xlink:type="simple" xlink:href="http://example.com/" office:name=""><text:span text:style-name="Definition">http://example.com/</text:span></text:a></text:p>+<text:p text:style-name="First_20_paragraph">Auto-links should not occur here:+<text:span text:style-name="Source_20_Text"><http://example.com/></text:span></text:p>+<text:p text:style-name="Preformatted_20_Text">or here: <http://example.com/></text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="images" />Images<text:bookmark-end text:name="images" /></text:h>+<text:p text:style-name="First_20_paragraph">From “Voyage dans la Lune” by+Georges Melies (1902):</text:p>+<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img1"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>+<text:p text:style-name="FigureCaption">lalune</text:p>+<text:p text:style-name="Text_20_body">Here is a movie+<draw:frame draw:name="img2"><draw:image xlink:href="movie.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame>+icon.</text:p>+<text:p text:style-name="Horizontal_20_Line" />+<text:h text:style-name="Heading_20_1" text:outline-level="1"><text:bookmark-start text:name="footnotes" />Footnotes<text:bookmark-end text:name="footnotes" /></text:h>+<text:p text:style-name="First_20_paragraph">Here is a footnote+reference,<text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here+is the footnote. It can go anywhere after the footnote reference. It need not be+placed at the end of the document.</text:p></text:note-body></text:note> and+another.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>2</text:note-citation><text:note-body><text:p text:style-name="Footnote">Here’s+the long note. This one contains multiple+blocks.</text:p><text:p text:style-name="Footnote">Subsequent blocks are+indented to show that they belong to the footnote (as with list+items).</text:p><text:p text:style-name="Preformatted_20_Text"><text:s text:c="2" />{ <code> }</text:p><text:p text:style-name="Footnote">If+you want, you can indent every line, but you can also be lazy and just indent+the first line of each block.</text:p></text:note-body></text:note> This should+<text:span text:style-name="Emphasis">not</text:span> be a footnote reference,+because it contains a space.[^my note] Here is an inline+note.<text:note text:id="ftn2" text:note-class="footnote"><text:note-citation>3</text:note-citation><text:note-body><text:p text:style-name="Footnote">This+is <text:span text:style-name="Emphasis">easier</text:span> to type. Inline+notes may contain+<text:a xlink:type="simple" xlink:href="http://google.com" office:name=""><text:span text:style-name="Definition">links</text:span></text:a>+and <text:span text:style-name="Source_20_Text">]</text:span> verbatim+characters, as well as [bracketed+text].</text:p></text:note-body></text:note></text:p>+<text:p text:style-name="Quotations">Notes can go in+quotes.<text:note text:id="ftn3" text:note-class="footnote"><text:note-citation>4</text:note-citation><text:note-body><text:p text:style-name="Footnote">In+quote.</text:p></text:note-body></text:note></text:p>+<text:list text:style-name="Numbering_20_1">+ <text:list-item>+ <text:p text:style-name="List_20_Number_20_Tight">And in list items.<text:note text:id="ftn4" text:note-class="footnote"><text:note-citation>5</text:note-citation><text:note-body><text:p text:style-name="Footnote">In list.</text:p></text:note-body></text:note></text:p> </text:list-item>
test/writer.opml view
@@ -42,7 +42,7 @@ <outline text="Fancy list markers" _note="(2) begins with 2 (3) and now 3 with a continuation iv. sublist with roman numerals, starting with 4 v. more items (A) a subsublist (B) a subsublist Nesting: A. Upper Alpha I. Upper Roman. (6) Decimal start with 6 c) Lower alpha with paren Autonumbering: 1. Autonumber. 2. More. 1. Nested. Should not be a list item: M.A. 2007 B. Williams --------------------------------------------------------------------------------"> </outline> </outline>-<outline text="Definition Lists" _note="Tight using spaces: apple : red fruit orange : orange fruit banana : yellow fruit Tight using tabs: apple : red fruit orange : orange fruit banana : yellow fruit Loose: apple : red fruit orange : orange fruit banana : yellow fruit Multiple blocks with italics: *apple* : red fruit contains seeds, crisp, pleasant to taste *orange* : orange fruit { orange code block } > orange block quote Multiple definitions, tight: apple : red fruit : computer orange : orange fruit : bank Multiple definitions, loose: apple : red fruit : computer orange : orange fruit : bank Blank line after term, indented marker, alternate markers: apple : red fruit : computer orange : orange fruit 1. sublist 2. sublist">+<outline text="Definition Lists" _note="Tight using spaces: apple : red fruit orange : orange fruit banana : yellow fruit Tight using tabs: apple : red fruit orange : orange fruit banana : yellow fruit Loose: apple : red fruit orange : orange fruit banana : yellow fruit Multiple blocks with italics: *apple* : red fruit contains seeds, crisp, pleasant to taste *orange* : orange fruit { orange code block } > orange block quote Multiple definitions, tight: apple : red fruit : computer orange : orange fruit : bank Multiple definitions, loose: apple : red fruit : computer orange : orange fruit : bank Blank line after term, indented marker, alternate markers: apple : red fruit : computer orange : orange fruit 1. sublist 2. sublist"> </outline> <outline text="HTML Blocks" _note="Simple block on one line: ::: {} foo ::: And nested without indentation: :::::: {} :::: {} ::: {} foo ::: :::: ::: {} bar ::: :::::: Interpreted markdown in a table: <table> <tr> <td> This is *emphasized* </td> <td> And this is **strong** </td> </tr> </table> <script type="text/javascript">document.write('This *should not* be interpreted as markdown');</script> Here's a simple block: ::: {} foo ::: This should be a code block, though: <div> foo </div> As should this: <div>foo</div> Now, nested: ::::: {} :::: {} ::: {} foo ::: :::: ::::: This should just be an HTML comment: <!-- Comment --> Multiline: <!-- Blah Blah --> <!-- This is another comment. --> Code block: <!-- Comment --> Just plain comment, with trailing spaces on the line: <!-- foo --> Code: <hr /> Hr's: <hr> <hr /> <hr /> <hr> <hr /> <hr /> <hr class="foo" id="bar" /> <hr class="foo" id="bar" /> <hr class="foo" id="bar"> --------------------------------------------------------------------------------"> </outline>
test/writer.plain view
@@ -257,93 +257,93 @@ Tight using spaces: apple- red fruit+ red fruit orange- orange fruit+ orange fruit banana- yellow fruit+ yellow fruit Tight using tabs: apple- red fruit+ red fruit orange- orange fruit+ orange fruit banana- yellow fruit+ yellow fruit Loose: apple - red fruit+ red fruit orange - orange fruit+ orange fruit banana - yellow fruit+ yellow fruit Multiple blocks with italics: apple - red fruit+ red fruit - contains seeds, crisp, pleasant to taste+ contains seeds, crisp, pleasant to taste orange - orange fruit+ orange fruit - { orange code block }+ { orange code block } - orange block quote+ orange block quote Multiple definitions, tight: apple- red fruit- computer+ red fruit+ computer orange- orange fruit- bank+ orange fruit+ bank Multiple definitions, loose: apple - red fruit+ red fruit - computer+ computer orange - orange fruit+ orange fruit - bank+ bank Blank line after term, indented marker, alternate markers: apple - red fruit+ red fruit - computer+ computer orange - orange fruit+ orange fruit - 1. sublist- 2. sublist+ 1. sublist+ 2. sublist HTML Blocks
test/writer.typst view
@@ -1,13 +1,9 @@ #let horizontalrule = line(start: (25%,0%), end: (75%,0%)) -#show terms: it => {- it.children- .map(child => [- #strong[#child.term]- #block(inset: (left: 1.5em, top: -0.4em))[#child.description]- ])- .join()-}+#show terms.item: it => block(breakable: false)[+ #text(weight: "bold")[#it.term]+ #block(inset: (left: 1.5em, top: -0.4em))[#it.description]+] #set table( inset: 6pt,@@ -97,48 +93,49 @@ } } - block(below: 1em, width: 100%)[- #if title != none {- align(center, block[- #text(weight: "bold", size: 1.5em)[#title #if thanks != none {- footnote(thanks, numbering: "*")- counter(footnote).update(n => n - 1)- }]- #(- if subtitle != none {- parbreak()- text(weight: "bold", size: 1.25em)[#subtitle]- }- )])- }-- #if authors != none and authors != [] {- let count = authors.len()- let ncols = calc.min(count, 3)- grid(- columns: (1fr,) * ncols,- row-gutter: 1.5em,- ..authors.map(author => align(center)[- #author.name \- #author.affiliation \- #author.email- ])- )- }+ if title != none {+ place(top, float: true, scope: "parent", clearance: 4mm, block(below: 1em, width: 100%)[+ #if title != none {+ align(center, block[+ #text(weight: "bold", size: 1.5em, hyphenate: false)[#title #if thanks != none {+ footnote(thanks, numbering: "*")+ counter(footnote).update(n => n - 1)+ }]+ #(+ if subtitle != none {+ parbreak()+ text(weight: "bold", size: 1.25em, hyphenate: false)[#subtitle]+ }+ )])+ } - #if date != none {- align(center)[#block(inset: 1em)[- #date- ]]- }+ #if authors != none and authors != [] {+ let count = authors.len()+ let ncols = calc.min(count, 3)+ grid(+ columns: (1fr,) * ncols,+ row-gutter: 1.5em,+ ..authors.map(author => align(center)[+ #author.name \+ #author.affiliation \+ #author.email+ ])+ )+ } - #if abstract != none {- block(inset: 2em)[- #text(weight: "semibold")[#abstract-title] #h(1em) #abstract- ]- }- ]+ #if date != none {+ align(center)[#block(inset: 1em)[+ #date+ ]]+ } + #if abstract != none {+ block(inset: 2em)[+ #text(weight: "semibold")[#abstract-title] #h(1em) #abstract+ ]+ }+ ])+ } doc } #show: doc => conf(@@ -198,8 +195,7 @@ Here's one with a bullet. \* criminey. -There should be a hard line break \-here.+There should be a hard line break \ here. #horizontalrule @@ -685,7 +681,7 @@ - $223$ - $p$-Tree - Here's some display math:- $ frac(d, d x) f \( x \) = lim_(h arrow.r 0) frac(f \( x + h \) - f \( x \), h) $+ $ frac(d, d x) f\(x\)= lim_(h arrow.r 0) frac(f\(x + h\)- f\(x\), h) $ - Here's one that has a line break in it: $alpha + omega times x^2$. These shouldn't be math:@@ -837,13 +833,13 @@ <images> From "Voyage dans la Lune" by Georges Melies (1902): -#figure(image("lalune.jpg"),+#figure(image("lalune.jpg", alt: "lalune"), caption: [ lalune ] ) -Here is a movie #box(image("movie.jpg")) icon.+Here is a movie #box(image("movie.jpg", alt: "movie")) icon. #horizontalrule
test/writers-lang-and-dir.latex view
@@ -69,6 +69,10 @@ \usepackage{bookmark} \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available \urlstyle{same}+% fallback for those not using the hyperref driver hyperxmp:+\makeatletter+\@ifundefined{xmpquote}{\newcommand{\xmpquote}[1]{#1}}{}+\makeatother \hypersetup{ pdflang={en}, hidelinks,