pandoc 3.10 → 3.10.1
raw patch · 140 files changed
+4252/−1304 lines, 140 filesdep ~commonmark-extensionsdep ~djotdep ~doclayoutbinary-addedPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: commonmark-extensions, djot, doclayout, emojis, pandoc-types, texmath, typst
API changes (from Hackage documentation)
Files
- AUTHORS.md +7/−0
- COPYING.md +11/−11
- MANUAL.txt +172/−77
- README.md +1/−0
- changelog.md +246/−0
- data/epub.css +7/−19
- data/templates/common.latex +2/−0
- data/templates/default.rtf +3/−0
- data/templates/default.t2t +17/−0
- data/templates/default.typst +6/−7
- data/templates/styles.html +0/−1
- pandoc.cabal +14/−8
- src/Text/Pandoc/App.hs +6/−1
- src/Text/Pandoc/App/CommandLineOptions.hs +4/−9
- src/Text/Pandoc/App/Opt.hs +12/−13
- src/Text/Pandoc/Error.hs +2/−2
- src/Text/Pandoc/Extensions.hs +2/−1
- src/Text/Pandoc/PDF.hs +2/−0
- src/Text/Pandoc/Readers/Docx.hs +70/−64
- src/Text/Pandoc/Readers/Docx/Parse.hs +49/−12
- src/Text/Pandoc/Readers/DokuWiki.hs +5/−5
- src/Text/Pandoc/Readers/HTML.hs +7/−12
- src/Text/Pandoc/Readers/LaTeX.hs +1/−1
- src/Text/Pandoc/Readers/Markdown.hs +2/−0
- src/Text/Pandoc/Readers/ODT/ContentReader.hs +0/−4
- src/Text/Pandoc/Readers/RST.hs +29/−13
- src/Text/Pandoc/Readers/RTF.hs +86/−6
- src/Text/Pandoc/Readers/Typst.hs +7/−3
- src/Text/Pandoc/Readers/Typst/Parsing.hs +25/−2
- src/Text/Pandoc/Shared.hs +24/−6
- src/Text/Pandoc/Writers.hs +3/−0
- src/Text/Pandoc/Writers/Docx.hs +24/−3
- src/Text/Pandoc/Writers/LaTeX.hs +9/−6
- src/Text/Pandoc/Writers/LaTeX/Caption.hs +7/−16
- src/Text/Pandoc/Writers/LaTeX/Table.hs +105/−51
- src/Text/Pandoc/Writers/LaTeX/Util.hs +20/−0
- src/Text/Pandoc/Writers/Markdown.hs +26/−18
- src/Text/Pandoc/Writers/ODT.hs +88/−9
- src/Text/Pandoc/Writers/OpenDocument.hs +7/−1
- src/Text/Pandoc/Writers/Powerpoint/Output.hs +180/−5
- src/Text/Pandoc/Writers/Powerpoint/Presentation.hs +21/−10
- src/Text/Pandoc/Writers/RTF.hs +208/−45
- src/Text/Pandoc/Writers/Shared.hs +1/−0
- src/Text/Pandoc/Writers/Texinfo.hs +7/−5
- src/Text/Pandoc/Writers/Txt2Tags.hs +377/−0
- src/Text/Pandoc/Writers/Typst.hs +14/−13
- test/Tests/Old.hs +2/−1
- test/Tests/Readers/Docx.hs +4/−0
- test/Tests/Readers/RST.hs +29/−0
- test/Tests/Readers/RTF.hs +2/−0
- test/Tests/Writers/Docx.hs +62/−84
- test/Tests/Writers/Powerpoint.hs +4/−0
- test/Tests/Writers/Txt2Tags.hs +124/−0
- test/command/1023.md +129/−0
- test/command/11673.md +6/−0
- test/command/11685.md +18/−0
- test/command/11689.docx binary
- test/command/11689.md +18/−0
- test/command/11701.md +9/−0
- test/command/11712.md +8/−0
- test/command/11715.md +10/−0
- test/command/11727.md +8/−0
- test/command/11735.md +14/−0
- test/command/11739.md +40/−0
- test/command/11745.md +26/−0
- test/command/11749.md +23/−0
- test/command/11758.md +13/−0
- test/command/11762.md +12/−0
- test/command/5474-figures.md +2/−2
- test/command/6774.md +3/−3
- test/command/7418.md +10/−0
- test/command/8240.md +14/−0
- test/command/gfm.md +12/−0
- test/command/pptx-table-content-same-slide.md +121/−0
- test/command/typst-auto-identifiers.md +37/−0
- test/djot-reader.native +8/−5
- test/docx/lists_restart_8367.docx binary
- test/docx/lists_restart_8367.native +13/−0
- test/docx/ns0-reference.docx binary
- test/pptx/comparison/non-text-first/output.pptx binary
- test/pptx/comparison/non-text-first/templated.pptx binary
- test/pptx/footer/basic/output.pptx binary
- test/pptx/footer/fixed-date/output.pptx binary
- test/pptx/footer/higher-slide-number/output.pptx binary
- test/pptx/footer/no-title-slide/output.pptx binary
- test/pptx/slide-level-0/h1-h2-with-table/output.pptx binary
- test/pptx/slide-level-0/h1-h2-with-table/templated.pptx binary
- test/pptx/table-with-surrounding-content/input.native +34/−0
- test/pptx/table-with-surrounding-content/output.pptx binary
- test/pptx/table-with-surrounding-content/templated.pptx binary
- test/rtf/list_legacy.native +14/−0
- test/rtf/list_legacy.rtf +4/−0
- test/rtf/list_multiparagraph.native +25/−0
- test/rtf/list_multiparagraph.rtf +12/−0
- test/tables.rtf +106/−106
- test/tables.t2t +46/−0
- test/test-pandoc.hs +2/−0
- test/testsuite.native +7/−7
- test/testsuite.txt +6/−6
- test/typst-reader.native +11/−11
- test/undergradmath.typ +10/−10
- test/writer.asciidoc +6/−6
- test/writer.asciidoc_legacy +6/−6
- test/writer.bbcode +2/−2
- test/writer.context +6/−6
- test/writer.djot +7/−7
- test/writer.docbook4 +6/−6
- test/writer.docbook5 +6/−6
- test/writer.dokuwiki +4/−10
- test/writer.fb2 +9/−9
- test/writer.haddock +5/−5
- test/writer.html4 +6/−7
- test/writer.html5 +6/−7
- test/writer.icml +17/−17
- test/writer.jats_archiving +5/−6
- test/writer.jats_articleauthoring +5/−6
- test/writer.jats_publishing +5/−6
- test/writer.jira +2/−2
- test/writer.latex +3/−5
- test/writer.man +7/−7
- test/writer.markdown +5/−5
- test/writer.markua +17/−17
- test/writer.mediawiki +6/−6
- test/writer.ms +7/−7
- test/writer.muse +7/−7
- test/writer.native +7/−7
- test/writer.opendocument +8/−8
- test/writer.opml +1/−1
- test/writer.org +5/−5
- test/writer.plain +5/−5
- test/writer.rst +5/−5
- test/writer.rtf +370/−333
- test/writer.t2t +662/−0
- test/writer.tei +6/−6
- test/writer.texinfo +7/−7
- test/writer.textile +6/−6
- test/writer.typst +30/−48
- test/writer.vimdoc +7/−7
- test/writer.xwiki +2/−2
- test/writer.zimwiki +2/−2
@@ -65,6 +65,7 @@ - Caleb McDaniel - Caleb Mclennan - Calvin Beck+- Can H. Tartanoglu - Carlos Scheidegger - Carlos Sosa - Carsten Allefeld@@ -76,6 +77,7 @@ - Charanjit Singh - Charles Tapley Hoyt - Charlotte Koch+- Chirag Dhamange - Chris Black - Chris Callison-Burch - Christian Conkle@@ -119,6 +121,7 @@ - Emerson Harkin - Emily Bourke - Emily Eisenberg+- Enrico Spinielli - Eric Kow - Eric Schrijver - Eric Seidel@@ -362,6 +365,7 @@ - Recai Oktaş - Repetitive - Reuben Thomas+- Robertas - Rowan Rodrik van der Molen - Roland Hieber - Roman Beránek@@ -378,6 +382,7 @@ - Santiago Zarate - Sascha Wilde - Scott Morrison+- Scott Talbert - Sean Soon - Sebastian Talmon - Sebbones@@ -422,6 +427,7 @@ - Timm Albers - Timothy Humphries - Tiziano Müller+- Tobias Deiminger - Todd Sifleet - Tomas Dahlqvist - TomBen@@ -490,6 +496,7 @@ - kaizshang91 - lawcho - lifeunleaded+- luginf - lux-lth - luz paz - lwolfsonkin
@@ -2,9 +2,9 @@ Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1991 Free Software Foundation, Inc. <https://fsf.org/>- + Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -96,17 +96,17 @@ distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - + **a)** You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. - + **b)** You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. - + **c)** If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement@@ -143,12 +143,12 @@ under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - + **a)** Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - + **b)** Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable@@ -156,7 +156,7 @@ terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - + **c)** Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the@@ -317,7 +317,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.- + You should have received a copy of the GNU General Public License along with this program; if not, see <https://www.gnu.org/licenses/>. @@ -330,7 +330,7 @@ Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome- to redistribute it under certain conditions; type `show c' + to redistribute it under certain conditions; type `show c' for details. The hypothetical commands \`show w' and \`show c' should show the@@ -345,7 +345,7 @@ Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'- (which makes passes at compilers) written + (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: 2026-06-03+date: 2026-07-21 --- # Synopsis@@ -138,8 +138,8 @@ [`amsfonts`], [`amsmath`], [`lm`], [`unicode-math`], [`iftex`], [`listings`] (if the `--listings` option is used), [`fancyvrb`], [`longtable`],-[`booktabs`], [`multirow`] (if the document contains a table with-cells that cross multiple rows), [`graphicx`] (if the document+[`caption`], [`booktabs`], [`multirow`] (if the document contains a table+with cells that cross multiple rows), [`graphicx`] (if the document contains images), [`bookmark`], [`xcolor`], [`soul`], [`geometry`] (with the `geometry` variable set), [`setspace`] (with `linestretch`), and@@ -191,6 +191,7 @@ [`lua-ul`]: https://ctan.org/pkg/lua-ul [`luatexja`]: https://ctan.org/pkg/luatexja [`longtable`]: https://ctan.org/pkg/longtable+[`caption`]: https://ctan.org/pkg/caption [`mathspec`]: https://ctan.org/pkg/mathspec [`microtype`]: https://ctan.org/pkg/microtype [`multirow`]: https://ctan.org/pkg/multirow@@ -363,6 +364,7 @@ - `rtf` ([Rich Text Format]) - `texinfo` ([GNU Texinfo]) - `textile` ([Textile])+ - `t2t` ([txt2tags]) - `slideous` ([Slideous] HTML and JavaScript slide show) - `slidy` ([Slidy] HTML and JavaScript slide show) - `dzslides` ([DZSlides] HTML5 + JavaScript slide show)@@ -422,11 +424,12 @@ 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 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.+ (see `--data-dir`). If *FILE* lacks an extension, pandoc will+ also try adding the `.yaml` extension if *FILE* is not found.+ 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` @@ -923,6 +926,12 @@ prefer it to be at the beginning of the document, before the title, you can use `--pdf-engine=pdfroff`. + Because the entries in a table of contents need heading+ identifiers to link to, this option forces the+ [`auto_identifiers`](#extension-auto_identifiers) extension on+ for the input format, even when it is off by default (as it is+ for `typst`).+ `--toc-depth=`*NUMBER* : Specify the number of section levels to include in the table@@ -3532,6 +3541,11 @@ [`install-font.sh`]: https://www.schaffter.ca/mom/bin/install-font.sh [ms-font-steps]: https://www.schaffter.ca/mom/momdoc/appendices.html#steps +### Variables for RTF++`fontsize`+: font size for body text, e.g. `12pt` or `12.5pt`.+ ### Variables set automatically Pandoc sets these variables automatically in response to [options] or@@ -3673,7 +3687,7 @@ This extension can be enabled/disabled for the following formats: input formats-: `markdown`, `latex`, `rst`, `mediawiki`, `textile`, `man`+: `markdown`, `latex`, `rst`, `mediawiki`, `textile`, `man`, `typst` output formats : `markdown`, `muse`@@ -3875,14 +3889,16 @@ ### Extension: `native_numbering` ### -Enables native numbering of figures and tables. Enumeration-starts at 1.--This extension can be enabled/disabled for the following formats:+Enables numbering of figures and tables via counter fields+specific to the target format. This extension+can be enabled/disabled for the following formats: output formats : `odt`, `opendocument`, `docx` +If this extension is not enabled, tables and figures in these+formats will not be numbered.+ ### Extension: `xrefs_name` ### Links to headings, figures and tables inside the document are@@ -4545,6 +4561,10 @@ Note: the '`#`' ordered list marker doesn't work with `commonmark`. +As with `commonmark`, ordered sublists must start with `1` or the+equivalent (e.g., `i` or `a`). This helps avoid unintentional+lists caused by things like parenthesized dates.+ ### Extension: `startnum` ### Pandoc also pays attention to the type of list marker used, and to the@@ -4607,7 +4627,7 @@ A term may have multiple definitions, and each definition may consist of one or more indented block elements (paragraph, code block,-list, etc.). The blocks in the definition shoud be indented to the column+list, etc.). The blocks in the definition should 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@@ -4739,9 +4759,12 @@ ## Tables -Four kinds of tables may be used. The first three kinds presuppose the use of-a fixed-width font, such as Courier. The fourth kind can be used with-proportionally spaced fonts, as it does not require lining up columns.+Four kinds of tables may be used. The first three kinds (simple,+multiline, and grid) require lining up columns and thus+presuppose the use of a fixed-width font, such as Courier.+The fourth kind (pipe tables) can be used with+proportionally spaced fonts, as it does not require lining up+columns. ### Extension: `table_captions` ### @@ -4986,6 +5009,29 @@ : Here's the caption. {#ident .class key="value"} +### Table placement in LaTeX ###++By default, pandoc will render tables in LaTeX using the `longtable`+environment. The tables will not "float" and they can span page boundaries.+If you prefer standard "floating" tables (which are limited to what can+fit on one page), add the `float` class to the table's attributes+(which can be specified after the caption). Optionally, the `latex-placement`+attribute may be used to pass parameters affecting the float placement:++ : The caption of the table. {#ident .float latex-placement="ht"}++Note that `longtable` does not work with two-column layouts, so if you+are producing a two-column document using LaTeX, you will need to specify+the `float` class on every table, or use this small Lua filter+to add it automatically:++```lua+function Table(el)+ el.classes:insert("float")+ return el+end+```+ ## Metadata blocks ### Extension: `pandoc_title_block` ###@@ -5398,7 +5444,7 @@ ~ It will appear verbatim surrounded by `\(...\)` (for inline math) or `\[...\]` (for display math). -Markdown, Emacs Org mode, ConTeXt, ZimWiki+Markdown, Emacs Org mode, ConTeXt, Txt2Tags, ZimWiki ~ It will appear verbatim surrounded by `$...$` (for inline math) or `$$...$$` (for display math). @@ -5463,8 +5509,8 @@ be disabled if desired.) The raw HTML is passed through unchanged in HTML, S5, Slidy, Slideous,-DZSlides, EPUB, Markdown, CommonMark, Emacs Org mode, and Textile-output, and suppressed in other formats.+DZSlides, EPUB, Markdown, CommonMark, Emacs Org mode, Textile, and+Txt2Tags output, and suppressed in other formats. For a more explicit way of including raw HTML in a Markdown document, see the [`raw_attribute` extension][Extension: `raw_attribute`].@@ -5744,7 +5790,8 @@ ## Images A link immediately preceded by a `!` will be treated as an image.-The link text will be used as the image's alt text:+The link text (the part in square brackets) will be used as the+image's alt text:  @@ -7175,7 +7222,9 @@ text: Sarah Jones identifier: - scheme: DOI- text: doi:10.234234.234/33+ text: 'urn:doi:10.234234.234/33'+ - scheme: ISBN-13+ text: 'urn:isbn:9780000000000' publisher: My Press rights: © 2007 John Smith, CC BY-NC ibooks:@@ -7185,25 +7234,30 @@ The following fields are recognized: `identifier`- ~ 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 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`.+ ~ Either a string value, or an object with fields `text` and+ `scheme` (optional), or a list of such objects. Valid values for+ `scheme` are `ISBN-10`, `GTIN-13`, `UPC`, `ISMN-10`, `DOI`,+ `LCCN`, `GTIN-14`, `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`. In the `text` field, it is+ advisable to specify a URN as in the examples above. Note+ that quotes are needed around a YAML field containing a colon. `title`- ~ Either a string value, or an object with fields `file-as` and- `type`, or a list of such objects. Valid values for `type` are- `main`, `subtitle`, `short`, `collection`, `edition`, `extended`.+ ~ Either a string value, or an object with fields `text`,+ `file-as` (optional) and `type` (optional), or a list of such+ objects. Valid values for `type` are `main`, `subtitle`,+ `short`, `collection`, `edition`, `extended`. `creator`- ~ Either a string value, or an object with fields `role`, `file-as`,- and `text`, or a list of such objects. Valid values for `role` are- [MARC relators], but- pandoc will attempt to translate the human-readable versions- (like "author" and "editor") to the appropriate marc relators.+ ~ Either a string value, or an object with fields `text`,+ `role` (optional), and `file-as` (optional), or a list of+ such objects. Valid values for `role` are [MARC relators],+ but pandoc will attempt to translate the human-readable+ versions (like "author" and "editor") to the appropriate marc+ relators. `contributor` ~ Same format as `creator`.@@ -7217,12 +7271,14 @@ language if nothing is specified. `subject`- ~ Either a string value, or an object with fields `text`, `authority`,- and `term`, or a list of such objects. Valid values for `authority`- are either a [reserved authority value] (currently `AAT`, `BIC`,- `BISAC`, `CLC`, `DDC`, `CLIL`, `EuroVoc`, `MEDTOP`, `LCSH`, `NDC`,- `Thema`, `UDC`, and `WGS`) or an absolute IRI identifying a custom- scheme. Valid values for `term` are defined by the scheme.+ ~ Either a string value, or an object with fields `text`,+ `authority` (optional), and `term` (optional), or a list of+ such objects. Valid values for `authority` are either a+ [reserved authority value] (currently `AAT`, `BIC`, `BISAC`,+ `CLC`, `DDC`, `CLIL`, `EuroVoc`, `MEDTOP`, `LCSH`, `NDC`,+ `Thema`, `UDC`, and `WGS`) or an absolute IRI identifying a+ custom scheme. Valid values for `term` are defined by the+ scheme. `description` ~ A string value.@@ -7994,38 +8050,73 @@ writer could in principle do anything on your file system. Please audit filters and custom writers very carefully before using them. -2. Several input formats (including LaTeX, Org, RST, and Typst)- support `include` directives that allow the contents of a file to be- included in the output. An untrusted attacker could use these- to view the contents of files on the file system. (Using the- `--sandbox` option can protect against this threat.)+2. If you want to use pandoc in a web application that accepts+ untrusted user input, you should be aware that running pandoc in+ this context requires special precautions, or you risk exfiltration+ of the contents of local files, or worse. In particular: -3. Several output formats (including RTF, FB2, HTML with- `--self-contained`, EPUB, Docx, and ODT) will embed encoded- or raw images into the output file. An untrusted attacker- could exploit this to view the contents of non-image files on the- file system. (Using the `--sandbox` option can protect- against this threat, but will also prevent including images in- these formats.)+ - Several input formats (including LaTeX, Org, RST, and Typst)+ support `include` directives that allow the contents of a file to be+ included in the output. An untrusted attacker could use these+ to view the contents of files on the file system. Using the+ `--sandbox` option will protect against this threat. -4. In reading HTML files, pandoc will attempt to include the- contents of `iframe` elements by fetching content from the- local file or URL specified by `src`. If untrusted HTML is- processed on a server, this has the potential to reveal anything- readable by the process running the server. Using the `-f html+raw_html`- will mitigate this threat by causing the whole `iframe`- to be parsed as a raw HTML block. Using `--sandbox` will also- protect against the threat.+ - Several output formats (including RTF, FB2, HTML with+ `--self-contained`, EPUB, Docx, and ODT) will embed encoded+ or raw images into the output file. An untrusted attacker+ could exploit this to view the contents of non-image files on the+ file system. Using the `--sandbox` option will protect+ against this threat, but will also prevent including images in+ these formats. -5. If your application uses pandoc as a Haskell library (rather than- shelling out to the executable), it is possible to use it in a mode- that fully isolates pandoc from your file system, by running the- pandoc operations in the `PandocPure` monad. See the document- [Using the pandoc API](https://pandoc.org/using-the-pandoc-api.html)- for more details. (This corresponds to the use of the `--sandbox`- option on the command line.)+ - In reading HTML files, pandoc will attempt to include the+ contents of `iframe` elements by fetching content from the+ local file or URL specified by `src`. If untrusted HTML is+ processed on a server, this has the potential to reveal+ anything readable by the process running the server or to+ enable server-side request forgery (SSRF) attacks+ ([CVE-2025-51591]). To mitigate such attacks, use+ `--sandbox` or `-f html+raw_html` (which causes the whole+ `iframe` to be parsed as a raw HTML block). -6. Pandoc's parsers can exhibit pathological performance on some+ - Using pandoc with `--pdf-engine` introduces additional risks,+ which cannot be mitigated by using `--sandbox`.+ For example, in `wkhtmltopdf` the `footer-html` and `header-html`+ metadata fields will be passed directly to `wkhtmltopdf`+ as `--footer-html` and `--header-html` arguments, and by using+ a `file:` URIs with these, one could exfiltrate local files.+ In addition, using `--pdf-engine=wkhtmltopdf` with `-f html+raw_html`+ enables an SSRF vulnerability in wkhtmltopdf ([CVE-2022-35583]).+ Note that [`wkhtmltopdf`) is+ [deprecated](https://wkhtmltopdf.org/status.html) and+ its authors recommend not to use it with any untrusted input.+ However, there may be similar issues with other pdf-engines.+ Anyone including a pdf-engine in a pandoc command run on+ untrusted input should audit the engine carefully and+ carefully control the use of `--pdf-engine-opt`.++ Here are some alternatives for safe use of pandoc in a web+ application:++ - Use `pandoc server` to spin up a local web server, and have your+ application make requests to it. The server runs in sandboxed mode+ and will not be able to read files or use filters.++ - Use the WASM version of pandoc. This allows the use of Lua filters,+ but everything runs in an isolated WASM sandbox.++ - Use `pandoc --sandbox`. However, be aware that the sandbox function+ only affects readers and writers, and security issues can arise if+ you use it together with `--filter` or `--pdf-engine`.++3. The HTML generated by pandoc is not guaranteed to be safe.+ If `raw_html` is enabled for the Markdown input, users can+ inject arbitrary HTML. Even if `raw_html` is disabled,+ users can include dangerous content in URLs and attributes.+ To be safe, you should run all HTML generated from untrusted+ user input through an HTML sanitizer.++4. Pandoc's parsers can exhibit pathological performance on some corner cases. It is wise to put any pandoc operations under a timeout, to avoid DOS attacks that exploit these issues. If you are using the pandoc executable, you can add the@@ -8035,12 +8126,16 @@ to pathological performance than the `markdown` parser, so it is a better choice when processing untrusted input. -7. The HTML generated by pandoc is not guaranteed to be safe.- If `raw_html` is enabled for the Markdown input, users can- inject arbitrary HTML. Even if `raw_html` is disabled,- users can include dangerous content in URLs and attributes.- To be safe, you should run all HTML generated from untrusted- user input through an HTML sanitizer.+5. If your application uses pandoc as a Haskell library (rather than+ shelling out to the executable), it is possible to use it in a mode+ that fully isolates pandoc from your file system, by running the+ pandoc operations in the `PandocPure` monad. See the document+ [Using the pandoc API](https://pandoc.org/using-the-pandoc-api.html)+ for more details. (This corresponds to the use of the `--sandbox`+ option on the command line.)++ [CVE-2025-51591]: https://nvd.nist.gov/vuln/detail/CVE-2025-51591+ [CVE-2022-35583]: https://nvd.nist.gov/vuln/detail/CVE-2022-35583 # Authors
@@ -221,6 +221,7 @@ Format](https://en.wikipedia.org/wiki/Rich_Text_Format)) - `texinfo` ([GNU Texinfo](https://www.gnu.org/software/texinfo/)) - `textile` ([Textile](https://textile-lang.com))+- `t2t` ([txt2tags](https://txt2tags.org)) - `slideous` ([Slideous](https://goessner.net/articles/slideous/) HTML and JavaScript slide show) - `slidy` ([Slidy](https://www.w3.org/Talks/Tools/Slidy2/) HTML and
@@ -1,5 +1,251 @@ # Revision history for pandoc +## pandoc 3.10.1 (2026-07-21)++ * New output format `t2t` (Txt2Tags markup, <https://txt2tags.org>))+ (luginf).++ * New module Text.Pandoc.Writers.Txt2Tags, exporting+ `writeTxt2Tags` (loginf) [API change]. Also exported from+ Text.Pandoc.Writers.++ * Change adding of `.yaml` extension in `--defaults` option (#11717).+ Previously it was always added if the specified filename+ lacked an extension. Now it is only added if there is+ no file with the original name. This facilitates using+ `--defaults` with bash/zsh `<(..)` or `=(..)`.++ * RST reader:++ + Fix nested placeholder resolution for inline elements (#11753,+ Tobias Deiminger). (Regression from pandoc 3.6.)+ + Treat undefined substitution references as plain text (#11727).+ This mirrors rst2html behavior.++ * Markdown reader:++ + Ordered sublists must start with 1, er equivalent, e.g. i (#11735).+ This brings the markdown parser in line with commonmark, and avoids+ a lot of unintended list starts. Note that ordered lists that+ are not sublists may still start with numbers other than 1.++ * ODT reader:++ + Don't create Emph just because of changed font (#11691).++ * RTF reader:++ + Support multi-paragraph list items.+ + Support legacy `\pn/\pntext` paragraph numbering (#11686).++ * Docx reader:++ + Improve horizontal rule detection (#11689).+ + Key list numbering off `abstractNumId`, fixing numbering for+ restarted lists (#8367).++ * LaTeX reader:++ + Handle `\hypertarget` with one braced parameter (#7418).++ * DokuWiki reader:++ + Skip non-cell content after table row (#11739).++ * Typst reader:++ + Support `auto_identifiers` extension (#11041).+ The extension is available for the typst reader but is off by+ default; enable it with `-f typst+auto_identifiers`. The related+ `gfm_auto_identifiers` and `ascii_identifiers` extensions are+ also made available.+ + Recognize `divider()` for horizontal rule (#11540).++ * HTML reader:++ + Fix unused variable warning in CI (#11704, Robertas).+ + Strip `language-` from all classes, not just first (#11701).+ Also combine classes from both code and pre class if they are+ nested.++ * Powerpoint writer:++ + Keep tables and surrounding text on same slide (#11433, Chris+ Callison-Burch). Previously, when a slide contained bullet+ points before and after a table, content would be split across+ multiple slides or use a two-column layout that didn't preserve+ the source order.++ * Texinfo writer:++ + Fix spacing bug around HorizontalRule (#11749).+ + fix escaping in links (#11758). Previously we dropped periods,+ commas, etc. This was a regression from 2024. All we really need+ to do is escape the comma.++ * LaTeX writer:++ + Provide a way to use table instead of longtable (#1023).+ When the `float` class is attached to a table, a standard+ floating `table` will be generated instead of a `longtable`.+ Placement can be specified via the `latex-placement` attribute.+ This will help, especially, those who use two-column layouts,+ since `longtable` is incompatible with these.+ + Fix footnotes in definition list headings (#8240).++ * Markdown writer:++ + Fix ordered list indentation bug (#11762).+ + Improve identification of code language class by looking it up+ in the syntax map (#11701).+ + In YAML metadata, put double quotes around strings that are+ numbers beginning with 0 or ending with 0 and+ having a decimal point (#11715). Otherwise they will read as+ YAML numbers and potentially be modified (e.g. 3.10 -> 3.1).++ * Docx writer:++ + Use namespace URI instead of prefix in extractPageLayout (#11697,+ Robertas).++ * ODT writer:++ + Use starmath for math. This improves appearance and+ editability of equations. The main code changes are due to+ @jdpipe (#11470).+ + Image anchoring, percent dimensions, text width resolution+ (#11746, Can H. Tartanoglu). Inline images now emit+ `text:anchor-type=as-char` on their `draw:frame`,+ anchoring the frame as a character so it flows with the+ surrounding text. When both width and height are given and the+ width is a percentage, the width is now resolved against the+ reference document text area width, mirroring how the docx+ writer derives its print width from the reference docx section+ properties. The height follows the aspect ratio.++ * RTF writer:++ + Emit real RTF lists with a list table.+ Lists were written as plain paragraphs with a literal marker and a+ hanging indent, carrying none of the `\ls`/`\ilvl` references or the+ `\listtable`/`\listoverridetable` that the RTF list model (and pandoc's+ own reader) expect, so lists could not round-trip.+ + Allow fontsize to be specified (#11750). The fontsize is specified+ in a variable or metadata field and passed through the renderer via+ a Reader monad.++ * Typst writer:++ + Fold `lang` into `pickTypstAttributes` (#11673).+ This ensures that `lang` attributes will be set for both+ Divs and Spans.+ + Add support for tight terms in Typst writer (#11748, Amir Dekel).+ This just affects whether a blank line is emitted in the markup.+ Note that pandoc's default template contains a show rule for+ terms that will make these blank lines irrelevant, but this change+ allows one to use tight lists with custom templates.+ + Further tight term list improvements. For tight list items+ consisting of just one Plain block, we no longer create a+ `#block` for the definition; this allows it to remain on the+ same line as the term.+ + Emit `divider()` as horizontal rule (#11540).++ * LaTeX template:++ + The `caption` package is included and a default spacing+ set between the caption and the table.++ * Typst template:++ + Remove custom show rule for terms. Instead, we use a set rule+ to set hanging-indent.+ + Remove old `horizontalRule` definition from default template.+ + Polyfill `divider` for typst < 0.15.+ + Allow multiword keywords (#11730, Albert Krewinkel).+ Typst expects single words as keywords, so keywords consisting of+ multiple words must be quoted (and should not be wrapped).++ * HTML template:++ + Remove hard-coded font-size for print CSS. Print CSS now uses+ the inherited font-size.++ * epub.css:++ + Get rid of obsolete #TOC rules (#11747). We don't generate+ anything with the TOC id in epubs. A table of contents is in+ `nav#toc` and we have rules for that.+ + Put clause for all headings before individual h1, h2, ...+ (#11742). This is more logical, since the individual clauses+ are meant to override.++ * Text.Pandoc.Shared:++ + Improve `makeSections` (#11745). Previously it would sometimes+ create doubled section divs. By leaving the inner heading's id+ on the heading itself, and then consolidating the inner and outer+ section divs, we can avoid this undesirable result.+ + `taskListItemToAscii`: handle empty task list case.+ + `taskListItemFromAscii: handle empty task list case (#11599,+ Chirag Dhamange).++ * Text.Pandoc.App.CommandLineOptions:++ + Use `optCSL` and `optBibliography` from Opt (#11741). Previously+ we set `optMetadata` directly, but that had some unintended+ effects, especially in interacting with defaults files. With+ this change, a `--csl` on the command line can override one set+ in a prior defaults file.++ * Text.Pandoc.App:++ + Enable `auto_identifiers` when a table of contents is requested+ (#11041). Table-of-contents entries link to heading identifiers,+ so when `--toc/--table-of-contents` is given, force the+ `auto_identifiers` extension on for the input format even when it+ is off by default (as it now is for typst). This makes+ typst-to-markdown `--toc` produce working links.++ * Text.Pandoc.Writers.Shared:++ + `htmlAttrs` - don't add `data-` prefix for `markdown` (#11685).+ This is necessary for the `markdown_attribute` extension to+ work properly.++ * Ensure that IO error messages go to stderr (#11710).++ * Use emojis 0.1.5, texmath 0.13.2,typst 0.11, typst-symbols 0.3,+ pandoc-types 1.23.1.2, djot 0.1.4.1, commonmark-extensions 0.2.7.1,+ skylighting-format-blaze-html 0.1.2.1.++ * Add Makefile rule to update all-cabal-hashes in flake.lock.++ * MANUAL.txt:++ + Clarify comment about table types (#11719).+ + Small clarification in image section (#11760).+ + Rewrite "A note on security." Clarify the risks of using+ pandoc in a web service and explain how to do so more safely.+ Note some specific vulnerabilities with the pdf-engine `wkhtmltopdf`.+ This incorporates the suggestions made in #11262 and also+ benefits from a report by Kai Aizen.+ + Clarify `native_numbering` extension (#11599).+ + Include Lua filter to set float attribute on tables.+ + Clarify expectations for EPUB metadata (#11723).+ + Improve instructions for specifying EPUB identifier (#11723).+ + Fix typo (#11720, Scott Talbert).++ * Fix typo in lua-filters.md (#11724, Enrico Spinielli).++ * Revamp `flake.nix` to use `haskell.nix` (#11707).+ This allows the project to be built using `nix build` and run+ using `nix run`. @srid deserves credit for most of this.+ stack.yaml is used as a source of truth for the versions to use,+ including for git repositories.++ * Change symlink to regular file for COPYING.md in+ pandoc-cli, pandoc-lua-engine, pandoc-server.+ ## pandoc 3.10 (2026-06-03) * Add `--typst-input` CLI option (#11588). This allows one to
@@ -37,6 +37,13 @@ vertical-align: sub; font-size: smaller; }+h1, h2, h3, h4, h5, h6 {+ text-indent: 0;+ text-align: left;+ font-weight: bold;+ page-break-after: avoid;+ page-break-inside: avoid;+} h1 { margin: 3em 0 0 0; font-size: 2em;@@ -63,13 +70,6 @@ h6 { font-size: 1em; }-h1, h2, h3, h4, h5, h6 {- text-indent: 0;- text-align: left;- font-weight: bold;- page-break-after: avoid;- page-break-inside: avoid;-} ol, ul { margin: 1em 0 0 1.7em;@@ -129,18 +129,6 @@ header { margin-bottom: 4em; text-align: center;-}-#TOC li {- list-style: none;-}-#TOC ul {- padding-left: 1.3em;-}-#TOC > ul {- padding-left: 0;-}-#TOC a:not(:hover) {- text-decoration: none; } code { white-space: pre-wrap;
@@ -69,6 +69,8 @@ $-- $if(tables)$ \usepackage{longtable,booktabs,array}+\usepackage{caption}+\captionsetup[table]{skip=6pt} \newcounter{none} % for unnumbered tables $if(multirow)$ \usepackage{multirow}
@@ -1,5 +1,8 @@ {\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 \fmodern Courier;}} {\colortbl;\red255\green0\blue0;\red0\green0\blue255;}+$if(listtable)$+$listtable$+$endif$ \widowctrl\hyphauto $for(header-includes)$ $header-includes$
@@ -0,0 +1,17 @@+$title$+$for(author)$$author$$sep$; $endfor$+$date$++$for(include-before)$+$include-before$++$endfor$+$if(toc)$+__TOC__++$endif$+$body$+$for(include-after)$++$include-after$+$endfor$
@@ -1,15 +1,14 @@-#let horizontalrule = line(start: (25%,0%), end: (75%,0%))--#show terms.item: it => block(breakable: false)[- #text(weight: "bold")[#it.term]- #block(inset: (left: 1.5em, top: -0.4em))[#it.description]-]+#set terms(hanging-indent: 1.5em) #set table( inset: 6pt, stroke: none ) +#let horizontalrule = line(start: (25%,0%), end: (75%,0%))+// Polyfill divider to allow compiling with typst < 0.15:+#let divider = if "divider" in std { divider } else { horizontalRule }+ #show figure.where( kind: table ): set figure.caption(position: $if(table-caption-position)$$table-caption-position$$else$top$endif$)@@ -61,7 +60,7 @@ ), $endif$ $if(keywords)$- keywords: ($for(keywords)$$keywords$$sep$,$endfor$),+ keywords: ($for(keywords)$"$keywords/nowrap$"$sep$,$endfor$), $endif$ $if(date)$ date: [$date$],
@@ -43,7 +43,6 @@ body { background-color: transparent; color: black;- font-size: 12pt; } p, h2, h3 { orphans: 3;
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: pandoc-version: 3.10+version: 3.10.1 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -93,6 +93,7 @@ data/templates/default.asciidoc data/templates/default.haddock data/templates/default.textile+ data/templates/default.t2t data/templates/default.org data/templates/default.epub2 data/templates/default.epub3@@ -226,6 +227,7 @@ test/command/9002.docx test/command/9603.docx test/command/11113.docx+ test/command/11689.docx test/command/biblio.bib test/command/averroes.bib test/command/A.txt@@ -347,6 +349,7 @@ test/tables.typst test/tables.rst test/tables.rtf+ test/tables.t2t test/tables.txt test/tables.fb2 test/tables.muse@@ -390,6 +393,7 @@ test/writer.rst test/writer.icml test/writer.rtf+ test/writer.t2t test/writer.tei test/writer.texinfo test/writer.fb2@@ -523,16 +527,16 @@ case-insensitive >= 1.2 && < 1.3, citeproc >= 0.13.0.1 && < 0.14, commonmark >= 0.3 && < 0.4,- commonmark-extensions >= 0.2.7 && < 0.3,+ commonmark-extensions >= 0.2.7.1 && < 0.3, commonmark-pandoc >= 0.3 && < 0.4, containers >= 0.6.0.1 && < 0.9, crypton >= 0.30 && < 1.2, data-default >= 0.4 && < 0.9, deepseq >= 1.3 && < 1.6, directory >= 1.2.3 && < 1.4,- doclayout >= 0.5.0.1 && < 0.6,+ doclayout >= 0.5.0.3 && < 0.6, doctemplates >= 0.11 && < 0.12,- emojis >= 0.1.4.1 && < 0.2,+ emojis >= 0.1.5 && < 0.2, exceptions >= 0.8 && < 0.11, file-embed >= 0.0 && < 0.1, filepath >= 1.1 && < 1.6,@@ -544,7 +548,7 @@ mime-types >= 0.1.1 && < 0.2, mtl >= 2.2 && < 2.4, network-uri >= 2.6 && < 2.8,- pandoc-types >= 1.23.1 && < 1.24,+ pandoc-types >= 1.23.1.2 && < 1.24, parsec >= 3.1 && < 3.2, pretty >= 1.1 && < 1.2, pretty-show >= 1.10 && < 1.11,@@ -558,7 +562,7 @@ syb >= 0.1 && < 0.8, tagsoup >= 0.14.6 && < 0.15, temporary >= 1.1 && < 1.4,- texmath >= 0.13.1.2 && < 0.14,+ texmath >= 0.13.2 && < 0.14, text >= 1.1.1.0 && < 2.2, text-conversions >= 0.3 && < 0.4, time >= 1.5 && < 1.17,@@ -570,9 +574,9 @@ zip-archive >= 0.4.3.1 && < 0.5, zlib >= 0.5 && < 0.8, xml >= 1.3.12 && < 1.4,- typst >= 0.10 && < 0.11,+ typst >= 0.11 && < 0.12, vector >= 0.12 && < 0.14,- djot >= 0.1.4 && < 0.2,+ djot >= 0.1.4.1 && < 0.2, asciidoc >= 0.1.0.3 && < 0.2 if !os(windows)@@ -671,6 +675,7 @@ Text.Pandoc.Writers.Org, Text.Pandoc.Writers.AsciiDoc, Text.Pandoc.Writers.Textile,+ Text.Pandoc.Writers.Txt2Tags, Text.Pandoc.Writers.MediaWiki, Text.Pandoc.Writers.DokuWiki, Text.Pandoc.Writers.XWiki,@@ -918,6 +923,7 @@ Tests.Writers.Ms Tests.Writers.AnnotatedTable Tests.Writers.BBCode+ Tests.Writers.Txt2Tags benchmark benchmark-pandoc import: common-executable
@@ -228,6 +228,11 @@ report $ Deprecated "markdown_github" "Use gfm instead." abbrevs <- readAbbreviations (optAbbreviations opts)+ -- Headings need identifiers to be linkable from a table of contents,+ -- so force auto_identifiers on when a TOC is requested (see #11041).+ let readerExts' = if writerTableOfContents writerOptions+ then enableExtension Ext_auto_identifiers readerExts+ else readerExts let readerOpts = def{ readerStandalone = standalone , readerColumns = optColumns opts@@ -236,7 +241,7 @@ , readerDefaultImageExtension = optDefaultImageExtension opts , readerTrackChanges = optTrackChanges opts , readerAbbreviations = abbrevs- , readerExtensions = readerExts+ , readerExtensions = readerExts' , readerStripComments = optStripComments opts , readerTypstInputs = optTypstInputs opts }
@@ -1006,21 +1006,16 @@ , Option "" ["bibliography"] (ReqArg- (\arg opt -> return opt{ optMetadata =- addMeta "bibliography"- (normalizePath arg) $- optMetadata opt })+ (\arg opt -> return opt{ optBibliography =+ optBibliography opt +++ [normalizePath arg] }) "FILE") "" , Option "" ["csl"] (ReqArg (\arg opt -> do- case lookupMeta (T.pack "csl") $ optMetadata opt of- Just _ -> optError $ PandocOptionError- "--csl option can only be used once"- Nothing -> return opt{ optMetadata = addMeta "csl" (normalizePath arg) $- optMetadata opt })+ return opt{ optCSL = Just (normalizePath arg) }) "FILE") ""
@@ -31,7 +31,7 @@ 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.FilePath ( (<.>), (</>), takeDirectory ) import System.Directory ( canonicalizePath ) import Data.Char (toLower, isSpace) import Data.Maybe (fromMaybe)@@ -891,19 +891,18 @@ -> FilePath -> m FilePath fullDefaultsPath dataDir file = do- let fp = if null (takeExtension file)- then addExtension file "yaml"- else file defaultDataDir <- liftIO defaultUserDataDir- let defaultFp = fromMaybe defaultDataDir dataDir </> "defaults" </> fp- fpExists <- fileExists fp- if fpExists- then return fp- else do- defaultFpExists <- fileExists defaultFp- if defaultFpExists- then return defaultFp- else return fp+ let ddir = fromMaybe defaultDataDir dataDir </> "defaults"+ let findFile [] = return file+ findFile (fp:fps) = do+ fpExists <- fileExists fp+ if fpExists+ then return fp+ else findFile fps+ findFile [file,+ file <.> "yaml",+ ddir </> file,+ ddir </> file <.> "yaml"] -- | In a list of lists, append another list in front of every list which -- starts with specific element.
@@ -26,7 +26,7 @@ import qualified Data.Text as T import GHC.Generics (Generic) import System.Exit (ExitCode (..), exitWith)-import System.IO (stderr)+import System.IO (stderr, hPutStrLn) import qualified Text.Pandoc.UTF8 as UTF8 import Text.Printf (printf) import Text.Pandoc.Shared (tshow)@@ -161,7 +161,7 @@ handleError (Left e) = case e of PandocIOError _ err' -> do- putStrLn $ displayException err'+ hPutStrLn stderr $ displayException err' exitWith (ExitFailure 1) _ -> err exitCode (renderError e) where
@@ -662,7 +662,8 @@ getAll "mediawiki" = autoIdExtensions <> extensionsFromList [ Ext_smart ]- getAll "typst" = extensionsFromList [Ext_citations, Ext_smart]+ getAll "typst" = autoIdExtensions <>+ extensionsFromList [Ext_citations, Ext_smart] getAll "djot" = extensionsFromList [Ext_sourcepos] getAll "man" = autoIdExtensions getAll _ = mempty
@@ -305,6 +305,8 @@ x | "! Package inputenc Error" `BC.isPrefixOf` x && program /= "xelatex" -> "\nTry running pandoc with --pdf-engine=xelatex."+ "! Package longtable Error: longtable not in 1-column mode."+ -> "\nTry adding the .float class attribute to your tables." _ -> "" return $ Left $ logmsg <> extramsg (ExitSuccess, Nothing) -> return $ Left ""
@@ -718,74 +718,80 @@ in M.insert (numId, lvl) start (M.filterWithKey notExpired listState) } makeHeaderAnchor $ headerWith ("", addNum classes, []) n ils-bodyPartToBlocks (Paragraph pPr parparts)- | Just True <- pBidi pPr = do- let pPr' = pPr { pBidi = Nothing }- local (\s -> s{ docxInBidi = True })- (bodyPartToBlocks (Paragraph pPr' parparts))- | isCodeDiv pPr = do- transform <- paragraphStyleToTransform pPr- return $- transform $- codeBlock $- T.concat $- map parPartToText parparts- | otherwise = do- ils <- trimSps . smushInlines <$> mapM parPartToInlines parparts- prevParaIls <- gets docxPrevPara- dropIls <- gets docxDropCap- let ils' = dropIls <> ils- let (paraOrPlain, pPr')- | hasStylesInheritedFrom ["Compact"] pPr = (plain, removeStyleNamed "Compact" pPr)- | otherwise = (para, pPr)- if dropCap pPr'- then do modify $ \s -> s { docxDropCap = ils' }- return mempty- else do modify $ \s -> s { docxDropCap = mempty }- let ils'' = (if null prevParaIls then mempty- else prevParaIls <> space) <> ils'- handleInsertion = do- modify $ \s -> s {docxPrevPara = mempty}- transform <- paragraphStyleToTransform pPr'- return $ transform $ paraOrPlain ils''- opts <- asks docxOptions- case (pChange pPr', readerTrackChanges opts) of- _ | null ils'', not (isEnabled Ext_empty_paragraphs opts) ->+bodyPartToBlocks (Paragraph pPr parparts) = do+ let getMainPar+ | Just True <- pBidi pPr = do+ let pPr' = pPr { pBidi = Nothing }+ local (\s -> s{ docxInBidi = True })+ (bodyPartToBlocks (Paragraph pPr' parparts))+ | isCodeDiv pPr = do+ transform <- paragraphStyleToTransform pPr+ return $+ transform $+ codeBlock $+ T.concat $+ map parPartToText parparts+ | otherwise = do+ ils <- trimSps . smushInlines <$> mapM parPartToInlines parparts+ prevParaIls <- gets docxPrevPara+ dropIls <- gets docxDropCap+ let ils' = dropIls <> ils+ let (paraOrPlain, pPr')+ | hasStylesInheritedFrom ["Compact"] pPr = (plain, removeStyleNamed "Compact" pPr)+ | otherwise = (para, pPr)+ if dropCap pPr'+ then do modify $ \s -> s { docxDropCap = ils' } return mempty- (Just (TrackedChange Insertion _), AcceptChanges) ->- handleInsertion- (Just (TrackedChange Insertion _), RejectChanges) -> do- modify $ \s -> s {docxPrevPara = ils''}- return mempty- (Just (TrackedChange Insertion (ChangeInfo _ cAuthor cDate))- , AllChanges) -> do- let attr = ("", ["paragraph-insertion"], addAuthorAndDate cAuthor cDate)- insertMark = spanWith attr mempty- transform <- paragraphStyleToTransform pPr'- return $ transform $- paraOrPlain $ ils'' <> insertMark- (Just (TrackedChange Deletion _), AcceptChanges) -> do- modify $ \s -> s {docxPrevPara = ils''}- return mempty- (Just (TrackedChange Deletion _), RejectChanges) ->- handleInsertion- (Just (TrackedChange Deletion (ChangeInfo _ cAuthor cDate))- , AllChanges) -> do- let attr = ("", ["paragraph-deletion"], addAuthorAndDate cAuthor cDate)- insertMark = spanWith attr mempty- transform <- paragraphStyleToTransform pPr'- return $ transform $- paraOrPlain $ ils'' <> insertMark- _ -> handleInsertion-bodyPartToBlocks (ListItem pPr numId lvl (Just levelInfo) parparts) = do- -- We check whether this current numId has previously been used,- -- since Docx expects us to pick up where we left off.+ else do modify $ \s -> s { docxDropCap = mempty }+ let ils'' = (if null prevParaIls then mempty+ else prevParaIls <> space) <> ils'+ handleInsertion = do+ modify $ \s -> s {docxPrevPara = mempty}+ transform <- paragraphStyleToTransform pPr'+ return $ transform $ paraOrPlain ils''+ opts <- asks docxOptions+ case (pChange pPr', readerTrackChanges opts) of+ _ | null ils'', not (isEnabled Ext_empty_paragraphs opts) ->+ return mempty+ (Just (TrackedChange Insertion _), AcceptChanges) ->+ handleInsertion+ (Just (TrackedChange Insertion _), RejectChanges) -> do+ modify $ \s -> s {docxPrevPara = ils''}+ return mempty+ (Just (TrackedChange Insertion (ChangeInfo _ cAuthor cDate))+ , AllChanges) -> do+ let attr = ("", ["paragraph-insertion"], addAuthorAndDate cAuthor cDate)+ insertMark = spanWith attr mempty+ transform <- paragraphStyleToTransform pPr'+ return $ transform $+ paraOrPlain $ ils'' <> insertMark+ (Just (TrackedChange Deletion _), AcceptChanges) -> do+ modify $ \s -> s {docxPrevPara = ils''}+ return mempty+ (Just (TrackedChange Deletion _), RejectChanges) ->+ handleInsertion+ (Just (TrackedChange Deletion (ChangeInfo _ cAuthor cDate))+ , AllChanges) -> do+ let attr = ("", ["paragraph-deletion"], addAuthorAndDate cAuthor cDate)+ insertMark = spanWith attr mempty+ transform <- paragraphStyleToTransform pPr'+ return $ transform $+ paraOrPlain $ ils'' <> insertMark+ _ -> handleInsertion+ (if pBottomBorder pPr+ then (<> horizontalRule)+ else id)+ <$> getMainPar+bodyPartToBlocks (ListItem pPr numId lvl isRestart (Just levelInfo) parparts) = do+ -- We check whether this current abstract numbering id has previously been+ -- used, since Docx expects us to pick up where we left off -- unless this+ -- item explicitly restarts numbering (see #8367). listState <- gets docxListState let startFromState = M.lookup (numId, lvl) listState Level _ fmt txt startFromLevelInfo = levelInfo start = case startFromState of- Just n -> n + 1- Nothing -> fromMaybe 1 startFromLevelInfo+ Just n | not isRestart -> n + 1+ _ -> fromMaybe 1 startFromLevelInfo kvs = [ ("level", lvl) , ("num-id", numId) , ("format", fmt)@@ -799,7 +805,7 @@ in M.insert (numId, lvl) start (M.filterWithKey notExpired listState) } blks <- bodyPartToBlocks (Paragraph pPr parparts) return $ divWith ("", ["list-item"], kvs) blks-bodyPartToBlocks (ListItem pPr _ _ _ parparts) =+bodyPartToBlocks (ListItem pPr _ _ _ _ parparts) = let pPr' = pPr {pStyle = constructBogusParStyleData "list-paragraph": pStyle pPr} in bodyPartToBlocks $ Paragraph pPr' parparts
@@ -96,6 +96,7 @@ lookupAttrBy, parseXMLElement, elChildren,+ onlyElems, QName(QName, qName), Content(Elem), Element(..))@@ -283,6 +284,7 @@ , pChange :: Maybe TrackedChange , pBidi :: Maybe Bool , pKeepNext :: Bool+ , pBottomBorder :: Bool } deriving Show @@ -295,13 +297,14 @@ , pChange = Nothing , pBidi = Just False , pKeepNext = False+ , pBottomBorder = False } data BodyPart = Paragraph ParagraphStyle [ParPart] | Heading Int ParaStyleName ParagraphStyle T.Text T.Text (Maybe Level) [ParPart]- | ListItem ParagraphStyle T.Text T.Text (Maybe Level) [ParPart]+ | ListItem ParagraphStyle T.Text T.Text Bool (Maybe Level) [ParPart] | Tbl (Maybe T.Text) T.Text TblGrid TblLook [Row] | Captioned ParagraphStyle [ParPart] BodyPart | HRule@@ -616,6 +619,28 @@ _ -> lookup ilvl $ map (\l@(Level i _ _ _) -> (i, l)) lvls +-- | Given a @numId@ and level, return the abstract numbering id (the stable+-- identifier shared by all numbering instances based on the same abstract+-- numbering definition) together with a flag indicating whether this+-- particular instance restarts numbering at this level (via a+-- @w:startOverride@). Word represents "restart numbering" by pointing the+-- first item of the restarted list at a new numId that shares the abstract+-- numbering of the original list but carries a startOverride; the remaining+-- items keep using the original numId. Keying list continuation off the+-- abstract numbering id (rather than the numId) lets those items be treated+-- as one continuous, restarted list. See #8367.+lookupNumberingInfo :: T.Text -> T.Text -> Numbering -> (T.Text, Bool)+lookupNumberingInfo numId ilvl (Numbering _ numbs _) =+ case lookup numId $+ map (\(Numb nid absnumid ovr) -> (nid, (absnumid, ovr))) numbs of+ Nothing -> (numId, False)+ Just (absNumId, ovrrides) ->+ let isRestart = case lookup ilvl $+ map (\lo@(LevelOverride i _ _) -> (i, lo)) ovrrides of+ Just (LevelOverride _ (Just _) _) -> True+ _ -> False+ in (absNumId, isRestart)+ loElemToLevelOverride :: NameSpaces -> Element -> Maybe LevelOverride loElemToLevelOverride ns element | isElem ns "w" "lvlOverride" element = do@@ -817,8 +842,10 @@ mkListItem :: ParagraphStyle -> Text -> Text -> [ParPart] -> D BodyPart mkListItem parstyle numId lvl parparts = do- lvlInfo <- lookupLevel numId lvl <$> asks envNumbering- return $ ListItem parstyle numId lvl lvlInfo parparts+ numbering <- asks envNumbering+ let lvlInfo = lookupLevel numId lvl numbering+ (absNumId, isRestart) = lookupNumberingInfo numId lvl numbering+ return $ ListItem parstyle absNumId lvl isRestart lvlInfo parparts pStyleIndentation :: ParagraphStyle -> Maybe ParIndentation pStyleIndentation style = (getParStyleField indent . pStyle) style@@ -874,7 +901,8 @@ elemToBodyPart ns element | isElem ns "w" "p" element , Just (numId, lvl) <- getNumInfo ns element = do- lvlInfo <- lookupLevel numId lvl <$> asks envNumbering+ numbering <- asks envNumbering+ let lvlInfo = lookupLevel numId lvl numbering parstyle <- elemToParagraphStyle ns element <$> asks envParStyles <*> asks envNumbering@@ -882,23 +910,26 @@ case pHeading parstyle of Nothing -> mkListItem parstyle numId lvl parparts Just (parstylename, lev)- -> return $ Heading lev parstylename parstyle numId lvl lvlInfo parparts+ -> let (absNumId, _) = lookupNumberingInfo numId lvl numbering+ in return $ Heading lev parstylename parstyle absNumId lvl lvlInfo parparts elemToBodyPart ns element | isElem ns "w" "p" element- , [Elem ppr] <- elContent element+ , [ppr] <- elChildren element , isElem ns "w" "pPr" ppr- , [Elem pbdr] <- elContent ppr+ , [pbdr] <- elChildren ppr , isElem ns "w" "pBdr" pbdr+ , [bot] <- elChildren pbdr+ , isElem ns "w" "bottom" bot = return HRule -- for this style of horizontal rule, see -- https://support.microsoft.com/en-us/office/insert-a-horizontal-line-9bf172f6-5908-4791-9bb9-2c952197b1a9 elemToBodyPart ns element -- pandoc-style horizontal rule | isElem ns "w" "p" element- , [Elem r] <- elContent element+ , [r] <- elChildren element , isElem ns "w" "r" r- , [Elem pict] <- elContent r+ , [pict] <- elChildren r , isElem ns "w" "pict" pict- , [Elem rect] <- elContent pict+ , [rect] <- elChildren pict , isElem ns "v" "rect" rect = return HRule elemToBodyPart ns element@@ -923,8 +954,10 @@ mkListItem parstyle numId lvl parparts Just (parstylename, lev) -> do let (numId, lvl) = fromMaybe ("","") $ pNumInfo parstyle- lvlInfo <- lookupLevel numId lvl <$> asks envNumbering- return $ Heading lev parstylename parstyle numId lvl lvlInfo parparts+ numbering <- asks envNumbering+ let lvlInfo = lookupLevel numId lvl numbering+ (absNumId, _) = lookupNumberingInfo numId lvl numbering+ return $ Heading lev parstylename parstyle absNumId lvl lvlInfo parparts Nothing -> return $ Paragraph parstyle parparts elemToBodyPart ns element | isElem ns "w" "tbl" element = do@@ -1376,6 +1409,10 @@ getTrackedChange ns , pBidi = checkOnOff ns pPr (elemName ns "w" "bidi") , pKeepNext = isJust $ findChildByName ns "w" "keepNext" pPr+ , pBottomBorder = case (onlyElems . elContent) <$>+ findChildByName ns "w" "pBdr" pPr of+ Just [x] -> isElem ns "w" "bottom" x+ _ -> False } | otherwise = defaultParagraphStyle
@@ -528,10 +528,11 @@ tableRows = many1 tableRow tableRow :: PandocMonad m => DWParser m [(Alignment, B.Blocks)]-tableRow = many1Till tableCell tableRowEnd+tableRow = tableCellSeparator *> many1 tableCell <* tableRowEnd -tableRowEnd :: PandocMonad m => DWParser m Char-tableRowEnd = try $ tableCellSeparator <* manyTill spaceChar eol+-- DokuWiki just ignores stuff after the end of a table row (#11739)+tableRowEnd :: PandocMonad m => DWParser m ()+tableRowEnd = void $ manyTill anyChar eol tableCellSeparator :: PandocMonad m => DWParser m Char tableCellSeparator = char '|' <|> char '^'@@ -542,8 +543,7 @@ cellContent = do -- https://www.dokuwiki.org/wiki:syntax#tables -- DokuWiki represents the alignment of cells with two spaces padding.- tableCellSeparator- cellInline <- manyTill inlineUnconsolidatedWhitespace (lookAhead tableCellSeparator)+ cellInline <- manyTill inlineUnconsolidatedWhitespace tableCellSeparator let left = [B.space, B.space] `isPrefixOf` cellInline let right = [B.space, B.space] `isSuffixOf` cellInline let alignment = case (left, right) of
@@ -649,18 +649,13 @@ pCodeBlock :: PandocMonad m => TagParser m Blocks pCodeBlock = try $ do TagOpen _ attr' <- pSatisfy (matchTagOpen "pre" [])- -- if the `pre` has no attributes, try if it is followed by a `code`- -- element and use those attributes if possible.- attr <- case attr' of- _:_ -> pure (toAttr attr')- [] -> option nullAttr $ do- TagOpen _ codeAttr <- pSatisfy (matchTagOpen "code" [])- pure $ toAttr- [ (k, v') | (k, v) <- codeAttr- -- strip language from class- , let v' = if k == "class"- then fromMaybe v (T.stripPrefix "language-" v)- else v ]+ -- merge attributes of `pre` and `code` tags+ TagOpen _ codeAttr <- pSatisfy (matchTagOpen "code" [])+ let stripLanguagePrefix x = fromMaybe x (T.stripPrefix "language-" x)+ let modifyClasses f ("class",v) =+ ("class", T.unwords . map f . T.words $ v)+ modifyClasses _ (k,v) = (k,v)+ let attr = toAttr $ map (modifyClasses stripLanguagePrefix) $ codeAttr <> attr' contents <- manyTill pAny (pCloses "pre" <|> eof) let rawText = T.concat $ map tagToText contents -- drop trailing newline if any
@@ -590,7 +590,7 @@ hypertargetInline :: PandocMonad m => LP m Inlines hypertargetInline = try $ do ref <- untokenize <$> braced- ils <- grouped inline+ ils <- tok return $ spanWith (ref, [], []) ils newToggle :: (Monoid a, PandocMonad m) => [Tok] -> LP m a
@@ -982,6 +982,8 @@ orderedList :: PandocMonad m => MarkdownParser m (F Blocks) orderedList = try $ do (start, style, delim) <- lookAhead (orderedListStart Nothing)+ ctx <- stateParserContext <$> getState+ when (ctx == ListItemState) $ guard (start == 1) unless (style `elem` [DefaultStyle, Decimal, Example] && delim `elem` [DefaultDelim, Period]) $ guardEnabled Ext_fancy_lists
@@ -368,15 +368,11 @@ hasEmphChanged :: PropertyTriple -> Bool hasEmphChanged = swing any [ hasChanged isEmphasised- , hasChangedM pitch , hasChanged underline ] hasChanged property triple@(_, property -> newProperty, _) = (/= Just newProperty) (lookupPreviousValue property triple)-- hasChangedM property triple@(_, textProps,_) =- fromMaybe False $ (/=) <$> property textProps <*> lookupPreviousValueM property triple lookupPreviousValue f = lookupPreviousStyleValue (fmap f . textProperties)
@@ -25,6 +25,7 @@ import qualified Data.Map as M import Data.Maybe (fromMaybe, maybeToList, isJust, isNothing, catMaybes) import Data.Sequence (ViewR (..), viewr)+import qualified Data.Set as Set import Data.Text (Text) import qualified Data.Text as T import Text.Printf (printf)@@ -170,7 +171,7 @@ return doc resolveBlockSubstitutions :: PandocMonad m => Block -> RSTParser m Block-resolveBlockSubstitutions x@(Para [Link _attr _ (s,_)])+resolveBlockSubstitutions (Para [Link _attr ils (s,_)]) | Just ref <- T.stripPrefix "##SUBST##" s = do substTable <- stateSubstitutions <$> getState let key@(Key key') = toKey $ stripFirstAndLast ref@@ -178,7 +179,7 @@ Nothing -> do pos <- getPosition logMessage $ ReferenceNotFound (tshow key') pos- return x+ return $ Para ils Just target -> case B.toList target of [bl] -> return bl@@ -186,7 +187,10 @@ resolveBlockSubstitutions x = return x resolveReferences :: PandocMonad m => Inline -> RSTParser m Inline-resolveReferences x@(Link _ ils (s,_))+resolveReferences = resolveReferences' Set.empty++resolveReferences' :: PandocMonad m => Set.Set Key -> Inline -> RSTParser m Inline+resolveReferences' seen x@(Link _ ils (s,_)) | Just ref <- T.stripPrefix "##REF##" s = do let isAnonKey (Key (T.uncons -> Just ('_',_))) = True isAnonKey _ = False@@ -199,11 +203,17 @@ [] -> mzero -- TODO log? (k:_) -> return k else return $ toKey ref- ((src,tit), attr) <- lookupKey [] key- -- if anonymous link, remove key so it won't be used again- when (isAnonKey key) $ updateState $ \st ->- st{ stateKeys = M.delete key keyTable }- return $ Link attr ils (src, tit)+ if key `Set.member` seen+ then do+ pos <- getPosition+ let Key key' = key+ logMessage $ CircularReference key' pos+ return x+ else do+ ((src,tit), attr) <- lookupKey [] key+ when (isAnonKey key) $ updateState $ \st ->+ st{ stateKeys = M.delete key keyTable }+ resolveReferences' (Set.insert key seen) (Link attr ils (src, tit)) | Just ref <- T.stripPrefix "##NOTE##" s = do state <- getState let notes = stateNotes state@@ -229,18 +239,24 @@ | Just ref <- T.stripPrefix "##SUBST##" s = do substTable <- stateSubstitutions <$> getState let key@(Key key') = toKey $ stripFirstAndLast ref- case M.lookup key substTable of+ if key `Set.member` seen+ then do+ pos <- getPosition+ logMessage $ CircularReference key' pos+ return $ Span ("",[],[]) ils+ else case M.lookup key substTable of Nothing -> do pos <- getPosition logMessage $ ReferenceNotFound (tshow key') pos- return x- Just target -> case- B.toList target of+ return $ Span ("",[],[]) ils+ Just target -> do+ resolved <- case B.toList target of [Para [t]] -> return t [Para xs] -> return $ Span nullAttr xs bls -> return $ Span nullAttr $ blocksToInlines bls+ resolveReferences' (Set.insert key seen) resolved | otherwise = return x-resolveReferences x = return x+resolveReferences' _ x = return x parseCitation :: PandocMonad m => (Text, Text) -> RSTParser m (Inlines, [Blocks])
@@ -76,6 +76,13 @@ , sListTable :: ListTable , sListOverrideTable :: ListTable , sEatChars :: Int+ , sListText :: Bool -- True after a \listtext group,+ -- marking the start of a new+ -- list item+ , sPnActive :: Bool -- True while legacy \pn+ -- paragraph numbering is in+ -- effect; every paragraph in+ -- scope is its own list item } deriving (Show) instance Default RTFState where@@ -92,6 +99,8 @@ , sListTable = mempty , sListOverrideTable = mempty , sEatChars = 0+ , sListText = False+ , sPnActive = False } type FontTable = IntMap.IntMap FontFamily@@ -452,6 +461,7 @@ case firsttok of Tok _ (ControlWord "shppict" _) -> inGroup (foldM processTok bs toks) Tok _ (ControlWord "shpinst" _) -> inGroup (foldM processTok bs toks)+ Tok _ (ControlWord "pn" _) -> bs <$ handlePn toks _ -> bs <$ (do oldTextContent <- sTextContent <$> getState processTok mempty (Tok pos (Grouped toks)) updateState $ \st -> st{ sTextContent = oldTextContent })@@ -474,10 +484,24 @@ bs <$ inGroup (handlePict toks) Grouped (Tok _ (ControlWord "stylesheet" _) : toks) -> bs <$ inGroup (handleStylesheet toks)- Grouped (Tok _ (ControlWord "listtext" _) : _) -> do+ Grouped (Tok _ (ControlWord cw _) : _)+ -- \listtext (Word 2000+) and \pntext (legacy Word 95-style+ -- paragraph numbering) are both auto-generated list-marker+ -- destinations. Their visible text (the bullet or number) is+ -- dropped; we synthesize markers ourselves. The marker also+ -- appears before the paragraph's \ls/\ilvl, so processing its+ -- contents would otherwise capture the marker text as the+ -- paragraph's first run, hiding the list properties from+ -- emitBlocks (see #11686).+ | cw == "listtext" || cw == "pntext" -> do -- eject any previous list items...sometimes TextEdit -- doesn't put in a \par- emitBlocks bs+ bs' <- emitBlocks bs+ -- A \listtext/\pntext group marks the beginning of a new list+ -- item. A list paragraph lacking one is a continuation+ -- paragraph of the current item (see emitBlocks).+ updateState $ \s -> s{ sListText = True }+ pure bs' Grouped (Tok _ (ControlWord "pgdsc" _) : _) -> pure bs Grouped (Tok _ (ControlWord "colortbl" _) : _) -> pure bs Grouped (Tok _ (ControlWord "listtable" _) : toks) ->@@ -650,6 +674,9 @@ ControlWord "pard" _ -> do newbs <- emitBlocks bs modifyGroup (const def)+ -- \pard resets paragraph properties, ending any legacy \pn+ -- paragraph numbering that was in effect.+ updateState $ \s -> s{ sPnActive = False } getStyleFormatting 0 >>= foldM processTok newbs ControlWord "par" _ -> emitBlocks bs _ -> pure bs@@ -735,7 +762,11 @@ emitBlocks :: PandocMonad m => Blocks -> RTFParser m Blocks emitBlocks bs = do annotatedToks <- reverse . sTextContent <$> getState- updateState $ \s -> s{ sTextContent = [] }+ -- A \listtext group marks a new item; legacy \pn paragraph numbering+ -- (sPnActive) likewise makes every paragraph its own item. Note that+ -- sPnActive persists across \par (until \pard) and so is not reset here.+ hadListText <- (||) <$> (sListText <$> getState) <*> (sPnActive <$> getState)+ updateState $ \s -> s{ sTextContent = [], sListText = False } let justCode = def{ gFontFamily = Just Modern } let prop = case annotatedToks of [] -> def@@ -760,10 +791,18 @@ (List lo parentlevel _lt items : cs) | lo == lst , parentlevel == level- -- add another item to existing list- -> do updateState $ \s ->+ -- A paragraph belonging to the current list level is+ -- either a new item (preceded by a \listtext group) or a+ -- continuation paragraph of the current item (no+ -- \listtext). This is what allows multi-paragraph list+ -- items to be parsed correctly.+ -> do let items' = case items of+ (i:is) | not hadListText+ -> (i <> newbs) : is+ _ -> newbs : items+ updateState $ \s -> s{ sListStack =- List lo level listType (newbs:items) : cs }+ List lo level listType items' : cs } pure mempty | lo /= lst || level < parentlevel -- close parent list and add new list@@ -901,6 +940,47 @@ Nothing -> Bullet Just numStyle -> Ordered (start,numStyle,Period) return $ IntMap.insert lvl listType levelTable++-- Legacy Word-95 style paragraph numbering: {\*\pn ...}. This+-- destination configures the auto-number (or bullet) for the current+-- list paragraph. Unlike modern lists there is no \listtable, so we+-- synthesize an entry in the list override table here. The \ls and+-- \ilvl that key the table appear inside the \pn group itself, as does+-- the numbering style (\pnlvlblt for a bullet, otherwise \pndec,+-- \pnucltr, etc.). See #11686.+handlePn :: PandocMonad m => [Tok] -> RTFParser m ()+handlePn toks = do+ let ls = headDef 0 [n | Tok _ (ControlWord "ls" (Just n)) <- toks]+ let lvl = headDef 0 [n | Tok _ (ControlWord "ilvl" (Just n)) <- toks]+ let start = headDef 1 [n | Tok _ (ControlWord "pnstart" (Just n)) <- toks]+ let isBullet = not $ null [() | Tok _ (ControlWord "pnlvlblt" _) <- toks]+ let pnStyle (Tok _ (ControlWord w _)) =+ case w of+ "pndec" -> Just Decimal+ "pnucltr" -> Just UpperAlpha+ "pnlcltr" -> Just LowerAlpha+ "pnucrm" -> Just UpperRoman+ "pnlcrm" -> Just LowerRoman+ _ -> Nothing+ pnStyle _ = Nothing+ let mbNumberStyle+ | isBullet = Nothing+ | otherwise = case mapMaybe pnStyle toks of+ (s:_) -> Just s+ [] -> Just Decimal -- \pnlvlbody default+ let listType = case mbNumberStyle of+ Nothing -> Bullet+ Just numStyle -> Ordered (start, numStyle, Period)+ -- Don't clobber a type already registered via a real \listtable.+ -- \pn is a paragraph property that stays in effect (auto-numbering or+ -- bulleting every paragraph) until reset by \pard, so flag it so that+ -- each following paragraph becomes its own list item.+ updateState $ \s ->+ s{ sListOverrideTable =+ IntMap.insertWith (\new old -> IntMap.union old new) ls+ (IntMap.singleton lvl listType)+ (sListOverrideTable s)+ , sPnActive = True } handleListOverrideTable :: PandocMonad m => [Tok] -> RTFParser m () handleListOverrideTable toks = mapM_ handleListOverride toks
@@ -31,6 +31,7 @@ import Text.Pandoc.Error (PandocError(..)) import Text.Pandoc.Translations (Term(References), translateTerm) import Text.Pandoc.Shared (tshow, blocksToInlines)+import Text.Pandoc.Parsing (registerHeader, reportLogMessages) import Control.Monad.Except (throwError) import Control.Monad (MonadPlus (mplus), void, guard, foldM) import Control.Monad.Trans (lift)@@ -79,7 +80,7 @@ Right content -> do let content' = fixNesting content let labs = findLabels [content']- runParserT pPandoc defaultPState{ sLabels = labs }+ runParserT pPandoc defaultPState{ sLabels = labs, sOptions = opts } inputName [content'] >>= either (throwError . PandocParseError . T.pack . show) pure @@ -188,6 +189,7 @@ (if null keywords then id else B.setMeta "keywords" keywords) $ meta+ reportLogMessages pure $ Pandoc meta' (B.toList bs) pBlocks :: PandocMonad m => P m B.Blocks@@ -264,8 +266,9 @@ ,("heading", \_ mbident fields -> do body <- getField "body" fields lev <- getField "level" fields <|> pure 1- B.headerWith (fromMaybe "" mbident,[],[]) lev- <$> pWithContents pInlines body)+ ils <- pWithContents pInlines body+ attr <- registerHeader (fromMaybe "" mbident,[],[]) ils+ pure $ B.headerWith attr lev ils) ,("quote", \_ _ fields -> do getField "block" fields >>= guard body <- getField "body" fields >>= pWithContents pBlocks@@ -385,6 +388,7 @@ >> M.lookup "angle" fields ) of Nothing -> pure B.horizontalRule _ -> pure mempty)+ ,("divider", \_ _ _fields -> pure B.horizontalRule) ,("numbering", \_ _ fields -> do numStyle <- getField "numbering" fields (nums :: V.Vector Integer) <- getField "numbers" fields
@@ -16,10 +16,13 @@ where import Control.Monad (MonadPlus) import Control.Monad.Reader (lift)+import Data.Default (def) import qualified Data.Foldable as F import qualified Data.Map as M import Data.Maybe (fromMaybe) import Data.Sequence (Seq)+import Data.Set (Set)+import qualified Data.Set as Set import Data.Text (Text) import Text.Parsec ( ParsecT, getInput, setInput, tokenPrim )@@ -27,18 +30,38 @@ ( Identifier, Content(Elt), FromVal(..), Val(VNone) ) import Text.Pandoc.Class.PandocMonad ( PandocMonad, report ) import Text.Pandoc.Logging (LogMessage(..))+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Parsing.Capabilities+ ( HasReaderOptions(..), HasIdentifierList(..), HasLogMessages(..) ) import Text.Pandoc.Definition data PState = PState { sLabels :: [Text]- , sMeta :: Meta }+ , sMeta :: Meta+ , sOptions :: ReaderOptions+ , sIdentifiers :: Set Text+ , sLogMessages :: [LogMessage] } deriving (Show) +instance HasReaderOptions PState where+ extractReaderOptions = sOptions++instance HasIdentifierList PState where+ extractIdentifierList = sIdentifiers+ updateIdentifierList f st = st{ sIdentifiers = f (sIdentifiers st) }++instance HasLogMessages PState where+ addLogMessage m st = st{ sLogMessages = m : sLogMessages st }+ getLogMessages = reverse . sLogMessages+ defaultPState :: PState defaultPState = PState { sLabels = []- , sMeta = mempty }+ , sMeta = mempty+ , sOptions = def+ , sIdentifiers = Set.empty+ , sLogMessages = [] } type P m a = ParsecT [Content] PState m a -- state tracks a list of labels in the document
@@ -569,16 +569,25 @@ | all (\case Header level' _ _ -> level' > level _ -> True) ys- , "column" `notElem` dclasses- , "columns" `notElem` dclasses- , "fragment" `notElem` dclasses = do+ , "section" `elem` dclasses+ || ("column" `notElem` dclasses &&+ "columns" `notElem` dclasses &&+ "fragment" `notElem` dclasses &&+ "cell" `notElem` dclasses) = do inner <- go (Header level hattr title':ys) rest <- go xs return $ case inner of- [Div divattr'@(dident',_,_) zs]- | T.null dident || T.null dident' || dident == dident'- -> Div (combineAttr divattr' divattr) zs : rest+ [Div divattr'@(dident',_,_) zs@(Header level' hattr' title'' : zs')]+ | dident == dident'+ -> Div (combineAttr divattr' divattr) zs : rest+ | (_,dclasses',dkvs) <- combineAttr divattr' divattr+ , ("",hclasses,hkvs) <- hattr'+ -> if T.null dident+ then Div (dident',dclasses',dkvs) zs : rest+ else Div (dident,dclasses',dkvs)+ (Header level' (dident',hclasses,hkvs) title''+ : zs') : rest _ -> Div divattr inner : rest go (Div attr xs : rest) = do xs' <- go xs@@ -663,8 +672,13 @@ taskListItemFromAscii = handleTaskListItem fromMd where fromMd (Str "[" : Space : Str "]" : Space : is) = Str "☐" : Space : is+ fromMd (Str "[ ]" : Space : is) = Str "☒" : Space : is fromMd (Str "[x]" : Space : is) = Str "☒" : Space : is fromMd (Str "[X]" : Space : is) = Str "☒" : Space : is+ fromMd [Str "[" , Space , Str "]"] = [Str "☐"]+ fromMd [Str "[ ]"] = [Str "☐"]+ fromMd [Str "[x]"] = [Str "☒"]+ fromMd [Str "[X]"] = [Str "☒"] fromMd is = is -- | Convert a list item containing text starting with @U+2610 BALLOT BOX@@@ -672,6 +686,10 @@ taskListItemToAscii :: Extensions -> [Block] -> [Block] taskListItemToAscii = handleTaskListItem toMd where+ toMd [Str "☐"] = [rawMd "[ ]"]+ toMd [Str "☒"] = [rawMd "[x]"]+ toMd [Str "❏"] = [rawMd "[ ]"]+ toMd [Str "✓"] = [rawMd "[x]"] toMd (Str "☐" : Space : is) = rawMd "[ ]" : Space : is toMd (Str "☒" : Space : is) = rawMd "[x]" : Space : is toMd (Str "❏" : Space : is) = rawMd "[ ]" : Space : is
@@ -75,6 +75,7 @@ , writeTEI , writeTexinfo , writeTextile+ , writeTxt2Tags , writeTypst , writeXML , writeXWiki@@ -135,6 +136,7 @@ import Text.Pandoc.Writers.TEI import Text.Pandoc.Writers.Texinfo import Text.Pandoc.Writers.Textile+import Text.Pandoc.Writers.Txt2Tags import Text.Pandoc.Writers.Typst import Text.Pandoc.Writers.XML import Text.Pandoc.Writers.XWiki@@ -202,6 +204,7 @@ ,("xwiki" , TextWriter writeXWiki) ,("zimwiki" , TextWriter writeZimWiki) ,("textile" , TextWriter writeTextile)+ ,("t2t" , TextWriter writeTxt2Tags) ,("typst" , TextWriter writeTypst) ,("rtf" , TextWriter writeRTF) ,("org" , TextWriter writeOrg)
@@ -115,8 +115,7 @@ -- 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')+ Just sectpr' -> setWmlPrefix sectpr' Nothing -> mknode "w:sectPr" [] [ mknode "w:footnotePr" [] [ mknode "w:numRestart" [("w:val","eachSect")] () ]@@ -477,6 +476,22 @@ go (Elem el) | p (elName el) = Elem (modifyAtPath ps f el) go c = c +setWmlPrefix :: Element -> Element+setWmlPrefix el =+ add_attrs (map fixWmlAttr (elAttribs el)) $+ mknode "w:sectPr" [] (map fixWmlChild (elChildren el))+ where+ fixWmlAttr attr = attr{ attrKey = fixWmlQName (attrKey attr) }+ fixWmlQName qn+ | isWmlNamespace qn = qn{ qPrefix = Just "w" }+ | otherwise = qn+ fixWmlChild e+ | qPrefix (elName e) /= Just "w"+ , isWmlNamespace (elName e) =+ e{ elName = fixWmlQName (elName e)+ , elAttribs = map fixWmlAttr (elAttribs e) }+ | otherwise = e+ -- | Load reference and distribution archives loadArchives :: PandocMonad m => WriterOptions@@ -496,12 +511,18 @@ readDataFile "reference.docx" return (refArchive, distArchive, username, utctime) +isWmlNamespace :: QName -> Bool+isWmlNamespace qn =+ qURI qn == Just+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main" ||+ qURI qn == Just "http://purl.oclc.org/ooxml/wordprocessingml/main"+ -- | 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 wname f qn = isWmlNamespace qn && f (qName qn) let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc -- Gets the template size
@@ -56,6 +56,7 @@ import Text.Pandoc.URI import Text.Pandoc.Slides import Text.Pandoc.Walk (query, walk, walkM)+import Text.Pandoc.Writers.LaTeX.Util (getAccumulatedNotes) import Text.Pandoc.Writers.LaTeX.Caption (getCaption) import Text.Pandoc.Writers.LaTeX.Table (tableToLaTeX) import Text.Pandoc.Writers.LaTeX.Citation (citationsToNatbib,@@ -64,7 +65,7 @@ PdfStandard (..)) import Text.Pandoc.Writers.LaTeX.Lang (toBabel) import Text.Pandoc.Writers.LaTeX.Util (stringToLaTeX, StringContext(..),- toLabel, inCmd,+ toLabel, inCmd, withExternalNotes, wrapDiv, hypertarget, labelFor, getListingsLanguage, mbBraced) import Text.Pandoc.Writers.Shared@@ -662,8 +663,9 @@ let spacing = if all (isTightList . snd) lst then text "\\tightlist" else empty+ notes <- getAccumulatedNotes return $ text ("\\begin{description}" <> inc) $$ spacing $$ vcat items $$- "\\end{description}"+ "\\end{description}" $$ notes blockToLaTeX HorizontalRule = return "\\begin{center}\\rule{0.5\\linewidth}{0.5pt}\\end{center}"@@ -677,7 +679,7 @@ (Ann.toTable attr blkCapt specs thead tbodies tfoot) blockToLaTeX (Figure (ident, _, kvs) captnode body) = do opts <- gets stOptions- (capt, captForLof, footnotes) <- getCaption inlineListToLaTeX True captnode+ (capt, captForLof) <- withExternalNotes $ getCaption inlineListToLaTeX captnode lab <- labelFor ident let caption = "\\caption" <> captForLof <> braces capt <> lab placement = case lookup "latex-placement" kvs of@@ -703,6 +705,7 @@ Table {} -> Any True _ -> Any False) st <- get+ footnotes <- getAccumulatedNotes return $ (case () of _ | containsTable body -> -- placing a longtable in a figure or center environment does@@ -762,9 +765,9 @@ defListItemToLaTeX :: PandocMonad m => ([Inline], [[Block]]) -> LW m (Doc Text) defListItemToLaTeX (term, defs) = do -- needed to turn off 'listings' because it breaks inside \item[...]:- modify $ \s -> s{stInItem = True}- term' <- inlineListToLaTeX term- modify $ \s -> s{stInItem = False}+ modify $ \s -> s{ stInItem = True }+ term' <- withExternalNotes $ inlineListToLaTeX term+ modify $ \s -> s{ stInItem = False } -- put braces around term if it contains an internal link, -- since otherwise we get bad bracket interactions: \item[\hyperref[..] let isInternalLink (Link _ _ (src,_))
@@ -21,29 +21,20 @@ import Text.DocLayout (Doc, brackets, empty) import Text.Pandoc.Shared import Text.Pandoc.Walk-import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)-import Text.Pandoc.Writers.LaTeX.Types- ( LW, WriterState (stExternalNotes, stNotes, stInCaption) )+import Text.Pandoc.Writers.LaTeX.Types ( LW, WriterState (stInCaption) ) --- | Produces the components of a LaTeX 'caption' command. Returns a triple--- containing the caption text, the short caption for the list of--- figures/tables, and the footnote definitions.+-- | Produces the components of a LaTeX 'caption' command. Returns a pair+-- containing the caption text and the short caption for the list of+-- figures/tables. getCaption :: PandocMonad m => ([Inline] -> LW m (Doc Text)) -- ^ inlines converter- -> Bool -- ^ whether to extract notes -> Caption- -> LW m (Doc Text, Doc Text, Doc Text)-getCaption inlineListToLaTeX externalNotes (Caption maybeShort long) = do+ -> LW m (Doc Text, Doc Text)+getCaption inlineListToLaTeX (Caption maybeShort long) = do modify $ \st -> st{ stInCaption = True } let long' = blocksToInlines long- oldExternalNotes <- gets stExternalNotes- modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] } capt <- inlineListToLaTeX long'- footnotes <- if externalNotes- then notesToLaTeX <$> gets stNotes- else return empty- modify $ \st -> st{ stExternalNotes = oldExternalNotes, stNotes = [] } -- We can't have footnotes in the list of figures/tables, so remove them: let getNote (Note _) = Any True getNote _ = Any False@@ -55,4 +46,4 @@ else return empty Just short -> toShortCapt short modify $ \st -> st{ stInCaption = False }- return (capt, captForLof, footnotes)+ return (capt, captForLof)
@@ -1,5 +1,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} {- | Module : Text.Pandoc.Writers.LaTeX.Table Copyright : Copyright (C) 2006-2024 John MacFarlane@@ -24,17 +26,17 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Definition import Text.DocLayout- ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest- , text, vcat, ($$) )+ ( Doc, braces, brackets, cr, empty, hcat, hsep, isEmpty, literal, nest+ , text, vcat, ($$)) import Text.Pandoc.Shared (splitBy, tshow) import Text.Pandoc.Walk (walk, query) import Data.Monoid (Any(..)) import Text.Pandoc.Writers.LaTeX.Caption (getCaption)-import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX) import Text.Pandoc.Writers.LaTeX.Types- ( LW, WriterState (stBeamer, stExternalNotes, stInMinipage, stMultiRow- , stNotes, stTable, stOptions) )-import Text.Pandoc.Writers.LaTeX.Util (labelFor)+ ( LW, WriterState (stBeamer, stInMinipage, stMultiRow+ , stTable, stOptions) )+import Text.Pandoc.Writers.LaTeX.Util (labelFor, withExternalNotes,+ getAccumulatedNotes) import Text.Printf (printf) import qualified Text.Pandoc.Builder as B import qualified Text.Pandoc.Writers.AnnotatedTable as Ann@@ -46,30 +48,103 @@ -> Ann.Table -> LW m (Doc Text) tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do+ let (Ann.Table (ident, classes, kvs) caption specs thead tbodies tfoot) = tbl+ let placement = brackets $ maybe mempty (text . T.unpack)+ $ lookup "latex-placement" kvs+ -- if the float class is included in table attributes, we generate a floating+ -- table environment; otherwise we use longtable+ beamer <- gets stBeamer+ let float = "float" `elem` classes+ let renderTable = do+ capt <- captionToLaTeX inlnsToLaTeX caption ident+ let isSimpleTable =+ all ((== ColWidthDefault) . snd) specs &&+ all (all isSimpleCell)+ (mconcat [ headRows thead+ , concatMap bodyRows tbodies+ , footRows tfoot+ ])+ let colDesc' = colDescriptors isSimpleTable tbl+ let colDesc = braces ("@{}" <> colDesc' <> "@{}")+ -- the @{} removes extra space at beginning and end+ let colCount = ColumnCount $ length specs+ let mkHead = headToLaTeX blksToLaTeX isSimpleTable colCount+ let mkRow = rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell+ if float+ then tableToLaTeXTable placement colDesc mkHead mkRow capt thead tbodies tfoot+ else tableToLaTeXLongtable colDesc mkHead mkRow capt thead tbodies tfoot+ -- See #5367 -- footnotehyper/footnote don't work in beamer,+ -- so we need to produce the notes outside the table...+ if float || beamer+ then ($$) <$> withExternalNotes renderTable <*> getAccumulatedNotes+ else renderTable++tableToLaTeXTable :: PandocMonad m+ => Doc Text+ -> Doc Text+ -> (Ann.TableHead -> LW m (Doc Text))+ -> ([Ann.Cell] -> LW m (Doc Text))+ -> Doc Text+ -> Ann.TableHead+ -> [Ann.TableBody]+ -> Ann.TableFoot+ -> LW m (Doc Text)+tableToLaTeXTable placement colDesc mkHead mkRow capt thead tbodies tfoot = do opts <- gets stOptions- let (Ann.Table (ident, _, _) caption specs thead tbodies tfoot) = tbl- CaptionDocs capt captNotes <- captionToLaTeX inlnsToLaTeX caption ident let hasTopCaption = not (isEmpty capt) && writerTableCaptionPosition opts == CaptionAbove let hasBottomCaption = not (isEmpty capt) && writerTableCaptionPosition opts == CaptionBelow- let isSimpleTable =- all ((== ColWidthDefault) . snd) specs &&- all (all isSimpleCell)- (mconcat [ headRows thead- , concatMap bodyRows tbodies- , footRows tfoot- ])- let removeNote (Note _) = Span ("", [], []) []- removeNote x = x- let colCount = ColumnCount $ length specs+ head' <- if isEmptyHead thead+ then return "\\toprule\\noalign{}"+ else mkHead thead+ rows' <- mapM mkRow $ mconcat (map bodyRows tbodies)+ lastfoot <- mapM mkRow $ footRows tfoot+ let foot' = (if isEmptyFoot tfoot+ then mempty+ else "\\midrule\\noalign{}" $$ vcat lastfoot)+ $$ "\\bottomrule\\noalign{}"+ modify $ \s -> s{ stTable = True }+ let makeUnnumbered x = "{\\def\\LTcaptype{none} % do not increment counter" $$ x $$ "}"+ return+ $ (if null capt then makeUnnumbered else id)+ $ "\\begin{table}" <> placement+ $$ "\\centering"+ $$ (if hasTopCaption+ then capt <> "\\tabularnewline"+ else mempty)+ $$ "\\begin{tabular}" <> colDesc+ $$ head'+ $$ vcat rows'+ $$ foot'+ $$ "\\end{tabular}"+ $$ (if hasBottomCaption+ then capt <> "\\tabularnewline"+ else mempty)+ $$ "\\end{table}"+++tableToLaTeXLongtable :: PandocMonad m+ => Doc Text+ -> (Ann.TableHead -> LW m (Doc Text))+ -> ([Ann.Cell] -> LW m (Doc Text))+ -> Doc Text+ -> Ann.TableHead+ -> [Ann.TableBody]+ -> Ann.TableFoot+ -> LW m (Doc Text)+tableToLaTeXLongtable colDesc mkHead mkRow capt thead tbodies tfoot = do+ opts <- gets stOptions+ let hasTopCaption = not (isEmpty capt) &&+ writerTableCaptionPosition opts == CaptionAbove+ let hasBottomCaption = not (isEmpty capt) &&+ writerTableCaptionPosition opts == CaptionBelow -- The first head is not repeated on the following pages. If we were to just -- use a single head, without a separate first head, then the caption would be -- repeated on all pages that contain a part of the table. We avoid this by -- making the caption part of the first head. The downside is that we must -- duplicate the header rows for this. head' <- do- let mkHead = headToLaTeX blksToLaTeX isSimpleTable colCount case (hasTopCaption, isEmptyHead thead) of (False, True) -> return "\\toprule\\noalign{}" (False, False) -> mkHead thead@@ -79,15 +154,15 @@ (True, False) -> do -- avoid duplicate notes in head and firsthead: firsthead <- mkHead thead+ let removeNote (Note _) = Span ("", [], []) []+ removeNote x = x repeated <- mkHead (walk removeNote thead) return $ capt <> "\\tabularnewline" $$ firsthead $$ "\\endfirsthead" $$ repeated- rows' <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $- mconcat (map bodyRows tbodies)- lastfoot <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $- footRows tfoot+ rows' <- mapM mkRow $ mconcat (map bodyRows tbodies)+ lastfoot <- mapM mkRow $ footRows tfoot let foot' = (if isEmptyFoot tfoot then mempty else "\\midrule\\noalign{}" $$ vcat lastfoot)@@ -96,14 +171,11 @@ then "\\tabularnewline" $$ capt else mempty) modify $ \s -> s{ stTable = True }- notes <- notesToLaTeX <$> gets stNotes beamer <- gets stBeamer let makeUnnumbered x = "{\\def\\LTcaptype{none} % do not increment counter" $$ x $$ "}" return $ (if null capt then makeUnnumbered else id)- $ "\\begin{longtable}[]" <>- braces ("@{}" <> colDescriptors isSimpleTable tbl <> "@{}")- -- the @{} removes extra space at beginning and end+ $ "\\begin{longtable}[]" <> colDesc $$ head' $$ "\\endhead" $$ vcat@@ -120,8 +192,6 @@ , vcat rows' ]) $$ "\\end{longtable}"- $$ captNotes- $$ notes isSimpleCell :: Ann.Cell -> Bool isSimpleCell (Ann.Cell _ _ (Cell _attr _align _rowspan _colspan blocks)) =@@ -184,28 +254,18 @@ AlignCenter -> "c" AlignDefault -> "l" -data CaptionDocs =- CaptionDocs- { captionCommand :: Doc Text- , captionNotes :: Doc Text- }- captionToLaTeX :: PandocMonad m => ([Inline] -> LW m (Doc Text)) -> Caption -> Text -- ^ table identifier (label)- -> LW m CaptionDocs+ -> LW m (Doc Text) captionToLaTeX inlnsToLaTeX caption ident = do- (captionText, captForLot, captNotes) <- getCaption inlnsToLaTeX False caption+ (captionText, captForLot) <- getCaption inlnsToLaTeX caption label <- labelFor ident- return $ CaptionDocs- { captionNotes = captNotes- , captionCommand = if isEmpty captionText && isEmpty label- then empty- else "\\caption" <> captForLot <>- braces captionText- <> label- }+ return $ if isEmpty captionText && isEmpty label+ then empty+ else "\\caption" <> captForLot <>+ braces captionText <> label type BlocksWriter m = [Block] -> LW m (Doc Text) @@ -322,11 +382,6 @@ let align = case align' of AlignDefault -> specAlign _ -> align'- beamer <- gets stBeamer- externalNotes <- gets stExternalNotes- -- See #5367 -- footnotehyper/footnote don't work in beamer,- -- so we need to produce the notes outside the table...- modify $ \st -> st{ stExternalNotes = beamer } let isPlainOrPara = \case Para{} -> True Plain{} -> True@@ -352,7 +407,6 @@ (if hasLineBreaks then "\\strut" else mempty) <> cr <> "\\end{minipage}"- modify $ \st -> st{ stExternalNotes = externalNotes } when (rowspan /= RowSpan 1) $ modify (\st -> st{ stMultiRow = True }) let inMultiColumn x = case colspan of
@@ -18,6 +18,8 @@ , labelFor , getListingsLanguage , mbBraced+ , withExternalNotes+ , getAccumulatedNotes ) where @@ -27,6 +29,7 @@ import Text.Pandoc.Options (WriterOptions(..), isEnabled) import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState(..)) import Text.Pandoc.Writers.LaTeX.Lang (toBabel)+import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX) import Text.Pandoc.Highlighting (toListingsLanguage) import Text.DocLayout import Text.Pandoc.Definition@@ -285,3 +288,20 @@ mbBraced x = if not (T.all isAlphaNum x) then "{" <> x <> "}" else x++withExternalNotes :: PandocMonad m+ => LW m a+ -> LW m a+withExternalNotes p = do+ oldExternalNotes <- gets stExternalNotes+ modify $ \st -> st{ stExternalNotes = True }+ res <- p+ modify $ \st -> st{ stExternalNotes = oldExternalNotes }+ return res++getAccumulatedNotes :: PandocMonad m+ => LW m (Doc Text)+getAccumulatedNotes = do+ res <- notesToLaTeX <$> gets stNotes+ modify $ \st -> st{ stNotes = [] }+ return res
@@ -28,9 +28,10 @@ import Data.List (intersperse, sortOn, union, find) import Data.List.NonEmpty (nonEmpty, NonEmpty(..)) import qualified Data.Map as M-import Data.Maybe (fromMaybe, mapMaybe, isNothing)+import Data.Maybe (fromMaybe, mapMaybe, isNothing, isJust) import qualified Data.Set as Set import Data.Text (Text)+import Text.Read (readMaybe) import Data.Char (isSpace) import qualified Data.Text as T import Text.HTML.TagSoup (Tag (..), isTagText, parseTags)@@ -55,6 +56,7 @@ WriterState(..), WriterEnv(..), Ref, Refs, MD, evalMD)+import Skylighting (lookupSyntax) -- | Convert Pandoc to Markdown. writeMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> m Text@@ -177,12 +179,20 @@ if hasNewlines x then hang 0 ("|" <> cr) x else case x of- Text _ t | isSpecialString t ->+ Text _ t | isSpecialString t || looksLikeNumber t -> "\"" <> fmap escapeInDoubleQuotes x <> "\"" _ | isNothing (foldM needsDoubleQuotes True x) -> "\"" <> fmap escapeInDoubleQuotes x <> "\"" | otherwise -> x where+ -- we need to put quotes around numbers that begin with 0+ -- or have decimal points, because their YAML renderings+ -- may differ. See #11715.+ looksLikeNumber t = case readMaybe (T.unpack t) of+ Nothing -> False+ Just (_ :: Double) ->+ (T.any (== '.') t && T.takeEnd 1 t == "0") ||+ T.take 1 t == "0" isSpecialString t = Set.member t specialStrings specialStrings = Set.fromList ["y", "Y", "yes", "Yes", "YES", "n", "N",@@ -596,7 +606,7 @@ then nowrap $ " " <> classOrAttrsToMarkdown opts attribs else let (_,cls,_) = attribs- in case getLangFromClasses cls of+ in case getLangFromClasses opts cls of Just l -> " " <> literal l Nothing -> empty blockToMarkdown' opts (BlockQuote blocks) = do@@ -714,13 +724,8 @@ | otherwise = DefaultDelim let attribs = (start', sty', delim') let markers = orderedListMarkers attribs- let markers' = case variant of- Markua -> markers- _ -> map (\m -> if T.length m < 3- then m <> T.replicate (3 - T.length m) " "- else m) markers contents <- inList $- zipWithM (orderedListItemToMarkdown opts) markers' items+ zipWithM (orderedListItemToMarkdown opts) markers items return $ (if isTightList items then vcat else vsep) contents <> blankline blockToMarkdown' opts (DefinitionList items) = do contents <- inList $ mapM (definitionListItemToMarkdown opts) items@@ -833,15 +838,18 @@ let exts = writerExtensions opts contents <- blockListToMarkdown opts $ taskListItemToAscii exts bs variant <- asks envVariant+ let beginsWithCodeBlock = case bs of+ CodeBlock{} : _ -> True+ _ -> False let sps = case writerTabStop opts - T.length marker of- n | n > 0 -> literal $ T.replicate n " "- _ -> literal " "+ _ | beginsWithCodeBlock -> 1 -- see #11762+ _ | variant == Markua -> 1+ n | n > 0 -> n+ _ -> 1 let ind = if isEnabled Ext_four_space_rule opts then writerTabStop opts- else max (writerTabStop opts) (T.length marker + 1)- let start = case variant of- Markua -> literal marker <> " "- _ -> literal marker <> sps+ else T.length marker + sps+ let start = literal marker <> literal (T.replicate sps " ") -- remove trailing blank line if item ends with a tight list let contents' = if itemEndsWithTightList bs then chomp contents <> cr@@ -958,11 +966,11 @@ -- Identify the class in a list of classes that corresponds to -- the language syntax. language-X turns to X.-getLangFromClasses :: [Text] -> Maybe Text-getLangFromClasses cs =+getLangFromClasses :: WriterOptions -> [Text] -> Maybe Text+getLangFromClasses opts cs = case find ("language-" `T.isPrefixOf`) cs of Just x -> Just (T.drop 9 x) Nothing ->- case filter (/= "sourceCode") cs of+ case [x | x <- cs, isJust (lookupSyntax x (writerSyntaxMap opts))] of (x:_) -> Just x [] -> Nothing
@@ -17,7 +17,7 @@ import Control.Monad.State.Strict (StateT, evalStateT, gets, modify, lift) import Control.Monad (MonadPlus(mplus)) import qualified Data.ByteString.Lazy as B-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe, listToMaybe) import Data.Generics (everywhere', mkT) import Data.List (isPrefixOf) import qualified Data.Map as Map@@ -102,7 +102,8 @@ readDataFile "reference.odt" -- handle formulas and pictures -- picEntriesRef <- P.newIORef ([] :: [Entry])- doc' <- walkM (transformPicMath opts) $ walk fixDisplayMath doc+ let refTextWidth = referenceTextWidthPt opts refArchive+ doc' <- walkM (transformPicMath opts refTextWidth) $ walk fixDisplayMath doc newContents <- lift $ writeOpenDocument opts{writerWrapText = WrapNone} doc' epochtime <- floor `fmap` lift P.getPOSIXTime let contentEntry = toEntry "content.xml" epochtime@@ -303,16 +304,49 @@ updateLangAttr x = x -- | transform both Image and Math elements-transformPicMath :: PandocMonad m => WriterOptions ->Inline -> O m Inline-transformPicMath opts (Image attr@(id', cls, _) lab (src,t)) = catchError+-- | Width of the text area in points, from the reference document's+-- page layout (page width minus horizontal margins). This mirrors how+-- the docx writer derives its print width from the reference docx+-- section properties.+referenceTextWidthPt :: WriterOptions -> Archive -> Maybe Double+referenceTextWidthPt opts archive = do+ entry <- findEntryByPath "styles.xml" archive+ styles <- either (const Nothing) Just $+ parseXMLElement $ toTextLazy $ fromEntry entry+ layout <- listToMaybe $ filterElementsName+ ((== "page-layout-properties") . qName) styles+ let dim attrName = do+ v <- findAttrBy ((== attrName) . qName) layout+ d <- lengthToDim v+ Just $ 72 * inInch opts d+ pageWidth <- dim "page-width"+ let margin = fromMaybe 0 . dim+ Just $ pageWidth - margin "margin-left" - margin "margin-right"++transformPicMath :: PandocMonad m+ => WriterOptions -> Maybe Double -> Inline -> O m Inline+transformPicMath opts mbTextWidthPt (Image attr@(id', cls, _) lab (src,t)) =+ catchError (do (img, mbMimeType) <- P.fetchItem src (ptX, ptY) <- case imageSize opts img of Right s -> return $ sizeInPoints s Left msg -> do report $ CouldNotDetermineImageSize src msg return (100, 100)+ let textWidthPt = fromMaybe 420 mbTextWidthPt let dims = case (getDim Width, getDim Height) of+ -- Percent dimensions are not valid ODF lengths. When both+ -- dimensions are given and the width is relative, resolve+ -- it against the reference document's text width (as the+ -- docx writer does) and let the height follow the image's+ -- aspect ratio.+ (Just (Percent wp), Just _) ->+ let wIn = wp / 100 * textWidthPt / 72+ in [ ("width", tshow (Inch wIn))+ , ("height", tshow (Inch (wIn / ratio))) ]+ (Just w@(Inch i), Just (Percent _)) ->+ [("width", tshow w), ("height", tshow (Inch (i / ratio)))] (Just w, Just h) -> [("width", tshow w), ("height", tshow h)] (Just w@(Percent _), Nothing) -> [("rel-width", tshow w),("rel-height", "scale"),("width", tshow ptX <> "pt"),("height", tshow ptY <> "pt")] (Nothing, Just h@(Percent _)) -> [("rel-width", "scale"),("rel-height", tshow h),("width", tshow ptX <> "pt"),("height", tshow ptY <> "pt")]@@ -347,14 +381,18 @@ report $ CouldNotFetchResource src $ T.pack (show e) return $ Emph lab) -transformPicMath _ (Math t math) = do+transformPicMath _ _ (Math t math) = do entries <- gets stEntries let dt = if t == InlineMath then DisplayInline else DisplayBlock- case writeMathML dt <$> readTeX math of+ case readTeX math of Left _ -> return $ Math t math- Right r -> do+ Right exps -> do let conf = XL.useShortEmptyTags (const False) XL.defaultConfigPP- let mathml = XL.ppcTopElement conf r+ let starMath =+ writeStarMath dt exps <> "\n" <> starMathCommentFromTeX math+ let mathmlElement =+ addStarMathAnnotation starMath (writeMathML dt exps)+ let mathml = XL.ppcTopElement conf mathmlElement epochtime <- floor `fmap` lift P.getPOSIXTime let dirname = "Formula-" ++ show (length entries) ++ "/" let fname = dirname ++ "content.xml"@@ -377,7 +415,48 @@ , ("xlink:show", "embed") , ("xlink:actuate", "onLoad")] -transformPicMath _ x = return x+transformPicMath _ _ x = return x++starMathCommentFromTeX :: T.Text -> T.Text+starMathCommentFromTeX tex =+ case T.lines normalized of+ [] -> "%% TeX:"+ (l : ls) ->+ T.intercalate "\n" (("%% TeX: " <> l) : map ("%% " <>) ls)+ where+ normalized = T.replace "\r\n" "\n" (T.replace "\r" "\n" tex)++addStarMathAnnotation :: T.Text -> XL.Element -> XL.Element+addStarMathAnnotation starMath e =+ case XL.elContent e of+ [XL.Elem sem] | XL.qName (XL.elName sem) == "semantics" ->+ e { XL.elContent = [XL.Elem (withAnnotation sem)] }+ _ ->+ e { XL.elContent = [XL.Elem (mkSemantics (XL.elContent e))] }+ where+ mkSemantics cs =+ XL.Element (mkMathQName "semantics") [] (cs ++ [XL.Elem annotation]) Nothing++ withAnnotation sem =+ sem { XL.elContent =+ filter (not . isStarMathAnnotation) (XL.elContent sem)+ ++ [XL.Elem annotation] }++ annotation =+ XL.Element (mkMathQName "annotation")+ [XL.Attr (XL.QName "encoding" Nothing Nothing) "StarMath 5.0"]+ [XL.Text (XL.CData XL.CDataText (T.unpack starMath) Nothing)]+ Nothing++ isStarMathAnnotation (XL.Elem el) =+ XL.qName (XL.elName el) == "annotation" &&+ any (\a -> XL.qName (XL.attrKey a) == "encoding"+ && XL.attrVal a == "StarMath 5.0")+ (XL.elAttribs el)+ isStarMathAnnotation _ = False++ mkMathQName n =+ XL.QName n (XL.qURI $ XL.elName e) (XL.qPrefix $ XL.elName e) documentSettings :: Bool -> B.ByteString documentSettings isTextMode = fromStringLazy $ render Nothing
@@ -747,8 +747,14 @@ getDims (("height", h):xs) = ("svg:height", h) : getDims xs getDims (("rel-height", w):xs) = ("style:rel-height", w) : getDims xs getDims (_:xs) = getDims xs+ -- Image is an Inline: anchor the frame as a character so+ -- it flows with the text. Without an explicit anchor,+ -- consumers default to paragraph anchoring and float the+ -- frame beside the following text. return $ inTags False "draw:frame"- (("draw:name", "img" <> tshow id') : getDims kvs) $+ (("draw:name", "img" <> tshow id')+ : ("text:anchor-type", "as-char")+ : getDims kvs) $ selfClosingTag "draw:image" [ ("xlink:href" , s ) , ("xlink:type" , "simple") , ("xlink:show" , "embed" )
@@ -1365,6 +1365,132 @@ shapesToElements layout shps = concat <$> mapM (shapeToElements layout) shps +-- | Create a GraphicFrame element with explicit positioning+graphicFrameToElementsWithPosition ::+ PandocMonad m =>+ Integer -> -- x position+ Integer -> -- y position+ Integer -> -- width (cx)+ Integer -> -- height (cy)+ [Graphic] ->+ [ParaElem] ->+ P m [(ShapeId, Element)]+graphicFrameToElementsWithPosition x y cx cy tbls caption = do+ let cy' = if not $ null caption then cy - captionHeight else cy++ elements <- mapM (graphicToElement cx) tbls+ let graphicFrameElts =+ ( 6+ , mknode "p:graphicFrame" [] $+ [ mknode "p:nvGraphicFramePr" []+ [ mknode "p:cNvPr" [("id", "6"), ("name", "Content Placeholder 5")] ()+ , mknode "p:cNvGraphicFramePr" []+ [mknode "a:graphicFrameLocks" [("noGrp", "1")] ()]+ , mknode "p:nvPr" []+ [mknode "p:ph" [("idx", "1")] ()]+ ]+ , mknode "p:xfrm" []+ [ mknode "a:off" [("x", tshow $ 12700 * x),+ ("y", tshow $ 12700 * y)] ()+ , mknode "a:ext" [("cx", tshow $ 12700 * cx),+ ("cy", tshow $ 12700 * cy')] ()+ ]+ ] <> elements+ )++ if not $ null caption+ then do capElt <- createCaption ((x, y), (cx, cy)) caption+ return [graphicFrameElts, capElt]+ else return [graphicFrameElts]++-- | Create a TextBox element with explicit positioning+textBoxToElementWithPosition ::+ PandocMonad m =>+ Element ->+ Integer -> -- x position+ Integer -> -- y position+ Integer -> -- width (cx)+ Integer -> -- height (cy)+ [Paragraph] ->+ P m (Maybe ShapeId, Element)+textBoxToElementWithPosition layout x y cx cy paras+ | ns <- elemToNameSpaces layout+ , Just cSld <- findChild (elemName ns "p" "cSld") layout+ , Just spTree <- findChild (elemName ns "p" "spTree") cSld = do+ (shapeId, sp) <- getContentShape ns spTree+ elements <- mapM paragraphToElement paras+ let txBody = mknode "p:txBody" [] $+ [mknode "a:bodyPr" [] (), mknode "a:lstStyle" [] ()] <> elements+ -- Create spPr with explicit positioning+ xfrm = mknode "a:xfrm" []+ [ mknode "a:off" [("x", tshow $ 12700 * x),+ ("y", tshow $ 12700 * y)] ()+ , mknode "a:ext" [("cx", tshow $ 12700 * cx),+ ("cy", tshow $ 12700 * cy)] ()+ ]+ spPr = mknode "p:spPr" [] [xfrm]+ return+ . (shapeId,)+ . surroundWithMathAlternate+ . replaceNamedChildren ns "p" "txBody" [txBody]+ . replaceNamedChildren ns "p" "spPr" [spPr]+ $ sp+textBoxToElementWithPosition _ _ _ _ _ _ = return (Nothing, mknode "p:sp" [] ())++-- | Convert shapes to elements with vertical stacking+-- This positions multiple shapes vertically within a content area,+-- preserving the original order of shapes from the source document+shapesToElementsStacked ::+ PandocMonad m =>+ Element -> -- layout+ Integer -> -- x position of content area+ Integer -> -- y position of content area+ Integer -> -- width (cx) of content area+ Integer -> -- total height (cy) of content area+ [Shape] ->+ P m [(Maybe ShapeId, Content)]+shapesToElementsStacked layout x y cx totalCy shapes = do+ -- Calculate heights for each shape based on content size+ let gap = 10 -- Small gap between elements++ -- Count "units" for each shape based on content+ -- Text paragraphs need more space than table rows (bullets have more padding)+ shapeUnits :: Shape -> Int+ shapeUnits (TextBox paras) = max 2 (length paras * 2) -- 2 units per paragraph+ shapeUnits (GraphicFrame tbls _) =+ max 2 $ sum [1 + length rows | Tbl _ _ _ rows <- tbls] -- header + data rows+ shapeUnits (Pic {}) = 4 -- images get moderate space+ shapeUnits (RawOOXMLShape _) = 2++ -- Calculate total units and height per unit+ totalUnits = sum $ map shapeUnits shapes+ heightPerUnit :: Double+ heightPerUnit = if totalUnits > 0+ then fromIntegral totalCy / fromIntegral totalUnits+ else fromIntegral totalCy++ -- Process shapes in order, tracking Y position+ let go :: PandocMonad m => Integer -> [Shape] -> P m [(Maybe ShapeId, Content)]+ go _ [] = return []+ go currentY (shape:rest) = do+ let units = shapeUnits shape+ shapeHeight = round $ fromIntegral units * heightPerUnit+ heightWithGap = shapeHeight - gap++ elts <- case shape of+ GraphicFrame tbls caption ->+ map (bimap Just Elem) <$>+ graphicFrameToElementsWithPosition x currentY cx heightWithGap tbls caption+ TextBox paras -> do+ elt <- textBoxToElementWithPosition layout x currentY cx heightWithGap paras+ return [(fst elt, Elem (snd elt))]+ _ -> return [] -- Skip other shapes for now++ restElts <- go (currentY + shapeHeight) rest+ return $ elts ++ restElts++ go y shapes+ graphicFrameToElements :: PandocMonad m => Element ->@@ -1566,9 +1692,33 @@ (shapeId, element) <- nonBodyTextToElement layout [PHType "title"] hdrShape let hdrShapeElements = [Elem element | not (null hdrShape)] contentHeaderId = if null hdrShape then Nothing else shapeId- content' <- local- (\env -> env {envPlaceholder = Placeholder ObjType 0})- (shapesToElements layout shapes)++ -- Check if we have multiple content shapes that need stacking+ let hasMultipleShapes = length shapes > 1+ hasGraphicAndText = any isGraphicFrame shapes && any isTextBox shapes+ where+ isGraphicFrame (GraphicFrame _ _) = True+ isGraphicFrame _ = False+ isTextBox (TextBox _) = True+ isTextBox _ = False++ content' <- if hasMultipleShapes && hasGraphicAndText+ then do+ -- Get content area dimensions for stacking+ master <- getMaster+ (pageWidth, pageHeight) <- asks envPresentationSize+ ((x, y), (cx, cy)) <- local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (getContentShapeSize ns layout master)+ `catchError`+ (\_ -> return ((0, 0), (pageWidth, pageHeight)))+ -- Use stacked layout for multiple shapes+ local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (shapesToElementsStacked layout x y cx cy shapes)+ else+ -- Use regular layout for single shapes+ local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (shapesToElements layout shapes)+ let contentContentIds = mapMaybe fst content' contentElements = snd <$> content' footer <- footerElements content@@ -1688,8 +1838,33 @@ (shapesToElements layout textShapes) let contentWithCaptionCaptionIds = mapMaybe fst text textElements = snd <$> text- content <- local (\env -> env {envPlaceholder = Placeholder ObjType 0})- (shapesToElements layout contentShapes)++ -- Check if we have multiple content shapes that need stacking+ let hasMultipleShapes = length contentShapes > 1+ hasGraphicAndText = any isGraphicFrame contentShapes && any isTextBox contentShapes+ where+ isGraphicFrame (GraphicFrame _ _) = True+ isGraphicFrame _ = False+ isTextBox (TextBox _) = True+ isTextBox _ = False++ content <- if hasMultipleShapes && hasGraphicAndText+ then do+ -- Get content area dimensions for stacking+ master <- getMaster+ (pageWidth, pageHeight) <- asks envPresentationSize+ ((x, y), (cx, cy)) <- local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (getContentShapeSize ns layout master)+ `catchError`+ (\_ -> return ((0, 0), (pageWidth, pageHeight)))+ -- Use stacked layout for multiple shapes+ local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (shapesToElementsStacked layout x y cx cy contentShapes)+ else+ -- Use regular layout for single shapes+ local (\env -> env {envPlaceholder = Placeholder ObjType 0})+ (shapesToElements layout contentShapes)+ let contentWithCaptionContentIds = mapMaybe fst content contentElements = snd <$> content footer <- footerElements contentWithCaption
@@ -697,12 +697,14 @@ let (nts, blks') = span isNotesDiv blks case cur of [Header n _ _] | n == slideLevel || slideLevel == 0 ->- splitBlocks' [] (acc ++ [cur ++ [tbl] ++ nts]) blks'- _ -> splitBlocks' []- (if any notText cur- then acc ++ ([cur | not (null cur)]) ++ [tbl : nts]- else acc ++ ([cur ++ [tbl] ++ nts]))- blks'+ -- Header + table: add to current and continue accumulating+ splitBlocks' (cur ++ [tbl] ++ nts) acc blks'+ _ -> let (newCur, newAcc) = if any notText cur+ -- Current has notText: save current, table starts new+ then ([tbl] ++ nts, acc ++ ([cur | not (null cur)]))+ -- Current is text-only: add table to current and continue+ else (cur ++ [tbl] ++ nts, acc)+ in splitBlocks' newCur newAcc blks' splitBlocks' cur acc (d@(Div (_, classes, _) _): blks) | "columns" `elem` classes = do slideLevel <- asks envSlideLevel let (nts, blks') = span isNotesDiv blks@@ -775,13 +777,22 @@ if makesBlankSlide (blk : blks) then pure (mkSlide BlankSlide) else mkSlide . ContentSlide [] <$> blocksToShapes (blk : blks)+ -- Check if there's a table in the content+ hasTable = any isTable (blk : blks)+ where+ isTable Table{} = True+ isTable _ = False in case break notText (blk : blks) of ([], _) -> contentOrBlankSlide (_, []) -> contentOrBlankSlide- (textBlocks, contentBlocks) -> do- textShapes <- blocksToShapes textBlocks- contentShapes <- blocksToShapes contentBlocks- return (mkSlide (ContentWithCaptionSlide [] textShapes contentShapes))+ (textBlocks, contentBlocks)+ -- When there's a table with surrounding text, use ContentSlide+ -- to keep everything in one column with proper vertical stacking+ | hasTable -> mkSlide . ContentSlide [] <$> blocksToShapes (blk : blks)+ | otherwise -> do+ textShapes <- blocksToShapes textBlocks+ contentShapes <- blocksToShapes contentBlocks+ return (mkSlide (ContentWithCaptionSlide [] textShapes contentShapes)) bodyBlocksToSlide _ [] spkNotes = do sldId <- asks envCurSlideId return $
@@ -15,6 +15,8 @@ ) where import Control.Monad.Except (catchError, throwError) import Control.Monad+import Control.Monad.Reader (ReaderT, runReaderT, asks)+import Control.Monad.State.Strict (State, runState, get, put) import qualified Data.ByteString as B import Data.Char (chr, isDigit, ord, isAlphaNum) import qualified Data.Map as M@@ -34,6 +36,8 @@ import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared import Text.Printf (printf)+import Text.Read (readMaybe)+import Text.DocTemplates (lookupContext) -- | Convert Image inlines into a raw RTF embedded image, read from a file, -- or a MediaBag, or the internet.@@ -83,6 +87,14 @@ return x) rtfEmbedImage _ x = return x +-- | Configuration for the RTF writer.+newtype WriterConfig = WriterConfig+ { fontSize :: Int -- ^ base font size in half points+ }++defaultWriterConfig :: WriterConfig+defaultWriterConfig = WriterConfig { fontSize = 12 }+ -- | Convert Pandoc to a string in rich text format. writeRTF :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeRTF options doc = do@@ -98,12 +110,24 @@ $ metamap metadata <- metaToContext options (fmap (literal . T.concat) .+ flip runReaderT defaultWriterConfig . mapM (blockToRTF 0 AlignDefault))- (fmap literal . inlinesToRTF)+ (fmap literal . flip runReaderT defaultWriterConfig .+ inlinesToRTF) meta'- body <- blocksToRTF 0 AlignDefault blocks- toc <- blocksToRTF 0 AlignDefault [toTableOfContents options blocks]+ let config = defaultWriterConfig{+ fontSize = maybe 24 (floor . (* (2.0 :: Double)))+ $ lookupContext "fontsize" metadata >>=+ T.stripSuffix "pt" >>= readMaybe . T.unpack }+ -- Tag list blocks with a list id and level so that the rendered RTF+ -- carries proper \ls/\ilvl references and a \listtable, which lets+ -- lists (including multi-paragraph list items) round-trip.+ let (blocks', listDefs) = prepareLists blocks+ body <- runReaderT (blocksToRTF 0 AlignDefault blocks') config+ toc <- runReaderT (blocksToRTF 0 AlignDefault [toTableOfContents options blocks])+ config let context = defField "body" body+ $ maybe id (defField "listtable") (listTableRTF listDefs) $ defField "spacer" spacer $ (if writerTableOfContents options then defField "table-of-contents" toc@@ -119,6 +143,73 @@ Just (_,'\n') -> body _ -> body <> T.singleton '\n' +-- | Information about a list needed to build the RTF list table:+-- a unique id (used both as @\\listid@ and @\\ls@), the list level+-- (@\\ilvl@) at which the list occurs, and its kind (bullet, or ordered+-- with the given attributes).+data ListInfo = ListInfo Int Int (Either () ListAttributes)++-- | Walk the document and tag every list with a unique id and its+-- nesting level, returning the tagged blocks together with the+-- information needed to build the list table. Tagged lists are wrapped+-- in a @Div@ with the @__rtflist@ class and @ls@/@lvl@ attributes,+-- which 'blockToRTF' recognizes.+prepareLists :: [Block] -> ([Block], [ListInfo])+prepareLists bs =+ let (bs', (_, defs)) = runState (mapM (goBlock 0) bs) (1, [])+ in (bs', reverse defs)+ where+ tag :: Int -> Either () ListAttributes -> [[Block]]+ -> ([[Block]] -> Block) -> State (Int, [ListInfo]) Block+ tag level kind items ctor = do+ (n, defs) <- get+ put (n + 1, ListInfo n level kind : defs)+ items' <- mapM (mapM (goBlock (level + 1))) items+ return $ Div ("", ["__rtflist"], [("ls", tshow n), ("lvl", tshow level)])+ [ctor items']+ goBlock :: Int -> Block -> State (Int, [ListInfo]) Block+ goBlock level (BulletList items) = tag level (Left ()) items BulletList+ goBlock level (OrderedList attrs items) =+ tag level (Right attrs) items (OrderedList attrs)+ goBlock level (BlockQuote bs') = BlockQuote <$> mapM (goBlock level) bs'+ goBlock level (Div attr bs') = Div attr <$> mapM (goBlock level) bs'+ goBlock level (Figure attr capt bs') =+ Figure attr capt <$> mapM (goBlock level) bs'+ goBlock _ b = return b++-- | RTF @\\levelnfc@ number-format code for an ordered-list style.+listNfc :: ListNumberStyle -> Int+listNfc UpperRoman = 1+listNfc LowerRoman = 2+listNfc UpperAlpha = 3+listNfc LowerAlpha = 4+listNfc _ = 0 -- Decimal, DefaultStyle, Example++-- | Build the @\\listtable@ and @\\listoverridetable@ for the collected+-- lists, or 'Nothing' if the document contains no lists.+listTableRTF :: [ListInfo] -> Maybe Text+listTableRTF [] = Nothing+listTableRTF infos = Just $+ "{\\*\\listtable" <> T.concat (map listEntry infos) <> "}\n" <>+ "{\\*\\listoverridetable" <> T.concat (map overrideEntry infos) <> "}\n"+ where+ listEntry (ListInfo lid level kind) =+ "{\\list\\listtemplateid" <> tshow lid <>+ T.concat [ levelEntry i kind | i <- [0..level] ] <>+ "{\\listname ;}\\listid" <> tshow lid <> "}\n"+ levelEntry i kind =+ let (nfc, start) = case kind of+ Left () -> (23 :: Int, 1 :: Int)+ Right (s, sty, _) -> (listNfc sty, s)+ li = (i + 1) * 360+ in "{\\listlevel\\levelnfc" <> tshow nfc <> "\\levelnfcn" <> tshow nfc <>+ "\\leveljc0\\leveljcn0\\levelfollow0\\levelstartat" <> tshow start <>+ "\\levelindent0{\\leveltext\\'01\\u8226 ?;}{\\levelnumbers;}\\fi-360\\li" <>+ tshow li <> "\\lin" <> tshow li <> " }"+ overrideEntry (ListInfo lid _ _) =+ "{\\listoverride\\listid" <> tshow lid <>+ "\\listoverridecount0\\ls" <> tshow lid <> "}"+ -- | Convert unicode characters (> 127) into rich text format representation. handleUnicode :: Text -> Text handleUnicode = T.concatMap $ \c ->@@ -163,36 +254,41 @@ codeStringToRTF str = T.intercalate "\\line\n" $ T.lines (stringToRTF str) -- | Make a paragraph with first-line indent, block indent, and space after.-rtfParSpaced :: Int -- ^ space after (in twips)+rtfParSpaced :: PandocMonad m+ => Int -- ^ space after (in twips) -> Int -- ^ block indent (in twips) -> Int -- ^ first line indent (relative to block) (in twips) -> Alignment -- ^ alignment -> Text -- ^ string with content- -> Text-rtfParSpaced spaceAfter indent firstLineIndent alignment content =+ -> ReaderT WriterConfig m Text+rtfParSpaced spaceAfter indent firstLineIndent alignment content = do+ fontsize <- asks fontSize let alignString = case alignment of AlignLeft -> "\\ql " AlignRight -> "\\qr " AlignCenter -> "\\qc " AlignDefault -> "\\ql "- in "{\\pard " <> alignString <>- "\\f0 \\sa" <> tshow spaceAfter <> " \\li" <> T.pack (show indent) <>+ return $ "{\\pard " <> alignString <>+ "\\f0 " <> renderFontSize fontsize <>+ " \\sa" <> tshow spaceAfter <> " \\li" <> T.pack (show indent) <> " \\fi" <> tshow firstLineIndent <> " " <> content <> "\\par}\n" -- | Default paragraph.-rtfPar :: Int -- ^ block indent (in twips)+rtfPar :: PandocMonad m+ => Int -- ^ block indent (in twips) -> Int -- ^ first line indent (relative to block) (in twips) -> Alignment -- ^ alignment -> Text -- ^ string with content- -> Text+ -> ReaderT WriterConfig m Text rtfPar = rtfParSpaced 180 -- | Compact paragraph (e.g. for compact list items).-rtfCompact :: Int -- ^ block indent (in twips)- -> Int -- ^ first line indent (relative to block) (in twips)- -> Alignment -- ^ alignment- -> Text -- ^ string with content- -> Text+rtfCompact :: PandocMonad m+ => Int -- ^ block indent (in twips)+ -> Int -- ^ first line indent (relative to block) (in twips)+ -> Alignment -- ^ alignment+ -> Text -- ^ string with content+ -> ReaderT WriterConfig m Text rtfCompact = rtfParSpaced 0 -- number of twips to indent@@ -221,7 +317,7 @@ => Int -> Alignment -> [Block]- -> m Text+ -> ReaderT WriterConfig m Text blocksToRTF indent align = fmap T.concat . mapM (blockToRTF indent align) -- | Convert Pandoc block element to RTF.@@ -229,38 +325,55 @@ => Int -- ^ indent level -> Alignment -- ^ alignment -> Block -- ^ block to convert- -> m Text+ -> ReaderT WriterConfig m Text+blockToRTF indent alignment (Div (_, classes, kvs) [blk])+ | "__rtflist" `elem` classes+ , Just ls <- lookup "ls" kvs >>= readInt+ , Just level <- lookup "lvl" kvs >>= readInt =+ case blk of+ BulletList lst -> spaceAtEnd . T.concat <$>+ mapM (listItemToRTF alignment indent (Just (ls, level))+ (bulletMarker indent)) lst+ OrderedList attribs lst -> spaceAtEnd . T.concat <$>+ zipWithM (listItemToRTF alignment indent (Just (ls, level)))+ (orderedMarkers indent attribs) lst+ _ -> blocksToRTF indent alignment [blk] blockToRTF indent alignment (Div _ bs) = blocksToRTF indent alignment bs blockToRTF indent alignment (Plain lst) =- rtfCompact indent 0 alignment <$> inlinesToRTF lst+ inlinesToRTF lst >>= rtfCompact indent 0 alignment blockToRTF indent alignment (Para lst) =- rtfPar indent 0 alignment <$> inlinesToRTF lst+ inlinesToRTF lst >>= rtfPar indent 0 alignment blockToRTF indent alignment (LineBlock lns) = blockToRTF indent alignment $ linesToPara lns blockToRTF indent alignment (BlockQuote lst) = blocksToRTF (indent + indentIncrement) alignment lst-blockToRTF indent _ (CodeBlock _ str) =- return $ rtfPar indent 0 AlignLeft ("\\f1 " <> codeStringToRTF str)+blockToRTF indent _ (CodeBlock _ str) = do+ fontsize <- asks fontSize+ rtfPar indent 0 AlignLeft+ $ "\\f1 " <> renderFontSize fontsize <> " " <> codeStringToRTF str blockToRTF _ _ b@(RawBlock f str) | f == Format "rtf" = return str | otherwise = do report $ BlockNotRendered b return "" blockToRTF indent alignment (BulletList lst) = spaceAtEnd . T.concat <$>- mapM (listItemToRTF alignment indent (bulletMarker indent)) lst+ mapM (listItemToRTF alignment indent Nothing (bulletMarker indent)) lst blockToRTF indent alignment (OrderedList attribs lst) = spaceAtEnd . T.concat <$>- zipWithM (listItemToRTF alignment indent) (orderedMarkers indent attribs) lst+ zipWithM (listItemToRTF alignment indent Nothing)+ (orderedMarkers indent attribs) lst blockToRTF indent alignment (DefinitionList lst) = spaceAtEnd . T.concat <$> mapM (definitionListItemToRTF alignment indent) lst-blockToRTF indent _ HorizontalRule = return $+blockToRTF indent _ HorizontalRule = rtfPar indent 0 AlignCenter "\\emdash\\emdash\\emdash\\emdash\\emdash" blockToRTF indent alignment (Header level _ lst) = do contents <- inlinesToRTF lst- return $ rtfPar indent 0 alignment $+ fontsize <- asks fontSize+ rtfPar indent 0 alignment $ "\\outlinelevel" <> tshow (level - 1) <>- " \\b \\fs" <> tshow (40 - (level * 4)) <> " " <> contents+ " \\b " <> renderFontSize (fontsize + ((6 - level) * 2)) <>+ " " <> contents blockToRTF indent alignment (Table _ blkCapt specs thead tbody tfoot) = do let (caption, aligns, sizes, headers, rows) = toLegacyTable blkCapt specs thead tbody tfoot caption' <- inlinesToRTF caption@@ -268,12 +381,13 @@ then return "" else tableRowToRTF True indent aligns sizes headers rows' <- T.concat <$> mapM (tableRowToRTF False indent aligns sizes) rows- return $ header' <> rows' <> rtfPar indent 0 alignment caption'+ ((header' <> rows') <>) <$> rtfPar indent 0 alignment caption' blockToRTF indent alignment (Figure attr capt body) = blockToRTF indent alignment $ figureDiv attr capt body tableRowToRTF :: PandocMonad m- => Bool -> Int -> [Alignment] -> [Double] -> [[Block]] -> m Text+ => Bool -> Int -> [Alignment] -> [Double] -> [[Block]]+ -> ReaderT WriterConfig m Text tableRowToRTF header indent aligns sizes' cols = do let totalTwips = 6 * 1440 -- 6 inches let sizes = if all (== 0) sizes'@@ -293,7 +407,8 @@ let end = "}\n\\intbl\\row}\n" return $ start <> columns <> end -tableItemToRTF :: PandocMonad m => Int -> Alignment -> [Block] -> m Text+tableItemToRTF :: PandocMonad m+ => Int -> Alignment -> [Block] -> ReaderT WriterConfig m Text tableItemToRTF indent alignment item = do contents <- blocksToRTF indent alignment item return $ "{" <> T.replace "\\pard" "\\pard\\intbl" contents <> "\\cell}\n"@@ -303,22 +418,58 @@ spaceAtEnd :: Text -> Text spaceAtEnd str = maybe str (<> "\\sa180\\par}\n") $ T.stripSuffix "\\par}\n" str +-- | Parse a decimal integer stored in a tag attribute.+readInt :: Text -> Maybe Int+readInt = safeRead++-- | Inject an @\\ls@/@\\ilvl@ reference into an already-rendered list+-- paragraph (used for continuation paragraphs of a multi-paragraph list+-- item, which carry the list reference but no @\\listtext@ marker). The+-- reference is inserted right before the @\\fi@ first-line-indent control+-- word, where the reader expects to find the paragraph's list properties.+addListRef :: Int -> Int -> Text -> Text+addListRef ls level t =+ let ref = "\\ls" <> tshow ls <> "\\ilvl" <> tshow level+ (pref, suff) = T.breakOn "\\fi" t+ in if T.null suff then t else pref <> ref <> suff+ -- | Convert list item (list of blocks) to RTF. listItemToRTF :: PandocMonad m- => Alignment -- ^ alignment- -> Int -- ^ indent level- -> Text -- ^ list start marker- -> [Block] -- ^ list item (list of blocks)- -> m Text-listItemToRTF alignment indent marker [] = return $- rtfCompact (indent + listIncrement) (negate listIncrement) alignment- (marker <> "\\tx" <> tshow listIncrement <> "\\tab ")-listItemToRTF alignment indent marker (listFirst:listRest) = do+ => Alignment -- ^ alignment+ -> Int -- ^ indent level+ -> Maybe (Int, Int) -- ^ list reference (@\\ls@, @\\ilvl@), if+ -- the list is part of the list table+ -> Text -- ^ list start marker+ -> [Block] -- ^ list item (list of blocks)+ -> ReaderT WriterConfig m Text+listItemToRTF alignment indent mbref marker [] =+ rtfCompact (indent + listIncrement) (negate listIncrement) alignment $+ case mbref of+ Nothing -> marker <> "\\tx" <> tshow listIncrement <> "\\tab "+ Just (ls, level) ->+ "\\ls" <> tshow ls <> "\\ilvl" <> tshow level <>+ "\\tx" <> tshow listIncrement <> " {\\listtext\\tab " <> marker <> "\\tab}"+listItemToRTF alignment indent mbref marker (listFirst:listRest) = do let f = blockToRTF (indent + listIncrement) alignment first <- f listFirst- rest <- mapM f listRest- let listMarker = "\\fi" <> tshow (negate listIncrement) <> " " <> marker <>- "\\tx" <> tshow listIncrement <> "\\tab"+ -- Continuation paragraphs carry the same \ls/\ilvl reference but no+ -- \listtext marker, so the reader merges them into the current item.+ -- Nested lists are tagged Divs that already carry their own reference,+ -- so they are left untouched.+ rest <- forM listRest $ \b -> do+ t <- f b+ return $ case mbref of+ Just (ls, level) | not (isTaggedList b) -> addListRef ls level t+ _ -> t+ let listMarker = case mbref of+ Nothing ->+ "\\fi" <> tshow (negate listIncrement) <> " " <> marker <>+ "\\tx" <> tshow listIncrement <> "\\tab"+ Just (ls, level) ->+ "\\fi" <> tshow (negate listIncrement) <>+ "\\ls" <> tshow ls <> "\\ilvl" <> tshow level <>+ "\\tx" <> tshow listIncrement <>+ " {\\listtext\\tab " <> marker <> "\\tab}" -- Find the first occurrence of \\fi or \\fi-, then replace it and the following -- digits with the list marker. let insertListMarker t = case popDigit $ optionDash $ T.drop 3 suff of@@ -336,12 +487,18 @@ -- insert the list marker into the (processed) first block return $ insertListMarker first <> T.concat rest +-- | Is this a list block tagged by 'prepareLists' (and hence already+-- carrying its own @\\ls@/@\\ilvl@ reference)?+isTaggedList :: Block -> Bool+isTaggedList (Div (_, classes, _) _) = "__rtflist" `elem` classes+isTaggedList _ = False+ -- | Convert definition list item (label, list of blocks) to RTF. definitionListItemToRTF :: PandocMonad m => Alignment -- ^ alignment -> Int -- ^ indent level -> ([Inline],[[Block]]) -- ^ list item (list of blocks)- -> m Text+ -> ReaderT WriterConfig m Text definitionListItemToRTF alignment indent (label, defs) = do labelText <- blockToRTF indent alignment (Plain label) itemsText <- blocksToRTF (indent + listIncrement) alignment (concat defs)@@ -350,13 +507,13 @@ -- | Convert list of inline items to RTF. inlinesToRTF :: PandocMonad m => [Inline] -- ^ list of inlines to convert- -> m Text+ -> ReaderT WriterConfig m Text inlinesToRTF lst = T.concat <$> mapM inlineToRTF lst -- | Convert inline item to RTF. inlineToRTF :: PandocMonad m => Inline -- ^ inline to convert- -> m Text+ -> ReaderT WriterConfig m Text inlineToRTF (Span _ lst) = inlinesToRTF lst inlineToRTF (Emph lst) = do contents <- inlinesToRTF lst@@ -385,7 +542,10 @@ inlineToRTF (Quoted DoubleQuote lst) = do contents <- inlinesToRTF lst return $ "\\u8220\"" <> contents <> "\\u8221\""-inlineToRTF (Code _ str) = return $ "{\\f1 " <> codeStringToRTF str <> "}"+inlineToRTF (Code _ str) = do+ fontsize <- asks fontSize+ return $ "{\\f1 " <> renderFontSize fontsize <>+ " " <> codeStringToRTF str <> "}" inlineToRTF (Str str) = return $ stringToRTF str inlineToRTF (Math t str) = texMathToInlines t str >>= inlinesToRTF inlineToRTF (Cite _ lst) = inlinesToRTF lst@@ -407,3 +567,6 @@ body <- T.concat <$> mapM (blockToRTF 0 AlignDefault) contents return $ "{\\super\\chftn}{\\*\\footnote\\chftn\\~\\plain\\pard " <> body <> "}"++renderFontSize :: Int -> Text+renderFontSize halfPoints = "\\fs" <> tshow halfPoints
@@ -217,6 +217,7 @@ || T.any (== ':') x -- e.g. epub: namespace || "data-" `T.isPrefixOf` x || "aria-" `T.isPrefixOf` x+ || x == "markdown" -- #11685 then x else "data-" <> x
@@ -48,7 +48,7 @@ , stOptions :: WriterOptions -- writer options } -data Context = NormalContext | NodeContext+data Context = NormalContext | NodeContext | ArgumentContext deriving (Eq, Show) withContext :: PandocMonad m => Context -> TI m a -> TI m a@@ -138,6 +138,7 @@ escChar '\x2026' = "@dots{}" escChar '\x2019' = "'" escChar ',' | context == NodeContext = ""+ escChar ',' | context == ArgumentContext = "@comma{}" escChar ':' | context == NodeContext = "" escChar '.' | context == NodeContext = "" escChar '(' | context == NodeContext = ""@@ -241,7 +242,8 @@ text "@end iftex" $$ text "@ifnottex" $$ text (replicate 72 '-') $$- text "@end ifnottex"+ text "@end ifnottex" $$+ blankline blockToTexinfo (Header 0 _ lst) = do txt <- if null lst@@ -528,7 +530,7 @@ Nothing -> literal <$> stringToTexinfo (T.filter (not . disallowedInNode) src) Just node -> pure $ literal node- contents <- withContext NodeContext $ inlineListToTexinfo txt+ contents <- withContext ArgumentContext $ inlineListToTexinfo txt return $ text "@ref" <> braces (target <> if contents == target then mempty@@ -537,13 +539,13 @@ [Str x] | escapeURI x == src -> -- autolink return $ literal $ "@url{" <> x <> "}" _ -> do- contents <- withContext NodeContext $ inlineListToTexinfo txt+ contents <- withContext ArgumentContext $ inlineListToTexinfo txt src1 <- stringToTexinfo src return $ literal ("@uref{" <> src1 <> ",") <> contents <> char '}' inlineToTexinfo (Image attr alternate (source, _)) = do- content <- withContext NodeContext $ inlineListToTexinfo alternate+ content <- withContext ArgumentContext $ inlineListToTexinfo alternate opts <- gets stOptions let showDim dim = case dimension dim attr of (Just (Pixel a)) -> showInInch opts (Pixel a) <> "in"
@@ -0,0 +1,377 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+ Module : Text.Pandoc.Writers.Txt2Tags+ Copyright : Copyright (C) 2008-2024 Eric Forgeot, based on John MacFarlane DokuWiki writer+ License : GNU GPL, version 2 or above++ Maintainer : Eric Forgeot+ Stability : alpha+ Portability : portable++Conversion of 'Pandoc' documents to Txt2Tags markup.++Txt2Tags: <https://www.txt2tags.org/>+-}++module Text.Pandoc.Writers.Txt2Tags ( writeTxt2Tags ) where+import Control.Monad (zipWithM)+import Control.Monad.Reader (ReaderT, asks, local, runReaderT)+import Data.Default (Default (..))+import Data.List (transpose)+import Data.List.NonEmpty (nonEmpty)+import Data.Text (Text)+import qualified Data.Text as T+import Text.Pandoc.Class.PandocMonad (PandocMonad, report)+import Text.Pandoc.Definition+import Text.Pandoc.ImageSize+import Text.Pandoc.Logging+import Text.Pandoc.Options (WrapOption (..), WriterOptions (writerTableOfContents,+ writerTemplate, writerWrapText))+import Text.Pandoc.Shared (figureDiv, linesToPara, removeFormatting, trimr)+import Text.Pandoc.URI (escapeURI, isURI)+import Text.Pandoc.Templates (renderTemplate)+import Text.DocLayout (render, literal)+import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable)++data WriterEnvironment = WriterEnvironment {+ stIndent :: Text -- Indentation prefix for the current list nesting level+ , stBackSlashLB :: Bool -- True inside table cells (use \\ for line breaks)+ }++instance Default WriterEnvironment where+ def = WriterEnvironment { stIndent = ""+ , stBackSlashLB = False }++type Txt2Tags m = ReaderT WriterEnvironment m++-- | Convert Pandoc to Txt2Tags.+writeTxt2Tags :: PandocMonad m => WriterOptions -> Pandoc -> m Text+writeTxt2Tags opts document =+ runTxt2Tags (pandocToTxt2Tags opts document)++runTxt2Tags :: PandocMonad m => Txt2Tags m a -> m a+runTxt2Tags = flip runReaderT def++-- | Return Txt2Tags representation of document.+pandocToTxt2Tags :: PandocMonad m+ => WriterOptions -> Pandoc -> Txt2Tags m Text+pandocToTxt2Tags opts (Pandoc meta blocks) = do+ metadata <- metaToContext opts+ (fmap (literal . trimr) . blockListToTxt2Tags opts)+ (fmap (literal . trimr) . inlineListToTxt2Tags opts)+ meta+ body <- blockListToTxt2Tags opts blocks+ let context = defField "body" body+ $ defField "toc" (writerTableOfContents opts) metadata+ return $+ case writerTemplate opts of+ Nothing -> body+ Just tpl -> render Nothing $ renderTemplate tpl context++-- | Escape special characters for Txt2Tags.+-- The %%text%% syntax disables Txt2Tags formatting interpretation.+escapeString :: Text -> Text+escapeString = T.replace "``" "%%``%%" .+ T.replace "--" "%%--%%" .+ T.replace "__" "%%__%%" .+ T.replace "**" "%%**%%" .+ T.replace "//" "%%//%%"++-- | Convert Pandoc block element to Txt2Tags.+blockToTxt2Tags :: PandocMonad m+ => WriterOptions -- ^ Options+ -> Block -- ^ Block element+ -> Txt2Tags m Text++blockToTxt2Tags opts (Div _attrs bs) = do+ contents <- blockListToTxt2Tags opts bs+ indent <- asks stIndent+ return $ contents <> if T.null indent then "\n" else ""++blockToTxt2Tags opts (Plain inlines) =+ inlineListToTxt2Tags opts inlines++blockToTxt2Tags opts (Para inlines) = do+ indent <- asks stIndent+ contents <- inlineListToTxt2Tags opts inlines+ return $ contents <> if T.null indent then "\n" else ""++blockToTxt2Tags opts (LineBlock lns) =+ blockToTxt2Tags opts $ linesToPara lns++blockToTxt2Tags _ b@(RawBlock f str)+ | f == Format "txt2tags" = return str+ -- Use the Txt2Tags raw area syntax (""") for block-level HTML pass-through:+ | f == Format "html" = return $ "\"\"\"\n" <> str <> "\n\"\"\"\n"+ | otherwise = "" <$ report (BlockNotRendered b)++blockToTxt2Tags _ HorizontalRule = return "\n--------------------\n"++blockToTxt2Tags opts (Header level _ inlines) = do+ -- Formatting is not allowed in headers, so strip it+ contents <- inlineListToTxt2Tags opts $ removeFormatting inlines+ let eqs = T.replicate level "="+ return $ eqs <> " " <> contents <> " " <> eqs <> "\n"++-- | Txt2Tags verbatim area uses ``` delimiters.+blockToTxt2Tags _ (CodeBlock _ str) =+ return $ "```\n" <> str <>+ (if "\n" `T.isSuffixOf` str then "" else "\n") <> "```\n"++-- | Txt2Tags has no blockquote syntax; render content without special markup.+blockToTxt2Tags opts (BlockQuote blocks) =+ blockListToTxt2Tags opts blocks++blockToTxt2Tags opts (Table _ blkCapt specs thead tbody tfoot) = do+ let (capt, aligns, _, headers, rows) = toLegacyTable blkCapt specs thead tbody tfoot+ captionDoc <- if null capt+ then return ""+ else do+ c <- inlineListToTxt2Tags opts capt+ return $ c <> "\n"+ headers' <- if all null headers+ then return []+ else zipWithM (tableItemToTxt2Tags opts) aligns headers+ rows' <- mapM (zipWithM (tableItemToTxt2Tags opts) aligns) rows+ let widths = map (maybe 0 maximum . nonEmpty . map T.length)+ $ transpose (headers':rows')+ let padTo (width, al) s =+ case width - T.length s of+ x | x > 0 ->+ if al == AlignLeft || al == AlignDefault+ then s <> T.replicate x " "+ else if al == AlignRight+ then T.replicate x " " <> s+ else T.replicate (x `div` 2) " " <>+ s <> T.replicate (x - x `div` 2) " "+ | otherwise -> s+ let renderRow sep cells =+ sep <> T.intercalate sep (zipWith padTo (zip widths aligns) cells) <> sep+ return $ captionDoc <>+ (if null headers' then "" else renderRow "|" headers' <> "\n") <>+ T.unlines (map (renderRow "|") rows')++blockToTxt2Tags opts (BulletList items) = do+ indent <- asks stIndent+ contents <- local (\s -> s { stIndent = stIndent s <> " " })+ (mapM (listItemToTxt2Tags opts) items)+ return $ vcat contents <> if T.null indent then "\n" else ""++blockToTxt2Tags opts (OrderedList _attribs items) = do+ indent <- asks stIndent+ contents <- local (\s -> s { stIndent = stIndent s <> " " })+ (mapM (orderedListItemToTxt2Tags opts) items)+ return $ vcat contents <> if T.null indent then "\n" else ""++blockToTxt2Tags opts (Figure attr capt body) =+ blockToTxt2Tags opts $ figureDiv attr capt body++blockToTxt2Tags opts (DefinitionList items) = do+ indent <- asks stIndent+ contents <- local (\s -> s { stIndent = stIndent s <> " " })+ (mapM (definitionListItemToTxt2Tags opts) items)+ return $ vcat contents <> if T.null indent then "\n" else ""++-- Auxiliary functions for lists:++-- | Convert bullet list item (list of blocks) to Txt2Tags.+listItemToTxt2Tags :: PandocMonad m+ => WriterOptions -> [Block] -> Txt2Tags m Text+listItemToTxt2Tags opts items = do+ bs <- mapM (blockToTxt2Tags opts) items+ indent <- asks stIndent+ -- BulletList increments indent by " ", so T.drop 2 gives the marker position:+ -- level 1 -> "", level 2 -> " ", etc.+ let markerIndent = T.drop 2 indent+ -- Use newlines between blocks; T.stripEnd preserves leading spaces (e.g. nested+ -- list indentation) while removing trailing newlines that would create blank lines.+ let contents = T.intercalate "\n" (map T.stripEnd bs)+ return $ markerIndent <> "- " <> contents++-- | Convert ordered list item (list of blocks) to Txt2Tags.+orderedListItemToTxt2Tags :: PandocMonad m => WriterOptions -> [Block] -> Txt2Tags m Text+orderedListItemToTxt2Tags opts items = do+ bs <- mapM (blockToTxt2Tags opts) items+ indent <- asks stIndent+ -- OrderedList increments indent by " ", so T.drop 2 gives the marker position+ let markerIndent = T.drop 2 indent+ let contents = T.intercalate "\n" (map T.stripEnd bs)+ return $ markerIndent <> "+ " <> contents++-- | Convert definition list item (label, list of blocks) to Txt2Tags.+-- Txt2Tags has no native definition list syntax; we use ": **term**" as a+-- label followed by indented definition content.+definitionListItemToTxt2Tags :: PandocMonad m+ => WriterOptions+ -> ([Inline], [[Block]])+ -> Txt2Tags m Text+definitionListItemToTxt2Tags opts (label, items) = do+ labelText <- inlineListToTxt2Tags opts label+ contents <- mapM (blockListToTxt2Tags opts) items+ indent <- asks stIndent+ let markerIndent = T.drop 2 indent+ let defIndent = markerIndent <> " "+ let fmtItem c = defIndent <> T.stripEnd c+ return $ markerIndent <> ": **" <> labelText <> "**\n" <>+ T.intercalate "\n" (map fmtItem contents)++-- | Concatenates strings with newlines between them.+vcat :: [Text] -> Text+vcat = T.intercalate "\n"++-- | For each string in the input list, replace newlines with Txt2Tags line+-- breaks (\\). Then join the list using double line breaks to simulate+-- paragraph breaks in table cells.+backSlashLineBreaks :: [Text] -> Text+backSlashLineBreaks ls = vcatBackSlash $ map (T.pack . escape . T.unpack) ls+ where+ vcatBackSlash = T.intercalate "\\\\ \\\\ " -- simulate paragraph break+ escape ['\n'] = "" -- remove trailing newlines+ escape ('\n':cs) = "\\\\ " <> escape cs+ escape (c:cs) = c : escape cs+ escape [] = []++-- Auxiliary functions for tables:++tableItemToTxt2Tags :: PandocMonad m+ => WriterOptions+ -> Alignment+ -> [Block]+ -> Txt2Tags m Text+tableItemToTxt2Tags opts align' item = do+ -- In Txt2Tags, alignment is indicated by spaces around cell content:+ -- leading space -> right, trailing space -> left, both -> center.+ let mkcell x = (if align' == AlignRight || align' == AlignCenter+ then " "+ else "") <> x <>+ (if align' == AlignLeft || align' == AlignCenter+ then " "+ else "")+ contents <- local (\s -> s { stBackSlashLB = True }) $+ blockListToTxt2Tags opts item+ return $ mkcell contents++-- | Convert list of Pandoc block elements to Txt2Tags.+blockListToTxt2Tags :: PandocMonad m+ => WriterOptions -- ^ Options+ -> [Block] -- ^ List of block elements+ -> Txt2Tags m Text+blockListToTxt2Tags opts blocks = do+ backSlash <- asks stBackSlashLB+ let blocks' = consolidateRawBlocks blocks+ if backSlash+ then backSlashLineBreaks <$> mapM (blockToTxt2Tags opts) blocks'+ else vcat <$> mapM (blockToTxt2Tags opts) blocks'++consolidateRawBlocks :: [Block] -> [Block]+consolidateRawBlocks [] = []+consolidateRawBlocks (RawBlock f1 b1 : RawBlock f2 b2 : xs)+ | f1 == f2 = consolidateRawBlocks (RawBlock f1 (b1 <> "\n" <> b2) : xs)+consolidateRawBlocks (x:xs) = x : consolidateRawBlocks xs++-- | Convert list of Pandoc inline elements to Txt2Tags.+inlineListToTxt2Tags :: PandocMonad m+ => WriterOptions -> [Inline] -> Txt2Tags m Text+inlineListToTxt2Tags opts lst =+ T.concat <$> mapM (inlineToTxt2Tags opts) lst++-- | Render inlines wrapped in the given left and right delimiters.+surroundInlines :: PandocMonad m+ => WriterOptions -> Text -> Text -> [Inline] -> Txt2Tags m Text+surroundInlines opts left right lst = do+ contents <- inlineListToTxt2Tags opts lst+ return $ left <> contents <> right++-- | Convert Pandoc inline element to Txt2Tags.+inlineToTxt2Tags :: PandocMonad m+ => WriterOptions -> Inline -> Txt2Tags m Text++inlineToTxt2Tags opts (Span _attrs ils) =+ inlineListToTxt2Tags opts ils++inlineToTxt2Tags opts (Emph lst) = surroundInlines opts "//" "//" lst++inlineToTxt2Tags opts (Underline lst) = surroundInlines opts "__" "__" lst++inlineToTxt2Tags opts (Strong lst) = surroundInlines opts "**" "**" lst++inlineToTxt2Tags opts (Strikeout lst) = surroundInlines opts "--" "--" lst++-- Txt2Tags has no superscript/subscript syntax; fall back to HTML tags.+inlineToTxt2Tags opts (Superscript lst) = surroundInlines opts "<sup>" "</sup>" lst++inlineToTxt2Tags opts (Subscript lst) = surroundInlines opts "<sub>" "</sub>" lst++inlineToTxt2Tags opts (SmallCaps lst) = inlineListToTxt2Tags opts lst++inlineToTxt2Tags opts (Quoted SingleQuote lst) = surroundInlines opts "\8216" "\8217" lst++inlineToTxt2Tags opts (Quoted DoubleQuote lst) = surroundInlines opts "\8220" "\8221" lst++inlineToTxt2Tags opts (Cite _ lst) = inlineListToTxt2Tags opts lst++-- | Inline code uses Txt2Tags verbatim syntax (double backticks).+inlineToTxt2Tags _ (Code _ str) =+ return $ "``" <> str <> "``"++inlineToTxt2Tags _ (Str str) = return $ escapeString str++inlineToTxt2Tags _ (Math mathType str) = return $ delim <> str <> delim+ -- note: str should NOT be escaped+ where delim = case mathType of+ DisplayMath -> "$$"+ InlineMath -> "$"++inlineToTxt2Tags _ il@(RawInline f str)+ | f == Format "txt2tags" = return str+ -- Use the Txt2Tags inline raw syntax ("") for HTML pass-through:+ | f == Format "html" = return $ "\"\"" <> str <> "\"\""+ | otherwise = "" <$ report (InlineNotRendered il)++inlineToTxt2Tags _ LineBreak = do+ backSlash <- asks stBackSlashLB+ return $ if backSlash then "\n" else "\\\\\n"++inlineToTxt2Tags opts SoftBreak =+ case writerWrapText opts of+ WrapNone -> return " "+ WrapAuto -> return " "+ WrapPreserve -> return "\n"++inlineToTxt2Tags _ Space = return " "++inlineToTxt2Tags opts (Link _ txt (src, _)) = do+ label <- inlineListToTxt2Tags opts txt+ case txt of+ [Str s] | "mailto:" `T.isPrefixOf` src -> return $ "<" <> s <> ">"+ | escapeURI s == src -> return src+ _ -> if isURI src+ then return $ "[" <> label <> " " <> src <> "]"+ else return $ "[" <> label <> " " <> src' <> "]"+ where src' = case T.uncons src of+ Just ('/', xs) -> xs+ _ -> src++inlineToTxt2Tags opts (Image attr alt (source, tit)) = do+ alt' <- inlineListToTxt2Tags opts alt+ let txt = case (tit, alt) of+ ("", []) -> ""+ ("", _ ) -> "|" <> alt'+ (_ , _ ) -> "|" <> tit+ return $ "[" <> source <> imageDims opts attr <> txt <> "]"++-- | Txt2Tags has no footnote syntax; render note content inline in parentheses.+inlineToTxt2Tags opts (Note contents) = do+ contents' <- blockListToTxt2Tags opts contents+ return $ "(" <> T.strip contents' <> ")"++imageDims :: WriterOptions -> Attr -> Text+imageDims opts attr = go (toPx $ dimension Width attr) (toPx $ dimension Height attr)+ where+ toPx = fmap (showInPixel opts) . checkPct+ checkPct (Just (Percent _)) = Nothing+ checkPct maybeDim = maybeDim+ go (Just w) Nothing = "?" <> w+ go (Just w) (Just h) = "?" <> w <> "x" <> h+ go Nothing (Just h) = "?0x" <> h+ go Nothing Nothing = ""
@@ -138,6 +138,9 @@ pickTypstAttrs :: [(Text, Text)] -> ([(Text, Text)],[(Text, Text)]) pickTypstAttrs = foldr go ([],[]) where+ go ("lang",lang)+ | Right l <- parseLang lang+ = second (("lang", tshow (langLanguage l)):) go (k,v) = case T.splitOn ":" k of ["typst", "text", x] -> second ((x,v):)@@ -232,7 +235,7 @@ contents <- blocksToTypst blocks return $ "#quote(block: true)[" $$ chomp contents $$ "]" $$ blankline HorizontalRule ->- return $ blankline <> "#horizontalrule" <> blankline+ return $ blankline <> "#divider()" <> blankline OrderedList attribs items -> do let addBlock = case attribs of (1, DefaultStyle, DefaultDelim) -> id@@ -261,8 +264,11 @@ return $ (if isTightList items then vcat items' else vsep items') $$ blankline- DefinitionList items ->- ($$ blankline) . vsep <$> mapM defListItemToTypst items+ DefinitionList items -> do+ let concat' = if all (isTightList . snd) items+ then vcat+ else vsep+ ($$ blankline) . concat' <$> mapM defListItemToTypst items Table (ident,tabclasses,tabkvs) (Caption _ caption) colspecs thead tbodies tfoot -> do let lab = toLabel FreestandingLabel ident capt' <- if null caption@@ -385,17 +391,9 @@ Div (ident,_,kvs) blocks -> do let lab = toLabel FreestandingLabel ident let (typstAttrs,typstTextAttrs) = pickTypstAttrs kvs- -- Handle lang attribute for Div elements- let langAttrs = case lookup "lang" kvs of- Nothing -> []- Just lang -> case parseLang lang of- Left _ -> []- Right l -> [("lang",- tshow (langLanguage l))]- let allTypstTextAttrs = typstTextAttrs ++ langAttrs contents <- blocksToTypst blocks return $ "#block" <> toTypstPropsListParens typstAttrs <> "["- $$ toTypstPoundSetText allTypstTextAttrs+ $$ toTypstPoundSetText typstTextAttrs $$ contents $$ ("]" <+> lab) @@ -405,7 +403,10 @@ term' <- inlinesToTypst term modify $ \st -> st{ stEscapeContext = NormalContext } defns' <- mapM blocksToTypst defns- return $ nowrap ("/ " <> term' <> ": " <> "#block[") $$+ return $+ case defns of+ [[Plain _]] -> hang 4 (nowrap ("/ " <> term' <> ": ")) (vcat defns')+ _ -> nowrap ("/ " <> term' <> ": " <> "#block[") $$ chomp (vsep defns') $$ "]" listItemToTypst :: PandocMonad m => Int -> Doc Text -> [Block] -> TW m (Doc Text)
@@ -173,7 +173,8 @@ "haddock-reader.haddock" "haddock-reader.native" ] , testGroup "txt2tags"- [ test' "reader" ["-r", "t2t", "-w", "native", "-s"]+ [ testGroup "writer" $ writerTests' "t2t"+ , test' "reader" ["-r", "t2t", "-w", "native", "-s"] "txt2tags.t2t" "txt2tags.native" ] , testGroup "epub" [ test' "features" ["-r", "epub", "-w", "native", "-s"]
@@ -282,6 +282,10 @@ "docx/lists_sublist_reset.docx" "docx/lists_sublist_reset.native" , testCompare+ "style-based list restarted on one item (#8367)"+ "docx/lists_restart_8367.docx"+ "docx/lists_restart_8367.native"+ , testCompare "definition lists" "docx/definition_list.docx" "docx/definition_list.native"
@@ -220,5 +220,34 @@ , "include newlines" =: "**before\nafter**" =?> para (strong (text "before\nafter"))+ , "bare reference reusing a named target resolves correctly" =:+ T.unlines+ [ ".. _target:"+ , ""+ , "See `alias <target_>`_ and again alias_."+ ] =?>+ divWith ("target",[],[])+ (para ("See " <> link "#target" "" "alias" <> " and again " <>+ link "#target" "" "alias" <> "."))+ , "self-referencing named target does not loop forever" =:+ "See `a <a_>`_." =?>+ para ("See " <> link "##REF##a" "" "a" <> ".")+ , "reference to internal target embedded in a substitution" =:+ T.unlines+ [ ".. _target:"+ , ""+ , "See |sub|."+ , ""+ , ".. |sub| replace:: `text <target_>`_"+ ] =?>+ divWith ("target",[],[])+ (para ("See " <> link "#target" "" "text" <> "."))+ , "circular substitution does not loop forever" =:+ T.unlines+ [ ".. |a| replace:: |a|"+ , ""+ , "Test |a| here."+ ] =?>+ para ("Test " <> spanWith ("",[],[]) "|a|" <> " here.") ] ]
@@ -35,6 +35,8 @@ , "formatting" , "list_simple" , "list_complex"+ , "list_multiparagraph"+ , "list_legacy" , "bookmark" , "table_simple" , "table_error_codes"
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Tests.Writers.Docx (tests) where -import Codec.Archive.Zip (findEntryByPath, fromEntry, toArchive)+import Codec.Archive.Zip (Archive, findEntryByPath, fromEntry, toArchive) import qualified Data.ByteString.Lazy as BL import Data.List (isInfixOf, isPrefixOf) import qualified Data.Map as M@@ -12,8 +12,35 @@ import Test.Tasty.HUnit import Tests.Writers.OOXML import Text.Pandoc-import Text.XML.Light (QName(QName), findAttr, findElements, parseXMLDoc)+import Text.XML.Light ( Element, QName(QName), findAttr, findElements+ , parseXMLDoc ) +wmlName :: String -> QName+wmlName n = QName n+ (Just "http://schemas.openxmlformats.org/wordprocessingml/2006/main")+ (Just "w")++entryBytes :: String -> Archive -> IO BL.ByteString+entryBytes path archive =+ maybe (assertFailure $ "Missing " ++ path) (return . fromEntry) $+ findEntryByPath path archive++entryXml :: String -> Archive -> IO Element+entryXml path archive =+ maybe (assertFailure $ "Invalid " ++ path) return . parseXMLDoc+ =<< entryBytes path archive++documentXml :: WriterOptions -> Pandoc -> IO Element+documentXml opts doc =+ entryXml "word/document.xml" . toArchive =<<+ runIOorExplode (setVerbosity ERROR >> writeDocx opts doc)++documentXmlFromNative :: WriterOptions -> FilePath -> IO Element+documentXmlFromNative opts fp = do+ txt <- T.readFile fp+ entryXml "word/document.xml" . toArchive =<<+ runIOorExplode (setVerbosity ERROR >> readNative def txt >>= writeDocx opts)+ -- 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 -- Word-generated docx file used to test the reader.@@ -223,82 +250,39 @@ "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)+ doc <- documentXml opts $ Pandoc mempty+ [ Header 1 ("ch1", [], []) [Str "Chapter", Space, Str "1"]+ , Para [Str "First", Space, Str "chapter."]+ ]+ let sectPrCount = length $ findElements (wmlName "sectPr") doc+ assertBool ("Expected 1 sectPr, 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)+ doc <- documentXml opts $ 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."]+ ]+ let sectPrCount = length $ findElements (wmlName "sectPr") doc+ assertBool ("Expected 3 sectPrs, 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" }+ 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+ doc <- entryXml "[Content_Types].xml" $ toArchive bs let partNameAttr = QName "PartName" Nothing Nothing let overrideName = QName "Override" Nothing Nothing let overrides = findElements overrideName doc@@ -311,43 +295,41 @@ -- 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)+ refStylesXml <- show <$> entryBytes "word/styles.xml" refArchive 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" }+ 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)+ stylesXml <- show <$> entryBytes "word/styles.xml" (toArchive bs) -- 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 "section properties from non-w-prefix reference docx" $ do+ let opts = def{writerReferenceDoc=Just "docx/ns0-reference.docx"}+ doc <- documentXmlFromNative opts "docx/inline_formatting.native"+ case findElements (wmlName "sectPr") doc of+ [] -> assertFailure "sectPr not found in output"+ sectPr:_ -> do+ assertBool "pgSz not found in output"+ (not $ null $ findElements (wmlName "pgSz") sectPr)+ findAttr (wmlName "type") sectPr @?= Just "continuous" , 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" }+ 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)+ stylesXml <- show <$> entryBytes "word/styles.xml" (toArchive bs) -- 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)"@@ -364,11 +346,7 @@ , 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)+ docXml <- show <$> entryBytes "word/document.xml" (toArchive bs) assertBool ("Expected FirstParagraph style after heading with footnote, got: " ++ docXml)
@@ -78,6 +78,10 @@ def "pptx/tables/input.native" "pptx/tables/output.pptx"+ , pptxTests "table with surrounding content stays on same slide"+ def+ "pptx/table-with-surrounding-content/input.native"+ "pptx/table-with-surrounding-content/output.pptx" , pptxTests "table of contents" def{ writerTableOfContents = True } "pptx/slide-breaks/input.native"
@@ -0,0 +1,124 @@+{-# LANGUAGE OverloadedStrings #-}+module Tests.Writers.Txt2Tags (tests) where++import Data.Text (Text)+import Test.Tasty+import Test.Tasty.HUnit (HasCallStack)+import Tests.Helpers+import Text.Pandoc+import Text.Pandoc.Arbitrary ()+import Text.Pandoc.Builder++txt2tags :: (ToPandoc a) => a -> Text+txt2tags = purely (writeTxt2Tags def) . toPandoc++infix 4 =:+(=:) :: (ToString a, ToPandoc a, HasCallStack)+ => String -> (a, Text) -> TestTree+(=:) = test txt2tags++tests :: [TestTree]+tests =+ [ testGroup "inline formatting"+ [ "bold" =: strong "text" =?> "**text**"+ , "italic" =: emph "text" =?> "//text//"+ , "underline" =: underline "text" =?> "__text__"+ , "strikeout" =: strikeout "text" =?> "--text--"+ , "inline code" =: code "foo" =?> "``foo``"+ ]+ , testGroup "escape special characters"+ [ "escape bold marker" =: str "a**b" =?> "a%%**%%b"+ , "escape italic marker" =: str "a//b" =?> "a%%//%%b"+ , "escape underline marker" =: str "a__b" =?> "a%%__%%b"+ , "escape strikeout marker" =: str "a--b" =?> "a%%--%%b"+ , "escape code marker" =: str "a``b" =?> "a%%``%%b"+ ]+ , testGroup "headers"+ [ "h1" =: header 1 "Heading" =?> "= Heading =\n"+ , "h2" =: header 2 "Heading" =?> "== Heading ==\n"+ , "h3" =: header 3 "Heading" =?> "=== Heading ===\n"+ , "h4" =: header 4 "Heading" =?> "==== Heading ====\n"+ ]+ , testGroup "code blocks"+ [ "no trailing newline in source"+ =: codeBlock "foo"+ =?> "```\nfoo\n```\n"+ , "trailing newline preserved"+ =: codeBlock "foo\n"+ =?> "```\nfoo\n```\n"+ ]+ , testGroup "lists"+ [ "bullet list"+ =: bulletList [para "foo", para "bar"]+ =?> "- foo\n- bar\n"+ , "ordered list"+ =: orderedList [para "foo", para "bar"]+ =?> "+ foo\n+ bar\n"+ , "nested bullet list"+ =: bulletList [para "a" <> bulletList [para "b"]]+ =?> "- a\n - b\n"+ , "nested ordered list"+ =: orderedList [para "a" <> orderedList [para "b"]]+ =?> "+ a\n + b\n"+ ]+ , testGroup "definition lists"+ [ "single term and definition"+ =: definitionList [("term", [para "definition"])]+ =?> ": **term**\n definition\n"+ , "multiple terms"+ =: definitionList+ [ ("foo", [para "def foo"])+ , ("bar", [para "def bar"])+ ]+ =?> ": **foo**\n def foo\n: **bar**\n def bar\n"+ , "multiple definitions for one term"+ =: definitionList [("term", [para "def1", para "def2"])]+ =?> ": **term**\n def1\n def2\n"+ ]+ , testGroup "blockquote"+ -- Txt2Tags has no blockquote syntax; content is rendered without special markup.+ [ "blockquote rendered as plain content"+ =: blockQuote (para "quoted")+ =?> "quoted\n"+ ]+ , testGroup "horizontal rule"+ [ "hr" =: horizontalRule =?> "\n--------------------\n"+ ]+ , testGroup "tables"+ [ "table with headers"+ =: simpleTable [plain "A", plain "B"]+ [[plain "1", plain "2"]]+ =?> "|A|B|\n|1|2|\n"+ , "table without headers"+ =: simpleTable [] [[plain "1", plain "2"]]+ =?> "|1|2|\n"+ ]+ , testGroup "links"+ [ "link with label"+ =: link "http://example.com" "" "example"+ =?> "[example http://example.com]"+ , "autolink"+ =: link "http://example.com" "" "http://example.com"+ =?> "http://example.com"+ , "email"+ =: link "mailto:user@example.com" "" "user@example.com"+ =?> "<user@example.com>"+ ]+ , testGroup "images"+ [ "simple image (no title, no alt)"+ -- Use imageWith + mempty to get truly empty alt ([]) vs str "" which gives [Str ""]+ =: imageWith ("", [], []) "image.png" "" mempty+ =?> "[image.png]"+ , "image with title"+ =: image "image.png" "My title" "ignored alt"+ =?> "[image.png|My title]"+ , "image with alt text (no title)"+ =: image "image.png" "" "alt text"+ =?> "[image.png|alt text]"+ ]+ , testGroup "raw blocks"+ [ "txt2tags passthrough"+ =: rawBlock "txt2tags" "raw content"+ =?> "raw content"+ ]+ ]
@@ -0,0 +1,129 @@+```+% pandoc -t latex+: Here's the caption.+It may span multiple lines. {.float #ident latex-placement="ht"}++---------------------------------------------------------------+ Centered Left Right+ Header Aligned Aligned Default aligned+---------- --------- ----------- ---------------------------+ First row 12.0 Example of a row that spans+ multiple lines.++ Second row 5.0 Here's another one. Note+ the blank line between rows.+---------------------------------------------------------------+^D+\begin{table}[ht]+\centering+\caption{Here's the caption. It may span multiple+lines.}\label{ident}\tabularnewline+\begin{tabular}{@{}+ >{\centering\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1667}}+ >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1528}}+ >{\raggedleft\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1806}}+ >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3889}}@{}}+\toprule\noalign{}+\begin{minipage}[b]{\linewidth}\centering+Centered Header+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright+Left Aligned+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft+Right Aligned+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright+Default aligned+\end{minipage} \\+\midrule\noalign{}+First & row & 12.0 & Example of a row that spans multiple lines. \\+Second & row & 5.0 & Here's another one. Note the blank line between+rows. \\+\bottomrule\noalign{}+\end{tabular}+\end{table}++```++```+% pandoc -t latex+: Simple table with no column headers {.float #ident}++------- ------ ---------- -------+ 12 12 12 12+ 123 123 123 123+ 1 1 1 1+------- ------ ---------- -------+^D+\begin{table}[]+\centering+\caption{Simple table with no column+headers}\label{ident}\tabularnewline+\begin{tabular}{@{}rlcr@{}}+\toprule\noalign{}+12 & 12 & 12 & 12 \\+123 & 123 & 123 & 123 \\+1 & 1 & 1 & 1 \\+\bottomrule\noalign{}+\end{tabular}+\end{table}++```++```+% pandoc -t latex++--------------------+---------------------+---------------+---------------++| Name^[In English.] | Capital | Population\ | Area\ |+| | | (in 2018) | (in km^2^) |++:==================:+:====================+:==============+:==============++| Denmark | Copenhagen | 5,809,502 | 43,094 |++--------------------+---------------------+---------------+---------------++| Finland | Helsinki | 5,537,364 | 338,145 |++--------------------+---------------------+---------------+---------------++| Iceland^[Brrr.] | 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" .float}+^D+\begin{table}[]+\centering+\caption{States belonging to the+\emph{Nordics.}}\label{nordics}\tabularnewline+\begin{tabular}{@{}+ >{\centering\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2727}}+ >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2857}}+ >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2078}}+ >{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2078}}@{}}+\toprule\noalign{}+\begin{minipage}[b]{\linewidth}\centering+Name\footnotemark{}+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright+Capital+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright+Population\\+(in 2018)\strut+\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright+Area\\+(in km\textsuperscript{2})\strut+\end{minipage} \\+\midrule\noalign{}+Denmark & Copenhagen & 5,809,502 & 43,094 \\+Finland & Helsinki & 5,537,364 & 338,145 \\+Iceland\footnotemark{} & Reykjavik & 343,518 & 103,000 \\+Norway & Oslo & 5,372,191 & 323,802 \\+Sweden & Stockholm & 10,313,447 & 450,295 \\+\midrule\noalign{}+Total & & 27,376,022 & 1,258,336 \\+\bottomrule\noalign{}+\end{tabular}+\end{table}+\addtocounter{footnote}{-1}+\footnotetext{In English.}+\addtocounter{footnote}{1}+\footnotetext{Brrr.}++```
@@ -0,0 +1,6 @@+```+% pandoc -t typst+[Bonjour]{lang=fr} world.+^D+#text(lang: "fr")[Bonjour] world.+```
@@ -0,0 +1,18 @@+```+% pandoc -f rst -t markdown_mmd+.. note::++ ``code``+^D+<div class="note" markdown="1">++<div class="title" markdown="1">++Note++</div>++`code`++</div>+```
binary file changed (absent → 15080 bytes)
@@ -0,0 +1,18 @@+```+% pandoc command/11689.docx -t native+^D+[ Para [ Str "Horizontal" , Space , Str "Line" ]+, Para [ Str "Hyphens" ]+, HorizontalRule+, Para [ Str "Underlines" ]+, HorizontalRule+, Para [ Str "Equal" , Space , Str "Signs" ]+, HorizontalRule+, Para [ Str "Asterisks" ]+, HorizontalRule+, Para [ Str "Number" , Space , Str "Signs" ]+, HorizontalRule+, Para [ Str "Tildes" ]+, HorizontalRule+]+```
@@ -0,0 +1,9 @@+````+% pandoc -f html -t gfm+<pre style="white-space: pre-wrap"><code class="hljs language-bash">echo hello+</code></pre>+^D+``` bash+echo hello+```+````
@@ -0,0 +1,8 @@+```+% pandoc -f gfm -t gfm+- [ ]+- [ ] bubbles+^D+- [ ]+- [ ] bubbles+```
@@ -0,0 +1,10 @@+```+% pandoc -f native -t markdown -s+Pandoc Meta {unMeta = fromList [ ("format_version", MetaString "3.10") ] } []+^D+---+format_version: "3.10"+---+++```
@@ -0,0 +1,8 @@+```+% pandoc -f rst -t markdown+[file|URL|PLAYLIST]++^D+2> [WARNING] Reference not found for '"url"' at line 4 column 1+\[file\|URL\|PLAYLIST\]+```
@@ -0,0 +1,14 @@+```+% pandoc+- Value ends with+ 2.+- Gilda+ (1946)+^D+<ul>+<li>Value ends with+2.</li>+<li>Gilda+(1946)</li>+</ul>+```
@@ -0,0 +1,40 @@+```+% pandoc -f dokuwiki -t native+| a | extra stuff+| b | extra stuff+after+^D+[ Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault ) ]+ (TableHead ( "" , [] , [] ) [])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "a" ] ]+ ]+ , Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "b" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+, Para [ Str "after" ]+]++```
@@ -0,0 +1,26 @@+```+% pandoc --section-divs+# Book Title++::: {#ch1 .section}+## Chapter 1+Hello world.+:::++::: {#ch2 .section}+## Chapter 2+Goodbye world.+:::+^D+<section id="book-title" class="level1">+<h1>Book Title</h1>+<section id="ch1" class="level2">+<h2 id="chapter-1">Chapter 1</h2>+<p>Hello world.</p>+</section>+<section id="ch2" class="level2">+<h2 id="chapter-2">Chapter 2</h2>+<p>Goodbye world.</p>+</section>+</section>+```
@@ -0,0 +1,23 @@+```+% pandoc -t texinfo+Before++----++After+^D+@node Top+@top Top++Before++@iftex+@bigskip@hrule@bigskip+@end iftex+@ifnottex+------------------------------------------------------------------------+@end ifnottex++After++```
@@ -0,0 +1,13 @@+```+% pandoc -t texinfo+[a.b](url)++[a,b](url)+^D+@node Top+@top Top++@uref{url,a.b}++@uref{url,a@comma{}b}+```
@@ -0,0 +1,12 @@+```+% pandoc -f native -t commonmark | pandoc -f commonmark -t native+[ OrderedList+ ( 1 , Decimal , Period )+ [ [ CodeBlock ( "" , [] , [] ) "hi" ] ]+]+^D+[ OrderedList+ ( 1 , Decimal , Period )+ [ [ CodeBlock ( "" , [] , [] ) "hi" ] ]+]+```
@@ -6,10 +6,10 @@  ^D-<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="FigureWithCaption"><draw:frame draw:name="img1" text:anchor-type="as-char"><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">Figure <text:sequence text:ref-name="refIllustration0" text:name="Illustration" text:formula="ooow:Illustration+1" style:num-format="1">1</text:sequence>: First image</text:p>-<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img2"><draw:image xlink:href="lalune.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" /></draw:frame></text:p>+<text:p text:style-name="FigureWithCaption"><draw:frame draw:name="img2" text:anchor-type="as-char"><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">Figure <text:sequence text:ref-name="refIllustration1" text:name="Illustration" text:formula="ooow:Illustration+1" style:num-format="1">2</text:sequence>: Second image</text:p> ```
@@ -21,7 +21,7 @@ <text:p text:style-name="First_20_paragraph">Chapter 1 references <text:bookmark-ref text:reference-format="text" text:ref-name="chapter1">The Chapter</text:bookmark-ref></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="FigureWithCaption"><draw:frame draw:name="img1" text:anchor-type="as-char"><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">Voyage dans la Lune</text:p> <text:p text:style-name="Text_20_body">Image 1 references <text:sequence-ref text:reference-format="caption" text:ref-name="lalune">La@@ -38,7 +38,7 @@ Chapter<text:bookmark-end text:name="chapter1" /></text:h> <text:p text:style-name="First_20_paragraph">Chapter 1 references <text:bookmark-ref text:reference-format="number" text:ref-name="chapter1"></text:bookmark-ref></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="FigureWithCaption"><draw:frame draw:name="img1" text:anchor-type="as-char"><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">Image 1 references <text:sequence-ref text:reference-format="value" text:ref-name="lalune"></text:sequence-ref></text:p>@@ -55,7 +55,7 @@ <text:p text:style-name="First_20_paragraph">Chapter 1 references <text:bookmark-ref text:reference-format="number" text:ref-name="chapter1"></text:bookmark-ref><text:s /><text:bookmark-ref text:reference-format="text" text:ref-name="chapter1">The Chapter</text:bookmark-ref></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="FigureWithCaption"><draw:frame draw:name="img1" text:anchor-type="as-char"><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">Voyage dans la Lune</text:p> <text:p text:style-name="Text_20_body">Image 1 references <text:sequence-ref text:reference-format="value" text:ref-name="lalune"></text:sequence-ref><text:s /><text:sequence-ref text:reference-format="caption" text:ref-name="lalune">La
@@ -0,0 +1,10 @@+```+% pandoc -f markdown+raw_tex -t latex+Lorem \hypertarget{anchor} etc++Lorem \hyperlink{anchor}{the link} etc+^D+Lorem \hypertarget{anchor} etc++Lorem \hyperlink{anchor}{the link} etc+```
@@ -0,0 +1,14 @@+```+% pandoc -t latex+Header[^fn]:+: Some other text.++[^fn]: A footnote.+^D+\begin{description}+\tightlist+\item[Header\footnotemark{}:]+Some other text.+\end{description}+\footnotetext{A footnote.}+```
@@ -220,3 +220,15 @@ - [ ] foo - [x] bar ```++```+% pandoc -f native -t gfm+[ BulletList+ [ [ Plain [ Str "\9744" ] ]+ , [ Plain [ Str "\9746" ] ]+ ]+]+^D+- [ ]+- [x]+```
@@ -0,0 +1,121 @@+Test that content after a table stays on the same slide.++```+% pandoc -t native+## Slide with Bullets and Table++- First bullet before table+- Second bullet before table++| A | B |+|---|---|+| 1 | 2 |++- Third bullet after table+- Fourth bullet after table+^D+[ Header+ 2+ ( "slide-with-bullets-and-table" , [] , [] )+ [ Str "Slide"+ , Space+ , Str "with"+ , Space+ , Str "Bullets"+ , Space+ , Str "and"+ , Space+ , Str "Table"+ ]+, BulletList+ [ [ Plain+ [ Str "First"+ , Space+ , Str "bullet"+ , Space+ , Str "before"+ , Space+ , Str "table"+ ]+ ]+ , [ Plain+ [ Str "Second"+ , Space+ , Str "bullet"+ , Space+ , Str "before"+ , Space+ , Str "table"+ ]+ ]+ ]+, Table+ ( "" , [] , [] )+ (Caption Nothing [])+ [ ( AlignDefault , ColWidthDefault )+ , ( AlignDefault , ColWidthDefault )+ ]+ (TableHead+ ( "" , [] , [] )+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "A" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "B" ] ]+ ]+ ])+ [ TableBody+ ( "" , [] , [] )+ (RowHeadColumns 0)+ []+ [ Row+ ( "" , [] , [] )+ [ Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "1" ] ]+ , Cell+ ( "" , [] , [] )+ AlignDefault+ (RowSpan 1)+ (ColSpan 1)+ [ Plain [ Str "2" ] ]+ ]+ ]+ ]+ (TableFoot ( "" , [] , [] ) [])+, BulletList+ [ [ Plain+ [ Str "Third"+ , Space+ , Str "bullet"+ , Space+ , Str "after"+ , Space+ , Str "table"+ ]+ ]+ , [ Plain+ [ Str "Fourth"+ , Space+ , Str "bullet"+ , Space+ , Str "after"+ , Space+ , Str "table"+ ]+ ]+ ]+]+```
@@ -0,0 +1,37 @@+With `auto_identifiers` enabled, headings without an explicit label get+automatic identifiers, with collisions disambiguated:++```+% pandoc -f typst+auto_identifiers -t native+= Introduction++Text.++== A Sub Section++= Introduction+^D+[ Header+ 1 ( "introduction" , [] , [] ) [ Str "Introduction" ]+, Para [ Str "Text." ]+, Header+ 2+ ( "a-sub-section" , [] , [] )+ [ Str "A" , Space , Str "Sub" , Space , Str "Section" ]+, Header+ 1 ( "introduction-1" , [] , [] ) [ Str "Introduction" ]+]+```++The extension is off by default, so headings have no identifiers:++```+% pandoc -f typst -t native+= Introduction++Text.+^D+[ Header 1 ( "" , [] , [] ) [ Str "Introduction" ]+, Para [ Str "Text." ]+]+```
@@ -1175,11 +1175,14 @@ , Code ( "" , [] , [] ) "$" , Str "," , Space- , Code ( "" , [] , [] ) "\\`, "- , Str "$"- , Code ( "" , [] , [] ) ", "- , Str "<html>"- , Code ( "" , [] , [] ) "."+ , Code ( "" , [] , [] ) "\\"+ , Str ","+ , Space+ , Code ( "" , [] , [] ) "\\$"+ , Str ","+ , Space+ , Code ( "" , [] , [] ) "<html>"+ , Str "." ] , Para [ Span
binary file changed (absent → 22718 bytes)
@@ -0,0 +1,13 @@+[Header 1 ("section-1",[],[]) [Str "Section",Space,Str "1"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "Item",Space,Str "1"]]+ ,[Para [Str "Item",Space,Str "2"]]+ ,[Para [Str "Item",Space,Str "3"]]]+,Para [Str "Conclusion"]+,Header 1 ("section-2",[],[]) [Str "Section",Space,Str "2"]+,OrderedList (1,Decimal,Period)+ [[Para [Str "Item",Space,Str "1"]]+ ,[Para [Str "Item",Space,Str "2"]]+ ,[Para [Str "Item",Space,Str "3"]]+ ,[Para [Str "Item",Space,Str "4"]]]+,Para [Str "Conclusion"]]
binary file changed (absent → 2289 bytes)
binary file changed (44459 → 44499 bytes)
binary file changed (57553 → 57591 bytes)
binary file changed (52718 → 52690 bytes)
binary file changed (51344 → 51318 bytes)
binary file changed (52729 → 52701 bytes)
binary file changed (52303 → 52277 bytes)
binary file changed (27885 → 27849 bytes)
binary file changed (40979 → 40948 bytes)
@@ -0,0 +1,34 @@+[Header 2 ("slide-with-bullets-and-table",[],[]) [Str "Slide",Space,Str "with",Space,Str "Bullets",Space,Str "and",Space,Str "Table"]+,BulletList+ [[Plain [Str "First",Space,Str "bullet",Space,Str "point",Space,Str "before",Space,Str "the",Space,Str "table"]]+ ,[Plain [Str "Second",Space,Str "bullet",Space,Str "point",Space,Str "before",Space,Str "the",Space,Str "table"]]]+,Table ("",[],[]) (Caption Nothing [])+ [(AlignDefault,ColWidthDefault)+ ,(AlignDefault,ColWidthDefault)]+ (TableHead ("",[],[])+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Column",Space,Str "A"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Column",Space,Str "B"]]]])+ [(TableBody ("",[],[]) (RowHeadColumns 0)+ []+ [Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Value",Space,Str "1"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Value",Space,Str "2"]]]+ ,Row ("",[],[])+ [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Value",Space,Str "3"]]+ ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1)+ [Plain [Str "Value",Space,Str "4"]]]])]+ (TableFoot ("",[],[]) [])+,BulletList+ [[Plain [Str "Third",Space,Str "bullet",Space,Str "point",Space,Str "after",Space,Str "the",Space,Str "table"]]+ ,[Plain [Str "Fourth",Space,Str "bullet",Space,Str "point",Space,Str "after",Space,Str "the",Space,Str "table"]]]+,Header 2 ("second-slide-for-reference",[],[]) [Str "Second",Space,Str "Slide",Space,Str "for",Space,Str "Reference"]+,BulletList+ [[Plain [Str "This",Space,Str "slide",Space,Str "has",Space,Str "just",Space,Str "bullets"]]+ ,[Plain [Str "No",Space,Str "table",Space,Str "here"]]+ ,[Plain [Str "Everything",Space,Str "stays",Space,Str "together"]]]]
binary file changed (absent → 28886 bytes)
binary file changed (absent → 41984 bytes)
@@ -0,0 +1,14 @@+Pandoc+ Meta { unMeta = fromList [] }+ [ OrderedList+ ( 1 , Decimal , Period )+ [ [ Para [ Str "A" ] ]+ , [ Para [ Str "Numbered" ] ]+ , [ Para [ Str "List" ] ]+ ]+ , BulletList+ [ [ Para [ Str "A" ] ]+ , [ Para [ Str "Bulleted" ] ]+ , [ Para [ Str "List" ] ]+ ]+ ]
@@ -0,0 +1,4 @@+{\rtf1\ansi\deff0{\fonttbl{\f0 Helvetica;}{\f2 Symbol;}{\f3 Symbol;}}+\plain\plain\f0\fs20\pard\ssparaaux0\s0{\pntext\pard\plain\f2\fs22 1.\tab}{\*\pn\pnlvlbody\pnstart1\pndec\ls3\ilvl0\pnhang{\pntxta \'2e}}\ls3\ilvl0\fi-360\li360\ql\plain\f0\fs20 A\par Numbered\par List\par+\pard\ssparaaux0\s0{\pntext\pard\plain\f3\fs22 \'b7\tab}{\*\pn\pnlvlblt\ls5\ilvl0\pnhang\pnf3{\pntxtb \'b7}}\ls5\ilvl0\fi-360\li360\ql\plain\f0\fs20 A\par Bulleted\par List\par+}
@@ -0,0 +1,25 @@+Pandoc+ Meta { unMeta = fromList [] }+ [ BulletList+ [ [ Para+ [ Str "First"+ , Space+ , Str "item,"+ , Space+ , Str "paragraph"+ , Space+ , Str "one."+ ]+ , Para+ [ Str "First"+ , Space+ , Str "item,"+ , Space+ , Str "paragraph"+ , Space+ , Str "two."+ ]+ ]+ , [ Para [ Str "Second" , Space , Str "item." ] ]+ ]+ ]
@@ -0,0 +1,12 @@+{\rtf1\ansi\ansicpg1252+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}+{\colortbl;\red0\green0\blue0;}+{\*\listtable{\list\listtemplateid1{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}+{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}+\pard\li720\fi-360+\ls1\ilvl0 {\listtext\tab \u8226 \tab}First item, paragraph one.\par+\pard\li720\fi-360+\ls1\ilvl0 First item, paragraph two.\par+\pard\li720\fi-360+\ls1\ilvl0 {\listtext\tab \u8226 \tab}Second item.\par+}
@@ -1,16 +1,16 @@-{\pard \ql \f0 \sa180 \li0 \fi0 Simple table with caption:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Simple table with caption:\par} { \trowd \trgaph120 \clbrdrb\brdrs\cellx2160\clbrdrb\brdrs\cellx4320\clbrdrb\brdrs\cellx6480\clbrdrb\brdrs\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 Right\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 Right\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Left\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Left\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Center\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Center\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Default\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Default\par} \cell} } \intbl\row}@@ -19,13 +19,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell} } \intbl\row}@@ -34,13 +34,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell} } \intbl\row}@@ -49,30 +49,30 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Simple table without caption:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Simple table without caption:\par} { \trowd \trgaph120 \clbrdrb\brdrs\cellx2160\clbrdrb\brdrs\cellx4320\clbrdrb\brdrs\cellx6480\clbrdrb\brdrs\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 Right\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 Right\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Left\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Left\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Center\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Center\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Default\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Default\par} \cell} } \intbl\row}@@ -81,13 +81,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell} } \intbl\row}@@ -96,13 +96,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell} } \intbl\row}@@ -111,30 +111,30 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 \par}-{\pard \ql \f0 \sa180 \li0 \fi0 Simple table indented two spaces:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Simple table indented two spaces:\par} { \trowd \trgaph120 \clbrdrb\brdrs\cellx2160\clbrdrb\brdrs\cellx4320\clbrdrb\brdrs\cellx6480\clbrdrb\brdrs\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 Right\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 Right\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Left\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Left\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Center\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Center\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Default\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Default\par} \cell} } \intbl\row}@@ -143,13 +143,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell} } \intbl\row}@@ -158,13 +158,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell} } \intbl\row}@@ -173,30 +173,30 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiline table with caption:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Demonstration of simple table syntax.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiline table with caption:\par} { \trowd \trgaph120 \clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2484\clbrdrb\brdrs\cellx3888\clbrdrb\brdrs\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Centered Header\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Centered Header\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Left Aligned\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Left Aligned\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 Right Aligned\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 Right Aligned\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Default aligned\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Default aligned\par} \cell} } \intbl\row}@@ -205,13 +205,13 @@ \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 First\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 First\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par} \cell} } \intbl\row}@@ -220,30 +220,30 @@ \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Second\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Second\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 5.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 5.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's the caption. It may span multiple lines.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiline table without caption:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's the caption. It may span multiple lines.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiline table without caption:\par} { \trowd \trgaph120 \clbrdrb\brdrs\cellx1296\clbrdrb\brdrs\cellx2484\clbrdrb\brdrs\cellx3888\clbrdrb\brdrs\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Centered Header\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Centered Header\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Left Aligned\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Left Aligned\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 Right Aligned\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 Right Aligned\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Default aligned\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Default aligned\par} \cell} } \intbl\row}@@ -252,13 +252,13 @@ \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 First\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 First\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par} \cell} } \intbl\row}@@ -267,30 +267,30 @@ \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Second\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Second\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 5.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 5.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 \par}-{\pard \ql \f0 \sa180 \li0 \fi0 Table without column headers:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Table without column headers:\par} { \trowd \trgaph120 \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12\par} \cell} } \intbl\row}@@ -299,13 +299,13 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 123\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 123\par} \cell} } \intbl\row}@@ -314,30 +314,30 @@ \cellx2160\cellx4320\cellx6480\cellx8640 \trkeep\intbl {-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 1\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 1\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 \par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiline table without column headers:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiline table without column headers:\par} { \trowd \trgaph120 \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 First\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 First\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 12.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 12.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Example of a row that spans multiple lines.\par} \cell} } \intbl\row}@@ -346,14 +346,14 @@ \cellx1296\cellx2484\cellx3888\cellx6912 \trkeep\intbl {-{{\pard\intbl \qc \f0 \sa0 \li0 \fi0 Second\par}+{{\pard\intbl \qc \f0 \fs24 \sa0 \li0 \fi0 Second\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 row\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 row\par} \cell}-{{\pard\intbl \qr \f0 \sa0 \li0 \fi0 5.0\par}+{{\pard\intbl \qr \f0 \fs24 \sa0 \li0 \fi0 5.0\par} \cell}-{{\pard\intbl \ql \f0 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par}+{{\pard\intbl \ql \f0 \fs24 \sa0 \li0 \fi0 Here\u8217's another one. Note the blank line between rows.\par} \cell} } \intbl\row}-{\pard \ql \f0 \sa180 \li0 \fi0 \par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \par}
@@ -0,0 +1,46 @@+Simple table with caption:++Demonstration of simple table syntax.+| Right|Left | Center |Default|+| 12|12 | 12 |12 |+| 123|123 | 123 |123 |+| 1|1 | 1 |1 |++Simple table without caption:++| Right|Left | Center |Default|+| 12|12 | 12 |12 |+| 123|123 | 123 |123 |+| 1|1 | 1 |1 |++Simple table indented two spaces:++Demonstration of simple table syntax.+| Right|Left | Center |Default|+| 12|12 | 12 |12 |+| 123|123 | 123 |123 |+| 1|1 | 1 |1 |++Multiline table with caption:++Here’s the caption. It may span multiple lines.+| Centered Header |Left Aligned | Right Aligned|Default aligned |+| First |row | 12.0|Example of a row that spans multiple lines. |+| Second |row | 5.0|Here’s another one. Note the blank line between rows. |++Multiline table without caption:++| Centered Header |Left Aligned | Right Aligned|Default aligned |+| First |row | 12.0|Example of a row that spans multiple lines. |+| Second |row | 5.0|Here’s another one. Note the blank line between rows. |++Table without column headers:++| 12|12 | 12 | 12|+| 123|123 | 123 | 123|+| 1|1 | 1 | 1|++Multiline table without column headers:++| First |row | 12.0|Example of a row that spans multiple lines. |+| Second |row | 5.0|Here’s another one. Note the blank line between rows.|
@@ -53,6 +53,7 @@ import qualified Tests.Writers.TEI import qualified Tests.Writers.Markua import qualified Tests.Writers.BBCode+import qualified Tests.Writers.Txt2Tags import qualified Tests.XML import qualified Tests.MediaBag import Text.Pandoc.Shared (inDirectory)@@ -86,6 +87,7 @@ , testGroup "Ms" Tests.Writers.Ms.tests , testGroup "AnnotatedTable" Tests.Writers.AnnotatedTable.tests , testGroup "BBCode" Tests.Writers.BBCode.tests+ , testGroup "Txt2Tags" Tests.Writers.Txt2Tags.tests ] , testGroup "Readers" [ testGroup "LaTeX" Tests.Readers.LaTeX.tests
@@ -595,7 +595,7 @@ , Str "continuation" ] , OrderedList- ( 4 , LowerRoman , Period )+ ( 1 , LowerRoman , Period ) [ [ Plain [ Str "sublist" , Space@@ -603,13 +603,13 @@ , Space , Str "roman" , Space- , Str "numerals,"+ , Str "numerals" , SoftBreak , Str "starting" , Space , Str "with" , Space- , Str "4"+ , Str "i." ] ] , [ Plain [ Str "more" , Space , Str "items" ]@@ -624,13 +624,13 @@ ] , Para [ Str "Nesting:" ] , OrderedList- ( 1 , UpperAlpha , Period )+ ( 4 , UpperAlpha , Period ) [ [ Plain [ Str "Upper" , Space , Str "Alpha" ] , OrderedList ( 1 , UpperRoman , Period ) [ [ Plain [ Str "Upper" , Space , Str "Roman." ] , OrderedList- ( 6 , Decimal , TwoParens )+ ( 1 , Decimal , TwoParens ) [ [ Plain [ Str "Decimal" , Space@@ -638,10 +638,10 @@ , Space , Str "with" , Space- , Str "6"+ , Str "1" ] , OrderedList- ( 3 , LowerAlpha , OneParen )+ ( 1 , LowerAlpha , OneParen ) [ [ Plain [ Str "Lower" , Space
@@ -237,18 +237,18 @@ with a continuation - iv. sublist with roman numerals,- starting with 4- v. more items+ i. sublist with roman numerals+ starting with i.+ ii. more items (A) a subsublist (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman.- (6) Decimal start with 6- c) Lower alpha with paren+ (1) Decimal start with 1+ a) Lower alpha with paren Autonumbering:
@@ -1299,7 +1299,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\cap" , Str "\8192"- , Code ( "" , [] , [] ) "sect"+ , Code ( "" , [] , [] ) "inter" ] ] ]@@ -1595,7 +1595,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\1488" , Str "\8192"- , Code ( "" , [] , [] ) "alef"+ , Code ( "" , [] , [] ) "aleph" ] ] ]@@ -3119,7 +3119,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\partial" , Str "\8192"- , Code ( "" , [] , [] ) "diff"+ , Code ( "" , [] , [] ) "partial" ] ] ]@@ -3150,7 +3150,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\oplus" , Str "\8192"- , Code ( "" , [] , [] ) "plus.circle"+ , Code ( "" , [] , [] ) "plus.o" ] ] ]@@ -3195,7 +3195,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\ominus" , Str "\8192"- , Code ( "" , [] , [] ) "minus.circle"+ , Code ( "" , [] , [] ) "minus.o" ] ] ]@@ -3209,8 +3209,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\295" , Str "\8192"- , Code- ( "" , [] , [] ) "planck.reduce"+ , Code ( "" , [] , [] ) "planck" ] ] ]@@ -3241,7 +3240,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\odot" , Str "\8192"- , Code ( "" , [] , [] ) "dot.circle"+ , Code ( "" , [] , [] ) "dot.o" ] ] ]@@ -3288,7 +3287,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\otimes" , Str "\8192"- , Code ( "" , [] , [] ) "times.circle"+ , Code ( "" , [] , [] ) "times.o" ] ] ]@@ -3919,7 +3918,7 @@ ( "" , [ "box" ] , [] ) [ Math InlineMath "\\bigcap" , Str "\8192"- , Code ( "" , [] , [] ) "sect.big"+ , Code ( "" , [] , [] ) "inter.big" ] ] ]@@ -3970,7 +3969,8 @@ [ Math InlineMath "\\langle\\rangle" , Str "\8192" , Code- ( "" , [] , [] ) "angle.l angle.r"+ ( "" , [] , [] )+ "chevron.l chevron.r" ] ] ]
@@ -167,13 +167,13 @@ columns: 3, column-gutter: 1em, cell($union$, `union`), cell($RR$, [`RR`, `bb(R)`]), cell($forall$, `forall`),- cell($sect$, `sect`), cell($bb(Z)$, [`ZZ`, `bb(Z)`]), cell($exists$, `exists`),+ cell($inter$, `inter`), cell($bb(Z)$, [`ZZ`, `bb(Z)`]), cell($exists$, `exists`), cell($subset$, `subset`), cell($bb(Q)$, [`QQ`, `bb(Q)`]), cell($not$, `not`), cell($subset.eq$, `subset.eq`), cell($bb(N)$, [`NN`, `bb(N)`]), cell($or$, `or`), cell($supset$, `supset`), cell($bb(C)$, [`CC`, `bb(C)`]), cell($and$, `and`), cell($supset.eq$, `supset.eq`), cell($diameter$, [`diameter`]), cell($tack.r$, `tack.r`), cell($in$, `in`), cell($nothing$, `nothing`), cell($models$, `models`),- cell($in.not$, `in.not`), cell($alef$, `alef`), cell($without$, `without`),+ cell($in.not$, `in.not`), cell($aleph$, `aleph`), cell($without$, `without`), )) Negate an operator, as in $subset.not$, with `subset.not`.@@ -257,11 +257,11 @@ cell($>>$, [`>>`, `gt.double`]), cell($tilde.equiv.not$, `tilde.equiv.not`), cell($divides$, `divides`), cell($approx$, `approx`), cell($tilde$, `tilde`), cell($divides.not$, `divides.not`), cell($\u{224D}$, [`\u{224D}` @tricky]), cell($tilde.eq$, `tilde.eq`), cell($n!$, `n!`),- cell($equiv$, `equiv`), cell($tilde.not$, `tilde.not`), cell($diff$, `diff`),- cell($prec$, `prec`), cell($plus.circle$, `plus.circle`), cell($nabla$, `nabla`),- cell($prec.eq$, `prec.eq`), cell($minus.circle$, `minus.circle`), cell($planck.reduce$, `planck.reduce`),- cell($succ$, `succ`), cell($dot.circle$, `dot.circle`), cell($circle.stroked.tiny$, `circle.stroked.tiny`),- cell($succ.eq$, `succ.eq`), cell($times.circle$, `times.circle`), cell($star$, `star`),+ cell($equiv$, `equiv`), cell($tilde.not$, `tilde.not`), cell($partial$, `partial`),+ cell($prec$, `prec`), cell($plus.o$, `plus.o`), cell($nabla$, `nabla`),+ cell($prec.eq$, `prec.eq`), cell($minus.o$, `minus.o`), cell($planck$, `planck`),+ cell($succ$, `succ`), cell($dot.o$, `dot.o`), cell($circle.stroked.tiny$, `circle.stroked.tiny`),+ cell($succ.eq$, `succ.eq`), cell($times.o$, `times.o`), cell($star$, `star`), cell($prop$, `prop`), cell($\u{2298}$, [`\u{2298}` @tricky]), cell($sqrt("")$, `sqrt("")`), cell($\u{2250}$, [`\u{2250}` @tricky]), cell($harpoon.tr$, `harpoon.tr`), cell($checkmark$, `checkmark`), ))@@ -294,14 +294,14 @@ #align(center, table( columns: 3, cell($integral$, `integral`), cell($integral.triple$, `integral.triple`), cell($union.big$, `union.big`),- cell($integral.double$, `integral.double`), cell($integral.cont$, `integral.cont`), cell($sect.big$, `sect.big`),+ cell($integral.double$, `integral.double`), cell($integral.cont$, `integral.cont`), cell($inter.big$, `inter.big`), )) = Fences #align(center, table( columns: 3, column-gutter: 1.5em,- cell($()$, `()`), cell($angle.l angle.r$, `angle.l angle.r`), cell($abs("")$, `abs("")`),+ cell($()$, `()`), cell($chevron.l chevron.r$, `chevron.l chevron.r`), cell($abs("")$, `abs("")`), cell($[]$, `[]`), cell($floor("")$, `floor("")`), cell($norm("")$, `norm("")`), cell(${}$, `{}`), cell($ceil("")$, `ceil("")`), ))@@ -322,7 +322,7 @@ #align(center, table( columns: 2, column-gutter: 1em,- $ lr(angle.l i, 2^(2^i) angle.r) $,+ $ lr(chevron.l i, 2^(2^i) chevron.r) $, ``` lr(angle.l i, 2^(2^i) angle.r) ```,
@@ -233,8 +233,8 @@ . and now 3 + with a continuation-[lowerroman, start=4]-.. sublist with roman numerals, starting with 4+[lowerroman]+.. sublist with roman numerals starting with i. .. more items [upperalpha] ... a subsublist@@ -242,13 +242,13 @@ Nesting: -[upperalpha]+[upperalpha, start=4] . Upper Alpha [upperroman] .. Upper Roman.-[arabic, start=6]-... Decimal start with 6-[loweralpha, start=3]+[arabic]+... Decimal start with 1+[loweralpha] .... Lower alpha with paren Autonumbering:
@@ -232,8 +232,8 @@ . and now 3 + with a continuation-[lowerroman, start=4]-.. sublist with roman numerals, starting with 4+[lowerroman]+.. sublist with roman numerals starting with i. .. more items [upperalpha] ... a subsublist@@ -241,13 +241,13 @@ Nesting: -[upperalpha]+[upperalpha, start=4] . Upper Alpha [upperroman] .. Upper Roman.-[arabic, start=6]-... Decimal start with 6-[loweralpha, start=3]+[arabic]+... Decimal start with 1+[loweralpha] .... Lower alpha with paren Autonumbering:
@@ -260,7 +260,7 @@ with a continuation [list=i]-[*]sublist with roman numerals, starting with 4+[*]sublist with roman numerals starting with i. [*]more items [list=A]@@ -279,7 +279,7 @@ [*]Upper Roman. [list=1]-[*]Decimal start with 6+[*]Decimal start with 1 [list=a] [*]Lower alpha with paren
@@ -431,9 +431,9 @@ with a continuation - \startenumerate[r,packed][start=4,stopper=.]+ \startenumerate[r,packed][stopper=.] \item- sublist with roman numerals, starting with 4+ sublist with roman numerals starting with i. \item more items \startenumerate[A,packed][left=(,stopper=)]@@ -447,16 +447,16 @@ Nesting: -\startenumerate[A,packed][stopper=.]+\startenumerate[A,packed][start=4,stopper=.] \item Upper Alpha \startenumerate[R,packed][stopper=.] \item Upper Roman.- \startenumerate[n,packed][start=6,left=(,stopper=)]+ \startenumerate[n,packed][left=(,stopper=)] \item- Decimal start with 6- \startenumerate[a,packed][start=3,stopper=)]+ Decimal start with 1+ \startenumerate[a,packed][stopper=)] \item Lower alpha with paren \stopenumerate
@@ -256,21 +256,21 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items+ i. sublist with roman numerals starting with i.+ ii. more items - (A) a subsublist- (B) a subsublist+ (A) a subsublist+ (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman. - (6) Decimal start with 6+ (1) Decimal start with 1 - c) Lower alpha with paren+ a) Lower alpha with paren Autonumbering:
@@ -525,10 +525,10 @@ <para> with a continuation </para>- <orderedlist numeration="lowerroman" spacing="compact" startingnumber="4">+ <orderedlist numeration="lowerroman" spacing="compact"> <listitem> <para>- sublist with roman numerals, starting with 4+ sublist with roman numerals starting with i. </para> </listitem> <listitem>@@ -554,7 +554,7 @@ <para> Nesting: </para>- <orderedlist numeration="upperalpha" spacing="compact">+ <orderedlist numeration="upperalpha" spacing="compact" startingnumber="4"> <listitem> <para> Upper Alpha@@ -564,12 +564,12 @@ <para> Upper Roman. </para>- <orderedlist numeration="arabic" spacing="compact" startingnumber="6">+ <orderedlist numeration="arabic" spacing="compact"> <listitem> <para>- Decimal start with 6+ Decimal start with 1 </para>- <orderedlist numeration="loweralpha" spacing="compact" startingnumber="3">+ <orderedlist numeration="loweralpha" spacing="compact"> <listitem> <para> Lower alpha with paren
@@ -527,10 +527,10 @@ <para> with a continuation </para>- <orderedlist numeration="lowerroman" spacing="compact" startingnumber="4">+ <orderedlist numeration="lowerroman" spacing="compact"> <listitem> <para>- sublist with roman numerals, starting with 4+ sublist with roman numerals starting with i. </para> </listitem> <listitem>@@ -556,7 +556,7 @@ <para> Nesting: </para>- <orderedlist numeration="upperalpha" spacing="compact">+ <orderedlist numeration="upperalpha" spacing="compact" startingnumber="4"> <listitem> <para> Upper Alpha@@ -566,12 +566,12 @@ <para> Upper Roman. </para>- <orderedlist numeration="arabic" spacing="compact" startingnumber="6">+ <orderedlist numeration="arabic" spacing="compact"> <listitem> <para>- Decimal start with 6+ Decimal start with 1 </para>- <orderedlist numeration="loweralpha" spacing="compact" startingnumber="3">+ <orderedlist numeration="loweralpha" spacing="compact"> <listitem> <para> Lower alpha with paren
@@ -211,7 +211,7 @@ - <WRAP> and now 3 with a continuation- - sublist with roman numerals, starting with 4+ - sublist with roman numerals starting with i. - more items - a subsublist - a subsublist@@ -219,16 +219,10 @@ Nesting: - - <WRAP>-Upper Alpha- - <WRAP>-Upper Roman.- - <WRAP>-Decimal start with 6+ - Upper Alpha+ - Upper Roman.+ - Decimal start with 1 - Lower alpha with paren-</WRAP>-</WRAP>-</WRAP> Autonumbering:
@@ -307,16 +307,16 @@ <empty-line /> <p> with a continuation</p> <empty-line />-<p>(3) iv. sublist with roman numerals,-starting with 4</p>-<p>(3) v. more items</p>-<p>(3) v. (A) a subsublist</p>-<p>(3) v. (B) a subsublist</p>+<p>(3) i. sublist with roman numerals+starting with i.</p>+<p>(3) ii. more items</p>+<p>(3) ii. (A) a subsublist</p>+<p>(3) ii. (B) a subsublist</p> <p>Nesting:</p>-<p>A. Upper Alpha</p>-<p>A. I. Upper Roman.</p>-<p>A. I. (6) Decimal start with 6</p>-<p>A. I. (6) c) Lower alpha with paren</p>+<p>D. Upper Alpha</p>+<p>D. I. Upper Roman.</p>+<p>D. I. (1) Decimal start with 1</p>+<p>D. I. (1) a) Lower alpha with paren</p> <p>Autonumbering:</p> <p>1. Autonumber.</p> <p>2. More.</p>
@@ -240,17 +240,17 @@ with a continuation - 4. sublist with roman numerals, starting with 4- 5. more items+ 1. sublist with roman numerals starting with i.+ 2. more items (1) a subsublist (2) a subsublist Nesting: -1. Upper Alpha+4. Upper Alpha 1. Upper Roman.- (6) Decimal start with 6- 3) Lower alpha with paren+ (1) Decimal start with 1+ 1) Lower alpha with paren Autonumbering:
@@ -44,7 +44,6 @@ body { background-color: transparent; color: black;- font-size: 12pt; } p, h2, h3 { orphans: 3;@@ -367,8 +366,8 @@ <li><p>begins with 2</p></li> <li><p>and now 3</p> <p>with a continuation</p>-<ol start="4" style="list-style-type: lower-roman">-<li>sublist with roman numerals, starting with 4</li>+<ol style="list-style-type: lower-roman">+<li>sublist with roman numerals starting with i.</li> <li>more items <ol style="list-style-type: upper-alpha"> <li>a subsublist</li>@@ -377,13 +376,13 @@ </ol></li> </ol> <p>Nesting:</p>-<ol style="list-style-type: upper-alpha">+<ol start="4" style="list-style-type: upper-alpha"> <li>Upper Alpha <ol style="list-style-type: upper-roman"> <li>Upper Roman.-<ol start="6" style="list-style-type: decimal">-<li>Decimal start with 6-<ol start="3" style="list-style-type: lower-alpha">+<ol style="list-style-type: decimal">+<li>Decimal start with 1+<ol style="list-style-type: lower-alpha"> <li>Lower alpha with paren</li> </ol></li> </ol></li>
@@ -44,7 +44,6 @@ body { background-color: transparent; color: black;- font-size: 12pt; } p, h2, h3 { orphans: 3;@@ -367,8 +366,8 @@ <li><p>begins with 2</p></li> <li><p>and now 3</p> <p>with a continuation</p>-<ol start="4" type="i">-<li>sublist with roman numerals, starting with 4</li>+<ol type="i">+<li>sublist with roman numerals starting with i.</li> <li>more items <ol type="A"> <li>a subsublist</li>@@ -377,13 +376,13 @@ </ol></li> </ol> <p>Nesting:</p>-<ol type="A">+<ol start="4" type="A"> <li>Upper Alpha <ol type="I"> <li>Upper Roman.-<ol start="6" type="1">-<li>Decimal start with 6-<ol start="3" type="a">+<ol type="1">+<li>Decimal start with 1+<ol type="a"> <li>Lower alpha with paren</li> </ol></li> </ol></li>
@@ -334,13 +334,13 @@ </TabList> </Properties> </ParagraphStyle>- <ParagraphStyle Self="ParagraphStyle/NumList > NumList > NumList > NumList > first > beginsWith-3 > lowerAlpha" Name="NumList > NumList > NumList > NumList > first > beginsWith-3 > lowerAlpha" NumberingExpression="^#.^t" NumberingLevel="4" BulletsAndNumberingListType="NumberedList" LeftIndent="30">+ <ParagraphStyle Self="ParagraphStyle/NumList > NumList > NumList > NumList > first > lowerAlpha" Name="NumList > NumList > NumList > NumList > first > lowerAlpha" NumberingExpression="^#.^t" NumberingLevel="4" BulletsAndNumberingListType="NumberedList" LeftIndent="30"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> <NumberingFormat type="string">a, b, c, d...</NumberingFormat> </Properties> </ParagraphStyle>- <ParagraphStyle Self="ParagraphStyle/NumList > NumList > NumList > first > beginsWith-6" Name="NumList > NumList > NumList > first > beginsWith-6" NumberingExpression="^#.^t" NumberingLevel="3" BulletsAndNumberingListType="NumberedList" LeftIndent="20">+ <ParagraphStyle Self="ParagraphStyle/NumList > NumList > NumList > first" Name="NumList > NumList > NumList > first" NumberingExpression="^#.^t" NumberingLevel="3" BulletsAndNumberingListType="NumberedList" LeftIndent="20"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> </Properties>@@ -357,18 +357,12 @@ <NumberingFormat type="string">A, B, C, D...</NumberingFormat> </Properties> </ParagraphStyle>- <ParagraphStyle Self="ParagraphStyle/NumList > NumList > beginsWith-4 > lowerRoman" Name="NumList > NumList > beginsWith-4 > lowerRoman" NumberingExpression="^#.^t" NumberingLevel="2" BulletsAndNumberingListType="NumberedList" LeftIndent="10">- <Properties>- <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn>- <NumberingFormat type="string">i, ii, iii, iv...</NumberingFormat>- </Properties>- </ParagraphStyle> <ParagraphStyle Self="ParagraphStyle/NumList > NumList > first" Name="NumList > NumList > first" NumberingExpression="^#.^t" NumberingLevel="2" BulletsAndNumberingListType="NumberedList" LeftIndent="10"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> </Properties> </ParagraphStyle>- <ParagraphStyle Self="ParagraphStyle/NumList > NumList > first > beginsWith-4 > lowerRoman" Name="NumList > NumList > first > beginsWith-4 > lowerRoman" NumberingExpression="^#.^t" NumberingLevel="2" BulletsAndNumberingListType="NumberedList" LeftIndent="10">+ <ParagraphStyle Self="ParagraphStyle/NumList > NumList > first > lowerRoman" Name="NumList > NumList > first > lowerRoman" NumberingExpression="^#.^t" NumberingLevel="2" BulletsAndNumberingListType="NumberedList" LeftIndent="10"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> <NumberingFormat type="string">i, ii, iii, iv...</NumberingFormat>@@ -380,6 +374,12 @@ <NumberingFormat type="string">I, II, III, IV...</NumberingFormat> </Properties> </ParagraphStyle>+ <ParagraphStyle Self="ParagraphStyle/NumList > NumList > lowerRoman" Name="NumList > NumList > lowerRoman" NumberingExpression="^#.^t" NumberingLevel="2" BulletsAndNumberingListType="NumberedList" LeftIndent="10">+ <Properties>+ <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn>+ <NumberingFormat type="string">i, ii, iii, iv...</NumberingFormat>+ </Properties>+ </ParagraphStyle> <ParagraphStyle Self="ParagraphStyle/NumList > Paragraph" Name="NumList > Paragraph" NumberingExpression="^#.^t" NumberingLevel="1" BulletsAndNumberingListType="NumberedList" LeftIndent="0"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn>@@ -405,7 +405,7 @@ <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> </Properties> </ParagraphStyle>- <ParagraphStyle Self="ParagraphStyle/NumList > first > upperAlpha" Name="NumList > first > upperAlpha" NumberingExpression="^#.^t" NumberingLevel="1" BulletsAndNumberingListType="NumberedList" LeftIndent="0">+ <ParagraphStyle Self="ParagraphStyle/NumList > first > beginsWith-4 > upperAlpha" Name="NumList > first > beginsWith-4 > upperAlpha" NumberingExpression="^#.^t" NumberingLevel="1" BulletsAndNumberingListType="NumberedList" LeftIndent="0"> <Properties> <BasedOn type="object">$ID/NormalParagraphStyle</BasedOn> <NumberingFormat type="string">A, B, C, D...</NumberingFormat>@@ -1144,13 +1144,13 @@ </CharacterStyleRange> </ParagraphStyleRange> <Br />-<ParagraphStyleRange NumberingStartAt="4" AppliedParagraphStyle="ParagraphStyle/NumList > NumList > first > beginsWith-4 > lowerRoman" NumberingContinue="false">+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > NumList > first > lowerRoman" NumberingContinue="false"> <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">- <Content>sublist with roman numerals, starting with 4</Content>+ <Content>sublist with roman numerals starting with i.</Content> </CharacterStyleRange> </ParagraphStyleRange> <Br />-<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > NumList > beginsWith-4 > lowerRoman">+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > NumList > lowerRoman"> <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle"> <Content>more items</Content> </CharacterStyleRange>@@ -1174,7 +1174,7 @@ </CharacterStyleRange> </ParagraphStyleRange> <Br />-<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > first > upperAlpha" NumberingContinue="false">+<ParagraphStyleRange NumberingStartAt="4" AppliedParagraphStyle="ParagraphStyle/NumList > first > beginsWith-4 > upperAlpha" NumberingContinue="false"> <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle"> <Content>Upper Alpha</Content> </CharacterStyleRange>@@ -1186,13 +1186,13 @@ </CharacterStyleRange> </ParagraphStyleRange> <Br />-<ParagraphStyleRange NumberingStartAt="6" AppliedParagraphStyle="ParagraphStyle/NumList > NumList > NumList > first > beginsWith-6" NumberingContinue="false">+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > NumList > NumList > first" NumberingContinue="false"> <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle">- <Content>Decimal start with 6</Content>+ <Content>Decimal start with 1</Content> </CharacterStyleRange> </ParagraphStyleRange> <Br />-<ParagraphStyleRange NumberingStartAt="3" AppliedParagraphStyle="ParagraphStyle/NumList > NumList > NumList > NumList > first > beginsWith-3 > lowerAlpha" NumberingContinue="false">+<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/NumList > NumList > NumList > NumList > first > lowerAlpha" NumberingContinue="false"> <CharacterStyleRange AppliedCharacterStyle="$ID/NormalCharacterStyle"> <Content>Lower alpha with paren</Content> </CharacterStyleRange>
@@ -361,11 +361,9 @@ <p>with a continuation</p> <list list-type="roman-lower"> <list-item>- <label>iv.</label>- <p>sublist with roman numerals, starting with 4</p>+ <p>sublist with roman numerals starting with i.</p> </list-item> <list-item>- <label>v.</label> <p>more items</p> <list list-type="alpha-upper"> <list-item>@@ -384,17 +382,18 @@ <p>Nesting:</p> <list list-type="alpha-upper"> <list-item>+ <label>D.</label> <p>Upper Alpha</p> <list list-type="roman-upper"> <list-item> <p>Upper Roman.</p> <list list-type="order"> <list-item>- <label>(6)</label>- <p>Decimal start with 6</p>+ <label>(1)</label>+ <p>Decimal start with 1</p> <list list-type="alpha-lower"> <list-item>- <label>c)</label>+ <label>a)</label> <p>Lower alpha with paren</p> </list-item> </list>
@@ -358,11 +358,9 @@ <p>with a continuation</p> <list list-type="order"> <list-item>- <label>iv.</label>- <p>sublist with roman numerals, starting with 4</p>+ <p>sublist with roman numerals starting with i.</p> </list-item> <list-item>- <label>v.</label> <p>more items</p> <list list-type="order"> <list-item>@@ -381,17 +379,18 @@ <p>Nesting:</p> <list list-type="order"> <list-item>+ <label>D.</label> <p>Upper Alpha</p> <list list-type="order"> <list-item> <p>Upper Roman.</p> <list list-type="order"> <list-item>- <label>(6)</label>- <p>Decimal start with 6</p>+ <label>(1)</label>+ <p>Decimal start with 1</p> <list list-type="order"> <list-item>- <label>c)</label>+ <label>a)</label> <p>Lower alpha with paren</p> </list-item> </list>
@@ -361,11 +361,9 @@ <p>with a continuation</p> <list list-type="roman-lower"> <list-item>- <label>iv.</label>- <p>sublist with roman numerals, starting with 4</p>+ <p>sublist with roman numerals starting with i.</p> </list-item> <list-item>- <label>v.</label> <p>more items</p> <list list-type="alpha-upper"> <list-item>@@ -384,17 +382,18 @@ <p>Nesting:</p> <list list-type="alpha-upper"> <list-item>+ <label>D.</label> <p>Upper Alpha</p> <list list-type="roman-upper"> <list-item> <p>Upper Roman.</p> <list list-type="order"> <list-item>- <label>(6)</label>- <p>Decimal start with 6</p>+ <label>(1)</label>+ <p>Decimal start with 1</p> <list list-type="alpha-lower"> <list-item>- <label>c)</label>+ <label>a)</label> <p>Lower alpha with paren</p> </list-item> </list>
@@ -172,7 +172,7 @@ # begins with 2 # and now 3 with a continuation-## sublist with roman numerals, starting with 4+## sublist with roman numerals starting with i. ## more items ### a subsublist ### a subsublist@@ -181,7 +181,7 @@ # Upper Alpha ## Upper Roman.-### Decimal start with 6+### Decimal start with 1 #### Lower alpha with paren Autonumbering:
@@ -432,10 +432,9 @@ \begin{enumerate} \def\labelenumii{\roman{enumii}.}- \setcounter{enumii}{3} \tightlist \item- sublist with roman numerals, starting with 4+ sublist with roman numerals starting with i. \item more items @@ -454,6 +453,7 @@ \begin{enumerate} \def\labelenumi{\Alph{enumi}.}+\setcounter{enumi}{3} \tightlist \item Upper Alpha@@ -466,14 +466,12 @@ \begin{enumerate} \def\labelenumiii{(\arabic{enumiii})}- \setcounter{enumiii}{5} \tightlist \item- Decimal start with 6+ Decimal start with 1 \begin{enumerate} \def\labelenumiv{\alph{enumiv})}- \setcounter{enumiv}{2} \tightlist \item Lower alpha with paren
@@ -254,9 +254,9 @@ .RS 4 .PP with a continuation-.IP "iv." 4-sublist with roman numerals, starting with 4-.IP " v." 4+.IP " i." 4+sublist with roman numerals starting with i.+.IP "ii." 4 more items .RS 4 .IP "(A)" 4@@ -267,16 +267,16 @@ .RE .PP Nesting:-.IP "A." 3+.IP "D." 3 Upper Alpha .RS 4 .IP "I." 3 Upper Roman. .RS 4-.IP "(6)" 4-Decimal start with 6+.IP "(1)" 4+Decimal start with 1 .RS 4-.IP "c)" 3+.IP "a)" 3 Lower alpha with paren .RE .RE
@@ -230,17 +230,17 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items+ i. sublist with roman numerals starting with i.+ ii. more items (A) a subsublist (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman.- (6) Decimal start with 6- c) Lower alpha with paren+ (1) Decimal start with 1+ a) Lower alpha with paren Autonumbering:
@@ -192,7 +192,7 @@ 1. Item 1, graf one. - Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.+ Item 1. graf two. The quick brown fox jumped over the lazy dog’s back. 2. Item 2. @@ -209,9 +209,9 @@ 1. First 2. Second:- * Fee- * Fie- * Foe+ * Fee+ * Fie+ * Foe 3. Third Same thing but with paragraphs:@@ -220,9 +220,9 @@ 2. Second: - * Fee- * Fie- * Foe+ * Fee+ * Fie+ * Foe 3. Third @@ -244,25 +244,25 @@ 3) and now 3 - with a continuation+ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items- A) a subsublist- B) a subsublist+ i. sublist with roman numerals starting with i.+ ii. 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+D. Upper Alpha+ I. Upper Roman.+ 1) Decimal start with 1+ a) Lower alpha with paren Autonumbering: 1. Autonumber. 2. More.- 1. Nested.+ 1. Nested. Should not be a list item:
@@ -216,8 +216,8 @@ <li><p>begins with 2</p></li> <li><p>and now 3</p> <p>with a continuation</p>-<ol start="4" style="list-style-type: lower-roman;">-<li>sublist with roman numerals, starting with 4</li>+<ol style="list-style-type: lower-roman;">+<li>sublist with roman numerals starting with i.</li> <li>more items <ol style="list-style-type: upper-alpha;"> <li>a subsublist</li>@@ -225,13 +225,13 @@ Nesting: -<ol style="list-style-type: upper-alpha;">+<ol start="4" style="list-style-type: upper-alpha;"> <li>Upper Alpha <ol style="list-style-type: upper-roman;"> <li>Upper Roman.-<ol start="6" style="list-style-type: decimal;">-<li>Decimal start with 6-<ol start="3" style="list-style-type: lower-alpha;">+<ol style="list-style-type: decimal;">+<li>Decimal start with 1+<ol style="list-style-type: lower-alpha;"> <li>Lower alpha with paren</li></ol></li></ol></li></ol></li></ol> Autonumbering:
@@ -394,9 +394,9 @@ .RS 5 .LP with a continuation-.IP " iv." 5-sublist with roman numerals, starting with 4-.IP " v." 5+.IP " i." 5+sublist with roman numerals starting with i.+.IP " ii." 5 more items .RS 5 .IP " (A)" 5@@ -407,16 +407,16 @@ .RE .LP Nesting:-.IP " A." 4+.IP " D." 4 Upper Alpha .RS 4 .IP " I." 4 Upper Roman. .RS 4-.IP " (6)" 5-Decimal start with 6+.IP " (1)" 5+Decimal start with 1 .RS 5-.IP " c)" 4+.IP " a)" 4 Lower alpha with paren .RE .RE
@@ -223,17 +223,17 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items- A. a subsublist- B. a subsublist+ i. sublist with roman numerals starting with i.+ ii. more items+ A. a subsublist+ B. a subsublist Nesting: - A. Upper Alpha+ D. Upper Alpha I. Upper Roman.- 6. Decimal start with 6- c. Lower alpha with paren+ 1. Decimal start with 1+ a. Lower alpha with paren Autonumbering:
@@ -572,7 +572,7 @@ , Para [ Str "with" , Space , Str "a" , Space , Str "continuation" ] , OrderedList- ( 4 , LowerRoman , Period )+ ( 1 , LowerRoman , Period ) [ [ Plain [ Str "sublist" , Space@@ -580,13 +580,13 @@ , Space , Str "roman" , Space- , Str "numerals,"+ , Str "numerals" , SoftBreak , Str "starting" , Space , Str "with" , Space- , Str "4"+ , Str "i." ] ] , [ Plain [ Str "more" , Space , Str "items" ]@@ -601,13 +601,13 @@ ] , Para [ Str "Nesting:" ] , OrderedList- ( 1 , UpperAlpha , Period )+ ( 4 , UpperAlpha , Period ) [ [ Plain [ Str "Upper" , Space , Str "Alpha" ] , OrderedList ( 1 , UpperRoman , Period ) [ [ Plain [ Str "Upper" , Space , Str "Roman." ] , OrderedList- ( 6 , Decimal , TwoParens )+ ( 1 , Decimal , TwoParens ) [ [ Plain [ Str "Decimal" , Space@@ -615,10 +615,10 @@ , Space , Str "with" , Space- , Str "6"+ , Str "1" ] , OrderedList- ( 3 , LowerAlpha , OneParen )+ ( 1 , LowerAlpha , OneParen ) [ [ Plain [ Str "Lower" , Space
@@ -523,10 +523,10 @@ <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 text:style-name="Pandoc_5f_Numbering_5f_2"> <text:list-item> <text:p text:style-name="List_20_Number_20_Tight">sublist with roman- numerals, starting with 4</text:p>+ numerals starting with i.</text:p> </text:list-item> <text:list-item> <text:p text:style-name="List_20_Number_20_Tight">more items</text:p>@@ -545,17 +545,17 @@ </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 text:style-name="Pandoc_5f_Numbering_5f_4" text:start-value="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 text:style-name="Pandoc_5f_Numbering_5f_1"> <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">+ 1</text:p>+ <text:list text:style-name="Pandoc_5f_Numbering_5f_6"> <text:list-item> <text:p text:style-name="List_20_Number_20_Tight">Lower alpha with paren</text:p>@@ -923,10 +923,10 @@ <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="FigureWithCaption"><draw:frame draw:name="img1" text:anchor-type="as-char"><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>+<draw:frame draw:name="img2" text:anchor-type="as-char"><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>
@@ -39,7 +39,7 @@ </outline> <outline text="Tabs and spaces" _note="- this is a list item indented with tabs - this is a list item indented with spaces - this is an example list item indented with tabs - this is an example list item indented with spaces"> </outline>- <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 text="Fancy list markers" _note="(2) begins with 2 (3) and now 3 with a continuation i. sublist with roman numerals starting with i. ii. more items (A) a subsublist (B) a subsublist Nesting: D. Upper Alpha I. Upper Roman. (1) Decimal start with 1 a) 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">
@@ -277,17 +277,17 @@ with a continuation - 4. [@4] sublist with roman numerals, starting with 4- 5. more items+ 1. sublist with roman numerals starting with i.+ 2. more items 1) a subsublist 2) a subsublist Nesting: -1. Upper Alpha+4. [@4] Upper Alpha 1. Upper Roman.- 6) [@6] Decimal start with 6- 3) [@3] Lower alpha with paren+ 1) Decimal start with 1+ 1) Lower alpha with paren Autonumbering:
@@ -226,17 +226,17 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items+ i. sublist with roman numerals starting with i.+ ii. more items (A) a subsublist (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman.- (6) Decimal start with 6- c) Lower alpha with paren+ (1) Decimal start with 1+ a) Lower alpha with paren Autonumbering:
@@ -266,21 +266,21 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items+ i. sublist with roman numerals starting with i.+ ii. more items (A) a subsublist (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman. - (6) Decimal start with 6+ (1) Decimal start with 1 - c) Lower alpha with paren+ a) Lower alpha with paren Autonumbering:
@@ -1,5 +1,42 @@ {\rtf1\ansi\deff0{\fonttbl{\f0 \fswiss Helvetica;}{\f1 \fmodern Courier;}} {\colortbl;\red255\green0\blue0;\red0\green0\blue255;}+{\*\listtable{\list\listtemplateid1{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid1}+{\list\listtemplateid2{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid2}+{\list\listtemplateid3{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid3}+{\list\listtemplateid4{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid4}+{\list\listtemplateid5{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid5}+{\list\listtemplateid6{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid6}+{\list\listtemplateid7{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid7}+{\list\listtemplateid8{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid8}+{\list\listtemplateid9{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid9}+{\list\listtemplateid10{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid10}+{\list\listtemplateid11{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid11}+{\list\listtemplateid12{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid12}+{\list\listtemplateid13{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid13}+{\list\listtemplateid14{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid14}+{\list\listtemplateid15{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li1080\lin1080 }{\listname ;}\listid15}+{\list\listtemplateid16{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid16}+{\list\listtemplateid17{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid17}+{\list\listtemplateid18{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid18}+{\list\listtemplateid19{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid19}+{\list\listtemplateid20{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid20}+{\list\listtemplateid21{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid21}+{\list\listtemplateid22{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid22}+{\list\listtemplateid23{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid23}+{\list\listtemplateid24{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li1080\lin1080 }{\listname ;}\listid24}+{\list\listtemplateid25{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat4\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid25}+{\list\listtemplateid26{\listlevel\levelnfc1\levelnfcn1\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc1\levelnfcn1\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid26}+{\list\listtemplateid27{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li1080\lin1080 }{\listname ;}\listid27}+{\list\listtemplateid28{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li1080\lin1080 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li1440\lin1440 }{\listname ;}\listid28}+{\list\listtemplateid29{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid29}+{\list\listtemplateid30{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid30}+{\list\listtemplateid31{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid31}+{\list\listtemplateid32{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid32}+{\list\listtemplateid33{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid33}+{\list\listtemplateid34{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid34}+{\list\listtemplateid35{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelindent0{\leveltext\'01\u8226 ?;}{\levelnumbers;}\fi-360\li360\lin360 }{\listname ;}\listid35}+}+{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}{\listoverride\listid13\listoverridecount0\ls13}{\listoverride\listid14\listoverridecount0\ls14}{\listoverride\listid15\listoverridecount0\ls15}{\listoverride\listid16\listoverridecount0\ls16}{\listoverride\listid17\listoverridecount0\ls17}{\listoverride\listid18\listoverridecount0\ls18}{\listoverride\listid19\listoverridecount0\ls19}{\listoverride\listid20\listoverridecount0\ls20}{\listoverride\listid21\listoverridecount0\ls21}{\listoverride\listid22\listoverridecount0\ls22}{\listoverride\listid23\listoverridecount0\ls23}{\listoverride\listid24\listoverridecount0\ls24}{\listoverride\listid25\listoverridecount0\ls25}{\listoverride\listid26\listoverridecount0\ls26}{\listoverride\listid27\listoverridecount0\ls27}{\listoverride\listid28\listoverridecount0\ls28}{\listoverride\listid29\listoverridecount0\ls29}{\listoverride\listid30\listoverridecount0\ls30}{\listoverride\listid31\listoverridecount0\ls31}{\listoverride\listid32\listoverridecount0\ls32}{\listoverride\listid33\listoverridecount0\ls33}{\listoverride\listid34\listoverridecount0\ls34}{\listoverride\listid35\listoverridecount0\ls35}} \widowctrl\hyphauto {\pard \qc \f0 \sa180 \li0 \fi0 \b \fs36 Pandoc Test Suite\par}@@ -7,438 +44,438 @@ {\pard \qc \f0 \sa180 \li0 \fi0 Anonymous\par} {\pard \qc \f0 \sa180 \li0 \fi0 July 17, 2006\par} {\pard \ql \f0 \sa180 \li0 \fi0 \par}-{\pard \ql \f0 \sa180 \li0 \fi0 This is a set of tests for pandoc. Most of them are adapted from John Gruber\u8217's markdown test suite.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Headers\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2 with an {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This is a set of tests for pandoc. Most of them are adapted from John Gruber\u8217's markdown test suite.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Headers\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2 with an {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul embedded link }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel2 \b \fs28 Level 3 with {\i emphasis}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel3 \b \fs24 Level 4\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel4 \b \fs20 Level 5\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Level 1\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2 with {\i emphasis}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel2 \b \fs28 Level 3\par}-{\pard \ql \f0 \sa180 \li0 \fi0 with no blank line\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2\par}-{\pard \ql \f0 \sa180 \li0 \fi0 with no blank line\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Paragraphs\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a regular paragraph.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 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.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's one with a bullet. * criminey.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 There should be a hard line break\line here.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Block Quotes\par}-{\pard \ql \f0 \sa180 \li0 \fi0 E-mail style:\par}-{\pard \ql \f0 \sa180 \li720 \fi0 This is a block quote. It is pretty short.\par}-{\pard \ql \f0 \sa180 \li720 \fi0 Code in a block quote:\par}-{\pard \ql \f0 \sa180 \li720 \fi0 \f1 sub status \{\line+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel2 \b \fs30 Level 3 with {\i emphasis}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel3 \b \fs28 Level 4\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel4 \b \fs26 Level 5\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Level 1\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2 with {\i emphasis}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel2 \b \fs30 Level 3\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 with no blank line\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Level 2\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 with no blank line\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Paragraphs\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's a regular paragraph.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 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.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's one with a bullet. * criminey.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 There should be a hard line break\line here.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Block Quotes\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 E-mail style:\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 This is a block quote. It is pretty short.\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 Code in a block quote:\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 \f1 \fs24 sub status \{\line print "working";\line \}\par}-{\pard \ql \f0 \sa180 \li720 \fi0 A list:\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 1.\tx360\tab item one\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 2.\tx360\tab item two\sa180\par}-{\pard \ql \f0 \sa180 \li720 \fi0 Nested block quotes:\par}-{\pard \ql \f0 \sa180 \li1440 \fi0 nested\par}-{\pard \ql \f0 \sa180 \li1440 \fi0 nested\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This should not be a block quote: 2 > 1.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 And a following paragraph.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Code Blocks\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Code:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 ---- (should be four hyphens)\line+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 A list:\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls1\ilvl0\tx360 {\listtext\tab 1.\tab} item one\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls1\ilvl0\tx360 {\listtext\tab 2.\tab} item two\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 Nested block quotes:\par}+{\pard \ql \f0 \fs24 \sa180 \li1440 \fi0 nested\par}+{\pard \ql \f0 \fs24 \sa180 \li1440 \fi0 nested\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This should not be a block quote: 2 > 1.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 And a following paragraph.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Code Blocks\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Code:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 ---- (should be four hyphens)\line \line sub status \{\line print "working";\line \}\line \line this code block is indented by one tab\par}-{\pard \ql \f0 \sa180 \li0 \fi0 And:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 this code block is indented by two tabs\line+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 And:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 this code block is indented by two tabs\line \line These should not be escaped: \\$ \\\\ \\> \\[ \\\{\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Lists\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Unordered\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Asterisks tight:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 1\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 2\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab asterisk 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Asterisks loose:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 1\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 2\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab asterisk 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Pluses tight:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 1\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 2\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Plus 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Pluses loose:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 1\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 2\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Plus 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Minuses tight:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 1\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 2\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Minus 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Minuses loose:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 1\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 2\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab Minus 3\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Ordered\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Tight:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab First\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Second\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Third\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 and:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab One\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Two\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Three\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Loose using tabs:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab First\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Second\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Third\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 and using spaces:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab One\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Two\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Three\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiple paragraphs:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab Item 1, graf one.\par}-{\pard \ql \f0 \sa180 \li360 \fi0 Item 1. graf two. The quick brown fox jumped over the lazy dog\u8217's back.\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Item 2.\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Item 3.\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Nested\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Tab\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Tab\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 \bullet \tx360\tab Tab\sa180\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's another:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab First\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Second:\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fee\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fie\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Foe\sa180\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Third\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Same thing but with paragraphs:\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 1.\tx360\tab First\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 2.\tx360\tab Second:\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fee\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Fie\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Foe\sa180\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 3.\tx360\tab Third\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Tabs and spaces\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab this is a list item indented with tabs\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab this is a list item indented with spaces\par}-{\pard \ql \f0 \sa180 \li720 \fi-360 \endash \tx360\tab this is an example list item indented with tabs\par}-{\pard \ql \f0 \sa180 \li720 \fi-360 \endash \tx360\tab this is an example list item indented with spaces\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Fancy list markers\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 (2)\tx360\tab begins with 2\par}-{\pard \ql \f0 \sa180 \li360 \fi-360 (3)\tx360\tab and now 3\par}-{\pard \ql \f0 \sa180 \li360 \fi0 with a continuation\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 iv.\tx360\tab sublist with roman numerals, starting with 4\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 v.\tx360\tab more items\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 (A)\tx360\tab a subsublist\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 (B)\tx360\tab a subsublist\sa180\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Nesting:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 A.\tx360\tab Upper Alpha\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 I.\tx360\tab Upper Roman.\par}-{\pard \ql \f0 \sa0 \li1080 \fi-360 (6)\tx360\tab Decimal start with 6\par}-{\pard \ql \f0 \sa0 \li1440 \fi-360 c)\tx360\tab Lower alpha with paren\sa180\sa180\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Autonumbering:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab Autonumber.\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab More.\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 a.\tx360\tab Nested.\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Should not be a list item:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 M.A.\u160 ?2007\par}-{\pard \ql \f0 \sa180 \li0 \fi0 B. Williams\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Definition Lists\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Tight using spaces:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa0 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa0 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}-{\pard \ql \f0 \sa0 \li360 \fi0 yellow fruit\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Tight using tabs:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa0 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa0 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}-{\pard \ql \f0 \sa0 \li360 \fi0 yellow fruit\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Loose:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa0 \li0 \fi0 banana\par}-{\pard \ql \f0 \sa180 \li360 \fi0 yellow fruit\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiple blocks with italics:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 {\i apple}\par}-{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa180 \li360 \fi0 contains seeds, crisp, pleasant to taste\par}-{\pard \ql \f0 \sa0 \li0 \fi0 {\i orange}\par}-{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa180 \li360 \fi0 \f1 \{ orange code block \}\par}-{\pard \ql \f0 \sa180 \li1080 \fi0 orange block quote\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiple definitions, tight:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa0 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa0 \li360 \fi0 computer\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa0 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa0 \li360 \fi0 bank\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiple definitions, loose:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa180 \li360 \fi0 computer\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa180 \li360 \fi0 bank\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Blank line after term, indented marker, alternate markers:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 apple\par}-{\pard \ql \f0 \sa180 \li360 \fi0 red fruit\par}-{\pard \ql \f0 \sa180 \li360 \fi0 computer\par}-{\pard \ql \f0 \sa0 \li0 \fi0 orange\par}-{\pard \ql \f0 \sa180 \li360 \fi0 orange fruit\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 1.\tx360\tab sublist\par}-{\pard \ql \f0 \sa0 \li720 \fi-360 2.\tx360\tab sublist\sa180\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 HTML Blocks\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Simple block on one line:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}-{\pard \ql \f0 \sa180 \li0 \fi0 And nested without indentation:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 foo\par}-{\pard \ql \f0 \sa0 \li0 \fi0 bar\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Interpreted markdown in a table:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 This is {\i emphasized}\par}-{\pard \ql \f0 \sa0 \li0 \fi0 And this is {\b strong}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a simple block:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 foo\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This should be a code block, though:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <div>\line+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Lists\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Unordered\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Asterisks tight:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls2\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 1\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls2\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 2\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls2\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Asterisks loose:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls3\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 1\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls3\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 2\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls3\ilvl0\tx360 {\listtext\tab \bullet \tab} asterisk 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Pluses tight:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls4\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 1\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls4\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 2\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls4\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Pluses loose:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls5\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 1\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls5\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 2\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls5\ilvl0\tx360 {\listtext\tab \bullet \tab} Plus 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Minuses tight:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls6\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 1\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls6\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 2\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls6\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Minuses loose:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls7\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 1\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls7\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 2\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls7\ilvl0\tx360 {\listtext\tab \bullet \tab} Minus 3\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Ordered\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Tight:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls8\ilvl0\tx360 {\listtext\tab 1.\tab} First\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls8\ilvl0\tx360 {\listtext\tab 2.\tab} Second\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls8\ilvl0\tx360 {\listtext\tab 3.\tab} Third\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 and:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls9\ilvl0\tx360 {\listtext\tab 1.\tab} One\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls9\ilvl0\tx360 {\listtext\tab 2.\tab} Two\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls9\ilvl0\tx360 {\listtext\tab 3.\tab} Three\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Loose using tabs:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls10\ilvl0\tx360 {\listtext\tab 1.\tab} First\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls10\ilvl0\tx360 {\listtext\tab 2.\tab} Second\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls10\ilvl0\tx360 {\listtext\tab 3.\tab} Third\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 and using spaces:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls11\ilvl0\tx360 {\listtext\tab 1.\tab} One\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls11\ilvl0\tx360 {\listtext\tab 2.\tab} Two\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls11\ilvl0\tx360 {\listtext\tab 3.\tab} Three\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiple paragraphs:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls12\ilvl0\tx360 {\listtext\tab 1.\tab} Item 1, graf one.\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \ls12\ilvl0\fi0 Item 1. graf two. The quick brown fox jumped over the lazy dog\u8217's back.\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls12\ilvl0\tx360 {\listtext\tab 2.\tab} Item 2.\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls12\ilvl0\tx360 {\listtext\tab 3.\tab} Item 3.\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Nested\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls13\ilvl0\tx360 {\listtext\tab \bullet \tab} Tab\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls14\ilvl1\tx360 {\listtext\tab \endash \tab} Tab\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls15\ilvl2\tx360 {\listtext\tab \bullet \tab} Tab\sa180\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's another:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls16\ilvl0\tx360 {\listtext\tab 1.\tab} First\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls16\ilvl0\tx360 {\listtext\tab 2.\tab} Second:\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls17\ilvl1\tx360 {\listtext\tab \endash \tab} Fee\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls17\ilvl1\tx360 {\listtext\tab \endash \tab} Fie\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls17\ilvl1\tx360 {\listtext\tab \endash \tab} Foe\sa180\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls16\ilvl0\tx360 {\listtext\tab 3.\tab} Third\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Same thing but with paragraphs:\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls18\ilvl0\tx360 {\listtext\tab 1.\tab} First\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls18\ilvl0\tx360 {\listtext\tab 2.\tab} Second:\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls19\ilvl1\tx360 {\listtext\tab \endash \tab} Fee\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls19\ilvl1\tx360 {\listtext\tab \endash \tab} Fie\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls19\ilvl1\tx360 {\listtext\tab \endash \tab} Foe\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls18\ilvl0\tx360 {\listtext\tab 3.\tab} Third\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Tabs and spaces\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls20\ilvl0\tx360 {\listtext\tab \bullet \tab} this is a list item indented with tabs\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls20\ilvl0\tx360 {\listtext\tab \bullet \tab} this is a list item indented with spaces\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi-360\ls21\ilvl1\tx360 {\listtext\tab \endash \tab} this is an example list item indented with tabs\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi-360\ls21\ilvl1\tx360 {\listtext\tab \endash \tab} this is an example list item indented with spaces\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Fancy list markers\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls22\ilvl0\tx360 {\listtext\tab (2)\tab} begins with 2\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi-360\ls22\ilvl0\tx360 {\listtext\tab (3)\tab} and now 3\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \ls22\ilvl0\fi0 with a continuation\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls23\ilvl1\tx360 {\listtext\tab i.\tab} sublist with roman numerals starting with i.\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls23\ilvl1\tx360 {\listtext\tab ii.\tab} more items\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls24\ilvl2\tx360 {\listtext\tab (A)\tab} a subsublist\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls24\ilvl2\tx360 {\listtext\tab (B)\tab} a subsublist\sa180\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Nesting:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls25\ilvl0\tx360 {\listtext\tab D.\tab} Upper Alpha\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls26\ilvl1\tx360 {\listtext\tab I.\tab} Upper Roman.\par}+{\pard \ql \f0 \fs24 \sa0 \li1080 \fi-360\ls27\ilvl2\tx360 {\listtext\tab (1)\tab} Decimal start with 1\par}+{\pard \ql \f0 \fs24 \sa0 \li1440 \fi-360\ls28\ilvl3\tx360 {\listtext\tab a)\tab} Lower alpha with paren\sa180\sa180\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Autonumbering:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls29\ilvl0\tx360 {\listtext\tab 1.\tab} Autonumber.\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls29\ilvl0\tx360 {\listtext\tab 2.\tab} More.\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360\ls30\ilvl1\tx360 {\listtext\tab a.\tab} Nested.\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Should not be a list item:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 M.A.\u160 ?2007\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 B. Williams\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Definition Lists\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Tight using spaces:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Tight using tabs:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Loose:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 banana\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 yellow fruit\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiple blocks with italics:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 {\i apple}\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 contains seeds, crisp, pleasant to taste\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 {\i orange}\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 \f1 \fs24 \{ orange code block \}\par}+{\pard \ql \f0 \fs24 \sa180 \li1080 \fi0 orange block quote\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiple definitions, tight:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 computer\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi0 bank\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiple definitions, loose:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 computer\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 bank\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Blank line after term, indented marker, alternate markers:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 apple\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 red fruit\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 computer\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 orange\par}+{\pard \ql \f0 \fs24 \sa180 \li360 \fi0 orange fruit\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360 1.\tx360\tab sublist\par}+{\pard \ql \f0 \fs24 \sa0 \li720 \fi-360 2.\tx360\tab sublist\sa180\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 HTML Blocks\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Simple block on one line:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 And nested without indentation:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 foo\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 bar\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Interpreted markdown in a table:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 This is {\i emphasized}\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 And this is {\b strong}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's a simple block:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 foo\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This should be a code block, though:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 <div>\line foo\line </div>\par}-{\pard \ql \f0 \sa180 \li0 \fi0 As should this:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <div>foo</div>\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Now, nested:\par}-{\pard \ql \f0 \sa0 \li0 \fi0 foo\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This should just be an HTML comment:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Multiline:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Code block:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <!-- Comment -->\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Just plain comment, with trailing spaces on the line:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Code:\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 <hr />\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Hr\u8217's:\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Inline Markup\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This is {\i emphasized}, and so {\i is this}.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This is {\b strong}, and so {\b is this}.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 An {\i {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 As should this:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 <div>foo</div>\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Now, nested:\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 foo\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This should just be an HTML comment:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Multiline:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Code block:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 <!-- Comment -->\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Just plain comment, with trailing spaces on the line:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Code:\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 <hr />\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Hr\u8217's:\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Inline Markup\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This is {\i emphasized}, and so {\i is this}.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This is {\b strong}, and so {\b is this}.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 An {\i {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul emphasized link }}} }.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\b {\i This is strong and em.}}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 So is {\b {\i this}} word.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\b {\i This is strong and em.}}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 So is {\b {\i this}} word.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This is code: {\f1 >}, {\f1 $}, {\f1 \\}, {\f1 \\$}, {\f1 <html>}.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\strike This is {\i strikeout}.}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Superscripts: a{\super bc}d a{\super {\i hello}} a{\super hello\u160 ?there}.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Subscripts: H{\sub 2}O, H{\sub 23}O, H{\sub many\u160 ?of\u160 ?them}O.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Smart quotes, ellipses, dashes\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \u8220"Hello,\u8221" said the spider. \u8220"\u8216'Shelob\u8217' is my name.\u8221"\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'A\u8217', \u8216'B\u8217', and \u8216'C\u8217' are letters.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'Oak,\u8217' \u8216'elm,\u8217' and \u8216'beech\u8217' are names of trees. So is \u8216'pine.\u8217'\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \u8216'He said, \u8220"I want to go.\u8221"\u8217' Were you alive in the 70\u8217's?\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here is some quoted \u8216'{\f1 code}\u8217' and a \u8220"{\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\b {\i This is strong and em.}}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 So is {\b {\i this}} word.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\b {\i This is strong and em.}}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 So is {\b {\i this}} word.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This is code: {\f1 \fs24 >}, {\f1 \fs24 $}, {\f1 \fs24 \\}, {\f1 \fs24 \\$}, {\f1 \fs24 <html>}.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\strike This is {\i strikeout}.}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Superscripts: a{\super bc}d a{\super {\i hello}} a{\super hello\u160 ?there}.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Subscripts: H{\sub 2}O, H{\sub 23}O, H{\sub many\u160 ?of\u160 ?them}O.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Smart quotes, ellipses, dashes\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \u8220"Hello,\u8221" said the spider. \u8220"\u8216'Shelob\u8217' is my name.\u8221"\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \u8216'A\u8217', \u8216'B\u8217', and \u8216'C\u8217' are letters.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \u8216'Oak,\u8217' \u8216'elm,\u8217' and \u8216'beech\u8217' are names of trees. So is \u8216'pine.\u8217'\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \u8216'He said, \u8220"I want to go.\u8221"\u8217' Were you alive in the 70\u8217's?\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here is some quoted \u8216'{\f1 \fs24 code}\u8217' and a \u8220"{\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul quoted link }}} \u8221".\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Some dashes: one\u8212-two \u8212- three\u8212-four \u8212- five.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Dashes between numbers: 5\u8211-7, 255\u8211-66, 1987\u8211-1999.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Ellipses\u8230 ?and\u8230 ?and\u8230 ?.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 LaTeX\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab \par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab 2\u8197 ?+\u8197 ?2\u8196 ?=\u8196 ?4\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i x}\u8196 ?\u8712 ?\u8196 ?{\i y}\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i \u945 ?}\u8197 ?\u8743 ?\u8197 ?{\i \u969 ?}\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab 223\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\i p}-Tree\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's some display math: $$\\frac\{d\}\{dx\}f(x)=\\lim_\{h\\to 0\}\\frac\{f(x+h)-f(x)\}\{h\}$$\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Here\u8217's one that has a line break in it: {\i \u945 ?}\u8197 ?+\u8197 ?{\i \u969 ?}\u8197 ?\u215 ?\u8197 ?{\i x}{\super 2}.\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 These shouldn\u8217't be math:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab To get the famous equation, write {\f1 $e = mc^2$}.\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab $22,000 is a {\i lot} of money. So is $34,000. (It worked if \u8220"lot\u8221" is emphasized.)\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Shoes ($20) and socks ($5).\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Escaped {\f1 $}: $73 {\i this should be emphasized} 23$.\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a LaTeX table:\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Special Characters\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here is some unicode:\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab I hat: \u206 ?\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab o umlaut: \u246 ?\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab section: \u167 ?\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab set membership: \u8712 ?\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab copyright: \u169 ?\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 AT&T has an ampersand in their name.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 AT&T is another way to write it.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This & that.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 4 < 5.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 6 > 5.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Backslash: \\\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Backtick: `\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Asterisk: *\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Underscore: _\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Left brace: \{\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Right brace: \}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Left bracket: [\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Right bracket: ]\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Left paren: (\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Right paren: )\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Greater-than: >\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Hash: #\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Period: .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Bang: !\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Plus: +\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Minus: -\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Links\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Explicit\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Just a {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Some dashes: one\u8212-two \u8212- three\u8212-four \u8212- five.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Dashes between numbers: 5\u8211-7, 255\u8211-66, 1987\u8211-1999.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Ellipses\u8230 ?and\u8230 ?and\u8230 ?.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 LaTeX\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} \par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} 2\u8197 ?+\u8197 ?2\u8196 ?=\u8196 ?4\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} {\i x}\u8196 ?\u8712 ?\u8196 ?{\i y}\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} {\i \u945 ?}\u8197 ?\u8743 ?\u8197 ?{\i \u969 ?}\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} 223\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} {\i p}-Tree\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} Here\u8217's some display math: $$\\frac\{d\}\{dx\}f(x)=\\lim_\{h\\to 0\}\\frac\{f(x+h)-f(x)\}\{h\}$$\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls31\ilvl0\tx360 {\listtext\tab \bullet \tab} Here\u8217's one that has a line break in it: {\i \u945 ?}\u8197 ?+\u8197 ?{\i \u969 ?}\u8197 ?\u215 ?\u8197 ?{\i x}{\super 2}.\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 These shouldn\u8217't be math:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls32\ilvl0\tx360 {\listtext\tab \bullet \tab} To get the famous equation, write {\f1 \fs24 $e = mc^2$}.\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls32\ilvl0\tx360 {\listtext\tab \bullet \tab} $22,000 is a {\i lot} of money. So is $34,000. (It worked if \u8220"lot\u8221" is emphasized.)\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls32\ilvl0\tx360 {\listtext\tab \bullet \tab} Shoes ($20) and socks ($5).\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls32\ilvl0\tx360 {\listtext\tab \bullet \tab} Escaped {\f1 \fs24 $}: $73 {\i this should be emphasized} 23$.\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's a LaTeX table:\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Special Characters\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here is some unicode:\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls33\ilvl0\tx360 {\listtext\tab \bullet \tab} I hat: \u206 ?\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls33\ilvl0\tx360 {\listtext\tab \bullet \tab} o umlaut: \u246 ?\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls33\ilvl0\tx360 {\listtext\tab \bullet \tab} section: \u167 ?\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls33\ilvl0\tx360 {\listtext\tab \bullet \tab} set membership: \u8712 ?\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls33\ilvl0\tx360 {\listtext\tab \bullet \tab} copyright: \u169 ?\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 AT&T has an ampersand in their name.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 AT&T is another way to write it.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This & that.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 4 < 5.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 6 > 5.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Backslash: \\\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Backtick: `\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Asterisk: *\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Underscore: _\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Left brace: \{\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Right brace: \}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Left bracket: [\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Right bracket: ]\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Left paren: (\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Right paren: )\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Greater-than: >\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Hash: #\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Period: .\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Bang: !\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Plus: +\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Minus: -\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Links\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Explicit\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Just a {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL and title }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL and title }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL and title }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL and title }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul URL and title }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/with_underscore"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/with_underscore"}}{\fldrslt{\ul with_underscore }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul Email link }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK ""}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK ""}}{\fldrslt{\ul Empty }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Reference\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Reference\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul bar }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 With {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 With {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul embedded [brackets] }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul b }}} by itself should be a link.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul once }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul twice }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Indented {\field{\*\fldinst{HYPERLINK "/url"}}{\fldrslt{\ul thrice }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This should [not][] be a link.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 [not]: /url\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This should [not][] be a link.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 [not]: /url\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul bar }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Foo {\field{\*\fldinst{HYPERLINK "/url/"}}{\fldrslt{\ul biz }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 With ampersands\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 With ampersands\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's a {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul link with an ampersand in the URL }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's a link with an amersand in the link text: {\field{\*\fldinst{HYPERLINK "http://att.com/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's a link with an amersand in the link text: {\field{\*\fldinst{HYPERLINK "http://att.com/"}}{\fldrslt{\ul AT&T }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul inline link }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's an {\field{\*\fldinst{HYPERLINK "/script?foo=1&bar=2"}}{\fldrslt{\ul inline link in pointy braces }}} .\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Autolinks\par}-{\pard \ql \f0 \sa180 \li0 \fi0 With an ampersand: {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel1 \b \fs32 Autolinks\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 With an ampersand: {\field{\*\fldinst{HYPERLINK "http://example.com/?foo=1&bar=2"}}{\fldrslt{\ul http://example.com/?foo=1&bar=2 }}} \par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab In a list?\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls34\ilvl0\tx360 {\listtext\tab \bullet \tab} In a list?\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls34\ilvl0\tx360 {\listtext\tab \bullet \tab} {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul http://example.com/ }}} \par}-{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab It should.\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 An e-mail address: {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls34\ilvl0\tx360 {\listtext\tab \bullet \tab} It should.\sa180\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 An e-mail address: {\field{\*\fldinst{HYPERLINK "mailto:nobody@nowhere.net"}}{\fldrslt{\ul nobody@nowhere.net }}} \par}-{\pard \ql \f0 \sa180 \li720 \fi0 Blockquoted: {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 Blockquoted: {\field{\*\fldinst{HYPERLINK "http://example.com/"}}{\fldrslt{\ul http://example.com/ }}} \par}-{\pard \ql \f0 \sa180 \li0 \fi0 Auto-links should not occur here: {\f1 <http://example.com/>}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 or here: <http://example.com/>\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Images\par}-{\pard \ql \f0 \sa180 \li0 \fi0 From \u8220"Voyage dans la Lune\u8221" by Georges Melies (1902):\par}-{\pard \ql \f0 \sa0 \li0 \fi0 {\pict\jpegblip\picw250\pich250\picwgoal3000\pichgoal3000 ffd8ffe000104a46494600010101007800780000ffdb00430006040506050406060506070706080a100a0a09090a140e0f0c1017141818171416161a1d251f1a1b231c1616202c20232627292a29191f2d302d283025282928ffdb0043010707070a080a130a0a13281a161a2828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828ffc000110800fa00fa03011100021101031101ffc4001c0000000701010000000000000000000000010203040506070008ffc4003e100002010303020404040502050500030001020300041105122106311322415107617181143291a1234252b1c115f016336272d1082443e1f1265382ffc40017010101010100000000000000000000000000010204ffc4001b11010101010003010000000000000000000001110212213141ffda000c03010002110311003f00dadd18a10a704f6a95ccc57e37750782b0d8d9ea0cd32e7c5446e07e9f4ad723119a7b89e61e348f260719278aad613cbb640002938c76a182b264fc87bd13009c0c019c76e3d68a072e1cf6f4cd502d330c28269a61bb39c923923d4fad44c08dccb95cfd28b8280769ee08a263891e1808739e4f1d8d149392172cc714050dbb9fde8960ed8c60b79b1ed44103b05c331dbdb1dc5026ac1946d20ff8140aa631c773ec738a0346a003bf93e9cf02801895e7b9a01886796c923bd0090a06393c76a0142003ce3d86680d8dd9392303f5341ccc1b3cf7a2c812c37e4923d381429757013209fa511c18146c9247a0f6a007900c0c671c6280854e086c673eb45c27c038fd68aedff2fda836ef881f136f25d5e6b7d1262964aa02b03f98fbf153131935edcc97576f35c33349212cc4f39f7ab26186dfce5b200f73451f7600dcb8cf27e7400c0b291914046c9e0718fde81371b8e7273f4ef4007691919240e714097f31f376e7b5008caee27807b0f5a02c8e1b3c6d27d33cd0201d839523144d1a149ae084b78da47638211771fd050d582c3a0faab5119b6d12f8ab1c06788a0fd4e2ac356fd1fe08754ddccaba849696309e598c9e2103fed1dcfdeadc44fea5ff00a7f956366d375e492403ca935bedcf1eea4ff6ac68a55efc1beb3b552574f8e7009ff933a927ec715bc82b3a8f4d6bba5ca1352d22fe061cf9a0383f71dea5119cc6c0baed3eaac0f1fad40897dcc3d81f7a052366c1007df3400f21edefc5008c28f30c9c5170ee4fc37830086395250a7c66770c18e78da31c0c63de8609b41f7c515c5172a30c3b76344a3e377cb2339cf7a242aea89808cce368272b8c1a2e107c672a49f5c1a181c9c7ae7da8a2119e7b1f5068099ffa68258a132062d8f9e0f34059502b61bf2824e681bb297ced2a71efda80f19c47b9c77fdbe74057c13e539cf3c1a0eeeb9c73f33405ddb4f18249c1e28062b79ae242902024465b9214614649e7bd0362a7249eddc513456e5720f38f5a1a98e96e95d6baa6ebc2d1ad1e65521649bb469f563534d6d7d31f04347d2a2fc5f535db6a0e83718906c887cbbe5a9a8bef44dce9f731ca9a2e89169d6d6f2184b1455dc07b11dcfeb4d16f119c649a681285b03d3e5500f87820ff006a0e098191de80ac9b8904647b55d11da9681a56a31f87a869f6970b8ffe4883629a289aefc16e92d441682da5b098f21ed9f033f353914d19b751fc08d66cc16d12fe2bf45ec92ff0df1fdbfb559ec667aff4eeb1a04db359d3ae6d40eccebe53f46ec7f5ab82263da7dcf3eb5174e5181076918c7de869503232491ee4515c1803824f03b51287f30e0e7d803449494832c157278a2e8c71fcb9f9d144639236824d01e142efb1768cfb9c7ef40512a818de78ff00a682518e7cc30ab9e00a02cce9953247bd41e467191ed9a04205ee99da4e4e3d283a524b0427b5026c18a8e082067db8341ce0e39ed409b6502907391edda80f2dfdc496f0c124ac6184b144cf0a4e338fd2894f7a7342d4ba9b568f4fd261f12571966270a8bfd47d8511bae85f02b47b7fc34bac5d5c5dc88a0c90ab6c8d9bedce3ef4d1ad691a6dae976a96d616d15b409f9638d70054a1dbc68ea51d4329f4619a8022b78e04548515117b05000a035c5c4702a995c26e3819f534047bcb68a458cce866719540724d02e41c0f7a012a40f6141cbc8e7bd01719e38e6838af1c0a04ca8206d3cd037bdb082fad9e0bd8a39e0718649141047d0d5d18f759fc0cd3af164b8e9999acae4e4f81236e898f7c0f55fed574615aee83a96817ef67abda3db4ebdb7f66f983d88a061bb8db9e3d45165076db83c1f950a53780d8247c80a2398f182724f1c7ad080c608cfa7a51a0062adc7afbd0130173bb9c5070f071cb37e82826106e8f615e01c9e680d6b35bc534be3c1e3831b2aa962bb188f2b71df1de819ae4b1048c7f57bd01a58268e332642ae0704f7cf6207af6a01b99e17b7b6416e227407c494139909ed9f4c0a04a4e501e0f1eb40d263e53dce7fa682c9d0bd13abf58dd6db18bc2b157c4975270ab8ef8f563f21447a73a03a1f4de8eb031582b497328066b97fcd21ff038edfde88b7e32703bd64188e7e6283864b73400cd804b67ca3268317eacea6d56ff005233592f8b6303f953fa4af7c2fa93417fe98b763e0ea171297bab98558068f695ce0e08fdbd281e5c6a57ba5e9d14d716ef7774f2ec112601da4f27ec2827ada74bab559a20e148fcae36b0f91140283729c77a0e0a7777a01dac68395719e39a029607cb901b19c501480ab9279f4a086ea8d0b48d76c0586b7143224a76c61ce1831fe93e86b43cd1f12fe19ea7d2533dcdbeebcd20b612651e68f9ece3fcf6fa5067cbcf20ff009a051724905411e94032799060723da8406d6c67e7ea68d0e1770fe5cfb5026c37039ef9a02eca098c91e6e01e71c500b1d8a49c12786cf6a06a4e256008e3d050119958007920e2801154e32fb4120927b014017eb1c523ac5209a356215c291b87be28957ef853f0d66eaa99352d515e1d190f947669ce7b0ffa7e74a8f4be996569a5d9c56b6704705b46bb5238d42851f2ac875712bc70b3c30f892019540704d01ad2669a0491936330c95ce7140b2e4939a03638c7e8680ae485e33bbe540d60d3ada162c90a02c7270a39340a4f28b68da4645007a8f6a069a746f73235ddcefc391e12b2e1916824948742c99382473c73404791c617695279dc0640f9502c578c9efeb4095cb4cb0830ba21cf999c6401f4f5a05061d430c8079a02e03b3004311c7d281b5e3cd676c65489ee594e4aafe6c7ae07a9a0a075bbea3a8ea96f047d3935ebc404f04ad29411e08e011d98fed416fd212ee5b05b4d5ad6300c615807f1171eaa49eff5ad418c7c55f8466dd66d57a521f20cbcd66a7247a9283dbe5418a63862479877cf1f6c5008e400bdf1ce684016fe53dfbd1a73794600e08ce3d6800377c8c7d6800a9cf75fd4503d91492460f7ee3d28247a7b459f5fd592d22711c206f9e563858a31f99cfd050583518ba75247b1d134f9aed21396d4669769931dc01c003f7a329c4d17458ac5b55d36c12e040a3f1da75c1cb04ede2447f7f6a94567ad7a66db4fbbb29ba7d65b8b4bd8ccd09c8231eaa07b8ab04a7c2cf87b3f53ea8d77abc72c1a5dabe2452bb5a561fc83e5ee7e541e988218ed2dd22b7855228d76a46a00000ec00a510bd4dd511f4fe84da95cc31f880022da4902b1e7d3e99ac86fd03d631f565b4ee6d4dbbc649009cab2e48c83f514165b8b94b6895c44f279c280839e78ce28178ae6de46748a789e453865570483ec6812d42e85a421fc37918b00a883924d024c6e99b7a2a966c0009e17dc9f9fed40f81c77e28139218e4ff9815b9cf23340a01c907b9140201038ed402fcafd28386464e4fd33c50272bc60032609cf00fbd024f722dc66f24822ddf972f8feff00e280f69b24844919cac9ce7de83a447f30ded823007b50459d6ecacb528349b979127651b1dc795f1f3f7a0990148054823dc5015d491c0a0c3be337c2ff00c489b5ee9c87172016b9b541c49ff5a8f7f71eb560c1fc43e0a47e1aa94277310431f91fa551c1727f29ed409b641c86e31839a3454805739c1f6a026f1fd740f64665fc8c31cfde82db79bb40e9e8f49b62eb7d7e8b717ec832c91ff247fa1dc7df2281bcc9369d671493c422b7911654c1215f92bb8827bf068624ba635392df5eb4b9924558ee5bc19b71cee43c6dc7cf34c657be8db0b0b9d0f51d2afe668934dbf9628ddb8c2b8c0073f3a80da37546a7d25174fd95dc125c69f7313ee5655dfc313bd483cf07b1f6a68d5b48d5ec758b612e9d7293211c8fe653f35ee2a084eb9e8bb1eafb3582fe496278f3e1c919fcb9f97ad03ee8dd017a6741b6d3229dae161057c5750a48249ec3eb4139238568f6a9e7b103b5037934cb3793c610a2cd9277a8da73f5140ee38f6280c4b11c65b934023006d50050030e4647de80c846de3b500fcf9fbd0197273ed4007b91400e580c8e45074a82400e72682b36fd2162b7f25ddc09af2766ceeb872db79cf00f6a0b3229550140e07007a50092db860673de818df473c862686dad6470d9cce3b7b63e740fa1de6252ebb5bd81cd00bee2d800d003a6464004763ce683ce9f1cbe1f1d3a67ea1d1a30b68edffba814708c7f9c63d0fafceaca31e6dc71e1f07daa82608c83819f7a1a11ce149238fd68d0a579ec682cfd27a7c3a86bd10bc38b3b756b8b93c1fe1a8c91f7381f7a034f752ea5aa5c5eb292f732128037619c018f6ec282e5a2cb047abda74d5ce9b6da80f136de4a496219b3e48c92000323ea73467519d3da5bb757dbda410ac90c77c23058f99007ee7ec31416882ee47d23acb5185caf8bab4691b1efe57fff0038a9457ee75a82f6e7429350466b482f2742c0f74241c80c38c64541a9cfa1e89ac0177d33ab3d8de28f2b5bca429f91140e2c7a9b5ae9fb85b6ea9b46b9b3c796fe040768f76ec0fafb1f9505df4ebdb3d4edd6e74db98ee216fe68ce47d280648f75e2485a44da385ddc13f4a025ddbdbea16a633286566ce55f9c8f6c502ad750db2c514f30dec428247e6340bbf04100b73402afb943ed2b9e30683836defe9403bc1e06734020e06280cafe8683a375941d841c77c1a0151b467b50159f00e4127e5402872371040c5046eb5aadbe9b1c02e2f6dad25b89047099c677b7b0140fe3f1010afc803f3018e68160c3041ee2823f5dba92d34db89a1d9e2843b03b6d05bd013560c1748d57aa2797c6b35bab78e6959dc47231580ff336dcfb03c1a58364b5bbb7d7fa7b7427f1f673830c8664285bd1815238fad20f2c7c41e979ba43aa2e2c1cb1b663bede438f3a13c7dc76fb5515e9065b851f7a02950002a09c51a1b83cf14176e90d3645e9ad7752752aac23b3439c066665c827e944d29a6410aea725c4567135bd840d3c88a723728c29c9efe6c50d3ee9545b0bf8ef2e6e3c2fc2c6f72f2920e5f19039ee4938a9a875d03278377acf52ddf867f036ef71923932bfe51fbd3475cdc369df0db4fb389d4ea37970fa9cc0b00511795ce7d4f181eb4cd2451755fc45ac16d637381b14ca36b641dfce723e4053170d6cb52bbb362f6d3cb19241f2b9029862f09f143549ba7e7d2eef6caf2797c66ee17fdfd69862d1a069da7dfdac579d17adcda5ea9e1a992376c4723e39e3b024fd7e94c458ac3e25dee8d31d3bae74e7b79002bf8b8549471db38f5f4ed4c165e943a06a328d4ba605b4b22a1523c420c64fbaf38a82d36f0ce7cf7463790729b53017e940e0b0ceceed8ce0500e1b70daa08f5c9ed41d271cd0132476e7d7ff00aa069797d2411168ed9a41fcc858211f73c5075acb25ca6fb82aa31e58a36c81f561dcd033d42169e158ac64b98151b3981c2966cf639f4a064c7a8ac55e4865b7d493701e1c8e52403ea3cbfda827e390ca3f2c914aa81991bd281cdacc2747215c60e0ee5c67e940cb51b0b2bcbd824bfb08ee1a252d1caea1821cfa67b1fa504982b2283ce08f518a08abb82f6dd0369a5662081e14ce40c7ae1b04fda82275cb0bfd4f4536f7114589a5412461f3e4ce4e0e060f63f6ab2893d3b4b5b5b78e22ed22aae3cc3cc7e64fad3449a22a461500007602a0cd7e3b74c26b5d2ad79147baf34eccca40e4a7f30ff3f6aba3cd0543267eb5427b86f1f4c76ef45d0eca1ad5ef224d13e1cf4fd9b22192fa67bc955f8c8c617fba9fb510d7a6ed3fd43a735e5b54964be658c048fb6cdd9e7eb8a186bac97d174e6d22e23437b7ac26b95e77c68bf950fa7279e2b22dba45b59e97a669fa4ea36aeff89cea9a90451fc355ff0096ad9f4ce3f41570675d4fa8c77da8de5cde5be26bc653171ca47dc1f6c9fed5562b97f70276808da7c24f0c1c63804e33fa8a2928c0e0383c8f7ed41d92a41393f4a2548595c2c37493db4cd04e8a08f139566edfef3445b6e7aeaf65d2df48ea2b11776ae02a93e564c772adef409f4ee8ba9a21d73a36fa579ad9f325afe599171ed9c30a960d5ba0fe2843abb47a6f510fc26a4c36890f9558fcc6783506a1147b510024e30339ce680d2c6ae9861eb9a009178a0205443b989e39cd01d8075e3047ce80563057ca381ed4011c4531e503d85013c91b804a21279c903341131cda8c3abdc8650f6d20c4321232adec3dc504bab2c113c9293bb1963df3408dd4b75e1efb2856463dbc43b4631fad047e9177ad4fe32ea16b1db4b8fe1aa92571f5f5a0916bc8e0895af5c46c17cd8c9ff7da80f6d736f7f6915c59cab35bc837238ed8a072a31c1ef4062870718a06f7702dc5b3c522ee4752ae0fa8230683c75d6ba3b74ef535fe984929149e4278ca9e47edfdab42058003763ed409f88ffd6dfad06b1f12ae612fa0c76e0b471e9916d23f973eb4158d3efeff004a984da5debc1295d8e4018dbf3145d583a2ad96f356bbd7f5d90dc59587f1e79a6392f28fcaa3ee47159444ea3aa5ddfc7acf50dcdc344d7a4dbc317f52641200f6000fdeb41b5ef51d8eab672ffa9e971c97c11638268e431a46000012a3b9a351567db823b11f3ef40948e428048207a8340ab48ae83cb83ee0f3428a982719edf3e68c9cc97d3fe15ad8c9be138f2bf38e7b8f6ef40f7a5f55bdd3f56b46d3649127f1405f08e7249c76f5fa50689d48ba5f545cdcbdb462cba9206411b2b055bb07d4fb1c73528d4fa8f52d62cf47b6b8d2e65fc458c49f8a818795c151939f977a823ba0fe253750eb7fe937b04293f9f6c90be41dbdc7ff006283473c1efc1a06f69776d73bbf0f2aca32572bc80470450284a46dfca19f819f5a04e799614def26c0bdce09cfd85045dc75769d12dc3c3e2491db0dd3c85195235f7c91cfd066ae0cdba9be31f4ec61a386c1ef9d4ee473e45cfb1cf34c101d3ff1ac9d481d46c628ed24751881880833f988e7b0fa5328dfed2f2def2ce2b9b79925b791772ca87208f7a60182ee2b95cc0c48f53823fbd40ac658b30f4f4a086d4ee1d75bb6b78f4e965596366fc5211b23238008fde81f43692da5bc30d97831a0397dc09e3d714087506bf61a2c4cd77324726d2caaec141f9fd2ae0c435bf8c57173ad7876f7a2daca10489121244cdf319ce3dbf5a834fe81f881a6f57bcb6ba7c53c72c11873e28cee1db391dbef4199ff00ea4348116a5a66a8a8a04aad04847a90723f6ad7d18c312ddc02a3815423ba0f63fa541687bd9efe1b533b3c9e0a78473e899e318a09bd0ba6eef543e3b2bd8e9b10064bd9e4da001dc81401aeeb29a984d0ba7d5e1d06d4e6594f06523bc8e7f5c0ac8af752dfc17d7090d9218ec6d9447129ee71fcc4fb9cd6842ab10dc0014f3e5a2c1704b671dfdc734525226dc939e283a362c7f940344a380393df144733e2276e38f5efcd01b4bbbfc3dda4a9298a44395902e4a9c70682660d4265d62de40b1bdc1545054f95c8fe627df141af7c3af8808f3dd68dd5d2a45765884b8908d8c3b6c27b7a77a945d7a5fa474bd2ba8e4d5748b28624955d5d8b13b79ee9e983d8d40a753758c7a46b96f6114725dc92279a2810b3a64f94900763cfafa503fd3b59b79ed84da34713c0cd890f0a158fa1f981de826e1b548959fc4dc5cee24b6467e59ed4101ff19e9f676baa5d6a72c50adb4ad1ac790ccc076200f7ad41e7df881d79a87576a5f87b0f161d381db1c2a36e7e6d8ff3416bf87ff082c6f208ef7a82f22b9761bd6d619785f6dc477fa53705ab57f83bd297ceb1e9caf67708db9c4526723e849e3e94f212dd25d117fd29a8c09a76b534fa39cf8b6b71ced38e36fb73417f52e64548e34007e673e9f21ef590a1c918c90718dc281a69b68f67118d9da5058b798f6fa7fe280daadd1b2d36eae70710c4d263df0a4d583cc7a668fd4bf11b5837d7c93dcd9a3146959822a0e781f4cfa55161e9dd7fa67a4f55b9e9aea3e9f81fc09ca0ba118998fcdb2338c7b528d39f4cd2ba76e2d357d292df4eb391809963420ce1b1b576fa1e7359119f1eb4e17dd033ca172d6b2a4df303383fdeb5c8f2eef3bce4e0e335684cb0c9f354160d36f64b0baf16072b91b5f03391f43c51aab23a5debe91c4fad4d73689e6fc3a290573ff4f03e59f4a3280d67581ce916567f84b58ce0a1fccec3d58fa9a084de08c90464e4d1a8e419059b201f4a05630a176918efc50176293872c17bf14042aa0125b03db14046c60b60123fde6827fa0c68edd5365ff11346ba6292ee64194240c807e59a32b7fc51bfe8bd5ed5db424860beb62b89218422ce09c11c01dbbd0660ae110bf1bf2154838dbebfefeb41a8f4cdac7f117458f4d9ecd2df53b4cf81a822808c47255c0f7c8e7fb54a2ec2cfabba3b4b4b8d3af12eedad40926b0f070a13f9b633649f7a82eba6ea4357d321d4ecad512daf20df26e016507fa4fbfaf3e98f9d067dd2bd2faac9aa4d72d72d1e9510ca46a7631c7a320e18f1dfd7bd059afb7da816d23de4ba5de211346a1e4785f190548e4648c63b64e6b43ce9d5baafe3b539c5b452dbda46c638a167cb281c73ee4ff9340e3a3fa5f5aea4ba58f4bb57dbfcf2b02a8bf7f7a0de3a5fa0b50d2a2d92eb3e048c0a97c867dbedcf6a944e5cf4f6b76d1b3d8ea42795066266c87c81c65b9cfaf15048e83af3cd64abac08edaf01546c38dae4e0657ee6826e5b892de3702292e2545ddb55700fd0fbfca81c4b3bc718716eef9eeaa402280d14ab3c0b2c65c06fe571823ed40df56b217fa6dd5ab9216689a33f2c8c558307e83b8d77a37aaa7d22f2512c28768800c9954671b3d33ebef568d0ef7a7749eb0b5bbbb162d657b32b46d2e1564c8ed9c5644d1b0b9bbd261d2a440af6cb0e2e5b1e7dbc1238e0f7a0375b696daa7496a3a4dac8a92cf078685b271db04d391e40d5ec4586a1716de2a49e0c8c85d3b120f715ba1899173ff305413070abd89cfe9f5a2d3ee9c8639fa874eb6b804c52dc46b20c9f302c3bd11e84d47e1af4d5dc6521d3e3b662c19a58721ff5a9a321f89bd27a374b456d158dccd34d333332c9b4b2afbe47a7cb1f7aa33d2bc0d8c0f1c8f6a2c14b6d501b39cf63450897380c319e3de8065031c038f7ed40d8faf1ce41e4d004876a8dc3cc7e743025c956c818028c904579e7f0e15695c9c0541924f6c00283d0bf07f42d6b48820b8d62d20b2b58d656404959e52f83c8ff00fcfafbd4a35bb06f12391a48dd55cee2b2f3818ed8f6a8158a159890f02242079147623e631c502b0db436d1ecb7458d4738038fb0a087d6eeb508f48bb7d32d95750752b6c26c905b3ddb6f61eb574794f5cb6b9d0fa9678b512b25d24bbe52b8c1638278fbd582c57ff12afaed45b5bc0d0d8a8c08a2731ee3eec5793f40450466a1d59af446293c186cd53ca0c36eab93dc649e49fbd048e89f1675ed35e301e293919dcbf9867b37cbe94a35fe94ea4d33aba6824306dc48015750d86c6e247b0cf63591a40b8dc23fc30f14138dcac3000f9d03687547f12e8dd5af816b13148dddbcd29039c0f6f6f7a0eb5d62caf5636825db70c9bc4328f0dc0271c8a090627d3073ce681acf6505ccf14d35bc2f2c2731bb28254fb8a075144a83ca806792400334049ee6281e2496408656d880ff0031f61fa50446bd76058ea1b9e21025a3bb48afe71df9c7b71de9c8f196a0de23ca7b827d4f7add117e0cbfd4b5059392369663ff004e71c51aa97e8f555eadd258f2bf8a889cff00dc28cbd0bf123a926e96d163bdb74490bca2321c678209ff001591e71eafd7a7d7ef45cde2c20aae144638033fb9ad2e1b5e69d058da431ccf21d4a5c3b4631b62523807feaf5c7a50222f2d648c25f5aeec8c2cd19dae3d3e87e944d3eb7e90d425b49ef2292de38224f1505c3f8724a9eeaa7bd0d57a60406059436306868a7803839c7ad1a158039c13f4a33a716767f8cb9b6b55e1ae2458813e9938cd07a9f42d0b4de99b4b7d1f41b58ff19b03c93ba06607fa8b1f5f619a5b8266d74a65d42da6ba90cce996dcdc8c9fff006a5a2c2635083b05ef83eb5028076341db4b1ed9f7a04651fc41db18ed419d75b744dbea335fcb0db0335f2057901c05da73c8f9d5d18a75174a3f4c47335e35da4ce418a489374254f707d463d33565d1529b569a489a17944b06ec8057d71dcd037b4b6b8bfba31584124b27e62a8a4f1ea68357f83da7ea5a76bfe0912453ccabb49194653cb60f6ce3dfda983d196cd108c2401711f9768e306b2297d73fc6d02773a8b591922693c5004bb9d72542fa2f6efde8314ff867aeeec27500b77bb5670e36ca19b1dff2e7f2fd2837ce8bd5dd348b78b552219022870d9c46e792a4f6c608a0b846c8e03232b29ec41cd0199f1410fd4b24b1e8f712c0a5e4452d851e6c639dbf3238a0afa42ba77475e4ba8470896681da45180b18da76af3c9029c8f26dc1df2b9c606e273e86b743331924f27f4a82c12280e59b008e79f6a2d4d74188ff00e30d203a82ad7519c1ff00b860d11ba7c5e86c9fa3afae6f4091e043e021270b21e01c7dcd6479ab4dd3aeb56be4b7b184cf2b301b57d07bfd2b4bad0fe25e9f6960ba7c7a55ac50cd750335ccaade7723b83b8f6e38a2207a5ba4e7ea3d93780cb616ca53781f99fbff009a0b675a5be9765d43a75a6ad3b25adb4185429b831c70303dfdfd2831eb8954ca48f3827819c71ed406b2b1b9bf9a5fc1c4ce2253238047957dc9345d122b792eee522811a495ce1157b93ed444ff0049f476b1aaf51c761345269d25be269259570c833c6077249e062a68f53e8ef0da69509d4ae225b92a04af232ab16f98cf1f4a5a266d4dbca8af13a329ecca723f51502d14f0cb9f05d1c8ee01c91f6a0393b4edfe63c8a031608859b38f97340d84d04e5846eae50f9829ce3eb400fb24466041f5e3d2823f56d22db57b192d6e61468a41c823ff0035651916bbf04ada7badda5cad6d1b72c09dc33f2a6875d25f0865d06fe2bc6d4c4d3282026cca8cfafcfd29a34cd234a10c768f711a78f1bb392a3001208e3ec69a26a58d640c832091c90706a084ea1d3eeafdadf4f86da3166c0b4b397c18f046140f5ce4d04f4702436e91c28a9122e028ed8a0a9f5a5b6a09a1bc5a135bc72cce048b3c5bc15c638f9d59043fc2db997481aa69dae49e1cb6bb643239211939e467818f97bd305965ebce9a10bc8da9dbaa2679dd9ce3d8530572cfac87566ab05ae9f1490692b9696e1f833738555f96793504df5f25945d2576b7ec16dc46792381c7b7ad5e60f234980e42f6c9c56a82ec3eff00bd4124e49700f1c646e3cd169ce9575f83d52cee324347323f6e3861ff008a23d47d4ba6a75074fdcd8ef317e2e2ff0098bdd4706a60c3f4ae8cd5f44eb8fc3e97248a638cbc73bf90483d463b373e9574685abf42a6b5649fea72bbdeac4a8d3b018cfae31f7a6895b6b29b41d30d8e9f6bbed9213e1b7a994e724fcbb5064bd7835a9752d3af75d8116354778f660788cbd9483dbb0a0cd20b2b8d43528ad2088bdcccf854039cff00e2827a0d34e9da1de896f2182492efc0976f998aa827d3d334113a74aa9a9298628e74570478bc0c7cf1da83724bb8246d3e6416b0384da61b5501c9f5c3704f152c037561a95f5fce61d3ad6db4ab950f34b331dd9f4191db8fdcd406d67a675ab4b6d325d1af248272a43430315ddec7038f6ad4b3f448bf47eb71cb69abddebf21d5e26896203846c30c8603b9c6452d9835901405660376319ac84bf13180779d8bb82827d4fb0a06f777367a75acd7170f1430a9f331200cfceae061a0cf6dac692d7365266191db0578f5edf3a6075a6c9278b3433188a467860d96fbd40fe540471409aa0c1140750001ed8ed4058e15133c983960077edf6a06faade5c5b7822d2d926766cb967da2341dd8f0727d85033d27597d62e2ee3163756915bbf8799d71e2f19dcbf2a092b88dd9a311950a0e5b70ce47fe6ac18af53f5b69da9752dd69da9ca906876e24465d9e69881c6ff005c679c0aa2bfd267a347512c93dbb5d42d90d3c800b68c9ce0ec3cfa528db74ad034db5905ee8be1ac728dc153984f3f980f4fb56453be2de8f647a6aff53796596f0aed46798ec033ce149c0fb0ad71479c9bb9dc3bf3c55a0b95f65a825150b481a407b93c0fda8a29c06671dc93803bd131eafd0af6dffe18d2ee25982a4b04603b7a9c631fad03bbe586381bc5945b96385718c827db3eb5288eb8ba934eb15fc3c535f05427796dcccdec7150637d5bd55d5362b7975aa4d0d919018adec8637807bb60723000e4f7cd58203538aefa8aeb478a7b9beba924547b8774cf8608036a80704639cf1f9855d1a7f4c68b67a03de5e5d59dad8d988c62e1c0f107a1e7fdf7a082ea6d07a6e3e99375a7cb6b3db093c727701e2360f7f53dfb50653d4130d42ee18f48b3f0232a15218936963ebf5fbd06dbf0cfa74855b9d46e04b730c6144691e12307d33ea7de8348ba6b5478a279a004f98c479247b81f5a9438805ac0be2e02e73c9ef8fbd40c2346d43578eefc40da7da1dc8b8eefea4fcb9fef419beabf12a4bcebcb2d2fa7ee0dc58492084b30236bb6467dce383f6a0b87556a67a7f4d95a0bbb5468816f0a69c78b2e072572719ce78357079dfab3af2e7a92c963b88d94abbbf91cedc93edf418aa2c5f0dbe2a6a9a0c90d8de34773a6a8da1186d6403fa48fec682d9adeb7a9b4c9d572dacc9a6c9700456e5ca910e000ecbd8e580352fb1ae7476bd6dd49a325e5a9f3025245fe961dea097523cc0919a032af039a006936c81423104649c703ef40dcce64bc3035a87b6f0c378f9fe7cf2b8fdf340a4b6e25962915d94a67807839f7a043586922b5636ec44c061063f31f6ab079d7fe19b7eb2d4efeef55d5d74f992e9a0fc3a441dcb13927b838c9aa2d4bf042c618e178efee6e18104870172318edf5c1e6945bbe1a748ea7d2315edbea3a99bcb190030c401010e4e783ee0fa56455be3d6b90c1a6268d69e17f1486900ee98ec29ccc183119419e7e55ba11f089f523ef5058363a8059fb8e31e9421b491056c01819e28d3d0ff07eea3d53a1e3b6b8db235aca63c139c0eea68ca47a9fa6ef757b83ff00bf68ad428c2f248c7a8f9fcea518df516adac74e7544f63a2ea172f1800291e6cee19ec78cd5826344e85b6bad25ba8fade5b99dae0ee11efc71e858f7e7d054a2d7d39a75ae8f7b6b00b8917f1516624b78429da327cec493db1db1d8540cf4aea28f58d6aeae2f6dd64b498082d880488d149fcea7d4939ab04175e6850a8d32de3b78e380c8de32c4db4e18e430fef543cf86fd0d691b4fabdf6648b3b2db69ce7dd87be68342d2f4fb9b5b891af1a28a2dc05bc5036d001e0eef7352884b961a2ea9aa7555c885e08d45b5bc52b61b686c120fb939fb541276bd4b61d53624d942e2f6200bc32290633e99f4233416dd3ad3f0d611c0c77b632e71dc9ef41156dd27a45addcb3dbd9c513b1dd941821bdc7b558333b9f873757fd69a85e3f813e9c7723b5d93265d872473c11544a68ff08fa75e290b42ec4e4124e70738fa5048e89f0f745d2aeadd2decedda6525c975121183c77f7a945c754d0e0d563682ed43425369403bff00bcd58308ba7d5fe13f5a05889974a9d8b46aede4914f707d88ff001528ddf4fd7edb54d1a1d56c312dab2e64dbc9418e78f5c541296d70b716d1cd6f8789977230ecc280cb7519b816f212b205de4e0843ce300f6cfcb39a0545c42cee88e0b458ddec33ee680eac92266360debc7b5056fad2d354b9b189745744be121daf27e550548ce3d4d58324d07a725e98ea2b7ff5381f5169a7579d021fe13904ee43ddfbe49038ab46e76cf05cc714f6d309232a4a98ce54fd6b2196bb7f2e9b631b2c427b891b6851db3eff002007341e5bf887aa2ea3d4f77378be381e42fdb711ed5a1554395caf1cd07617dcd04fc85402101da791421b49920331381c60d1a69bf02f56f03a925b12c162b98c955f775e47df19a32d99b518268e4491668704a79d4aeec7b7bd4a30feb7e9144d76e265697c3e2693631674273803e556087d76f35fd49859e9925ccf611141106f2e182e3241f727f5a94681a268f79ad1b1b8b9dd66b1c2b1ce9bb06361c1e7bf3fe6a096b0d3ba57488e485b52b40909c386901607d47bf7a0ae758eb69ac4d15be81a748f0a9c35cc90b2eff4c03c1c638a0b77405c5d5d45f87be5fe359a88b81b401dc1c7d38fb50586fed18ea3015790091591e447c1518c8c7a0a0a5754d8c9d49a8d9f4ee9dba0b3b5224b9692327728f627e7c6682f9a7e996b6b3a8b6b748a348820c7720761412c064e3041ce282b5d4bd73d3bd3f33daea97ac2e540dd0a292dc8cd043c1f15ba2a7923b65bb910371b9a12141f9d02edf13ba2ade56857551e5e77244c54fd0e280746ebfe99bbbd655d56dcdc9ce08465565f4ee3bfca82d53eb3a6dac3e25c5f5ba646402e33fa77a0aff5b74ad8757e9ca972844aa37c520fcca7d3f5ab067bd369a8f467544d626c98e9f7118f0200e4465c903049c8c9e6ad1b24334b6fa6249716cab20037c309dd83db03b5640dddac3764a4f02cb1103863919fa7a1a06d6f600c37162911b7b252b87dc773f1927393f4a079f868edae1ae6328a8b1ed38e30050226e85d5dc1f879011b3c47c2f604719f9d01eff4f4b83e3c6b18bb452b1cac9b8a83de80b16e8208a3b7b58e1407cc061427cc0ff1560ce7a8f592d69a97504cad2dac01a2b53900c3e9e51ea58f727d0551e73bfb86b99a49a46dcf21c96340dc13804f20f6f9501c0e3b8a0963316fcc4607007f57bd084d64dec01200ce483468ff0040d525d1755b4d4206ff0095207c11dc67ff0019a18f56584f6daad9dade4211e39104a8ded9152b235cd8c530613229c8c1c8ef50472e81690ee00322b0c100f0debdbb7ca8111ace856371358cba85aa5cc407891ccf83f2ef4048b4ad2e59bf116769672c72f99dd1437239078e2824a4d3e1b94559234110e781839fa0a0561b38ad532a12319c86c6307e740a9732a3a00cac870cd8e0faf0681be8b6db965bb909df3c85806eeabced5a09523647e6e0fef419a6adf116daf7ac34be9dd1da686e7f1ca2e243b76320ce57df9ff1560cc3e3f470ff00c78255b842b35bc6c4af9b6e323d3e95467b6365f8dbcf062beb68c119595d8aaff6e282422e9899b4f6bb5d46cda2562a76316c1078f4a0859e1b9b762c0bf94f0e84feb4125a57505c58ea70dd5d0174a986d92b1c13f6f5a0de7a5be366877260b5d42dee2d2423124a487507ebdf15289dd3fac7a7bab6feded74d61733473acdb5a162142ff00313d81ed505fa58fc6d809380c1b9f5c502e0e05040ea367a85dea454de2ff00a610375b04c16c7a16ef8340b5f6930dce9375636acf6a278f04c5dd4f1dbf4a084e91d06f3a52dee62bbd4a2b882494ced3c8a448063b63b638fde803ab7ae749b2b3096d792c93c8c109b55dcd18ce3710473ffdd043dc758dc5869044565aa5dda4c3c2b7bc78c1f14e3963db03e7c0ab066bf1327d41ba76ca6bc48ecad24c456f6b0c87cf8e4bbfa138c0fa9aa3297c83dd4e28395811cf2680a5b93c7ed413cd1ff0f3c797b8031406645236b0508406f30e68ba49c051b97d0e0e7d28ad57e19f575c5be8f269515dac772877c11bc464dea7ba8c739ce78f9d3193bb8ebfea2bcbd6b5b6b8b58bb7f13c2f0ce31cf0deb4c0f2dbad6d743d2ee99efae752d6c02a86e0054524f6383c7ff94c0b6af274c75149a46a5a82c46f1e1479fc3190bd8156fbe7f4a960bf74e9d253f1167a3ac09e0856610e3041ec7f6c540f67b892cee7f8d18368232ef2af2508c7047cf340ead5bf130accc9b1186541e723d09ffc5033bbb1b82d74d6b37f1244daa1b38073df3f4a08eeb1d3b50d4fa6a5b4d32f12cef1902ee73e523d476fde8306eb0d3fabfa4ba92c278af67bb7281606472f90bdd58558253a6afb40ea1d62283a8b461a66a6f931cf6a7c2466f7cfb939e7b5515fbed3747b5eb8f06eb78d35080a2ec9719c76f98049a0b4ebdd37d1bad869acbf0b03c5c16b29444adf50ded41995f68564a263a66b31cd02be152505493f51c1a088bab69ad1bc179e320f07c37c8a0692b46c4995f0381db39a0b2fc34e971d57d4705bc8db6c50ef9dd97b81fcbf7381528f5ae97a1d8e996d1db69b0c7648855b10a81b80f43c739c54134147b9a036063279fb5046e957726a0f2cfe04915b06db1788305ffeac7a0a00d72f8d9c491c06337533050ac7185cf2df6a06da2da4293488f34973328c34aea428c9ec3eded40ee7d2ad249448f6b133820ee2833df3fde819ea96897461b05b87815f2ee919e5d47704fa039ab079b3e326b70eafd4ef6d6650d8e9ebf868b69c8247723efebf2aa280eb9193ebedc5002a124e015340018fb8fde82cf32b1603d0678cd02406dce3008e47ce81b499c331383c9c9f5a2e9c69377369f7d6f796a4acf148acb83fb511e91b3b3d0bab745b7d45acedd8e3732b71b1fd73f7a5a19eafd09a56a0a96b1c705b49c48510761ce4fcfbd4d0d752826b2b583476fc3daacb295b79d768de8a32b1e71f989e49f6a7d14dd1af5ba275a45b8b093c054492ea769092373765c1da4679fbd306e36ba9595fe9f0dcdbcc92c33e1579cf27d0d409ea178f68521b6b76926ee8a7853f7ff140bc768d78f6f73748d1cd103b543f0091cf6efc502f7319dac194371d8b6326829f0c501d7ae6fa568d5d4942c806d4db81839f53c8cd59456fae6e628749b5bab8b1865b08e4726588ec11e7f2e49071c93da9a31dd4341d675e9a5bad374f9858162d0b4ac70e18f0573df35a0c759f87bd53a404f174f965dfff00f479b1ef570576e34bd4b4cc0bdb3b9b7258a00e846e3f2a94376475cee4914af7ca9150685f09ba61efb52fc7dd69bf8eb7c158d1d0b47bb38f37efde968d6eeb4eb5e91d6ad25b660aee59974db6881690918e31ce39279e062a5a34bb57b88adedd1e379679065d80036679e6a07e8391bce7e940c659ef5afe1286de3b16f2b8903094b7b2fa7ce81eb380c4260ed193f2a0cd6fa5d4a4ea0fc7bdadcce923158a3039db83c038e3ef41a0e96b2ad8a35e009291b8a939d9f227e43bd590436bbd6fa269202c974b7123602c76e779624e00e29833bf897d493e896525dbcb2a6b5a9c3e1456b91b6d60cf989c7f31f7a60c02490961ebcf3eb541308e39e067b507007b96007a67fb50178f97eb4165ce18165c2927b773fad023202d9c8dbb7818ff003408300b87f2f1c107d0d0c15a4f2e339c90467f6a18bdfc2cea8ff4bd561b4b9ba686d6e64552c4f954e7d7e46a60f4688d240af1b2bc6cbf5047ca960617ba658de1b792f2d94a5ab33461b18524633fa1a81b5c8b5168967369d23c0e0a24622dc981d81c76aba29df0bb48d660d52fceb88d069f04aeb69130037127f37b9c0ed9a8350781240bbc06da72323b1f7a0eb8816e633192ebc8c9472a78fa50349b4c83c068e24f0ddbcc1c13b837be4d055b57e98b996d4db5b4a893dc1e6620b6ccf2c467efc504ce97a38d3f4d874bf09af6d46e2f25cb82724e791db15650a43f878b51fc34f3da8f132b6d6a98c80a39ff007e99aba249631b58b9047239ec3e55368aeeb7d2da6f52c0eb7f16e87f2c6e836ba90724ab7a67b55d115ac7c3e8aed2182def4c56a14096368959a423d77e3229a27b41e9d8343b01069c8a8dc9660aa3713df3c64d4a1c695d3d6b67a8cba94b9b8d4e61869e4e4a8c636a7f4afcaa09a485519caae19b966f7a0435196582c656b74df3e308beec7b50629375775b691ac5bdb6b16d6378779f019b00a31cf391c9c2f1daae0b35ef52f5374de88d77aa45a6cd25ddc0108694ee2188c28007603d6a0d16c92430a4b2ed3230dc401855cfa0a0a07c45d7b5db9d462e9ee960b14b2ee134ef8c850012147ec78ab0670b643a2efae753d72686e6e2da211db42176079c8e768f65e39f7aa332d6f58bbd635096f6fe6692695b24f603d801e82823cb900ee00e68006460051dfd680ed9f0c905b713d8d006d5f5419fa505a18f94e40501b1b81a04186d62402c87be3d6810b81290aea8467201231cd1749dbc437f9f1e201db3de8ba07dc0175c027f28a335b17c26f888d6b6d0e8fabf892a29c453b1e547f49f7a946d6424f08236491c833ee0835073294888894120700f0280813c40a6711bc8843e00fca7d3ef40e41dc081f9a811681c6f7565329185623b7e9de812b3bcf11ff0b74563bd50494cf120071b97e5fda80d7577046c9019d5669dbc340324eec67fb734103d5da96bf67a7cf0e916f6e2765f25ddc4c11107ab1c8c647cce2816d3ec7f0f6564cae6e67da375e6d52cc4af2e4fb13ed4145f899d47b3499f4bb6d46cda49b69b92921565c3648e3dd40c81cd5c0ae89f13ec246d3e379ed2d6da180b5d34849da1780b128e49271c9f4a60ba685d5fa36bc42d95c324ec7090cc9b1d87b81ed50588958977cacaaa3b9341c655f12348d1dcb8dc1946540f99a019e2134454eeda7bed3839cd052fe2136b536b5d3563a1ca53c49da4b9507198940ce7e5c9fbe281c6b7a974cf4ee4ea7242d76dc784a3c595b3e9b464e3f6ad0ac745ccbd4fadcbabea42da56959a382ce7460d6b1a93c01f97272093ebf6a82f1ad6af0e9da5cb3cecf6902216919f82aa3818c7a9f4c530649a9f5269ba7429d472239bc991a1b0d3c3152880f0f23039e7bf3de90635ab6a377aa5ebdcdecef2c9239e59f3827e5ed54302195fcc38cd01245395c1f5f4a05b606538e483c501b6939e3b5077860f3914165754c33e549000dbe87de813b820c27fa7baafb8a04a69c98e281e42618c795338033df1f3a06c03e4e029247007ad010093c35674da71f977640340081a190658e41c820f141b0fc33f8926c218b4ed609366a02249bb2d19ce3ea4528dbece68eead926b7916689c643a9e0d643387521fea2f693c2d6efc786ee46d9bfed3eff2a04669edf5295ff057a60bd865309246d3bbbedc1efef41d63a8dec9ab4fa7dd4510fc3c69234ca186e2d9c003b7a67bd034bad0a5bb96e25d575267889cc1b54446d9bd0a37bfbfbd02925945a72cba8dddc48b3f87b1e58f23c623f292bdb7fa7cf38a0a5750f54ebba56a9a67fc516b6d6fd3970ea9234677c8dc7f38f6e4640ce282d1ac4b16bfa72c1d2bad430cd1ba822061865f5007d3daac19cf547c189357d561bbd3eee683c62cd786e9b73337b8c7bd512bd39f06adedec2de0d5ae639da372e6485363107f97767b505cee755d03a5e58ac228659af123184b7b733322e38c91dbf5a943ab3d52e64b49ee755d2e64950e238e35f10c884e17cbe87dc540e6d7509a4f110e9f7566a471712850abf6ce463e6280bacea36fd33a4497f773cf32c698dcc4beee33938edc7ad05534aea683ae61d64c4d2a69b6b88d16d5ca5c303f3e386cf61db140e27b5e99e96b64bdd562b6b30aa36c6c37cac7dc9eec6b42c1a66a962fa70beb6b516d0cbe76322f86c78f6c66831bf8b5d5d2dfa35a5dce60b1933b6ce3c788769f2b331ec1b8fd2831b79649984b239773c1dc68129725c1c640e73400ec781d8fb1a03c4a85d0c8582640257bd01e51fc42236263c9c67be280429c6037eb405dbf5fd682c2a0bb976cf07d3fc5009279ef8ec4e68193a9902b28e7dc71fb501d95b098e0f6dd9e0d0049131019b047b8390281bb292484e47c8500c4f242c3076bf704704739a0be7c3febfbae9a5daf23cd017c7e19fb107bb67d0f6fd6837cd2757d1fab34f4f05e37dde630b1c3a91edf4f7159103d6eb7da65fdbdf59dadb5e2460ac876ed9e1c8c060f9efe9c8a0a75cfc42d5742d2ee5a7e9dbb494b6d6b9bc930cce4f940e3cd81ed4160e98f88315e689fff0022b57664199cc5196f0c7a164ef8f98cd0589baffa68590985eb15c0db1985839f6c2919340b69d03f5285bdd6f4bf021424db4329cb153fccc3d09c76a090d3340d2f479a7bab3b38e2924e5e451cfd280d7dafe936f6c5e4bd89813b02a36589ce318a0358dc35cc4e17f9bf234cdbb78fa0c607a7340e6cec20b1596610c6934b8323226379edda81da8dcb9ec40a042f50b5bb21645473b58b11dbd7bfca8304f8add5d67a9ea8ba5d8ea72c1a4d8a952f10f2c920e368cf71e99fad5833dd0754d6ed66bdb2e9a91a5babb2a310465a57c1ddc1038e7bd5171d3748b8d46ee1ff005298dc6a764c27d4eeaee7fe1c01795881c9e7804fe940dbe287c4b6d75a1b1d1c986d62277c91bf131f4c0f6fad0663737135d3b497124924871f98e7803007d2811dc5b83903dc0a0333f03be7de8122df2c9a05a11e5f51f7a05ce7071804fca8033e5da0734020b0183bb23e5416269577ed0e5323078ceeefdff6a03dbcd62914c2f629a47c622689800879e4fbd046f9d8a2a03e31385c0e73da8b83ca590947dcaead8208e73da8849b3e19ce704f7c5015586d006431f5cf61f3a04ee586ff002481c8fe6191408f0011eb8e30682774dea9bbb5784492ca6385832e1ca95e3d2834be9df8c312e2db5eb4375080337000f1303d18763591a469baef4d755989ec6f6dae5a23e20b599406dd8e080ddbed41272f4dd8caf1c86d163910f9595882a3d718a035edd695d3b6a926b57d0ac65b10b4e06eedd863bf141077fd7af2782bd3fa26a1a8891d57c630948c0279393dcd04cf5875258f4de9f0cb7b7b6d66d2b81ba752d85f5214724fed41036bd79d2fe319d7a8f4b9c81e58de2f04827b9ce09a07a3acecf54b790685ace8697606009e52c377b7f2e682b097d7d36acf0f55df5edbdc0977412468cb6ce3be10af3c63b9c8a0b0751f505be9690dd5d752436f62a3fe4c6448f3b7b0c64e38f615734651f107e3045ac42b67a7693018633b965bc1bc838ee173807bf7cd33065baaeb1a95f2c11dfcd2bc51fe48880aa3e8a062a8b059f595df4ae9a74de9e9ec499d43c97b1427c6e47e525bb63e4282ad3ea3712893c599dbc4259c1627713c927de81043950df97db1406da8411c92063be280230839627078e79a0390a71b5bb5003a8c1232338e4507025573e9fbd02a0e41dc0e680c3691cf714053bb34160895dc16f291d98d02322aa39f3e14707ffaa06f202a5bb0c7201f4a343aca51090497efdfbfce89840c8db8e46573923ff14410b00490d9f5c1a0425dd8ce4673e873cd0265e4dbe7041ed814009b8cbb8e5863bd07163b7716e0607b6698060b96b7b9478dc8643918247ee39a60b7e97f133a8b4e0c63d4ee597380923970a3ef4c0e13e25dfcfab457ba95bdbddb212016501867b9cfbfda982f907c74b282da34874a9048aa479c83838edc62982b7ac7c42d235cd67f15ac5b40c366418a2cb0c1c81e6f5e31db14c160d035de8cd4a3f18ea96562cc37359dfe9cac887fef039fd6b39446f56ea5d13a9dca4579a922496b1975b8d22dfc3566cf9557230703be715ac1431d4d2275325d7fae6b4f6f182a93ef1e32a9f41938f6a60afeb1a95c5fea53dccf772cf2c8c489240031f627e7565c0d67bbf160487c1801073bc0c31f91f953420f2bc8c7c52cc540032738a809905c0f4fa501940208e73df34028e703938a0577ae013f4a001300db4f03b71407461ce0502dca8c9c7dcf6a003fafcbdcd0070bc1e0fd734070db467b8a04cb9c9e68274b93bcb1daa40200ed4099765249ec476cf340849b8b264823bf34689ee009cb671df1409bc8e8b8e770e3ec68984d9c953cf97be2860b248caaebc107dc67f7a184c31232db88fd451031ce50e76039f5c8045026efb8f93279e0fd680b239504f0483d88ef409ee25bb90c79c0e050151c6e21b39ce783eb40adbcc2cefa17bdb61322387781c950e3dbdf9c8a066f28790b22e013db3dbef54726081e63c6460d34191b1bb0720f634060e7600412c781502409c8e3d7b500ed71dbef8ed40243f181c0a02e5d4e0fad006f644e4819e3b501f7e3049e7b501bc43b4e391da80558003392d40a23305e320d02e64cf998e1bf5a032b0c927b8e68049c8c8e71c6280377043118f4e680bbff00de0504ddbb3128371c1c64668024e59f3cd02521254e4fad1a2107e48fe6a6809ddb9e78a029e1463d05027ffc744a6c3857c7b1a205ff00e637fbf4a02b12b1794e39f4a02024e7249ed409924720906800005173fd7404989698ee39e4f7a04cf723d07a501fff0097ed406ffe36a018ff00281e99a037f4d0731f3bfd28007e53400ff99a810248c0cf140bc60123233cff008a0557f9beb4056eff007a07109243e79a03778b27bfbd02b128c27039a054001b818a06609de793da815006070283ffd9}\par}-{\pard \ql \f0 \sa0 \li0 \fi0 lalune\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here is a movie {\pict\jpegblip\picw20\pich22\picwgoal400\pichgoal440 ffd8ffe000104a46494600010101004800480000fffe0050546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d6265722031393935ffdb00430001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffdb00430101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffc00011080016001403012200021101031101ffc4001a000100020301000000000000000000000000080905060a07ffc400231000010501000300010500000000000000060304050708020001090a11153976b7ffc400160101010100000000000000000000000000060800ffc400261101000102050109000000000000000000010200030405061121b33134365154717475b4ffda000c03010002110311003f00a90cf388f366a62aa720ed6ae07f96901f3831d973452b8cf36fe3570fc908e46d466433e5dd954f2e96992d9e498c7753faa44916e016ca91cc7d88b38fe60a5b97737defcbcc539c98d336a57f4fc2ca9a486bf07ab575ad9a3af4df221d8215e36df86c4504ff0024574551b3d687ee0575757b3ad64e311ee62bd94158d37e24198c43973099f1fc0c41614d950246513a081abf76cfe7061f6863281e6352fd1670949c148dd6dfb0d25f5b3689b1d5c965b0eacbf4e0932ad28e22ab9ae945633f4744bd3c8cee0a7fdf085b9000f449c5f7afa30b83e0b6fd7b0c8429c9467ff9715347c891e25fa24a205861aa715e6a09bd0488237dc2723414d9891381524e8ca7c0894664f835653631ab55ee7e3de433e4ff001b30949124e4c10c8b6ad0a479b3f9c937b2cf5bc0095ad600a0a41a0e9faee174a1c605e161c6c7a313539650b0113190f1a8368e60d5b24f30ff008ea7f0bf867fa6595feeb6978f1fe0f9c26177f4d63a51a9235184750e7d18811339cd000000c75f000e00380380ae390c350def826ed42ad051fa6f501c50f9b699c3b69cbeb76476d202bf3ac985b6e0e968be66572893e6a744540bd9722e5c87956848629bc2559306bd113e8653d3b6aff651dfad7a3ac8b02958cba02a93ccf525757039bae6cff090e1d90688e8aa233ee86a4c4a3e0586d6b2340522e47dcb7d0046d8a5acb05a123ee25d2b230b2ada6e2e2f9ede3c05202520ec2487b0d56562529d8b3393bca76adca4ec1bca508abb001babc007915d84fe3dd14e207e3c62f8379da2a3b861fb6629d28dba53b6ea388ebfed866bf6dfb553455e91ed547ae92e9445253a4fdf3efb4f8ebdfbe7d3c78f1ee0bb9e13e358e942a4ed49e22cff00eeb35fdd7ebfffd9} icon.\par}-{\pard \qc \f0 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \outlinelevel0 \b \fs36 Footnotes\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Here is a footnote reference,{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.\par}-} and another.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 Here\u8217's the long note. This one contains multiple blocks.\par}-{\pard \ql \f0 \sa180 \li0 \fi0 Subsequent blocks are indented to show that they belong to the footnote (as with list items).\par}-{\pard \ql \f0 \sa180 \li0 \fi0 \f1 \{ <code> \}\par}-{\pard \ql \f0 \sa180 \li0 \fi0 If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.\par}-} This should {\i not} be a footnote reference, because it contains a space.[^my note] Here is an inline note.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 This is {\i easier} to type. Inline notes may contain {\field{\*\fldinst{HYPERLINK "http://google.com"}}{\fldrslt{\ul+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Auto-links should not occur here: {\f1 \fs24 <http://example.com/>}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 or here: <http://example.com/>\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Images\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 From \u8220"Voyage dans la Lune\u8221" by Georges Melies (1902):\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 {\pict\jpegblip\picw250\pich250\picwgoal3000\pichgoal3000 ffd8ffe000104a46494600010101007800780000ffdb00430006040506050406060506070706080a100a0a09090a140e0f0c1017141818171416161a1d251f1a1b231c1616202c20232627292a29191f2d302d283025282928ffdb0043010707070a080a130a0a13281a161a2828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828ffc000110800fa00fa03011100021101031101ffc4001c0000000701010000000000000000000000010203040506070008ffc4003e100002010303020404040502050500030001020300041105122106311322415107617181143291a1234252b1c115f016336272d1082443e1f1265382ffc40017010101010100000000000000000000000000010204ffc4001b11010101010003010000000000000000000001110212213141ffda000c03010002110311003f00dadd18a10a704f6a95ccc57e37750782b0d8d9ea0cd32e7c5446e07e9f4ad723119a7b89e61e348f260719278aad613cbb640002938c76a182b264fc87bd13009c0c019c76e3d68a072e1cf6f4cd502d330c28269a61bb39c923923d4fad44c08dccb95cfd28b8280769ee08a263891e1808739e4f1d8d149392172cc714050dbb9fde8960ed8c60b79b1ed44103b05c331dbdb1dc5026ac1946d20ff8140aa631c773ec738a0346a003bf93e9cf02801895e7b9a01886796c923bd0090a06393c76a0142003ce3d86680d8dd9392303f5341ccc1b3cf7a2c812c37e4923d381429757013209fa511c18146c9247a0f6a007900c0c671c6280854e086c673eb45c27c038fd68aedff2fda836ef881f136f25d5e6b7d1262964aa02b03f98fbf153131935edcc97576f35c33349212cc4f39f7ab26186dfce5b200f73451f7600dcb8cf27e7400c0b291914046c9e0718fde81371b8e7273f4ef4007691919240e714097f31f376e7b5008caee27807b0f5a02c8e1b3c6d27d33cd0201d839523144d1a149ae084b78da47638211771fd050d582c3a0faab5119b6d12f8ab1c06788a0fd4e2ac356fd1fe08754ddccaba849696309e598c9e2103fed1dcfdeadc44fea5ff00a7f956366d375e492403ca935bedcf1eea4ff6ac68a55efc1beb3b552574f8e7009ff933a927ec715bc82b3a8f4d6bba5ca1352d22fe061cf9a0383f71dea5119cc6c0baed3eaac0f1fad40897dcc3d81f7a052366c1007df3400f21edefc5008c28f30c9c5170ee4fc37830086395250a7c66770c18e78da31c0c63de8609b41f7c515c5172a30c3b76344a3e377cb2339cf7a242aea89808cce368272b8c1a2e107c672a49f5c1a181c9c7ae7da8a2119e7b1f5068099ffa68258a132062d8f9e0f34059502b61bf2824e681bb297ced2a71efda80f19c47b9c77fdbe74057c13e539cf3c1a0eeeb9c73f33405ddb4f18249c1e28062b79ae242902024465b9214614649e7bd0362a7249eddc513456e5720f38f5a1a98e96e95d6baa6ebc2d1ad1e65521649bb469f563534d6d7d31f04347d2a2fc5f535db6a0e83718906c887cbbe5a9a8bef44dce9f731ca9a2e89169d6d6f2184b1455dc07b11dcfeb4d16f119c649a681285b03d3e5500f87820ff006a0e098191de80ac9b8904647b55d11da9681a56a31f87a869f6970b8ffe4883629a289aefc16e92d441682da5b098f21ed9f033f353914d19b751fc08d66cc16d12fe2bf45ec92ff0df1fdbfb559ec667aff4eeb1a04db359d3ae6d40eccebe53f46ec7f5ab82263da7dcf3eb5174e5181076918c7de869503232491ee4515c1803824f03b51287f30e0e7d803449494832c157278a2e8c71fcb9f9d144639236824d01e142efb1768cfb9c7ef40512a818de78ff00a682518e7cc30ab9e00a02cce9953247bd41e467191ed9a04205ee99da4e4e3d283a524b0427b5026c18a8e082067db8341ce0e39ed409b6502907391edda80f2dfdc496f0c124ac6184b144cf0a4e338fd2894f7a7342d4ba9b568f4fd261f12571966270a8bfd47d8511bae85f02b47b7fc34bac5d5c5dc88a0c90ab6c8d9bedce3ef4d1ad691a6dae976a96d616d15b409f9638d70054a1dbc68ea51d4329f4619a8022b78e04548515117b05000a035c5c4702a995c26e3819f534047bcb68a458cce866719540724d02e41c0f7a012a40f6141cbc8e7bd01719e38e6838af1c0a04ca8206d3cd037bdb082fad9e0bd8a39e0718649141047d0d5d18f759fc0cd3af164b8e9999acae4e4f81236e898f7c0f55fed574615aee83a96817ef67abda3db4ebdb7f66f983d88a061bb8db9e3d45165076db83c1f950a53780d8247c80a2398f182724f1c7ad080c608cfa7a51a0062adc7afbd0130173bb9c5070f071cb37e82826106e8f615e01c9e680d6b35bc534be3c1e3831b2aa962bb188f2b71df1de819ae4b1048c7f57bd01a58268e332642ae0704f7cf6207af6a01b99e17b7b6416e227407c494139909ed9f4c0a04a4e501e0f1eb40d263e53dce7fa682c9d0bd13abf58dd6db18bc2b157c4975270ab8ef8f563f21447a73a03a1f4de8eb031582b497328066b97fcd21ff038edfde88b7e32703bd64188e7e6283864b73400cd804b67ca3268317eacea6d56ff005233592f8b6303f953fa4af7c2fa93417fe98b763e0ea171297bab98558068f695ce0e08fdbd281e5c6a57ba5e9d14d716ef7774f2ec112601da4f27ec2827ada74bab559a20e148fcae36b0f91140283729c77a0e0a7777a01dac68395719e39a029607cb901b19c501480ab9279f4a086ea8d0b48d76c0586b7143224a76c61ce1831fe93e86b43cd1f12fe19ea7d2533dcdbeebcd20b612651e68f9ece3fcf6fa5067cbcf20ff009a051724905411e94032799060723da8406d6c67e7ea68d0e1770fe5cfb5026c37039ef9a02eca098c91e6e01e71c500b1d8a49c12786cf6a06a4e256008e3d050119958007920e2801154e32fb4120927b014017eb1c523ac5209a356215c291b87be28957ef853f0d66eaa99352d515e1d190f947669ce7b0ffa7e74a8f4be996569a5d9c56b6704705b46bb5238d42851f2ac875712bc70b3c30f892019540704d01ad2669a0491936330c95ce7140b2e4939a03638c7e8680ae485e33bbe540d60d3ada162c90a02c7270a39340a4f28b68da4645007a8f6a069a746f73235ddcefc391e12b2e1916824948742c99382473c73404791c617695279dc0640f9502c578c9efeb4095cb4cb0830ba21cf999c6401f4f5a05061d430c8079a02e03b3004311c7d281b5e3cd676c65489ee594e4aafe6c7ae07a9a0a075bbea3a8ea96f047d3935ebc404f04ad29411e08e011d98fed416fd212ee5b05b4d5ad6300c615807f1171eaa49eff5ad418c7c55f8466dd66d57a521f20cbcd66a7247a9283dbe5418a63862479877cf1f6c5008e400bdf1ce684016fe53dfbd1a73794600e08ce3d6800377c8c7d6800a9cf75fd4503d91492460f7ee3d28247a7b459f5fd592d22711c206f9e563858a31f99cfd050583518ba75247b1d134f9aed21396d4669769931dc01c003f7a329c4d17458ac5b55d36c12e040a3f1da75c1cb04ede2447f7f6a94567ad7a66db4fbbb29ba7d65b8b4bd8ccd09c8231eaa07b8ab04a7c2cf87b3f53ea8d77abc72c1a5dabe2452bb5a561fc83e5ee7e541e988218ed2dd22b7855228d76a46a00000ec00a510bd4dd511f4fe84da95cc31f880022da4902b1e7d3e99ac86fd03d631f565b4ee6d4dbbc649009cab2e48c83f514165b8b94b6895c44f279c280839e78ce28178ae6de46748a789e453865570483ec6812d42e85a421fc37918b00a883924d024c6e99b7a2a966c0009e17dc9f9fed40f81c77e28139218e4ff9815b9cf23340a01c907b9140201038ed402fcafd28386464e4fd33c50272bc60032609cf00fbd024f722dc66f24822ddf972f8feff00e280f69b24844919cac9ce7de83a447f30ded823007b50459d6ecacb528349b979127651b1dc795f1f3f7a0990148054823dc5015d491c0a0c3be337c2ff00c489b5ee9c87172016b9b541c49ff5a8f7f71eb560c1fc43e0a47e1aa94277310431f91fa551c1727f29ed409b641c86e31839a3454805739c1f6a026f1fd740f64665fc8c31cfde82db79bb40e9e8f49b62eb7d7e8b717ec832c91ff247fa1dc7df2281bcc9369d671493c422b7911654c1215f92bb8827bf068624ba635392df5eb4b9924558ee5bc19b71cee43c6dc7cf34c657be8db0b0b9d0f51d2afe668934dbf9628ddb8c2b8c0073f3a80da37546a7d25174fd95dc125c69f7313ee5655dfc313bd483cf07b1f6a68d5b48d5ec758b612e9d7293211c8fe653f35ee2a084eb9e8bb1eafb3582fe496278f3e1c919fcb9f97ad03ee8dd017a6741b6d3229dae161057c5750a48249ec3eb4139238568f6a9e7b103b5037934cb3793c610a2cd9277a8da73f5140ee38f6280c4b11c65b934023006d50050030e4647de80c846de3b500fcf9fbd0197273ed4007b91400e580c8e45074a82400e72682b36fd2162b7f25ddc09af2766ceeb872db79cf00f6a0b3229550140e07007a50092db860673de818df473c862686dad6470d9cce3b7b63e740fa1de6252ebb5bd81cd00bee2d800d003a6464004763ce683ce9f1cbe1f1d3a67ea1d1a30b68edffba814708c7f9c63d0fafceaca31e6dc71e1f07daa82608c83819f7a1a11ce149238fd68d0a579ec682cfd27a7c3a86bd10bc38b3b756b8b93c1fe1a8c91f7381f7a034f752ea5aa5c5eb292f732128037619c018f6ec282e5a2cb047abda74d5ce9b6da80f136de4a496219b3e48c92000323ea73467519d3da5bb757dbda410ac90c77c23058f99007ee7ec31416882ee47d23acb5185caf8bab4691b1efe57fff0038a9457ee75a82f6e7429350466b482f2742c0f74241c80c38c64541a9cfa1e89ac0177d33ab3d8de28f2b5bca429f91140e2c7a9b5ae9fb85b6ea9b46b9b3c796fe040768f76ec0fafb1f9505df4ebdb3d4edd6e74db98ee216fe68ce47d280648f75e2485a44da385ddc13f4a025ddbdbea16a633286566ce55f9c8f6c502ad750db2c514f30dec428247e6340bbf04100b73402afb943ed2b9e30683836defe9403bc1e06734020e06280cafe8683a375941d841c77c1a0151b467b50159f00e4127e5402872371040c5046eb5aadbe9b1c02e2f6dad25b89047099c677b7b0140fe3f1010afc803f3018e68160c3041ee2823f5dba92d34db89a1d9e2843b03b6d05bd013560c1748d57aa2797c6b35bab78e6959dc47231580ff336dcfb03c1a58364b5bbb7d7fa7b7427f1f673830c8664285bd1815238fad20f2c7c41e979ba43aa2e2c1cb1b663bede438f3a13c7dc76fb5515e9065b851f7a02950002a09c51a1b83cf14176e90d3645e9ad7752752aac23b3439c066665c827e944d29a6410aea725c4567135bd840d3c88a723728c29c9efe6c50d3ee9545b0bf8ef2e6e3c2fc2c6f72f2920e5f19039ee4938a9a875d03278377acf52ddf867f036ef71923932bfe51fbd3475cdc369df0db4fb389d4ea37970fa9cc0b00511795ce7d4f181eb4cd2451755fc45ac16d637381b14ca36b641dfce723e4053170d6cb52bbb362f6d3cb19241f2b9029862f09f143549ba7e7d2eef6caf2797c66ee17fdfd69862d1a069da7dfdac579d17adcda5ea9e1a992376c4723e39e3b024fd7e94c458ac3e25dee8d31d3bae74e7b79002bf8b8549471db38f5f4ed4c165e943a06a328d4ba605b4b22a1523c420c64fbaf38a82d36f0ce7cf7463790729b53017e940e0b0ceceed8ce0500e1b70daa08f5c9ed41d271cd0132476e7d7ff00aa069797d2411168ed9a41fcc858211f73c5075acb25ca6fb82aa31e58a36c81f561dcd033d42169e158ac64b98151b3981c2966cf639f4a064c7a8ac55e4865b7d493701e1c8e52403ea3cbfda827e390ca3f2c914aa81991bd281cdacc2747215c60e0ee5c67e940cb51b0b2bcbd824bfb08ee1a252d1caea1821cfa67b1fa504982b2283ce08f518a08abb82f6dd0369a5662081e14ce40c7ae1b04fda82275cb0bfd4f4536f7114589a5412461f3e4ce4e0e060f63f6ab2893d3b4b5b5b78e22ed22aae3cc3cc7e64fad3449a22a461500007602a0cd7e3b74c26b5d2ad79147baf34eccca40e4a7f30ff3f6aba3cd0543267eb5427b86f1f4c76ef45d0eca1ad5ef224d13e1cf4fd9b22192fa67bc955f8c8c617fba9fb510d7a6ed3fd43a735e5b54964be658c048fb6cdd9e7eb8a186bac97d174e6d22e23437b7ac26b95e77c68bf950fa7279e2b22dba45b59e97a669fa4ea36aeff89cea9a90451fc355ff0096ad9f4ce3f41570675d4fa8c77da8de5cde5be26bc653171ca47dc1f6c9fed5562b97f70276808da7c24f0c1c63804e33fa8a2928c0e0383c8f7ed41d92a41393f4a2548595c2c37493db4cd04e8a08f139566edfef3445b6e7aeaf65d2df48ea2b11776ae02a93e564c772adef409f4ee8ba9a21d73a36fa579ad9f325afe599171ed9c30a960d5ba0fe2843abb47a6f510fc26a4c36890f9558fcc6783506a1147b510024e30339ce680d2c6ae9861eb9a009178a0205443b989e39cd01d8075e3047ce80563057ca381ed4011c4531e503d85013c91b804a21279c903341131cda8c3abdc8650f6d20c4321232adec3dc504bab2c113c9293bb1963df3408dd4b75e1efb2856463dbc43b4631fad047e9177ad4fe32ea16b1db4b8fe1aa92571f5f5a0916bc8e0895af5c46c17cd8c9ff7da80f6d736f7f6915c59cab35bc837238ed8a072a31c1ef4062870718a06f7702dc5b3c522ee4752ae0fa8230683c75d6ba3b74ef535fe984929149e4278ca9e47edfdab42058003763ed409f88ffd6dfad06b1f12ae612fa0c76e0b471e9916d23f973eb4158d3efeff004a984da5debc1295d8e4018dbf3145d583a2ad96f356bbd7f5d90dc59587f1e79a6392f28fcaa3ee47159444ea3aa5ddfc7acf50dcdc344d7a4dbc317f52641200f6000fdeb41b5ef51d8eab672ffa9e971c97c11638268e431a46000012a3b9a351567db823b11f3ef40948e428048207a8340ab48ae83cb83ee0f3428a982719edf3e68c9cc97d3fe15ad8c9be138f2bf38e7b8f6ef40f7a5f55bdd3f56b46d3649127f1405f08e7249c76f5fa50689d48ba5f545cdcbdb462cba9206411b2b055bb07d4fb1c73528d4fa8f52d62cf47b6b8d2e65fc458c49f8a818795c151939f977a823ba0fe253750eb7fe937b04293f9f6c90be41dbdc7ff006283473c1efc1a06f69776d73bbf0f2aca32572bc80470450284a46dfca19f819f5a04e799614def26c0bdce09cfd85045dc75769d12dc3c3e2491db0dd3c85195235f7c91cfd066ae0cdba9be31f4ec61a386c1ef9d4ee473e45cfb1cf34c101d3ff1ac9d481d46c628ed24751881880833f988e7b0fa5328dfed2f2def2ce2b9b79925b791772ca87208f7a60182ee2b95cc0c48f53823fbd40ac658b30f4f4a086d4ee1d75bb6b78f4e965596366fc5211b23238008fde81f43692da5bc30d97831a0397dc09e3d714087506bf61a2c4cd77324726d2caaec141f9fd2ae0c435bf8c57173ad7876f7a2daca10489121244cdf319ce3dbf5a834fe81f881a6f57bcb6ba7c53c72c11873e28cee1db391dbef4199ff00ea4348116a5a66a8a8a04aad04847a90723f6ad7d18c312ddc02a3815423ba0f63fa541687bd9efe1b533b3c9e0a78473e899e318a09bd0ba6eef543e3b2bd8e9b10064bd9e4da001dc81401aeeb29a984d0ba7d5e1d06d4e6594f06523bc8e7f5c0ac8af752dfc17d7090d9218ec6d9447129ee71fcc4fb9cd6842ab10dc0014f3e5a2c1704b671dfdc734525226dc939e283a362c7f940344a380393df144733e2276e38f5efcd01b4bbbfc3dda4a9298a44395902e4a9c70682660d4265d62de40b1bdc1545054f95c8fe627df141af7c3af8808f3dd68dd5d2a45765884b8908d8c3b6c27b7a77a945d7a5fa474bd2ba8e4d5748b28624955d5d8b13b79ee9e983d8d40a753758c7a46b96f6114725dc92279a2810b3a64f94900763cfafa503fd3b59b79ed84da34713c0cd890f0a158fa1f981de826e1b548959fc4dc5cee24b6467e59ed4101ff19e9f676baa5d6a72c50adb4ad1ac790ccc076200f7ad41e7df881d79a87576a5f87b0f161d381db1c2a36e7e6d8ff3416bf87ff082c6f208ef7a82f22b9761bd6d619785f6dc477fa53705ab57f83bd297ceb1e9caf67708db9c4526723e849e3e94f212dd25d117fd29a8c09a76b534fa39cf8b6b71ced38e36fb73417f52e64548e34007e673e9f21ef590a1c918c90718dc281a69b68f67118d9da5058b798f6fa7fe280daadd1b2d36eae70710c4d263df0a4d583cc7a668fd4bf11b5837d7c93dcd9a3146959822a0e781f4cfa55161e9dd7fa67a4f55b9e9aea3e9f81fc09ca0ba118998fcdb2338c7b528d39f4cd2ba76e2d357d292df4eb391809963420ce1b1b576fa1e7359119f1eb4e17dd033ca172d6b2a4df303383fdeb5c8f2eef3bce4e0e335684cb0c9f354160d36f64b0baf16072b91b5f03391f43c51aab23a5debe91c4fad4d73689e6fc3a290573ff4f03e59f4a3280d67581ce916567f84b58ce0a1fccec3d58fa9a084de08c90464e4d1a8e419059b201f4a05630a176918efc50176293872c17bf14042aa0125b03db14046c60b60123fde6827fa0c68edd5365ff11346ba6292ee64194240c807e59a32b7fc51bfe8bd5ed5db424860beb62b89218422ce09c11c01dbbd0660ae110bf1bf2154838dbebfefeb41a8f4cdac7f117458f4d9ecd2df53b4cf81a822808c47255c0f7c8e7fb54a2ec2cfabba3b4b4b8d3af12eedad40926b0f070a13f9b633649f7a82eba6ea4357d321d4ecad512daf20df26e016507fa4fbfaf3e98f9d067dd2bd2faac9aa4d72d72d1e9510ca46a7631c7a320e18f1dfd7bd059afb7da816d23de4ba5de211346a1e4785f190548e4648c63b64e6b43ce9d5baafe3b539c5b452dbda46c638a167cb281c73ee4ff9340e3a3fa5f5aea4ba58f4bb57dbfcf2b02a8bf7f7a0de3a5fa0b50d2a2d92eb3e048c0a97c867dbedcf6a944e5cf4f6b76d1b3d8ea42795066266c87c81c65b9cfaf15048e83af3cd64abac08edaf01546c38dae4e0657ee6826e5b892de3702292e2545ddb55700fd0fbfca81c4b3bc718716eef9eeaa402280d14ab3c0b2c65c06fe571823ed40df56b217fa6dd5ab9216689a33f2c8c558307e83b8d77a37aaa7d22f2512c28768800c9954671b3d33ebef568d0ef7a7749eb0b5bbbb162d657b32b46d2e1564c8ed9c5644d1b0b9bbd261d2a440af6cb0e2e5b1e7dbc1238e0f7a0375b696daa7496a3a4dac8a92cf078685b271db04d391e40d5ec4586a1716de2a49e0c8c85d3b120f715ba1899173ff305413070abd89cfe9f5a2d3ee9c8639fa874eb6b804c52dc46b20c9f302c3bd11e84d47e1af4d5dc6521d3e3b662c19a58721ff5a9a321f89bd27a374b456d158dccd34d333332c9b4b2afbe47a7cb1f7aa33d2bc0d8c0f1c8f6a2c14b6d501b39cf63450897380c319e3de8065031c038f7ed40d8faf1ce41e4d004876a8dc3cc7e743025c956c818028c904579e7f0e15695c9c0541924f6c00283d0bf07f42d6b48820b8d62d20b2b58d656404959e52f83c8ff00fcfafbd4a35bb06f12391a48dd55cee2b2f3818ed8f6a8158a159890f02242079147623e631c502b0db436d1ecb7458d4738038fb0a087d6eeb508f48bb7d32d95750752b6c26c905b3ddb6f61eb574794f5cb6b9d0fa9678b512b25d24bbe52b8c1638278fbd582c57ff12afaed45b5bc0d0d8a8c08a2731ee3eec5793f40450466a1d59af446293c186cd53ca0c36eab93dc649e49fbd048e89f1675ed35e301e293919dcbf9867b37cbe94a35fe94ea4d33aba6824306dc48015750d86c6e247b0cf63591a40b8dc23fc30f14138dcac3000f9d03687547f12e8dd5af816b13148dddbcd29039c0f6f6f7a0eb5d62caf5636825db70c9bc4328f0dc0271c8a090627d3073ce681acf6505ccf14d35bc2f2c2731bb28254fb8a075144a83ca806792400334049ee6281e2496408656d880ff0031f61fa50446bd76058ea1b9e21025a3bb48afe71df9c7b71de9c8f196a0de23ca7b827d4f7add117e0cbfd4b5059392369663ff004e71c51aa97e8f555eadd258f2bf8a889cff00dc28cbd0bf123a926e96d163bdb74490bca2321c678209ff001591e71eafd7a7d7ef45cde2c20aae144638033fb9ad2e1b5e69d058da431ccf21d4a5c3b4631b62523807feaf5c7a50222f2d648c25f5aeec8c2cd19dae3d3e87e944d3eb7e90d425b49ef2292de38224f1505c3f8724a9eeaa7bd0d57a60406059436306868a7803839c7ad1a158039c13f4a33a716767f8cb9b6b55e1ae2458813e9938cd07a9f42d0b4de99b4b7d1f41b58ff19b03c93ba06607fa8b1f5f619a5b8266d74a65d42da6ba90cce996dcdc8c9fff006a5a2c2635083b05ef83eb5028076341db4b1ed9f7a04651fc41db18ed419d75b744dbea335fcb0db0335f2057901c05da73c8f9d5d18a75174a3f4c47335e35da4ce418a489374254f707d463d33565d1529b569a489a17944b06ec8057d71dcd037b4b6b8bfba31584124b27e62a8a4f1ea68357f83da7ea5a76bfe0912453ccabb49194653cb60f6ce3dfda983d196cd108c2401711f9768e306b2297d73fc6d02773a8b591922693c5004bb9d72542fa2f6efde8314ff867aeeec27500b77bb5670e36ca19b1dff2e7f2fd2837ce8bd5dd348b78b552219022870d9c46e792a4f6c608a0b846c8e03232b29ec41cd0199f1410fd4b24b1e8f712c0a5e4452d851e6c639dbf3238a0afa42ba77475e4ba8470896681da45180b18da76af3c9029c8f26dc1df2b9c606e273e86b743331924f27f4a82c12280e59b008e79f6a2d4d74188ff00e30d203a82ad7519c1ff00b860d11ba7c5e86c9fa3afae6f4091e043e021270b21e01c7dcd6479ab4dd3aeb56be4b7b184cf2b301b57d07bfd2b4bad0fe25e9f6960ba7c7a55ac50cd750335ccaade7723b83b8f6e38a2207a5ba4e7ea3d93780cb616ca53781f99fbff009a0b675a5be9765d43a75a6ad3b25adb4185429b831c70303dfdfd2831eb8954ca48f3827819c71ed406b2b1b9bf9a5fc1c4ce2253238047957dc9345d122b792eee522811a495ce1157b93ed444ff0049f476b1aaf51c761345269d25be269259570c833c6077249e062a68f53e8ef0da69509d4ae225b92a04af232ab16f98cf1f4a5a266d4dbca8af13a329ecca723f51502d14f0cb9f05d1c8ee01c91f6a0393b4edfe63c8a031608859b38f97340d84d04e5846eae50f9829ce3eb400fb24466041f5e3d2823f56d22db57b192d6e61468a41c823ff0035651916bbf04ada7badda5cad6d1b72c09dc33f2a6875d25f0865d06fe2bc6d4c4d3282026cca8cfafcfd29a34cd234a10c768f711a78f1bb392a3001208e3ec69a26a58d640c832091c90706a084ea1d3eeafdadf4f86da3166c0b4b397c18f046140f5ce4d04f4702436e91c28a9122e028ed8a0a9f5a5b6a09a1bc5a135bc72cce048b3c5bc15c638f9d59043fc2db997481aa69dae49e1cb6bb643239211939e467818f97bd305965ebce9a10bc8da9dbaa2679dd9ce3d8530572cfac87566ab05ae9f1490692b9696e1f833738555f96793504df5f25945d2576b7ec16dc46792381c7b7ad5e60f234980e42f6c9c56a82ec3eff00bd4124e49700f1c646e3cd169ce9575f83d52cee324347323f6e3861ff008a23d47d4ba6a75074fdcd8ef317e2e2ff0098bdd4706a60c3f4ae8cd5f44eb8fc3e97248a638cbc73bf90483d463b373e9574685abf42a6b5649fea72bbdeac4a8d3b018cfae31f7a6895b6b29b41d30d8e9f6bbed9213e1b7a994e724fcbb5064bd7835a9752d3af75d8116354778f660788cbd9483dbb0a0cd20b2b8d43528ad2088bdcccf854039cff00e2827a0d34e9da1de896f2182492efc0976f998aa827d3d334113a74aa9a9298628e74570478bc0c7cf1da83724bb8246d3e6416b0384da61b5501c9f5c3704f152c037561a95f5fce61d3ad6db4ab950f34b331dd9f4191db8fdcd406d67a675ab4b6d325d1af248272a43430315ddec7038f6ad4b3f448bf47eb71cb69abddebf21d5e26896203846c30c8603b9c6452d9835901405660376319ac84bf13180779d8bb82827d4fb0a06f777367a75acd7170f1430a9f331200cfceae061a0cf6dac692d7365266191db0578f5edf3a6075a6c9278b3433188a467860d96fbd40fe540471409aa0c1140750001ed8ed4058e15133c983960077edf6a06faade5c5b7822d2d926766cb967da2341dd8f0727d85033d27597d62e2ee3163756915bbf8799d71e2f19dcbf2a092b88dd9a311950a0e5b70ce47fe6ac18af53f5b69da9752dd69da9ca906876e24465d9e69881c6ff005c679c0aa2bfd267a347512c93dbb5d42d90d3c800b68c9ce0ec3cfa528db74ad034db5905ee8be1ac728dc153984f3f980f4fb56453be2de8f647a6aff53796596f0aed46798ec033ce149c0fb0ad71479c9bb9dc3bf3c55a0b95f65a825150b481a407b93c0fda8a29c06671dc93803bd131eafd0af6dffe18d2ee25982a4b04603b7a9c631fad03bbe586381bc5945b96385718c827db3eb5288eb8ba934eb15fc3c535f05427796dcccdec7150637d5bd55d5362b7975aa4d0d919018adec8637807bb60723000e4f7cd58203538aefa8aeb478a7b9beba924547b8774cf8608036a80704639cf1f9855d1a7f4c68b67a03de5e5d59dad8d988c62e1c0f107a1e7fdf7a082ea6d07a6e3e99375a7cb6b3db093c727701e2360f7f53dfb50653d4130d42ee18f48b3f0232a15218936963ebf5fbd06dbf0cfa74855b9d46e04b730c6144691e12307d33ea7de8348ba6b5478a279a004f98c479247b81f5a9438805ac0be2e02e73c9ef8fbd40c2346d43578eefc40da7da1dc8b8eefea4fcb9fef419beabf12a4bcebcb2d2fa7ee0dc58492084b30236bb6467dce383f6a0b87556a67a7f4d95a0bbb5468816f0a69c78b2e072572719ce78357079dfab3af2e7a92c963b88d94abbbf91cedc93edf418aa2c5f0dbe2a6a9a0c90d8de34773a6a8da1186d6403fa48fec682d9adeb7a9b4c9d572dacc9a6c9700456e5ca910e000ecbd8e580352fb1ae7476bd6dd49a325e5a9f3025245fe961dea097523cc0919a032af039a006936c81423104649c703ef40dcce64bc3035a87b6f0c378f9fe7cf2b8fdf340a4b6e25962915d94a67807839f7a043586922b5636ec44c061063f31f6ab079d7fe19b7eb2d4efeef55d5d74f992e9a0fc3a441dcb13927b838c9aa2d4bf042c618e178efee6e18104870172318edf5c1e6945bbe1a748ea7d2315edbea3a99bcb190030c401010e4e783ee0fa56455be3d6b90c1a6268d69e17f1486900ee98ec29ccc183119419e7e55ba11f089f523ef5058363a8059fb8e31e9421b491056c01819e28d3d0ff07eea3d53a1e3b6b8db235aca63c139c0eea68ca47a9fa6ef757b83ff00bf68ad428c2f248c7a8f9fcea518df516adac74e7544f63a2ea172f1800291e6cee19ec78cd5826344e85b6bad25ba8fade5b99dae0ee11efc71e858f7e7d054a2d7d39a75ae8f7b6b00b8917f1516624b78429da327cec493db1db1d8540cf4aea28f58d6aeae2f6dd64b498082d880488d149fcea7d4939ab04175e6850a8d32de3b78e380c8de32c4db4e18e430fef543cf86fd0d691b4fabdf6648b3b2db69ce7dd87be68342d2f4fb9b5b891af1a28a2dc05bc5036d001e0eef7352884b961a2ea9aa7555c885e08d45b5bc52b61b686c120fb939fb541276bd4b61d53624d942e2f6200bc32290633e99f4233416dd3ad3f0d611c0c77b632e71dc9ef41156dd27a45addcb3dbd9c513b1dd941821bdc7b558333b9f873757fd69a85e3f813e9c7723b5d93265d872473c11544a68ff08fa75e290b42ec4e4124e70738fa5048e89f0f745d2aeadd2decedda6525c975121183c77f7a945c754d0e0d563682ed43425369403bff00bcd58308ba7d5fe13f5a05889974a9d8b46aede4914f707d88ff001528ddf4fd7edb54d1a1d56c312dab2e64dbc9418e78f5c541296d70b716d1cd6f8789977230ecc280cb7519b816f212b205de4e0843ce300f6cfcb39a0545c42cee88e0b458ddec33ee680eac92266360debc7b5056fad2d354b9b189745744be121daf27e550548ce3d4d58324d07a725e98ea2b7ff5381f5169a7579d021fe13904ee43ddfbe49038ab46e76cf05cc714f6d309232a4a98ce54fd6b2196bb7f2e9b631b2c427b891b6851db3eff002007341e5bf887aa2ea3d4f77378be381e42fdb711ed5a1554395caf1cd07617dcd04fc85402101da791421b49920331381c60d1a69bf02f56f03a925b12c162b98c955f775e47df19a32d99b518268e4491668704a79d4aeec7b7bd4a30feb7e9144d76e265697c3e2693631674273803e556087d76f35fd49859e9925ccf611141106f2e182e3241f727f5a94681a268f79ad1b1b8b9dd66b1c2b1ce9bb06361c1e7bf3fe6a096b0d3ba57488e485b52b40909c386901607d47bf7a0ae758eb69ac4d15be81a748f0a9c35cc90b2eff4c03c1c638a0b77405c5d5d45f87be5fe359a88b81b401dc1c7d38fb50586fed18ea3015790091591e447c1518c8c7a0a0a5754d8c9d49a8d9f4ee9dba0b3b5224b9692327728f627e7c6682f9a7e996b6b3a8b6b748a348820c7720761412c064e3041ce282b5d4bd73d3bd3f33daea97ac2e540dd0a292dc8cd043c1f15ba2a7923b65bb910371b9a12141f9d02edf13ba2ade56857551e5e77244c54fd0e280746ebfe99bbbd655d56dcdc9ce08465565f4ee3bfca82d53eb3a6dac3e25c5f5ba646402e33fa77a0aff5b74ad8757e9ca972844aa37c520fcca7d3f5ab067bd369a8f467544d626c98e9f7118f0200e4465c903049c8c9e6ad1b24334b6fa6249716cab20037c309dd83db03b5640dddac3764a4f02cb1103863919fa7a1a06d6f600c37162911b7b252b87dc773f1927393f4a079f868edae1ae6328a8b1ed38e30050226e85d5dc1f879011b3c47c2f604719f9d01eff4f4b83e3c6b18bb452b1cac9b8a83de80b16e8208a3b7b58e1407cc061427cc0ff1560ce7a8f592d69a97504cad2dac01a2b53900c3e9e51ea58f727d0551e73bfb86b99a49a46dcf21c96340dc13804f20f6f9501c0e3b8a0963316fcc4607007f57bd084d64dec01200ce483468ff0040d525d1755b4d4206ff0095207c11dc67ff0019a18f56584f6daad9dade4211e39104a8ded9152b235cd8c530613229c8c1c8ef50472e81690ee00322b0c100f0debdbb7ca8111ace856371358cba85aa5cc407891ccf83f2ef4048b4ad2e59bf116769672c72f99dd1437239078e2824a4d3e1b94559234110e781839fa0a0561b38ad532a12319c86c6307e740a9732a3a00cac870cd8e0faf0681be8b6db965bb909df3c85806eeabced5a09523647e6e0fef419a6adf116daf7ac34be9dd1da686e7f1ca2e243b76320ce57df9ff1560cc3e3f470ff00c78255b842b35bc6c4af9b6e323d3e95467b6365f8dbcf062beb68c119595d8aaff6e282422e9899b4f6bb5d46cda2562a76316c1078f4a0859e1b9b762c0bf94f0e84feb4125a57505c58ea70dd5d0174a986d92b1c13f6f5a0de7a5be366877260b5d42dee2d2423124a487507ebdf15289dd3fac7a7bab6feded74d61733473acdb5a162142ff00313d81ed505fa58fc6d809380c1b9f5c502e0e05040ea367a85dea454de2ff00a610375b04c16c7a16ef8340b5f6930dce9375636acf6a278f04c5dd4f1dbf4a084e91d06f3a52dee62bbd4a2b882494ced3c8a448063b63b638fde803ab7ae749b2b3096d792c93c8c109b55dcd18ce3710473ffdd043dc758dc5869044565aa5dda4c3c2b7bc78c1f14e3963db03e7c0ab066bf1327d41ba76ca6bc48ecad24c456f6b0c87cf8e4bbfa138c0fa9aa3297c83dd4e28395811cf2680a5b93c7ed413cd1ff0f3c797b8031406645236b0508406f30e68ba49c051b97d0e0e7d28ad57e19f575c5be8f269515dac772877c11bc464dea7ba8c739ce78f9d3193bb8ebfea2bcbd6b5b6b8b58bb7f13c2f0ce31cf0deb4c0f2dbad6d743d2ee99efae752d6c02a86e0054524f6383c7ff94c0b6af274c75149a46a5a82c46f1e1479fc3190bd8156fbe7f4a960bf74e9d253f1167a3ac09e0856610e3041ec7f6c540f67b892cee7f8d18368232ef2af2508c7047cf340ead5bf130accc9b1186541e723d09ffc5033bbb1b82d74d6b37f1244daa1b38073df3f4a08eeb1d3b50d4fa6a5b4d32f12cef1902ee73e523d476fde8306eb0d3fabfa4ba92c278af67bb7281606472f90bdd58558253a6afb40ea1d62283a8b461a66a6f931cf6a7c2466f7cfb939e7b5515fbed3747b5eb8f06eb78d35080a2ec9719c76f98049a0b4ebdd37d1bad869acbf0b03c5c16b29444adf50ded41995f68564a263a66b31cd02be152505493f51c1a088bab69ad1bc179e320f07c37c8a0692b46c4995f0381db39a0b2fc34e971d57d4705bc8db6c50ef9dd97b81fcbf7381528f5ae97a1d8e996d1db69b0c7648855b10a81b80f43c739c54134147b9a036063279fb5046e957726a0f2cfe04915b06db1788305ffeac7a0a00d72f8d9c491c06337533050ac7185cf2df6a06da2da4293488f34973328c34aea428c9ec3eded40ee7d2ad249448f6b133820ee2833df3fde819ea96897461b05b87815f2ee919e5d47704fa039ab079b3e326b70eafd4ef6d6650d8e9ebf868b69c8247723efebf2aa280eb9193ebedc5002a124e015340018fb8fde82cf32b1603d0678cd02406dce3008e47ce81b499c331383c9c9f5a2e9c69377369f7d6f796a4acf148acb83fb511e91b3b3d0bab745b7d45acedd8e3732b71b1fd73f7a5a19eafd09a56a0a96b1c705b49c48510761ce4fcfbd4d0d752826b2b583476fc3daacb295b79d768de8a32b1e71f989e49f6a7d14dd1af5ba275a45b8b093c054492ea769092373765c1da4679fbd306e36ba9595fe9f0dcdbcc92c33e1579cf27d0d409ea178f68521b6b76926ee8a7853f7ff140bc768d78f6f73748d1cd103b543f0091cf6efc502f7319dac194371d8b6326829f0c501d7ae6fa568d5d4942c806d4db81839f53c8cd59456fae6e628749b5bab8b1865b08e4726588ec11e7f2e49071c93da9a31dd4341d675e9a5bad374f9858162d0b4ac70e18f0573df35a0c759f87bd53a404f174f965dfff00f479b1ef570576e34bd4b4cc0bdb3b9b7258a00e846e3f2a94376475cee4914af7ca9150685f09ba61efb52fc7dd69bf8eb7c158d1d0b47bb38f37efde968d6eeb4eb5e91d6ad25b660aee59974db6881690918e31ce39279e062a5a34bb57b88adedd1e379679065d80036679e6a07e8391bce7e940c659ef5afe1286de3b16f2b8903094b7b2fa7ce81eb380c4260ed193f2a0cd6fa5d4a4ea0fc7bdadcce923158a3039db83c038e3ef41a0e96b2ad8a35e009291b8a939d9f227e43bd590436bbd6fa269202c974b7123602c76e779624e00e29833bf897d493e896525dbcb2a6b5a9c3e1456b91b6d60cf989c7f31f7a60c02490961ebcf3eb541308e39e067b507007b96007a67fb50178f97eb4165ce18165c2927b773fad023202d9c8dbb7818ff003408300b87f2f1c107d0d0c15a4f2e339c90467f6a18bdfc2cea8ff4bd561b4b9ba686d6e64552c4f954e7d7e46a60f4688d240af1b2bc6cbf5047ca960617ba658de1b792f2d94a5ab33461b18524633fa1a81b5c8b5168967369d23c0e0a24622dc981d81c76aba29df0bb48d660d52fceb88d069f04aeb69130037127f37b9c0ed9a8350781240bbc06da72323b1f7a0eb8816e633192ebc8c9472a78fa50349b4c83c068e24f0ddbcc1c13b837be4d055b57e98b996d4db5b4a893dc1e6620b6ccf2c467efc504ce97a38d3f4d874bf09af6d46e2f25cb82724e791db15650a43f878b51fc34f3da8f132b6d6a98c80a39ff007e99aba249631b58b9047239ec3e55368aeeb7d2da6f52c0eb7f16e87f2c6e836ba90724ab7a67b55d115ac7c3e8aed2182def4c56a14096368959a423d77e3229a27b41e9d8343b01069c8a8dc9660aa3713df3c64d4a1c695d3d6b67a8cba94b9b8d4e61869e4e4a8c636a7f4afcaa09a485519caae19b966f7a0435196582c656b74df3e308beec7b50629375775b691ac5bdb6b16d6378779f019b00a31cf391c9c2f1daae0b35ef52f5374de88d77aa45a6cd25ddc0108694ee2188c28007603d6a0d16c92430a4b2ed3230dc401855cfa0a0a07c45d7b5db9d462e9ee960b14b2ee134ef8c850012147ec78ab0670b643a2efae753d72686e6e2da211db42176079c8e768f65e39f7aa332d6f58bbd635096f6fe6692695b24f603d801e82823cb900ee00e68006460051dfd680ed9f0c905b713d8d006d5f5419fa505a18f94e40501b1b81a04186d62402c87be3d6810b81290aea8467201231cd1749dbc437f9f1e201db3de8ba07dc0175c027f28a335b17c26f888d6b6d0e8fabf892a29c453b1e547f49f7a946d6424f08236491c833ee0835073294888894120700f0280813c40a6711bc8843e00fca7d3ef40e41dc081f9a811681c6f7565329185623b7e9de812b3bcf11ff0b74563bd50494cf120071b97e5fda80d7577046c9019d5669dbc340324eec67fb734103d5da96bf67a7cf0e916f6e2765f25ddc4c11107ab1c8c647cce2816d3ec7f0f6564cae6e67da375e6d52cc4af2e4fb13ed4145f899d47b3499f4bb6d46cda49b69b92921565c3648e3dd40c81cd5c0ae89f13ec246d3e379ed2d6da180b5d34849da1780b128e49271c9f4a60ba685d5fa36bc42d95c324ec7090cc9b1d87b81ed50588958977cacaaa3b9341c655f12348d1dcb8dc1946540f99a019e2134454eeda7bed3839cd052fe2136b536b5d3563a1ca53c49da4b9507198940ce7e5c9fbe281c6b7a974cf4ee4ea7242d76dc784a3c595b3e9b464e3f6ad0ac745ccbd4fadcbabea42da56959a382ce7460d6b1a93c01f97272093ebf6a82f1ad6af0e9da5cb3cecf6902216919f82aa3818c7a9f4c530649a9f5269ba7429d472239bc991a1b0d3c3152880f0f23039e7bf3de90635ab6a377aa5ebdcdecef2c9239e59f3827e5ed54302195fcc38cd01245395c1f5f4a05b606538e483c501b6939e3b5077860f3914165754c33e549000dbe87de813b820c27fa7baafb8a04a69c98e281e42618c795338033df1f3a06c03e4e029247007ad010093c35674da71f977640340081a190658e41c820f141b0fc33f8926c218b4ed609366a02249bb2d19ce3ea4528dbece68eead926b7916689c643a9e0d643387521fea2f693c2d6efc786ee46d9bfed3eff2a04669edf5295ff057a60bd865309246d3bbbedc1efef41d63a8dec9ab4fa7dd4510fc3c69234ca186e2d9c003b7a67bd034bad0a5bb96e25d575267889cc1b54446d9bd0a37bfbfbd02925945a72cba8dddc48b3f87b1e58f23c623f292bdb7fa7cf38a0a5750f54ebba56a9a67fc516b6d6fd3970ea9234677c8dc7f38f6e4640ce282d1ac4b16bfa72c1d2bad430cd1ba822061865f5007d3daac19cf547c189357d561bbd3eee683c62cd786e9b73337b8c7bd512bd39f06adedec2de0d5ae639da372e6485363107f97767b505cee755d03a5e58ac228659af123184b7b733322e38c91dbf5a943ab3d52e64b49ee755d2e64950e238e35f10c884e17cbe87dc540e6d7509a4f110e9f7566a471712850abf6ce463e6280bacea36fd33a4497f773cf32c698dcc4beee33938edc7ad05534aea683ae61d64c4d2a69b6b88d16d5ca5c303f3e386cf61db140e27b5e99e96b64bdd562b6b30aa36c6c37cac7dc9eec6b42c1a66a962fa70beb6b516d0cbe76322f86c78f6c66831bf8b5d5d2dfa35a5dce60b1933b6ce3c788769f2b331ec1b8fd2831b79649984b239773c1dc68129725c1c640e73400ec781d8fb1a03c4a85d0c8582640257bd01e51fc42236263c9c67be280429c6037eb405dbf5fd682c2a0bb976cf07d3fc5009279ef8ec4e68193a9902b28e7dc71fb501d95b098e0f6dd9e0d0049131019b047b8390281bb292484e47c8500c4f242c3076bf704704739a0be7c3febfbae9a5daf23cd017c7e19fb107bb67d0f6fd6837cd2757d1fab34f4f05e37dde630b1c3a91edf4f7159103d6eb7da65fdbdf59dadb5e2460ac876ed9e1c8c060f9efe9c8a0a75cfc42d5742d2ee5a7e9dbb494b6d6b9bc930cce4f940e3cd81ed4160e98f88315e689fff0022b57664199cc5196f0c7a164ef8f98cd0589baffa68590985eb15c0db1985839f6c2919340b69d03f5285bdd6f4bf021424db4329cb153fccc3d09c76a090d3340d2f479a7bab3b38e2924e5e451cfd280d7dafe936f6c5e4bd89813b02a36589ce318a0358dc35cc4e17f9bf234cdbb78fa0c607a7340e6cec20b1596610c6934b8323226379edda81da8dcb9ec40a042f50b5bb21645473b58b11dbd7bfca8304f8add5d67a9ea8ba5d8ea72c1a4d8a952f10f2c920e368cf71e99fad5833dd0754d6ed66bdb2e9a91a5babb2a310465a57c1ddc1038e7bd5171d3748b8d46ee1ff005298dc6a764c27d4eeaee7fe1c01795881c9e7804fe940dbe287c4b6d75a1b1d1c986d62277c91bf131f4c0f6fad0663737135d3b497124924871f98e7803007d2811dc5b83903dc0a0333f03be7de8122df2c9a05a11e5f51f7a05ce7071804fca8033e5da0734020b0183bb23e5416269577ed0e5323078ceeefdff6a03dbcd62914c2f629a47c622689800879e4fbd046f9d8a2a03e31385c0e73da8b83ca590947dcaead8208e73da8849b3e19ce704f7c5015586d006431f5cf61f3a04ee586ff002481c8fe6191408f0011eb8e30682774dea9bbb5784492ca6385832e1ca95e3d2834be9df8c312e2db5eb4375080337000f1303d18763591a469baef4d755989ec6f6dae5a23e20b599406dd8e080ddbed41272f4dd8caf1c86d163910f9595882a3d718a035edd695d3b6a926b57d0ac65b10b4e06eedd863bf141077fd7af2782bd3fa26a1a8891d57c630948c0279393dcd04cf5875258f4de9f0cb7b7b6d66d2b81ba752d85f5214724fed41036bd79d2fe319d7a8f4b9c81e58de2f04827b9ce09a07a3acecf54b790685ace8697606009e52c377b7f2e682b097d7d36acf0f55df5edbdc0977412468cb6ce3be10af3c63b9c8a0b0751f505be9690dd5d752436f62a3fe4c6448f3b7b0c64e38f615734651f107e3045ac42b67a7693018633b965bc1bc838ee173807bf7cd33065baaeb1a95f2c11dfcd2bc51fe48880aa3e8a062a8b059f595df4ae9a74de9e9ec499d43c97b1427c6e47e525bb63e4282ad3ea3712893c599dbc4259c1627713c927de81043950df97db1406da8411c92063be280230839627078e79a0390a71b5bb5003a8c1232338e4507025573e9fbd02a0e41dc0e680c3691cf714053bb34160895dc16f291d98d02322aa39f3e14707ffaa06f202a5bb0c7201f4a343aca51090497efdfbfce89840c8db8e46573923ff14410b00490d9f5c1a0425dd8ce4673e873cd0265e4dbe7041ed814009b8cbb8e5863bd07163b7716e0607b6698060b96b7b9478dc8643918247ee39a60b7e97f133a8b4e0c63d4ee597380923970a3ef4c0e13e25dfcfab457ba95bdbddb212016501867b9cfbfda982f907c74b282da34874a9048aa479c83838edc62982b7ac7c42d235cd67f15ac5b40c366418a2cb0c1c81e6f5e31db14c160d035de8cd4a3f18ea96562cc37359dfe9cac887fef039fd6b39446f56ea5d13a9dca4579a922496b1975b8d22dfc3566cf9557230703be715ac1431d4d2275325d7fae6b4f6f182a93ef1e32a9f41938f6a60afeb1a95c5fea53dccf772cf2c8c489240031f627e7565c0d67bbf160487c1801073bc0c31f91f953420f2bc8c7c52cc540032738a809905c0f4fa501940208e73df34028e703938a0577ae013f4a001300db4f03b71407461ce0502dca8c9c7dcf6a003fafcbdcd0070bc1e0fd734070db467b8a04cb9c9e68274b93bcb1daa40200ed4099765249ec476cf340849b8b264823bf34689ee009cb671df1409bc8e8b8e770e3ec68984d9c953cf97be2860b248caaebc107dc67f7a184c31232db88fd451031ce50e76039f5c8045026efb8f93279e0fd680b239504f0483d88ef409ee25bb90c79c0e050151c6e21b39ce783eb40adbcc2cefa17bdb61322387781c950e3dbdf9c8a066f28790b22e013db3dbef54726081e63c6460d34191b1bb0720f634060e7600412c781502409c8e3d7b500ed71dbef8ed40243f181c0a02e5d4e0fad006f644e4819e3b501f7e3049e7b501bc43b4e391da80558003392d40a23305e320d02e64cf998e1bf5a032b0c927b8e68049c8c8e71c6280377043118f4e680bbff00de0504ddbb3128371c1c64668024e59f3cd02521254e4fad1a2107e48fe6a6809ddb9e78a029e1463d05027ffc744a6c3857c7b1a205ff00e637fbf4a02b12b1794e39f4a02024e7249ed409924720906800005173fd7404989698ee39e4f7a04cf723d07a501fff0097ed406ffe36a018ff00281e99a037f4d0731f3bfd28007e53400ff99a810248c0cf140bc60123233cff008a0557f9beb4056eff007a07109243e79a03778b27bfbd02b128c27039a054001b818a06609de793da815006070283ffd9}\par}+{\pard \ql \f0 \fs24 \sa0 \li0 \fi0 lalune\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here is a movie {\pict\jpegblip\picw20\pich22\picwgoal400\pichgoal440 ffd8ffe000104a46494600010101004800480000fffe0050546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d6265722031393935ffdb00430001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffdb00430101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101ffc00011080016001403012200021101031101ffc4001a000100020301000000000000000000000000080905060a07ffc400231000010501000300010500000000000000060304050708020001090a11153976b7ffc400160101010100000000000000000000000000060800ffc400261101000102050109000000000000000000010200030405061121b33134365154717475b4ffda000c03010002110311003f00a90cf388f366a62aa720ed6ae07f96901f3831d973452b8cf36fe3570fc908e46d466433e5dd954f2e96992d9e498c7753faa44916e016ca91cc7d88b38fe60a5b97737defcbcc539c98d336a57f4fc2ca9a486bf07ab575ad9a3af4df221d8215e36df86c4504ff0024574551b3d687ee0575757b3ad64e311ee62bd94158d37e24198c43973099f1fc0c41614d950246513a081abf76cfe7061f6863281e6352fd1670949c148dd6dfb0d25f5b3689b1d5c965b0eacbf4e0932ad28e22ab9ae945633f4744bd3c8cee0a7fdf085b9000f449c5f7afa30b83e0b6fd7b0c8429c9467ff9715347c891e25fa24a205861aa715e6a09bd0488237dc2723414d9891381524e8ca7c0894664f835653631ab55ee7e3de433e4ff001b30949124e4c10c8b6ad0a479b3f9c937b2cf5bc0095ad600a0a41a0e9faee174a1c605e161c6c7a313539650b0113190f1a8368e60d5b24f30ff008ea7f0bf867fa6595feeb6978f1fe0f9c26177f4d63a51a9235184750e7d18811339cd000000c75f000e00380380ae390c350def826ed42ad051fa6f501c50f9b699c3b69cbeb76476d202bf3ac985b6e0e968be66572893e6a744540bd9722e5c87956848629bc2559306bd113e8653d3b6aff651dfad7a3ac8b02958cba02a93ccf525757039bae6cff090e1d90688e8aa233ee86a4c4a3e0586d6b2340522e47dcb7d0046d8a5acb05a123ee25d2b230b2ada6e2e2f9ede3c05202520ec2487b0d56562529d8b3393bca76adca4ec1bca508abb001babc007915d84fe3dd14e207e3c62f8379da2a3b861fb6629d28dba53b6ea388ebfed866bf6dfb553455e91ed547ae92e9445253a4fdf3efb4f8ebdfbe7d3c78f1ee0bb9e13e358e942a4ed49e22cff00eeb35fdd7ebfffd9} icon.\par}+{\pard \qc \f0 \fs24 \sa180 \li0 \fi0 \emdash\emdash\emdash\emdash\emdash\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \outlinelevel0 \b \fs34 Footnotes\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here is a footnote reference,{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.\par}+} and another.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Here\u8217's the long note. This one contains multiple blocks.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 Subsequent blocks are indented to show that they belong to the footnote (as with list items).\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 \f1 \fs24 \{ <code> \}\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.\par}+} This should {\i not} be a footnote reference, because it contains a space.[^my note] Here is an inline note.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This is {\i easier} to type. Inline notes may contain {\field{\*\fldinst{HYPERLINK "http://google.com"}}{\fldrslt{\ul links }}}- and {\f1 ]} verbatim characters, as well as [bracketed text].\par}+ and {\f1 \fs24 ]} verbatim characters, as well as [bracketed text].\par} }\par}-{\pard \ql \f0 \sa180 \li720 \fi0 Notes can go in quotes.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 In quote.\par}+{\pard \ql \f0 \fs24 \sa180 \li720 \fi0 Notes can go in quotes.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \fs24 \sa180 \li0 \fi0 In quote.\par} }\par}-{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab And in list items.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \sa180 \li0 \fi0 In list.\par}+{\pard \ql \f0 \fs24 \sa0 \li360 \fi-360\ls35\ilvl0\tx360 {\listtext\tab 1.\tab} And in list items.{\super\chftn}{\*\footnote\chftn\~\plain\pard {\pard \ql \f0 \fs24 \sa180 \li0 \fi0 In list.\par} }\sa180\par}-{\pard \ql \f0 \sa180 \li0 \fi0 This paragraph should not be part of the note, as it is not indented.\par}+{\pard \ql \f0 \fs24 \sa180 \li0 \fi0 This paragraph should not be part of the note, as it is not indented.\par} }
@@ -0,0 +1,662 @@+Pandoc Test Suite+John MacFarlane; Anonymous+July 17, 2006++This is a set of tests for pandoc. Most of them are adapted from John Gruber’s markdown test suite.+++--------------------++= Headers =++== Level 2 with an embedded link ==++=== Level 3 with emphasis ===++==== Level 4 ====++===== Level 5 =====++= Level 1 =++== Level 2 with emphasis ==++=== Level 3 ===++with no blank line++== Level 2 ==++with no blank line+++--------------------++= Paragraphs =++Here’s a regular paragraph.++In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.++Here’s one with a bullet. * criminey.++There should be a hard line break\\+here.+++--------------------++= Block Quotes =++E-mail style:++This is a block quote. It is pretty short.++Code in a block quote:++```+sub status {+ print "working";+}+```++A list:+++ item one++ item two++Nested block quotes:++nested++nested++This should not be a block quote: 2 > 1.++And a following paragraph.+++--------------------++= Code Blocks =++Code:++```+---- (should be four hyphens)++sub status {+ print "working";+}++this code block is indented by one tab+```++And:++```+ this code block is indented by two tabs++These should not be escaped: \$ \\ \> \[ \{+```+++--------------------++= Lists =++== Unordered ==++Asterisks tight:++- asterisk 1+- asterisk 2+- asterisk 3++Asterisks loose:++- asterisk 1+- asterisk 2+- asterisk 3++Pluses tight:++- Plus 1+- Plus 2+- Plus 3++Pluses loose:++- Plus 1+- Plus 2+- Plus 3++Minuses tight:++- Minus 1+- Minus 2+- Minus 3++Minuses loose:++- Minus 1+- Minus 2+- Minus 3++== Ordered ==++Tight:+++ First++ Second++ Third++and:+++ One++ Two++ Three++Loose using tabs:+++ First++ Second++ Third++and using spaces:+++ One++ Two++ Three++Multiple paragraphs:+++ Item 1, graf one.+Item 1. graf two. The quick brown fox jumped over the lazy dog’s back.++ Item 2.++ Item 3.++== Nested ==++- Tab+ - Tab+ - Tab++Here’s another:+++ First++ Second:+ - Fee+ - Fie+ - Foe++ Third++Same thing but with paragraphs:+++ First++ Second:+ - Fee+ - Fie+ - Foe++ Third++== Tabs and spaces ==++- this is a list item indented with tabs+- this is a list item indented with spaces+ - this is an example list item indented with tabs+ - this is an example list item indented with spaces++== Fancy list markers ==+++ begins with 2++ and now 3+with a continuation+ + sublist with roman numerals starting with i.+ + more items+ + a subsublist+ + a subsublist++Nesting:+++ Upper Alpha+ + Upper Roman.+ + Decimal start with 1+ + Lower alpha with paren++Autonumbering:+++ Autonumber.++ More.+ + Nested.++Should not be a list item:++M.A. 2007++B. Williams+++--------------------++= Definition Lists =++Tight using spaces:++: **apple**+ red fruit+: **orange**+ orange fruit+: **banana**+ yellow fruit++Tight using tabs:++: **apple**+ red fruit+: **orange**+ orange fruit+: **banana**+ yellow fruit++Loose:++: **apple**+ red fruit+: **orange**+ orange fruit+: **banana**+ yellow fruit++Multiple blocks with italics:++: **//apple//**+ red fruit+contains seeds, crisp, pleasant to taste+: **//orange//**+ orange fruit+```+{ orange code block }+```++orange block quote++Multiple definitions, tight:++: **apple**+ red fruit+ computer+: **orange**+ orange fruit+ bank++Multiple definitions, loose:++: **apple**+ red fruit+ computer+: **orange**+ orange fruit+ bank++Blank line after term, indented marker, alternate markers:++: **apple**+ red fruit+ computer+: **orange**+ orange fruit+ + sublist+ + sublist++= HTML Blocks =++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">+"""+++--------------------++= Inline Markup =++This is //emphasized//, and so //is this//.++This is **strong**, and so **is this**.++An //[emphasized link url]//.++**//This is strong and em.//**++So is **//this//** word.++**//This is strong and em.//**++So is **//this//** word.++This is code: ``>``, ``$``, ``\``, ``\$``, ``<html>``.++--This is //strikeout//.--++Superscripts: a<sup>bc</sup>d a<sup>//hello//</sup> a<sup>hello there</sup>.++Subscripts: H<sub>2</sub>O, H<sub>23</sub>O, H<sub>many of them</sub>O.++These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.+++--------------------++= Smart quotes, ellipses, dashes =++“Hello,” said the spider. “‘Shelob’ is my name.”++‘A’, ‘B’, and ‘C’ are letters.++‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’++‘He said, “I want to go.”’ Were you alive in the 70’s?++Here is some quoted ‘``code``’ and a “[quoted link http://example.com/?foo=1&bar=2]”.++Some dashes: one—two — three—four — five.++Dashes between numbers: 5–7, 255–66, 1987–1999.++Ellipses…and…and….+++--------------------++= LaTeX =++- +- $2+2=4$+- $x \in y$+- $\alpha \wedge \omega$+- $223$+- $p$-Tree+- Here’s some display math: $$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$+- Here’s one that has a line break in it: $\alpha + \omega \times x^2$.++These shouldn’t be math:++- To get the famous equation, write ``$e = mc^2$``.+- $22,000 is a //lot// of money. So is $34,000. (It worked if “lot” is emphasized.)+- Shoes ($20) and socks ($5).+- Escaped ``$``: $73 //this should be emphasized// 23$.++Here’s a LaTeX table:++++--------------------++= Special Characters =++Here is some unicode:++- I hat: Î+- o umlaut: ö+- section: §+- set membership: ∈+- copyright: ©++AT&T has an ampersand in their name.++AT&T is another way to write it.++This & that.++4 < 5.++6 > 5.++Backslash: \++Backtick: `++Asterisk: *++Underscore: _++Left brace: {++Right brace: }++Left bracket: [++Right bracket: ]++Left paren: (++Right paren: )++Greater-than: >++Hash: #++Period: .++Bang: !++Plus: +++Minus: -+++--------------------++= Links =++== Explicit ==++Just a [URL url/].++[URL and title url/].++[URL and title url/].++[URL and title url/].++[URL and title url/]++[URL and title url/]++[with_underscore url/with_underscore]++[Email link mailto:nobody@nowhere.net]++[Empty ].++== Reference ==++Foo [bar url/].++With [embedded [brackets] url/].++[b url/] by itself should be a link.++Indented [once url].++Indented [twice url].++Indented [thrice url].++This should [not][] be a link.++```+[not]: /url+```++Foo [bar url/].++Foo [biz url/].++== With ampersands ==++Here’s a [link with an ampersand in the URL http://example.com/?foo=1&bar=2].++Here’s a link with an amersand in the link text: [AT&T http://att.com/].++Here’s an [inline link script?foo=1&bar=2].++Here’s an [inline link in pointy braces script?foo=1&bar=2].++== Autolinks ==++With an ampersand: http://example.com/?foo=1&bar=2++- In a list?+- http://example.com/+- It should.++An e-mail address: <nobody@nowhere.net>++Blockquoted: http://example.com/++Auto-links should not occur here: ``<http://example.com/>``++```+or here: <http://example.com/>+```+++--------------------++= Images =++From “Voyage dans la Lune” by Georges Melies (1902):++[lalune.jpg|Voyage dans la Lune]+lalune+++Here is a movie [movie.jpg|movie] icon.+++--------------------++= Footnotes =++Here is a footnote reference,(Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.) and another.(Here’s the long note. This one contains multiple blocks.++Subsequent blocks are indented to show that they belong to the footnote (as with list items).++```+ { <code> }+```++If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.) This should //not// be a footnote reference, because it contains a space.[^my note] Here is an inline note.(This is //easier// to type. Inline notes may contain [links http://google.com] and ``]`` verbatim characters, as well as [bracketed text].)++Notes can go in quotes.(In quote.)+++ And in list items.(In list.)++This paragraph should not be part of the note, as it is not indented.
@@ -350,8 +350,8 @@ <p>and now 3</p> <p>with a continuation</p> <list type="ordered:lowerroman">- <item n="4">- <p>sublist with roman numerals, starting with 4</p>+ <item>+ <p>sublist with roman numerals starting with i.</p> </item> <item> <p>more items</p>@@ -369,16 +369,16 @@ </list> <p>Nesting:</p> <list type="ordered:upperalpha">- <item>+ <item n="4"> <p>Upper Alpha</p> <list type="ordered:upperroman"> <item> <p>Upper Roman.</p> <list type="ordered:arabic">- <item n="6">- <p>Decimal start with 6</p>+ <item>+ <p>Decimal start with 1</p> <list type="ordered:loweralpha">- <item n="3">+ <item> <p>Lower alpha with paren</p> </item> </list>
@@ -444,9 +444,9 @@ with a continuation -@enumerate 4+@enumerate @item-sublist with roman numerals, starting with 4+sublist with roman numerals starting with i. @item more items @enumerate A@@ -462,16 +462,16 @@ Nesting: -@enumerate A+@enumerate D @item Upper Alpha @enumerate @item Upper Roman.-@enumerate 6+@enumerate @item-Decimal start with 6-@enumerate c+Decimal start with 1+@enumerate a @item Lower alpha with paren @end enumerate@@ -948,7 +948,7 @@ It should. @end itemize -An e-mail address: @uref{mailto:nobody@@nowhere.net,nobody@@nowherenet}+An e-mail address: @uref{mailto:nobody@@nowhere.net,nobody@@nowhere.net} @quotation Blockquoted: @url{http://example.com/}
@@ -215,8 +215,8 @@ <li><p>begins with 2</p></li> <li><p>and now 3</p> <p>with a continuation</p>-<ol start="4" style="list-style-type: lower-roman;">-<li>sublist with roman numerals, starting with 4</li>+<ol style="list-style-type: lower-roman;">+<li>sublist with roman numerals starting with i.</li> <li>more items <ol style="list-style-type: upper-alpha;"> <li>a subsublist</li>@@ -229,13 +229,13 @@ Nesting: -<ol style="list-style-type: upper-alpha;">+<ol start="4" style="list-style-type: upper-alpha;"> <li>Upper Alpha <ol style="list-style-type: upper-roman;"> <li>Upper Roman.-<ol start="6" style="list-style-type: decimal;">-<li>Decimal start with 6-<ol start="3" style="list-style-type: lower-alpha;">+<ol style="list-style-type: decimal;">+<li>Decimal start with 1+<ol style="list-style-type: lower-alpha;"> <li>Lower alpha with paren</li> </ol> </li>
@@ -1,15 +1,14 @@-#let horizontalrule = line(start: (25%,0%), end: (75%,0%))--#show terms.item: it => block(breakable: false)[- #text(weight: "bold")[#it.term]- #block(inset: (left: 1.5em, top: -0.4em))[#it.description]-]+#set terms(hanging-indent: 1.5em) #set table( inset: 6pt, stroke: none ) +#let horizontalrule = line(start: (25%,0%), end: (75%,0%))+// Polyfill divider to allow compiling with typst < 0.15:+#let divider = if "divider" in std { divider } else { horizontalRule }+ #show figure.where( kind: table ): set figure.caption(position: top)@@ -159,7 +158,7 @@ This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite. -#horizontalrule+#divider() = Headers <headers>@@ -183,7 +182,7 @@ <level-2> with no blank line -#horizontalrule+#divider() = Paragraphs <paragraphs>@@ -197,7 +196,7 @@ There should be a hard line break \ here. -#horizontalrule+#divider() = Block Quotes <block-quotes>@@ -236,7 +235,7 @@ And a following paragraph. -#horizontalrule+#divider() = Code Blocks <code-blocks>@@ -260,7 +259,7 @@ These should not be escaped: \$ \\ \> \[ \{ ``` -#horizontalrule+#divider() = Lists <lists>@@ -396,8 +395,8 @@ with a continuation #block[- #set enum(numbering: "i.", start: 4)- + sublist with roman numerals, starting with 4+ #set enum(numbering: "i.", start: 1)+ + sublist with roman numerals starting with i. + more items #block[ #set enum(numbering: "(A)", start: 1)@@ -410,16 +409,16 @@ Nesting: #block[-#set enum(numbering: "A.", start: 1)+#set enum(numbering: "A.", start: 4) + Upper Alpha #block[ #set enum(numbering: "I.", start: 1) + Upper Roman. #block[- #set enum(numbering: "(1)", start: 6)- + Decimal start with 6+ #set enum(numbering: "(1)", start: 1)+ + Decimal start with 1 #block[- #set enum(numbering: "a)", start: 3)+ #set enum(numbering: "a)", start: 1) + Lower alpha with paren ] ]@@ -438,37 +437,21 @@ B. Williams -#horizontalrule+#divider() = Definition Lists <definition-lists> Tight using spaces: -/ apple: #block[-red fruit-]--/ orange: #block[-orange fruit-]--/ banana: #block[-yellow fruit-]+/ apple: red fruit+/ orange: orange fruit+/ banana: yellow fruit Tight using tabs: -/ apple: #block[-red fruit-]--/ orange: #block[-orange fruit-]--/ banana: #block[-yellow fruit-]+/ apple: red fruit+/ orange: orange fruit+/ banana: yellow fruit Loose: @@ -511,7 +494,6 @@ computer ]- / orange: #block[ orange fruit @@ -620,7 +602,7 @@ Hr's: -#horizontalrule+#divider() = Inline Markup <inline-markup>@@ -649,7 +631,7 @@ These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a\~b c\~d. -#horizontalrule+#divider() = Smart quotes, ellipses, dashes <smart-quotes-ellipses-dashes>@@ -670,7 +652,7 @@ Ellipses…and…and…. -#horizontalrule+#divider() = LaTeX <latex>@@ -694,7 +676,7 @@ Here's a LaTeX table: -#horizontalrule+#divider() = Special Characters <special-characters>@@ -748,7 +730,7 @@ Minus: - -#horizontalrule+#divider() = Links <links>@@ -827,7 +809,7 @@ or here: <http://example.com/> ``` -#horizontalrule+#divider() = Images <images>@@ -841,7 +823,7 @@ Here is a movie #box(image("movie.jpg", alt: "movie")) icon. -#horizontalrule+#divider() = Footnotes <footnotes>
@@ -245,17 +245,17 @@ with a continuation - iv. sublist with roman numerals, starting with 4- v. more items- (A) a subsublist- (B) a subsublist+ i. sublist with roman numerals starting with i.+ ii. more items+ (A) a subsublist+ (B) a subsublist Nesting: -A. Upper Alpha+D. Upper Alpha I. Upper Roman.- (6) Decimal start with 6- c) Lower alpha with paren+ (1) Decimal start with 1+ a) Lower alpha with paren Autonumbering:
@@ -215,7 +215,7 @@ with a continuation -11. sublist with roman numerals, starting with 4+11. sublist with roman numerals starting with i. 11. more items 111. a subsublist 111. a subsublist@@ -224,7 +224,7 @@ 1. Upper Alpha 11. Upper Roman.-111. Decimal start with 6+111. Decimal start with 1 1111. Lower alpha with paren Autonumbering:
@@ -211,7 +211,7 @@ 1. begins with 2 2. and now 3 with a continuation- 1. sublist with roman numerals, starting with 4+ 1. sublist with roman numerals starting with i. 2. more items 1. a subsublist 2. a subsublist@@ -220,7 +220,7 @@ 1. Upper Alpha 1. Upper Roman.- 1. Decimal start with 6+ 1. Decimal start with 1 1. Lower alpha with paren Autonumbering: