packages feed

pandoc 3.8.2.1 → 3.8.3

raw patch · 163 files changed

+15273/−2809 lines, 163 filesdep +asciidocdep ~citeprocdep ~djotdep ~texmathbinary-added

Dependencies added: asciidoc

Dependency ranges changed: citeproc, djot, texmath, typst

Files

AUTHORS.md view
@@ -32,6 +32,7 @@ - Aner Lucero - Anti-Distinctlyminty - Antoine Latter+- Anton Antich - Antonio Terceiro - Arata Mizuki - Arata Mizuki@@ -39,6 +40,7 @@ - Arlo O'Keeffe - Artem Pelenitsyn - Artyom Kazak+- Asliddinbek Azizovich - B. Scott Michel - Bastien Dumont - Ben Firshman@@ -184,6 +186,7 @@ - Jakob Voß - James Aspnes - James P. Ascher+- James Barlow - James Scott-Brown - Jamie F. Olson - Jan Larres
INSTALL.md view
@@ -138,9 +138,6 @@  You can also install from source, using the instructions below under [Compiling from source].-Note that most distros have the Haskell platform in their-package repositories.  For example, on Debian/Ubuntu,-you can install it with `apt-get install haskell-platform`.  By default, Pandoc creates PDFs using LaTeX.  We recommend installing [TeX Live](https://www.tug.org/texlive/) via your package@@ -265,9 +262,12 @@      This procedure will install the released version of pandoc,     which will be downloaded automatically from HackageDB.-    The `pandoc` executable will be placed in `$HOME/.cabal/bin`+    The `pandoc` executable will be symlinked in`$HOME/.cabal/bin`     on linux/unix/macOS and in `%APPDATA%\cabal\bin` on Windows.-    Make sure this directory is in your path.+    Make sure this directory is in your path. To specify a+    custom install directory, use `--installdir`. To have+    the executable copied instead of symlinked, use+    `--install-method=copy`.      If you want to install a modified or development version of     pandoc instead, switch to the source directory before running@@ -293,12 +293,10 @@ assume that the pandoc source directory is your working directory. You will need cabal version 2.0 or higher. -1.  Install dependencies:  in addition to the [Haskell platform],-    you will need a number of additional libraries.  You can install-    them all with+1.  Install dependencies:          cabal update-        cabal install --only-dependencies+        cabal build --only-dependencies  2.  Configure: @@ -335,19 +333,20 @@          cabal haddock --html-location=URL --hyperlink-source +5.  Install +        cabal install pandoc-cli+ ### Creating a relocatable binary  It is possible to compile pandoc such that the data files pandoc uses are embedded in the binary.  The resulting binary can be run from any directory and is completely self-contained. With cabal, add `-fembed_data_files` to the `cabal configure`-or `cabal install` commands.+or `cabal build` commands.  With stack, use `--flag pandoc:embed_data_files`. -- ### Running tests  Pandoc comes with an automated test suite.@@ -402,7 +401,6 @@ [FreeBSD]: https://www.freshports.org/textproc/hs-pandoc/ [GHC]:  https://www.haskell.org/ghc/ [GitLab CI/CD]: https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/-[Haskell platform]: https://hackage.haskell.org/platform/ [MacPorts]: https://ports.macports.org/port/pandoc/ [MacTeX]: https://tug.org/mactex/ [OpenBSD ports]: https://cvsweb.openbsd.org/ports/textproc/pandoc/
MANUAL.txt view
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: 2025-10-20+date: 2025-12-01 ---  # Synopsis@@ -44,7 +44,7 @@  If no *input-files* are specified, input is read from *stdin*. Output goes to *stdout* by default. For output to a file,-use the `-o` option:+use the `-o`/`--output` option:      pandoc -o output.html input.txt @@ -233,6 +233,7 @@ :   Specify input format.  *FORMAT* can be:      ::: {#input-formats}+    - `asciidoc` ([AsciiDoc] markup)     - `bibtex` ([BibTeX] bibliography)     - `biblatex` ([BibLaTeX] bibliography)     - `bits` ([BITS] XML, alias for `jats`)@@ -273,6 +274,7 @@     - `opml` ([OPML])     - `org` ([Emacs Org mode])     - `pod` (Perl's [Plain Old Documentation])+    - `pptx` ([PowerPoint])     - `ris` ([RIS] bibliography)     - `rtf` ([Rich Text Format])     - `rst` ([reStructuredText])@@ -282,6 +284,7 @@     - `twiki` ([TWiki markup])     - `typst` ([typst])     - `vimwiki` ([Vimwiki])+    - `xlsx` ([Excel spreadsheet][XLSX])     - `xml` (XML version of native AST)     - the path of a custom Lua reader, see [Custom readers and writers] below     :::@@ -301,6 +304,12 @@     - `asciidoc` (modern [AsciiDoc] as interpreted by [AsciiDoctor])     - `asciidoc_legacy` ([AsciiDoc] as interpreted by [`asciidoc-py`]).     - `asciidoctor` (deprecated synonym for `asciidoc`)+    - `bbcode` [BBCode]+    - `bbcode_fluxbb` [BBCode (FluxBB)]+    - `bbcode_phpbb` [BBCode (phpBB)]+    - `bbcode_steam` [BBCode (Hubzilla)]+    - `bbcode_hubzilla` [BBCode (Hubzilla)]+    - `bbcode_xenforo` [BBCode (xenForo)]     - `beamer` ([LaTeX beamer][`beamer`] slide show)     - `bibtex` ([BibTeX] bibliography)     - `biblatex` ([BibLaTeX] bibliography)@@ -512,6 +521,7 @@ [DokuWiki markup]: https://www.dokuwiki.org/dokuwiki [ZimWiki markup]: https://zim-wiki.org/manual/Help/Wiki_Syntax.html [XWiki markup]: https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/XWikiSyntax/+[XLSX]: https://en.wikipedia.org/wiki/Microsoft_Excel#File_formats [Vimdoc]: https://vimhelp.org/helphelp.txt.html#help-writing [TWiki markup]: https://twiki.org/cgi-bin/view/TWiki/TextFormattingRules [TikiWiki markup]: https://doc.tiki.org/Wiki-Syntax-Text#The_Markup_Language_Wiki-Syntax@@ -546,6 +556,12 @@ [EndNote XML bibliography]: https://support.clarivate.com/Endnote/s/article/EndNote-XML-Document-Type-Definition [typst]: https://typst.app [mdoc]: https://mandoc.bsd.lv/man/mdoc.7.html+[BBCode]: https://www.bbcode.org/reference.php+[BBCode (FluxBB)]: https://web.archive.org/web/20210623155046/https://fluxbb.org/forums/help.php#bbcode+[BBCode (Hubzilla)]: https://hubzilla.org/help/member/bbcode+[BBCode (Steam)]: https://steamcommunity.com/comment/ForumTopic/formattinghelp+[BBCode (phpBB)]: https://www.phpbb.com/community/help/bbcode+[BBCode (xenForo)]: https://www.xenfocus.com/community/help/bb-codes/  ## Reader options {.options} @@ -5696,28 +5712,36 @@  An image with nonempty alt text, occurring by itself in a paragraph, will be rendered as a figure with a caption.  The-image's alt text will be used as the caption.+image's description will be used as the caption. -    ![This is the caption](/url/of/image.png)+    ![This is the caption.](image.png)  How this is rendered depends on the output format. Some output formats (e.g. RTF) do not yet support figures. In those formats, you'll just get an image in a paragraph by itself, with-no caption. For LaTeX output, you can specify a [figure's-positioning](https://www.overleaf.com/learn/latex/Positioning_images_and_tables#The_figure_environment)-by adding the `latex-placement` attribute.--    ![This is the caption](/url/of/image.png){latex-placement="ht"}+no caption.  If you just want a regular inline image, just make sure it is not the only thing in the paragraph. One way to do this is to insert a nonbreaking space after the image: -    ![This image won't be a figure](/url/of/image.png)\+    ![This image won't be a figure](image.png)\  Note that in reveal.js slide shows, an image in a paragraph by itself that has the `r-stretch` class will fill the screen, and the caption and figure tags will be omitted.++To specify an alt text for the image that is different+from the caption, you can use an explicit attribute (assuming the+`link_attributes` extension is set):++    ![The caption.](image.png){alt="description of image"}++For LaTeX output, you can specify a [figure's+positioning](https://www.overleaf.com/learn/latex/Positioning_images_and_tables#The_figure_environment)+by adding the `latex-placement` attribute.++    ![The caption.](image.png){latex-placement="ht"}  ### Extension: `link_attributes` ### 
README.md view
@@ -28,6 +28,7 @@  <div id="input-formats"> +- `asciidoc` ([AsciiDoc](https://asciidoc.org/) markup) - `bibtex` ([BibTeX](https://ctan.org/pkg/bibtex) bibliography) - `biblatex` ([BibLaTeX](https://ctan.org/pkg/biblatex) bibliography) - `bits` ([BITS](https://jats.nlm.nih.gov/extensions/bits/) XML, alias@@ -91,6 +92,8 @@ - `org` ([Emacs Org mode](https://orgmode.org)) - `pod` (Perl’s [Plain Old   Documentation](https://perldoc.perl.org/perlpod))+- `pptx`+  ([PowerPoint](https://en.wikipedia.org/wiki/Microsoft_PowerPoint)) - `ris` ([RIS](https://en.wikipedia.org/wiki/RIS_(file_format))   bibliography) - `rtf` ([Rich Text@@ -105,6 +108,8 @@   markup](https://twiki.org/cgi-bin/view/TWiki/TextFormattingRules)) - `typst` ([typst](https://typst.app)) - `vimwiki` ([Vimwiki](https://vimwiki.github.io))+- `xlsx` ([Excel+  spreadsheet](https://en.wikipedia.org/wiki/Microsoft_Excel#File_formats)) - `xml` (XML version of native AST) - the path of a custom Lua reader, see [Custom readers and   writers](https://pandoc.org/MANUAL.html#custom-readers-and-writers)@@ -124,6 +129,17 @@ - `asciidoc_legacy` ([AsciiDoc](https://asciidoc.org/) as interpreted by   [`asciidoc-py`](https://github.com/asciidoc-py/asciidoc-py)). - `asciidoctor` (deprecated synonym for `asciidoc`)+- `bbcode` [BBCode](https://www.bbcode.org/reference.php)+- `bbcode_fluxbb` [BBCode+  (FluxBB)](https://web.archive.org/web/20210623155046/https://fluxbb.org/forums/help.php#bbcode)+- `bbcode_phpbb` [BBCode+  (phpBB)](https://www.phpbb.com/community/help/bbcode)+- `bbcode_steam` [BBCode+  (Hubzilla)](https://hubzilla.org/help/member/bbcode)+- `bbcode_hubzilla` [BBCode+  (Hubzilla)](https://hubzilla.org/help/member/bbcode)+- `bbcode_xenforo` [BBCode+  (xenForo)](https://www.xenfocus.com/community/help/bb-codes/) - `beamer` ([LaTeX beamer](https://ctan.org/pkg/beamer) slide show) - `bibtex` ([BibTeX](https://ctan.org/pkg/bibtex) bibliography) - `biblatex` ([BibLaTeX](https://ctan.org/pkg/biblatex) bibliography)
changelog.md view
@@ -1,5 +1,206 @@ # Revision history for pandoc +## pandoc 3.8.3 (2025-12-01)++  * Add `asciidoc` as an input format (#1456).++  * Add `xlsx` (Microsoft Excel) as an input format (Anton Antich).+    Each worksheet turns into a section containing a table.++  * Add `pptx` (PowerPoint) as new input format (Anton Antich).++  * Add `bbcode` as a new output format (#11242, reptee). Several variants+    of BBCode are also supported: `bbcode_fluxbb` (FluxBB), `bbcode_phpbb`+    (phpBB), `bbcode_steam` (Hubzilla), `bbcode_hubzilla` (Hubzilla),+    and `bbcode_xenforo` (xenForo).++  * New exported module Text.Pandoc.Readers.AsciiDoc,+    exporting `readAsciiDoc` [API change].++  * New module `Text.Pandoc.Readers.Pptx`,+    exporting `readPptx` (Anton Antich) [API change].++  * New module `Text.Pandoc.Readers.Xlsx`,+    exporting `readXlsx` (Anton Antich) [API change].++  * LaTeX reader:++    + Revert `\linebreak` as LineBreak (#11272). `\linebreak` is more+      of a hint, it shouldn't produce a hard break.+    + Better handling of `\makeatletter` in parsing raw LaTeX (#11270).+    + Fix spurious paragraph breaks in math environments (#11265,+      Emmanuel Ferdman). Previously, a math environment with extra+      space before the `\end` would get rendered with a blank line,+      which LaTeX treats as a paragraph break.+    + Change type on `rawLaTeXParser` in Text.Pandoc.LaTeX.Parsing.+      The preparser doesn't need to return a value.+    + Fix `rawTeXParser` (#11253).  Make macro expansion in raw LaTeX+      depend on the setting of the `latex_macros` extension.  Previously+      macros were always expanded, even in raw TeX in markdown. In+      addition, there was previously a bug that caused content to be+      garbled in certain cases.+    + Handle `ifstrequal` at a lower level, like the other `if`+      commands (#11253).+    + Move `ifstrequal`, `iftoggle`, etc., which were misplaced in+      `environments`, to `blockCommands`, so these commands work properly.++  * Docx reader:++    + Handle REF link instruction (#11296, Ezwal).+    + Check recursively for caption styles (Albert Krewinkel).+      The docx reader uses caption styles to identify figures and+      captioned tables. It now checks for known caption styles in the+      full styles hierarchy of a paragraph instead of just checking+      the style directly. This allows to recognize caption styles that+      are built on top of the basic *caption* style, as is sometimes+      the case in sophisticated styles.++  * Markdown reader:++    + Fix performance issue in links with `'` (#10880).++  * Typst reader:++    + Handle document metadata and `#title` (jgm/typst-hs#80).+      Note that previously, the typst reader never returned document+      metadata.  Now it does, even if the typst document does not contain+      a `#title` function that would result in actually printing the+      title block.++  * Djot reader:++    + Add Space elements (#11250). Previously we just got big+      Str elements with spaces included. But many pandoc writers+      assume that breakable spaces will be Space elements, and this+      is also required for automatic wrapping.++  * RST reader:++    + Correctly handle intraword emphasis (#11309).++  * Text.Pandoc.Readers:++    + Export `readAsciiDoc`, `readXlsx`, `readPptx` [API change].++  * New module Text.Pandoc.Writers.BBCode, exporting+    `writeBBCode`,  `writeBBCodeSteam`, `writeBBCodeFluxBB`,+    `writeBBCodePhpBB`, `writeBBCodeHubzilla`, `writeBBCodeXenforo`+    [API change].++  * LaTeX writer:++    + Make level 1-3 headings work inside blockquotes (#11281, James Barlow).+    + Remove `split` from list of math environments (#11274).+    + Improve handling of math environments in tex math (#11266).++  * HTML writer:++    + Add reveal.js `scroll` and `scrollSnap` options to writer and+      template (#10052, Asliddinbek Azizovich).+    + Use 'defer' when including mathjax script, as recommended in+      MathJax docs (#11292).++  * ANSI writer:++    + Apply row spans in tables (#10149, Tuong Nguyen Manh).+      The ANSI writer is now able to keep track of row spans and apply+      them in rows.++  * Pptx writer:++    + Handle reference doc without slides (#7536, Tuong Nguyen Manh).++  * AsciiDoc writer:++    + Add more table features (#11267, Tuong Nguyen Manh):+      Row span and column span, footer row, individual horizontal+      cell alignment.++  * Typst template:++    + Fix font for compatibility with typst 0.14, which doesn't+      permit an empty array for `font` (#11238).+    + Re-add `columns` to typst template (#11259), fixing a+      pandoc 3.8 regression.+    + Fix syntax for bibliography inclusion (#11233, Mickaël Canouil).+      Previously the syntax was wrong when multiple bibliography files+      were specified. Typst expects an array.++  * Text.Pandoc.Writers:++    + Export `writeBBCode`,  `writeBBCodeSteam`, `writeBBCodeFluxBB`,+      `writeBBCodePhpBB`, `writeBBCodeHubzilla`, `writeBBCodeXenforo`+      [API change].++  * Text.Pandoc.Writers.Shared:++    + Add functions `insertCurrentSpansAtColumn`, `takePreviousSpansAtColumn`+      and `decrementTrailingRowSpans` for applying and keeping track of+      RowSpans over multiple rows (#10149, Tuong Nguyen Manh). [API change]++  * Text.Pandoc.Logging:++    + Change message for missing HTML title warning (#11307). Suggest+      setting the `pagetitle` variable instead of setting `title` in metadata.++  * Lua subsystem:++    + Preserve common state of custom Lua readers (Albert Krewinkel).+      The common state is transferred to Lua when calling a custom Lua+      reader, and is now also transferred back after the reader has+      finished. This ensures that info messages, warnings, and+      mediabag entries are available to the main program and all+      subsequent processing steps.++  * Text.Pandoc.PDF:++    + Avoid converting SVG to PDF when non-TeX PDF engine is used (#11275).+      This fixes a 3.8 regression, which caused documents with SVGs to+      raise an error when converted to PDF using WeasyPrint.+    + Fix a 3.8 regression with typst and smart quotes (#11256).+      Before 3.8, the default behavior when producing a PDF `-t typst`+      was to produce smart quotes according to typst's defaults.+      (This could be defeated by specifying `-t typst-smart`.)+      This behavior broke in 3.8 because of a change to Text.Pandoc.PDF.+      This change caused `smart` to be disabled for all formats when+      producing PDFs, when before it was only disable for TeX-based+      formats (to avoid bad ligatures). This commit restores the old+      behavior. Possibly the regression also other affects other+      non-TeX formats, e.g. HTML.++  * Text.Pandoc.Shared:++    + Add functions `allRowsEmpty` and `tableBodiesToRows` from the+      RST writer for reuse in other writers. (Tuong Nguyen Manh) [API+      change].++  * Text.Pandoc.Citeproc:++    + Allow formatting in locator to be transmitted to citeproc.+      We do this indirectly, by rendering the formatting using the+      HTML tags that citeproc recognizes.  Fixes jgm/citeproc#68+      and jgm/citeproc#163. Note that formatting is only possible for+      locators given in the explicit form, surrounded by curly braces.+      It won't work for implicit locators, since these expect+      number-like expressions.++  * New non-exported module Text.Pandoc.Readers.OOXML.Shared+    containing functions factored out from+    Text.Pandoc.Readers.Docx.Util (Anton Antich).++  * Tests: The common file `nativeDiff` has been extracted from+    the Docx and Pptx text files and put in Tests.Helpers.++  * Use asciidoc 0.1, djot 0.1.2.4, texmath 0.13.0.2, typst 0.8.1,+    citeproc 0.12.++  * MANUAL.txt:++    + Improve `implicit_figure` documentation (#11082).+    + Give both forms of options when referring to them (#11306).++  * Update INSTALL.md (#11271).+ ## pandoc 3.8.2.1 (2025-10-20)    * HTML reader: allow blank space between open and close `iframe`.
+ data/templates/default.bbcode view
@@ -0,0 +1,1 @@+$body$
data/templates/default.revealjs view
@@ -232,6 +232,19 @@         // devices. It is advisable to set this to a lower number than         // viewDistance in order to save resources.         mobileViewDistance: $mobileViewDistance$,+$if(view)$++        // Enable scroll view+        view: '$view/nowrap$',+        // see https://revealjs.com/scroll-view/#scrollbar+        scrollProgress: $scrollProgress$,+        // see https://revealjs.com/scroll-view/#url-activation+        scrollActivationWidth: '$scrollActivationWidth$',+        // see https://revealjs.com/scroll-view/#scroll-snapping+        scrollSnap: '$scrollSnap$',+        // Experimental. see https://revealjs.com/scroll-view/#scroll-snapping+        scrollLayout: '$scrollLayout$',+$endif$ $if(parallaxBackgroundImage)$          // Parallax background image
data/templates/default.typst view
@@ -149,7 +149,7 @@ $endif$ $if(bibliography)$ -#bibliography($for(bibliography)$"$bibliography$"$sep$,$endfor$$if(full-bibliography)$, full: true$endif$)+#bibliography(($for(bibliography)$"$bibliography$"$sep$,$endfor$)$if(full-bibliography)$, full: true$endif$) $endif$ $endif$ $for(include-after)$
data/templates/template.typst view
@@ -23,7 +23,7 @@   paper: "us-letter",   lang: "en",   region: "US",-  font: (),+  font: none,   fontsize: 11pt,   mathfont: none,   codefont: none,@@ -46,6 +46,7 @@     paper: paper,     margin: margin,     numbering: pagenumbering,+    columns: cols   )    set par(@@ -54,9 +55,9 @@   )   set text(lang: lang,            region: region,-           font: font,            size: fontsize) +  set text(font: font) if font != none   show math.equation: set text(font: mathfont) if mathfont != none   show raw: set text(font: codefont) if codefont != none 
− data/translations/aeb.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/afb.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/apd.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-DZ.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-EG.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-IQ.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-JO.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-LB.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-MA.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-MR.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-PS.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-SA.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-SY.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-TN.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ar-YE.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/arq.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ary.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/arz.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/ayl.yaml
@@ -1,21 +0,0 @@-Abstract: ملخص-Appendix: الملاحق-Bibliography: المصادر-Cc: نسخة ل‬-Chapter: باب-Contents: المحتويات-Encl: المرفقات-Figure: شكل-Glossary: قاموس-Index: الفهرس-ListOfFigures: قائمة الأشكال-ListOfTables: قائمة الجداول-Page: صفحة-Part: القسم-Preface: مدخل-Proof: برهان-References: المراجع-See: راجع-SeeAlso: راجع أيضًا-Table: جدول-To: إلى
− data/translations/bs-Latn.yaml
@@ -1,21 +0,0 @@-Abstract: Sažetak-Appendix: Dodatak-Bibliography: Bibliografija-Cc: Kopija-Chapter: Poglavlje-Contents: Sadržaj-Encl: Prilozi-Figure: Slika-Glossary: Rječnik-Index: Indeks-ListOfFigures: Popis slika-ListOfTables: Popis tabela-Page: Stranica-Part: Dio-Preface: Predgovor-Proof: Dokaz-References: Literatura-See: Vidjeti-SeeAlso: Također vidjeti-Table: Tabela-To: Prima
− data/translations/ckb.yaml
@@ -1,21 +0,0 @@-Abstract: پوختە-Appendix: پاشکۆ-Bibliography: کتێبنامە-Cc: ڕوونووس-Chapter: بەندی-Contents: نێوەڕۆک-Encl: هاوپێچ-Figure: وێنەی-Glossary: فەرهەنگۆک-Index: پێنوێن-ListOfFigures: لیستی وێنەکان-ListOfTables: لیستی خشتەکان-Page: لاپەڕە-Part: بەشی-Preface: پێشەكی-Proof: سەلماندن-References: سەرچاوەکان-See: چاو لێکەن-SeeAlso: هەروەها چاو لێکەن-Table: خشتەی-To: بۆ
− data/translations/cu-Cyrs.yaml
@@ -1,20 +0,0 @@-Abstract: А҆ннота́цїѧ-Appendix: Приложе́нїе-Bibliography: Вивлїогра́фїѧ-Cc: исх.-Chapter: Глава̀-Contents: Содержа́нїе}-Encl: вкл.-Figure: И҆з̾ѡбраже́нїе-Index: Предмѣ́тный ᲂу҆каза́тель-ListOfFigures: Надписа́нїе и҆з̾ѡбраже́нїй-ListOfTables: Надписа́нїе табли́цъ-Page: с.-Part: Ча́сть-Preface: Предисло́вїе-Proof: Доказа́тельство-References: Примѣча̑нїѧ-See: зрѝ-SeeAlso: зрѝ та́кожде-Table: Табли́ца-To: вх.
− data/translations/de-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-AT-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-AT-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-AT.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-CH-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-CH-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-CH.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-DE-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-DE-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-DE.yaml
@@ -1,21 +0,0 @@-Abstract: Zusammenfassung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Glossar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: siehe-SeeAlso: siehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-AT-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-AT-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-AT.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-CH-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-CH-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-CH.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Beilage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-DE-1901.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-DE-1996.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf-DE.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/de-Latf.yaml
@@ -1,21 +0,0 @@-Abstract: Zuſammenfaſſung-Appendix: Anhang-Bibliography: Literaturverzeichnis-Cc: Verteiler-Chapter: Kapitel-Contents: Inhaltsverzeichnis-Encl: Anlage(n)-Figure: Abbildung-Glossary: Gloſſar-Index: Index-ListOfFigures: Abbildungsverzeichnis-ListOfTables: Tabellenverzeichnis-Page: Seite-Part: Teil-Preface: Vorwort-Proof: Beweis-References: Literatur-See: ſiehe-SeeAlso: ſiehe auch-Table: Tabelle-To: An
− data/translations/el-polyton.yaml
@@ -1,21 +0,0 @@-Abstract: Περίληψη-Appendix: Παράρτημα-Bibliography: Βιβλιογραφία-Cc: Κοινοποίηση-Chapter: Κεφάλαιο-Contents: Περιεχόμενα-Encl: Συνημμένα-Figure: Σχῆμα-Glossary: Γλωσσάρι-Index: Εὑρετήριο-ListOfFigures: Κατάλογος Σχημάτων-ListOfTables: Κατάλογος Πινάκων-Page: Σελίδα-Part: Μέρος-Preface: Πρόλογος-Proof: Ἀπόδειξη-References: Ἀναφορές-See: βλέπε-SeeAlso: βλέπε ἐπίσης-Table: Πίνακας-To: Πρὸς
− data/translations/en-AU.yaml
@@ -1,21 +0,0 @@-Abstract: Abstract-Appendix: Appendix-Bibliography: Bibliography-Cc: cc-Chapter: Chapter-Contents: Contents-Encl: encl-Figure: Figure-Glossary: Glossary-Index: Index-ListOfFigures: List of Figures-ListOfTables: List of Tables-Page: Page-Part: Part-Preface: Preface-Proof: Proof-References: References-See: see-SeeAlso: see also-Table: Table-To: To
− data/translations/en-CA.yaml
@@ -1,21 +0,0 @@-Abstract: Abstract-Appendix: Appendix-Bibliography: Bibliography-Cc: cc-Chapter: Chapter-Contents: Contents-Encl: encl-Figure: Figure-Glossary: Glossary-Index: Index-ListOfFigures: List of Figures-ListOfTables: List of Tables-Page: Page-Part: Part-Preface: Preface-Proof: Proof-References: References-See: see-SeeAlso: see also-Table: Table-To: To
− data/translations/en-GB.yaml
@@ -1,21 +0,0 @@-Abstract: Abstract-Appendix: Appendix-Bibliography: Bibliography-Cc: cc-Chapter: Chapter-Contents: Contents-Encl: encl-Figure: Figure-Glossary: Glossary-Index: Index-ListOfFigures: List of Figures-ListOfTables: List of Tables-Page: Page-Part: Part-Preface: Preface-Proof: Proof-References: References-See: see-SeeAlso: see also-Table: Table-To: To
− data/translations/en-NZ.yaml
@@ -1,21 +0,0 @@-Abstract: Abstract-Appendix: Appendix-Bibliography: Bibliography-Cc: cc-Chapter: Chapter-Contents: Contents-Encl: encl-Figure: Figure-Glossary: Glossary-Index: Index-ListOfFigures: List of Figures-ListOfTables: List of Tables-Page: Page-Part: Part-Preface: Preface-Proof: Proof-References: References-See: see-SeeAlso: see also-Table: Table-To: To
− data/translations/en-US.yaml
@@ -1,21 +0,0 @@-Abstract: Abstract-Appendix: Appendix-Bibliography: Bibliography-Cc: cc-Chapter: Chapter-Contents: Contents-Encl: encl-Figure: Figure-Glossary: Glossary-Index: Index-ListOfFigures: List of Figures-ListOfTables: List of Tables-Page: Page-Part: Part-Preface: Preface-Proof: Proof-References: References-See: see-SeeAlso: see also-Table: Table-To: To
− data/translations/fr-BE.yaml
@@ -1,20 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Figure-Glossary: Glossaire-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Table
− data/translations/fr-CA.yaml
@@ -1,20 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Figure-Glossary: Glossaire-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Table
− data/translations/fr-CH.yaml
@@ -1,20 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Figure-Glossary: Glossaire-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Table
− data/translations/fr-FR.yaml
@@ -1,19 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Fig.-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: Partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Tab.
− data/translations/fr-LU.yaml
@@ -1,20 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Figure-Glossary: Glossaire-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Table
− data/translations/fr-x-acadian.yaml
@@ -1,20 +0,0 @@-Abstract: Résumé-Appendix: Annexe-Bibliography: Bibliographie-Cc: Copie à-Chapter: Chapitre-Contents: Table des matières-Encl: P.~J.-Figure: Figure-Glossary: Glossaire-Index: Index-ListOfFigures: Table des figures-ListOfTables: Liste des tableaux-Page: page-Part: partie-Preface: Préface-Proof: Démonstration-References: Références-See: voir-SeeAlso: voir aussi-Table: Table
− data/translations/kmr.yaml
@@ -1,21 +0,0 @@-Abstract: Kurtebîr-Appendix: Tebînîya-Bibliography: Çavkanîya Pirtukan-Cc: Belavker-Chapter: Serê-Contents: Navêrok-Encl: Dumahik-Figure: Dimenê-Glossary: Çavkanîya lêkolînê-Index: Endeks-ListOfFigures: Hejmara Dimena-ListOfTables: Hejmara Kevalen-Page: Rûpelê-Part: Bêşa-Preface: Peşgotin-Proof: Delîl-References: Pirtuken bijartî-See: binêra-SeeAlso: le vêya ji binêra-Table: Kevala-To: Ji bo
− data/translations/la-x-classic.yaml
@@ -1,20 +0,0 @@-Abstract: Summarium-Appendix: Additamentum-Bibliography: Conspectus librorum-Cc: Exemplar-Chapter: Caput-Contents: Index-Encl: Additur-Figure: Descriptio-Glossary: Glossarium-Index: Index rerum notabilium-ListOfFigures: Conspectus descriptionum-ListOfTables: Conspectus tabularum-Page: charta-Part: Pars-Preface: Praefatio-Proof: Demonstratio-References: Conspectus librorum-See: cfr.-SeeAlso: cfr.-Table: Tabula
− data/translations/la-x-ecclesia.yaml
@@ -1,20 +0,0 @@-Abstract: Summarium-Appendix: Additamentum-Bibliography: Conspectus librorum-Cc: Exemplar-Chapter: Caput-Contents: Index-Encl: Additur-Figure: Descriptio-Glossary: Glossarium-Index: Index rerum notabilium-ListOfFigures: Conspectus descriptionum-ListOfTables: Conspectus tabularum-Page: charta-Part: Pars-Preface: Praefatio-Proof: Demonstratio-References: Conspectus librorum-See: cfr.-SeeAlso: cfr.-Table: Tabula
− data/translations/la-x-medieval.yaml
@@ -1,20 +0,0 @@-Abstract: Summarium-Appendix: Additamentum-Bibliography: Conspectus librorum-Cc: Exemplar-Chapter: Caput-Contents: Index-Encl: Additur-Figure: Descriptio-Glossary: Glossarium-Index: Index rerum notabilium-ListOfFigures: Conspectus descriptionum-ListOfTables: Conspectus tabularum-Page: charta-Part: Pars-Preface: Præfatio-Proof: Demonstratio-References: Conspectus librorum-See: cfr.-SeeAlso: cfr.-Table: Tabula
− data/translations/pa-Guru.yaml
@@ -1,20 +0,0 @@-Abstract: ਨਿਚੋੜ-Appendix: ਲੜੀਵਾਰ-Bibliography: ਸੰਬੰਧਤ ਹਵਾਲੇ-Cc: ਕਾਪੀ-Chapter: ਪਾਠ-Contents: ਸਮਗਰੀ-Encl: ਨੱਥੀ-Figure: ਸ਼ਕਲ-Glossary: ਕੁੰਜੀ-Index: ਸੂਚੀ-ListOfFigures: ਸ਼ਕਲਾਂ ਦੀ ਲੜੀ-ListOfTables: ਲੜੀਆਂ ਦਾ ਲੇਖਾ-Page: ਵਰਕਾ-Part: ਹਿੱਸਾ-Preface: ਮੁੱਖਬੰਦ-Proof: ਪਰਮਾਣ-References: ਹਵਾਲਾ-See: ਵੇਖੋ-SeeAlso: ਹੋਰ-Table: ਲੇਖਾ
− data/translations/ro-MD.yaml
@@ -1,21 +0,0 @@-Abstract: Rezumat-Appendix: Anexa-Bibliography: Bibliografie-Cc: Copie-Chapter: Capitolul-Contents: Cuprins-Encl: Anexă-Figure: Figura-Glossary: Glosar-Index: Index-ListOfFigures: Listă de figuri-ListOfTables: Listă de tabele-Page: Pagina-Part: Partea-Preface: Prefaţă-Proof: Demonstraţie-References: Bibliografie-See: Vezi-SeeAlso: Vezi de asemenea-Table: Tabela-To: Pentru
− data/translations/sr-Cyrl-BA.yaml
@@ -1,21 +0,0 @@-Abstract: Сажетак-Appendix: Додатак-Bibliography: Библиографиjа-Cc: Копиjе-Chapter: Глава-Contents: Садржаj-Encl: Прилози-Figure: Слика-Glossary: Речник-Index: Индекс-ListOfFigures: Списак слика-ListOfTables: Списак табела-Page: страна-Part: Део-Preface: Предговор-Proof: Доказ-References: Литература-See: види-SeeAlso: видитакође-Table: Табела-To: Прима
− data/translations/sr-Cyrl-ME.yaml
@@ -1,21 +0,0 @@-Abstract: Сажетак-Appendix: Додатак-Bibliography: Библиографиjа-Cc: Копиjе-Chapter: Глава-Contents: Садржаj-Encl: Прилози-Figure: Слика-Glossary: Речник-Index: Индекс-ListOfFigures: Списак слика-ListOfTables: Списак табела-Page: страна-Part: Део-Preface: Предговор-Proof: Доказ-References: Литература-See: види-SeeAlso: видитакође-Table: Табела-To: Прима
− data/translations/sr-Cyrl-XK.yaml
@@ -1,21 +0,0 @@-Abstract: Сажетак-Appendix: Додатак-Bibliography: Библиографиjа-Cc: Копиjе-Chapter: Глава-Contents: Садржаj-Encl: Прилози-Figure: Слика-Glossary: Речник-Index: Индекс-ListOfFigures: Списак слика-ListOfTables: Списак табела-Page: страна-Part: Део-Preface: Предговор-Proof: Доказ-References: Литература-See: види-SeeAlso: видитакође-Table: Табела-To: Прима
− data/translations/sr-Latn-BA.yaml
@@ -1,21 +0,0 @@-Abstract: Sažetak-Appendix: Dodatak-Bibliography: Bibliografija-Cc: Kopije-Chapter: Glava-Contents: Sadržaj-Encl: Prilozi-Figure: Slika-Glossary: Rečnik-Index: Indeks-ListOfFigures: Spisak slika-ListOfTables: Spisak tabela-Page: strana-Part: Deo-Preface: Predgovor-Proof: Dokaz-References: Literatura-See: vidi-SeeAlso: vidi takođe-Table: Tabela-To: Prima
− data/translations/sr-Latn-ME.yaml
@@ -1,21 +0,0 @@-Abstract: Sažetak-Appendix: Dodatak-Bibliography: Bibliografija-Cc: Kopije-Chapter: Glava-Contents: Sadržaj-Encl: Prilozi-Figure: Slika-Glossary: Rečnik-Index: Indeks-ListOfFigures: Spisak slika-ListOfTables: Spisak tabela-Page: strana-Part: Deo-Preface: Predgovor-Proof: Dokaz-References: Literatura-See: vidi-SeeAlso: vidi takođe-Table: Tabela-To: Prima
− data/translations/sr-Latn-XK.yaml
@@ -1,21 +0,0 @@-Abstract: Sažetak-Appendix: Dodatak-Bibliography: Bibliografija-Cc: Kopije-Chapter: Glava-Contents: Sadržaj-Encl: Prilozi-Figure: Slika-Glossary: Rečnik-Index: Indeks-ListOfFigures: Spisak slika-ListOfTables: Spisak tabela-Page: strana-Part: Deo-Preface: Predgovor-Proof: Dokaz-References: Literatura-See: vidi-SeeAlso: vidi takođe-Table: Tabela-To: Prima
− data/translations/sr-Latn-ijekavsk.yaml
@@ -1,21 +0,0 @@-Abstract: Sažetak-Appendix: Dodatak-Bibliography: Bibliografija-Cc: Kopije-Chapter: Glava-Contents: Sadržaj-Encl: Prilozi-Figure: Slika-Glossary: Rječnik-Index: Indeks-ListOfFigures: Spisak slika-ListOfTables: Spisak tabela-Page: strana-Part: Dio-Preface: Predgovor-Proof: Dokaz-References: Literatura-See: vidi-SeeAlso: vidi takođe-Table: Tabela-To: Prima
− data/translations/sr-ijekavsk.yaml
@@ -1,21 +0,0 @@-Abstract: Сажетак-Appendix: Додатак-Bibliography: Библиографиjа-Cc: Копиjе-Chapter: Глава-Contents: Садржаj-Encl: Прилози-Figure: Слика-Glossary: Рјечник-Index: Индекс-ListOfFigures: Списак слика-ListOfTables: Списак табела-Page: страна-Part: Дио-Preface: Предговор-Proof: Доказ-References: Литература-See: види-SeeAlso: види такође-Table: Табела-To: Прима
− data/translations/zh-CN.yaml
@@ -1,21 +0,0 @@-Abstract: 摘要-Appendix: 附录-Bibliography: 参考文献-Cc: 抄送-Chapter: 章-Contents: 目录-Encl: 附件-Figure: 图-Glossary: 词汇表-Index: 索引-ListOfFigures: 插图-ListOfTables: 表格-Page: 页-Part: 部分-Preface: 前言-Proof: 证明-References: 参考文献-See: 参照-SeeAlso: 参照-Table: 表-To: 收件人
− data/translations/zh-TW.yaml
@@ -1,21 +0,0 @@-Abstract: 摘要-Appendix: 附錄-Bibliography: 參考文獻-Cc: 抄送-Chapter: 章-Contents: 目錄-Encl: 附件-Figure: 圖-Glossary: 詞彙表-Index: 索引-ListOfFigures: 插圖-ListOfTables: 表格-Page: 頁-Part: 部分-Preface: 前言-Proof: 證明-References: 參考文獻-See: 參照-SeeAlso: 參照-Table: 表-To: 收件人
− data/translations/zh.yaml
@@ -1,13 +0,0 @@-Abstract: 摘要-Appendix: 附录-Bibliography: 参考文献-Chapter: 章-Contents: 目录-Figure: 图-Index: 索引-ListOfFigures: 插图-ListOfTables: 表格-Part: 部分-Proof: 证明-References: 参考文献-Table: 表
pandoc.cabal view
@@ -1,6 +1,6 @@ cabal-version:   2.4 name:            pandoc-version:         3.8.2.1+version:         3.8.3 build-type:      Simple license:         GPL-2.0-or-later license-file:    COPYING.md@@ -111,6 +111,7 @@                  data/templates/font-settings.latex                  data/templates/after-header-includes.latex                  data/templates/default.vimdoc+                 data/templates/default.bbcode                   -- translations                  data/translations/*.yaml@@ -274,6 +275,10 @@                  test/command/6466-whole.hs                  test/command/7861.yaml                  test/command/7861/metadata/placeholder+                 test/asciidoc-reader.adoc+                 test/asciidoc-reader.native+                 test/asciidoc-reader-include.rb+                 test/asciidoc-reader-include.adoc                  test/docbook-chapter.docbook                  test/docbook-reader.docbook                  test/docbook-xref.docbook@@ -342,6 +347,7 @@                  test/tables.fb2                  test/tables.muse                  test/tables.vimdoc+                 test/tables.bbcode                  test/tables.xwiki                  test/tables/*.html4                  test/tables/*.html5@@ -389,6 +395,7 @@                  test/writer.xwiki                  test/writer.muse                  test/writer.vimdoc+                 test/writer.bbcode                  test/ansi-test.ansi                  test/writers-lang-and-dir.latex                  test/writers-lang-and-dir.context@@ -423,6 +430,8 @@                  test/pptx/*.pptx                  test/pptx/**/*.pptx                  test/pptx/**/*.native+                 test/pptx-reader/basic.pptx+                 test/pptx-reader/basic.native                  test/ipynb/*.native                  test/ipynb/*.in.native                  test/ipynb/*.out.native@@ -435,6 +444,8 @@                  test/odt/odt/*.odt                  test/odt/markdown/*.md                  test/odt/native/*.native+                 test/xlsx-reader/*.xlsx+                 test/xlsx-reader/*.native                  test/pod-reader.pod                  test/vimdoc/*.markdown                  test/vimdoc/*.vimdoc@@ -503,7 +514,7 @@                  blaze-markup          >= 0.8      && < 0.9,                  bytestring            >= 0.9      && < 0.13,                  case-insensitive      >= 1.2      && < 1.3,-                 citeproc              >= 0.11     && < 0.12,+                 citeproc              >= 0.12     && < 0.13,                  commonmark            >= 0.2.6.1  && < 0.3,                  commonmark-extensions >= 0.2.6    && < 0.3,                  commonmark-pandoc     >= 0.2.3    && < 0.3,@@ -544,7 +555,7 @@                  syb                   >= 0.1      && < 0.8,                  tagsoup               >= 0.14.6   && < 0.15,                  temporary             >= 1.1      && < 1.4,-                 texmath               >= 0.13.0.1 && < 0.14,+                 texmath               >= 0.13.0.2 && < 0.14,                  text                  >= 1.1.1.0  && < 2.2,                  text-conversions      >= 0.3      && < 0.4,                  time                  >= 1.5      && < 1.16,@@ -556,9 +567,10 @@                  zip-archive           >= 0.4.3.1  && < 0.5,                  zlib                  >= 0.5      && < 0.8,                  xml                   >= 1.3.12   && < 1.4,-                 typst                 >= 0.8.0.2  && < 0.9,+                 typst                 >= 0.8.1    && < 0.9,                  vector                >= 0.12     && < 0.14,-                 djot                  >= 0.1.2.3  && < 0.2,+                 djot                  >= 0.1.2.4  && < 0.2,+                 asciidoc              >= 0.1      && < 0.2,                  tls                   >= 2.0.1    && < 2.2,                  crypton-x509-system   >= 1.6.7    && < 1.7 @@ -583,6 +595,7 @@                    Text.Pandoc.Translations,                    Text.Pandoc.Translations.Types,                    Text.Pandoc.Readers,+                   Text.Pandoc.Readers.AsciiDoc,                    Text.Pandoc.Readers.HTML,                    Text.Pandoc.Readers.LaTeX,                    Text.Pandoc.Readers.Markdown,@@ -607,6 +620,8 @@                    Text.Pandoc.Readers.TikiWiki,                    Text.Pandoc.Readers.Txt2Tags,                    Text.Pandoc.Readers.Docx,+                   Text.Pandoc.Readers.Pptx,+                   Text.Pandoc.Readers.Xlsx,                    Text.Pandoc.Readers.ODT,                    Text.Pandoc.Readers.EPUB,                    Text.Pandoc.Readers.Muse,@@ -666,6 +681,7 @@                    Text.Pandoc.Writers.BibTeX,                    Text.Pandoc.Writers.ANSI,                    Text.Pandoc.Writers.Vimdoc,+                   Text.Pandoc.Writers.BBCode,                    Text.Pandoc.PDF,                    Text.Pandoc.UTF8,                    Text.Pandoc.Scripting,@@ -714,6 +730,14 @@                    Text.Pandoc.Readers.Docx.Util,                    Text.Pandoc.Readers.Docx.Symbols,                    Text.Pandoc.Readers.Docx.Fields,+                   Text.Pandoc.Readers.OOXML.Shared,+                   Text.Pandoc.Readers.Pptx.Parse,+                   Text.Pandoc.Readers.Pptx.Shapes,+                   Text.Pandoc.Readers.Pptx.Slides,+                   Text.Pandoc.Readers.Pptx.SmartArt,+                   Text.Pandoc.Readers.Xlsx.Parse,+                   Text.Pandoc.Readers.Xlsx.Cells,+                   Text.Pandoc.Readers.Xlsx.Sheets,                    Text.Pandoc.Readers.HTML.Parsing,                    Text.Pandoc.Readers.HTML.Table,                    Text.Pandoc.Readers.HTML.TagCategories,@@ -850,6 +874,8 @@                   Tests.Readers.RST                   Tests.Readers.RTF                   Tests.Readers.Docx+                  Tests.Readers.Pptx+                  Tests.Readers.Xlsx                   Tests.Readers.ODT                   Tests.Readers.Txt2Tags                   Tests.Readers.EPUB@@ -881,6 +907,7 @@                   Tests.Writers.OOXML                   Tests.Writers.Ms                   Tests.Writers.AnnotatedTable+                  Tests.Writers.BBCode  benchmark benchmark-pandoc   import:          common-executable
src/Text/Pandoc/Citeproc/Locator.hs view
@@ -69,13 +69,47 @@   (rawlab, la, _) <- pLocatorLabelDelimited locMap   -- we only care about balancing {} and [] (because of the outer [] scope);   -- the rest can be anything-  let inner = do { t <- anyToken; return (True, stringify t) }+  let inner = do { t <- anyToken; return (True, cslJsonify t) }   gs <- many (pBalancedBraces [('{','}'), ('[',']')] inner)   _ <- pMatchChar "}" (== '}')-  let lo = T.concat $ map snd gs+  let lo = mconcat $ map snd gs   return $ LocatorInfo{ locatorLoc = lo,                         locatorLabel = la,                         locatorRaw = rawlab <> "{" <> lo <> "}" }++-- a variant of stringify that preserves formatting using CSL JSON+-- conventions+cslJsonify :: Inline -> Text+cslJsonify = go+  where goMany :: [Inline] -> T.Text+        goMany = mconcat . map go+        go :: Inline -> T.Text+        go (Str t) = t+        go Space = " "+        go SoftBreak = " "+        go LineBreak = " "+        go (Emph ils) = "<i>" <> goMany ils <> "</i>"+        go (Underline ils) = "<u>" <> goMany ils <> "</u>"+        go (Strong ils) = "<b>" <> goMany ils <> "</b>"+        go (Strikeout ils) = goMany ils+        go (Superscript ils) = "<sup>" <> goMany ils <> "</sup>"+        go (Subscript ils) = "<sub>" <> goMany ils <> "</sub>"+        go (SmallCaps ils) = "<span style=\"font-variant:small-caps;\">" <>+                              goMany ils <> "</span>"+        go (Quoted SingleQuote ils) = "'" <> goMany ils <> "'"+        go (Quoted DoubleQuote ils) = "\"" <> goMany ils <> "\""+        go (Cite _ ils) = goMany ils+        go (Code _ t) = t+        go (Math _ t) = t+        go (RawInline _ _) = ""+        go (Link _ ils _) = goMany ils+        go (Image _ ils _) = goMany ils+        go (Note _) = ""+        go (Span (_,cls@(_:_),_) ils) =+          "<span class=\"" <> T.unwords cls <> "\">" <> goMany ils <> "</span>"+        go (Span (_,[],[("style","baseline")]) ils) =+          "<span style=\"baseline\">" <> goMany ils <> "</span>"+        go (Span _ ils) = goMany ils  pLocatorLabelDelimited :: LocatorMap -> LocatorParser (Text, Text, Bool) pLocatorLabelDelimited locMap
src/Text/Pandoc/Logging.hs view
@@ -377,8 +377,7 @@        NoTitleElement fallback ->          "This document format requires a nonempty <title> element.\n" <>          "Defaulting to '" <> fallback <> "' as the title.\n" <>-         "To specify a title, use 'title' in metadata or " <>-         "--metadata title=\"...\"."+         "To specify a title, use --variable pagetitle=\"...\"."        NoLangSpecified ->          "No value for 'lang' was specified in the metadata.\n" <>          "It is recommended that lang be specified for this format."
src/Text/Pandoc/PDF.hs view
@@ -90,11 +90,27 @@ #else   let tmpdir = mediaDir #endif-  doc' <- handleImages opts tmpdir doc-  source <- writer opts{ writerExtensions = -- disable use of quote-                            -- ligatures to avoid bad ligatures like ?`-                            disableExtension Ext_smart-                             (writerExtensions opts) } doc'+  let isTeXFormat "context" = True+      isTeXFormat "tectonic" = True+      isTeXFormat "latexmk" = True+      isTeXFormat "lualatex" = True+      isTeXFormat "lualatex-dev" = True+      isTeXFormat "pdflatex" = True+      isTeXFormat "pdflatex-dev" = True+      isTeXFormat "xelatex" = True+      isTeXFormat _ = False+  let opts' = if isTeXFormat program+                 then -- disable quote ligatures to avoid bad ligatures like ?`+                      opts{ writerExtensions = disableExtension Ext_smart+                                (writerExtensions opts) }+                 else opts+  source <- fillMediaBag doc+              >>= extractMedia tmpdir+              >>= (if isTeXFormat program+                      then walkM (convertImages opts' tmpdir)+                      else return)+              >>= writer opts'+   verbosity <- getVerbosity   let compileHTML mkOutArgs = do         -- check to see if there is anything in mediabag, and if so,@@ -106,7 +122,7 @@         liftIO $           toPdfViaTempFile verbosity program pdfargs mkOutArgs ".html" source'   case takeBaseName program of-    "wkhtmltopdf" -> makeWithWkhtmltopdf program pdfargs writer opts doc+    "wkhtmltopdf" -> makeWithWkhtmltopdf program pdfargs writer opts' doc     "pagedjs-cli" -> compileHTML (\f -> ["-o", f])     "prince"      -> compileHTML (\f -> ["-o", f])     "weasyprint"  -> compileHTML (:[])@@ -114,7 +130,7 @@         toPdfViaTempFile verbosity program ("compile":pdfargs) (:[]) ".typ" source     "pdfroff" -> do       let paperargs =-            case lookupContext "papersize" (writerVariables opts) of+            case lookupContext "papersize" (writerVariables opts') of               Just s                 | T.takeEnd 1 s == "l" -> ["-P-p" <>                                            T.unpack (T.dropEnd 1 s), "-P-l"]@@ -127,7 +143,7 @@       generic2pdf program args source     "groff" -> do       let paperargs =-            case lookupContext "papersize" (writerVariables opts) of+            case lookupContext "papersize" (writerVariables opts') of               Just s                 | T.takeEnd 1 s == "l" -> ["-P-p" <>                                            T.unpack (T.dropEnd 1 s), "-P-l"]@@ -202,16 +218,7 @@   verbosity <- getVerbosity   liftIO $ toPdfViaTempFile verbosity program args (:[]) ".html" source -handleImages :: (PandocMonad m, MonadIO m)-             => WriterOptions-             -> FilePath      -- ^ temp dir to store images-             -> Pandoc        -- ^ document-             -> m Pandoc-handleImages opts tmpdir doc =-  fillMediaBag doc >>=-    extractMedia tmpdir >>=-    walkM (convertImages opts tmpdir)-+-- convert SVG to PDF, and pixel formatst to PNG or JPEG, for TeX formats convertImages :: (PandocMonad m, MonadIO m)               => WriterOptions -> FilePath -> Inline -> m Inline convertImages opts tmpdir (Image attr ils (src, tit)) = do
src/Text/Pandoc/Readers.hs view
@@ -25,7 +25,10 @@     -- * Readers: converting /to/ Pandoc format     Reader (..)   , readers+  , readAsciiDoc   , readDocx+  , readPptx+  , readXlsx   , readODT   , readMarkdown   , readCommonMark@@ -82,11 +85,14 @@ import Text.Pandoc.Extensions import qualified Text.Pandoc.Format as Format import Text.Pandoc.Options+import Text.Pandoc.Readers.AsciiDoc import Text.Pandoc.Readers.CommonMark import Text.Pandoc.Readers.Markdown import Text.Pandoc.Readers.Creole import Text.Pandoc.Readers.DocBook import Text.Pandoc.Readers.Docx+import Text.Pandoc.Readers.Pptx+import Text.Pandoc.Readers.Xlsx import Text.Pandoc.Readers.DokuWiki import Text.Pandoc.Readers.EPUB import Text.Pandoc.Readers.FB2@@ -138,6 +144,7 @@           ,("markdown_mmd",  TextReader readMarkdown)           ,("commonmark"   , TextReader readCommonMark)           ,("commonmark_x" , TextReader readCommonMark)+          ,("asciidoc"     , TextReader readAsciiDoc)           ,("creole"       , TextReader readCreole)           ,("dokuwiki"     , TextReader readDokuWiki)           ,("gfm"          , TextReader readCommonMark)@@ -157,6 +164,8 @@           ,("twiki"        , TextReader readTWiki)           ,("tikiwiki"     , TextReader readTikiWiki)           ,("docx"         , ByteStringReader readDocx)+          ,("pptx"         , ByteStringReader readPptx)+          ,("xlsx"         , ByteStringReader readXlsx)           ,("odt"          , ByteStringReader readODT)           ,("t2t"          , TextReader readTxt2Tags)           ,("epub"         , ByteStringReader readEPUB)
+ src/Text/Pandoc/Readers/AsciiDoc.hs view
@@ -0,0 +1,416 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}++{- |+   Module      : Text.Pandoc.Readers.AsciiDoc+   Copyright   : Copyright (C) 2024 John MacFarlane+   License     : GNU GPL, version 2 or above++   Maintainer  : John MacFarlane <jgm@berkeley.edu>+   Stability   : alpha+   Portability : portable++Reads and evaluates a AsciiDoc document as a Pandoc AST.+-}+module Text.Pandoc.Readers.AsciiDoc+  ( readAsciiDoc+  )+where++import Text.Pandoc.Class+import Text.Pandoc.Options+import Text.Pandoc.Definition+import Text.Pandoc.Walk+import Text.Pandoc.Shared (addPandocAttributes, blocksToInlines, safeRead,+                           tshow)+import qualified Text.Pandoc.UTF8 as UTF8+import qualified AsciiDoc as A+import Text.Pandoc.Error+import qualified Text.Pandoc.Builder as B+import Text.Pandoc.Readers.HTML (readHtml)+import Control.Monad.Except (throwError)+import Control.Monad+import Text.Pandoc.Parsing (newPos, sourceName)+import Text.Pandoc.Logging+import Text.Pandoc.Sources+import Control.Monad.State+import Data.List (intersperse, foldl')+import Data.Char (chr, ord)+import qualified Data.Text as T+import qualified Data.Map as M+import Data.Maybe (fromMaybe)++-- import Debug.Trace++-- | Read AsciiDoc from an input string and return a Pandoc document.+readAsciiDoc :: (PandocMonad m, ToSources a) => ReaderOptions -> a -> m Pandoc+readAsciiDoc _opts inp = do+  let Sources sources = toSources inp+  (mconcat <$> mapM+   (\(sourcepos, t) ->+     A.parseDocument getIncludeFile raiseError (sourceName sourcepos) t)+    sources)+   >>= resolveFootnotes+   >>= resolveStem+   >>= resolveIcons+   >>= toPandoc+ where+  getIncludeFile fp = UTF8.toText <$> readFileStrict fp+  raiseError fp pos msg = throwError $ PandocParseError $ T.pack+                            $ msg <> " at " <> show fp <>+                              " char " <> show pos++toPandoc :: PandocMonad m => A.Document -> m Pandoc+toPandoc doc =+  Pandoc <$> doMeta (A.docMeta doc)+         <*> (B.toList <$> doBlocks (A.docBlocks doc))++resolveFootnotes :: Monad m => A.Document -> m A.Document+resolveFootnotes doc = do+  evalStateT (A.mapInlines go doc) (mempty :: M.Map T.Text [A.Inline])+ where+   go (A.Inline attr (A.Footnote (Just (A.FootnoteId fnid)) ils)) = do+     fnmap <- get+     case M.lookup fnid fnmap of+       Just ils' ->+         pure $ A.Inline attr (A.Footnote (Just (A.FootnoteId fnid)) ils')+       Nothing -> do+         put $ M.insert fnid ils fnmap+         pure $ A.Inline attr (A.Footnote (Just (A.FootnoteId fnid)) ils)+   go x = pure x++resolveStem :: Monad m => A.Document -> m A.Document+resolveStem doc = do+  let defaultType = case M.lookup "stem" (A.docAttributes (A.docMeta doc)) of+                      Just "asciimath" -> A.AsciiMath+                      _ -> A.LaTeXMath+  let doInlineStem (A.Inline attr (A.Math Nothing t)) =+        pure $ A.Inline attr (A.Math (Just defaultType) t)+      doInlineStem x = pure x+  let doBlockStem (A.Block attr mbtit (A.MathBlock Nothing t)) =+        pure $ A.Block attr mbtit (A.MathBlock (Just defaultType) t)+      doBlockStem x = A.mapInlines doInlineStem x+  A.mapBlocks doBlockStem doc++-- resolve icons as either characters in an icon font or images+resolveIcons :: Monad m => A.Document -> m A.Document+resolveIcons doc = A.mapInlines fromIcon doc+ where+   docattrs = A.docAttributes (A.docMeta doc)+   iconFont = case M.lookup "icons" docattrs of+                Just "font" -> True+                _ -> False+   iconsdir = fromMaybe "./images/icons" $ M.lookup "iconsdir" docattrs+   icontype = fromMaybe "png" $ M.lookup "icontype" docattrs+   addClasses cls (A.Attr ps kvs) =+     A.Attr ps $+      case M.lookup "role" kvs of+       Just r -> M.insert "role" (T.unwords (r : cls)) kvs+       Nothing -> M.insert "role" (T.unwords cls) kvs+   fromIcon (A.Inline attr (A.Icon name)) =+     if iconFont+        then pure $+              A.Inline (addClasses ["fa", "fa-" <> name] attr) (A.Span [])+        else pure $ -- default is to use an image+              A.Inline (addClasses ["icon"] attr)+                 (A.InlineImage+                   (A.Target+                      (iconsdir <> "/" <> name <> "." <> icontype))+                      Nothing Nothing Nothing)+   fromIcon x = pure x++addAttribution :: Maybe A.Attribution -> B.Blocks -> B.Blocks+addAttribution Nothing bs = bs+addAttribution (Just (A.Attribution t)) bs = B.fromList $+  case B.toList bs of+    [B.Div attr bls] -> [B.Div attr (bls ++ [attrBlock])]+    [B.BlockQuote bls] -> [B.BlockQuote (bls ++ [attrBlock])]+    xs -> xs ++ [attrBlock]+ where+   attrBlock = Para (B.toList $ B.text $ "\x2014 " <> t)++doMeta :: PandocMonad m => A.Meta -> m B.Meta+doMeta meta = do+  tit' <- doInlines (A.docTitle meta)+  pure $+    (if tit' == mempty+        then id+        else B.setMeta "title" tit') .+    (case A.docAuthors meta of+       [] -> id+       as -> B.setMeta "author" (map fromAuthor as)) .+    (case A.docRevision meta of+       Nothing -> id+       Just (A.Revision vers mbdate mbremark) ->+         B.setMeta "version" vers .+         maybe id (B.setMeta "date") mbdate .+         maybe id (B.setMeta "remark") mbremark) .+    flip (foldl' (\m (k,v) ->+                    -- leave out flags that are set just for processing+                    if k == "sectids" || k == "stem"+                       then m+                       else if T.null v+                               then B.setMeta k True m+                               else B.setMeta k v m))+      (M.toList (A.docAttributes meta))+    $ mempty++fromAuthor :: A.Author -> B.Inlines+fromAuthor au = B.text (A.authorName au) <>+  maybe mempty (\email ->+    " (" <> B.link ("mailto:" <> email) "" (B.str email) <> ")")+    (A.authorEmail au)++doBlocks :: PandocMonad m => [A.Block] -> m B.Blocks+doBlocks = fmap mconcat . mapM doBlock++addBlockAttr :: A.Attr -> B.Blocks -> B.Blocks+addBlockAttr (A.Attr _ kvs') bs =+  case B.toList bs of+    x@(B.OrderedList{}) : xs -> -- "start" is handled in list attribs+      addPandocAttributes (M.toList $ M.delete "start" kvs)+             (B.singleton x) <> B.fromList xs+    x:xs -> addPandocAttributes (M.toList kvs) (B.singleton x)+                <> B.fromList xs+    [] -> mempty+ where+  kvs = M.mapKeys (\k -> if k == "role" then "class" else k) kvs'++addBlockTitle :: B.Inlines -> B.Blocks -> B.Blocks+addBlockTitle tit' bs =+  let tit = B.toList tit'+  in case B.toList bs of+    [B.Table attr _ colspecs thead tbody tfoot] ->+      B.singleton $ B.Table attr (B.Caption Nothing [B.Plain tit])+                     colspecs thead tbody tfoot+    [B.Figure attr _ bs'] ->+      B.singleton $ B.Figure attr (B.Caption Nothing [B.Plain tit]) bs'+    [B.Div attr (B.Div ("",["title"],[]) [Para _] : bs')] ->+      -- replace existing title, which might be e.g. "Note"+      B.singleton $ B.Div attr (B.Div ("",["title"],[]) [B.Para tit] : bs')+    [B.Div attr bs'] -> -- put title Div inside+      B.singleton $ B.Div attr (B.Div ("",["title"],[]) [B.Para tit] : bs')+    _ -> B.divWith B.nullAttr (B.divWith ("",["title"],[]) (B.para tit') <> bs)++doBlock :: PandocMonad m => A.Block -> m B.Blocks+doBlock (A.Block attr@(A.Attr ps kvs) mbtitle bt) = do+  mbtitle' <- case mbtitle of+                Nothing -> pure Nothing+                Just (A.BlockTitle ils) -> Just <$> doInlines ils+  addBlockAttr attr . maybe id addBlockTitle mbtitle' <$>+   case bt of+    A.Section (A.Level lev) ils bs -> do+      ils' <- doInlines ils+      bs' <- doBlocks bs+      pure $ (B.header lev ils') <> bs'+    A.DiscreteHeading (A.Level lev) ils ->+      B.header lev <$> doInlines ils+    A.Paragraph ils -> B.para <$> doInlines ils+    A.LiteralBlock t -> pure $ B.codeBlock t+    A.Listing mblang lns -> do+      let fromCallout (A.Callout i)+            | i <= 20 = T.pack [' ', chr (0x2460 + i - 1)]+            | otherwise = "<" <> tshow i <> ">"+      let fromSourceLine (A.SourceLine t callouts) =+            t <> mconcat (map fromCallout callouts)+      let code = T.intercalate "\n" $ map fromSourceLine lns+      let classes = case mblang of+                      Nothing -> []+                      Just (A.Language l) -> [l]+      pure $ B.codeBlockWith ("", classes, []) code+    A.IncludeListing _ _ Nothing -> pure mempty+    A.IncludeListing mblang _fp (Just lns) ->+      doBlock (A.Block mempty mbtitle (A.Listing mblang lns))+    A.ExampleBlock bs -> B.divWith ("",["example"],[]) <$> doBlocks bs+    A.Sidebar bs -> B.divWith ("",["sidebar"],[]) <$> doBlocks bs+    A.OpenBlock bs -> B.divWith ("",[],[]) <$> doBlocks bs+    A.QuoteBlock mbattrib bs ->+      addAttribution mbattrib . B.blockQuote <$> doBlocks bs+    A.Verse mbattrib bs ->+      addAttribution mbattrib . B.blockQuote <$> doBlocks bs+    -- TODO when texmath's asciimath parser works, convert:+    A.MathBlock (Just A.AsciiMath) t -> pure $ B.para $ B.displayMath t+    A.MathBlock (Just A.LaTeXMath) t -> pure $ B.para $ B.displayMath t+    A.MathBlock Nothing _ ->+      throwError $ PandocParseError "Encountered math type Nothing"+    A.List (A.BulletList _) items ->+      B.bulletList <$> mapM doItem items+    A.List A.CheckList items ->+      B.bulletList <$> mapM doItem items+    A.List (A.OrderedList _ mbstart) items -> do+      let start = fromMaybe (1 :: Int)+                    (mbstart `mplus` (M.lookup "start" kvs >>= safeRead))+      let getStyle xs = case xs of+                  "arabic":_ -> Decimal+                  "decimal":_ -> Decimal+                  "loweralpha":_ -> LowerAlpha+                  "upperalpha":_ -> UpperAlpha+                  "lowerroman":_ -> LowerRoman+                  "upperroman":_ -> UpperRoman+                  _:rest -> getStyle rest+                  [] -> DefaultStyle+      let sty = getStyle ps+      let delim = DefaultDelim+      B.orderedListWith (start, sty, delim) <$> mapM doItem items+    A.List A.CalloutList items ->+      B.divWith ("",["callout-list"],[]) . B.orderedList <$> mapM doItem items+    A.DefinitionList items+      | "ordered" `elem` ps ->+          B.orderedList <$>+             mapM (fmap (B.definitionList . (:[])) . doDefListItem) items+      | otherwise -> B.definitionList <$> mapM doDefListItem items+    A.Table specs mbHeader rows mbFooter -> do+      let toAlign A.AlignLeft = B.AlignLeft+          toAlign A.AlignCenter = B.AlignCenter+          toAlign A.AlignRight = B.AlignRight+      let fromCell (A.TableCell bs mbHorizAlign _mbVertAlign colspan rowspan) =+            B.Cell B.nullAttr (maybe B.AlignDefault toAlign mbHorizAlign)+                        (B.RowSpan rowspan) (B.ColSpan colspan) . B.toList+                   <$> doBlocks bs+      let fromRow (A.TableRow cs) = B.Row B.nullAttr <$> mapM fromCell cs+      tbody <- B.TableBody B.nullAttr (B.RowHeadColumns 0) [] <$> mapM fromRow rows+      thead <- B.TableHead B.nullAttr <$> maybe (pure []) (mapM fromRow) mbHeader+      tfoot <- B.TableFoot B.nullAttr <$> maybe (pure []) (mapM fromRow) mbFooter+      let totalWidth = sum $ map (fromMaybe 1 . A.colWidth) specs+      let toColSpec spec = (maybe B.AlignDefault toAlign (A.colHorizAlign spec),+                             maybe B.ColWidthDefault+                               (B.ColWidth . (\x ->+                                   fromIntegral x / fromIntegral totalWidth))+                               (A.colWidth spec))+      let colspecs = map toColSpec specs+      pure $ B.table (B.Caption Nothing mempty) -- added by addBlockTitle+                colspecs thead [tbody] tfoot+    A.BlockImage target mbalt mbw mbh -> do+      img' <- doInline (A.Inline mempty (A.InlineImage target mbalt mbw mbh))+      -- TODO have a global function that adds the title to caption here:+      pure $ B.figure (Caption Nothing mempty) -- added by addBlockTitle+                      (B.plain img')+    -- TODO alt text?+    A.BlockAudio (A.Target t) ->+      pure $ B.plain $ B.image t "" (B.str t)+    -- TODO alt text?+    A.BlockVideo (A.Target t) ->+      pure $ B.plain $ B.image t "" (B.str t)+    A.TOC -> pure $ B.divWith ("toc",[],[]) mempty+    A.Admonition admonitionType bs -> do+      let admon = T.pack $ show admonitionType+      bs' <- doBlocks bs+      pure $ B.divWith ("",[T.toLower admon],[])+           $ B.divWith ("",["title"],[]) (B.para (B.str admon)) <> bs'+    A.PageBreak ->+      pure $ B.divWith ("", ["page-break"], [("wrapper", "1")]) B.horizontalRule+    A.ThematicBreak -> pure $ B.horizontalRule+    A.Include fp (Just bs) ->+      B.divWith ("",["included"],[("path",T.pack fp)]) <$> doBlocks bs+    A.Include fp Nothing -> do+      report $ CouldNotLoadIncludeFile (T.pack fp) (newPos "" 0 0)+      pure mempty+    A.PassthroughBlock t ->+         case runPure (readHtml def{+                               readerExtensions = extensionsFromList [Ext_raw_html]+                               } t) of+        Left _ -> pure $ B.rawBlock "html" t+        Right (Pandoc _ bs) -> pure $ B.fromList bs++doItem :: PandocMonad m => A.ListItem -> m B.Blocks+doItem (A.ListItem Nothing bs) = doBlocks bs+doItem (A.ListItem (Just checkstate) bs) = do+  bs' <- doBlocks bs+  let check = case checkstate of+                A.Checked -> Str "\9746"+                A.Unchecked -> Str "\9744"+  pure $ B.fromList+       $ case B.toList bs' of+           (B.Para ils : rest) -> B.Para (check : B.Space : ils) : rest+           (B.Plain ils : rest) -> B.Plain (check : B.Space : ils) : rest+           rest -> B.Para [check] : rest++doDefListItem :: PandocMonad m+              => ([A.Inline], [A.Block]) -> m (B.Inlines , [B.Blocks])+doDefListItem (lab, bs) = do+  lab' <- doInlines lab+  bs' <- doBlocks bs+  pure (lab', [bs'])++doInlines :: PandocMonad m => [A.Inline] -> m B.Inlines+doInlines = fmap mconcat . mapM doInline++doInline :: PandocMonad m => A.Inline -> m B.Inlines+doInline (A.Inline (A.Attr _ps kvs') it) = do+  let kvs = M.mapKeys (\k -> if k == "role" then "class" else k) kvs'+  addPandocAttributes (M.toList kvs) <$>+   case it of+    A.Str t -> pure $ B.text t+    A.HardBreak -> pure B.linebreak+    A.Bold ils -> B.strong <$> doInlines ils+    A.Italic ils -> B.emph <$> doInlines ils+    A.Monospace ils -> walk monospaceStr <$> doInlines ils+    A.Superscript ils -> B.superscript <$> doInlines ils+    A.Subscript ils -> B.subscript <$> doInlines ils+    A.Highlight ils -> B.spanWith ("",["mark"],[]) <$> doInlines ils+    A.Strikethrough ils -> B.strikeout <$> doInlines ils+    A.DoubleQuoted ils -> B.doubleQuoted <$> doInlines ils+    A.SingleQuoted ils -> B.singleQuoted <$> doInlines ils+    -- TODO when texmath's asciimath parser works, convert:+    A.Math (Just A.AsciiMath) t -> pure $ B.math t+    A.Math (Just A.LaTeXMath) t -> pure $ B.math t+    A.Math Nothing _ ->+      throwError $ PandocParseError "Encountered math type Nothing"+    A.Icon t -> pure $ B.spanWith ("",["icon"],[("name",t)])+                         (B.str ("[" <> t <> "]"))+    A.Button t -> pure $ B.spanWith ("",["button"],[])+                         (B.strong $ B.str ("[" <> t <> "]"))+    A.Kbd ts -> pure $ mconcat $ intersperse (B.str "+") $+         map (B.spanWith ("",["kbd"],[]) . B.strong . B.str) ts+    A.Menu ts -> pure $ B.spanWith ("",["menu"],[]) $+        B.strong $ B.text $ T.intercalate " › " ts+    -- TODO do we need linktype?+    A.Link _linkType (A.Target t) ils -> B.link t "" <$> doInlines ils+    A.InlineImage (A.Target url) mbalt mbwidth mbheight -> do+      let alt = case mbalt of+                  Just (A.AltText t) -> B.text t+                  Nothing -> mempty+          width = case mbwidth of+                  Just (A.Width n) -> [("width", T.pack $ show n <> "px")]+                  Nothing -> []+          height = case mbheight of+                  Just (A.Height n) -> [("height", T.pack $ show n <> "px")]+                  Nothing -> []+      pure $ B.imageWith ("",[], width ++ height) url "" alt+    A.Footnote _ ils -> B.note . B.para <$> doInlines ils+    A.InlineAnchor t _ -> pure $ B.spanWith (t, [], []) mempty+    A.BibliographyAnchor t _ -> pure $ B.spanWith (t, [], []) mempty+    A.CrossReference t Nothing ->+      pure $ B.linkWith ("",["cross-reference"],[]) ("#" <> t) "" (B.str t)+    A.CrossReference t (Just ils) -> do+      B.linkWith ("",["cross-reference"],[]) ("#" <> t) "" <$> doInlines ils+    A.AttributeReference (A.AttributeName t) -> -- if this is here, it's unresolved+      pure $ B.str ("{" <> t <> "}")+    A.Span ils -> B.spanWith B.nullAttr <$> doInlines ils+    A.IndexEntry (A.TermInText t) ->+      pure $ B.spanWith ("",["index"],[("term",t)]) (B.text t)+    A.IndexEntry (A.TermConcealed ts) ->+      pure $ B.spanWith ("",["index"],[("term",T.intercalate "," ts)]) mempty+    A.Counter name ctype val ->+      pure $ B.spanWith ("",["counter"],[("name",name)]) $ B.str $+        case ctype of+          A.DecimalCounter -> tshow val+          A.UpperAlphaCounter -> T.singleton $ chr (ord 'A' + val - 1)+          A.LowerAlphaCounter -> T.singleton $ chr (ord 'a' + val - 1)+    -- Passthrough is hard to get right, because pandoc's RawInline needs+    -- a format specifier. Often in asciidoc passthrough is used as a form+    -- of escaping, so the best approach seems to be treating it as HTML+    -- and parsing it:+    A.Passthrough t -> do+      case runPure (readHtml def{+                               readerExtensions = extensionsFromList [Ext_raw_html]+                               } t) of+        Left _ -> pure $ B.rawInline "html" t+        Right (Pandoc _ bs) -> pure $ B.fromList . blocksToInlines $ bs++monospaceStr :: Inline -> Inline+monospaceStr (Str t) = Code B.nullAttr t+monospaceStr x = x
src/Text/Pandoc/Readers/Djot.hs view
@@ -186,7 +186,7 @@ convertInline :: PandocMonad m => D.Node D.Inline -> ReaderT Env m Inlines convertInline (D.Node pos attr il) = addAttrToInline pos attr <$>   case il of-    D.Str bs -> pure $ str (UTF8.toText bs)+    D.Str bs -> pure $ text (UTF8.toText bs)     D.Emph ils -> emph <$> convertInlines ils     D.Strong ils -> strong <$> convertInlines ils     D.Highlight ils -> spanWith ("",["mark"],[]) <$> convertInlines ils
src/Text/Pandoc/Readers/Docx.hs view
@@ -482,6 +482,7 @@                           ++ [("bold","") | entryBold ie]                           ++ [("italic","") | entryItalic ie])) mempty     PagerefField fieldAnchor True -> parPartToInlines' $ InternalHyperLink fieldAnchor children+    CrossrefField fieldAnchor True -> parPartToInlines' $ InternalHyperLink fieldAnchor children     EndNoteCite t -> do       formattedCite <- smushInlines <$> mapM parPartToInlines' children       opts <- asks docxOptions
src/Text/Pandoc/Readers/Docx/Fields.hs view
@@ -35,6 +35,7 @@ data FieldInfo = HyperlinkField URL                 -- The boolean indicates whether the field is a hyperlink.                | PagerefField Anchor Bool+               | CrossrefField Anchor Bool                | IndexrefField IndexEntry                | CslCitation T.Text                | CslBibliography@@ -57,6 +58,8 @@     <|>     indexref     <|>+    crossref+    <|>     addIn     <|>     return UnknownField@@ -140,6 +143,15 @@   switches <- many fieldSwitch   let isLink = any ((== 'h') . fst) switches   return $ PagerefField farg isLink++crossref :: Parser FieldInfo+crossref = do+  string "REF"+  spaces+  farg <- fieldArgument+  switches <- many fieldSwitch+  let isLink = any ((== 'h') . fst) switches+  return $ CrossrefField farg isLink  -- second element of tuple is optional "see". indexref :: Parser FieldInfo
src/Text/Pandoc/Readers/Docx/Parse.hs view
@@ -1361,13 +1361,19 @@   -- return svg if present:   filterElementName (\(QName tag _ _) -> tag == "svgBlip") el `mplus` pure blip +-- | Checks if any style in the style hierarchy is a caption style. hasCaptionStyle :: ParagraphStyle -> Bool-hasCaptionStyle parstyle = any (isCaptionStyleName . pStyleName) (pStyle parstyle)+hasCaptionStyle =+  any (isCaptionStyleName . pStyleName) . concatMap nestedStyles . pStyle  where -- note that these are case insensitive:    isCaptionStyleName "caption" = True    isCaptionStyleName "table caption" = True    isCaptionStyleName "image caption" = True    isCaptionStyleName _ = False++   -- Gets all the style names in the style hierarchy+   nestedStyles :: ParStyle -> [ParStyle]+   nestedStyles ps = ps : maybe [] nestedStyles (psParentStyle ps)  stripCaptionLabel :: [Element] -> [Element] stripCaptionLabel els =
src/Text/Pandoc/Readers/Docx/Util.hs view
@@ -24,51 +24,11 @@                                       , extractChildren                                       ) where -import qualified Data.Text as T-import Data.Text (Text)-import Text.Pandoc.XML.Light-import qualified Data.Map as M import Data.List (partition)--type NameSpaces = M.Map Text Text--elemToNameSpaces :: Element -> NameSpaces-elemToNameSpaces = foldr (\(Attr qn val) ->-                             case qn of-                               QName s _ (Just "xmlns") -> M.insert s val-                               _ -> id) mempty . elAttribs--elemName :: NameSpaces -> Text -> Text -> QName-elemName ns prefix name =-  QName name (M.lookup prefix ns)-             (if T.null prefix then Nothing else Just prefix)--isElem :: NameSpaces -> Text -> Text -> Element -> Bool-isElem ns prefix name element =-  let ns' = ns <> elemToNameSpaces element-  in qName (elName element) == name &&-     qURI (elName element) == M.lookup prefix ns'--findChildByName :: NameSpaces -> Text -> Text -> Element -> Maybe Element-findChildByName ns pref name el =-  let ns' = ns <> elemToNameSpaces el-  in  findChild (elemName ns' pref name) el--findChildrenByName :: NameSpaces -> Text -> Text -> Element -> [Element]-findChildrenByName ns pref name el =-  let ns' = ns <> elemToNameSpaces el-  in  findChildren (elemName ns' pref name) el---- | Like 'findChildrenByName', but searches descendants.-findElementByName :: NameSpaces -> Text -> Text -> Element -> Maybe Element-findElementByName ns pref name el =-  let ns' = ns <> elemToNameSpaces el-  in  findElement (elemName ns' pref name) el--findAttrByName :: NameSpaces -> Text -> Text -> Element -> Maybe Text-findAttrByName ns pref name el =-  let ns' = ns <> elemToNameSpaces el-  in  findAttr (elemName ns' pref name) el+import Text.Pandoc.XML.Light+import Text.Pandoc.Readers.OOXML.Shared+  (NameSpaces, elemName, isElem, elemToNameSpaces,+   findChildByName, findChildrenByName, findElementByName, findAttrByName)   -- | Removes child elements that satisfy a given condition.
src/Text/Pandoc/Readers/LaTeX.hs view
@@ -144,16 +144,28 @@   toks <- getInputTokens   snd <$> (           rawLaTeXParser toks-             (macroDef (const mempty) <|>+             (makeAtLetterSection <|>+              macroDef (const mempty) <|>               do choice (map controlSeq                    ["include", "input", "subfile", "usepackage"])                  skipMany opt                  braced                  return mempty) blocks       <|> rawLaTeXParser toks-           (environment <|> blockCommand)+           (void (environment <|> blockCommand))            (mconcat <$> many (block <|> beginOrEndCommand))) +makeAtLetterSection :: PandocMonad m => LP m ()+makeAtLetterSection = try $ do+  controlSeq "makeatletter"+  void $ manyTill+    (   whitespace+    <|> newlineTok+    <|> macroDef (const ())+    <|> void environment+    <|> void blockCommand+    ) (controlSeq "makeatother")+ -- See #4667 for motivation; sometimes people write macros -- that just evaluate to a begin or end command, which blockCommand -- won't accept.@@ -177,8 +189,7 @@           (   rawLaTeXParser toks               (mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))               inlines-          <|> rawLaTeXParser toks (inlineEnvironment <|> inlineCommand')-              inlines+          <|> rawLaTeXParser toks (void inline) inlines           )   finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439   return $ raw <> T.pack finalbraces@@ -187,7 +198,7 @@ inlineCommand = do   lookAhead (try (char '\\' >> letter))   toks <- getInputTokens-  fst <$> rawLaTeXParser toks (inlineEnvironment <|> inlineCommand')+  fst <$> rawLaTeXParser toks (void (inlineEnvironment <|> inlineCommand'))           inlines  -- inline elements:@@ -397,7 +408,6 @@     , ("thanks", skipopts >> note <$> grouped block)     , ("footnote", skipopts >> footnote)     , ("newline", pure B.linebreak)-    , ("linebreak", pure B.linebreak)     , ("passthrough", fixPassthroughEscapes <$> tok)     -- \passthrough macro used by latex writer                            -- for listings@@ -426,7 +436,6 @@     , ("textcolor", coloredInline "color")     , ("colorbox", coloredInline "background-color")     -- etoolbox-    , ("ifstrequal", ifstrequal)     , ("newtoggle", braced >>= newToggle)     , ("toggletrue", braced >>= setToggle True)     , ("togglefalse", braced >>= setToggle False)@@ -566,18 +575,6 @@                   report $ UndefinedToggle name' pos   return () -ifstrequal :: (PandocMonad m, Monoid a) => LP m a-ifstrequal = do-  str1 <- tok-  str2 <- tok-  ifequal <- withVerbatimMode braced-  ifnotequal <- withVerbatimMode braced-  TokStream _ ts <- getInput-  if str1 == str2-     then setInput $ TokStream False (ifequal ++ ts)-     else setInput $ TokStream False (ifnotequal ++ ts)-  return mempty- coloredInline :: PandocMonad m => Text -> LP m Inlines coloredInline stylename = do   skipopts@@ -1025,6 +1022,11 @@    , ("epigraph", epigraph)    -- alignment    , ("raggedright", pure mempty)+   -- etoolbox+   , ("newtoggle", braced >>= newToggle)+   , ("toggletrue", braced >>= setToggle True)+   , ("togglefalse", braced >>= setToggle False)+   , ("iftoggle", try $ ifToggle >> block)    ]  skipSameFileToks :: PandocMonad m => LP m ()@@ -1068,12 +1070,7 @@    , ("ly", rawVerbEnv "ly")    -- amsthm    , ("proof", proof blocks opt)-   -- etoolbox-   , ("ifstrequal", ifstrequal)-   , ("newtoggle", braced >>= newToggle)-   , ("toggletrue", braced >>= setToggle True)-   , ("togglefalse", braced >>= setToggle False)-   , ("iftoggle", try $ ifToggle >> block)+   -- other    , ("CSLReferences", braced >> braced >> env "CSLReferences" blocks)    , ("otherlanguage", env "otherlanguage" otherlanguageEnv)    ]
src/Text/Pandoc/Readers/LaTeX/Math.hs view
@@ -21,7 +21,7 @@ import Text.Pandoc.Readers.LaTeX.Parsing import Text.Pandoc.TeX import Text.Pandoc.Class-import Text.Pandoc.Shared (trimMath, stripTrailingNewlines)+import Text.Pandoc.Shared (trimMath, trimr) import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,                             optional, space, spaces, withRaw, (<|>)) import Control.Applicative ((<|>), optional)@@ -82,7 +82,7 @@ mathEnv name = withMathMode $ do   optional blankline   res <- manyTill anyTok (end_ name)-  return $ stripTrailingNewlines $ untokenize res+  return $ trimr $ untokenize res  inlineEnvironment :: PandocMonad m => LP m Inlines inlineEnvironment = try $ do
src/Text/Pandoc/Readers/LaTeX/Parsing.hs view
@@ -279,7 +279,7 @@        return result  rawLaTeXParser :: (PandocMonad m, HasMacros s, HasReaderOptions s, Show a)-               => [Tok] -> LP m a -> LP m a+               => [Tok] -> LP m () -> LP m a                -> ParsecT Sources s m (a, Text) rawLaTeXParser toks parser valParser = do   pstate <- getState@@ -301,14 +301,14 @@               Left _    -> mzero               Right ((val, raw), st) -> do                 updateState (updateMacros ((NonEmpty.head (sMacros st)) <>))-                let skipTilPos stopPos = do-                      anyChar+                let rawChar = do                       pos <- getPosition-                      if pos >= stopPos-                         then return ()-                         else skipTilPos stopPos-                skipTilPos endpos-                let result = untokenize raw+                      if pos >= endpos+                         then mzero+                         else anyChar+                result <- (guardEnabled Ext_latex_macros+                             >> (untokenize raw <$ skipMany rawChar))+                          <|> T.pack <$> many rawChar                 -- ensure we end with space if input did, see #4442                 let result' =                       case reverse toks' of@@ -650,16 +650,30 @@     Tok pos Word t : _       | startsWithAlphaNum t -> return $ Tok pos Spaces " " : ts'     _ -> return ts'-trySpecialMacro "iftrue" ts = handleIf True ts-trySpecialMacro "iffalse" ts = handleIf False ts+trySpecialMacro "iftrue" ts = handleIf (ifParser True) ts+trySpecialMacro "iffalse" ts = handleIf (ifParser False) ts trySpecialMacro "ifmmode" ts = do   mathMode <- sMathMode <$> getState-  handleIf mathMode ts+  handleIf (ifParser mathMode) ts+trySpecialMacro "ifstrequal" ts = do+  handleIf ifStrequalParser ts trySpecialMacro _ _ = mzero -handleIf :: PandocMonad m => Bool -> [Tok] -> LP m [Tok]-handleIf b ts = do-  res' <- lift $ runParserT (ifParser b) defaultLaTeXState "tokens"+ifStrequalParser :: PandocMonad m => LP m [Tok]+ifStrequalParser = do+  str1 <- braced <|> count 1 anyTok+  str2 <- braced <|> count 1 anyTok+  ifequal <- withVerbatimMode (braced <|> count 1 anyTok)+  ifnotequal <- withVerbatimMode (braced <|> count 1 anyTok)+  TokStream _ ts <- getInput+  return $+    if untokenize str1 == untokenize str2+       then ifequal ++ ts+       else ifnotequal ++ ts++handleIf :: PandocMonad m => LP m [Tok] -> [Tok] -> LP m [Tok]+handleIf parser ts = do+  res' <- lift $ runParserT parser defaultLaTeXState "tokens"                $ TokStream False ts   case res' of     Left _ -> Prelude.fail "Could not parse conditional"
src/Text/Pandoc/Readers/Markdown.hs view
@@ -1826,9 +1826,9 @@         return $ "(" <> result <> ")"   let linkTitle' = try $ spnl >> linkTitle   let urlChunk = do-        notFollowedBy linkTitle'         try parenthesizedChars-          <|> (notFollowedBy (oneOf " )") >> litChar)+          <|> (notFollowedBy (oneOf "\n\r )") >> litChar)+          <|> (lookAhead (oneOf "\n\r") >> notFollowedBy linkTitle' >> litChar)           <|> try (many1Char spaceChar <* notFollowedBy (oneOf "\"')"))   let sourceURL = T.unwords . T.words . T.concat <$> many urlChunk   src <- try (litBetween '<' '>') <|> try base64DataURI <|> sourceURL
+ src/Text/Pandoc/Readers/OOXML/Shared.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.OOXML.Shared+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Shared utilities for Office Open XML (OOXML) readers (DOCX, PPTX).+Provides common functions for ZIP archive handling, XML parsing,+namespace management, and DrawingML parsing.+-}+module Text.Pandoc.Readers.OOXML.Shared+  ( -- * Constants+    emusPerInch+  , emuToInches+  , inchesToEmu+    -- * Types+  , NameSpaces+  , elemName+  , elemToNameSpaces+  , isElem+  , findChildByName+  , findChildrenByName+  , findElementByName+  , findAttrByName+  ) where++import qualified Data.Map as M+import qualified Data.Text as T+import Data.Text (Text)+import Text.Pandoc.XML.Light++-- | Type alias for namespace mappings+type NameSpaces = M.Map Text Text++-- | English Metric Units per inch+-- 1 inch = 914400 EMUs (used in OOXML for dimensions)+emusPerInch :: Integer+emusPerInch = 914400++-- | Convert EMUs to inches+emuToInches :: Integer -> Double+emuToInches n = fromIntegral n / fromIntegral emusPerInch++-- | Convert inches to EMUs+inchesToEmu :: Double -> Integer+inchesToEmu n = round (n * fromIntegral emusPerInch)++-- | Extract namespace declarations from element attributes+elemToNameSpaces :: Element -> NameSpaces+elemToNameSpaces = foldr (\(Attr qn val) ->+                            case qn of+                              QName s _ (Just "xmlns") -> M.insert s val+                              _ -> id) mempty . elAttribs++-- | Create a qualified name from namespace map, prefix, and local name+elemName :: NameSpaces -> Text -> Text -> QName+elemName ns prefix name =+  QName name+        (M.lookup prefix ns)+        (if T.null prefix then Nothing else Just prefix)++-- | Check if element matches namespace prefix and local name+isElem :: NameSpaces -> Text -> Text -> Element -> Bool+isElem ns prefix name element =+  let ns' = ns <> elemToNameSpaces element+  in  qName (elName element) == name &&+      qURI (elName element) == M.lookup prefix ns'++-- | Find first child element matching namespace and name+findChildByName :: NameSpaces -> Text -> Text -> Element -> Maybe Element+findChildByName ns pref name el =+  let ns' = ns <> elemToNameSpaces el+  in  findChild (elemName ns' pref name) el++-- | Find all children matching namespace and name+findChildrenByName :: NameSpaces -> Text -> Text -> Element -> [Element]+findChildrenByName ns pref name el =+  let ns' = ns <> elemToNameSpaces el+  in  findChildren (elemName ns' pref name) el++-- | Find element anywhere in descendants matching namespace and name+findElementByName :: NameSpaces -> Text -> Text -> Element -> Maybe Element+findElementByName ns pref name el =+  let ns' = ns <> elemToNameSpaces el+  in  findElement (elemName ns' pref name) el++-- | Find attribute value by namespace prefix and name+findAttrByName :: NameSpaces -> Text -> Text -> Element -> Maybe Text+findAttrByName ns pref name el =+  let ns' = ns <> elemToNameSpaces el+  in  findAttr (elemName ns' pref name) el
+ src/Text/Pandoc/Readers/Pptx.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Pptx+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Conversion of PPTX (PowerPoint) documents to 'Pandoc' document.+-}+module Text.Pandoc.Readers.Pptx (readPptx) where++import qualified Data.ByteString.Lazy as B+import qualified Data.Text as T+import Codec.Archive.Zip (toArchiveOrFail)+import Control.Monad.Except (throwError)+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import Text.Pandoc.Definition (Pandoc(..))+import Text.Pandoc.Error (PandocError(..))+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Readers.Pptx.Parse (archiveToPptx)+import Text.Pandoc.Readers.Pptx.Slides (pptxToOutput)++-- | Read PPTX file into Pandoc AST+readPptx :: PandocMonad m => ReaderOptions -> B.ByteString -> m Pandoc+readPptx opts bytes =+  case toArchiveOrFail bytes of+    Right archive ->+      case archiveToPptx archive of+        Right pptx -> do+          -- Convert Pptx intermediate to Pandoc AST+          (meta, blocks) <- pptxToOutput opts pptx+          return $ Pandoc meta blocks++        Left err ->+          throwError $ PandocParseError $+            "Failed to parse PPTX: " <> err++    Left err ->+      throwError $ PandocParseError $+        "Failed to unpack PPTX archive: " <> T.pack err
+ src/Text/Pandoc/Readers/Pptx/Parse.hs view
@@ -0,0 +1,216 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Pptx.Parse+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Parsing of PPTX archive to intermediate representation.+-}+module Text.Pandoc.Readers.Pptx.Parse+  ( Pptx(..)+  , PresentationDoc(..)+  , PptxSlide(..)+  , SlideId(..)+  , archiveToPptx+  ) where++import Codec.Archive.Zip (Archive, Entry, findEntryByPath, fromEntry)+import qualified Data.ByteString.Lazy as B+import Data.List (find)+import Data.Maybe (mapMaybe)+import qualified Data.Text as T+import qualified Data.Text.Lazy.Encoding as TL+import Data.Text (Text)+import System.FilePath (splitFileName)+import Text.Pandoc.Readers.OOXML.Shared+import Text.Pandoc.XML.Light+import Text.Read (readMaybe)++-- | Slide identifier+newtype SlideId = SlideId Int deriving (Show, Eq, Ord)++-- | Complete PPTX document (intermediate representation)+data Pptx = Pptx+  { pptxPresentation :: PresentationDoc+  , pptxSlides       :: [PptxSlide]+  , pptxArchive      :: Archive+  } deriving (Show)++-- | Individual slide data+data PptxSlide = PptxSlide+  { slideId      :: SlideId+  , slidePath    :: FilePath+  , slideElement :: Element     -- The parsed p:sld element+  , slideRels    :: [(Text, Text)]  -- Slide relationships+  } deriving (Show)++-- | Presentation-level information from presentation.xml+data PresentationDoc = PresentationDoc+  { presNameSpaces   :: NameSpaces+  , presSlideSize    :: (Integer, Integer)  -- (width, height) in pixels+  , presSlideIds     :: [(SlideId, Text)]   -- (slideId, relationshipId)+  } deriving (Show)++-- | Parse PPTX archive to intermediate representation+archiveToPptx :: Archive -> Either Text Pptx+archiveToPptx archive = do+  -- Find and parse presentation.xml+  presPath <- getPresentationXmlPath archive+  presElem <- loadXMLFromArchive archive presPath+  presDoc <- elemToPresentation presElem++  -- Load presentation relationships to resolve slide paths+  presRelsPath <- getPresentationRelsPath archive presPath+  presRels <- loadRelationships archive presRelsPath++  -- Parse each slide+  slides <- mapM (parseSlide archive presRels) (presSlideIds presDoc)++  return $ Pptx presDoc slides archive++-- | Find presentation.xml via root relationships+getPresentationXmlPath :: Archive -> Either Text FilePath+getPresentationXmlPath archive = do+  -- Load _rels/.rels+  relsEntry <- maybeToEither "Missing _rels/.rels" $+               findEntryByPath "_rels/.rels" archive++  relsElem <- parseXMLFromEntry relsEntry++  -- The Relationships element has a default namespace, but Relationship children don't use prefix+  -- We need to look at all children regardless of namespace+  let relElems = onlyElems $ elContent relsElem++  -- Look for relationship containing "officeDocument" in Type attribute+  case find isOfficeDocRel relElems of+    Nothing -> Left $ "No presentation.xml relationship found. Found " <>+                     T.pack (show (length relElems)) <> " relationships."+    Just rel -> do+      target <- maybeToEither "Missing Target attribute" $+                findAttr (unqual "Target") rel+      return $ T.unpack target  -- Convert Text to FilePath++  where+    isOfficeDocRel el =+      case findAttr (unqual "Type") el of+        -- Must end with "/officeDocument" to avoid matching "/extended-properties"+        Just relType -> "/officeDocument" `T.isSuffixOf` relType+        Nothing -> False++-- | Load and parse XML from archive entry+loadXMLFromArchive :: Archive -> FilePath -> Either Text Element+loadXMLFromArchive archive path = do+  entry <- maybeToEither ("Entry not found: " <> T.pack path) $+           findEntryByPath path archive++  let xmlBytes = fromEntry entry+  parseXMLFromBS xmlBytes++-- | Parse XML from ByteString+parseXMLFromBS :: B.ByteString -> Either Text Element+parseXMLFromBS = parseXMLElement . TL.decodeUtf8++-- | Parse XML from Entry+parseXMLFromEntry :: Entry -> Either Text Element+parseXMLFromEntry = parseXMLFromBS . fromEntry++-- | Parse presentation.xml element to PresentationDoc+elemToPresentation :: Element -> Either Text PresentationDoc+elemToPresentation presElem = do+  let ns = elemToNameSpaces presElem++  -- Extract slide size (with defaults)+  let sizeElem = findChildByName ns "p" "sldSz" presElem+      (widthEMU, heightEMU) = case sizeElem of+        Just el ->+          let cx = readAttrInt "cx" el+              cy = readAttrInt "cy" el+           in (cx, cy)+        Nothing -> (9144000, 6858000)  -- Default 10" x 7.5"++  -- Convert EMUs to pixels (approximate for metadata)+  let width = widthEMU `div` emusPerInch+      height = heightEMU `div` emusPerInch++  -- Extract slide ID list (optional - some presentations may have no slides)+  let sldIdLstElem = findChildByName ns "p" "sldIdLst" presElem++  slideRefs <- case sldIdLstElem of+    Nothing -> return []  -- No slides is valid for templates/masters-only presentations+    Just el -> do+      let sldIdElems = findChildren (elemName ns "p" "sldId") el+      mapM (extractSlideRef ns) (zip [1..] sldIdElems)++  return $ PresentationDoc+    { presNameSpaces = ns+    , presSlideSize = (width, height)+    , presSlideIds = slideRefs+    }++-- | Extract slide ID and relationship ID from p:sldId element+extractSlideRef :: NameSpaces -> (Int, Element) -> Either Text (SlideId, Text)+extractSlideRef ns (idx, sldIdElem) = do+  relId <- maybeToEither ("Missing r:id in slide " <> T.pack (show idx)) $+           findAttrByName ns "r" "id" sldIdElem++  return (SlideId idx, relId)++-- | Safe read attribute as Integer (with default of 0)+readAttrInt :: Text -> Element -> Integer+readAttrInt attrName el =+  case findAttr (unqual attrName) el of+    Just str -> case readMaybe (T.unpack str) of+      Just n -> n+      Nothing -> 0+    Nothing -> 0++-- | Get presentation relationships path+getPresentationRelsPath :: Archive -> FilePath -> Either Text FilePath+getPresentationRelsPath _archive presPath =+  -- ppt/presentation.xml → ppt/_rels/presentation.xml.rels+  let (dir, file) = splitFileName presPath+      relsPath = dir ++ "/_rels/" ++ file ++ ".rels"+   in Right relsPath++-- | Load relationships from .rels file+loadRelationships :: Archive -> FilePath -> Either Text [(Text, Text)]+loadRelationships archive relsPath =+  case findEntryByPath relsPath archive of+    Nothing -> Right []  -- No relationships is OK+    Just entry -> do+      relsElem <- parseXMLFromEntry entry+      let relElems = onlyElems $ elContent relsElem+      return $ mapMaybe extractRelationship relElems+  where+    extractRelationship el = do+      relId <- findAttr (unqual "Id") el+      target <- findAttr (unqual "Target") el+      return (relId, target)++-- | Parse a single slide+parseSlide :: Archive -> [(Text, Text)] -> (SlideId, Text) -> Either Text PptxSlide+parseSlide archive rels (sid, relId) = do+  -- Resolve relationship to get slide path+  target <- maybeToEither ("Relationship not found: " <> relId) $+            lookup relId rels++  -- Resolve relative path: ppt/slides/slide1.xml+  let slidePath' = "ppt/" <> T.unpack target++  -- Load and parse slide XML+  slideElem <- loadXMLFromArchive archive slidePath'++  -- Load slide-specific relationships+  slideRelsPath <- getPresentationRelsPath archive slidePath'+  slideRels' <- loadRelationships archive slideRelsPath++  return $ PptxSlide sid slidePath' slideElem slideRels'++-- | Helper: Maybe a -> Either Text a+maybeToEither :: Text -> Maybe a -> Either Text a+maybeToEither err Nothing = Left err+maybeToEither _ (Just x) = Right x
+ src/Text/Pandoc/Readers/Pptx/Shapes.hs view
@@ -0,0 +1,330 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-partial-fields #-}+{- |+   Module      : Text.Pandoc.Readers.Pptx.Shapes+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Parsing of PPTX shapes (text boxes, images, tables, diagrams).+-}+module Text.Pandoc.Readers.Pptx.Shapes+  ( PptxShape(..)+  , PptxParagraph(..)+  , BulletType(..)+  , parseShapes+  , parseShape+  , shapeToBlocks+  , isTitlePlaceholder+  , extractDrawingMLText+  ) where++import Codec.Archive.Zip (Archive, findEntryByPath, fromEntry)+import qualified Data.ByteString.Lazy as B+import Data.List (find, groupBy)+import Data.Maybe (mapMaybe)+import qualified Data.Text as T+import Data.Text (Text)+import Text.Read (readMaybe)+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import qualified Text.Pandoc.Class.PandocMonad as P+import Text.Pandoc.Definition+import Text.Pandoc.Readers.OOXML.Shared+import Text.Pandoc.Readers.Pptx.SmartArt+import Text.Pandoc.XML.Light++-- | Paragraph with bullet/numbering information+data PptxParagraph = PptxParagraph+  { paraLevel   :: Int            -- Bullet level (0, 1, 2...)+  , paraBullet  :: BulletType+  , paraText    :: Text+  } deriving (Show)++-- | Bullet type+data BulletType+  = NoBullet+  | Bullet                        -- Has bullet (character detected or implicit)+  | WingdingsBullet              -- Detected via Wingdings symbol+  deriving (Show, Eq)++-- | Shape types in PPTX slides+data PptxShape+  = PptxTextBox [PptxParagraph]         -- Parsed paragraphs with bullet info+  | PptxPicture+      { picRelId  :: Text               -- Relationship ID (lazy loading)+      , picTitle  :: Text+      , picAlt    :: Text+      }+  | PptxTable [[Text]]                  -- Simple text cells for now+  | PptxDiagramRef+      { dgmDataRelId   :: Text          -- Relationship to data.xml+      , dgmLayoutRelId :: Text          -- Relationship to layout.xml+      }+  | PptxGraphic Text                    -- Placeholder for other graphics+  deriving (Show)++-- | Parse all shapes from shape tree+parseShapes :: NameSpaces -> Element -> [PptxShape]+parseShapes ns spTreeElem =+  let shapeElems = onlyElems $ elContent spTreeElem+      -- Merge parent namespaces with element namespaces+      ns' = ns <> elemToNameSpaces spTreeElem+   in mapMaybe (parseShape ns') shapeElems++-- | Parse individual shape element+parseShape :: NameSpaces -> Element -> Maybe PptxShape+parseShape ns el+  -- Text box: <p:sp> with <p:txBody>+  | isElem ns "p" "sp" el =+      case findChildByName ns "p" "txBody" el of+        Just txBody ->+          let paras = parseParagraphs ns txBody+           in if null paras+              then Nothing+              else Just $ PptxTextBox paras+        Nothing -> Nothing++  -- Picture: <p:pic>+  | isElem ns "p" "pic" el = do+      nvPicPr <- findChildByName ns "p" "nvPicPr" el+      cNvPr <- findChildByName ns "p" "cNvPr" nvPicPr++      let title = maybe "" id $ findAttr (unqual "name") cNvPr+          alt = maybe "" id $ findAttr (unqual "descr") cNvPr++      -- Get blip relationship ID+      blipFill <- findChildByName ns "p" "blipFill" el+      blip <- findChildByName ns "a" "blip" blipFill+      relId <- findAttrByName ns "r" "embed" blip++      return $ PptxPicture relId title alt++  -- GraphicFrame: table or diagram+  | isElem ns "p" "graphicFrame" el =+      case findChildByName ns "a" "graphic" el >>=+           findChildByName ns "a" "graphicData" of+        Nothing -> Nothing+        Just graphicData ->+          case findAttr (unqual "uri") graphicData of+            Nothing -> Just $ PptxGraphic "no-uri"+            Just uri ->+              if "table" `T.isInfixOf` uri+                then+                  -- Table+                  case findChildByName ns "a" "tbl" graphicData of+                    Just tbl ->+                      let rows = parseTableRows ns tbl+                       in Just $ PptxTable rows+                    Nothing -> Nothing+                else if "diagram" `T.isInfixOf` uri+                  then+                    -- SmartArt diagram - dgm namespace is declared inline on relIds element+                    let dgmRelIds = find (\e -> qName (elName e) == "relIds") (elChildren graphicData)+                     in case dgmRelIds of+                          Nothing -> Just $ PptxGraphic "diagram-no-relIds"+                          Just relIdsElem ->+                            -- Get r:dm and r:lo attributes (r namespace is in parent)+                            let ns' = ns <> elemToNameSpaces relIdsElem+                             in case (findAttrByName ns' "r" "dm" relIdsElem,+                                      findAttrByName ns' "r" "lo" relIdsElem) of+                                  (Just dataRelId, Just layoutRelId) ->+                                    Just $ PptxDiagramRef dataRelId layoutRelId+                                  _ -> Just $ PptxGraphic "diagram-missing-rels"+                  else+                    -- Other graphic (chart, etc.)+                    Just $ PptxGraphic ("other: " <> uri)++  -- Skip other shapes for now+  | otherwise = Nothing++-- | Parse table rows (simple text extraction)+parseTableRows :: NameSpaces -> Element -> [[Text]]+parseTableRows ns tblElem =+  let trElems = findChildrenByName ns "a" "tr" tblElem+   in map (parseTableRow ns) trElems++parseTableRow :: NameSpaces -> Element -> [Text]+parseTableRow ns trElem =+  let tcElems = findChildrenByName ns "a" "tc" trElem+   in map extractCellText tcElems+  where+    extractCellText tcElem =+      -- Get text from txBody/a:p/a:r/a:t+      case findChildByName ns "a" "txBody" tcElem of+        Just txBody -> extractDrawingMLText txBody+        Nothing -> ""++-- | Convert shape to Pandoc blocks+shapeToBlocks :: PandocMonad m => Archive -> [(Text, Text)] -> PptxShape -> m [Block]+shapeToBlocks _archive _rels (PptxTextBox paras) =+  return $ paragraphsToBlocks paras+shapeToBlocks archive rels (PptxPicture relId title alt) = do+  -- Resolve relationship to get media path+  case lookup relId rels of+    Nothing -> return []  -- Image not found+    Just target -> do+      let mediaPath = resolveMediaPath target++      -- Load image bytes and add to MediaBag+      case loadMediaFromArchive archive mediaPath of+        Nothing -> return []+        Just mediaBytes -> do+          P.insertMedia (T.unpack mediaPath) Nothing mediaBytes++          let altText = if T.null alt then [] else [Str alt]+          return [Para [Image nullAttr altText (mediaPath, title)]]++shapeToBlocks _archive _rels (PptxTable rows) =+  -- Simple table representation for now+  case rows of+    [] -> return []+    (headerRow:bodyRows) -> do+      let makeCell text = Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str text]]+          headerCells = map makeCell headerRow+          bodyCells = map (map makeCell) bodyRows+          caption = Caption Nothing []+          colSpec = replicate (length headerRow) (AlignDefault, ColWidthDefault)+          headerRow' = Row nullAttr headerCells+          bodyRows' = map (Row nullAttr) bodyCells+          thead = TableHead nullAttr [headerRow']+          tbody = [TableBody nullAttr 0 [] bodyRows']+          tfoot = TableFoot nullAttr []+      return [Table nullAttr caption colSpec thead tbody tfoot]++shapeToBlocks archive rels (PptxDiagramRef dataRelId layoutRelId) = do+  -- Parse SmartArt diagram+  case parseDiagram archive rels dataRelId layoutRelId of+    Left err -> do+      -- Failed to parse diagram, return placeholder+      return [Para [Str $ "[Diagram parse error: " <> err <> "]"]]+    Right diagram ->+      return $ diagramToBlocks diagram+shapeToBlocks _archive _rels (PptxGraphic text) =+  -- Placeholder for other graphics (charts, etc.)+  return [Para [Str $ "[Graphic: " <> text <> "]"]]++-- | Resolve media path (handle relative paths)+resolveMediaPath :: Text -> Text+resolveMediaPath target =+  if "../media/" `T.isPrefixOf` target+    then "ppt/media/" <> T.drop 9 target  -- "../media/" = 9 chars+    else if "media/" `T.isPrefixOf` target+      then "ppt/" <> target+      else target++-- | Load media file from archive+loadMediaFromArchive :: Archive -> Text -> Maybe B.ByteString+loadMediaFromArchive archive path =+  case findEntryByPath (T.unpack path) archive of+    Just entry -> Just $ fromEntry entry+    Nothing -> Nothing++-- | Parse paragraphs from text box+parseParagraphs :: NameSpaces -> Element -> [PptxParagraph]+parseParagraphs ns txBody =+  let pElems = findChildrenByName ns "a" "p" txBody+   in map (parseParagraph ns) pElems++-- | Parse individual paragraph+parseParagraph :: NameSpaces -> Element -> PptxParagraph+parseParagraph ns pElem =+  let level = parseBulletLevel ns pElem+      bullet = detectBulletType ns pElem+      text = extractParagraphText ns pElem+   in PptxParagraph level bullet text++-- | Parse bullet level from paragraph properties+parseBulletLevel :: NameSpaces -> Element -> Int+parseBulletLevel ns pElem =+  case findChildByName ns "a" "pPr" pElem >>=+       findAttr (unqual "lvl") >>=+       (\s -> readMaybe (T.unpack s) :: Maybe Int) of+    Just lvl -> lvl+    Nothing -> 0  -- Default to level 0++-- | Detect bullet type+detectBulletType :: NameSpaces -> Element -> BulletType+detectBulletType ns pElem =+  -- Check for explicit <a:pPr><a:buChar>+  case findChildByName ns "a" "pPr" pElem >>=+       findChildByName ns "a" "buChar" of+    Just _buCharElem -> Bullet+    Nothing ->+      -- Check for Wingdings symbol (common in PowerPoint)+      if hasWingdingsSymbol ns pElem+        then WingdingsBullet+        else NoBullet++-- | Check if paragraph starts with Wingdings symbol+hasWingdingsSymbol :: NameSpaces -> Element -> Bool+hasWingdingsSymbol ns pElem =+  let runs = findChildrenByName ns "a" "r" pElem+      checkRun r = case findChildByName ns "a" "rPr" r >>=+                        findChildByName ns "a" "sym" of+                     Just symElem ->+                       case findAttr (unqual "typeface") symElem of+                         Just typeface -> "Wingdings" `T.isInfixOf` typeface+                         Nothing -> False+                     Nothing -> False+   in any checkRun runs++-- | Extract text from paragraph+extractParagraphText :: NameSpaces -> Element -> Text+extractParagraphText _ns pElem =+  -- Find all <a:t> elements and concatenate+  let textElems = filterElementsName (\qn -> qName qn == "t") pElem+      texts = map strContent textElems+   in T.unwords $ filter (not . T.null) texts++-- | Extract text from DrawingML element (finds all <a:t> descendants)+extractDrawingMLText :: Element -> Text+extractDrawingMLText el =+  let textElems = filterElementsName (\qn -> qName qn == "t") el+      texts = map strContent textElems+   in T.unwords $ filter (not . T.null) texts++-- | Convert paragraphs to blocks, grouping bullets into lists+paragraphsToBlocks :: [PptxParagraph] -> [Block]+paragraphsToBlocks paras =+  -- If we have multiple paragraphs with bullets, group them+  let hasBullets = any (\p -> paraBullet p /= NoBullet) paras+   in if hasBullets+      then groupBulletParagraphs paras+      else map (\p -> Para [Str $ paraText p]) paras++-- | Group bullet paragraphs into lists+groupBulletParagraphs :: [PptxParagraph] -> [Block]+groupBulletParagraphs paras =+  let grouped = groupBy sameBulletLevel paras+   in concatMap groupToBlock grouped+  where+    sameBulletLevel p1 p2 =+      (paraBullet p1 /= NoBullet) &&+      (paraBullet p2 /= NoBullet) &&+      (paraLevel p1 == paraLevel p2)++    groupToBlock :: [PptxParagraph] -> [Block]+    groupToBlock [] = []+    groupToBlock ps@(p:_)+      | paraBullet p /= NoBullet =+          -- Bullet list+          let items = map (\para -> [Plain [Str $ paraText para]]) ps+           in [BulletList items]+      | otherwise =+          -- Plain paragraph+          map (\para -> Para [Str $ paraText para]) ps++-- | Check if shape is title placeholder (also used in Slides module)+isTitlePlaceholder :: NameSpaces -> Element -> Bool+isTitlePlaceholder ns el =+  case findChildByName ns "p" "nvSpPr" el >>=+       findChildByName ns "p" "nvPr" >>=+       findChildByName ns "p" "ph" of+    Just phElem ->+      case findAttr (unqual "type") phElem of+        Just phType -> phType == "title" || phType == "ctrTitle"+        Nothing -> False+    Nothing -> False
+ src/Text/Pandoc/Readers/Pptx/Slides.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Pptx.Slides+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Conversion of PPTX slides to Pandoc AST blocks.+-}+module Text.Pandoc.Readers.Pptx.Slides+  ( pptxToOutput+  ) where++import Codec.Archive.Zip (Archive)+import Data.List (find)+import Data.Maybe (mapMaybe)+import qualified Data.Text as T+import Data.Text (Text)+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import Text.Pandoc.Definition+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Readers.OOXML.Shared+import Text.Pandoc.Readers.Pptx.Parse+import Text.Pandoc.Readers.Pptx.Shapes+import Text.Pandoc.XML.Light++-- | Convert Pptx intermediate representation to Pandoc AST+pptxToOutput :: PandocMonad m => ReaderOptions -> Pptx -> m (Meta, [Block])+pptxToOutput _opts pptx = do+  let slides = pptxSlides pptx+      archive = pptxArchive pptx++  -- Convert each slide to blocks+  slideBlocks <- concat <$> mapM (slideToBlocks archive) slides++  return (mempty, slideBlocks)++-- | Convert slide to blocks+slideToBlocks :: PandocMonad m => Archive -> PptxSlide -> m [Block]+slideToBlocks archive slide = do+  let SlideId n = slideId slide+      slideElem = slideElement slide+      rels = slideRels slide+      ns = elemToNameSpaces slideElem++      -- Extract title from title placeholder+      title = extractSlideTitle ns slideElem++      -- Create header+      slideIdent = "slide-" <> T.pack (show n)+      headerText = if T.null title+                   then "Slide " <> T.pack (show n)+                   else title+      header = Header 2 (slideIdent, [], []) [Str headerText]++  -- Parse shapes and convert to blocks+  case findChildByName ns "p" "cSld" slideElem >>=+       findChildByName ns "p" "spTree" of+    Nothing -> return [header]+    Just spTree -> do+      -- Filter out title placeholder shapes before parsing+      let allShapeElems = onlyElems $ elContent spTree+          nonTitleShapeElems = filter (not . isTitlePlaceholder ns) allShapeElems+          shapes = mapMaybe (parseShape ns) nonTitleShapeElems+      shapeBlocks <- concat <$> mapM (shapeToBlocks archive rels) shapes+      return $ header : shapeBlocks++-- | Extract title from title placeholder+extractSlideTitle :: NameSpaces -> Element -> Text+extractSlideTitle ns slideElem =+  case findChildByName ns "p" "cSld" slideElem >>=+       findChildByName ns "p" "spTree" of+    Nothing -> ""+    Just spTree ->+      -- Find shape with ph type="title"+      let shapes = onlyElems $ elContent spTree+          titleShape = find (isTitlePlaceholder ns) shapes+       in maybe "" extractDrawingMLText titleShape++-- isTitlePlaceholder is imported from Shapes module
+ src/Text/Pandoc/Readers/Pptx/SmartArt.hs view
@@ -0,0 +1,220 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Pptx.SmartArt+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++SmartArt diagram parsing and text extraction for PPTX.+-}+module Text.Pandoc.Readers.Pptx.SmartArt+  ( PptxDiagram(..)+  , parseDiagram+  , diagramToBlocks+  ) where++import Codec.Archive.Zip (Archive, findEntryByPath, fromEntry)+import qualified Data.Map.Strict as M+import Data.Maybe (mapMaybe)+import qualified Data.Text as T+import qualified Data.Text.Lazy.Encoding as TL+import Data.Text (Text)+import Text.Pandoc.Definition+import Text.Pandoc.Readers.OOXML.Shared+import Text.Pandoc.XML.Light++-- | SmartArt diagram data+data PptxDiagram = PptxDiagram+  { diagramType :: Text               -- Layout type (chevron, cycle, etc.)+  , diagramNodes :: [(Text, [Text])]  -- (nodeText, childTexts)+  } deriving (Show)++-- | Parse SmartArt diagram from relationship IDs+parseDiagram :: Archive+             -> [(Text, Text)]  -- Slide relationships+             -> Text            -- data relationship ID+             -> Text            -- layout relationship ID+             -> Either Text PptxDiagram+parseDiagram archive rels dataRelId layoutRelId = do+  -- Resolve relationships to file paths+  dataTarget <- maybeToEither ("Relationship not found: " <> dataRelId) $+                lookup dataRelId rels+  layoutTarget <- maybeToEither ("Relationship not found: " <> layoutRelId) $+                  lookup layoutRelId rels++  -- Resolve relative paths (diagrams are in ../diagrams/ from slides/)+  let dataPath = resolveDiagramPath dataTarget+      layoutPath = resolveDiagramPath layoutTarget++  -- Load XML files+  dataElem <- loadXMLFromArchive archive dataPath+  layoutElem <- loadXMLFromArchive archive layoutPath++  -- Extract layout type+  layoutType <- extractLayoutType layoutElem++  -- Extract text nodes with hierarchy+  nodes <- extractDiagramNodes dataElem++  return $ PptxDiagram layoutType nodes++-- | Resolve diagram path (handle ../diagrams/ relative paths)+resolveDiagramPath :: Text -> FilePath+resolveDiagramPath target =+  if "../diagrams/" `T.isPrefixOf` target+    then "ppt/diagrams/" ++ T.unpack (T.drop 12 target)  -- "../diagrams/" = 12 chars+    else T.unpack target++-- | Load XML from archive+loadXMLFromArchive :: Archive -> FilePath -> Either Text Element+loadXMLFromArchive archive path =+  case findEntryByPath path archive of+    Nothing -> Left $ "File not found in archive: " <> T.pack path+    Just entry ->+      let xmlBytes = fromEntry entry+          lazyText = TL.decodeUtf8 xmlBytes+       in parseXMLElement lazyText++-- | Extract layout type from layout XML+extractLayoutType :: Element -> Either Text Text+extractLayoutType layoutElem = do+  -- Look for uniqueId attribute: "urn:.../layout/chevron2"+  case findAttr (unqual "uniqueId") layoutElem of+    Just uid ->+      -- Extract last part after last /+      let layoutName = T.takeWhileEnd (/= '/') uid+       in Right layoutName+    Nothing ->+      -- Fallback: look for title+      case findChildByName ns "dgm" "title" layoutElem >>=+           findAttr (unqual "val") of+        Just title -> Right title+        Nothing -> Right "unknown"+  where+    ns = elemToNameSpaces layoutElem++-- | Extract text nodes from diagram data+extractDiagramNodes :: Element -> Either Text [(Text, [Text])]+extractDiagramNodes dataElem = do+  let ns = elemToNameSpaces dataElem++  -- Find point list+  ptLst <- maybeToEither "Missing dgm:ptLst" $+           findChildByName ns "dgm" "ptLst" dataElem++  let ptElems = findChildrenByName ns "dgm" "pt" ptLst++  -- Build node map: modelId → text+  let nodeMap = M.fromList $ mapMaybe (extractNodeText ns) ptElems++  -- Parse connections+  let cxnLst = findChildByName ns "dgm" "cxnLst" dataElem+      connections = maybe [] (parseConnections ns) cxnLst++  -- Build parent-child map+  let parentMap = buildParentMap connections++  -- Find parent nodes (nodes that have children)+  let parentIds = M.keys parentMap++  -- Build hierarchy - only show nodes that are parents+  -- (children are shown under their parents)+  let hierarchy = map (buildNodeWithChildren nodeMap parentMap) parentIds+      -- Filter out nodes with empty text (presentation nodes)+      validHierarchy = filter (\(nodeText, _) -> not $ T.null nodeText) hierarchy++  return validHierarchy++-- | Extract text from a point element (returns Nothing if no text)+extractNodeText :: NameSpaces -> Element -> Maybe (Text, Text)+extractNodeText ns ptElem = do+  modelId <- findAttr (unqual "modelId") ptElem++  -- Extract text from dgm:t element (which contains a:p/a:r/a:t)+  let text = case findChildByName ns "dgm" "t" ptElem of+        Just tElem ->+          -- Recursively get ALL text content from all descendants+          getAllText tElem+        Nothing -> ""++  -- Only return nodes with actual text+  if T.null (T.strip text)+    then Nothing+    else return (modelId, text)++-- | Connection between nodes+data Connection = Connection+  { connType :: Text+  , connSrc  :: Text+  , connDest :: Text+  } deriving (Show)++-- | Parse connections+parseConnections :: NameSpaces -> Element -> [Connection]+parseConnections ns cxnLst =+  let cxnElems = findChildrenByName ns "dgm" "cxn" cxnLst+   in mapMaybe (parseConnection ns) cxnElems++parseConnection :: NameSpaces -> Element -> Maybe Connection+parseConnection _ns cxnElem = do+  let cxnType = maybe "" id $ findAttr (unqual "type") cxnElem  -- Empty if no type+  srcId <- findAttr (unqual "srcId") cxnElem+  destId <- findAttr (unqual "destId") cxnElem+  return $ Connection cxnType srcId destId++-- | Build parent-child map from connections+-- Use connections WITHOUT a type attribute (these are the data hierarchy)+buildParentMap :: [Connection] -> M.Map Text [Text]+buildParentMap connections =+  let dataConnections = filter (\c -> T.null (connType c)) connections+   in foldr addConn M.empty dataConnections+  where+    addConn conn m = M.insertWith (++) (connSrc conn) [connDest conn] m++-- | Build node with its children+buildNodeWithChildren :: M.Map Text Text -> M.Map Text [Text] -> Text -> (Text, [Text])+buildNodeWithChildren nodeMap parentMap nodeId =+  let nodeText = M.findWithDefault "" nodeId nodeMap+      childIds = M.findWithDefault [] nodeId parentMap+      -- Only include children that have text+      childTexts = filter (not . T.null) $+                   map (\cid -> M.findWithDefault "" cid nodeMap) childIds+   in (nodeText, childTexts)++-- | Convert diagram to Pandoc blocks+diagramToBlocks :: PptxDiagram -> [Block]+diagramToBlocks diagram =+  let nodes = diagramNodes diagram+      layoutType = diagramType diagram++      -- Build content blocks+      contentBlocks = concatMap nodeToBlocks nodes++   in [Div ("", ["smartart", layoutType], [("layout", layoutType)])+           contentBlocks]++-- | Convert node to blocks+nodeToBlocks :: (Text, [Text]) -> [Block]+nodeToBlocks (nodeText, childTexts) =+  if null childTexts+    then [Para [Strong [Str nodeText]]]+    else [ Para [Strong [Str nodeText]]+         , BulletList [[Plain [Str child]] | child <- childTexts]+         ]++-- | Recursively extract all text from an element and its descendants+getAllText :: Element -> Text+getAllText el =+  let textFromContent (Text cdata) = cdData cdata+      textFromContent (Elem e) = getAllText e+      textFromContent _ = ""+      texts = map textFromContent (elContent el)+   in T.unwords $ filter (not . T.null) texts++-- Helper functions+maybeToEither :: Text -> Maybe a -> Either Text a+maybeToEither err Nothing = Left err+maybeToEither _ (Just x) = Right x
src/Text/Pandoc/Readers/RST.hs view
@@ -1536,11 +1536,12 @@  escapedChar :: Monad m => RSTParser m Inlines escapedChar = do c <- escaped anyChar-                 unless (canPrecedeOpener c) updateLastStrPos-                 return $ if c == ' ' || c == '\n' || c == '\r'-                             -- '\ ' is null in RST-                             then mempty-                             else B.str $ T.singleton c+                 if c == ' ' || c == '\n' || c == '\r'+                    -- '\ ' is null in RST+                    then return mempty+                    else do+                      unless (canPrecedeOpener c) updateLastStrPos+                      return $ B.str $ T.singleton c  canPrecedeOpener :: Char -> Bool canPrecedeOpener c =
src/Text/Pandoc/Readers/Typst.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverloadedStrings #-}@@ -33,7 +34,7 @@ import Control.Monad (MonadPlus (mplus), void, guard, foldM) import qualified Data.Foldable as F import qualified Data.Map as M-import Data.Maybe (catMaybes, fromMaybe)+import Data.Maybe (catMaybes, fromMaybe, isJust) import Data.Sequence (Seq) import qualified Data.Sequence as Seq import qualified Data.Set as Set@@ -158,39 +159,34 @@ pPandoc = do   Elt "document" _ fields <- pTok isDocument   bs <- getField "body" fields >>= pWithContents pBlocks-  pure $ B.doc bs-  -- The following alternative code would add metadata from the-  -- fields on the document element. It is commented out because-  -- the typst metadata doesn't print anything by default, in contrast-  -- to pandoc with its usual templates.  Hence, with this code,-  -- converting a typst document might yield a double title, author, etc.-  ---  -- title <- (getField "title" fields >>= pWithContents pInlines) <|>-  --             pure mempty-  -- authors <- (getField "author" fields >>=-  --                         mapM (pWithContents pInlines) . V.toList) <|>-  --            ((:[]) <$> (getField "author" fields >>=-  --                          (\x -> guard (not (null x)) *>-  --                            pWithContents pInlines x))) <|>-  --             pure []-  -- date <- (getField "date" fields >>= pWithContents pInlines) <|>-  --             pure mempty-  -- keywords <- (getField "keywords" fields >>=-  --                mapM (pWithContents pInlines) . V.toList)-  --               <|> pure []-  -- pure $-  --   (if title == mempty-  --       then id-  --       else B.setMeta "title" title) .-  --   (if null authors-  --       then id-  --       else B.setMeta "author" authors) .-  --   (if null date-  --       then id-  --       else B.setMeta "date" date) .-  --   (if null keywords-  --       then id-  --       else B.setMeta "keywords" keywords) $ B.doc bs+  title <- (getField "title" fields >>= pWithContents pInlines) <|>+              pure mempty+  authors <- (getField "author" fields >>=+                          mapM (pWithContents pInlines) . V.toList) <|>+             ((:[]) <$> (getField "author" fields >>=+                           (\x -> guard (not (null x)) *>+                             pWithContents pInlines x))) <|>+              pure []+  date <- (getField "date" fields >>= pWithContents pInlines) <|>+              pure mempty+  keywords <- (getField "keywords" fields >>=+                 mapM (pWithContents pInlines) . V.toList)+                <|> pure []+  meta <- sMeta <$> getState+  let meta' =+        (if title == mempty || isJust (lookupMeta "title" meta)+            then id+            else B.setMeta "title" title) .+        (if null authors+            then id+            else B.setMeta "author" authors) .+        (if null date+            then id+            else B.setMeta "date" date) .+        (if null keywords+            then id+            else B.setMeta "keywords" keywords) $ meta+  pure $ Pandoc meta' (B.toList bs)  pBlocks :: PandocMonad m => P m B.Blocks pBlocks = mconcat <$> many pBlock@@ -252,6 +248,14 @@       -- sometimes text elements include para breaks       notFollowedBy $ void $ pWithContents pInlines body       pWithContents pBlocks body)+  ,("title", \_ _ fields -> do+      body <- getField "body" fields+      case body of+        VContent cs -> do+          ils <- pWithContents pInlines cs <|> pure mempty+          updateState $ \s -> s{ sMeta = B.setMeta "title" ils (sMeta s) }+          pure mempty+        _ -> pure mempty)   ,("box", \_ _ fields -> do       body <- getField "body" fields       B.divWith ("", ["box"], []) <$> pWithContents pBlocks body)
src/Text/Pandoc/Readers/Typst/Parsing.hs view
@@ -27,15 +27,18 @@     ( Identifier, Content(Elt), FromVal(..), Val(VNone) ) import Text.Pandoc.Class.PandocMonad ( PandocMonad, report ) import Text.Pandoc.Logging (LogMessage(..))+import Text.Pandoc.Definition -newtype PState = PState-        { sLabels :: [Text]}+data PState = PState+        { sLabels :: [Text]+        , sMeta :: Meta }         deriving (Show)  defaultPState :: PState defaultPState =   PState-  { sLabels = [] }+  { sLabels = []+  , sMeta = mempty }  type P m a = ParsecT [Content] PState m a -- state tracks a list of labels in the document
+ src/Text/Pandoc/Readers/Xlsx.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Xlsx+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Conversion of XLSX (Excel spreadsheet) documents to 'Pandoc' document.+-}+module Text.Pandoc.Readers.Xlsx (readXlsx) where++import qualified Data.ByteString.Lazy as B+import qualified Data.Text as T+import Codec.Archive.Zip (toArchiveOrFail)+import Control.Monad.Except (throwError)+import Text.Pandoc.Class.PandocMonad (PandocMonad)+import Text.Pandoc.Definition (Pandoc(..))+import Text.Pandoc.Error (PandocError(..))+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Readers.Xlsx.Parse (archiveToXlsx)+import Text.Pandoc.Readers.Xlsx.Sheets (xlsxToOutput)++-- | Read XLSX file into Pandoc AST+readXlsx :: PandocMonad m => ReaderOptions -> B.ByteString -> m Pandoc+readXlsx opts bytes =+  case toArchiveOrFail bytes of+    Right archive ->+      case archiveToXlsx archive of+        Right xlsx -> do+          let (meta, blocks) = xlsxToOutput opts xlsx+          return $ Pandoc meta blocks+        Left err ->+          throwError $ PandocParseError $ "Failed to parse XLSX: " <> err++    Left err ->+      throwError $ PandocParseError $+        "Failed to unpack XLSX archive: " <> T.pack err
+ src/Text/Pandoc/Readers/Xlsx/Cells.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Xlsx.Cells+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Cell types and parsing for XLSX.+-}+module Text.Pandoc.Readers.Xlsx.Cells+  ( CellRef(..)+  , XlsxCell(..)+  , CellValue(..)+  , parseCellRef+  ) where++import qualified Data.Text as T+import Data.Text (Text)+import Data.Char (ord, isAlpha)+import Text.Read (readMaybe)++-- | Cell reference (A1 notation)+data CellRef = CellRef+  { cellRefCol :: Int    -- 1-based (A=1, B=2, ..., AA=27)+  , cellRefRow :: Int    -- 1-based+  } deriving (Show, Eq, Ord)++-- | Cell value types+data CellValue+  = TextValue Text+  | NumberValue Double+  | EmptyValue+  deriving (Show, Eq)++-- | Parsed cell+data XlsxCell = XlsxCell+  { cellRef :: CellRef+  , cellValue :: CellValue+  , cellBold :: Bool+  , cellItalic :: Bool+  } deriving (Show)++-- | Parse cell reference (A1 → CellRef)+parseCellRef :: Text -> Either Text CellRef+parseCellRef ref = do+  let (colStr, rowStr) = T.span isAlpha ref++  row <- case readMaybe (T.unpack rowStr) of+    Just r | r > 0 -> Right r+    _ -> Left $ "Invalid row: " <> rowStr++  col <- parseColumn colStr++  return $ CellRef col row++-- | Parse column (A=1, Z=26, AA=27, etc.)+parseColumn :: Text -> Either Text Int+parseColumn colStr+  | T.null colStr = Left "Empty column"+  | otherwise = Right $ T.foldl' (\acc c -> acc * 26 + (ord c - ord 'A' + 1)) 0 colStr
+ src/Text/Pandoc/Readers/Xlsx/Parse.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Xlsx.Parse+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Parsing of XLSX archive to intermediate representation.+-}+module Text.Pandoc.Readers.Xlsx.Parse+  ( Xlsx(..)+  , XlsxWorkbook(..)+  , XlsxSheet(..)+  , SheetId(..)+  , SharedStrings+  , Styles(..)+  , FontInfo(..)+  , archiveToXlsx+  ) where++import Codec.Archive.Zip (Archive, Entry, findEntryByPath, fromEntry)+import Data.List (find)+import qualified Data.Map.Strict as M+import Data.Maybe (mapMaybe, fromMaybe)+import qualified Data.Text as T+import qualified Data.Text.Lazy.Encoding as TL+import Data.Text (Text)+import qualified Data.Vector as V+import System.FilePath (splitFileName)+import Text.Pandoc.Readers.OOXML.Shared+import Text.Pandoc.Readers.Xlsx.Cells+import Text.Pandoc.XML.Light+import Text.Read (readMaybe)++-- | Sheet identifier+newtype SheetId = SheetId Int deriving (Show, Eq, Ord)++-- | Shared strings table (Vector for O(1) lookup)+type SharedStrings = V.Vector Text++-- | Font information+data FontInfo = FontInfo+  { fontBold :: Bool+  , fontItalic :: Bool+  , fontUnderline :: Bool+  } deriving (Show)++-- | Style information+data Styles = Styles+  { styleFonts :: V.Vector FontInfo+  } deriving (Show)++-- | Complete XLSX document+data Xlsx = Xlsx+  { xlsxWorkbook :: XlsxWorkbook+  , xlsxSheets :: [XlsxSheet]+  , xlsxSharedStrings :: SharedStrings+  , xlsxStyles :: Styles+  } deriving (Show)++-- | Workbook information+data XlsxWorkbook = XlsxWorkbook+  { workbookSheetNames :: [(SheetId, Text, Text)]  -- (id, name, relId)+  } deriving (Show)++-- | Individual worksheet+data XlsxSheet = XlsxSheet+  { sheetId :: SheetId+  , sheetName :: Text+  , sheetCells :: M.Map CellRef XlsxCell+  } deriving (Show)++-- | Parse XLSX archive+archiveToXlsx :: Archive -> Either Text Xlsx+archiveToXlsx archive = do+  -- Find and parse workbook.xml+  workbookPath <- getWorkbookXmlPath archive+  workbookElem <- loadXMLFromArchive archive workbookPath+  workbook <- parseWorkbook workbookElem+    `addContext` ("Parsing workbook.xml from: " <> T.pack workbookPath)++  -- Load workbook relationships+  workbookRels <- loadRelationships archive (relsPathFor workbookPath)++  -- Parse shared strings (look for sharedStrings relationship)+  sharedStrings <- case findRelWithTarget workbookRels "sharedStrings" of+    Just (_, target) -> do+      let path = "xl/" ++ T.unpack target+      el <- loadXMLFromArchive archive path+      parseSharedStrings el+    Nothing -> Right V.empty++  -- Parse styles+  styles <- case findRelWithTarget workbookRels "styles" of+    Just (_, target) -> do+      let path = "xl/" ++ T.unpack target+      el <- loadXMLFromArchive archive path+      parseStyles el+    Nothing -> Right $ Styles V.empty++  -- Parse worksheets+  sheets <- mapM (\sheetInfo -> parseSheet archive workbookRels sharedStrings styles sheetInfo)+                 (workbookSheetNames workbook)++  return $ Xlsx workbook sheets sharedStrings styles++-- | Find workbook.xml via root relationships+getWorkbookXmlPath :: Archive -> Either Text FilePath+getWorkbookXmlPath archive = do+  relsEntry <- maybeToEither "Missing _rels/.rels" $+               findEntryByPath "_rels/.rels" archive+  relsElem <- parseXMLFromEntry relsEntry++  let relElems = onlyElems $ elContent relsElem+  case find isOfficeDocRel relElems of+    Nothing -> Left "No workbook.xml relationship found"+    Just rel -> do+      target <- maybeToEither "Missing Target" $ findAttr (unqual "Target") rel+      return $ T.unpack target+  where+    isOfficeDocRel el =+      case (findAttr (unqual "Type") el, findAttr (unqual "Target") el) of+        (Just relType, Just target) ->+          "officeDocument" `T.isInfixOf` relType && "workbook" `T.isInfixOf` target+        _ -> False++-- | Parse workbook.xml+parseWorkbook :: Element -> Either Text XlsxWorkbook+parseWorkbook wbElem = do+  let ns = elemToNameSpaces wbElem++  -- Find sheets element (match by local name only)+  sheets <- maybeToEither "Missing <sheets>" $+            find (\e -> qName (elName e) == "sheets") (onlyElems $ elContent wbElem)++  let sheetElems = filter (\e -> qName (elName e) == "sheet") (onlyElems $ elContent sheets)+  sheetRefs <- mapM (parseSheetRef ns) (zip [1..] sheetElems)++  return $ XlsxWorkbook sheetRefs++parseSheetRef :: NameSpaces -> (Int, Element) -> Either Text (SheetId, Text, Text)+parseSheetRef ns (idx, sheetElem) = do+  let name = fromMaybe ("Sheet" <> T.pack (show idx)) $+             findAttr (unqual "name") sheetElem+  relId <- maybeToEither "Missing r:id" $+           findAttrByName ns "r" "id" sheetElem+  return (SheetId idx, name, relId)++-- | Parse shared strings+parseSharedStrings :: Element -> Either Text SharedStrings+parseSharedStrings sstElem = do+  let siElems = filter (\e -> qName (elName e) == "si") (onlyElems $ elContent sstElem)+      strings = map extractString siElems+  return $ V.fromList strings+  where+    extractString siElem =+      case find (\e -> qName (elName e) == "t") (onlyElems $ elContent siElem) of+        Just tElem -> strContent tElem+        Nothing -> getAllText siElem++-- | Parse styles (fonts only for MVP)+parseStyles :: Element -> Either Text Styles+parseStyles stylesElem = do+  -- Parse fonts (match by local name)+  let fontsElem = find (\e -> qName (elName e) == "fonts") (onlyElems $ elContent stylesElem)+      fontElems = maybe [] (\fe -> filter (\e -> qName (elName e) == "font") (onlyElems $ elContent fe)) fontsElem+      fonts = V.fromList $ map (parseFont mempty) fontElems++  return $ Styles fonts++parseFont :: NameSpaces -> Element -> FontInfo+parseFont _ns fontElem =+  FontInfo+    { fontBold = any (\e -> qName (elName e) == "b") (onlyElems $ elContent fontElem)+    , fontItalic = any (\e -> qName (elName e) == "i") (onlyElems $ elContent fontElem)+    , fontUnderline = any (\e -> qName (elName e) == "u") (onlyElems $ elContent fontElem)+    }++-- | Parse individual worksheet+parseSheet :: Archive -> [(Text, Text)] -> SharedStrings -> Styles -> (SheetId, Text, Text) -> Either Text XlsxSheet+parseSheet archive rels sharedStrings styles (sid, name, relId) = do+  target <- maybeToEither ("Sheet relationship not found: " <> relId) $+            lookup relId rels++  let sheetPath = "xl/" ++ T.unpack target+  sheetElem <- loadXMLFromArchive archive sheetPath++  cells <- parseSheetCells sheetElem sharedStrings styles++  return $ XlsxSheet sid name cells++-- | Parse sheet cells+parseSheetCells :: Element -> SharedStrings -> Styles -> Either Text (M.Map CellRef XlsxCell)+parseSheetCells sheetElem sharedStrings styles = do+  -- Find sheetData by local name+  case find (\e -> qName (elName e) == "sheetData") (onlyElems $ elContent sheetElem) of+    Nothing -> return M.empty+    Just sheetData -> do+      let rowElems = filter (\e -> qName (elName e) == "row") (onlyElems $ elContent sheetData)+          cellElems = concatMap (\r -> filter (\e -> qName (elName e) == "c") (onlyElems $ elContent r)) rowElems+          cells = mapMaybe (parseCell sharedStrings styles) cellElems+      return $ M.fromList [(cellRef c, c) | c <- cells]++-- | Parse individual cell+parseCell :: SharedStrings -> Styles -> Element -> Maybe XlsxCell+parseCell sharedStrings styles cElem = do+  -- Get cell reference+  refText <- findAttr (unqual "r") cElem+  cellRefParsed <- either (const Nothing) Just $ parseCellRef refText++  -- Get cell type (default to number if missing)+  let cellType = fromMaybe "" $ findAttr (unqual "t") cElem+      styleIdx = findAttr (unqual "s") cElem >>= readMaybe . T.unpack++  -- Get value (match by local name)+  let vElem = find (\e -> qName (elName e) == "v") (onlyElems $ elContent cElem)+      vText = maybe "" strContent vElem++  -- Parse value based on type+  let value = if cellType == "s"+              then+                -- Shared string+                case readMaybe (T.unpack vText) of+                  Just idx | idx >= 0 && idx < V.length sharedStrings ->+                    TextValue (sharedStrings V.! idx)+                  _ -> EmptyValue+              else if T.null vText+                then EmptyValue+                else+                  -- Number+                  case readMaybe (T.unpack vText) of+                    Just n -> NumberValue n+                    Nothing -> TextValue vText++  -- Get formatting from style+  let (bold, italic) = case styleIdx of+        Just idx | idx >= 0 && idx < V.length (styleFonts styles) ->+          let font = styleFonts styles V.! idx+           in (fontBold font, fontItalic font)+        _ -> (False, False)++  return $ XlsxCell cellRefParsed value bold italic++-- Helper functions+loadXMLFromArchive :: Archive -> FilePath -> Either Text Element+loadXMLFromArchive archive path = do+  entry <- maybeToEither ("Entry not found: " <> T.pack path) $+           findEntryByPath path archive+  parseXMLFromEntry entry++parseXMLFromEntry :: Entry -> Either Text Element+parseXMLFromEntry entry =+  let lazyText = TL.decodeUtf8 $ fromEntry entry+   in parseXMLElement lazyText++loadRelationships :: Archive -> FilePath -> Either Text [(Text, Text)]+loadRelationships archive relsPath =+  case findEntryByPath relsPath archive of+    Nothing -> Right []+    Just entry -> do+      relsElem <- parseXMLFromEntry entry+      let relElems = onlyElems $ elContent relsElem+      return $ mapMaybe extractRel relElems+  where+    extractRel el = do+      relId <- findAttr (unqual "Id") el+      target <- findAttr (unqual "Target") el+      return (relId, target)++relsPathFor :: FilePath -> FilePath+relsPathFor path =+  let (dir, file) = splitFileName path+   in dir ++ "/_rels/" ++ file ++ ".rels"++findRelWithTarget :: [(Text, Text)] -> Text -> Maybe (Text, Text)+findRelWithTarget rels targetName =+  find (\(_, target) -> targetName `T.isInfixOf` target) rels++maybeToEither :: Text -> Maybe a -> Either Text a+maybeToEither err Nothing = Left err+maybeToEither _ (Just x) = Right x++getAllText :: Element -> Text+getAllText el =+  let textFromContent (Text cdata) = cdData cdata+      textFromContent (Elem e) = getAllText e+      textFromContent _ = ""+      texts = map textFromContent (elContent el)+   in T.unwords $ filter (not . T.null) texts++addContext :: Either Text a -> Text -> Either Text a+addContext (Right x) _ = Right x+addContext (Left err) ctx = Left (err <> " (context: " <> ctx <> ")")
+ src/Text/Pandoc/Readers/Xlsx/Sheets.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Text.Pandoc.Readers.Xlsx.Sheets+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Conversion of XLSX sheets to Pandoc AST.+-}+module Text.Pandoc.Readers.Xlsx.Sheets+  ( xlsxToOutput+  ) where++import qualified Data.Map.Strict as M+import qualified Data.Text as T+import Data.List (sort, dropWhileEnd)+import Data.Char (isSpace)+import Text.Pandoc.Definition+import Text.Pandoc.Options (ReaderOptions)+import Text.Pandoc.Readers.Xlsx.Parse+import Text.Pandoc.Readers.Xlsx.Cells+import qualified Text.Pandoc.Builder as B++-- | Convert XLSX to Pandoc output+xlsxToOutput :: ReaderOptions -> Xlsx -> (Meta, [Block])+xlsxToOutput _opts xlsx =+  let sheets = xlsxSheets xlsx+      sheetBlocks = concatMap sheetToBlocks sheets+   in (mempty, sheetBlocks)++-- | Convert sheet to blocks (header + table)+sheetToBlocks :: XlsxSheet -> [Block]+sheetToBlocks sheet =+  let SheetId n = sheetId sheet+      name = sheetName sheet+      sheetIdent = "sheet-" <> T.pack (show n)+      header = Header 2 (sheetIdent, [], []) (B.toList (B.text name))++      -- Convert cells to table+      tableBlock = case cellsToTable sheet of+        Just tbl -> [tbl]+        Nothing -> []  -- Empty sheet+   in header : tableBlock++-- | Convert cells to Pandoc Table+cellsToTable :: XlsxSheet -> Maybe Block+cellsToTable sheet+  | M.null (sheetCells sheet) = Nothing+  | otherwise =+      let cells = sheetCells sheet+          -- Get bounds+          refs = sort $ M.keys cells+          minCol = minimum $ map cellRefCol refs+          maxCol = maximum $ map cellRefCol refs+          minRow = minimum $ map cellRefRow refs+          maxRow = maximum $ map cellRefRow refs++          -- Build dense grid+          grid = [ [ M.lookup (CellRef col row) cells+                   | col <- [minCol..maxCol]+                   ]+                 | row <- [minRow..maxRow]+                 ]++          -- First row is header (simple heuristic)+          (headerRow, bodyRows) = case grid of+            (h:bs) -> (h, bs)+            [] -> ([], [])++          -- Filter out trailing empty rows (rows with only whitespace)+          filteredBodyRows = dropWhileEnd isEmptyRow bodyRows++          makeCell mcell = case mcell of+            Just cell ->+              let inlines = cellToInlines cell+               in Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) [Plain inlines]+            Nothing ->+              Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) [Plain []]++          numCols = length headerRow+          colSpec = replicate numCols (AlignDefault, ColWidthDefault)+          thead = TableHead nullAttr [Row nullAttr $ map makeCell headerRow]+          tbody = [TableBody nullAttr 0 [] $ map (Row nullAttr . map makeCell) filteredBodyRows]+          tfoot = TableFoot nullAttr []++       in Just $ Table nullAttr (Caption Nothing []) colSpec thead tbody tfoot++-- | Check if a row contains only whitespace or empty cells+isEmptyRow :: [Maybe XlsxCell] -> Bool+isEmptyRow = all isEmptyCell+  where+    isEmptyCell Nothing = True+    isEmptyCell (Just cell) = case cellValue cell of+      EmptyValue -> True+      TextValue t -> T.all isSpace t+      NumberValue _ -> False++-- | Convert cell to Pandoc inlines+cellToInlines :: XlsxCell -> [Inline]+cellToInlines cell =+  let base = case cellValue cell of+        TextValue t -> B.toList $ B.text t+        NumberValue n -> [Str $ T.pack $ show n]+        EmptyValue -> []++      applyBold inls = if cellBold cell then [Strong inls] else inls+      applyItalic inls = if cellItalic cell then [Emph inls] else inls++   in applyItalic $ applyBold base
src/Text/Pandoc/Templates.hs view
@@ -121,6 +121,11 @@        "markdown_phpextra" -> getDefaultTemplate "markdown"        "gfm"               -> getDefaultTemplate "commonmark"        "commonmark_x"      -> getDefaultTemplate "commonmark"+       "bbcode_phpbb"      -> getDefaultTemplate "bbcode"+       "bbcode_fluxbb"     -> getDefaultTemplate "bbcode"+       "bbcode_steam"      -> getDefaultTemplate "bbcode"+       "bbcode_hubzilla"   -> getDefaultTemplate "bbcode"+       "bbcode_xenforo"    -> getDefaultTemplate "bbcode"        _        -> do          let fname = "templates" </> "default" <.> T.unpack format          readDataFile fname >>= toTextM fname
src/Text/Pandoc/Writers.hs view
@@ -80,6 +80,12 @@     , writeXWiki     , writeZimWiki     , writeVimdoc+    , writeBBCode+    , writeBBCodeSteam+    , writeBBCodeFluxBB+    , writeBBCodePhpBB+    , writeBBCodeHubzilla+    , writeBBCodeXenforo     , getWriter     ) where @@ -134,6 +140,14 @@ import Text.Pandoc.Writers.XWiki import Text.Pandoc.Writers.ZimWiki import Text.Pandoc.Writers.Vimdoc+import Text.Pandoc.Writers.BBCode (+  writeBBCode,+  writeBBCodeFluxBB,+  writeBBCodeHubzilla,+  writeBBCodePhpBB,+  writeBBCodeSteam,+  writeBBCodeXenforo,+ )  data Writer m = TextWriter (WriterOptions -> Pandoc -> m Text)               | ByteStringWriter (WriterOptions -> Pandoc -> m BL.ByteString)@@ -209,6 +223,12 @@   ,("ansi"         , TextWriter writeANSI)   ,("xml"          , TextWriter writeXML)   ,("vimdoc"       , TextWriter writeVimdoc)+  ,("bbcode"       , TextWriter writeBBCode)+  ,("bbcode_steam" , TextWriter writeBBCodeSteam)+  ,("bbcode_phpbb" , TextWriter writeBBCodePhpBB)+  ,("bbcode_fluxbb", TextWriter writeBBCodeFluxBB)+  ,("bbcode_hubzilla" , TextWriter writeBBCodeHubzilla)+  ,("bbcode_xenforo" , TextWriter writeBBCodeXenforo)   ]  -- | Retrieve writer, extensions based on formatSpec (format+extensions).
src/Text/Pandoc/Writers/ANSI.hs view
@@ -15,6 +15,7 @@ import Control.Monad.State.Strict ( StateT, gets, modify, evalStateT ) import Control.Monad (foldM) import Data.List (intersperse)+import qualified Data.Map as M import Data.Maybe (fromMaybe) import Data.Text (Text) import Text.DocLayout ((<+>), ($$), ($+$))@@ -108,9 +109,7 @@ titleBlock width meta =   if null most      then D.empty-     else (case width of-             Just w -> D.cblock w-             Nothing -> id) $ most $+$ hr+     else (maybe id D.cblock width) $ most $+$ hr   where     title = D.bold (fromMaybe D.empty $ getField "title" meta)     subtitle = fromMaybe D.empty $ getField "subtitle" meta@@ -193,7 +192,6 @@   contents <- withFewerColumns 2 $ blockListToANSI opts blocks   return ( D.prefixed "│ " contents $$ D.blankline) --- TODO: Row spans don't work blockToANSI opts (Table _ (Caption _ caption) colSpecs (TableHead _ thead) tbody (TableFoot _ tfoot)) = do   let captionInlines = blocksToInlines caption   captionMarkup <-@@ -215,22 +213,40 @@       maxWidth k = claimWidth k   let widths = map maxWidth inWidths   let decor = [D.hsep $ map rule widths]-  head' <- mapM (goRow widths . unRow) thead-  body' <- mapM (goRow widths . unRow) (unBodies tbody)-  foot' <- mapM (goRow widths . unRow) tfoot+  head' <- (makeRows widths . map unRow) thead+  body' <- (makeRows widths . map unRow) (tableBodiesToRows tbody)+  foot' <- (makeRows widths . map unRow) tfoot   modify $ \s -> s{stInTable = wasTable}   return $ D.vcat (head' <> decor <> body' <> decor <> foot') $+$ captionMarkup   where     unRow (Row _ cs) = cs-    unBody (TableBody _ _ hd bd) = hd <> bd-    unBodies = concatMap unBody-    goRow ws cs = do-      (d, _) <- foldM goCell ([], ws) cs-      return $ D.hcat $ intersperse (D.vfill " ") $ reverse d-    goCell (r, ws) (Cell _ aln _ (ColSpan cspan) inner) = do+    makeRows ws rows = do+      (docs, _) <- foldM (goRow ws) ([], M.empty) rows+      return $ reverse docs+    goRow _ (r, spans) [] =+      -- Empty rows are not displayed but previous row spans still apply for them.+      let spans' = M.map decrementPreviousRowSpans spans+      in  return (r, spans')+    goRow ws (r, spans) cs = do+      (d, (nextPos, spans'), _) <- foldM goCell ([], (0, spans), ws) cs+      let spans'' = decrementTrailingRowSpans nextPos spans' -- Handle previous row spans next to the end of the current row+      return (D.hcat (intersperse (D.vfill " ") $ reverse d):r, spans'')+    goCell (r, (colPos, spans), ws) cell@(Cell _ aln (RowSpan rspan) (ColSpan cspan) inner)+      | Just (ColSpan previousColSpan, spans') <- takePreviousSpansAtColumn colPos spans = do+          (r', nextPos, ws') <- makeCell r colPos ws AlignDefault previousColSpan []+          goCell (r', (nextPos, spans'), ws') cell+      | otherwise = do+          (r', nextPos, ws') <- makeCell r colPos ws aln cspan inner+          let spans' = insertCurrentSpansAtColumn colPos spans (RowSpan rspan) (ColSpan cspan)+          return (r', (nextPos, spans'), ws')+    decrementPreviousRowSpans spans@(RowSpan rspan, cspan) =+      if rspan >= 1+        then (RowSpan rspan - 1, cspan)+        else spans+    makeCell r colPos ws aln cspan inner = do       let (ws', render) = next ws aln cspan       innerDoc <- blockListToANSI opts inner-      return ((render innerDoc):r, ws')+      return ((render innerDoc):r, colPos + cspan, ws')     tcell AlignLeft    = D.lblock     tcell AlignRight   = D.rblock     tcell AlignCenter  = D.cblock
src/Text/Pandoc/Writers/AsciiDoc.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP  #-} {-# LANGUAGE LambdaCase        #-} {-# LANGUAGE OverloadedStrings #-} {- |@@ -28,9 +29,15 @@ import Control.Monad.State.Strict     ( StateT, MonadState(get), gets, modify, evalStateT ) import Data.Char (isPunctuation, isSpace)-import Data.List (delete, intercalate, intersperse)-import Data.List.NonEmpty (NonEmpty(..))-import Data.Maybe (fromMaybe, isJust)+#if MIN_VERSION_base(4,19,0)+import Data.List (delete, intercalate, intersperse, mapAccumL, uncons, sortOn, unsnoc)+#else+import Data.List (delete, intercalate, intersperse, mapAccumL, uncons, sortOn)+#endif+import Data.List.NonEmpty (NonEmpty((:|)), (<|))+import qualified Data.List.NonEmpty as NonEmpty+import Data.Maybe (fromMaybe, isJust, catMaybes)+import qualified Data.Map as M import qualified Data.Set as Set import qualified Data.Text as T import Data.Text (Text)@@ -43,12 +50,18 @@ import Text.Pandoc.Options import Text.Pandoc.Parsing hiding (blankline, space) import Text.DocLayout+import Text.Pandoc.Builder (emptyCell) import Text.Pandoc.Shared import Text.Pandoc.URI import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Shared import Text.Pandoc.Walk (walk) +#if !MIN_VERSION_base(4,19,0)+unsnoc :: [a] -> Maybe ([a], a)+unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing+#endif+ data WriterState = WriterState { defListMarker       :: Text                                , orderedListLevel    :: Int                                , bulletListLevel     :: Int@@ -269,9 +282,12 @@                      else contents   let bar = text "____"   return $ bar $$ chomp contents' $$ bar <> blankline-blockToAsciiDoc opts block@(Table _ blkCapt specs thead tbody tfoot) = do-  let (caption, aligns, widths, headers, rows) =-        toLegacyTable blkCapt specs thead tbody tfoot+blockToAsciiDoc opts block@(Table _ blkCapt specs thead@(TableHead _ originalHeaders) originalTbody tfoot@(TableFoot _ originalFooters)) = do+  let (caption, aligns, widths, _, _) =+        toLegacyTable blkCapt specs thead originalTbody tfoot+  let headers = adjustEmptyRows originalHeaders+  let rows = adjustEmptyRows $ tableBodiesToRows originalTbody+  let footers = adjustEmptyRows originalFooters   caption' <- inlineListToAsciiDoc opts caption   let caption'' = if null caption                      then empty@@ -290,15 +306,19 @@                      ws        -> ws   let totalwidth :: Integer       totalwidth = floor $ sum widths * 100-  let colspec al wi = (case al of-                         AlignLeft    -> "<"-                         AlignCenter  -> "^"-                         AlignRight   -> ">"-                         AlignDefault -> "") +++  let alignmentOperator AlignLeft     = "<"+      alignmentOperator AlignCenter   = "^"+      alignmentOperator AlignRight    = ">"+      alignmentOperator AlignDefault  = ""+  let colspec al wi = (alignmentOperator al) ++                       if wi == 0 then "" else show wi ++ "%"-  let headerspec = if all null headers+  let optionSpecForRows rowList spec = if allRowsEmpty rowList then Nothing else Just spec+  let headerspec = optionSpecForRows headers "header"+  let footerspec = optionSpecForRows footers "footer"+  let optionsList = catMaybes [headerspec, footerspec]+  let optionsspec = if null optionsList                       then empty-                      else text "options=\"header\","+                      else text "options=\"" <> text (intercalate "," optionsList) <> text "\","   let widthspec = if totalwidth == 0                      then empty                      else text "width="@@ -310,7 +330,7 @@          <> doubleQuotes (text $ intercalate ","              $ zipWith colspec aligns widths')          <> text ","-         <> headerspec <> text "]"+         <> optionsspec <> text "]"    -- construct cells and recurse in case of nested tables   parentTableLevel <- gets tableNestingLevel@@ -335,19 +355,48 @@                                d <- blockListToAsciiDoc opts bs                                return $ (text "a" <> separator) $$ d -  let makeRow cells = hsep `fmap` mapM makeCell cells-  rows' <- mapM makeRow rows-  head' <- makeRow headers+  let colSpanFactor (ColSpan colSpan) = if colSpan > 1+                                          then text $ show colSpan+                                          else empty+  let rowSpanFactor (RowSpan rowSpan) = if rowSpan > 1+                                          then text $ "." ++ show rowSpan+                                          else empty++  let makeCellWithSpansAndAlignment (Cell _ alignment rowSpan colSpan blocks) = do+        let spanFactor = colSpanFactor colSpan <> rowSpanFactor rowSpan+        cell <- makeCell blocks+        let alignedCell = alignmentOperator alignment <> cell++        return $ if null spanFactor+          then alignedCell+          else spanFactor <> text "+" <> alignedCell++  let makeRow (Row attr []) = makeRow $ Row attr $ replicate (length widths') emptyCell+      makeRow (Row _ cells) = hsep `fmap` mapM makeCellWithSpansAndAlignment cells++  -- AsciiDoc only supports 1 header row and 1 footer row.+  let headerRow = Data.List.uncons $ adjustHeaders headers+  let footerRow = unsnoc $ adjustFooters footers+  let tailHeaderRows = if allRowsEmpty headers then [] else maybe [] snd headerRow+  let initFooterRows = if allRowsEmpty footers then [] else maybe [] fst footerRow+  rows' <- mapM makeRow $ tailHeaderRows ++ rows ++ initFooterRows+  head' <- case headerRow of+            Nothing -> return empty+            Just (headerRow', _) -> makeRow headerRow'+  foot <- case footerRow of+            Nothing -> return empty+            Just (_, footerRow') -> makeRow footerRow'   modify $ \st -> st{ tableNestingLevel = parentTableLevel }-  let head'' = if all null headers then empty else head'+  let head'' = if allRowsEmpty headers then empty else head'+  let foot' = if allRowsEmpty footers then empty else foot   let colwidth = if writerWrapText opts == WrapAuto                     then writerColumns opts                     else 100000-  let maxwidth = maximum $ fmap offset (head' :| rows')+  let maxwidth = maximum $ fmap offset (foot <| (head' :| rows'))   let body = if maxwidth > colwidth then vsep rows' else vcat rows'   let border = separator <> text "==="   return $-    caption'' $$ tablespec $$ border $$ head'' $$ body $$ border $$ blankline+    caption'' $$ tablespec $$ border $$ head'' $$ body $$ foot' $$ border $$ blankline blockToAsciiDoc opts (BulletList items) = do   inlist <- gets inList   modify $ \st -> st{ inList = True }@@ -715,3 +764,144 @@                 then empty                 else "," <> mconcat (intersperse "," dimList)   return $ literal src <> "[" <> linktext <> linktitle <> dims <> "]"++-- | Adjust header rows for the fact that AsciiDoc only supports a single header row.+--+-- The first header row will become the single header row in AsciiDoc with the+-- other rows becoming the top body rows.+-- All cells of the first header row with a RowSpan > 1 will be mapped to+-- RowSpan 1 and the remaining RowSpans of those cells wll be added as empty+-- columns into the second row beneath them to preserve the original layout.+adjustHeaders :: [Row] -> [Row]+adjustHeaders [] = []+adjustHeaders [row] = [row]+adjustHeaders (Row attr firstHeaderCells:secondRow:remainingRows) =+  let ((_, emptyHeaderCells), headerRow) = mapAccumL adjustHeaderRowCell (0, []) firstHeaderCells+      secondRow' = applyEmptyCells secondRow emptyHeaderCells+  in  Row attr headerRow:secondRow':remainingRows+ where+  adjustHeaderRowCell (columnPosition, emptyCells) cell@(Cell cellAttr alignment (RowSpan rowSpan) (ColSpan colSpan) blocks) =+    let nextColumnPosition = columnPosition + colSpan+        adjustedHeaderCell = Cell cellAttr alignment (RowSpan 1) (ColSpan colSpan) blocks+        emptyHeaderRowCell = Cell nullAttr AlignDefault (RowSpan rowSpan - 1) (ColSpan colSpan) []+        emptyCellPosition = (columnPosition, emptyHeaderRowCell)+    in  if rowSpan > 1+          then ((nextColumnPosition, emptyCellPosition:emptyCells), adjustedHeaderCell)+          else ((nextColumnPosition, emptyCells), cell)++-- | Adjust footer rows for the fact that AsciiDoc only supports a single footer row.+--+-- The last footer row will become the single footer row in AsciiDoc with the+-- previous footer rows becoming the bottom body rows.+-- All column indices of cells whose RowSpans would reach that last footer row+-- are collected and subtracted by 1. Those collected column indices will then+-- be applied as empty columns into the last footer row to preserve the original+-- layout.+adjustFooters :: [Row] -> [Row]+adjustFooters [] = []+adjustFooters [row] = [row]+adjustFooters rows = adjustFooters' [] (0, length rows) M.empty rows+ where+  adjustFooters' _ _ _ [] = []+  adjustFooters' columnIndices _ _ [row] = [applyEmptyCells row columnIndices]+  adjustFooters' columnIndices rowInfo@(rowIndex, footerLength) previousRowSpans (row:rest) =+    -- Need to keep track of RowSpans from previous rows and how they occupy+    -- space in rows beneath them to be able to apply the correct column+    -- position of RowSpans that would reach the last footer row.+    let (previousRowSpans', row', columnIndices') = adjustFooterRow rowInfo previousRowSpans row+        rows' = adjustFooters' (columnIndices ++ columnIndices') (rowIndex + 1, footerLength) previousRowSpans' rest+    in  row':rows'++  adjustFooterRow rowInfo previousRowSpans (Row attr cells) =+    let ((nextColumnPosition, previousRowSpans'), cells') = mapAccumL (adjustFooterCell rowInfo) (0, previousRowSpans) cells+        (cells'', columnIndices) = unzip cells'++        -- Apply row spans from a previous row that are next to the end of the+        -- current row's cells to keep track of the correct column position.+        previousRowSpans'' = decrementTrailingRowSpans nextColumnPosition previousRowSpans'+    in  (previousRowSpans'', Row attr cells'', catMaybes columnIndices)++-- | Adjust footer cell for the fact that AsciiDoc only supports a single footer row.+--+-- Collects cells whose RowSpan would reach to the last footer row and applies+-- them as empty cells to that last footer row.+adjustFooterCell :: (Int, Int) -> (Int, M.Map Int (RowSpan, ColSpan)) -> Cell -> ((Int, M.Map Int (RowSpan, ColSpan)), (Cell, Maybe (Int, Cell)))+adjustFooterCell rowInfo@(rowIndex, footerLength) (columnPosition, previousSpans) cell@(Cell _ _ (RowSpan rowSpan) (ColSpan colSpan) _)+  | Just (ColSpan previousColSpan, previousSpans') <- takePreviousSpansAtColumn columnPosition previousSpans =+      -- Apply row span from a previous row that occupies this column to keep+      -- track of the correct column position.+      adjustFooterCell rowInfo (columnPosition + previousColSpan, previousSpans') cell+  | rowSpan > 1 && rowIndex + rowSpan >= footerLength =+      -- Adjust row span that would reach all the way to the last footer row and+      -- keep track of that to apply it to the last footer row.+      ((nextColumnPosition, previousRowSpans'), (decrementRowSpanInCell cell, Just (columnPosition, emptyCellWithColSpan)))+  | otherwise = ((nextColumnPosition, previousRowSpans'), (cell, Nothing))+ where+  -- Keep track of this cell's RowSpan for the rows following it.+  previousRowSpans' = insertCurrentSpansAtColumn columnPosition previousSpans (RowSpan rowSpan) (ColSpan colSpan)+  nextColumnPosition = columnPosition + colSpan+  emptyCellWithColSpan = Cell nullAttr AlignDefault (RowSpan 1) (ColSpan colSpan) []++-- | Adjust empty rows for AsciiDoc.+--+-- An empty row without any cells decrements RowSpans that cover it and is+-- removed by them to adjust for being unable to express empty rows with no+-- cells in AsciiDoc.+adjustEmptyRows :: [Row] -> [Row]+adjustEmptyRows = adjustEmptyRows' . map applyInitialRowsLeft+ where+  adjustEmptyRows' [] = []+  adjustEmptyRows' (row:rest)+    | maxRowSpan' <- maxRowSpan row+    , maxRowSpan' > 1 =+        -- Consume empty rows within the row's span.+        let followingRows = take (maxRowSpan' - 1) rest+            rows = consumeEmptyRows (row :| []) followingRows+            rest' = drop (length followingRows) rest+        in  rowFromCellsWithRowsLeft (NonEmpty.head rows) : adjustEmptyRows' (NonEmpty.tail rows ++ rest')+    | otherwise = rowFromCellsWithRowsLeft row : adjustEmptyRows' rest++  rowFromCellsWithRowsLeft (attr, cellsWithRowsLeft) = Row attr $ map fst cellsWithRowsLeft+  cellRowSpan (Cell _ _ (RowSpan rowSpan) _ _) = rowSpan++  consumeEmptyRows rows [] = NonEmpty.reverse rows+  consumeEmptyRows rows (followingRow:restRows) =+    if null (snd followingRow) && any rowHasRowSpanAndRowsLeft rows+      then consumeEmptyRows (fmap (subtractRowsLeft decrementRowSpanInCell) rows) restRows -- Consume empty row for RowSpan and remove it+      else consumeEmptyRows (followingRow <| fmap (subtractRowsLeft id) rows) restRows++  rowHasRowSpanAndRowsLeft (_, cells) = any cellHasRowSpanAndRowsLeft cells+  cellHasRowSpanAndRowsLeft (cell, rowsLeft) = cellRowSpan cell > 1 && rowsLeft >= 1++  subtractRowsLeft changeCell (attr, cells) = (attr, map (subtractRowsLeftCell changeCell) cells)++  subtractRowsLeftCell changeCell cellPair@(cell, rowsLeft)+    | rowsLeft >= 1 = (changeCell cell, rowsLeft - 1)+    | otherwise = cellPair++  applyInitialRowsLeft (Row attr cells) = (attr, map applyInitialRowsLeftCell cells)++  applyInitialRowsLeftCell cell+    | rowSpan <- cellRowSpan cell, rowSpan > 1 = (cell, rowSpan - 1) -- Minus its own row+    | otherwise = (cell, 0)++  maxRowSpan (_, []) = 0+  maxRowSpan (_, cells) = maximum $ map (cellRowSpan . fst) cells++-- | Decrement the RowSpan of a Cell if that RowSpan > 1.+decrementRowSpanInCell :: Cell -> Cell+decrementRowSpanInCell cell@(Cell attr alignment (RowSpan rowSpan) colSpan blocks) =+  if rowSpan > 1+    then Cell attr alignment (RowSpan rowSpan - 1) colSpan blocks+    else cell++-- | Apply empty table cells at the given positions inside a Row.+applyEmptyCells :: Row -> [(Int, Cell)] -> Row+applyEmptyCells (Row attr cells) = Row attr . applyEmptyCells' 0 cells . sortOn fst+ where+  applyEmptyCells' _  cells' [] = cells'+  applyEmptyCells' currentPosition cells' ((columnPosition, columnEmptyCell@(Cell _ _ _ (ColSpan colSpan) _)):rest)+    | columnPosition == currentPosition = columnEmptyCell : applyEmptyCells' (currentPosition + colSpan) cells' rest+  applyEmptyCells' _ [] _ = []+  applyEmptyCells' currentPosition (cell@(Cell _ _ _ (ColSpan currentCellColSpan) _):restCells) emptyCellList =+    cell : applyEmptyCells' (currentPosition + currentCellColSpan) restCells emptyCellList
+ src/Text/Pandoc/Writers/BBCode.hs view
@@ -0,0 +1,1089 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE TypeApplications #-}+{- |+   Module      : Text.Pandoc.Writers.BBCode+   Copyright   : © 2025 Aleksey Myshko <git@crii.xyz>+   License     : GNU GPL, version 2 or above++   Maintainer  : Aleksey Myshko <git@crii.xyz>+   Stability   : alpha+   Portability : portable++Conversion of 'Pandoc' documents to various BBCode flavors.+-}++module Text.Pandoc.Writers.BBCode (+  -- * Predefined writers+  -- Writers for different flavors of BBCode. 'writeBBCode' is a synonym for+  -- 'writeBBCode_official'+  writeBBCode,+  writeBBCodeOfficial,+  writeBBCodeSteam,+  writeBBCodePhpBB,+  writeBBCodeFluxBB,+  writeBBCodeHubzilla,+  writeBBCodeXenforo,++  -- * Extending the writer+  -- $extending+  FlavorSpec (..),+  WriterState (..),+  RR,+  writeBBCodeCustom,+  inlineToBBCode,+  inlineListToBBCode,+  blockToBBCode,+  blockListToBBCode,++  -- ** Handling attributes+  -- $wrapping_spans_divs+  attrToMap,++  -- * Predefined flavor specifications+  officialSpec,+  steamSpec,+  phpbbSpec,+  fluxbbSpec,+  hubzillaSpec,+  xenforoSpec,+) where++import Control.Applicative (some)+import Control.Monad (forM)+import Control.Monad.Reader (MonadReader (..), ReaderT (..), asks)+import Control.Monad.State (MonadState (..), StateT, evalStateT, gets, modify)+import Data.Default (Default (..))+import Data.Either (isRight)+import Data.Foldable (toList)+import Data.Map.Strict (Map)+import qualified Data.Map.Strict as Map+import Data.Maybe (fromMaybe, isJust)+import Data.Sequence (Seq, (|>))+import qualified Data.Sequence as Seq+import Data.Text (Text)+import qualified Data.Text as T+import Text.DocLayout hiding (char, link, text)+import Text.Pandoc.Class.PandocMonad (PandocMonad, report)+import Text.Pandoc.Definition+import Text.Pandoc.Logging (LogMessage (..))+import Text.Pandoc.Options (WriterOptions (..))+import Text.Pandoc.Parsing (char, digit, eof, readWith)+import Text.Pandoc.Shared (inquotes, onlySimpleTableCells, removeFormatting, trim, tshow)+import Text.Pandoc.Templates (renderTemplate)+import Text.Pandoc.URI (escapeURI)+import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable, unsmartify)+import Text.Read (readMaybe)++-- Type synonym to prevent haddock-generated HTML from overflowing+type PandocTable =+  (Attr, Caption, [ColSpec], TableHead, [TableBody], TableFoot)++-- $extending+-- If you want to support more Pandoc elements (or render some of them+-- differently) you can do so by creating your own 'FlavorSpec'+--+-- The module exports the @'FlavorSpec'@s underlying @writeBBCode_*@ functions,+-- namely 'officialSpec', 'steamSpec', 'phpbbSpec', 'fluxbbSpec',+-- 'hubzillaSpec'.+--+-- You can create and use your own renderers, for instance here we define a+-- renderer for 'CodeBlock' and use it to create a derivative format:+--+-- > renderCodeBlockCustom :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+-- > renderCodeBlockCustom (_, cls, _) code = do+-- >   let opening = case cls of+-- >         (lang : _) -> "[code=" <> lang <> "]"+-- >         ("c++" : _) -> "[code=cpp]"+-- >         _ -> "[code]"+-- >   pure $ mconcat [literal opening, literal code, cr, "[/code]"]+-- >+-- > specCustom = officialSpec{renderCodeBlock = renderCodeBlockCustom}+--+-- Then we can use it to render 'Pandoc' document via 'writeBBCode_custom'++{- | Data type that is a collection of renderers for most elements in a Pandoc+AST (see 'Block' and 'Inline')++The intention here is to allow inheritance between formats, for instance if+format A and format @B@ differ only in rendering tables, @B@ can be implemented+as @A{'renderTable' = renderTableB}@+-}+data FlavorSpec = FlavorSpec+  { renderBlockQuote ::+      forall m.+      (PandocMonad m) =>+      [Block] ->+      RR m (Doc Text)+  -- ^ Render 'BlockQuote'+  , renderBulletList ::+      forall m.+      (PandocMonad m) =>+      [[Block]] ->+      RR m (Doc Text)+  -- ^ Render 'BulletList'+  , renderCodeBlock ::+      forall m.+      (PandocMonad m) =>+      Attr ->+      Text ->+      RR m (Doc Text)+  -- ^ Render 'CodeBlock'+  , renderDefinitionList ::+      forall m.+      (PandocMonad m) =>+      [([Inline], [[Block]])] ->+      RR m (Doc Text)+  -- ^ Render 'DefinitionList'+  , renderHeader ::+      forall m.+      (PandocMonad m) =>+      Int ->+      Attr ->+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Header'+  , renderInlineCode ::+      forall m.+      (PandocMonad m) =>+      Attr ->+      Text ->+      RR m (Doc Text)+  -- ^ Render 'Code'+  , renderLink ::+      forall m.+      (PandocMonad m) =>+      Attr ->+      [Inline] ->+      Target ->+      RR m (Doc Text)+  -- ^ Render 'Link'+  , renderOrderedList ::+      forall m.+      (PandocMonad m) =>+      ListAttributes ->+      [[Block]] ->+      RR m (Doc Text)+  -- ^ Render 'OrderedList'+  , renderStrikeout ::+      forall m.+      (PandocMonad m) =>+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Strikeout'+  , renderTable :: forall m. (PandocMonad m) => PandocTable -> RR m (Doc Text)+  -- ^ Render 'Table'+  , renderHorizontalRule ::+      forall m.+      (PandocMonad m) =>+      RR m (Doc Text)+  -- ^ Render 'HorizontalRule'+  , renderLineBlock ::+      forall m.+      (PandocMonad m) =>+      [[Inline]] ->+      RR m (Doc Text)+  -- ^ Render 'LineBlock'+  , renderPara ::+      forall m.+      (PandocMonad m) =>+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Para'+  , renderSuperscript ::+      forall m.+      (PandocMonad m) =>+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Superscript'+  , renderSubscript :: forall m. (PandocMonad m) => [Inline] -> RR m (Doc Text)+  -- ^ Render 'Subscript'+  , renderSmallCaps :: forall m. (PandocMonad m) => [Inline] -> RR m (Doc Text)+  -- ^ Render 'SmallCaps'+  , renderCite ::+      forall m.+      (PandocMonad m) =>+      [Citation] ->+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Cite'+  , renderNote :: forall m. (PandocMonad m) => [Block] -> RR m (Doc Text)+  -- ^ Render 'Note'+  , renderFigure ::+      forall m.+      (PandocMonad m) =>+      Attr ->+      Caption ->+      [Block] ->+      RR m (Doc Text)+  -- ^ Render 'Figure'+  , renderQuoted ::+      forall m.+      (PandocMonad m) =>+      QuoteType ->+      [Inline] ->+      RR m (Doc Text)+  -- ^ Render 'Quoted'+  , renderMath ::+      forall m.+      (PandocMonad m) =>+      MathType ->+      Text ->+      RR m (Doc Text)+  -- ^ Render 'Math'+  , renderImage ::+      forall m.+      (PandocMonad m) =>+      Attr ->+      [Inline] ->+      Target ->+      RR m (Doc Text)+  -- ^ Render 'Image'+  , wrapSpanDiv :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+  -- ^ Wrap document in bbcode tags based on attributes/classes. Boolean flag+  -- indicates whether passed argument is a Div or a Span (True means Div)+  }++data WriterState = WriterState+  { writerOptions :: WriterOptions+  , flavorSpec :: FlavorSpec+  , inList :: Bool+  }++instance Default WriterState where+  def =+    WriterState+      { writerOptions = def+      , flavorSpec = officialSpec+      , inList = False+      }++-- | The base of a renderer monad.+type RR m a = StateT (Seq (Doc Text)) (ReaderT WriterState m) a++pandocToBBCode :: (PandocMonad m) => Pandoc -> RR m Text+pandocToBBCode (Pandoc meta body) = do+  opts <- asks writerOptions+  -- Run the rendering that mutates the state by producing footnotes+  bodyContents <- blockListToBBCode body+  -- Get the footnotes+  footnotes <- get+  -- Separate footnotes (if any) with a horizontal rule+  footnotesSep <-+    if null footnotes+      then pure empty+      else+        (\hr -> blankline <> hr <> blankline)+          <$> blockToBBCode HorizontalRule+  -- Put footnotes after the main text+  let docText = bodyContents <> footnotesSep <> vsep (toList footnotes)+  metadata <- metaToContext opts blockListToBBCode inlineListToBBCode meta+  let context = defField "body" docText metadata+  case writerTemplate opts of+    Just tpl -> pure $ render Nothing (renderTemplate tpl context)+    Nothing -> pure $ render Nothing docText++writeBBCode+  , writeBBCodeOfficial+  , writeBBCodeSteam+  , writeBBCodePhpBB+  , writeBBCodeFluxBB+  , writeBBCodeHubzilla+  , writeBBCodeXenforo ::+    (PandocMonad m) => WriterOptions -> Pandoc -> m Text+writeBBCode = writeBBCodeOfficial+writeBBCodeOfficial = writeBBCodeCustom officialSpec+writeBBCodeSteam = writeBBCodeCustom steamSpec+writeBBCodePhpBB = writeBBCodeCustom phpbbSpec+writeBBCodeFluxBB = writeBBCodeCustom fluxbbSpec+writeBBCodeHubzilla = writeBBCodeCustom hubzillaSpec+writeBBCodeXenforo = writeBBCodeCustom xenforoSpec++{- | Convert a 'Pandoc' document to BBCode using the given 'FlavorSpec' and+'WriterOptions'.+-}+writeBBCodeCustom ::+  (PandocMonad m) => FlavorSpec -> WriterOptions -> Pandoc -> m Text+writeBBCodeCustom spec opts document =+  runRR mempty def{writerOptions = opts, flavorSpec = spec} $+    pandocToBBCode document+ where+  runRR :: (Monad m) => Seq (Doc Text) -> WriterState -> RR m a -> m a+  runRR footnotes writerState action =+    runReaderT (evalStateT action footnotes) writerState++blockListToBBCode :: (PandocMonad m) => [Block] -> RR m (Doc Text)+blockListToBBCode blocks =+  chomp . vsep . filter (not . null)+    <$> mapM blockToBBCode blocks++blockToBBCode :: (PandocMonad m) => Block -> RR m (Doc Text)+blockToBBCode block = do+  spec <- asks flavorSpec+  case block of+    Plain inlines -> inlineListToBBCode inlines+    Para inlines -> renderPara spec inlines+    LineBlock inliness -> renderLineBlock spec inliness+    CodeBlock attr code -> renderCodeBlock spec attr code+    RawBlock format raw -> case format of+      "bbcode" -> pure $ literal raw+      _ -> "" <$ report (BlockNotRendered block)+    BlockQuote blocks -> renderBlockQuote spec blocks+    OrderedList attr items -> renderOrderedList spec attr items+    BulletList items -> renderBulletList spec items+    DefinitionList items -> renderDefinitionList spec items+    Header level attr inlines -> renderHeader spec level attr inlines+    HorizontalRule -> renderHorizontalRule spec+    Table attr blkCapt specs thead tbody tfoot ->+      renderTable spec (attr, blkCapt, specs, thead, tbody, tfoot)+    Figure attr caption blocks -> renderFigure spec attr caption blocks+    Div attr blocks -> do+      contents <- blockListToBBCode blocks+      let kvcMap = attrToMap attr+      -- whether passed contents is a Div (Block) element+      --                      vvvv+      pure $ wrapSpanDiv spec True kvcMap contents++inlineToBBCode :: (PandocMonad m) => Inline -> RR m (Doc Text)+inlineToBBCode inline = do+  spec <- asks flavorSpec+  case inline of+    Str str -> do+      opts <- asks writerOptions+      pure . literal $ unsmartify opts str+    Emph inlines -> do+      contents <- inlineListToBBCode inlines+      pure $ mconcat ["[i]", contents, "[/i]"]+    Underline inlines -> do+      contents <- inlineListToBBCode inlines+      pure $ mconcat ["[u]", contents, "[/u]"]+    Strong inlines -> do+      contents <- inlineListToBBCode inlines+      pure $ mconcat ["[b]", contents, "[/b]"]+    Strikeout inlines -> renderStrikeout spec inlines+    Superscript inlines -> renderSuperscript spec inlines+    Subscript inlines -> renderSubscript spec inlines+    SmallCaps inlines -> renderSmallCaps spec inlines+    Quoted typ inlines -> renderQuoted spec typ inlines+    Cite cits inlines -> renderCite spec cits inlines+    Code attr code -> renderInlineCode spec attr code+    Space -> pure space+    SoftBreak -> pure space+    LineBreak -> pure cr+    Math typ math -> renderMath spec typ math+    RawInline (Format format) text -> case format of+      "bbcode" -> pure $ literal text+      _ -> "" <$ report (InlineNotRendered inline)+    Link attr txt target -> renderLink spec attr txt target+    Image attr alt target -> renderImage spec attr alt target+    Note blocks -> renderNote spec blocks+    Span attr inlines -> do+      contents <- inlineListToBBCode inlines+      let kvcMap = attrToMap attr+      -- whether passed contents is a Div (Block element)+      --                      vvvvv+      pure $ wrapSpanDiv spec False kvcMap contents++renderImageDefault ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderImageDefault (_, _, kvList) alt (source, title) = do+  altText <-+    trim . render Nothing+      <$> inlineListToBBCode (removeFormatting alt)+  let kvMap = Map.fromList kvList+  -- No BBCode flavor supported by the Writer has local images support, but we+  -- still allow source to be plain path or anything else+  pure . literal $+    mconcat+      [ "[img"+      , if T.null altText+          then ""+          else " alt=" <> inquotes altText+      , if T.null title+          then ""+          else " title=" <> inquotes title+      , case Map.lookup "width" kvMap of+          Just w+            | isJust (readMaybe @Int $ T.unpack w) ->+                " width=" <> inquotes w+          _ -> ""+      , case Map.lookup "height" kvMap of+          Just h+            | isJust (readMaybe @Int $ T.unpack h) ->+                " height=" <> inquotes h+          _ -> ""+      , "]"+      , source+      , "[/img]"+      ]++renderImageOmit ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderImageOmit _ _ _ = pure ""++{- | Basic phpBB doesn't support any attributes, although+@[img src=https://example.com]whatever[/img]@ is supported, but text in tag has+no effect+-}+renderImagePhpBB ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderImagePhpBB _ _ (source, _) =+  pure . literal $ mconcat ["[img]", source, "[/img]"]++renderImageXenforo ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderImageXenforo (_, _, kvList) alt (source, title) = do+  altText <-+    trim . render Nothing+      <$> inlineListToBBCode (removeFormatting alt)+  let kvMap = Map.fromList kvList+  -- No BBCode flavor supported by the Writer has local images support, but we+  -- still allow source to be plain path or anything else+  pure . literal $+    mconcat+      [ "[img"+      , if T.null altText+          then ""+          else " alt=" <> inquotes altText+      , if T.null title+          then ""+          else " title=" <> inquotes title+      , case Map.lookup "width" kvMap of+          Just w+            | isRight (readWith sizeP Nothing w) ->+                " width=" <> w+          _ -> ""+      , "]"+      , source+      , "[/img]"+      ]+ where+  sizeP = some digit >> char '%' >> eof++{- | Check whether character is a bracket++>>> T.filter notBracket "[a]b[[ó]qü]]n®"+"ab\243q\252n\174"+-}+notBracket :: Char -> Bool+notBracket = \case+  '[' -> False+  ']' -> False+  _ -> True++-- FluxBB uses [img=alt text] instead of [img alt="alt text"]+renderImageFluxBB ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderImageFluxBB _ alt (source, _) = do+  alt' <- T.filter notBracket . render Nothing <$> inlineListToBBCode alt+  pure . literal $+    mconcat+      [ "[img"+      , if T.null alt'+          then ""+          else "=" <> alt'+      , "]"+      , source+      , "[/img]"+      ]++inlineListToBBCode :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+inlineListToBBCode inlines = mconcat <$> mapM inlineToBBCode inlines++-- Taken from Data.Ord+clamp :: (Ord a) => (a, a) -> a -> a+clamp (low, high) a = min high (max a low)++renderHeaderDefault ::+  (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)+renderHeaderDefault level _attr inlines =+  case clamp (1, 4) level of+    1 -> inlineToBBCode $ Underline [Strong inlines]+    2 -> inlineToBBCode $ Strong inlines+    3 -> inlineToBBCode $ Underline inlines+    _ -> inlineListToBBCode inlines++-- Adapted from Text.Pandoc.Writers.Org+renderLinkDefault ::+  (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)+renderLinkDefault _ txt (src, _) =+  case txt of+    [Str x]+      | escapeURI x == src ->+          pure $ "[url]" <> literal x <> "[/url]"+    _ -> do+      contents <- inlineListToBBCode txt+      let suffix = if T.null src then "" else "=" <> src+      pure $ "[url" <> literal suffix <> "]" <> contents <> "[/url]"++renderCodeBlockDefault :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderCodeBlockDefault (_, cls, _) code = do+  let opening = case cls of+        (lang : _) -> "[code=" <> lang <> "]"+        _ -> "[code]"+  pure $ mconcat [literal opening, literal code, cr, "[/code]"]++renderCodeBlockSimple :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderCodeBlockSimple _ code = do+  pure $ mconcat [literal "[code]", literal code, cr, "[/code]"]++renderInlineCodeLiteral :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderInlineCodeLiteral _ code = pure $ literal code++renderInlineCodeNoParse :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderInlineCodeNoParse _ code =+  pure $ mconcat [literal "[noparse]", literal code, "[/noparse]"]++renderInlineCodeHubzilla :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderInlineCodeHubzilla _ code =+  pure $ mconcat [literal "[code]", literal code, "[/code]"]++renderInlineCodeXenforo :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)+renderInlineCodeXenforo _ code =+  pure $ mconcat [literal "[icode]", literal code, "[/icode]"]++renderStrikeoutDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderStrikeoutDefault inlines = do+  contents <- inlineListToBBCode inlines+  pure $ mconcat ["[s]", contents, "[/s]"]++renderStrikeoutSteam :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderStrikeoutSteam inlines = do+  contents <- inlineListToBBCode inlines+  pure $ mconcat ["[strike]", contents, "[/strike]"]++renderDefinitionListDefault ::+  (PandocMonad m) => [([Inline], [[Block]])] -> RR m (Doc Text)+renderDefinitionListDefault items = do+  items' <- forM items $ \(term, definitions) -> do+    term' <- inlineListToBBCode term+    definitions' <- blockToBBCode (BulletList definitions)+    pure $ term' $$ definitions'+  pure $ vcat items'++renderDefinitionListHubzilla ::+  (PandocMonad m) => [([Inline], [[Block]])] -> RR m (Doc Text)+renderDefinitionListHubzilla items = do+  items' <- forM items $ \(term, definitions) -> do+    term' <- inlineListToBBCode term+    let term'' = "[*= " <> term' <> "]"+    definitions' <- forM definitions blockListToBBCode+    pure $ vcat (term'' : definitions')+  pure $ vcat (literal "[dl terms=\"b\"]" : items' ++ [literal "[/dl]"])++listWithTags ::+  (PandocMonad m) =>+  Text ->+  Text ->+  ([[Block]] -> RR m [Doc Text]) ->+  [[Block]] ->+  RR m (Doc Text)+listWithTags open close renderItems items = do+  contents <- local (\s -> s{inList = True}) (renderItems items)+  pure $ vcat $ literal open : contents ++ [literal close]++starListItems :: (PandocMonad m) => [[Block]] -> RR m [Doc Text]+starListItems items = forM items $ \item -> do+  item' <- blockListToBBCode item+  pure $ literal "[*]" <> item'++listStyleCode :: ListNumberStyle -> Maybe Text+listStyleCode = \case+  Decimal -> Just "1"+  DefaultStyle -> Just "1"+  LowerAlpha -> Just "a"+  UpperAlpha -> Just "A"+  LowerRoman -> Just "i"+  UpperRoman -> Just "I"+  Example -> Nothing++renderBulletListOfficial :: (PandocMonad m) => [[Block]] -> RR m (Doc Text)+renderBulletListOfficial = listWithTags "[list]" "[/list]" starListItems++renderBulletListHubzilla :: (PandocMonad m) => [[Block]] -> RR m (Doc Text)+renderBulletListHubzilla = listWithTags "[ul]" "[/ul]" starListItems++renderOrderedListHubzilla ::+  (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)+renderOrderedListHubzilla (_, style, _) = case style of+  DefaultStyle -> listWithTags "[ol]" "[/ol]" starListItems+  Example -> listWithTags "[ol]" "[/ol]" starListItems+  _ -> listWithTags ("[list=" <> suffix <> "]") "[/list]" starListItems+ where+  suffix = fromMaybe "1" $ listStyleCode style++renderOrderedListOfficial ::+  (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)+renderOrderedListOfficial (_, style, _) = do+  let suffix = maybe "" ("=" <>) (listStyleCode style)+  listWithTags ("[list" <> suffix <> "]") "[/list]" starListItems++renderOrderedListSteam ::+  (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)+renderOrderedListSteam _ =+  listWithTags "[olist]" "[/olist]" starListItems++renderHeaderSteam ::+  (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)+renderHeaderSteam level _ inlines = do+  body <- inlineListToBBCode inlines+  let capped = clamp (1, 3) level+      open = "[h" <> tshow capped <> "]"+      close = "[/h" <> tshow capped <> "]"+  pure $ literal open <> body <> literal close++renderHeaderHubzilla ::+  (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)+renderHeaderHubzilla level _ inlines = do+  body <- inlineListToBBCode inlines+  let capped = clamp (1, 6) level+      open = "[h" <> tshow capped <> "]"+      close = "[/h" <> tshow capped <> "]"+  pure $ literal open <> body <> literal close++-- xenForo supports levels 1--3, but levels other than 1--3 become div with+-- .bbHeading class which can be linked to.+renderHeaderXenforo ::+  (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)+renderHeaderXenforo level _ inlines = do+  body <- inlineListToBBCode inlines+  let capped = max 1 level+      open = "[heading=" <> tshow capped <> "]"+      close = "[/heading]"+  pure $ literal open <> body <> literal close++renderTableGeneric ::+  (PandocMonad m) =>+  Text ->+  Text ->+  Text ->+  (Attr, Caption, [ColSpec], TableHead, [TableBody], TableFoot) ->+  RR m (Doc Text)+renderTableGeneric tableTag headerCellTag bodyCellTag table = do+  caption' <- inlineListToBBCode caption+  table' <-+    if not simpleCells+      then "" <$ report (BlockNotRendered tableBlock)+      else do+        headerDocs <-+          if null headers+            then pure []+            else pure <$> renderTableRow headerCellTag headers+        rowDocs <- mapM (renderTableRow bodyCellTag) rows+        pure $ renderTable' headerDocs rowDocs+  pure $ caption' $$ table'+ where+  (attr, blkCapt, specs, thead, tbody, tfoot) = table+  (caption, _, _, headers, rows) = toLegacyTable blkCapt specs thead tbody tfoot+  tableBlock = Table attr blkCapt specs thead tbody tfoot+  simpleCells = onlySimpleTableCells (headers : rows)+  renderTable' headerDocs rowDocs =+    vcat+      [ literal ("[" <> tableTag <> "]")+      , vcat headerDocs+      , vcat rowDocs+      , literal ("[/" <> tableTag <> "]")+      ]+  renderCell cellTag cellDoc =+    mconcat+      [ literal ("[" <> cellTag <> "]")+      , cellDoc+      , literal ("[/" <> cellTag <> "]")+      ]+  renderTableRow cellTag cells = do+    renderedCells <- mapM blockListToBBCode cells+    let cellsDoc = mconcat $ map (renderCell cellTag) renderedCells+    pure $ literal "[tr]" <> cellsDoc <> literal "[/tr]"++renderTableDefault ::+  (PandocMonad m) =>+  ( Attr+  , Caption+  , [ColSpec]+  , TableHead+  , [TableBody]+  , TableFoot+  ) ->+  RR m (Doc Text)+renderTableDefault = renderTableGeneric "table" "th" "td"++renderTableOmit ::+  (PandocMonad m) =>+  ( Attr+  , Caption+  , [ColSpec]+  , TableHead+  , [TableBody]+  , TableFoot+  ) ->+  RR m (Doc Text)+renderTableOmit (_, blkCapt, specs, thead, tbody, tfoot) = do+  let (caption, _, _, _, _) = toLegacyTable blkCapt specs thead tbody tfoot+  caption' <- inlineListToBBCode caption+  pure $ caption' $$ "(TABLE)"++-- $wrapping_spans_divs+-- Consider attribute a key-value pair with a Just value, and respectively+-- class is key-value pair with Nothing value.+-- For instance, given @("", ["cl1"], [("k", "v")]) :: 'Attr'@, respective Map+-- should look like @'Map.fromList' [("cl1", 'Nothing'), ("k", 'Just' "v")]@+--+-- This transformation is handled by 'attrToMap'+--+-- Example definition of a wrapSpanDiv:+--+-- > {-# LANGUAGE OverloadedStrings #-}+-- > import Data.Map (Map)+-- > import qualified Data.Map as Map+-- > import Text.DocLayout+-- > import Data.Text (Text)+-- > import qualified Data.Text as T+-- >+-- > wrapSpanDivSteam :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+-- > wrapSpanDivSteam isDiv kvc doc = Map.foldrWithKey wrap doc kvc+-- >  where+-- >   wrap "spoiler" (Just _) acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+-- >   wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+-- >   wrap _ _ acc = acc+--+-- To verify it works, wrap some text in unnamed spoiler+--+-- >>> render Nothing $ wrapSpanDivSteam True (attrToMap ("", ["spoiler"], [])) "I am text"+-- "[spoiler]I am text[/spoiler]"++{- | The goal of the transformation is to treat classes and key-value pairs+uniformly.++Class list becomes Map where all values are Nothing, and list of key-value+pairs is converted to Map via 'Map.toList'. Both Maps are then merged.+-}+attrToMap :: Attr -> Map Text (Maybe Text)+attrToMap (_, classes, kvList) =+  Map.fromList kvList' `Map.union` Map.fromList classes'+ where+  kvList' = map (\(k, v) -> (k, Just v)) kvList+  classes' = map (\k -> (k, Nothing)) classes++wrapSpanDivOfficial :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivOfficial isDiv kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "left" Nothing acc | isDiv = "[left]" <> acc <> "[/left]"+  wrap "center" Nothing acc | isDiv = "[center]" <> acc <> "[/center]"+  wrap "right" Nothing acc | isDiv = "[right]" <> acc <> "[/right]"+  wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+  wrap "spoiler" (Just v) acc+    | isDiv =+        literal ("[spoiler=" <> T.filter notBracket v <> "]")+          <> acc+          <> "[/spoiler]"+  wrap "size" (Just v) acc+    | Just v' <- readMaybe @Int (T.unpack v)+    , v' > 0 =+        literal ("[size=" <> v <> "]") <> acc <> "[/size]"+  wrap "color" (Just v) acc =+    literal ("[color=" <> v <> "]") <> acc <> "[/color]"+  wrap _ _ acc = acc++wrapSpanDivSteam :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivSteam isDiv kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "spoiler" (Just _) acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+  wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+  wrap _ _ acc = acc++wrapSpanDivPhpBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivPhpBB _ kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "color" (Just v) acc =+    literal ("[color=" <> v <> "]") <> acc <> "[/color]"+  wrap _ _ acc = acc++wrapSpanDivFluxBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivFluxBB _ kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "color" (Just v) acc =+    literal ("[color=" <> v <> "]") <> acc <> "[/color]"+  wrap _ _ acc = acc++wrapSpanDivHubzilla :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivHubzilla isDiv kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "center" Nothing acc | isDiv = "[center]" <> acc <> "[/center]"+  wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+  wrap "spoiler" (Just v) acc+    | isDiv =+        literal ("[spoiler=" <> T.filter notBracket v <> "]")+          <> acc+          <> "[/spoiler]"+  wrap "size" (Just v) acc+    | Just v' <- readMaybe @Int (T.unpack v)+    , v' > 0 =+        literal ("[size=" <> v <> "]") <> acc <> "[/size]"+  wrap "color" (Just v) acc =+    literal ("[color=" <> v <> "]") <> acc <> "[/color]"+  wrap "font" (Just v) acc = literal ("[font=" <> v <> "]") <> acc <> "[/font]"+  wrap _ _ acc = acc++wrapSpanDivXenforo :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text+wrapSpanDivXenforo isDiv kvc doc = Map.foldrWithKey wrap doc kvc+ where+  wrap "left" Nothing acc | isDiv = "[left]" <> acc <> "[/left]"+  wrap "center" Nothing acc | isDiv = "[center]" <> acc <> "[/center]"+  wrap "right" Nothing acc | isDiv = "[right]" <> acc <> "[/right]"+  wrap "spoiler" _ acc | not isDiv = "[ispoiler]" <> acc <> "[/ispoiler]"+  wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"+  wrap "spoiler" (Just v) acc+    | isDiv =+        literal ("[spoiler=" <> T.filter notBracket v <> "]")+          <> acc+          <> "[/spoiler]"+  wrap "size" (Just v) acc+    | Just v' <- readMaybe @Int (T.unpack v)+    , v' > 0 =+        literal ("[size=" <> v <> "]") <> acc <> "[/size]"+  wrap "color" (Just v) acc =+    literal ("[color=" <> v <> "]") <> acc <> "[/color]"+  wrap "font" (Just v) acc = literal ("[font=" <> v <> "]") <> acc <> "[/font]"+  wrap _ _ acc = acc++renderOrderedListFluxbb ::+  (PandocMonad m) =>+  ListAttributes ->+  [[Block]] ->+  RR m (Doc Text)+renderOrderedListFluxbb (_, style, _) =+  let suffix = case style of+        LowerAlpha -> "=a"+        UpperAlpha -> "=a"+        _ -> "=1"+   in listWithTags ("[list" <> suffix <> "]") "[/list]" starListItems++renderOrderedListXenforo ::+  (PandocMonad m) =>+  ListAttributes ->+  [[Block]] ->+  RR m (Doc Text)+renderOrderedListXenforo _ =+  listWithTags "[list=1]" "[/list]" starListItems++renderLinkEmailAware ::+  (PandocMonad m) =>+  Attr ->+  [Inline] ->+  Target ->+  RR m (Doc Text)+renderLinkEmailAware attr txt target@(src, _) = do+  case T.stripPrefix "mailto:" src of+    Just address -> do+      linkText <- inlineListToBBCode txt+      let isAutoEmail = case txt of+            [Str x] -> x == address+            _ -> False+      pure $+        if isAutoEmail+          then literal "[email]" <> literal address <> "[/email]"+          else literal ("[email=" <> address <> "]") <> linkText <> "[/email]"+    Nothing -> renderLinkDefault attr txt target++renderBlockQuoteDefault :: (PandocMonad m) => [Block] -> RR m (Doc Text)+renderBlockQuoteDefault blocks = do+  contents <- blockListToBBCode blocks+  pure $ vcat ["[quote]", contents, "[/quote]"]++renderBlockQuoteFluxBB :: (PandocMonad m) => [Block] -> RR m (Doc Text)+renderBlockQuoteFluxBB blocks = do+  contents <- blockListToBBCode blocks+  isInList <- asks inList+  if isInList+    then "" <$ report (BlockNotRendered $ BlockQuote blocks)+    else pure $ vcat ["[quote]", contents, "[/quote]"]++renderHorizontalRuleDefault :: (PandocMonad m) => RR m (Doc Text)+renderHorizontalRuleDefault = pure "* * *"++renderHorizontalRuleHR :: (PandocMonad m) => RR m (Doc Text)+renderHorizontalRuleHR = pure "[hr]"++renderLineBlockDefault :: (PandocMonad m) => [[Inline]] -> RR m (Doc Text)+renderLineBlockDefault inliness = vcat <$> mapM inlineListToBBCode inliness++renderParaDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderParaDefault inlines = inlineListToBBCode inlines++renderSuperscriptDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderSuperscriptDefault = inlineListToBBCode++renderSubscriptDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderSubscriptDefault = inlineListToBBCode++renderSmallCapsDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)+renderSmallCapsDefault = inlineListToBBCode++renderCiteDefault ::+  (PandocMonad m) => [Citation] -> [Inline] -> RR m (Doc Text)+renderCiteDefault _ = inlineListToBBCode++renderNoteDefault :: (PandocMonad m) => [Block] -> RR m (Doc Text)+renderNoteDefault blocks = do+  -- NOTE: no BBCode flavor has native syntax for footnotes.+  newN <- gets (succ . Seq.length)+  contents <- blockListToBBCode blocks+  let pointer = "(" <> tshow newN <> ")"+  let contents' = literal pointer <> space <> contents+  modify (|> contents')+  pure $ literal pointer++renderFigureDefault ::+  (PandocMonad m) => Attr -> Caption -> [Block] -> RR m (Doc Text)+renderFigureDefault _ (Caption _ caption) blocks = do+  caption' <- blockListToBBCode caption+  contents <- blockListToBBCode blocks+  pure $ contents $$ caption'++renderQuotedDefault ::+  (PandocMonad m) => QuoteType -> [Inline] -> RR m (Doc Text)+renderQuotedDefault typ inlines = do+  let quote = case typ of SingleQuote -> "'"; DoubleQuote -> "\""+  contents <- inlineListToBBCode inlines+  pure $ mconcat [quote, contents, quote]++renderMathDefault :: (PandocMonad m) => MathType -> Text -> RR m (Doc Text)+renderMathDefault typ math = case typ of+  InlineMath ->+    inlineToBBCode $+      Code ("", ["latex"], []) ("$" <> math <> "$")+  DisplayMath ->+    blockToBBCode $+      CodeBlock ("", ["latex"], []) ("$$" <> math <> "$$")++{- | Format documentation: <https://www.bbcode.org/reference.php>++There is no such thing as «Official» bbcode format, nonetheless this spec+implements what is described on bbcode.org, which is a reasonable base that can+be extended/contracted as needed.+-}+officialSpec :: FlavorSpec+officialSpec =+  FlavorSpec+    { renderOrderedList = renderOrderedListOfficial+    , renderBulletList = renderBulletListOfficial+    , renderDefinitionList = renderDefinitionListDefault+    , renderHeader = renderHeaderDefault+    , renderTable = renderTableDefault+    , renderLink = renderLinkEmailAware+    , renderCodeBlock = renderCodeBlockDefault+    , renderInlineCode = renderInlineCodeLiteral+    , renderStrikeout = renderStrikeoutDefault+    , renderBlockQuote = renderBlockQuoteDefault+    , renderHorizontalRule = renderHorizontalRuleDefault+    , renderLineBlock = renderLineBlockDefault+    , renderPara = renderParaDefault+    , renderSuperscript = renderSuperscriptDefault+    , renderSubscript = renderSubscriptDefault+    , renderSmallCaps = renderSmallCapsDefault+    , renderCite = renderCiteDefault+    , renderNote = renderNoteDefault+    , renderFigure = renderFigureDefault+    , renderMath = renderMathDefault+    , renderQuoted = renderQuotedDefault+    , renderImage = renderImageDefault+    , wrapSpanDiv = wrapSpanDivOfficial+    }++{- | Format documentation: <https://steamcommunity.com/comment/ForumTopic/formattinghelp>++Used at: <https://steamcommunity.com/discussions/forum>++Quirks:++- There seems to be no way to show external images on steam.+  https://steamcommunity.com/sharedfiles/filedetails/?id=2807121939 shows [img]+  and [previewimg] can (could?) be used to show images, although it is likely+  reserved for steam urls only.+-}+steamSpec :: FlavorSpec+steamSpec =+  officialSpec+    { renderOrderedList = renderOrderedListSteam+    , renderHeader = renderHeaderSteam+    , renderLink = renderLinkDefault+    , renderInlineCode = renderInlineCodeNoParse+    , renderStrikeout = renderStrikeoutSteam+    , renderImage = renderImageOmit+    , wrapSpanDiv = wrapSpanDivSteam+    , renderHorizontalRule = renderHorizontalRuleHR+    }++{- | Format documentation: <https://www.phpbb.com/community/help/bbcode>++Used at: <https://www.phpbb.com/community>++Quirks:++- PhpBB docs don't mention strikeout support, but their+  [support forum](https://www.phpbb.com/community) does support it.+- Same for named code blocks.+- @[email=example\@example.com]the email[/url]@ is a valid use of [email]+  tag on the phpBB community forum despite not being in the docs.+-}+phpbbSpec :: FlavorSpec+phpbbSpec =+  officialSpec+    { renderTable = renderTableOmit+    , renderImage = renderImagePhpBB+    , wrapSpanDiv = wrapSpanDivPhpBB+    }++{- | Format documentation: <https://web.archive.org/web/20210623155046/https://fluxbb.org/forums/help.php#bbcode>++Used at: https://bbs.archlinux.org+-}+fluxbbSpec :: FlavorSpec+fluxbbSpec =+  officialSpec+    { renderOrderedList = renderOrderedListFluxbb+    , renderCodeBlock = renderCodeBlockSimple+    , renderTable = renderTableOmit+    , renderBlockQuote = renderBlockQuoteFluxBB+    , renderImage = renderImageFluxBB+    , wrapSpanDiv = wrapSpanDivFluxBB+    }++{- | Format documentation: <https://hubzilla.org/help/member/bbcode>++Used at: <https://hub.netzgemeinde.eu> (see [other hubs](https://hubzilla.org/pubsites))++Quirks:++- If link target is not a URI, it simply points to https://$BASEURL/ when+  rendered by a hub.+-}+hubzillaSpec :: FlavorSpec+hubzillaSpec =+  officialSpec+    { renderOrderedList = renderOrderedListHubzilla+    , renderBulletList = renderBulletListHubzilla+    , renderDefinitionList = renderDefinitionListHubzilla+    , renderHeader = renderHeaderHubzilla+    , renderInlineCode = renderInlineCodeHubzilla+    , renderLink = renderLinkDefault+    , wrapSpanDiv = wrapSpanDivHubzilla+    , renderHorizontalRule = renderHorizontalRuleHR+    }++{- | Format documentation: <https://www.xenfocus.com/community/help/bb-codes/>++Used at: see <https://xenforo.com/>+-}+xenforoSpec :: FlavorSpec+xenforoSpec =+  officialSpec+    { wrapSpanDiv = wrapSpanDivXenforo+    , renderHeader = renderHeaderXenforo+    , renderInlineCode = renderInlineCodeXenforo+    , renderHorizontalRule = renderHorizontalRuleHR+    , renderOrderedList = renderOrderedListXenforo+    , renderImage = renderImageXenforo+    }
src/Text/Pandoc/Writers/HTML.hs view
@@ -317,7 +317,8 @@         MathJax url           | slideVariant /= RevealJsSlides ->           -- mathjax is handled via a special plugin in revealjs-            H.script ! A.src (toValue $ toURI html5 url)+            H.script ! A.defer mempty+                    ! A.src (toValue $ toURI html5 url)                     ! A.type_ "text/javascript"                     $ case slideVariant of                             SlideousSlides ->@@ -431,7 +432,11 @@                          defField "transitionSpeed" ("default" :: Doc Text) .                          defField "backgroundTransition" ("fade" :: Doc Text) .                          defField "viewDistance" ("3" :: Doc Text) .-                         defField "mobileViewDistance" ("2" :: Doc Text)+                         defField "mobileViewDistance" ("2" :: Doc Text) .+                         defField "scrollProgress" True .+                         defField "scrollActivationWidth" ("0" :: Doc Text) .+                         defField "scrollSnap" ("mandatory" :: Doc Text) .+                         defField "scrollLayout" ("full" :: Doc Text)                       else id) .                   defField "document-css" (isNothing mCss && slideVariant == NoSlides) .                   defField "quotes" (stQuotes st) .
src/Text/Pandoc/Writers/LaTeX.hs view
@@ -832,7 +832,7 @@                           5  -> "subparagraph"                           _  -> ""   inQuote <- gets stInQuote-  let prefix = if inQuote && level' >= 4+  let prefix = if inQuote                   then text "\\mbox{}%"                   -- needed for \paragraph, \subparagraph in quote environment                   -- see http://tex.stackexchange.com/questions/169830/@@ -1375,7 +1375,7 @@  isMathEnv :: Text -> Bool isMathEnv t =-  case T.stripPrefix "\\begin{" t of+  case T.stripPrefix "\\begin{" (T.dropWhile isSpaceChar t) of     Nothing -> False     Just t' -> T.takeWhile (/= '}') t' `elem`       [ "align", "align*"@@ -1386,12 +1386,17 @@       , "darray", "darray*"       , "gather", "gather*"       , "multline", "multline*"-      , "split"       , "subequations"       , "equation", "equation*"       , "eqnarray"       , "displaymath"       ]+ where+   isSpaceChar '\n' = True+   isSpaceChar '\r' = True+   isSpaceChar '\t' = True+   isSpaceChar ' ' = True+   isSpaceChar _ = False  -- True if the math needs the cancel package needsCancel :: Text -> Bool
src/Text/Pandoc/Writers/Powerpoint/Output.hs view
@@ -1417,7 +1417,7 @@ graphicToElement :: PandocMonad m => Integer -> Graphic -> P m Element graphicToElement tableWidth (Tbl widths tblPr hdrCells rows) = do   let totalWidth = sum widths-  let colWidths = if any (== 0.0) widths+  let colWidths = if 0.0 `elem` widths                   then if null hdrCells                       then case rows of                          r@(_:_) : _ -> replicate (length r) $@@ -2444,8 +2444,11 @@   P m Element presentationToSldIdLst minimumSlideRId (Presentation _ slides) = do   ids <- mapM (slideToSldIdElement minimumSlideRId) slides-  return $ mknode "p:sldIdLst" [] ids+  return $ mkNodeSldIdLst ids +mkNodeSldIdLst :: [Element] -> Element+mkNodeSldIdLst = mknode "p:sldIdLst" []+ presentationToPresentationElement ::   PandocMonad m =>   PresentationRIdUpdateData ->@@ -2459,10 +2462,9 @@   sldIdLst <- presentationToSldIdLst minSlideRId pres    let modifySldIdLst :: Content -> Content-      modifySldIdLst (Elem e) = case elName e of-        (QName "sldIdLst" _ _) -> Elem sldIdLst-        _                      -> Elem e-      modifySldIdLst ct = ct+      modifySldIdLst ct = if isSldIdLst ct+                          then Elem sldIdLst+                          else ct        notesMasterRId = maxSlideRId @@ -2488,15 +2490,9 @@       removeUnwantedMaster :: [Content] -> [Content]       removeUnwantedMaster = concatMap removeUnwantedMaster' -      insertNotesMaster' :: Content -> [Content]-      insertNotesMaster' (Elem e) = case elName e of-        (QName "sldMasterIdLst" _ _) -> [Elem e, Elem notesMasterElem]-        _                            -> [Elem e]-      insertNotesMaster' ct = [ct]-       insertNotesMaster :: [Content] -> [Content]       insertNotesMaster = if presHasSpeakerNotes pres-                          then concatMap insertNotesMaster'+                          then insertAfterSldMasterIdLst notesMasterElem                           else id        updateRIds :: Content -> Content@@ -2516,10 +2512,33 @@         let newValue = updatePresentationRId presentationUpdateRIdData oldValue         pure attr {attrVal = "rId" <> T.pack (show newValue)} +      -- if there is no sldIdLst in the presentation.xml file, add an empty one+      -- after the sldMasterIdLst so modifySldIdLst can replace it.++      insertSldIdListIfMissing :: [Content] -> [Content]+      insertSldIdListIfMissing contentList = if any isSldIdLst contentList+                                             then contentList+                                             else insertAfterSldMasterIdLst (mkNodeSldIdLst []) contentList++      insertAfterSldMasterIdLst' :: Content -> Content -> [Content]+      insertAfterSldMasterIdLst' newElement ct = if isElemName "sldMasterIdLst" ct+                                                 then [ct, newElement]+                                                 else [ct]++      insertAfterSldMasterIdLst :: Element -> [Content] -> [Content]+      insertAfterSldMasterIdLst newElement = concatMap $ insertAfterSldMasterIdLst' $ Elem newElement++      isElemName :: T.Text -> Content -> Bool+      isElemName name (Elem e) = qName (elName e) == name+      isElemName _ _ = False++      isSldIdLst :: Content -> Bool+      isSldIdLst = isElemName "sldIdLst"+       newContent = insertNotesMaster $                    removeUnwantedMaster $                    (modifySldIdLst . updateRIds) <$>-                   elContent element+                   insertSldIdListIfMissing (elContent element)    return $ element{elContent = newContent} 
src/Text/Pandoc/Writers/RST.hs view
@@ -925,23 +925,19 @@             -> TableFoot             -> m (Doc Text) simpleTable opts blocksToDoc (TableHead _ headers) tbody (TableFoot _ footers) = do-  headerDocs <- if all isEmptyRow headers+  headerDocs <- if allRowsEmpty headers                    then return []                    else fixEmpties <$> mapM rowToDoc headers   rowDocs <- fixEmpties <$> mapM rowToDoc ((tableBodiesToRows tbody) ++ footers)   let numChars = maybe 0 maximum . NE.nonEmpty . map (offset . fst)   let colWidths = map numChars $ transpose (headerDocs ++ rowDocs)   let hline = nowrap $ hsep (map (\n -> literal (T.replicate n "=")) colWidths)-  let hdr = if all isEmptyRow headers+  let hdr = if allRowsEmpty headers                then mempty                else hline $$ mapToRow colWidths headerDocs   let bdy = mapToRow colWidths rowDocs   return $ hdr $$ hline $$ bdy $$ hline   where-    isEmptyRow (Row _ cells) = all isEmptyCell cells--    isEmptyCell (Cell _ _ _ _ blocks) = null blocks-     -- can't have empty cells in first column:     fixEmpties (d:ds) = fixEmpties' d : ds     fixEmpties [] = []@@ -991,10 +987,3 @@             then colWidthsSum + colWidthsLength - 1             else colWidthsSum       in  literal $ T.replicate dashLength "-"---- | Concatenates the header and body Rows of a List of TableBody into a flat--- List of Rows.-tableBodiesToRows :: [TableBody] -> [Row]-tableBodiesToRows = concatMap tableBodyToRows-  where-    tableBodyToRows (TableBody _ _ headerRows bodyRows) = headerRows ++ bodyRows
src/Text/Pandoc/Writers/Shared.hs view
@@ -50,6 +50,11 @@                      , isOrderedListMarker                      , toTaskListItem                      , delimited+                     , allRowsEmpty+                     , tableBodiesToRows+                     , insertCurrentSpansAtColumn+                     , takePreviousSpansAtColumn+                     , decrementTrailingRowSpans                      ) where import Safe (lastMay, maximumMay)@@ -59,7 +64,7 @@ import Data.Aeson (ToJSON (..), encode) import Data.Char (chr, ord, isSpace, isLetter, isUpper) import Data.List (groupBy, intersperse, foldl', transpose)-import Data.List.NonEmpty (NonEmpty(..))+import Data.List.NonEmpty (NonEmpty((:|))) import Data.Text.Conversions (FromText(..)) import qualified Data.Map as M import qualified Data.Text as T@@ -857,3 +862,66 @@   toList (Concat (Concat a b) c) = toList (Concat a (Concat b c))   toList (Concat a b) = a : toList b   toList x = [x]++-- | Determine whether all rows and their cells are empty.+allRowsEmpty :: [Row] -> Bool+allRowsEmpty = all isEmptyRow+ where+  isEmptyRow (Row _ cells) = all isEmptyCell cells+  isEmptyCell (Cell _ _ _ _ blocks) = null blocks++-- | Concatenates the header and body Rows of a List of TableBody into a flat+-- List of Rows.+tableBodiesToRows :: [TableBody] -> [Row]+tableBodiesToRows = concatMap tableBodyToRows+  where+    tableBodyToRows (TableBody _ _ headerRows bodyRows) = headerRows ++ bodyRows++-- | Insert the current span information of a table cell to keep track of it in+-- subsequent rows.+--+-- If 'RowSpan' @> 1@, the current span information will be inserted. Otherwise+-- the previous span information will be left unchanged.+--+-- Use 'takePreviousSpansAtColumn' to take previous span information at+-- subsequent rows. Use 'decrementTrailingRowSpans' to handle previous trailing+-- spans at the end of a row.+--+-- For writers that need to manually apply the 'RowSpan' of cells over multiple+-- rows or otherwise have to keep track of it.+insertCurrentSpansAtColumn :: Int -> M.Map Int (RowSpan, ColSpan) -> RowSpan -> ColSpan -> M.Map Int (RowSpan, ColSpan)+insertCurrentSpansAtColumn columnPosition previousSpans (RowSpan rowSpan) colSpan =+  if (rowSpan > 1)+    then M.insert columnPosition (RowSpan rowSpan - 1, colSpan) previousSpans -- Minus its own row.+    else previousSpans++-- | Take previous span information at a column position that was added with+-- 'insertCurrentSpansAtColumn' if available.+--+-- If the previous 'RowSpan' @>= 1@, this will return 'Just' the previous+-- 'ColSpan' and an adjusted span information where that 'RowSpan' is either+-- decremented or deleted if it would fall to 0. Otherwise this will return+-- 'Nothing'.+takePreviousSpansAtColumn :: Int -> M.Map Int (RowSpan, ColSpan) -> Maybe (ColSpan, M.Map Int (RowSpan, ColSpan))+takePreviousSpansAtColumn columnPosition previousSpans+  | Just previous@(RowSpan previousRowSpan, previousColSpan) <- M.lookup columnPosition previousSpans+  , previousRowSpan >= 1 = Just (previousColSpan, decrementPreviousRowSpans previous)+  | otherwise = Nothing+ where+  decrementPreviousRowSpans (RowSpan previousRowSpan, previousColSpan) =+    if previousRowSpan > 1+      then M.insert columnPosition (RowSpan previousRowSpan - 1, previousColSpan) previousSpans+      else M.delete columnPosition previousSpans++-- | Decrement all previously tracked trailing 'RowSpan' elements at or after a+-- column position.+--+-- For handling previous row spans that are next to the end of a row's cells+-- that were previously added with 'insertCurrentSpansAtColumn'.+decrementTrailingRowSpans :: Int -> M.Map Int (RowSpan, ColSpan) -> M.Map Int (RowSpan, ColSpan)+decrementTrailingRowSpans columnPosition = M.mapWithKey decrementTrailing+  where+    decrementTrailing previousColumnPosition previousSpan@(RowSpan rowSpan, colSpan) =+      if previousColumnPosition >= columnPosition && rowSpan >= 1+        then (RowSpan rowSpan - 1, colSpan)+        else previousSpan
test/Tests/Helpers.hs view
@@ -16,6 +16,7 @@                      , TestResult(..)                      , setupEnvironment                      , showDiff+                     , nativeDiff                      , testGolden                      , (=?>)                      , purely@@ -131,6 +132,19 @@ vividize (Both s _) = "  " ++ s vividize (First s)  = "- " ++ s vividize (Second s) = "+ " ++ s++nativeDiff :: FilePath -> Pandoc -> Pandoc -> IO (Maybe String)+nativeDiff normPath expectedNative actualNative+  | expectedNative == actualNative = return Nothing+  | otherwise = Just <$> do+      expected <- T.unpack <$> runIOorExplode (writeNative def expectedNative)+      actual <- T.unpack <$> runIOorExplode (writeNative def actualNative)+      let dash = replicate 72 '-'+      let diff = getDiff (lines actual) (lines expected)+      return $ '\n' : dash +++               "\n--- " ++ normPath +++               "\n+++ " ++ "test" ++ "\n" +++               showDiff (1,1) diff ++ dash  purely :: (b -> PandocPure a) -> b -> a purely f = either (error . show) id . runPure . f
test/Tests/Old.hs view
@@ -78,6 +78,14 @@     , s5WriterTest' "inserts"  ["-s", "-H", "insert",       "-B", "insert", "-A", "insert", "-c", "main.css"] "html4"     ]+  , testGroup "asciidoc"+    [ testGroup "writer" (writerTests' "asciidoc" +++                          writerTests' "asciidoc_legacy")+    , testGroup "reader"+      [ test' "basic" ["-f", "asciidoc", "-t", "native", "-s"]+          "asciidoc-reader.adoc" "asciidoc-reader.native"+      ]+    ]   , testGroup "textile"     [ testGroup "writer" $ writerTests' "textile"     , test' "reader" ["-r", "textile", "-w", "native", "-s"]@@ -183,9 +191,7 @@         "tikiwiki-reader.tikiwiki" "tikiwiki-reader.native" ]   , testGroup "other writers" $ map (\f -> testGroup f $ writerTests' f)     [ "opendocument" , "context" , "texinfo", "icml", "tei"-    , "man" , "plain" , "asciidoc", "asciidoc_legacy"-    , "xwiki", "zimwiki"-    ]+    , "man" , "plain" , "xwiki", "zimwiki" ]   , testGroup "writers-lang-and-dir"     [ test' "latex" ["-f", "native", "-t", "latex", "-s"]       "writers-lang-and-dir.native" "writers-lang-and-dir.latex"@@ -275,6 +281,7 @@             "vimdoc/headers.markdown" "vimdoc/headers-numbered.vimdoc"         ]     ]+  , testGroup "bbcode" [testGroup "writer" $ writerTests' "bbcode"]   ]  where     test'           = test pandocPath
test/Tests/Readers/Docx.hs view
@@ -12,7 +12,6 @@ -} module Tests.Readers.Docx (tests) where -import Data.Algorithm.Diff (getDiff) import Codec.Archive.Zip import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as B@@ -33,20 +32,6 @@  testCompare :: String -> FilePath -> FilePath -> TestTree testCompare = testCompareWithOpts defopts---nativeDiff :: FilePath -> Pandoc -> Pandoc -> IO (Maybe String)-nativeDiff normPath expectedNative actualNative-  | expectedNative == actualNative = return Nothing-  | otherwise = Just <$> do-      expected <- T.unpack <$> runIOorExplode (writeNative def expectedNative)-      actual <- T.unpack <$> runIOorExplode (writeNative def actualNative)-      let dash = replicate 72 '-'-      let diff = getDiff (lines actual) (lines expected)-      return $ '\n' : dash ++-               "\n--- " ++ normPath ++-               "\n+++ " ++ "test" ++ "\n" ++-               showDiff (1,1) diff ++ dash  testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree testCompareWithOpts opts testName docxFP nativeFP =
+ test/Tests/Readers/Pptx.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Tests.Readers.Pptx+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Tests for the PPTX reader.+-}+module Tests.Readers.Pptx (tests) where++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as B+import Test.Tasty+import Test.Tasty.Golden.Advanced+import Tests.Helpers+import Text.Pandoc+import Text.Pandoc.UTF8 as UTF8++defopts :: ReaderOptions+defopts = def{ readerExtensions = getDefaultExtensions "pptx" }++testCompare :: String -> FilePath -> FilePath -> TestTree+testCompare = testCompareWithOpts defopts++testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree+testCompareWithOpts opts testName pptxFP nativeFP =+  goldenTest+  testName+  (do nf <- UTF8.toText <$> BS.readFile nativeFP+      runIOorExplode (readNative def nf))+  (do df <- B.readFile pptxFP+      runIOorExplode (readPptx opts df))+  (nativeDiff nativeFP)+  (\a -> runIOorExplode (writeNative def{ writerTemplate = Just mempty} a)+            >>= BS.writeFile nativeFP . UTF8.fromText)++tests :: [TestTree]+tests = [ testGroup "basic"+          [ testCompare+            "text extraction"+            "pptx-reader/basic.pptx"+            "pptx-reader/basic.native"+          ]+        ]
+ test/Tests/Readers/Xlsx.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}+{- |+   Module      : Tests.Readers.Xlsx+   Copyright   : © 2025 Anton Antic+   License     : GNU GPL, version 2 or above++   Maintainer  : Anton Antic <anton@everworker.ai>+   Stability   : alpha+   Portability : portable++Tests for the XLSX reader.+-}+module Tests.Readers.Xlsx (tests) where++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as B+import Test.Tasty+import Test.Tasty.Golden.Advanced+import Tests.Helpers+import Text.Pandoc+import Text.Pandoc.UTF8 as UTF8++defopts :: ReaderOptions+defopts = def{ readerExtensions = getDefaultExtensions "xlsx" }++testCompare :: String -> FilePath -> FilePath -> TestTree+testCompare = testCompareWithOpts defopts++testCompareWithOpts :: ReaderOptions -> String -> FilePath -> FilePath -> TestTree+testCompareWithOpts opts testName xlsxFP nativeFP =+  goldenTest+  testName+  (do nf <- UTF8.toText <$> BS.readFile nativeFP+      runIOorExplode (readNative def nf))+  (do df <- B.readFile xlsxFP+      runIOorExplode (readXlsx opts df))+  (nativeDiff nativeFP)+  (\a -> runIOorExplode (writeNative def{ writerTemplate = Just mempty} a)+            >>= BS.writeFile nativeFP . UTF8.fromText)++tests :: [TestTree]+tests = [ testGroup "basic"+          [ testCompare+            "sheet extraction"+            "xlsx-reader/basic.xlsx"+            "xlsx-reader/basic.native"+          ]+        ]
+ test/Tests/Writers/BBCode.hs view
@@ -0,0 +1,355 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-}++module Tests.Writers.BBCode (tests) where++import Data.Maybe (isNothing)+import Data.Text as T+import Test.Tasty+import Test.Tasty.HUnit (HasCallStack)+import Test.Tasty.QuickCheck+import Tests.Helpers+import Text.Pandoc+import Text.Pandoc.Arbitrary ()+import Text.Pandoc.Builder+import Text.Pandoc.Shared (tshow)+import Text.Read (readMaybe)++bbcodeDefault+  , bbcodeSteam+  , bbcodePhpBB+  , bbcodeFluxBB+  , bbcodeHubzilla+  , bbcodeXenforo ::+    (ToPandoc a) => a -> Text+bbcodeDefault = purely (writeBBCode def) . toPandoc+bbcodeSteam = purely (writeBBCodeSteam def) . toPandoc+bbcodePhpBB = purely (writeBBCodePhpBB def) . toPandoc+bbcodeFluxBB = purely (writeBBCodeFluxBB def) . toPandoc+bbcodeHubzilla = purely (writeBBCodeHubzilla def) . toPandoc+bbcodeXenforo = purely (writeBBCodeXenforo def) . toPandoc++infix 4 =:, `steam`, `phpbb`, `fluxbb`, `hubzilla`, `xenforo`+(=:)+  , steam+  , phpbb+  , fluxbb+  , hubzilla+  , xenforo ::+    (ToString a, ToPandoc a, HasCallStack) =>+    String ->+    (a, Text) ->+    TestTree+(=:) = test bbcodeDefault+steam = test bbcodeSteam+phpbb = test bbcodePhpBB+fluxbb = test bbcodeFluxBB+hubzilla = test bbcodeHubzilla+xenforo = test bbcodeXenforo++spanClasses :: [Text] -> Inlines -> Inlines+spanClasses cls = spanWith ("", cls, [])++spanAttrs :: [(Text, Text)] -> Inlines -> Inlines+spanAttrs kvList = spanWith ("", [], kvList)++divClasses :: [Text] -> Blocks -> Blocks+divClasses cls = divWith ("", cls, [])++divAttrs :: [(Text, Text)] -> Blocks -> Blocks+divAttrs kvList = divWith ("", [], kvList)++tests :: [TestTree]+tests =+  [ testGroup+      "spans classes"+      [ "left" =: spanClasses ["left"] "foo" =?> "foo"+      , "center" =: spanClasses ["center"] "foo" =?> "foo"+      , "right" =: spanClasses ["right"] "foo" =?> "foo"+      , "spoiler" =: spanClasses ["spoiler"] "foo" =?> "foo"+      ]+  , testGroup+      "spans attributes"+      [ testProperty "incorrect size ignored" . property $ do+          n <- arbitrary @String+          let nInt = readMaybe @Int n+          let actual = bbcodeDefault (spanAttrs [("size", T.pack n)] "foo")+          pure $ isNothing nInt ==> actual === "foo"+      , testProperty "size<=0 ignored" . property $ do+          NonPositive n <- arbitrary @(NonPositive Int)+          let actual = bbcodeDefault (spanAttrs [("size", tshow n)] "foo")+          pure $ actual === "foo"+      , testProperty "size>0" . property $ do+          Positive n <- arbitrary @(Positive Int)+          let actual = bbcodeDefault (spanAttrs [("size", tshow n)] "foo")+          let expected = "[size=" <> tshow n <> "]" <> "foo[/size]"+          pure $ actual === expected+      , "size=20" =: spanAttrs [("size", "20")] "foo" =?> "[size=20]foo[/size]"+      , "color=#AAAAAA"+          =: spanAttrs [("color", "#AAAAAA")] "foo"+          =?> "[color=#AAAAAA]foo[/color]"+      , "spoiler ignored"+          =: spanAttrs [("spoiler", "name with spaces and ]brackets[]")] "foo"+          =?> "foo"+      ]+  , testGroup+      "divs classes"+      [ "left"+          =: divClasses ["left"] (para "foo")+          =?> "[left]foo[/left]"+      , "center"+          =: divClasses ["center"] (para "foo")+          =?> "[center]foo[/center]"+      , "right"+          =: divClasses ["right"] (para "foo")+          =?> "[right]foo[/right]"+      , "spoiler"+          =: divClasses ["spoiler"] (para "foo")+          =?> "[spoiler]foo[/spoiler]"+      ]+  , testGroup+      "divs attributes"+      [ testProperty "incorrect size ignored" . property $ do+          n <- arbitrary @String+          let nInt = readMaybe @Int n+          let actual = bbcodeDefault (divAttrs [("size", T.pack n)] $ para "foo")+          pure $ isNothing nInt ==> actual === "foo"+      , testProperty "size<=0 ignored" . property $ do+          NonPositive n <- arbitrary @(NonPositive Int)+          let actual = bbcodeDefault (divAttrs [("size", tshow n)] $ para "foo")+          pure $ actual === "foo"+      , testProperty "size>0" . property $ do+          Positive n <- arbitrary @(Positive Int)+          let actual = bbcodeDefault (divAttrs [("size", tshow n)] $ para "foo")+          let expected = "[size=" <> tshow n <> "]" <> "foo[/size]"+          pure $ actual === expected+      , "size=20"+          =: divAttrs [("size", "20")] (para "foo")+          =?> "[size=20]foo[/size]"+      , "color=#AAAAAA"+          =: divAttrs [("color", "#AAAAAA")] (para "foo")+          =?> "[color=#AAAAAA]foo[/color]"+      , "spoiler"+          =: divAttrs+            [("spoiler", "name with spaces and ]brackets[]")]+            (para "foo")+          =?> "[spoiler=name with spaces and brackets]foo[/spoiler]"+      ]+  , testGroup+      "default flavor"+      [ "link"+          =: link "https://example.com" "title" "label"+          =?> "[url=https://example.com]label[/url]"+      , "autolink"+          =: link "https://example.com" "title" "https://example.com"+          =?> "[url]https://example.com[/url]"+      , "email autolink"+          =: link+            "mailto:example@example.com"+            "title"+            "example@example.com"+          =?> "[email]example@example.com[/email]"+      , "named email"+          =: link "mailto:example@example.com" "title" "example email"+          =?> "[email=example@example.com]example email[/email]"+      , "h0" =: header 0 "heading 0" =?> "[u][b]heading 0[/b][/u]"+      , "h1" =: header 1 "heading 1" =?> "[u][b]heading 1[/b][/u]"+      , "h2" =: header 2 "heading 2" =?> "[b]heading 2[/b]"+      , "h3" =: header 3 "heading 3" =?> "[u]heading 3[/u]"+      , "h4" =: header 4 "heading 4" =?> "heading 4"+      , "h5" =: header 5 "heading 5" =?> "heading 5"+      ]+  , testGroup+      "steam"+      [ test bbcodeSteam "dename spoiler" $+          divAttrs [("spoiler", "bar")] (para "foo")+            =?> ("[spoiler]foo[/spoiler]" :: Text)+      , testProperty "ordered list styleless" . property $ do+          let listItems = [para "foo", para "bar", para "baz"]+          attrsRand <- (,,) <$> arbitrary <*> arbitrary <*> arbitrary+          let actual = bbcodeSteam $ orderedListWith attrsRand listItems+          let expected = "[olist]\n[*]foo\n[*]bar\n[*]baz\n[/olist]"+          pure $ actual === expected+      , "h0" `steam` header 0 "heading 0" =?> "[h1]heading 0[/h1]"+      , "h1" `steam` header 1 "heading 1" =?> "[h1]heading 1[/h1]"+      , "h2" `steam` header 2 "heading 2" =?> "[h2]heading 2[/h2]"+      , "h3" `steam` header 3 "heading 3" =?> "[h3]heading 3[/h3]"+      , "h4" `steam` header 4 "heading 4" =?> "[h3]heading 4[/h3]"+      , "code"+          `steam` codeWith ("id", ["haskell"], []) "map (2^) [1..5]"+          =?> "[noparse]map (2^) [1..5][/noparse]"+      ]+  , testGroup+      "phpBB"+      [ "image"+          `phpbb` imageWith+            ("id", [], [("width", "100")])+            "https://example.com"+            "title"+            "alt text"+          =?> "[img]https://example.com[/img]"+      ]+  , testGroup+      "FluxBB"+      [ "image"+          `fluxbb` imageWith+            ("id", [], [("width", "100")])+            "https://example.com"+            "title"+            "alt text"+          =?> "[img=alt text]https://example.com[/img]"+      , testProperty "ordered list" . property $ do+          let listItems = [para "foo", para "bar", para "baz"]+          attrsRand <- (,,) <$> arbitrary <*> arbitrary <*> arbitrary+          let actual = bbcodeFluxBB $ orderedListWith attrsRand listItems+          let opening = case attrsRand of+                (_, LowerAlpha, _) -> "[list=a]"+                (_, UpperAlpha, _) -> "[list=a]"+                _ -> "[list=1]"+          let expected = opening <> "\n[*]foo\n[*]bar\n[*]baz\n[/list]"+          pure $ actual === expected+      , "ulist > BlockQuote not rendered"+          `fluxbb` bulletList [blockQuote (para "foo") <> para "bar"]+          =?> "[list]\n[*]bar\n[/list]"+      , "code block"+          `fluxbb` codeBlockWith+            ("id", ["haskell"], [])+            ( T.intercalate "\n" $+                [ "vals ="+                , "  take 10"+                , "    . filter (\\x -> (x - 5) `mod` 3 == 0)"+                , "    $ map (2 ^) [1 ..]"+                ]+            )+          =?> T.intercalate+            "\n"+            [ "[code]vals ="+            , "  take 10"+            , "    . filter (\\x -> (x - 5) `mod` 3 == 0)"+            , "    $ map (2 ^) [1 ..]"+            , "[/code]"+            ]+      ]+  , testGroup+      "Hubzilla"+      [ "unordered list"+          `hubzilla` bulletList [para "foo", para "bar", para "baz"]+          =?> "[ul]\n[*]foo\n[*]bar\n[*]baz\n[/ul]"+      , testProperty "ordered list" . property $ do+          let listItems = [para "foo", para "bar", para "baz"]+          attrsRand <- (,,) <$> arbitrary <*> arbitrary <*> arbitrary+          let actual = bbcodeHubzilla $ orderedListWith attrsRand listItems+          let (opening, closing) = case attrsRand of+                (_, Decimal, _) -> ("[list=1]", "[/list]")+                (_, DefaultStyle, _) -> ("[ol]", "[/ol]")+                (_, Example, _) -> ("[ol]", "[/ol]")+                (_, LowerAlpha, _) -> ("[list=a]", "[/list]")+                (_, UpperAlpha, _) -> ("[list=A]", "[/list]")+                (_, LowerRoman, _) -> ("[list=i]", "[/list]")+                (_, UpperRoman, _) -> ("[list=I]", "[/list]")+          let expected =+                opening <> "\n[*]foo\n[*]bar\n[*]baz\n" <> closing+          pure $ actual === expected+      , "definition list"+          `hubzilla` definitionList+            [ ("term_foo", [para "def_foo1", para "def_foo2"])+            , ("term_bar", [para "def_bar1", para "def_bar2"])+            , ("term_baz", [para "def_baz1", para "def_baz2"])+            ]+          =?> mconcat+            [ "[dl terms=\"b\"]\n"+            , "[*= term_foo]\ndef_foo1\ndef_foo2\n"+            , "[*= term_bar]\ndef_bar1\ndef_bar2\n"+            , "[*= term_baz]\ndef_baz1\ndef_baz2\n"+            , "[/dl]"+            ]+      , "h0" `hubzilla` header 0 "heading 0" =?> "[h1]heading 0[/h1]"+      , "h1" `hubzilla` header 1 "heading 1" =?> "[h1]heading 1[/h1]"+      , "h2" `hubzilla` header 2 "heading 2" =?> "[h2]heading 2[/h2]"+      , "h3" `hubzilla` header 3 "heading 3" =?> "[h3]heading 3[/h3]"+      , "h4" `hubzilla` header 4 "heading 4" =?> "[h4]heading 4[/h4]"+      , "h5" `hubzilla` header 5 "heading 5" =?> "[h5]heading 5[/h5]"+      , "h6" `hubzilla` header 6 "heading 6" =?> "[h6]heading 6[/h6]"+      , "h7" `hubzilla` header 7 "heading 7" =?> "[h6]heading 7[/h6]"+      , "link"+          `hubzilla` link "https://example.com" "title" "label"+          =?> "[url=https://example.com]label[/url]"+      , "autolink"+          `hubzilla` link "https://example.com" "title" "https://example.com"+          =?> "[url]https://example.com[/url]"+      , "email autolink"+          `hubzilla` link+            "mailto:example@example.com"+            "title"+            "example@example.com"+          =?> "[url=mailto:example@example.com]example@example.com[/url]"+      , "named email"+          `hubzilla` link "mailto:example@example.com" "title" "example email"+          =?> "[url=mailto:example@example.com]example email[/url]"+      , "inline code"+          `hubzilla` ( "inline code: "+                        <> codeWith ("id", ["haskell"], []) "map (2^) [1..5]"+                     )+          =?> "inline code: [code]map (2^) [1..5][/code]"+      , "font"+          `hubzilla` divAttrs [("font", "serif")] (para "foo")+          =?> "[font=serif]foo[/font]"+      ]+  , testGroup+      "xenForo"+      [ "unordered list"+          `xenforo` bulletList [para "foo", para "bar", para "baz"]+          =?> "[list]\n[*]foo\n[*]bar\n[*]baz\n[/list]"+      , testProperty "ordered list styleless" . property $ do+          let listItems = [para "foo", para "bar", para "baz"]+          attrsRand <- (,,) <$> arbitrary <*> arbitrary <*> arbitrary+          let actual = bbcodeXenforo $ orderedListWith attrsRand listItems+          let expected = "[list=1]\n[*]foo\n[*]bar\n[*]baz\n[/list]"+          pure $ actual === expected+      , "h0" `xenforo` header 0 "heading 0" =?> "[heading=1]heading 0[/heading]"+      , "h1" `xenforo` header 1 "heading 1" =?> "[heading=1]heading 1[/heading]"+      , "h2" `xenforo` header 2 "heading 2" =?> "[heading=2]heading 2[/heading]"+      , "h3" `xenforo` header 3 "heading 3" =?> "[heading=3]heading 3[/heading]"+      , "h4" `xenforo` header 4 "heading 4" =?> "[heading=4]heading 4[/heading]"+      , "link"+          `xenforo` link "https://example.com" "title" "label"+          =?> "[url=https://example.com]label[/url]"+      , "autolink"+          `xenforo` link "https://example.com" "title" "https://example.com"+          =?> "[url]https://example.com[/url]"+      , "email autolink"+          `xenforo` link+            "mailto:example@example.com"+            "title"+            "example@example.com"+          =?> "[email]example@example.com[/email]"+      , "named email"+          `xenforo` link "mailto:example@example.com" "title" "example email"+          =?> "[email=example@example.com]example email[/email]"+      , "inline code"+          `xenforo` ( "inline code: "+                        <> codeWith ("id", ["haskell"], []) "map (2^) [1..5]"+                    )+          =?> "inline code: [icode]map (2^) [1..5][/icode]"+      , "font"+          `xenforo` divAttrs [("font", "serif")] (para "foo")+          =?> "[font=serif]foo[/font]"+      , "inline spoiler"+          `xenforo` ("It was " <> spanClasses ["spoiler"] ("DNS") <> "!")+          =?> "It was [ispoiler]DNS[/ispoiler]!"+      , "image w=50% h=50%"+          `xenforo` imageWith+            ("", [], [("width", "50%"), ("height", "50%")])+            "https://example.com"+            "title text"+            "alt text"+          =?> "[img alt=\"alt text\" title=\"title text\" width=50%]https://example.com[/img]"+      , "image w=50 h=50"+          `xenforo` imageWith+            ("", [], [("width", "50"), ("height", "50")])+            "https://example.com"+            ""+            ""+          =?> "[img]https://example.com[/img]"+      ]+  ]
test/Tests/Writers/Powerpoint.hs view
@@ -276,5 +276,17 @@       def {writerReferenceDoc = Just "pptx/reference-deleted-layouts.pptx"}       "pptx/layouts/input.native"       "pptx/layouts/deleted.pptx"+    , ooxmlTest+      writePowerpoint+      "Slides can be missing from the reference doc"+      def {writerReferenceDoc = Just "pptx/reference-no-slides.pptx"}+      "pptx/reference-no-slides/add-slides/input.native"+      "pptx/reference-no-slides/add-slides/output.pptx"+    , ooxmlTest+      writePowerpoint+      "Notes are placed at the right position with a reference doc without slides"+      def {writerReferenceDoc = Just "pptx/reference-no-slides.pptx"}+      "pptx/reference-no-slides/with-notes/input.native"+      "pptx/reference-no-slides/with-notes/output.pptx"     ]   in regularTests <> referenceSpecificTests
+ test/asciidoc-reader-include.adoc view
@@ -0,0 +1,4 @@+This is a test!++. one+.. two
+ test/asciidoc-reader-include.rb view
@@ -0,0 +1,4 @@+# A function+def foo+  return 42+end
+ test/asciidoc-reader.adoc view
@@ -0,0 +1,908 @@+// Some comment here.+= AsciiDoc reader test+John MacFarlane <jgm@berkeley.edu>; John Doe <doe@example.com>+v1.0, 2025-11-24+:custom: Foo bar \+baz+:flag:+:stem: latexmath++[#firsty]+== Inline markup++=== Characters and escapes++Dog's has a curved apostrophe, but dog\'s does not.++An escaped symbol: \*star\*.++Character references: &auml;&#160;&#x22E0; ++=== Line breaks++This is a hard ++break.++Or set it for a whole paragraph++[%hardbreaks]+These are+all+hard+breaks.++=== Autolinks++http://example.com/foobar?a=333&b=no%20body, me@example.com++<http://example.com/foobar?a=333&b=no%20body>, <me@example.com>++=== Cross-reference++See <<firsty>>++See <<firsty,My great section on Inline markup>>++Go to <<anch,an inline anchor>>++=== Anchors++An [[anch]]inline anchor.++[[[bibanchor]]Doe, John. A Book.++=== Inline macros++kbd:[F11]++kbd:[Ctrl+Shift+F]++menu:File[Save]++menu:Reader[Markdown > Pandoc]++btn:[Cancel]++icon:heart[2x,role=red]++anchor:tiger++pass:[<b>*bold*</b>]++link:downloads/report.pdf[Get Report]++link:tools.html#editors[]++link:file:///home/username[Your files]++Tricky cases:++link:pass:[My Documents/report.pdf][Get Report]++link:My&#32;Documents/report.pdf[Get Report]++link:My%20Documents/report.pdf[Get Report]++link:++https://example.org/now_this__link_works.html++[]++mailto:join@discuss.example.org[Subscribe]++mailto:join@discuss.example.org["Click, subscribe, and participate!",role=mail]++xref:link-macro-attributes[use attributes within the link macro]++image::sunset.jpg[Sunset]++image::name.png[]++image::sunset.jpg[Sunset,300,400]++image::sunset.jpg[alt=Sunset,width=300,height=400]++[latexmath]++++++e=mc^2+++++++[asciimath]++++++sin n / 3+++++++[stem]++++++e^i+++++++=== Attribute substitutions++{custom}++{nonexistent}++Built in: x{blank}y{empty}z{sp}a{nbsp}b{zwsp}c{apos}d{lsquo}++=== Bold and italic++Constrained: *this is bold _and italic_*.++Unconstrained: wild**content__with italic__stuff**.++=== Monospace++`simple`++`complex *with bold* text and a link:foo.html[]`++unconstrained``wwow``okay++=== Span and inline attributes++[.red]#Bonjour *monsieur*#++Un[.red]##constrained##content++With #no attribute# it's highlighted.++=== Sub and superscript++H~2~O++H~a{sp}b~O++Not subscript: H~a b~O.++H^2&O++H^a{sp}b^O++Not subscript: H^a b^O.++=== Passthrough++Here the special characters just come through as literal:+++<b>*test*</b>+++xx++<b>*test*</b>++xx++But here they are passed through:++xx+++<b>*test*</b>+++xx++=== Quoted++"`double quoted`"++'`single quoted`'++=== Footnotes++Doublefootnote:[The double hail-and-rainbow level makes my toes tingle.]++A bold statement!footnote:disclaimer[Opinions are my own.]+Another outrageous statement.footnote:disclaimer[]++== Block markup++=== Sections++==== Another level++===== Level 5++#### Markdown style++##### Level 5++=== Discrete heading++[discrete]+==== A discrete heading, not a section++=== Paragraph++This is a paragraph+whose source fits on two lines.++{.This is my title}+A paragraph with a title.++=== Example block++.Optional title+[example]+This is an example of an example block.++.Optional title+====+Paragraph *one*.++Paragraph *two*.+====++=== Admonition++Simple form:++WARNING: This is very dangerous.+Don't do it unless you understand the risks.++[IMPORTANT]+.Title of the admonition+====+Remember:++. Don't do this.+. And don't do that.+====++=== Sidebar++[sidebar]+A simple sidebar.++.Optional Title *with strong emphasis*+****+Here is a sidebar.++TIP: It can contain any type of content.+****++=== Literal block++Short indented code:++  $ ls -a+  $ cat /foo/bar/baz \+       /bi/bim/bop++[literal]+This is+  a literal block too.++....+  Fenced+    $+ *a* literal++****+not a sidebar+****+....++=== Listing++[source,ruby]+----+require 'sinatra'++get '/hi' do+  "Hello World!"+end+----++Implied:++[source,ruby]+----+require 'sinatra'++get '/hi' do+  "Hello World!"+end+----++[,ruby]+----+include::asciidoc-reader-include.rb[]+----++[#hello.haskell]+----+putStrLn $ unwords ["Hello", "world"]+----++Line numbering:++[%linenums,ruby]+----+puts 1+puts 2+puts 3+----++----+This doesn't have a language.+  +="hi"+----++And with a callout list:++[source,ruby]+----+require 'sinatra' <1>++get '/hi' do <2> <3>+  "Hello World!"+end+----+<1> Library import+<2> URL mapping+<3> Response block++Markdown-style fenced:++```ruby+def foo+  return 5+end+```++=== Verse++[verse,Carl Sandburg, two lines from the poem Fog]+The fog comes+on little cat feet.++[verse,Carl Sandburg,Fog]+____+The fog comes+on little cat feet.+It sits looking+over harbor and city+on silent haunches+and then moves on.+____++=== Collapsible++Click here for more.+[%collapsible%open]+====+This is collapsible.++It can be hidden.+====++.Click me!+[%collapsible]+This paragraph is+also collapsible.++=== Quote++[quote,Captain James T. Kirk,Star Trek IV: The Voyage Home]+Everybody remember where we parked.++[quote,Monty Python and the Holy Grail]+____+Dennis: Come and see the violence inherent in the system. Help! Help! I'm being+repressed.++King Arthur: Bloody peasant!++Dennis: Oh, what a giveaway! Did you hear that? Did you hear that, eh? That's what I'm+on about! Did you see him repressing me? You saw him, Didn't you?+____++[quote.movie#roads,Dr. Emmett Brown]+____+Roads? Where we're going, we don't need roads.+____++=== Pass+++++++<p>pass <em>through</em>+  </p>+++++++=== Open block++.A title.+[key="a value"]+--+Any content can go here:++. one+. two+--++=== Anchor++[[goals]]+* one+* two++=== Breaks++Asciidoc thematic break:++'''++Markdown style:++---+- - -+***+* * *++Page breaks:++<<<++[%always]+<<<++=== List++* Edgar Allan Poe+* Sheri S. Tepper+* Bill Bryson++// titled++.Kizmet's Favorite Authors+* Edgar Allan Poe+* Sheri S. Tepper+* Bill Bryson++// hyphen++- Edgar Allan Poe+- Sheri S. Tepper+- Bill Bryson++. Nested list+* West wood maze+** Maze heart+*** Reflection pool+** Secret exit+* Level 1 list item+** Level 2 list item+*** Level 3 list item+**** Level 4 list item+***** Level 5 list item+****** etc.+* Level 1 list item++// attributes++[square]+* one+* two+* three++// ordered with actual numbers++1. Protons+2. Electrons+3. Neutrons++// ordered with .++. Protons+. Electrons+. Neutrons++Start with 4:++4. Step four+5. Step five+6. Step six++or++[start=4]+. Step four+. Step five+. Step six++Reversed:++[%reversed]+.Parts of an atom+. Protons+. Electrons+. Neutrons++Nested++. Step 1+. Step 2+.. Step 2a+.. Step 2b+. Step 3++Mixed nested++. Linux+* Fedora+* Ubuntu+* Slackware+. BSD+* FreeBSD+* NetBSD++With spacing++. Linux+* Fedora+* Ubuntu+* Slackware+. BSD+* FreeBSD+* NetBSD++With number styles++[lowerroman,start=5]+. Five+. Six+[loweralpha]+.. a+.. b+.. c+. Seven++Checklist++* [*] checked+* [x] also checked+* [ ] not checked+* normal list item++Separate lists with block attribute++* Apples+* Oranges+[]+. Wash+. Slice++Multiline items++* Blah blah.+Blah blah.+* The document header in AsciiDoc is optional.+If present, it must start with a document title.++* Optional author and revision information lines+immediately follow the document title.++* The document header must be separated from+  the remainder of the document by one or more+  empty lines and it cannot contain empty lines.++Complex item++* The header in AsciiDoc must start with a document title.+++----+= Document Title+----+++Keep in mind that the header is optional.+* Optional author and revision information lines immediately follow the document+title.+++----+= Document Title+Doc Writer <doc.writer@asciidoc.org>+v1.0, 2022-01-01+----+* Second item++Empty principle element:++. {empty}+++----+test+----++=== Table++==== Simple with column specs++[cols="3,2,3"]+|===+|This content is placed in the first cell of column 1+|This line starts with a vertical bar so this content is placed in a new cell in+column 2 |When the processor encounters a whitespace followed by a vertical bar it+ends the previous cell and starts a new cell+|===++==== Repeated column in specs++[cols="2*"]+|===+>s|This cell's specifier indicates that this cell's content is right-aligned and bold.+|The cell specifier on this cell hasn't been set explicitly, so the default+properties are applied.+|===++==== Simple without column specs++|===+|Column 1, header row |Column 2, header row++|Cell in column 1, row 2+|Cell in column 2, row 2++|Cell in column 1, row 3+|Cell in column 2, row 3+|===++==== With caption++.My cool table.+|===+|Column 1, header row |Column 2, header row++|Cell in column 1, row 2+|Cell in column 2, row 2++|Cell in column 1, row 3+|Cell in column 2, row 3+|===++==== No header++By default the first line should turn into the header, but this+can be disabled:++[%noheader]+|===+|Cell in column 1, row 1 |Cell in column 2, row 1+|Cell in column 1, row 2 |Cell in column 2, row 2+|===++And also explicitly enabled:++[%header%footer%autowidth,cols=2*~]+|===+|Cell A1 |Cell B1+|Cell A2 |Cell B2+|Cell A3 |Cell B3+|===++==== Footer++[%header%footer,cols="2,2,1"]+|===+|Column 1, header row+|Column 2, header row+|Column 3, header row+|Cell in column 1, row 2+|Cell in column 2, row 2+|Cell in column 3, row 2+|Column 1, footer row+|Column 2, footer row+|Column 3, footer row+|===++or++[options="footer"]+|===+|Column 1, header row |Column 2, header row+|Cell in column 1, row 2+|Cell in column 2, row 2+|Cell in column 1, row 3+|Cell in column 2, row 3+|Column 1, footer row+|Column 2, footer row+|===++==== Alignment++|===+|Column Name |Column Name+2+^|This cell spans two columns, and its content is horizontally centered because the+cell specifier includes the `+^+` operator.+2*^|This content is duplicated in two adjacent columns.+Its content is horizontally centered because the cell specifier+includes the `+^+` operator.+|===++==== Multiple paragraphs in cells++|===++|Single paragraph on row 1++|First paragraph on row 2++Second paragraph on row 2+|===++==== Complex table++|===++2*>m|This content is duplicated across two columns.++It is aligned right horizontally.++And it is monospaced.++.3+^.>s|This cell spans 3 rows. The content is centered horizontally, aligned to the bottom of the cell, and strong.+e|This content is emphasized.++.^l|This content is aligned to the top of the cell and literal.++a|+[source]+puts "This is a source block!"++|===++==== Column styles++[cols="m,m"]+|===+|monospace | mono+d|default | mono+|===++==== Block elements in cells++|===+|Normal Style |AsciiDoc Style+|This cell isn't prefixed with an `a`, so the processor doesn't interpret the+following lines as an AsciiDoc list.++* List item 1+* List item 2+* List item 3++a|This cell is prefixed with an `a`, so the processor interprets the following lines+as an AsciiDoc list.++* List item 1+* List item 2+* List item 3++|This cell isn't prefixed with an `a`, so the processor doesn't interpret the listing+block delimiters or the `source` style.++[source,python]+----+import os+print ("%s" %(os.uname()))+----++a|This cell is prefixed with an `a`, so the listing block is processed and rendered+according to the `source` style rules.++[source,python]+----+import os+print "%s" %(os.uname())+----+|===++==== Col and rowspan++|===+|Column 1, header row |Column 2, header row | Column 3, header row+2.2+|This cell spans 2 cols and 2 rows+|Cell in column 3, row 2+|Cell in column 3, row 3+3+|Cell in column 1-3, row 4+|===++==== CSV table++[%header,format=csv]+|===+Artist,Track,Genre+Baauer,Harlem Shake,Hip Hop+The Lumineers,Ho Hey,Folk Rock+|===++or++,===+Artist,Track,Genre+Baauer,Harlem Shake,Hip Hop+,===++==== DSV table++[format=dsv,separator=;]+|===+a;b;c+d;e;f+|===++or++:===+Artist:Track:Genre+Robyn:Indestructible:Dance+:===++=== Definition list++CPU:: The brain of the computer.+Hard drive:: Permanent storage for operating system and/or user files.++Mixed++Dairy::+* Milk+* Eggs+Bakery::+* Bread+Produce::+* Bananas++With spaces++Dairy::++  * Milk+  * Eggs++Bakery::++  * Bread++Produce::++  * Bananas++Nested++Operating Systems::+Linux:::+ . Fedora+  * Desktop+ . Ubuntu+  * Desktop+  * Server+BSD:::+ . FreeBSD+ . NetBSD+Cloud Providers::+ PaaS:::+  . OpenShift+  . CloudBees+ IaaS:::+  . Amazon EC2++This just affects the output:++[horizontal,labelwidth=25,itemwidth=75]+CPU:: The brain of the computer.+RAM:: Temporarily stores information the CPU uses during operation.++Q&A list++[qanda]+What is the answer?::+This is the answer.+Are cameras allowed?::+Are backpacks allowed?::+No.++Ordered description list (with numbers)++[ordered]+&:: ampersand+>:: greater than++=== Block macros++image::sunset.jpg[Sunset,300,200]++video::mymovie.mp4[]++audio::mysong.mp3[]++toc::[]++include::asciidoc-reader-include.adoc[]+
+ test/asciidoc-reader.native view
@@ -0,0 +1,4418 @@+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "author"+            , MetaList+                [ MetaInlines+                    [ Str "John"+                    , Space+                    , Str "MacFarlane"+                    , Space+                    , Str "("+                    , Link+                        ( "" , [] , [] )+                        [ Str "jgm@berkeley.edu" ]+                        ( "mailto:jgm@berkeley.edu" , "" )+                    , Str ")"+                    ]+                , MetaInlines+                    [ Str "John"+                    , Space+                    , Str "Doe"+                    , Space+                    , Str "("+                    , Link+                        ( "" , [] , [] )+                        [ Str "doe@example.com" ]+                        ( "mailto:doe@example.com" , "" )+                    , Str ")"+                    ]+                ]+            )+          , ( "custom" , MetaString "Foo bar baz" )+          , ( "date" , MetaString "2025-11-24" )+          , ( "flag" , MetaBool True )+          , ( "title"+            , MetaInlines+                [ Str "AsciiDoc"+                , Space+                , Str "reader"+                , Space+                , Str "test"+                ]+            )+          , ( "version" , MetaString "1.0" )+          ]+    }+  [ Header+      1+      ( "firsty" , [] , [] )+      [ Str "Inline" , Space , Str "markup" ]+  , Header+      2+      ( "_characters_and_escapes" , [] , [] )+      [ Str "Characters"+      , Space+      , Str "and"+      , Space+      , Str "escapes"+      ]+  , Para+      [ Str "Dog\8217s"+      , Space+      , Str "has"+      , Space+      , Str "a"+      , Space+      , Str "curved"+      , Space+      , Str "apostrophe,"+      , Space+      , Str "but"+      , Space+      , Str "dog's"+      , Space+      , Str "does"+      , Space+      , Str "not."+      ]+  , Para+      [ Str "An"+      , Space+      , Str "escaped"+      , Space+      , Str "symbol:"+      , Space+      , Str "*star*."+      ]+  , Para+      [ Str "Character"+      , Space+      , Str "references:"+      , Space+      , Str "\228\160\8928"+      ]+  , Header+      2+      ( "_line_breaks" , [] , [] )+      [ Str "Line" , Space , Str "breaks" ]+  , Para+      [ Str "This"+      , Space+      , Str "is"+      , Space+      , Str "a"+      , Space+      , Str "hard"+      , LineBreak+      , Str "break."+      ]+  , Para+      [ Str "Or"+      , Space+      , Str "set"+      , Space+      , Str "it"+      , Space+      , Str "for"+      , Space+      , Str "a"+      , Space+      , Str "whole"+      , Space+      , Str "paragraph"+      ]+  , Div+      ( ""+      , []+      , [ ( "wrapper" , "1" ) , ( "options" , "hardbreaks" ) ]+      )+      [ Para+          [ Str "These"+          , Space+          , Str "are"+          , LineBreak+          , Str "all"+          , LineBreak+          , Str "hard"+          , LineBreak+          , Str "breaks."+          ]+      ]+  , Header 2 ( "_autolinks" , [] , [] ) [ Str "Autolinks" ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "http://example.com/foobar?a=333&b=no%20body" ]+          ( "http://example.com/foobar?a=333&b=no%20body" , "" )+      , Str ","+      , Space+      , Link+          ( "" , [] , [] )+          [ Str "me@example.com" ]+          ( "me@example.com" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "http://example.com/foobar?a=333&b=no%20body" ]+          ( "http://example.com/foobar?a=333&b=no%20body" , "" )+      , Str ","+      , Space+      , Str "<"+      , Link+          ( "" , [] , [] )+          [ Str "me@example.com" ]+          ( "me@example.com" , "" )+      , Str ">"+      ]+  , Header+      2 ( "_cross_reference" , [] , [] ) [ Str "Cross-reference" ]+  , Para+      [ Str "See"+      , Space+      , Link+          ( "" , [ "cross-reference" ] , [] )+          [ Str "Inline" , Space , Str "markup" ]+          ( "#firsty" , "" )+      ]+  , Para+      [ Str "See"+      , Space+      , Link+          ( "" , [ "cross-reference" ] , [] )+          [ Str "My"+          , Space+          , Str "great"+          , Space+          , Str "section"+          , Space+          , Str "on"+          , Space+          , Str "Inline"+          , Space+          , Str "markup"+          ]+          ( "#firsty" , "" )+      ]+  , Para+      [ Str "Go"+      , Space+      , Str "to"+      , Space+      , Link+          ( "" , [ "cross-reference" ] , [] )+          [ Str "an" , Space , Str "inline" , Space , Str "anchor" ]+          ( "#anch" , "" )+      ]+  , Header 2 ( "_anchors" , [] , [] ) [ Str "Anchors" ]+  , Para+      [ Str "An"+      , Space+      , Span ( "anch" , [] , [] ) []+      , Str "inline"+      , Space+      , Str "anchor."+      ]+  , Para+      [ Span ( "[bibanchor" , [] , [] ) []+      , Str "Doe,"+      , Space+      , Str "John."+      , Space+      , Str "A"+      , Space+      , Str "Book."+      ]+  , Header+      2+      ( "_inline_macros" , [] , [] )+      [ Str "Inline" , Space , Str "macros" ]+  , Para+      [ Span ( "" , [ "kbd" ] , [] ) [ Strong [ Str "F11" ] ] ]+  , Para+      [ Span ( "" , [ "kbd" ] , [] ) [ Strong [ Str "Ctrl" ] ]+      , Str "+"+      , Span ( "" , [ "kbd" ] , [] ) [ Strong [ Str "Shift" ] ]+      , Str "+"+      , Span ( "" , [ "kbd" ] , [] ) [ Strong [ Str "F" ] ]+      ]+  , Para+      [ Span+          ( "" , [ "menu" ] , [] )+          [ Strong [ Str "File\160\8250\160Save" ] ]+      ]+  , Para+      [ Span+          ( "" , [ "menu" ] , [] )+          [ Strong+              [ Str "Reader\160\8250\160Markdown\160\8250\160Pandoc" ]+          ]+      ]+  , Para+      [ Span+          ( "" , [ "button" ] , [] ) [ Strong [ Str "[Cancel]" ] ]+      ]+  , Para+      [ Image+          ( "" , [ "red icon" ] , [] )+          []+          ( "./images/icons/heart.png" , "" )+      ]+  , Para [ Str "anchor:tiger" ]+  , Para [ Strong [ Str "*bold*" ] ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Get" , Space , Str "Report" ]+          ( "downloads/report.pdf" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "tools.html#editors" ]+          ( "tools.html#editors" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Your" , Space , Str "files" ]+          ( "file:///home/username" , "" )+      ]+  , Para [ Str "Tricky" , Space , Str "cases:" ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Get" , Space , Str "Report" ]+          ( "My Documents/report.pdf" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Get" , Space , Str "Report" ]+          ( "My&#32;Documents/report.pdf" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Get" , Space , Str "Report" ]+          ( "My%20Documents/report.pdf" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "https://example.org/now_this__link_works.html" ]+          ( "https://example.org/now_this__link_works.html" , "" )+      ]+  , Para+      [ Link+          ( "" , [] , [] )+          [ Str "Subscribe" ]+          ( "join@discuss.example.org" , "" )+      ]+  , Para+      [ Link+          ( "" , [ "mail" ] , [] )+          [ Str "Click,"+          , Space+          , Str "subscribe,"+          , Space+          , Str "and"+          , Space+          , Str "participate!"+          ]+          ( "join@discuss.example.org" , "" )+      ]+  , Para+      [ Link+          ( "" , [ "cross-reference" ] , [] )+          [ Str "use"+          , Space+          , Str "attributes"+          , Space+          , Str "within"+          , Space+          , Str "the"+          , Space+          , Str "link"+          , Space+          , Str "macro"+          ]+          ( "#link-macro-attributes" , "" )+      ]+  , Figure+      ( "" , [] , [] )+      (Caption Nothing [])+      [ Plain+          [ Image+              ( "" , [] , [] ) [ Str "Sunset" ] ( "sunset.jpg" , "" )+          ]+      ]+  , Figure+      ( "" , [] , [] )+      (Caption Nothing [])+      [ Plain [ Image ( "" , [] , [] ) [] ( "name.png" , "" ) ] ]+  , Figure+      ( "" , [] , [] )+      (Caption Nothing [])+      [ Plain+          [ Image+              ( ""+              , []+              , [ ( "width" , "300px" ) , ( "height" , "400px" ) ]+              )+              [ Str "Sunset" ]+              ( "sunset.jpg" , "" )+          ]+      ]+  , Div+      ( ""+      , []+      , [ ( "wrapper" , "1" )+        , ( "alt" , "Sunset" )+        , ( "height" , "400" )+        , ( "width" , "300" )+        ]+      )+      [ Figure+          ( "" , [] , [] )+          (Caption Nothing [])+          [ Plain [ Image ( "" , [] , [] ) [] ( "sunset.jpg" , "" ) ]+          ]+      ]+  , Para [ Math DisplayMath "e=mc^2\n" ]+  , Para [ Math DisplayMath "sin n / 3\n" ]+  , Para [ Math DisplayMath "e^i\n" ]+  , Header+      2+      ( "_attribute_substitutions" , [] , [] )+      [ Str "Attribute" , Space , Str "substitutions" ]+  , Para [ Str "Foo" , Space , Str "bar" , Space , Str "baz" ]+  , Para [ Str "{nonexistent}" ]+  , Para+      [ Str "Built"+      , Space+      , Str "in:"+      , Space+      , Str "xyz"+      , Space+      , Str "a\160b\8203c'd\8216"+      ]+  , Header+      2+      ( "_bold_and_italic" , [] , [] )+      [ Str "Bold" , Space , Str "and" , Space , Str "italic" ]+  , Para+      [ Str "Constrained:"+      , Space+      , Strong+          [ Str "this"+          , Space+          , Str "is"+          , Space+          , Str "bold"+          , Space+          , Emph [ Str "and" , Space , Str "italic" ]+          ]+      , Str "."+      ]+  , Para+      [ Str "Unconstrained:"+      , Space+      , Str "wild"+      , Strong+          [ Str "content"+          , Emph [ Str "with" , Space , Str "italic" ]+          , Str "stuff"+          ]+      , Str "."+      ]+  , Header 2 ( "_monospace" , [] , [] ) [ Str "Monospace" ]+  , Para [ Code ( "" , [] , [] ) "simple" ]+  , Para+      [ Code ( "" , [] , [] ) "complex"+      , Space+      , Strong+          [ Code ( "" , [] , [] ) "with"+          , Space+          , Code ( "" , [] , [] ) "bold"+          ]+      , Space+      , Code ( "" , [] , [] ) "text"+      , Space+      , Code ( "" , [] , [] ) "and"+      , Space+      , Code ( "" , [] , [] ) "a"+      , Space+      , Link+          ( "" , [] , [] )+          [ Code ( "" , [] , [] ) "foo.html" ]+          ( "foo.html" , "" )+      ]+  , Para+      [ Str "unconstrained"+      , Code ( "" , [] , [] ) "wwow"+      , Str "okay"+      ]+  , Header+      2+      ( "_span_and_inline_attributes" , [] , [] )+      [ Str "Span"+      , Space+      , Str "and"+      , Space+      , Str "inline"+      , Space+      , Str "attributes"+      ]+  , Para+      [ Span+          ( "" , [ "red" ] , [] )+          [ Str "Bonjour" , Space , Strong [ Str "monsieur" ] ]+      ]+  , Para+      [ Str "Un"+      , Span ( "" , [ "red" ] , [] ) [ Str "constrained" ]+      , Str "content"+      ]+  , Para+      [ Str "With"+      , Space+      , Span+          ( "" , [ "mark" ] , [] )+          [ Str "no" , Space , Str "attribute" ]+      , Space+      , Str "it\8217s"+      , Space+      , Str "highlighted."+      ]+  , Header+      2+      ( "_sub_and_superscript" , [] , [] )+      [ Str "Sub"+      , Space+      , Str "and"+      , Space+      , Str "superscript"+      ]+  , Para [ Str "H" , Subscript [ Str "2" ] , Str "O" ]+  , Para+      [ Str "H"+      , Subscript [ Str "a" , Space , Str "b" ]+      , Str "O"+      ]+  , Para+      [ Str "Not"+      , Space+      , Str "subscript:"+      , Space+      , Str "H~a"+      , Space+      , Str "b~O."+      ]+  , Para [ Str "H^2&O" ]+  , Para+      [ Str "H"+      , Superscript [ Str "a" , Space , Str "b" ]+      , Str "O"+      ]+  , Para+      [ Str "Not"+      , Space+      , Str "subscript:"+      , Space+      , Str "H^a"+      , Space+      , Str "b^O."+      ]+  , Header+      2 ( "_passthrough" , [] , [] ) [ Str "Passthrough" ]+  , Para+      [ Str "Here"+      , Space+      , Str "the"+      , Space+      , Str "special"+      , Space+      , Str "characters"+      , Space+      , Str "just"+      , Space+      , Str "come"+      , Space+      , Str "through"+      , Space+      , Str "as"+      , Space+      , Str "literal:"+      ]+  , Para [ Str "<b>*test*</b>" ]+  , Para [ Str "xx<b>*test*</b>xx" ]+  , Para+      [ Str "But"+      , Space+      , Str "here"+      , Space+      , Str "they"+      , Space+      , Str "are"+      , Space+      , Str "passed"+      , Space+      , Str "through:"+      ]+  , Para [ Str "xx" , Strong [ Str "*test*" ] , Str "xx" ]+  , Header 2 ( "_quoted" , [] , [] ) [ Str "Quoted" ]+  , Para+      [ Quoted DoubleQuote [ Str "double" , Space , Str "quoted" ]+      ]+  , Para+      [ Quoted SingleQuote [ Str "single" , Space , Str "quoted" ]+      ]+  , Header 2 ( "_footnotes" , [] , [] ) [ Str "Footnotes" ]+  , Para+      [ Str "Double"+      , Note+          [ Para+              [ Str "The"+              , Space+              , Str "double"+              , Space+              , Str "hail-and-rainbow"+              , Space+              , Str "level"+              , Space+              , Str "makes"+              , Space+              , Str "my"+              , Space+              , Str "toes"+              , Space+              , Str "tingle."+              ]+          ]+      ]+  , Para+      [ Str "A"+      , Space+      , Str "bold"+      , Space+      , Str "statement!"+      , Note+          [ Para+              [ Str "Opinions"+              , Space+              , Str "are"+              , Space+              , Str "my"+              , Space+              , Str "own."+              ]+          ]+      , SoftBreak+      , Str "Another"+      , Space+      , Str "outrageous"+      , Space+      , Str "statement."+      , Note+          [ Para+              [ Str "Opinions"+              , Space+              , Str "are"+              , Space+              , Str "my"+              , Space+              , Str "own."+              ]+          ]+      ]+  , Header+      1+      ( "_block_markup" , [] , [] )+      [ Str "Block" , Space , Str "markup" ]+  , Header 2 ( "_sections" , [] , [] ) [ Str "Sections" ]+  , Header+      3+      ( "_another_level" , [] , [] )+      [ Str "Another" , Space , Str "level" ]+  , Header+      4 ( "_level_5" , [] , [] ) [ Str "Level" , Space , Str "5" ]+  , Header+      3+      ( "_markdown_style" , [] , [] )+      [ Str "Markdown" , Space , Str "style" ]+  , Header+      4+      ( "_level_5_2" , [] , [] )+      [ Str "Level" , Space , Str "5" ]+  , Header+      2+      ( "_discrete_heading" , [] , [] )+      [ Str "Discrete" , Space , Str "heading" ]+  , Header+      3+      ( "" , [] , [] )+      [ Str "A"+      , Space+      , Str "discrete"+      , Space+      , Str "heading,"+      , Space+      , Str "not"+      , Space+      , Str "a"+      , Space+      , Str "section"+      ]+  , Header 2 ( "_paragraph" , [] , [] ) [ Str "Paragraph" ]+  , Para+      [ Str "This"+      , Space+      , Str "is"+      , Space+      , Str "a"+      , Space+      , Str "paragraph"+      , SoftBreak+      , Str "whose"+      , Space+      , Str "source"+      , Space+      , Str "fits"+      , Space+      , Str "on"+      , Space+      , Str "two"+      , Space+      , Str "lines."+      ]+  , Para+      [ Str "{.This"+      , Space+      , Str "is"+      , Space+      , Str "my"+      , Space+      , Str "title}"+      , SoftBreak+      , Str "A"+      , Space+      , Str "paragraph"+      , Space+      , Str "with"+      , Space+      , Str "a"+      , Space+      , Str "title."+      ]+  , Header+      2+      ( "_example_block" , [] , [] )+      [ Str "Example" , Space , Str "block" ]+  , Div+      ( "" , [] , [] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para [ Str "Optional" , Space , Str "title" ] ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "an"+          , Space+          , Str "example"+          , Space+          , Str "of"+          , Space+          , Str "an"+          , Space+          , Str "example"+          , Space+          , Str "block."+          ]+      ]+  , Div+      ( "" , [ "example" ] , [] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para [ Str "Optional" , Space , Str "title" ] ]+      , Para+          [ Str "Paragraph" , Space , Strong [ Str "one" ] , Str "." ]+      , Para+          [ Str "Paragraph" , Space , Strong [ Str "two" ] , Str "." ]+      ]+  , Header 2 ( "_admonition" , [] , [] ) [ Str "Admonition" ]+  , Para [ Str "Simple" , Space , Str "form:" ]+  , Div+      ( "" , [ "warning" ] , [] )+      [ Div ( "" , [ "title" ] , [] ) [ Para [ Str "Warning" ] ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "very"+          , Space+          , Str "dangerous."+          , SoftBreak+          , Str "Don\8217t"+          , Space+          , Str "do"+          , Space+          , Str "it"+          , Space+          , Str "unless"+          , Space+          , Str "you"+          , Space+          , Str "understand"+          , Space+          , Str "the"+          , Space+          , Str "risks."+          ]+      ]+  , Div+      ( "" , [ "important" ] , [] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para+              [ Str "Title"+              , Space+              , Str "of"+              , Space+              , Str "the"+              , Space+              , Str "admonition"+              ]+          ]+      , Para [ Str "Remember:" ]+      , OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para+                [ Str "Don\8217t"+                , Space+                , Str "do"+                , Space+                , Str "this."+                ]+            ]+          , [ Para+                [ Str "And"+                , Space+                , Str "don\8217t"+                , Space+                , Str "do"+                , Space+                , Str "that."+                ]+            ]+          ]+      ]+  , Header 2 ( "_sidebar" , [] , [] ) [ Str "Sidebar" ]+  , Para+      [ Str "A" , Space , Str "simple" , Space , Str "sidebar." ]+  , Div+      ( "" , [ "sidebar" ] , [] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para+              [ Str "Optional"+              , Space+              , Str "Title"+              , Space+              , Strong+                  [ Str "with"+                  , Space+                  , Str "strong"+                  , Space+                  , Str "emphasis"+                  ]+              ]+          ]+      , Para+          [ Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "a"+          , Space+          , Str "sidebar."+          ]+      , Div+          ( "" , [ "tip" ] , [] )+          [ Div ( "" , [ "title" ] , [] ) [ Para [ Str "Tip" ] ]+          , Para+              [ Str "It"+              , Space+              , Str "can"+              , Space+              , Str "contain"+              , Space+              , Str "any"+              , Space+              , Str "type"+              , Space+              , Str "of"+              , Space+              , Str "content."+              ]+          ]+      ]+  , Header+      2+      ( "_literal_block" , [] , [] )+      [ Str "Literal" , Space , Str "block" ]+  , Para+      [ Str "Short"+      , Space+      , Str "indented"+      , Space+      , Str "code:"+      ]+  , CodeBlock+      ( "" , [] , [] )+      "$ ls -a\n$ cat /foo/bar/baz \\\n     /bi/bim/bop\n"+  , CodeBlock+      ( "" , [] , [] ) "This is\n  a literal block too.\n"+  , CodeBlock+      ( "" , [] , [] )+      "  Fenced\n    $+ *a* literal\n\n****\nnot a sidebar\n****\n"+  , Header 2 ( "_listing" , [] , [] ) [ Str "Listing" ]+  , CodeBlock+      ( "" , [ "ruby" ] , [] )+      "require 'sinatra'\n\nget '/hi' do\n  \"Hello World!\"\nend"+  , Para [ Str "Implied:" ]+  , CodeBlock+      ( "" , [ "ruby" ] , [] )+      "require 'sinatra'\n\nget '/hi' do\n  \"Hello World!\"\nend"+  , CodeBlock+      ( "" , [ "ruby" ] , [] )+      "# A function\ndef foo\n  return 42\nend"+  , CodeBlock+      ( "hello" , [ "haskell" ] , [] )+      "putStrLn $ unwords [\"Hello\", \"world\"]"+  , Para [ Str "Line" , Space , Str "numbering:" ]+  , CodeBlock+      ( "" , [] , [ ( "options" , "linenums" ) ] )+      "puts 1\nputs 2\nputs 3"+  , CodeBlock+      ( "" , [] , [] ) "This doesn't have a language.\n  +=\"hi\""+  , Para+      [ Str "And"+      , Space+      , Str "with"+      , Space+      , Str "a"+      , Space+      , Str "callout"+      , Space+      , Str "list:"+      ]+  , CodeBlock+      ( "" , [ "ruby" ] , [] )+      "require 'sinatra' \9312\n\nget '/hi' do \9313 \9314\n  \"Hello World!\"\nend"+  , Div+      ( "" , [ "callout-list" ] , [] )+      [ OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para [ Str "Library" , Space , Str "import" ] ]+          , [ Para [ Str "URL" , Space , Str "mapping" ] ]+          , [ Para [ Str "Response" , Space , Str "block" ] ]+          ]+      ]+  , Para [ Str "Markdown-style" , Space , Str "fenced:" ]+  , CodeBlock+      ( "" , [ "ruby" ] , [] ) "def foo\n  return 5\nend"+  , Header 2 ( "_verse" , [] , [] ) [ Str "Verse" ]+  , BlockQuote+      [ Para+          [ Str "The"+          , Space+          , Str "fog"+          , Space+          , Str "comes"+          , LineBreak+          , Str "on"+          , Space+          , Str "little"+          , Space+          , Str "cat"+          , Space+          , Str "feet."+          ]+      , Para+          [ Str "\8212"+          , Space+          , Str "Carl"+          , Space+          , Str "Sandburg,"+          , Space+          , Str "two"+          , Space+          , Str "lines"+          , Space+          , Str "from"+          , Space+          , Str "the"+          , Space+          , Str "poem"+          , Space+          , Str "Fog"+          ]+      ]+  , BlockQuote+      [ Para+          [ Str "The"+          , Space+          , Str "fog"+          , Space+          , Str "comes"+          , LineBreak+          , Str "on"+          , Space+          , Str "little"+          , Space+          , Str "cat"+          , Space+          , Str "feet."+          , LineBreak+          , Str "It"+          , Space+          , Str "sits"+          , Space+          , Str "looking"+          , LineBreak+          , Str "over"+          , Space+          , Str "harbor"+          , Space+          , Str "and"+          , Space+          , Str "city"+          , LineBreak+          , Str "on"+          , Space+          , Str "silent"+          , Space+          , Str "haunches"+          , LineBreak+          , Str "and"+          , Space+          , Str "then"+          , Space+          , Str "moves"+          , Space+          , Str "on."+          ]+      , Para+          [ Str "\8212"+          , Space+          , Str "Carl"+          , Space+          , Str "Sandburg,"+          , Space+          , Str "Fog"+          ]+      ]+  , Header+      2 ( "_collapsible" , [] , [] ) [ Str "Collapsible" ]+  , Para+      [ Str "Click"+      , Space+      , Str "here"+      , Space+      , Str "for"+      , Space+      , Str "more."+      ]+  , Div+      ( ""+      , [ "example" ]+      , [ ( "options" , "collapsible,open" ) ]+      )+      [ Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "collapsible."+          ]+      , Para+          [ Str "It"+          , Space+          , Str "can"+          , Space+          , Str "be"+          , Space+          , Str "hidden."+          ]+      ]+  , Div+      ( "" , [] , [ ( "options" , "collapsible" ) ] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para [ Str "Click" , Space , Str "me!" ] ]+      , Para+          [ Str "This"+          , Space+          , Str "paragraph"+          , Space+          , Str "is"+          , SoftBreak+          , Str "also"+          , Space+          , Str "collapsible."+          ]+      ]+  , Header 2 ( "_quote" , [] , [] ) [ Str "Quote" ]+  , BlockQuote+      [ Para+          [ Str "Everybody"+          , Space+          , Str "remember"+          , Space+          , Str "where"+          , Space+          , Str "we"+          , Space+          , Str "parked."+          ]+      , Para+          [ Str "\8212"+          , Space+          , Str "Captain"+          , Space+          , Str "James"+          , Space+          , Str "T."+          , Space+          , Str "Kirk,"+          , Space+          , Str "Star"+          , Space+          , Str "Trek"+          , Space+          , Str "IV:"+          , Space+          , Str "The"+          , Space+          , Str "Voyage"+          , Space+          , Str "Home"+          ]+      ]+  , BlockQuote+      [ Para+          [ Str "Dennis:"+          , Space+          , Str "Come"+          , Space+          , Str "and"+          , Space+          , Str "see"+          , Space+          , Str "the"+          , Space+          , Str "violence"+          , Space+          , Str "inherent"+          , Space+          , Str "in"+          , Space+          , Str "the"+          , Space+          , Str "system."+          , Space+          , Str "Help!"+          , Space+          , Str "Help!"+          , Space+          , Str "I\8217m"+          , Space+          , Str "being"+          , SoftBreak+          , Str "repressed."+          ]+      , Para+          [ Str "King"+          , Space+          , Str "Arthur:"+          , Space+          , Str "Bloody"+          , Space+          , Str "peasant!"+          ]+      , Para+          [ Str "Dennis:"+          , Space+          , Str "Oh,"+          , Space+          , Str "what"+          , Space+          , Str "a"+          , Space+          , Str "giveaway!"+          , Space+          , Str "Did"+          , Space+          , Str "you"+          , Space+          , Str "hear"+          , Space+          , Str "that?"+          , Space+          , Str "Did"+          , Space+          , Str "you"+          , Space+          , Str "hear"+          , Space+          , Str "that,"+          , Space+          , Str "eh?"+          , Space+          , Str "That\8217s"+          , Space+          , Str "what"+          , Space+          , Str "I\8217m"+          , SoftBreak+          , Str "on"+          , Space+          , Str "about!"+          , Space+          , Str "Did"+          , Space+          , Str "you"+          , Space+          , Str "see"+          , Space+          , Str "him"+          , Space+          , Str "repressing"+          , Space+          , Str "me?"+          , Space+          , Str "You"+          , Space+          , Str "saw"+          , Space+          , Str "him,"+          , Space+          , Str "Didn\8217t"+          , Space+          , Str "you?"+          ]+      , Para+          [ Str "\8212"+          , Space+          , Str "Monty"+          , Space+          , Str "Python"+          , Space+          , Str "and"+          , Space+          , Str "the"+          , Space+          , Str "Holy"+          , Space+          , Str "Grail"+          ]+      ]+  , Div+      ( "roads" , [ "movie" ] , [ ( "wrapper" , "1" ) ] )+      [ BlockQuote+          [ Para+              [ Str "Roads?"+              , Space+              , Str "Where"+              , Space+              , Str "we\8217re"+              , Space+              , Str "going,"+              , Space+              , Str "we"+              , Space+              , Str "don\8217t"+              , Space+              , Str "need"+              , Space+              , Str "roads."+              ]+          , Para+              [ Str "\8212"+              , Space+              , Str "Dr."+              , Space+              , Str "Emmett"+              , Space+              , Str "Brown"+              ]+          ]+      ]+  , Header 2 ( "_pass" , [] , [] ) [ Str "Pass" ]+  , Para [ Str "pass" , Space , Emph [ Str "through" ] ]+  , Header+      2+      ( "_open_block" , [] , [] )+      [ Str "Open" , Space , Str "block" ]+  , Div+      ( "" , [] , [ ( "key" , "a value" ) ] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para [ Str "A" , Space , Str "title." ] ]+      , Para+          [ Str "Any"+          , Space+          , Str "content"+          , Space+          , Str "can"+          , Space+          , Str "go"+          , Space+          , Str "here:"+          ]+      , OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para [ Str "one" ] ] , [ Para [ Str "two" ] ] ]+      ]+  , Header 2 ( "_anchor" , [] , [] ) [ Str "Anchor" ]+  , Div+      ( "goals" , [] , [ ( "wrapper" , "1" ) ] )+      [ BulletList+          [ [ Para [ Str "one" ] ] , [ Para [ Str "two" ] ] ]+      ]+  , Header 2 ( "_breaks" , [] , [] ) [ Str "Breaks" ]+  , Para+      [ Str "Asciidoc"+      , Space+      , Str "thematic"+      , Space+      , Str "break:"+      ]+  , HorizontalRule+  , Para [ Str "Markdown" , Space , Str "style:" ]+  , HorizontalRule+  , HorizontalRule+  , HorizontalRule+  , HorizontalRule+  , Para [ Str "Page" , Space , Str "breaks:" ]+  , Div+      ( "" , [ "page-break" ] , [ ( "wrapper" , "1" ) ] )+      [ HorizontalRule ]+  , Div+      ( ""+      , [ "page-break" ]+      , [ ( "options" , "always" ) , ( "wrapper" , "1" ) ]+      )+      [ HorizontalRule ]+  , Header 2 ( "_list" , [] , [] ) [ Str "List" ]+  , BulletList+      [ [ Para+            [ Str "Edgar" , Space , Str "Allan" , Space , Str "Poe" ]+        ]+      , [ Para+            [ Str "Sheri" , Space , Str "S." , Space , Str "Tepper" ]+        ]+      , [ Para [ Str "Bill" , Space , Str "Bryson" ] ]+      ]+  , Div+      ( "" , [] , [] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para+              [ Str "Kizmet\8217s"+              , Space+              , Str "Favorite"+              , Space+              , Str "Authors"+              ]+          ]+      , BulletList+          [ [ Para+                [ Str "Edgar"+                , Space+                , Str "Allan"+                , Space+                , Str "Poe"+                ]+            ]+          , [ Para+                [ Str "Sheri"+                , Space+                , Str "S."+                , Space+                , Str "Tepper"+                ]+            ]+          , [ Para [ Str "Bill" , Space , Str "Bryson" ] ]+          ]+      ]+  , BulletList+      [ [ Para+            [ Str "Edgar" , Space , Str "Allan" , Space , Str "Poe" ]+        ]+      , [ Para+            [ Str "Sheri" , Space , Str "S." , Space , Str "Tepper" ]+        ]+      , [ Para [ Str "Bill" , Space , Str "Bryson" ] ]+      ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Nested" , Space , Str "list" ]+        , BulletList+            [ [ Para+                  [ Str "West"+                  , Space+                  , Str "wood"+                  , Space+                  , Str "maze"+                  ]+              , BulletList+                  [ [ Para [ Str "Maze" , Space , Str "heart" ]+                    , BulletList+                        [ [ Para+                              [ Str "Reflection" , Space , Str "pool" ]+                          ]+                        ]+                    ]+                  , [ Para [ Str "Secret" , Space , Str "exit" ] ]+                  ]+              ]+            , [ Para+                  [ Str "Level"+                  , Space+                  , Str "1"+                  , Space+                  , Str "list"+                  , Space+                  , Str "item"+                  ]+              , BulletList+                  [ [ Para+                        [ Str "Level"+                        , Space+                        , Str "2"+                        , Space+                        , Str "list"+                        , Space+                        , Str "item"+                        ]+                    , BulletList+                        [ [ Para+                              [ Str "Level"+                              , Space+                              , Str "3"+                              , Space+                              , Str "list"+                              , Space+                              , Str "item"+                              ]+                          , BulletList+                              [ [ Para+                                    [ Str "Level"+                                    , Space+                                    , Str "4"+                                    , Space+                                    , Str "list"+                                    , Space+                                    , Str "item"+                                    ]+                                , BulletList+                                    [ [ Para+                                          [ Str "Level"+                                          , Space+                                          , Str "5"+                                          , Space+                                          , Str "list"+                                          , Space+                                          , Str "item"+                                          ]+                                      , BulletList+                                          [ [ Para [ Str "etc." ] ] ]+                                      ]+                                    ]+                                ]+                              ]+                          ]+                        ]+                    ]+                  ]+              ]+            , [ Para+                  [ Str "Level"+                  , Space+                  , Str "1"+                  , Space+                  , Str "list"+                  , Space+                  , Str "item"+                  ]+              ]+            ]+        ]+      ]+  , BulletList+      [ [ Para [ Str "one" ] ]+      , [ Para [ Str "two" ] ]+      , [ Para [ Str "three" ] ]+      ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Protons" ] ]+      , [ Para [ Str "Electrons" ] ]+      , [ Para [ Str "Neutrons" ] ]+      ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Protons" ] ]+      , [ Para [ Str "Electrons" ] ]+      , [ Para [ Str "Neutrons" ] ]+      ]+  , Para+      [ Str "Start" , Space , Str "with" , Space , Str "4:" ]+  , OrderedList+      ( 4 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Step" , Space , Str "four" ] ]+      , [ Para [ Str "Step" , Space , Str "five" ] ]+      , [ Para [ Str "Step" , Space , Str "six" ] ]+      ]+  , Para [ Str "or" ]+  , OrderedList+      ( 4 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Step" , Space , Str "four" ] ]+      , [ Para [ Str "Step" , Space , Str "five" ] ]+      , [ Para [ Str "Step" , Space , Str "six" ] ]+      ]+  , Para [ Str "Reversed:" ]+  , Div+      ( "" , [] , [ ( "options" , "reversed" ) ] )+      [ Div+          ( "" , [ "title" ] , [] )+          [ Para+              [ Str "Parts"+              , Space+              , Str "of"+              , Space+              , Str "an"+              , Space+              , Str "atom"+              ]+          ]+      , OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para [ Str "Protons" ] ]+          , [ Para [ Str "Electrons" ] ]+          , [ Para [ Str "Neutrons" ] ]+          ]+      ]+  , Para [ Str "Nested" ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Step" , Space , Str "1" ] ]+      , [ Para [ Str "Step" , Space , Str "2" ]+        , OrderedList+            ( 1 , DefaultStyle , DefaultDelim )+            [ [ Para [ Str "Step" , Space , Str "2a" ] ]+            , [ Para [ Str "Step" , Space , Str "2b" ] ]+            ]+        ]+      , [ Para [ Str "Step" , Space , Str "3" ] ]+      ]+  , Para [ Str "Mixed" , Space , Str "nested" ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Linux" ]+        , BulletList+            [ [ Para [ Str "Fedora" ] ]+            , [ Para [ Str "Ubuntu" ] ]+            , [ Para [ Str "Slackware" ] ]+            ]+        ]+      , [ Para [ Str "BSD" ]+        , BulletList+            [ [ Para [ Str "FreeBSD" ] ] , [ Para [ Str "NetBSD" ] ] ]+        ]+      ]+  , Para [ Str "With" , Space , Str "spacing" ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [ Str "Linux" ]+        , BulletList+            [ [ Para [ Str "Fedora" ] ]+            , [ Para [ Str "Ubuntu" ] ]+            , [ Para [ Str "Slackware" ] ]+            ]+        ]+      , [ Para [ Str "BSD" ]+        , BulletList+            [ [ Para [ Str "FreeBSD" ] ] , [ Para [ Str "NetBSD" ] ] ]+        ]+      ]+  , Para+      [ Str "With" , Space , Str "number" , Space , Str "styles" ]+  , OrderedList+      ( 5 , LowerRoman , DefaultDelim )+      [ [ Para [ Str "Five" ] ]+      , [ Para [ Str "Six" ]+        , OrderedList+            ( 1 , LowerAlpha , DefaultDelim )+            [ [ Para [ Str "a" ] ]+            , [ Para [ Str "b" ] ]+            , [ Para [ Str "c" ] ]+            ]+        ]+      , [ Para [ Str "Seven" ] ]+      ]+  , Para [ Str "Checklist" ]+  , BulletList+      [ [ Para [ Str "\9746" , Space , Str "checked" ] ]+      , [ Para+            [ Str "\9746" , Space , Str "also" , Space , Str "checked" ]+        ]+      , [ Para+            [ Str "\9744" , Space , Str "not" , Space , Str "checked" ]+        ]+      , [ Para+            [ Str "normal" , Space , Str "list" , Space , Str "item" ]+        ]+      ]+  , Para+      [ Str "Separate"+      , Space+      , Str "lists"+      , Space+      , Str "with"+      , Space+      , Str "block"+      , Space+      , Str "attribute"+      ]+  , BulletList+      [ [ Para [ Str "Apples" ] ]+      , [ Para [ Str "Oranges" ]+        , OrderedList+            ( 1 , DefaultStyle , DefaultDelim )+            [ [ Para [ Str "Wash" ] ] , [ Para [ Str "Slice" ] ] ]+        ]+      ]+  , Para [ Str "Multiline" , Space , Str "items" ]+  , BulletList+      [ [ Para+            [ Str "Blah"+            , Space+            , Str "blah."+            , SoftBreak+            , Str "Blah"+            , Space+            , Str "blah."+            ]+        ]+      , [ Para+            [ Str "The"+            , Space+            , Str "document"+            , Space+            , Str "header"+            , Space+            , Str "in"+            , Space+            , Str "AsciiDoc"+            , Space+            , Str "is"+            , Space+            , Str "optional."+            , SoftBreak+            , Str "If"+            , Space+            , Str "present,"+            , Space+            , Str "it"+            , Space+            , Str "must"+            , Space+            , Str "start"+            , Space+            , Str "with"+            , Space+            , Str "a"+            , Space+            , Str "document"+            , Space+            , Str "title."+            ]+        ]+      ]+  , BulletList+      [ [ Para+            [ Str "Optional"+            , Space+            , Str "author"+            , Space+            , Str "and"+            , Space+            , Str "revision"+            , Space+            , Str "information"+            , Space+            , Str "lines"+            , SoftBreak+            , Str "immediately"+            , Space+            , Str "follow"+            , Space+            , Str "the"+            , Space+            , Str "document"+            , Space+            , Str "title."+            ]+        ]+      ]+  , BulletList+      [ [ Para+            [ Str "The"+            , Space+            , Str "document"+            , Space+            , Str "header"+            , Space+            , Str "must"+            , Space+            , Str "be"+            , Space+            , Str "separated"+            , Space+            , Str "from"+            , SoftBreak+            , Str "the"+            , Space+            , Str "remainder"+            , Space+            , Str "of"+            , Space+            , Str "the"+            , Space+            , Str "document"+            , Space+            , Str "by"+            , Space+            , Str "one"+            , Space+            , Str "or"+            , Space+            , Str "more"+            , SoftBreak+            , Str "empty"+            , Space+            , Str "lines"+            , Space+            , Str "and"+            , Space+            , Str "it"+            , Space+            , Str "cannot"+            , Space+            , Str "contain"+            , Space+            , Str "empty"+            , Space+            , Str "lines."+            ]+        ]+      ]+  , Para [ Str "Complex" , Space , Str "item" ]+  , BulletList+      [ [ Para+            [ Str "The"+            , Space+            , Str "header"+            , Space+            , Str "in"+            , Space+            , Str "AsciiDoc"+            , Space+            , Str "must"+            , Space+            , Str "start"+            , Space+            , Str "with"+            , Space+            , Str "a"+            , Space+            , Str "document"+            , Space+            , Str "title."+            ]+        , CodeBlock ( "" , [] , [] ) "= Document Title"+        , Para+            [ Str "Keep"+            , Space+            , Str "in"+            , Space+            , Str "mind"+            , Space+            , Str "that"+            , Space+            , Str "the"+            , Space+            , Str "header"+            , Space+            , Str "is"+            , Space+            , Str "optional."+            ]+        ]+      , [ Para+            [ Str "Optional"+            , Space+            , Str "author"+            , Space+            , Str "and"+            , Space+            , Str "revision"+            , Space+            , Str "information"+            , Space+            , Str "lines"+            , Space+            , Str "immediately"+            , Space+            , Str "follow"+            , Space+            , Str "the"+            , Space+            , Str "document"+            , SoftBreak+            , Str "title."+            ]+        , CodeBlock+            ( "" , [] , [] )+            "= Document Title\nDoc Writer <doc.writer@asciidoc.org>\nv1.0, 2022-01-01"+        ]+      , [ Para [ Str "Second" , Space , Str "item" ] ]+      ]+  , Para+      [ Str "Empty"+      , Space+      , Str "principle"+      , Space+      , Str "element:"+      ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ Para [] , CodeBlock ( "" , [] , [] ) "test" ] ]+  , Header 2 ( "_table" , [] , [] ) [ Str "Table" ]+  , Header+      3+      ( "_simple_with_column_specs" , [] , [] )+      [ Str "Simple"+      , Space+      , Str "with"+      , Space+      , Str "column"+      , Space+      , Str "specs"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidth 0.375 )+      , ( AlignDefault , ColWidth 0.25 )+      , ( AlignDefault , ColWidth 0.375 )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "placed"+                     , Space+                     , Str "in"+                     , Space+                     , Str "the"+                     , Space+                     , Str "first"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "of"+                     , Space+                     , Str "column"+                     , Space+                     , Str "1"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "line"+                     , Space+                     , Str "starts"+                     , Space+                     , Str "with"+                     , Space+                     , Str "a"+                     , Space+                     , Str "vertical"+                     , Space+                     , Str "bar"+                     , Space+                     , Str "so"+                     , Space+                     , Str "this"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "placed"+                     , Space+                     , Str "in"+                     , Space+                     , Str "a"+                     , Space+                     , Str "new"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "in"+                     , SoftBreak+                     , Str "column"+                     , Space+                     , Str "2"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "When"+                     , Space+                     , Str "the"+                     , Space+                     , Str "processor"+                     , Space+                     , Str "encounters"+                     , Space+                     , Str "a"+                     , Space+                     , Str "whitespace"+                     , Space+                     , Str "followed"+                     , Space+                     , Str "by"+                     , Space+                     , Str "a"+                     , Space+                     , Str "vertical"+                     , Space+                     , Str "bar"+                     , Space+                     , Str "it"+                     , SoftBreak+                     , Str "ends"+                     , Space+                     , Str "the"+                     , Space+                     , Str "previous"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "and"+                     , Space+                     , Str "starts"+                     , Space+                     , Str "a"+                     , Space+                     , Str "new"+                     , Space+                     , Str "cell"+                     ]+                 ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot ( "" , [] , [] ) [])+  , Header+      3+      ( "_repeated_column_in_specs" , [] , [] )+      [ Str "Repeated"+      , Space+      , Str "column"+      , Space+      , Str "in"+      , Space+      , Str "specs"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignRight+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Strong+                         [ Str "This"+                         , Space+                         , Str "cell\8217s"+                         , Space+                         , Str "specifier"+                         , Space+                         , Str "indicates"+                         , Space+                         , Str "that"+                         , Space+                         , Str "this"+                         , Space+                         , Str "cell\8217s"+                         , Space+                         , Str "content"+                         , Space+                         , Str "is"+                         , Space+                         , Str "right-aligned"+                         , Space+                         , Str "and"+                         , Space+                         , Str "bold."+                         ]+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "The"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "specifier"+                     , Space+                     , Str "on"+                     , Space+                     , Str "this"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "hasn\8217t"+                     , Space+                     , Str "been"+                     , Space+                     , Str "set"+                     , Space+                     , Str "explicitly,"+                     , Space+                     , Str "so"+                     , Space+                     , Str "the"+                     , Space+                     , Str "default"+                     , SoftBreak+                     , Str "properties"+                     , Space+                     , Str "are"+                     , Space+                     , Str "applied."+                     ]+                 ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot ( "" , [] , [] ) [])+  , Header+      3+      ( "_simple_without_column_specs" , [] , [] )+      [ Str "Simple"+      , Space+      , Str "without"+      , Space+      , Str "column"+      , Space+      , Str "specs"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "3"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "3"+                     ]+                 ]+             ]+         ])+  , Header+      3+      ( "_with_caption" , [] , [] )+      [ Str "With" , Space , Str "caption" ]+  , Table+      ( "" , [] , [] )+      (Caption+         Nothing+         [ Plain+             [ Str "My" , Space , Str "cool" , Space , Str "table." ]+         ])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "3"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "3"+                     ]+                 ]+             ]+         ])+  , Header+      3+      ( "_no_header" , [] , [] )+      [ Str "No" , Space , Str "header" ]+  , Para+      [ Str "By"+      , Space+      , Str "default"+      , Space+      , Str "the"+      , Space+      , Str "first"+      , Space+      , Str "line"+      , Space+      , Str "should"+      , Space+      , Str "turn"+      , Space+      , Str "into"+      , Space+      , Str "the"+      , Space+      , Str "header,"+      , Space+      , Str "but"+      , Space+      , Str "this"+      , SoftBreak+      , Str "can"+      , Space+      , Str "be"+      , Space+      , Str "disabled:"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead ( "" , [] , [] ) [])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "1"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "1"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "2"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "2"+                     ]+                 ]+             ]+         ])+  , Para+      [ Str "And"+      , Space+      , Str "also"+      , Space+      , Str "explicitly"+      , Space+      , Str "enabled:"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Cell" , Space , Str "A1" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Cell" , Space , Str "B1" ] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para [ Str "Cell" , Space , Str "A2" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para [ Str "Cell" , Space , Str "B2" ] ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Cell" , Space , Str "A3" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Cell" , Space , Str "B3" ] ]+             ]+         ])+  , Header 3 ( "_footer" , [] , [] ) [ Str "Footer" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidth 0.4 )+      , ( AlignDefault , ColWidth 0.4 )+      , ( AlignDefault , ColWidth 0.2 )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "3,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "3,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "footer"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "footer"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "3,"+                     , Space+                     , Str "footer"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+  , Para [ Str "or" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "1,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "3"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "2,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "3"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "footer"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "footer"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+  , Header 3 ( "_alignment" , [] , [] ) [ Str "Alignment" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Column" , Space , Str "Name" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Column" , Space , Str "Name" ] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignCenter+                  (RowSpan 1)+                  (ColSpan 2)+                  [ Para+                      [ Str "This"+                      , Space+                      , Str "cell"+                      , Space+                      , Str "spans"+                      , Space+                      , Str "two"+                      , Space+                      , Str "columns,"+                      , Space+                      , Str "and"+                      , Space+                      , Str "its"+                      , Space+                      , Str "content"+                      , Space+                      , Str "is"+                      , Space+                      , Str "horizontally"+                      , Space+                      , Str "centered"+                      , Space+                      , Str "because"+                      , Space+                      , Str "the"+                      , SoftBreak+                      , Str "cell"+                      , Space+                      , Str "specifier"+                      , Space+                      , Str "includes"+                      , Space+                      , Str "the"+                      , Space+                      , Code ( "" , [] , [] ) "^"+                      , Space+                      , Str "operator."+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignCenter+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "duplicated"+                     , Space+                     , Str "in"+                     , Space+                     , Str "two"+                     , Space+                     , Str "adjacent"+                     , Space+                     , Str "columns."+                     , SoftBreak+                     , Str "Its"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "horizontally"+                     , Space+                     , Str "centered"+                     , Space+                     , Str "because"+                     , Space+                     , Str "the"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "specifier"+                     , SoftBreak+                     , Str "includes"+                     , Space+                     , Str "the"+                     , Space+                     , Code ( "" , [] , [] ) "^"+                     , Space+                     , Str "operator."+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignCenter+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "duplicated"+                     , Space+                     , Str "in"+                     , Space+                     , Str "two"+                     , Space+                     , Str "adjacent"+                     , Space+                     , Str "columns."+                     , SoftBreak+                     , Str "Its"+                     , Space+                     , Str "content"+                     , Space+                     , Str "is"+                     , Space+                     , Str "horizontally"+                     , Space+                     , Str "centered"+                     , Space+                     , Str "because"+                     , Space+                     , Str "the"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "specifier"+                     , SoftBreak+                     , Str "includes"+                     , Space+                     , Str "the"+                     , Space+                     , Code ( "" , [] , [] ) "^"+                     , Space+                     , Str "operator."+                     ]+                 ]+             ]+         ])+  , Header+      3+      ( "_multiple_paragraphs_in_cells" , [] , [] )+      [ Str "Multiple"+      , Space+      , Str "paragraphs"+      , Space+      , Str "in"+      , Space+      , Str "cells"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault ) ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Single"+                     , Space+                     , Str "paragraph"+                     , Space+                     , Str "on"+                     , Space+                     , Str "row"+                     , Space+                     , Str "1"+                     ]+                 ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "First"+                     , Space+                     , Str "paragraph"+                     , Space+                     , Str "on"+                     , Space+                     , Str "row"+                     , Space+                     , Str "2"+                     ]+                 , Para+                     [ Str "Second"+                     , Space+                     , Str "paragraph"+                     , Space+                     , Str "on"+                     , Space+                     , Str "row"+                     , Space+                     , Str "2"+                     ]+                 ]+             ]+         ])+  , Header+      3+      ( "_complex_table" , [] , [] )+      [ Str "Complex" , Space , Str "table" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignRight+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Code ( "" , [] , [] ) "This"+                     , Space+                     , Code ( "" , [] , [] ) "content"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "duplicated"+                     , Space+                     , Code ( "" , [] , [] ) "across"+                     , Space+                     , Code ( "" , [] , [] ) "two"+                     , Space+                     , Code ( "" , [] , [] ) "columns."+                     ]+                 , Para+                     [ Code ( "" , [] , [] ) "It"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "aligned"+                     , Space+                     , Code ( "" , [] , [] ) "right"+                     , Space+                     , Code ( "" , [] , [] ) "horizontally."+                     ]+                 , Para+                     [ Code ( "" , [] , [] ) "And"+                     , Space+                     , Code ( "" , [] , [] ) "it"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "monospaced."+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignRight+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Code ( "" , [] , [] ) "This"+                     , Space+                     , Code ( "" , [] , [] ) "content"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "duplicated"+                     , Space+                     , Code ( "" , [] , [] ) "across"+                     , Space+                     , Code ( "" , [] , [] ) "two"+                     , Space+                     , Code ( "" , [] , [] ) "columns."+                     ]+                 , Para+                     [ Code ( "" , [] , [] ) "It"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "aligned"+                     , Space+                     , Code ( "" , [] , [] ) "right"+                     , Space+                     , Code ( "" , [] , [] ) "horizontally."+                     ]+                 , Para+                     [ Code ( "" , [] , [] ) "And"+                     , Space+                     , Code ( "" , [] , [] ) "it"+                     , Space+                     , Code ( "" , [] , [] ) "is"+                     , Space+                     , Code ( "" , [] , [] ) "monospaced."+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignCenter+                  (RowSpan 2)+                  (ColSpan 1)+                  [ Para+                      [ Strong+                          [ Str "This"+                          , Space+                          , Str "cell"+                          , Space+                          , Str "spans"+                          , Space+                          , Str "3"+                          , Space+                          , Str "rows."+                          , Space+                          , Str "The"+                          , Space+                          , Str "content"+                          , Space+                          , Str "is"+                          , Space+                          , Str "centered"+                          , Space+                          , Str "horizontally,"+                          , Space+                          , Str "aligned"+                          , Space+                          , Str "to"+                          , Space+                          , Str "the"+                          , Space+                          , Str "bottom"+                          , Space+                          , Str "of"+                          , Space+                          , Str "the"+                          , Space+                          , Str "cell,"+                          , Space+                          , Str "and"+                          , Space+                          , Str "strong."+                          ]+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Emph+                          [ Str "This"+                          , Space+                          , Str "content"+                          , Space+                          , Str "is"+                          , Space+                          , Str "emphasized."+                          ]+                      ]+                  ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ CodeBlock+                      ( "" , [] , [] )+                      "This content is aligned to the top of the cell and literal.\n\n"+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ CodeBlock+                     ( "" , [] , [] ) "puts \"This is a source block!\""+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 []+             ]+         ])+  , Header+      3+      ( "_column_styles" , [] , [] )+      [ Str "Column" , Space , Str "styles" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Code ( "" , [] , [] ) "monospace" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Code ( "" , [] , [] ) "mono" ] ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "default" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Code ( "" , [] , [] ) "mono" ] ]+             ]+         ])+  , Header+      3+      ( "_block_elements_in_cells" , [] , [] )+      [ Str "Block"+      , Space+      , Str "elements"+      , Space+      , Str "in"+      , Space+      , Str "cells"+      ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Normal" , Space , Str "Style" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "AsciiDoc" , Space , Str "Style" ] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "This"+                      , Space+                      , Str "cell"+                      , Space+                      , Str "isn\8217t"+                      , Space+                      , Str "prefixed"+                      , Space+                      , Str "with"+                      , Space+                      , Str "an"+                      , Space+                      , Code ( "" , [] , [] ) "a"+                      , Str ","+                      , Space+                      , Str "so"+                      , Space+                      , Str "the"+                      , Space+                      , Str "processor"+                      , Space+                      , Str "doesn\8217t"+                      , Space+                      , Str "interpret"+                      , Space+                      , Str "the"+                      , SoftBreak+                      , Str "following"+                      , Space+                      , Str "lines"+                      , Space+                      , Str "as"+                      , Space+                      , Str "an"+                      , Space+                      , Str "AsciiDoc"+                      , Space+                      , Str "list."+                      ]+                  , Para+                      [ Str "*"+                      , Space+                      , Str "List"+                      , Space+                      , Str "item"+                      , Space+                      , Str "1"+                      , SoftBreak+                      , Str "*"+                      , Space+                      , Str "List"+                      , Space+                      , Str "item"+                      , Space+                      , Str "2"+                      , SoftBreak+                      , Str "*"+                      , Space+                      , Str "List"+                      , Space+                      , Str "item"+                      , Space+                      , Str "3"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "This"+                      , Space+                      , Str "cell"+                      , Space+                      , Str "is"+                      , Space+                      , Str "prefixed"+                      , Space+                      , Str "with"+                      , Space+                      , Str "an"+                      , Space+                      , Code ( "" , [] , [] ) "a"+                      , Str ","+                      , Space+                      , Str "so"+                      , Space+                      , Str "the"+                      , Space+                      , Str "processor"+                      , Space+                      , Str "interprets"+                      , Space+                      , Str "the"+                      , Space+                      , Str "following"+                      , Space+                      , Str "lines"+                      , SoftBreak+                      , Str "as"+                      , Space+                      , Str "an"+                      , Space+                      , Str "AsciiDoc"+                      , Space+                      , Str "list."+                      ]+                  , BulletList+                      [ [ Para+                            [ Str "List"+                            , Space+                            , Str "item"+                            , Space+                            , Str "1"+                            ]+                        ]+                      , [ Para+                            [ Str "List"+                            , Space+                            , Str "item"+                            , Space+                            , Str "2"+                            ]+                        ]+                      , [ Para+                            [ Str "List"+                            , Space+                            , Str "item"+                            , Space+                            , Str "3"+                            ]+                        ]+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "isn\8217t"+                     , Space+                     , Str "prefixed"+                     , Space+                     , Str "with"+                     , Space+                     , Str "an"+                     , Space+                     , Code ( "" , [] , [] ) "a"+                     , Str ","+                     , Space+                     , Str "so"+                     , Space+                     , Str "the"+                     , Space+                     , Str "processor"+                     , Space+                     , Str "doesn\8217t"+                     , Space+                     , Str "interpret"+                     , Space+                     , Str "the"+                     , Space+                     , Str "listing"+                     , SoftBreak+                     , Str "block"+                     , Space+                     , Str "delimiters"+                     , Space+                     , Str "or"+                     , Space+                     , Str "the"+                     , Space+                     , Code ( "" , [] , [] ) "source"+                     , Space+                     , Str "style."+                     ]+                 , Para+                     [ Str "----"+                     , SoftBreak+                     , Str "import"+                     , Space+                     , Str "os"+                     , SoftBreak+                     , Str "print"+                     , Space+                     , Str "(\"%s\""+                     , Space+                     , Str "%(os.uname()))"+                     , SoftBreak+                     , Str "----"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "This"+                     , Space+                     , Str "cell"+                     , Space+                     , Str "is"+                     , Space+                     , Str "prefixed"+                     , Space+                     , Str "with"+                     , Space+                     , Str "an"+                     , Space+                     , Code ( "" , [] , [] ) "a"+                     , Str ","+                     , Space+                     , Str "so"+                     , Space+                     , Str "the"+                     , Space+                     , Str "listing"+                     , Space+                     , Str "block"+                     , Space+                     , Str "is"+                     , Space+                     , Str "processed"+                     , Space+                     , Str "and"+                     , Space+                     , Str "rendered"+                     , SoftBreak+                     , Str "according"+                     , Space+                     , Str "to"+                     , Space+                     , Str "the"+                     , Space+                     , Code ( "" , [] , [] ) "source"+                     , Space+                     , Str "style"+                     , Space+                     , Str "rules."+                     ]+                 , CodeBlock+                     ( "" , [ "python" ] , [] )+                     "import os\nprint \"%s\" %(os.uname())"+                 ]+             ]+         ])+  , Header+      3+      ( "_col_and_rowspan" , [] , [] )+      [ Str "Col" , Space , Str "and" , Space , Str "rowspan" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "1,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "2,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para+                     [ Str "Column"+                     , Space+                     , Str "3,"+                     , Space+                     , Str "header"+                     , Space+                     , Str "row"+                     ]+                 ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 2)+                  (ColSpan 2)+                  [ Para+                      [ Str "This"+                      , Space+                      , Str "cell"+                      , Space+                      , Str "spans"+                      , Space+                      , Str "2"+                      , Space+                      , Str "cols"+                      , Space+                      , Str "and"+                      , Space+                      , Str "2"+                      , Space+                      , Str "rows"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "3,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "2"+                      ]+                  ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para+                      [ Str "Cell"+                      , Space+                      , Str "in"+                      , Space+                      , Str "column"+                      , Space+                      , Str "3,"+                      , Space+                      , Str "row"+                      , Space+                      , Str "3"+                      ]+                  ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 3)+                 [ Para+                     [ Str "Cell"+                     , Space+                     , Str "in"+                     , Space+                     , Str "column"+                     , Space+                     , Str "1-3,"+                     , Space+                     , Str "row"+                     , Space+                     , Str "4"+                     ]+                 ]+             ]+         ])+  , Header+      3+      ( "_csv_table" , [] , [] )+      [ Str "CSV" , Space , Str "table" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Artist" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Track" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Genre" ] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para [ Str "Baauer" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para [ Str "Harlem" , Space , Str "Shake" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Para [ Str "Hip" , Space , Str "Hop" ] ]+              ]+          ]+      ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "The" , Space , Str "Lumineers" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Ho" , Space , Str "Hey" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Folk" , Space , Str "Rock" ] ]+             ]+         ])+  , Para [ Str "or" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Artist" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Track" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Genre" ] ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Baauer" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Harlem" , Space , Str "Shake" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Hip" , Space , Str "Hop" ] ]+             ]+         ])+  , Header+      3+      ( "_dsv_table" , [] , [] )+      [ Str "DSV" , Space , Str "table" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "a" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "b" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "c" ] ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "d" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "e" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "f" ] ]+             ]+         ])+  , Para [ Str "or" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Artist" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Track" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Genre" ] ]+             ]+         ])+      [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]+      (TableFoot+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Robyn" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Indestructible" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Para [ Str "Dance" ] ]+             ]+         ])+  , Header+      2+      ( "_definition_list" , [] , [] )+      [ Str "Definition" , Space , Str "list" ]+  , DefinitionList+      [ ( [ Str "CPU" ]+        , [ [ Para+                [ Str "The"+                , Space+                , Str "brain"+                , Space+                , Str "of"+                , Space+                , Str "the"+                , Space+                , Str "computer."+                ]+            ]+          ]+        )+      , ( [ Str "Hard" , Space , Str "drive" ]+        , [ [ Para+                [ Str "Permanent"+                , Space+                , Str "storage"+                , Space+                , Str "for"+                , Space+                , Str "operating"+                , Space+                , Str "system"+                , Space+                , Str "and/or"+                , Space+                , Str "user"+                , Space+                , Str "files."+                ]+            ]+          ]+        )+      ]+  , Para [ Str "Mixed" ]+  , DefinitionList+      [ ( [ Str "Dairy" ]+        , [ [ BulletList+                [ [ Para [ Str "Milk" ] ]+                , [ Para [ Str "Eggs" ]+                  , DefinitionList [ ( [ Str "Bakery" ] , [ [] ] ) ]+                  ]+                , [ Para [ Str "Bread" ]+                  , DefinitionList [ ( [ Str "Produce" ] , [ [] ] ) ]+                  ]+                , [ Para [ Str "Bananas" ] ]+                ]+            ]+          ]+        )+      ]+  , Para [ Str "With" , Space , Str "spaces" ]+  , DefinitionList [ ( [ Str "Dairy" ] , [ [] ] ) ]+  , BulletList+      [ [ Para [ Str "Milk" ] ] , [ Para [ Str "Eggs" ] ] ]+  , DefinitionList [ ( [ Str "Bakery" ] , [ [] ] ) ]+  , BulletList [ [ Para [ Str "Bread" ] ] ]+  , DefinitionList [ ( [ Str "Produce" ] , [ [] ] ) ]+  , BulletList [ [ Para [ Str "Bananas" ] ] ]+  , Para [ Str "Nested" ]+  , DefinitionList+      [ ( [ Str "Operating" , Space , Str "Systems" ]+        , [ [ DefinitionList+                [ ( [ Str "Linux" ]+                  , [ [ OrderedList+                          ( 1 , DefaultStyle , DefaultDelim )+                          [ [ Para [ Str "Fedora" ]+                            , BulletList [ [ Para [ Str "Desktop" ] ] ]+                            ]+                          , [ Para [ Str "Ubuntu" ]+                            , BulletList+                                [ [ Para [ Str "Desktop" ] ]+                                , [ Para [ Str "Server" ] ]+                                ]+                            ]+                          ]+                      ]+                    ]+                  )+                , ( [ Str "BSD" ]+                  , [ [ OrderedList+                          ( 1 , DefaultStyle , DefaultDelim )+                          [ [ Para [ Str "FreeBSD" ] ]+                          , [ Para [ Str "NetBSD" ]+                            , DefinitionList+                                [ ( [ Str "Cloud"+                                    , Space+                                    , Str "Providers"+                                    ]+                                  , [ [ DefinitionList+                                          [ ( [ Str "PaaS" ] , [ [] ] )+                                          ]+                                      ]+                                    ]+                                  )+                                ]+                            ]+                          , [ Para [ Str "OpenShift" ] ]+                          , [ Para [ Str "CloudBees" ] ]+                          ]+                      ]+                    ]+                  )+                , ( [ Str "IaaS" ]+                  , [ [ OrderedList+                          ( 1 , DefaultStyle , DefaultDelim )+                          [ [ Para [ Str "Amazon" , Space , Str "EC2" ]+                            ]+                          ]+                      ]+                    ]+                  )+                ]+            , Para+                [ Str "This"+                , Space+                , Str "just"+                , Space+                , Str "affects"+                , Space+                , Str "the"+                , Space+                , Str "output:"+                ]+            ]+          ]+        )+      ]+  , Div+      ( ""+      , []+      , [ ( "wrapper" , "1" )+        , ( "itemwidth" , "75" )+        , ( "labelwidth" , "25" )+        ]+      )+      [ DefinitionList+          [ ( [ Str "CPU" ]+            , [ [ Para+                    [ Str "The"+                    , Space+                    , Str "brain"+                    , Space+                    , Str "of"+                    , Space+                    , Str "the"+                    , Space+                    , Str "computer."+                    ]+                ]+              ]+            )+          , ( [ Str "RAM" ]+            , [ [ Para+                    [ Str "Temporarily"+                    , Space+                    , Str "stores"+                    , Space+                    , Str "information"+                    , Space+                    , Str "the"+                    , Space+                    , Str "CPU"+                    , Space+                    , Str "uses"+                    , Space+                    , Str "during"+                    , Space+                    , Str "operation."+                    ]+                ]+              ]+            )+          ]+      ]+  , Para [ Str "Q&A" , Space , Str "list" ]+  , DefinitionList+      [ ( [ Str "What"+          , Space+          , Str "is"+          , Space+          , Str "the"+          , Space+          , Str "answer?"+          ]+        , [ [ Para+                [ Str "This"+                , Space+                , Str "is"+                , Space+                , Str "the"+                , Space+                , Str "answer."+                ]+            ]+          ]+        )+      , ( [ Str "Are"+          , Space+          , Str "cameras"+          , Space+          , Str "allowed?"+          ]+        , [ [] ]+        )+      , ( [ Str "Are"+          , Space+          , Str "backpacks"+          , Space+          , Str "allowed?"+          ]+        , [ [ Para [ Str "No." ] ] ]+        )+      ]+  , Para+      [ Str "Ordered"+      , Space+      , Str "description"+      , Space+      , Str "list"+      , Space+      , Str "(with"+      , Space+      , Str "numbers)"+      ]+  , OrderedList+      ( 1 , DefaultStyle , DefaultDelim )+      [ [ DefinitionList+            [ ( [ Str "&" ] , [ [ Para [ Str "ampersand" ] ] ] ) ]+        ]+      , [ DefinitionList+            [ ( [ Str ">" ]+              , [ [ Para [ Str "greater" , Space , Str "than" ] ] ]+              )+            ]+        ]+      ]+  , Header+      2+      ( "_block_macros" , [] , [] )+      [ Str "Block" , Space , Str "macros" ]+  , Figure+      ( "" , [] , [] )+      (Caption Nothing [])+      [ Plain+          [ Image+              ( ""+              , []+              , [ ( "width" , "300px" ) , ( "height" , "200px" ) ]+              )+              [ Str "Sunset" ]+              ( "sunset.jpg" , "" )+          ]+      ]+  , Plain+      [ Image+          ( "" , [] , [] )+          [ Str "mymovie.mp4" ]+          ( "mymovie.mp4" , "" )+      ]+  , Plain+      [ Image+          ( "" , [] , [] ) [ Str "mysong.mp3" ] ( "mysong.mp3" , "" )+      ]+  , Div ( "toc" , [] , [] ) []+  , Div+      ( ""+      , [ "included" ]+      , [ ( "path" , "asciidoc-reader-include.adoc" ) ]+      )+      [ Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "a"+          , Space+          , Str "test!"+          ]+      , OrderedList+          ( 1 , DefaultStyle , DefaultDelim )+          [ [ Para [ Str "one" ]+            , OrderedList+                ( 1 , DefaultStyle , DefaultDelim )+                [ [ Para [ Str "two" ] ] ]+            ]+          ]+      ]+  ]
+ test/command/10149.md view
@@ -0,0 +1,296 @@+Row spans+```+% pandoc -f html --columns 24 -t ansi+<table>+  <thead>+    <tr>+      <td rowspan="3">1</td>+      <td>2</td>+      <td>3</td>+      <td>4</td>+      <td rowspan="4">5</td>+      <td>6</td>+    </tr>+    <tr>+      <td>2</td>+      <td colspan="2" rowspan="2">3</td>+      <td>6</td>+    </tr>+    <tr>+      <td rowspan="2">2</td>+      <td>6</td>+    </tr>+    <tr>+      <td>1</td>+      <td>3</td>+      <td>4</td>+      <td>6</td>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td colspan="2">a</td>+      <td rowspan="2">c</td>+      <td>d</td>+      <td>e</td>+      <td>f</td>+    </tr>+    <tr>+      <td>a</td>+      <td>b</td>+      <td colspan="3" rowspan="2">d</td>+    </tr>+    <tr>+      <td>a</td>+      <td>b</td>+      <td>c</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td colspan="2" rowspan="4">A</td>+      <td>C</td>+      <td>D</td>+      <td colspan="2" rowspan="3">E</td>+    </tr>+    <tr>+      <td>C</td>+      <td>D</td>+    </tr>+    <tr>+      <td>C</td>+      <td>D</td>+    </tr>+    <tr>+      <td>C</td>+      <td>D</td>+      <td>E</td>+      <td>F</td>+    </tr>+  </tfoot>+</table>+^D+1   2   3   4   5   6+    2   3           6+    2               6+1       3   4       6+─── ─── ─── ─── ─── ───+a       c   d   e   f+a   b       d+a   b   c+─── ─── ─── ─── ─── ───+A       C   D   E+        C   D+        C   D+        C   D   E   F[0m]8;;\+```++Empty rows+```+% pandoc -f native --columns 12 -t ansi+[ Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 3)+               (ColSpan 2)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "3" ] ]+           ]+       , Row ( "" , [] , [] ) []+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "3" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 2)+                (ColSpan 1)+                [ Plain [ Str "3" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 4)+                (ColSpan 1)+                [ Plain [ Str "2" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "3" ] ]+            ]+        , Row ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "3" ] ]+            ]+        ]+    ]+    (TableFoot+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "3" ] ]+           ]+       , Row ( "" , [] , [] ) []+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 3)+               (ColSpan 1)+               [ Plain [ Str "3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "2" ] ]+           ]+       , Row ( "" , [] , [] ) []+       ])+]+^D+1       3+        3+1   2   3+─── ─── ───+1   2   3+1   2+1       3+1       3+─── ─── ───+1   2   3+1   2   3+1   2[0m]8;;\+```
+ test/command/11253.md view
@@ -0,0 +1,27 @@+```+% pandoc -f markdown -t native+\ifstrequal{hello}{hello}{TRUE}{FALSE}+\ifstrequal{hello}{world}{TRUE}{FALSE}+^D+[ Para+    [ RawInline (Format "tex") "TRUE"+    , SoftBreak+    , RawInline (Format "tex") "FALSE"+    ]+]+```++```+% pandoc -f markdown-latex_macros -t native+\ifstrequal{hello}{hello}{TRUE}{FALSE}+\ifstrequal{hello}{world}{TRUE}{FALSE}+^D+[ Para+    [ RawInline+        (Format "tex") "\\ifstrequal{hello}{hello}{TRUE}{FALSE}"+    , SoftBreak+    , RawInline+        (Format "tex") "\\ifstrequal{hello}{world}{TRUE}{FALSE}"+    ]+]+```
+ test/command/11266.md view
@@ -0,0 +1,19 @@+```+% pandoc -t latex+$$+\begin{eqnarray}+S &\rightarrow& a A                      \nonumber \\+A &\rightarrow& d B \ | \ b A \ | \ c A  \nonumber \\+B &\rightarrow& a c \ | \ b C \ | \ c A  \nonumber \\+C &\rightarrow& \epsilon                 \nonumber+\end{eqnarray}+$$+^D++\begin{eqnarray}+S &\rightarrow& a A                      \nonumber \\+A &\rightarrow& d B \ | \ b A \ | \ c A  \nonumber \\+B &\rightarrow& a c \ | \ b C \ | \ c A  \nonumber \\+C &\rightarrow& \epsilon                 \nonumber+\end{eqnarray}+```
+ test/command/11270.md view
@@ -0,0 +1,25 @@+```+% pandoc -f markdown -t native -s+---+header-includes: |+    \makeatletter+    \beamer@ignorenonframefalse+    \makeatother+...++^D+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "header-includes"+            , MetaBlocks+                [ RawBlock+                    (Format "tex")+                    "\\makeatletter\n\\beamer@ignorenonframefalse\n\\makeatother"+                ]+            )+          ]+    }+  []+```
+ test/command/11309.md view
@@ -0,0 +1,6 @@+```+% pandoc -f rst -t native+Cho\ **co**\ late+^D+[ Para [ Str "Cho" , Strong [ Str "co" ] , Str "late" ] ]+```
+ test/command/7326.md view
@@ -0,0 +1,1227 @@+Table with row and column spans+```+% pandoc -f html -t asciidoc+<table>+  <colgroup>+    <col style="width: 17%" />+    <col style="width: 16%" />+    <col style="width: 15%" />+    <col style="width: 52%" />+  </colgroup>+  <thead>+    <tr>+      <th>Header 1</th>+      <th>Header 2</th>+      <th>Header 3</th>+      <th>Header 4</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>body row 1</td>+      <td>column 2</td>+      <td>column 3</td>+      <td>column 4</td>+    </tr>+    <tr>+      <td>body row 2</td>+      <td colspan="2">Cells may span columns.</td>+      <td>fff</td>+    </tr>+    <tr>+      <td>body row 3</td>+      <td rowspan="2">Cells may span rows.</td>+      <td rowspan="2">+        <ul>+          <li>Cells</li>+          <li>can</li>+          <li>contain</li>+          <li>blocks.</li>+        </ul>+      </td>+      <td rowspan="2">+        <ul>+          <li>This is a very long line of text</li>+          <li><a href="http://www.python.org/">Python</a></li>+          <li>b</li>+          <li>c</li>+        </ul>+      </td>+    </tr>+    <tr>+      <td>body row 4</td>+    </tr>+  </tbody>+</table>+^D+[width="100%",cols="17%,16%,15%,52%",options="header",]+|===+|Header 1 |Header 2 |Header 3 |Header 4+|body row 1 |column 2 |column 3 |column 4+|body row 2 2+|Cells may span columns. |fff+|body row 3 .2+|Cells may span rows. .2+a|+* Cells+* can+* contain+* blocks.++.2+a|+* This is a very long line of text+* http://www.python.org/[Python]+* b+* c++|body row 4+|===+```++Header and footer.+AsciiDoc only supports 1 header and 1 footer row.+So for multiple header and/or footer rows all the extra rows become part of the table body.+```+% pandoc -f html -t asciidoc+<table>+  <thead>+    <tr>+      <th colspan="2">Inputs</th>+      <th>Output</th>+    </tr>+    <tr>+      <th>A</th>+      <th>B</th>+      <th>A or B</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>False</td>+      <td>False</td>+      <td>False</td>+    </tr>+    <tr>+      <td>True</td>+      <td>False</td>+      <td>True</td>+    </tr>+    <tr>+      <td>False</td>+      <td>True</td>+      <td>True</td>+    </tr>+    <tr>+      <td>True</td>+      <td>True</td>+      <td>True</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td>A</td>+      <td>B</td>+      <td>A or B</td>+    </tr>+    <tr>+      <td colspan="2">Inputs</td>+      <td>Output</td>+    </tr>+  </tfoot>+</table>+<table>+  <thead>+    <tr>+      <th colspan="2">Header</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>Body 1-1</td>+      <td>Body 2-1</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td colspan="2">Footer</td>+    </tr>+  </tfoot>+</table>+^D+[cols=",,",options="header,footer",]+|===+2+|Inputs |Output+|A |B |A or B+|False |False |False+|True |False |True+|False |True |True+|True |True |True+|A |B |A or B+2+|Inputs |Output+|===++[cols=",",options="header,footer",]+|===+2+|Header+|Body 1-1 |Body 2-1+2+|Footer+|===+```++Table without header but with footer rows+```+% pandoc -f html -t asciidoc+<table>+  <colgroup>+    <col style="width: 37%" />+    <col style="width: 37%" />+    <col style="width: 26%" />+  </colgroup>+  <tbody>+    <tr>+      <td>False</td>+      <td>False</td>+      <td>False</td>+    </tr>+    <tr>+      <td>True</td>+      <td>False</td>+      <td>True</td>+    </tr>+    <tr>+      <td>False</td>+      <td>True</td>+      <td>True</td>+    </tr>+    <tr>+      <td>True</td>+      <td>True</td>+      <td>True</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td>A</td>+      <td>B</td>+      <td>A or B</td>+    </tr>+    <tr>+      <td colspan="2">Inputs</td>+      <td>Output</td>+    </tr>+  </tfoot>+</table>+^D+[width="100%",cols="37%,37%,26%",options="footer",]+|===+|False |False |False+|True |False |True+|False |True |True+|True |True |True+|A |B |A or B+2+|Inputs |Output+|===+```++Adjust row span for multiple header rows+```+% pandoc -f html -t asciidoc+<table style="width: 63%">+  <colgroup>+    <col style="width: 30%" />+    <col style="width: 11%" />+    <col style="width: 11%" />+    <col style="width: 11%" />+  </colgroup>+  <thead>+    <tr>+      <th rowspan="2">Location</th>+      <th colspan="3">Temperature 1961-1990 in degree Celsius</th>+    </tr>+    <tr>+      <th>min</th>+      <th>mean</th>+      <th>max</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>Antarctica</td>+      <td>-89.2</td>+      <td>N/A</td>+      <td>19.8</td>+    </tr>+    <tr>+      <td>Earth</td>+      <td>-89.2</td>+      <td>14</td>+      <td>56.7</td>+    </tr>+  </tbody>+</table>+<table style="width: 63%">+  <colgroup>+    <col style="width: 11%" />+    <col style="width: 11%" />+    <col style="width: 11%" />+    <col style="width: 30%" />+  </colgroup>+  <thead>+    <tr>+      <th colspan="3">Temperature 1961-1990 in degree Celsius</th>+      <th rowspan="2">Location</th>+    </tr>+    <tr>+      <th>min</th>+      <th>mean</th>+      <th>max</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>-89.2</td>+      <td>N/A</td>+      <td>19.8</td>+      <td>Antarctica</td>+    </tr>+    <tr>+      <td>-89.2</td>+      <td>14</td>+      <td>56.7</td>+      <td>Earth</td>+    </tr>+  </tbody>+</table>+<table style="width: 65%">+  <colgroup>+    <col style="width: 11%" />+    <col style="width: 11%" />+    <col style="width: 11%" />+    <col style="width: 18%" />+    <col style="width: 14%" />+  </colgroup>+  <thead>+    <tr>+      <th colspan="3">Temperature 1961-1990 in degree Celsius</th>+      <th rowspan="2">Location</th>+      <th>Extra</th>+    </tr>+    <tr>+      <th>min</th>+      <th>mean</th>+      <th>max</th>+      <th>Extra 2</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td>-89.2</td>+      <td>N/A</td>+      <td>19.8</td>+      <td>Antarctica</td>+      <td>Extra 3</td>+    </tr>+    <tr>+      <td>-89.2</td>+      <td>14</td>+      <td>56.7</td>+      <td>Earth</td>+      <td>Extra 4</td>+    </tr>+  </tbody>+</table>+<table>+  <thead>+    <tr>+      <th>Header 1-1</th>+      <th colspan="2" rowspan="2">Header 1-2</th>+    </tr>+    <tr>+      <th>Header 2-1</th>+    </tr>+    <tr>+      <th>Header 3-1</th>+      <th>Header 3-2</th>+      <th>Header 3-3</th>+    </tr>+  </thead>+  <tbody>+    <tr>+      <td rowspan="2">Body 1-1</td>+      <td colspan="2">Body 1-2</td>+    </tr>+    <tr>+      <td>Body 2-1</td>+      <td>Body 2-2</td>+    </tr>+  </tbody>+</table>+<table>+  <thead>+    <tr>+      <th rowspan="2">Header 1-1</th>+      <th>Header 1-2</th>+      <th rowspan="2">Header 1-3</th>+    </tr>+    <tr>+      <th>Header 2-1</th>+    </tr>+    <tr>+      <th>Header 3-1</th>+      <th>Header 3-2</th>+      <th>Header 3-3</th>+    </tr>+  </thead>+  <tbody></tbody>+</table>+^D+[width="63%",cols="49%,17%,17%,17%",options="header",]+|===+|Location 3+|Temperature 1961-1990 in degree Celsius+| |min |mean |max+|Antarctica |-89.2 |N/A |19.8+|Earth |-89.2 |14 |56.7+|===++[width="63%",cols="19%,17%,17%,47%",options="header",]+|===+3+|Temperature 1961-1990 in degree Celsius |Location+|min |mean |max |+|-89.2 |N/A |19.8 |Antarctica+|-89.2 |14 |56.7 |Earth+|===++[width="65%",cols="20%,16%,16%,27%,21%",options="header",]+|===+3+|Temperature 1961-1990 in degree Celsius |Location |Extra+|min |mean |max | |Extra 2+|-89.2 |N/A |19.8 |Antarctica |Extra 3+|-89.2 |14 |56.7 |Earth |Extra 4+|===++[cols=",,",options="header",]+|===+|Header 1-1 2+|Header 1-2+|Header 2-1 2+|+|Header 3-1 |Header 3-2 |Header 3-3+.2+|Body 1-1 2+|Body 1-2+|Body 2-1 |Body 2-2+|===++[cols=",,",options="header",]+|===+|Header 1-1 |Header 1-2 |Header 1-3+| |Header 2-1 |+|Header 3-1 |Header 3-2 |Header 3-3+|===+```++Adjust row span in multiple footer rows.+```+% pandoc -f html -t asciidoc+<table>+  <colgroup>+    <col style="width: 40%" />+    <col style="width: 40%" />+    <col style="width: 20%" />+  </colgroup>+  <tbody>+    <tr>+      <td>Body 1-1</td>+      <td>Body 1-2</td>+      <td>Body 1-3</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td colspan="2">Footer 1-1/2</td>+      <td>Footer 1-3</td>+    </tr>+    <tr>+      <td>Footer 2-1</td>+      <td rowspan="3">Span 3</td>+      <td>Footer 2-3</td>+    </tr>+    <tr>+      <td rowspan="2">Span 2</td>+      <td>Footer 3-3</td>+    </tr>+    <tr>+      <td>Footer 4-3</td>+    </tr>+  </tfoot>+</table>+<table>+  <tbody>+    <tr>+      <td>Body 1-1</td>+      <td>Body 1-2</td>+      <td>Body 1-3</td>+      <td>Body 1-4</td>+      <td>Body 1-5</td>+    </tr>+    <tr>+      <td>Body 2-1</td>+      <td>Body 2-2</td>+      <td>Body 2-3</td>+      <td>Body 2-4</td>+      <td>Body 2-5</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td colspan="3">Footer 1-1/2/3</td>+      <td>Footer 1-4</td>+      <td>Footer 1-5</td>+    </tr>+    <tr>+      <td>Footer 2-1</td>+      <td rowspan="3">Span 3</td>+      <td>Footer 2-3</td>+      <td colspan="2">Footer 2-4/5</td>+    </tr>+    <tr>+      <td rowspan="2">Span 2</td>+      <td colspan="2">Footer 3-3/4</td>+      <td rowspan="2">Span 2</td>+    </tr>+    <tr>+      <td rowspan="3">Span 3</td>+      <td>Footer 4-4</td>+    </tr>+    <tr>+      <td>Footer 5-1</td>+      <td>Footer 5-2</td>+      <td>Footer 5-4</td>+      <td rowspan="2">Span 2</td>+    </tr>+    <tr>+      <td colspan="2">Footer 6-1/2</td>+      <td>Footer 6-4</td>+    </tr>+  </tfoot>+</table>+<table>+  <tbody>+    <tr>+      <td>Body 1</td>+      <td>Body 2</td>+      <td>Body 3</td>+      <td>Body 4</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td>Footer 1-1</td>+      <td colspan="2" rowspan="3">Span 3</td>+      <td rowspan="2">Span 2</td>+    </tr>+    <tr>+      <td>Footer 2-1</td>+    </tr>+    <tr>+      <td>Footer 3-1</td>+      <td>Footer 3-4</td>+    </tr>+  </tfoot>+</table>+<table>+  <tbody>+    <tr>+      <td>Body 1-1</td>+      <td>Body 1-2</td>+      <td>Body 1-3</td>+      <td>Body 1-4</td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td colspan="2">Footer 1-1/2</td>+      <td rowspan="6">Span 6</td>+      <td>Footer 1-4</td>+    </tr>+    <tr>+      <td rowspan="3">Span 3</td>+      <td>Footer 2-2</td>+      <td>Footer 2-4</td>+    </tr>+    <tr>+      <td>Footer 3-2</td>+      <td>Footer 3-4</td>+    </tr>+    <tr>+      <td>Footer 4-2</td>+      <td>Footer 4-4</td>+    </tr>+    <tr>+      <td>Footer 5-1</td>+      <td>Footer 5-2</td>+      <td rowspan="2">Span 2</td>+    </tr>+    <tr>+      <td colspan="2">Footer 6-1/2</td>+    </tr>+  </tfoot>+</table>+^D+[width="100%",cols="40%,40%,20%",options="footer",]+|===+|Body 1-1 |Body 1-2 |Body 1-3+2+|Footer 1-1/2 |Footer 1-3+|Footer 2-1 .2+|Span 3 |Footer 2-3+|Span 2 |Footer 3-3+| | |Footer 4-3+|===++[cols=",,,,",options="footer",]+|===+|Body 1-1 |Body 1-2 |Body 1-3 |Body 1-4 |Body 1-5+|Body 2-1 |Body 2-2 |Body 2-3 |Body 2-4 |Body 2-5+3+|Footer 1-1/2/3 |Footer 1-4 |Footer 1-5+|Footer 2-1 .3+|Span 3 |Footer 2-3 2+|Footer 2-4/5+.2+|Span 2 2+|Footer 3-3/4 .2+|Span 2+.2+|Span 3 |Footer 4-4+|Footer 5-1 |Footer 5-2 |Footer 5-4 |Span 2+2+|Footer 6-1/2 | |Footer 6-4 |+|===++[cols=",,,",options="footer",]+|===+|Body 1 |Body 2 |Body 3 |Body 4+|Footer 1-1 2.2+|Span 3 .2+|Span 2+|Footer 2-1+|Footer 3-1 2+| |Footer 3-4+|===++[cols=",,,",options="footer",]+|===+|Body 1-1 |Body 1-2 |Body 1-3 |Body 1-4+2+|Footer 1-1/2 .5+|Span 6 |Footer 1-4+.3+|Span 3 |Footer 2-2 |Footer 2-4+|Footer 3-2 |Footer 3-4+|Footer 4-2 |Footer 4-4+|Footer 5-1 |Footer 5-2 |Span 2+2+|Footer 6-1/2 | |+|===+```++Individual cell alignments+```+% pandoc -f native -t asciidoc+[ Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignLeft+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Left" , Space , Str "Header" ] ]+           , Cell+               ( "" , [] , [] )+               AlignCenter+               (RowSpan 2)+               (ColSpan 2)+               [ Plain [ Str "Center" , Space , Str "Headers" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignRight+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Right" , Space , Str "Header" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignCenter+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Center" , Space , Str "Header" ] ]+           , Cell+               ( "" , [] , [] )+               AlignRight+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Right" , Space , Str "Header" ] ]+           , Cell+               ( "" , [] , [] )+               AlignLeft+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Left" , Space , Str "Header" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignRight+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "Right" , Space , Str "Body" ] ]+           , Cell+               ( "" , [] , [] )+               AlignLeft+               (RowSpan 1)+               (ColSpan 2)+               [ Plain [ Str "Left" , Space , Str "Body" ] ]+           ]+        , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignCenter+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Center" , Space , Str "Body" ] ]+           , Cell+               ( "" , [] , [] )+               AlignRight+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Right" , Space , Str "Body" ] ]+           ]+        ]+    ]+    (TableFoot+        ( "" , [] , [] )+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignCenter+                (RowSpan 1)+                (ColSpan 3)+                [ Plain [ Str "Center" , Space , Str "Footer" ] ]+            ]+        , Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignLeft+                 (RowSpan 1)+                 (ColSpan 2)+                 [ Plain [ Str "Left" , Space , Str "Footer" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignCenter+                 (RowSpan 3)+                 (ColSpan 1)+                 [ Plain [ Str "Center" , Space , Str "Footer" ] ]+             ]+         , Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignRight+                 (RowSpan 1)+                 (ColSpan 2)+                 [ Plain [ Str "Right" , Space , Str "Footer" ] ]+             ]+         , Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignCenter+                 (RowSpan 1)+                 (ColSpan 2)+                 [ Plain [ Str "Center" , Space , Str "Footer" ] ]+             ]+        ])+]+^D+[cols=",,",options="header,footer",]+|===+<|Left Header 2+^|Center Headers+>|Right Header 2+|+^|Center Header >|Right Header <|Left Header+.2+>|Right Body 2+<|Left Body+^|Center Body >|Right Body+3+^|Center Footer+2+<|Left Footer .2+^|Center Footer+2+>|Right Footer+2+^|Center Footer |+|===+```++Adjust row span for empty rows and handle empty rows in general+```+% pandoc -f native -t asciidoc+[ Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "Header" , Space , Str "1-1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 3)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "3" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "Header" , Space , Str "1-3" ] ]+           ]+       , Row ( "" , [] , [] ) []+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Header" , Space , Str "2-1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Header" , Space , Str "2-3" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 3)+                (ColSpan 2)+                [ Plain [ Str "Body" , Space , Str "1-1/2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 5)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "5" ] ]+            ]+        , Row ( "" , [] , [] ) []+        , Row ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "2-1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "2-2" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "3-1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "3-2" ] ]+            ]+        , Row ( "" , [] , [] ) []+        ]+    ]+    (TableFoot+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 5)+               (ColSpan 1)+               [ Plain+                   [ Str "Span" , Space , Str "5" ]+               ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 2)+               [ Plain [ Str "Footer" , Space , Str "1-2" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 2)+               [ Plain+                   [ Str "Span" , Space , Str "2" ]+               ]+           ]+       , Row ( "" , [] , [] ) []+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 2)+               [ Plain [ Str "Footer" , Space , Str "3-2/3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 2)+               [ Plain [ Str "Footer" , Space , Str "4-2/3" ] ]+           ]+       ])+, Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead ( "" , [] , [] ) [])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "1-1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "1-2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 3)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "4" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 5)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "5" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "2-2" ] ]+            ]+        , Row+            ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "3-2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "3-3" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "4-2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "4-3" ] ]+            ]+        , Row+            ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "6-1" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "6-2" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "6-3" ] ]+            ]+        ]+    ]+    (TableFoot+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "1-1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 8)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "8" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "1-3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 3)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "3" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "2-3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "2" ] ]+           ]+       , Row ( "" , [] , [] ) []+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "4-1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "4-3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Footer" , Space , Str "5-1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 3)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "3" ] ]+           ]+       , Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 2)+               (ColSpan 1)+               [ Plain [ Str "Span" , Space , Str "2" ] ]+           ]+       , Row ( "" , [] , [] ) []+       ])+, Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead ( "" , [] , [] ) [])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [ "rowspan-cell" ] , [] )+                AlignDefault+                (RowSpan 6)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "6" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "1-2" ] ]+            , Cell+                ( "" , [ "rowspan-cell" ] , [] )+                AlignDefault+                (RowSpan 2)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "2" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [ "rowspan-cell" ] , [] )+                AlignDefault+                (RowSpan 3)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "3" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [ "rowspan-cell" ] , [] )+                AlignDefault+                (RowSpan 4)+                (ColSpan 1)+                [ Plain [ Str "Span" , Space , Str "4" ] ]+            ]+        , Row ( "" , [] , [] ) []+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "3-2" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Body" , Space , Str "4-2" ] ]+            ]+        , Row ( "" , [] , [] ) []+        , Row ( "" , [] , [] ) []+        ]+    ]+    (TableFoot ( "" , [] , [] ) [])+]+^D+[cols=",,",options="header,footer",]+|===+|Header 1-1 |Span 3 |Header 1-3+|Header 2-1 | |Header 2-3+2+|Body 1-1/2 .3+|Span 5+|Body 2-1 |Body 2-2+|Body 3-1 |Body 3-2+| | |+.3+|Span 5 2+|Footer 1-2+2+|Span 2+2+|Footer 3-2/3+| 2+|Footer 4-2/3+|===++[cols=",,",options="footer",]+|===+|Body 1-1 |Body 1-2 .2+|Span 4+.3+|Span 5 |Body 2-2+|Body 3-2 |Body 3-3+|Body 4-2 |Body 4-3+| | |+|Body 6-1 |Body 6-2 |Span 6-3+|Footer 1-1 .5+|Span 8 |Footer 1-3+.2+|Span 3 |Footer 2-3+|Span 2+|Footer 4-1 |Footer 4-3+|Footer 5-1 |Span 3+|Span 2 | |+|===++[cols=",,",]+|===+.5+|Span 6 |Body 1-2 .2+|Span 2+.2+|Span 3+.3+|Span 4+|Body 3-2+|Body 4-2+| | |+| | |+|===+```
test/command/8665.md view
@@ -23,7 +23,7 @@ ^D [cols=",",options="header",] |===-|h1 |h2-|!@#$%^&++*++()++{++}{vbar}~?{plus}-',."++<>[]\`++ |col 2+<|h1 <|h2+<|!@#$%^&++*++()++{++}{vbar}~?{plus}-',."++<>[]\`++ <|col 2 |=== ```
test/command/9002.md view
@@ -16,5 +16,5 @@ <tbody> </tbody> </table>-<p>See Table 1 This is my table!</p>+<p>See <a href="#_Ref143272803">Table 1 This is my table!</a></p> ```
+ test/command/9953.md view
@@ -0,0 +1,29 @@+```+% pandoc -f markdown -t native -s+---+header-includes: |+    \makeatletter+    \let\old@verbatim@font=\verbatim@font+    \def\verbatim@font{%+    \fontsize{10}{12}%+    \old@verbatim@font+    }+    \makeatother+...+^D+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "header-includes"+            , MetaBlocks+                [ RawBlock+                    (Format "tex")+                    "\\makeatletter\n\\let\\old@verbatim@font=\\verbatim@font\n\\def\\verbatim@font{%\n\\fontsize{10}{12}%\n\\old@verbatim@font\n}\n\\makeatother"+                ]+            )+          ]+    }+  []++```
+ test/command/latex-math-trailing-space.md view
@@ -0,0 +1,38 @@+Test that trailing spaces before \end{equation} don't create spurious paragraph breaks:++```+% pandoc -f latex -t latex+\begin{equation}+  a+ \end{equation}+^D+\begin{equation}+  a+\end{equation}+```++Same for align environment:++```+% pandoc -f latex -t latex+\begin{align}+  x &= y \\+ \end{align}+^D+\begin{align}+  x &= y \\+\end{align}+```++Test with multiple trailing spaces:++```+% pandoc -f latex -t latex+\begin{equation}+  a + b+   \end{equation}+^D+\begin{equation}+  a + b+\end{equation}+```
+ test/command/typst-hs-80.md view
@@ -0,0 +1,55 @@+```+% pandoc -f typst -t native -s+#set document(+  title: [My Title],+)++#title()+^D+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "title"+            , MetaInlines [ Str "My" , Space , Str "Title" ]+            )+          ]+    }+  []+```++```+% pandoc -f typst -t native -s+#set document(+  title: [ignored],+)++#title[My Title]+^D+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "title"+            , MetaInlines [ Str "My" , Space , Str "Title" ]+            )+          ]+    }+  []+```++```+% pandoc -f typst -t native -s+#title[My Title]+^D+Pandoc+  Meta+    { unMeta =+        fromList+          [ ( "title"+            , MetaInlines [ Str "My" , Space , Str "Title" ]+            )+          ]+    }+  []+```
test/djot-reader.native view
@@ -2,1024 +2,2364 @@   Meta { unMeta = fromList [] }   [ Div       ( "Pandoc-Test-Suite" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Pandoc Test Suite" ]-      , Para-          [ Str "John MacFarlane" , SoftBreak , Str "Anonymous" ]-      , Para [ Str "July 17, 2006" ]-      , Para-          [ Str-              "This is a set of tests for pandoc. Most of them are adapted from John Gruber\8217s"-          , SoftBreak-          , Str "markdown test suite."-          ]-      , HorizontalRule-      ]-  , Div-      ( "headers" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Headers" ]-      , Div-          ( "level-2-with-an-embedded-link" , [ "section" ] , [] )-          [ Header-              2-              ( "" , [] , [] )-              [ Str "Level 2 with an "-              , Link-                  ( "" , [] , [] )-                  [ Str "embedded link" ]-                  ( "/url" , "" )-              ]-          , Div-              ( "level-3-with-emphasis" , [ "section" ] , [] )-              [ Header-                  3-                  ( "" , [] , [] )-                  [ Str "Level 3 with " , Emph [ Str "emphasis" ] ]-              , Div-                  ( "level-4" , [ "section" ] , [] )-                  [ Header 4 ( "" , [] , [] ) [ Str "Level 4" ]-                  , Div-                      ( "level-5" , [ "section" ] , [] )-                      [ Header 5 ( "" , [] , [] ) [ Str "Level 5" ] ]-                  ]-              ]-          ]-      ]-  , Div-      ( "level-1" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Level 1" ]-      , Div-          ( "level-2-with-emphasis" , [ "section" ] , [] )-          [ Header-              2-              ( "" , [] , [] )-              [ Str "Level 2 with " , Emph [ Str "emphasis" ] ]-          , Div-              ( "level-3" , [ "section" ] , [] )-              [ Header 3 ( "" , [] , [] ) [ Str "Level 3" ]-              , Para [ Str "with no blank line" ]-              ]-          ]-      , Div-          ( "level-2" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Level 2" ]-          , Para [ Str "with no blank line" ]-          , HorizontalRule-          ]-      ]-  , Div-      ( "paragraphs" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Paragraphs" ]-      , Para [ Str "Here\8217s a regular paragraph." ]-      , Para-          [ Str-              "In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item."-          , SoftBreak-          , Str-              "Because a hard-wrapped line in the middle of a paragraph looked like a list"-          , SoftBreak-          , Str "item."-          ]-      , Para [ Str "Here\8217s one with a bullet. * criminey." ]-      , Para-          [ Str "There should be a hard line break"-          , LineBreak-          , Str "here."-          ]-      , HorizontalRule-      ]-  , Div-      ( "block-quotes" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Block Quotes" ]-      , Para [ Str "E-mail style:" ]-      , BlockQuote-          [ Para [ Str "This is a block quote. It is pretty short." ]-          ]-      , BlockQuote-          [ Para [ Str "Code in a block quote:" ]-          , CodeBlock-              ( "" , [ "" ] , [] )-              "sub status {\n    print \"working\";\n}\n"-          , Para [ Str "A list:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Plain [ Str "item one" ] ]-              , [ Plain [ Str "item two" ] ]-              ]-          , Para [ Str "Nested block quotes:" ]-          , BlockQuote [ Para [ Str "nested" ] ]-          , BlockQuote [ Para [ Str "nested" ] ]-          ]-      , Para [ Str "This should not be a block quote: 2 > 1." ]-      , Para [ Str "And a following paragraph." ]-      , HorizontalRule-      ]-  , Div-      ( "code-blocks" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Code Blocks" ]-      , Para [ Str "Code:" ]-      , CodeBlock-          ( "" , [ "" ] , [] )-          "---- (should be four hyphens)\n\nsub status {\n    print \"working\";\n}\n\nthis code block is indented by one tab\n"-      , Para [ Str "And:" ]-      , CodeBlock-          ( "" , [ "" ] , [] )-          "    this code block is indented by two tabs\n\nThese should not be escaped:  \\$ \\\\ \\> \\[ \\{\n"-      , HorizontalRule-      ]-  , Div-      ( "lists" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Lists" ]-      , Div-          ( "unordered" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Unordered" ]-          , Para [ Str "Asterisks tight:" ]-          , BulletList-              [ [ Plain [ Str "asterisk 1" ] ]-              , [ Plain [ Str "asterisk 2" ] ]-              , [ Plain [ Str "asterisk 3" ] ]-              ]-          , Para [ Str "Asterisks loose:" ]-          , BulletList-              [ [ Para [ Str "asterisk 1" ] ]-              , [ Para [ Str "asterisk 2" ] ]-              , [ Para [ Str "asterisk 3" ] ]-              ]-          , Para [ Str "Pluses tight:" ]-          , BulletList-              [ [ Plain [ Str "Plus 1" ] ]-              , [ Plain [ Str "Plus 2" ] ]-              , [ Plain [ Str "Plus 3" ] ]-              ]-          , Para [ Str "Pluses loose:" ]-          , BulletList-              [ [ Para [ Str "Plus 1" ] ]-              , [ Para [ Str "Plus 2" ] ]-              , [ Para [ Str "Plus 3" ] ]-              ]-          , Para [ Str "Minuses tight:" ]-          , BulletList-              [ [ Plain [ Str "Minus 1" ] ]-              , [ Plain [ Str "Minus 2" ] ]-              , [ Plain [ Str "Minus 3" ] ]-              ]-          , Para [ Str "Minuses loose:" ]-          , BulletList-              [ [ Para [ Str "Minus 1" ] ]-              , [ Para [ Str "Minus 2" ] ]-              , [ Para [ Str "Minus 3" ] ]-              ]-          ]-      , Div-          ( "ordered" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Ordered" ]-          , Para [ Str "Tight:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Plain [ Str "First" ] ]-              , [ Plain [ Str "Second" ] ]-              , [ Plain [ Str "Third" ] ]-              ]-          , Para [ Str "and:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Plain [ Str "One" ] ]-              , [ Plain [ Str "Two" ] ]-              , [ Plain [ Str "Three" ] ]-              ]-          , Para [ Str "Loose using tabs:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Para [ Str "First" ] ]-              , [ Para [ Str "Second" ] ]-              , [ Para [ Str "Third" ] ]-              ]-          , Para [ Str "and using spaces:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Para [ Str "One" ] ]-              , [ Para [ Str "Two" ] ]-              , [ Para [ Str "Three" ] ]-              ]-          , Para [ Str "Multiple paragraphs:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Para [ Str "Item 1, graf one." ]-                , Para-                    [ Str-                        "Item 1. graf two. The quick brown fox jumped over the lazy dog\8217s back."-                    ]-                ]-              , [ Para [ Str "Item 2." ] ]-              , [ Para [ Str "Item 3." ] ]-              ]-          ]-      , Div-          ( "nested" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Nested" ]-          , BulletList-              [ [ Plain [ Str "Tab" ]-                , BulletList-                    [ [ Plain [ Str "Tab" ]-                      , BulletList [ [ Plain [ Str "Tab" ] ] ]-                      ]-                    ]-                ]-              ]-          , Para [ Str "Here\8217s another:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Plain [ Str "First" ] ]-              , [ Plain [ Str "Second:" ]-                , BulletList-                    [ [ Plain [ Str "Fee" ] ]-                    , [ Plain [ Str "Fie" ] ]-                    , [ Plain [ Str "Foe" ] ]-                    ]-                ]-              , [ Plain [ Str "Third" ] ]-              ]-          , Para [ Str "Same thing but with paragraphs:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Para [ Str "First" ] ]-              , [ Para [ Str "Second:" ]-                , BulletList-                    [ [ Plain [ Str "Fee" ] ]-                    , [ Plain [ Str "Fie" ] ]-                    , [ Plain [ Str "Foe" ] ]-                    ]-                ]-              , [ Para [ Str "Third" ] ]-              ]-          ]-      , Div-          ( "tabs-and-spaces" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Tabs and spaces" ]-          , BulletList-              [ [ Para [ Str "this is a list item indented with tabs" ]-                ]-              , [ Para-                    [ Str "this is a list item indented with spaces" ]-                , BulletList-                    [ [ Para-                          [ Str-                              "this is an example list item indented with tabs"-                          ]-                      ]-                    , [ Para-                          [ Str-                              "this is an example list item indented with spaces"-                          ]-                      ]-                    ]-                ]-              ]-          ]-      , Div-          ( "fancy-list-markers" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Fancy list markers" ]-          , OrderedList-              ( 2 , Decimal , TwoParens )-              [ [ Para [ Str "begins with 2" ] ]-              , [ Para [ Str "and now 3" ]-                , Para [ Str "with a continuation" ]-                , OrderedList-                    ( 4 , LowerRoman , Period )-                    [ [ Plain-                          [ Str-                              "sublist with roman numerals, starting with 4"-                          ]-                      ]-                    , [ Plain [ Str "more items" ]-                      , OrderedList-                          ( 1 , UpperAlpha , TwoParens )-                          [ [ Plain [ Str "a subsublist" ] ]-                          , [ Plain [ Str "a subsublist" ] ]-                          ]-                      ]-                    ]-                ]-              ]-          , Para [ Str "Nesting:" ]-          , OrderedList-              ( 1 , UpperAlpha , Period )-              [ [ Plain [ Str "Upper Alpha" ]-                , OrderedList-                    ( 1 , UpperRoman , Period )-                    [ [ Plain [ Str "Upper Roman." ]-                      , OrderedList-                          ( 6 , Decimal , TwoParens )-                          [ [ Plain [ Str "Decimal start with 6" ]-                            , OrderedList-                                ( 3 , LowerAlpha , OneParen )-                                [ [ Plain-                                      [ Str "Lower alpha with paren" ]-                                  ]-                                ]-                            ]-                          ]-                      ]-                    ]-                ]-              ]-          , Para [ Str "Autonumbering:" ]-          , OrderedList-              ( 1 , Decimal , Period )-              [ [ Plain [ Str "Autonumber." ] ]-              , [ Plain [ Str "More." ]-                , OrderedList-                    ( 1 , Decimal , Period )-                    [ [ Plain [ Str "Nested." ] ] ]-                ]-              ]-          , Para [ Str "Should not be a list item:" ]-          , Para [ Str "M.A.\160\&2007" ]-          , OrderedList-              ( 2 , UpperAlpha , Period )-              [ [ Plain [ Str "Williams" ] ] ]-          , HorizontalRule-          ]-      ]-  , Div-      ( "definition-lists" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Definition Lists" ]-      , Para [ Str "Tight using spaces:" ]-      , DefinitionList-          [ ( [ Str "apple" ] , [ [ Plain [ Str "red fruit" ] ] ] )-          , ( [ Str "orange" ]-            , [ [ Plain [ Str "orange fruit" ] ] ]-            )-          , ( [ Str "banana" ]-            , [ [ Plain [ Str "yellow fruit" ] ] ]-            )-          ]-      , Para [ Str "Tight using tabs:" ]-      , DefinitionList-          [ ( [ Str "apple" ] , [ [ Plain [ Str "red fruit" ] ] ] )-          , ( [ Str "orange" ]-            , [ [ Plain [ Str "orange fruit" ] ] ]-            )-          , ( [ Str "banana" ]-            , [ [ Plain [ Str "yellow fruit" ] ] ]-            )-          ]-      , Para [ Str "Loose:" ]-      , DefinitionList-          [ ( [ Str "apple" ] , [ [ Para [ Str "red fruit" ] ] ] )-          , ( [ Str "orange" ] , [ [ Para [ Str "orange fruit" ] ] ] )-          , ( [ Str "banana" ] , [ [ Para [ Str "yellow fruit" ] ] ] )-          ]-      , Para [ Str "Multiple blocks with italics:" ]-      , DefinitionList-          [ ( [ Emph [ Str "apple" ] ]-            , [ [ Para [ Str "red fruit" ]-                , Para-                    [ Str "contains seeds, crisp, pleasant to taste" ]-                ]-              ]-            )-          , ( [ Emph [ Str "orange" ] ]-            , [ [ Para [ Str "orange fruit" ]-                , CodeBlock-                    ( "" , [ "" ] , [] ) "{ orange code block }\n"-                , BlockQuote [ Para [ Str "orange block quote" ] ]-                ]-              ]-            )-          ]-      , Para [ Str "Multiple definitions, tight:" ]-      , DefinitionList-          [ ( [ Str "apple" ]-            , [ [ Para [ Str "red fruit" ] , Para [ Str "computer" ] ] ]-            )-          , ( [ Str "orange" ]-            , [ [ Para [ Str "orange fruit" ] , Para [ Str "bank" ] ] ]-            )-          ]-      , Para [ Str "Multiple definitions, loose:" ]-      , DefinitionList-          [ ( [ Str "apple" ]-            , [ [ Para [ Str "red fruit" ] , Para [ Str "computer" ] ] ]-            )-          , ( [ Str "orange" ]-            , [ [ Para [ Str "orange fruit" ] , Para [ Str "bank" ] ] ]-            )-          ]-      , Para-          [ Str-              "Blank line after term, indented marker, alternate markers:"-          ]-      , DefinitionList-          [ ( [ Str "apple" ]-            , [ [ Para [ Str "red fruit" ] , Para [ Str "computer" ] ] ]-            )-          , ( [ Str "orange" ]-            , [ [ Para [ Str "orange fruit" ]-                , OrderedList-                    ( 1 , Decimal , Period )-                    [ [ Plain [ Str "sublist" ] ]-                    , [ Plain [ Str "sublist" ] ]-                    ]-                ]-              ]-            )-          ]-      ]-  , Div-      ( "html-blocks" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "HTML Blocks" ]-      , Para [ Str "Simple block on one line:" ]-      , Div ( "" , [] , [] ) [ Para [ Str "foo" ] ]-      , Para [ Str "And nested without indentation:" ]-      , Div-          ( "" , [] , [] )-          [ Div-              ( "" , [] , [] )-              [ Div ( "" , [] , [] ) [ Para [ Str "foo" ] ] ]-          , Div ( "" , [] , [] ) [ Para [ Str "bar" ] ]-          ]-      , Para [ Str "Interpreted markdown in a table:" ]-      , Para [ Str "This is " , Emph [ Str "emphasized" ] ]-      , Para [ Str "And this is " , Strong [ Str "strong" ] ]-      , Para [ Str "Here\8217s a simple block:" ]-      , Div ( "" , [] , [] ) [ Para [ Str "foo" ] ]-      , Para [ Str "This should be a code block, though:" ]-      , CodeBlock ( "" , [ "" ] , [] ) "<div>\n    foo\n</div>\n"-      , Para [ Str "As should this:" ]-      , CodeBlock ( "" , [ "" ] , [] ) "<div>foo</div>\n"-      , Para [ Str "Now, nested:" ]-      , Div-          ( "" , [] , [] )-          [ Div-              ( "" , [] , [] )-              [ Div ( "" , [] , [] ) [ Para [ Str "foo" ] ] ]-          ]-      , Para [ Str "This should just be an HTML comment:" ]-      , Para [ Str "Multiline:" ]-      , Para [ Str "Code block:" ]-      , CodeBlock ( "" , [ "" ] , [] ) "<!-- Comment -->\n"-      , Para-          [ Str-              "Just plain comment, with trailing spaces on the line:"-          ]-      , Para [ Str "Code:" ]-      , CodeBlock ( "" , [ "" ] , [] ) "<hr />\n"-      , Para [ Str "Hr\8217s:" ]-      , HorizontalRule-      ]-  , Div-      ( "inline-markup" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Inline Markup" ]-      , Para-          [ Str "This is "-          , Emph [ Str "emphasized" ]-          , Str ", and so "-          , Emph [ Str "is this" ]-          , Str "."-          ]-      , Para-          [ Str "This is "-          , Strong [ Str "strong" ]-          , Str ", and so "-          , Strong [ Str "is this" ]-          , Str "."-          ]-      , Para-          [ Str "An "-          , Emph-              [ Link-                  ( "" , [] , [] )-                  [ Str "emphasized link" ]-                  ( "/url" , "" )-              ]-          , Str "."-          ]-      , Para [ Strong [ Emph [ Str "This is strong and em." ] ] ]-      , Para-          [ Str "So is "-          , Strong [ Emph [ Str "this" ] ]-          , Str " word."-          ]-      , Para [ Strong [ Emph [ Str "This is strong and em." ] ] ]-      , Para-          [ Str "So is "-          , Strong [ Emph [ Str "this" ] ]-          , Str " word."-          ]-      , Para-          [ Str "This is code: "-          , Code ( "" , [] , [] ) ">"-          , Str ", "-          , Code ( "" , [] , [] ) "$"-          , Str ", "-          , Code ( "" , [] , [] ) "\\`, "-          , Str "$"-          , Code ( "" , [] , [] ) ", "-          , Str "<html>"-          , Code ( "" , [] , [] ) "."-          ]-      , Para-          [ Span-              ( "" , [ "deleted" ] , [] )-              [ Str "This is " , Emph [ Str "strikeout" ] , Str "." ]-          ]-      , Para-          [ Str "Superscripts: a"-          , Superscript [ Str "bc" ]-          , Str "d a"-          , Superscript [ Emph [ Str "hello" ] ]-          , Str " a"-          , Superscript [ Str "hello\160there" ]-          , Str "."-          ]-      , Para-          [ Str "Subscripts: H"-          , Subscript [ Str "2" ]-          , Str "O, H"-          , Subscript [ Str "23" ]-          , Str "O, H"-          , Subscript [ Str "many\160of\160them" ]-          , Str "O."-          ]-      , Para-          [ Str-              "These should not be superscripts or subscripts, because of the unescaped spaces:"-          , SoftBreak-          , Str "a^b c^d, a~b c~d."-          ]-      , HorizontalRule-      ]-  , Div-      ( "smart-quotes-ellipses-dashes" , [ "section" ] , [] )-      [ Header-          1 ( "" , [] , [] ) [ Str "Smart quotes, ellipses, dashes" ]-      , Para-          [ Quoted DoubleQuote [ Str "Hello," ]-          , Str " said the spider. "-          , Quoted-              DoubleQuote-              [ Quoted SingleQuote [ Str "Shelob" ]-              , Str " is my name."-              ]-          ]-      , Para-          [ Quoted SingleQuote [ Str "A" ]-          , Str ", "-          , Quoted SingleQuote [ Str "B" ]-          , Str ", and "-          , Quoted SingleQuote [ Str "C" ]-          , Str " are letters."-          ]-      , Para-          [ Quoted SingleQuote [ Str "Oak," ]-          , Str " "-          , Quoted SingleQuote [ Str "elm," ]-          , Str " and "-          , Quoted SingleQuote [ Str "beech" ]-          , Str " are names of trees. So is "-          , Quoted SingleQuote [ Str "pine." ]-          ]-      , Para-          [ Quoted-              SingleQuote-              [ Str "He said, "-              , Quoted DoubleQuote [ Str "I want to go." ]-              ]-          , Str " Were you alive in the 70\8217s?"-          ]-      , Para-          [ Str "Here is some quoted "-          , Quoted SingleQuote [ Code ( "" , [] , [] ) "code" ]-          , Str " and a "-          , Quoted-              DoubleQuote-              [ Link-                  ( "" , [] , [] )-                  [ Str "quoted" , SoftBreak , Str "link" ]-                  ( "http://example.com/?foo=1&bar=2" , "" )-              ]-          , Str "."-          ]-      , Para-          [ Str-              "Some dashes: one\8212two \8212 three\8212four \8212 five."-          ]-      , Para-          [ Str-              "Dashes between numbers: 5\8211\&7, 255\8211\&66, 1987\8211\&1999."-          ]-      , Para [ Str "Ellipses\8230and\8230and\8230." ]-      , HorizontalRule-      ]-  , Div-      ( "latex" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "LaTeX" ]-      , BulletList-          [ []-          , [ Plain [ Math InlineMath "2+2=4" ] ]-          , [ Plain [ Math InlineMath "x \\in y" ] ]-          , [ Plain [ Math InlineMath "\\alpha \\wedge \\omega" ] ]-          , [ Plain [ Math InlineMath "223" ] ]-          , [ Plain [ Math InlineMath "p" , Str "-Tree" ] ]-          , [ Plain-                [ Str "Here\8217s some display math:"-                , SoftBreak-                , Math-                    DisplayMath-                    "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"-                ]-            ]-          , [ Plain-                [ Str "Here\8217s one that has a line break in it: "-                , Math InlineMath "\\alpha + \\omega \\times x^2"-                , Str "."-                ]-            ]-          ]-      , Para [ Str "These shouldn\8217t be math:" ]-      , BulletList-          [ [ Plain-                [ Str "To get the famous equation, write "-                , Code ( "" , [] , [] ) "$e = mc^2$"-                , Str "."-                ]-            ]-          , [ Plain-                [ Str "$22,000 is a "-                , Emph [ Str "lot" ]-                , Str " of money. So is $34,000. (It worked if "-                , Quoted DoubleQuote [ Str "lot" ]-                , Str " is"-                , SoftBreak-                , Str "emphasized.)"-                ]-            ]-          , [ Plain [ Str "Shoes ($20) and socks ($5)." ] ]-          , [ Plain-                [ Str "Escaped "-                , Code ( "" , [] , [] ) "$"-                , Str ": $73 "-                , Emph [ Str "this should be emphasized" ]-                , Str " 23$."-                ]-            ]-          ]-      , Para [ Str "Here\8217s a LaTeX table:" ]-      , HorizontalRule-      ]-  , Div-      ( "special-characters" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Special Characters" ]-      , Para [ Str "Here is some unicode:" ]-      , BulletList-          [ [ Plain [ Str "I hat: \206" ] ]-          , [ Plain [ Str "o umlaut: \246" ] ]-          , [ Plain [ Str "section: \167" ] ]-          , [ Plain [ Str "set membership: \8712" ] ]-          , [ Plain [ Str "copyright: \169" ] ]-          ]-      , Para [ Str "AT&T has an ampersand in their name." ]-      , Para [ Str "AT&T is another way to write it." ]-      , Para [ Str "This & that." ]-      , Para [ Str "4 < 5." ]-      , Para [ Str "6 > 5." ]-      , Para [ Str "Backslash: \\" ]-      , Para [ Str "Backtick: `" ]-      , Para [ Str "Asterisk: *" ]-      , Para [ Str "Underscore: _" ]-      , Para [ Str "Left brace: {" ]-      , Para [ Str "Right brace: }" ]-      , Para [ Str "Left bracket: [" ]-      , Para [ Str "Right bracket: ]" ]-      , Para [ Str "Left paren: (" ]-      , Para [ Str "Right paren: )" ]-      , Para [ Str "Greater-than: >" ]-      , Para [ Str "Hash: #" ]-      , Para [ Str "Period: ." ]-      , Para [ Str "Bang: !" ]-      , Para [ Str "Plus: +" ]-      , Para [ Str "Minus: -" ]-      , HorizontalRule-      ]-  , Div-      ( "links" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Links" ]-      , Div-          ( "explicit" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Explicit" ]-          , Para-              [ Str "Just a "-              , Link ( "" , [] , [] ) [ Str "URL" ] ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Link-                  ( "" , [] , [ ( "title" , "title" ) ] )-                  [ Str "URL and title" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Link-                  ( ""-                  , []-                  , [ ( "title" , "title preceded by two spaces" ) ]-                  )-                  [ Str "URL and title" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Link-                  ( ""-                  , []-                  , [ ( "title" , "title preceded by a tab" ) ]-                  )-                  [ Str "URL and title" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Link-                  ( ""-                  , []-                  , [ ( "title" , "title with \"quotes\" in it" ) ]-                  )-                  [ Str "URL and title" ]-                  ( "/url/" , "" )-              ]-          , Para-              [ Link-                  ( ""-                  , []-                  , [ ( "title" , "title with single quotes" ) ]-                  )-                  [ Str "URL and title" ]-                  ( "/url/" , "" )-              ]-          , Para-              [ Link-                  ( "" , [] , [] )-                  [ Str "with_underscore" ]-                  ( "/url/with_underscore" , "" )-              ]-          , Para-              [ Link-                  ( "" , [] , [] )-                  [ Str "Email link" ]-                  ( "mailto:nobody@nowhere.net" , "" )-              ]-          , Para-              [ Link ( "" , [] , [] ) [ Str "Empty" ] ( "" , "" )-              , Str "."-              ]-          ]-      , Div-          ( "reference" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Reference" ]-          , Para-              [ Str "Foo "-              , Link ( "" , [] , [] ) [ Str "bar" ] ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Str "With "-              , Link-                  ( "" , [] , [] )-                  [ Str "embedded [brackets]" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Link ( "" , [] , [] ) [ Str "b" ] ( "/url/" , "" )-              , Str " by itself should be a link."-              ]-          , Para-              [ Str "Indented "-              , Link ( "" , [] , [] ) [ Str "once" ] ( "/url" , "" )-              , Str "."-              ]-          , Para-              [ Str "Indented "-              , Link ( "" , [] , [] ) [ Str "twice" ] ( "/url" , "" )-              , Str "."-              ]-          , Para-              [ Str "Indented "-              , Link ( "" , [] , [] ) [ Str "thrice" ] ( "/url" , "" )-              , Str "."-              ]-          , Para [ Str "This should [not][] be a link." ]-          , CodeBlock ( "" , [ "" ] , [] ) "[not]: /url\n"-          , Para-              [ Str "Foo "-              , Link-                  ( ""-                  , []-                  , [ ( "title" , "Title with \"quotes\" inside" ) ]-                  )-                  [ Str "bar" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          , Para-              [ Str "Foo "-              , Link-                  ( ""-                  , []-                  , [ ( "title" , "Title with \"quote\" inside" ) ]-                  )-                  [ Str "biz" ]-                  ( "/url/" , "" )-              , Str "."-              ]-          ]-      , Div-          ( "with-ampersands" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "With ampersands" ]-          , Para-              [ Str "Here\8217s a "-              , Link-                  ( "" , [] , [] )-                  [ Str "link with an ampersand in the URL" ]-                  ( "http://example.com/?foo=1&bar=2" , "" )-              , Str "."-              ]-          , Para-              [ Str-                  "Here\8217s a link with an amersand in the link text:"-              , SoftBreak-              , Link-                  ( "" , [] , [ ( "title" , "AT&T" ) ] )-                  [ Str "AT&T" ]-                  ( "http://att.com/" , "" )-              , Str "."-              ]-          , Para-              [ Str "Here\8217s an "-              , Link-                  ( "" , [] , [] )-                  [ Str "inline link" ]-                  ( "/script?foo=1&bar=2" , "" )-              , Str "."-              ]-          , Para-              [ Str "Here\8217s an "-              , Link-                  ( "" , [] , [] )-                  [ Str "inline link in pointy braces" ]-                  ( "/script?foo=1&bar=2" , "" )-              , Str "."-              ]-          ]-      , Div-          ( "autolinks" , [ "section" ] , [] )-          [ Header 2 ( "" , [] , [] ) [ Str "Autolinks" ]-          , Para-              [ Str "With an ampersand: "-              , Link-                  ( "" , [ "uri" ] , [] )-                  [ Str "http://example.com/?foo=1&bar=2" ]-                  ( "http://example.com/?foo=1&bar=2" , "" )-              ]-          , BulletList-              [ [ Plain [ Str "In a list?" ] ]-              , [ Plain-                    [ Link-                        ( "" , [ "uri" ] , [] )-                        [ Str "http://example.com/" ]-                        ( "http://example.com/" , "" )-                    ]-                ]-              , [ Plain [ Str "It should." ] ]-              ]-          , Para-              [ Str "An e-mail address: "-              , Link-                  ( "" , [ "email" ] , [] )-                  [ Str "nobody@nowhere.net" ]-                  ( "mailto:nobody@nowhere.net" , "" )-              ]-          , BlockQuote-              [ Para-                  [ Str "Blockquoted: "-                  , Link-                      ( "" , [ "uri" ] , [] )-                      [ Str "http://example.com/" ]-                      ( "http://example.com/" , "" )-                  ]-              ]-          , Para-              [ Str "Auto-links should not occur here: "-              , Code ( "" , [] , [] ) "<http://example.com/>"-              ]-          , CodeBlock-              ( "" , [ "" ] , [] ) "or here: <http://example.com/>\n"-          , HorizontalRule-          ]-      ]-  , Div-      ( "images" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Images" ]-      , Para-          [ Str "From "-          , Quoted DoubleQuote [ Str "Voyage dans la Lune" ]-          , Str " by Georges Melies (1902):"-          ]-      , Div-          ( "" , [] , [] )-          [ Para-              [ Image-                  ( "" , [] , [ ( "title" , "Voyage dans la Lune" ) ] )-                  [ Str "lalune" ]-                  ( "lalune.jpg" , "" )-              ]-          , Div ( "" , [ "caption" ] , [] ) [ Para [ Str "lalune" ] ]-          ]-      , Para-          [ Str "Here is a movie "-          , Image-              ( "" , [] , [] ) [ Str "movie" ] ( "movie.jpg" , "" )-          , Str " icon."-          ]-      , HorizontalRule-      ]-  , Div-      ( "footnotes" , [ "section" ] , [] )-      [ Header 1 ( "" , [] , [] ) [ Str "Footnotes" ]-      , Para-          [ Str "Here is a footnote reference,"-          , Note-              [ Para-                  [ Str-                      "Here is the footnote. It can go anywhere after the footnote reference. It"-                  , SoftBreak-                  , Str "need not be placed at the end of the document."-                  ]-              ]-          , Str " and another."-          , Note-              [ Para-                  [ Str-                      "Here\8217s the long note. This one contains multiple blocks."-                  ]-              , Para-                  [ Str-                      "Subsequent blocks are indented to show that they belong to the footnote (as"-                  , SoftBreak-                  , Str "with list items)."-                  ]-              , CodeBlock ( "" , [ "" ] , [] ) "{ <code> }\n"-              , Para-                  [ Str-                      "If you want, you can indent every line, but you can also be lazy and just"-                  , SoftBreak-                  , Str "indent the first line of each block."-                  ]-              ]-          , Str " This should "-          , Emph [ Str "not" ]-          , Str " be a"-          , SoftBreak-          , Str-              "footnote reference, because it contains a space.[^my note] Here is an inline"-          , SoftBreak-          , Str "note."-          , Note-              [ Para-                  [ Str "This is "-                  , Emph [ Str "easier" ]-                  , Str " to type. Inline notes may contain"-                  , SoftBreak-                  , Link-                      ( "" , [] , [] )-                      [ Str "links" ]-                      ( "http://google.com" , "" )-                  , Str " and "-                  , Code ( "" , [] , [] ) "]"-                  , Str " verbatim characters, as well as"-                  , SoftBreak-                  , Str "[bracketed text]."-                  ]-              ]-          ]-      , BlockQuote-          [ Para-              [ Str "Notes can go in quotes."-              , Note [ Para [ Str "In quote." ] ]-              ]-          ]-      , OrderedList-          ( 1 , Decimal , Period )-          [ [ Plain-                [ Str "And in list items."-                , Note [ Para [ Str "In list." ] ]-                ]-            ]-          ]-      , Para-          [ Str-              "This paragraph should not be part of the note, as it is not indented."+      [ Header+          1+          ( "" , [] , [] )+          [ Str "Pandoc" , Space , Str "Test" , Space , Str "Suite" ]+      , Para+          [ Str "John"+          , Space+          , Str "MacFarlane"+          , SoftBreak+          , Str "Anonymous"+          ]+      , Para+          [ Str "July" , Space , Str "17," , Space , Str "2006" ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "a"+          , Space+          , Str "set"+          , Space+          , Str "of"+          , Space+          , Str "tests"+          , Space+          , Str "for"+          , Space+          , Str "pandoc."+          , Space+          , Str "Most"+          , Space+          , Str "of"+          , Space+          , Str "them"+          , Space+          , Str "are"+          , Space+          , Str "adapted"+          , Space+          , Str "from"+          , Space+          , Str "John"+          , Space+          , Str "Gruber\8217s"+          , SoftBreak+          , Str "markdown"+          , Space+          , Str "test"+          , Space+          , Str "suite."+          ]+      , HorizontalRule+      ]+  , Div+      ( "headers" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Headers" ]+      , Div+          ( "level-2-with-an-embedded-link" , [ "section" ] , [] )+          [ Header+              2+              ( "" , [] , [] )+              [ Str "Level"+              , Space+              , Str "2"+              , Space+              , Str "with"+              , Space+              , Str "an"+              , Space+              , Link+                  ( "" , [] , [] )+                  [ Str "embedded" , Space , Str "link" ]+                  ( "/url" , "" )+              ]+          , Div+              ( "level-3-with-emphasis" , [ "section" ] , [] )+              [ Header+                  3+                  ( "" , [] , [] )+                  [ Str "Level"+                  , Space+                  , Str "3"+                  , Space+                  , Str "with"+                  , Space+                  , Emph [ Str "emphasis" ]+                  ]+              , Div+                  ( "level-4" , [ "section" ] , [] )+                  [ Header+                      4+                      ( "" , [] , [] )+                      [ Str "Level" , Space , Str "4" ]+                  , Div+                      ( "level-5" , [ "section" ] , [] )+                      [ Header+                          5+                          ( "" , [] , [] )+                          [ Str "Level" , Space , Str "5" ]+                      ]+                  ]+              ]+          ]+      ]+  , Div+      ( "level-1" , [ "section" ] , [] )+      [ Header+          1 ( "" , [] , [] ) [ Str "Level" , Space , Str "1" ]+      , Div+          ( "level-2-with-emphasis" , [ "section" ] , [] )+          [ Header+              2+              ( "" , [] , [] )+              [ Str "Level"+              , Space+              , Str "2"+              , Space+              , Str "with"+              , Space+              , Emph [ Str "emphasis" ]+              ]+          , Div+              ( "level-3" , [ "section" ] , [] )+              [ Header+                  3 ( "" , [] , [] ) [ Str "Level" , Space , Str "3" ]+              , Para+                  [ Str "with"+                  , Space+                  , Str "no"+                  , Space+                  , Str "blank"+                  , Space+                  , Str "line"+                  ]+              ]+          ]+      , Div+          ( "level-2" , [ "section" ] , [] )+          [ Header+              2 ( "" , [] , [] ) [ Str "Level" , Space , Str "2" ]+          , Para+              [ Str "with"+              , Space+              , Str "no"+              , Space+              , Str "blank"+              , Space+              , Str "line"+              ]+          , HorizontalRule+          ]+      ]+  , Div+      ( "paragraphs" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Paragraphs" ]+      , Para+          [ Str "Here\8217s"+          , Space+          , Str "a"+          , Space+          , Str "regular"+          , Space+          , Str "paragraph."+          ]+      , Para+          [ Str "In"+          , Space+          , Str "Markdown"+          , Space+          , Str "1.0.0"+          , Space+          , Str "and"+          , Space+          , Str "earlier."+          , Space+          , Str "Version"+          , Space+          , Str "8."+          , Space+          , Str "This"+          , Space+          , Str "line"+          , Space+          , Str "turns"+          , Space+          , Str "into"+          , Space+          , Str "a"+          , Space+          , Str "list"+          , Space+          , Str "item."+          , SoftBreak+          , Str "Because"+          , Space+          , Str "a"+          , Space+          , Str "hard-wrapped"+          , Space+          , Str "line"+          , Space+          , Str "in"+          , Space+          , Str "the"+          , Space+          , Str "middle"+          , Space+          , Str "of"+          , Space+          , Str "a"+          , Space+          , Str "paragraph"+          , Space+          , Str "looked"+          , Space+          , Str "like"+          , Space+          , Str "a"+          , Space+          , Str "list"+          , SoftBreak+          , Str "item."+          ]+      , Para+          [ Str "Here\8217s"+          , Space+          , Str "one"+          , Space+          , Str "with"+          , Space+          , Str "a"+          , Space+          , Str "bullet."+          , Space+          , Str "*"+          , Space+          , Str "criminey."+          ]+      , Para+          [ Str "There"+          , Space+          , Str "should"+          , Space+          , Str "be"+          , Space+          , Str "a"+          , Space+          , Str "hard"+          , Space+          , Str "line"+          , Space+          , Str "break"+          , LineBreak+          , Str "here."+          ]+      , HorizontalRule+      ]+  , Div+      ( "block-quotes" , [ "section" ] , [] )+      [ Header+          1 ( "" , [] , [] ) [ Str "Block" , Space , Str "Quotes" ]+      , Para [ Str "E-mail" , Space , Str "style:" ]+      , BlockQuote+          [ Para+              [ Str "This"+              , Space+              , Str "is"+              , Space+              , Str "a"+              , Space+              , Str "block"+              , Space+              , Str "quote."+              , Space+              , Str "It"+              , Space+              , Str "is"+              , Space+              , Str "pretty"+              , Space+              , Str "short."+              ]+          ]+      , BlockQuote+          [ Para+              [ Str "Code"+              , Space+              , Str "in"+              , Space+              , Str "a"+              , Space+              , Str "block"+              , Space+              , Str "quote:"+              ]+          , CodeBlock+              ( "" , [ "" ] , [] )+              "sub status {\n    print \"working\";\n}\n"+          , Para [ Str "A" , Space , Str "list:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Plain [ Str "item" , Space , Str "one" ] ]+              , [ Plain [ Str "item" , Space , Str "two" ] ]+              ]+          , Para+              [ Str "Nested"+              , Space+              , Str "block"+              , Space+              , Str "quotes:"+              ]+          , BlockQuote [ Para [ Str "nested" ] ]+          , BlockQuote [ Para [ Str "nested" ] ]+          ]+      , Para+          [ Str "This"+          , Space+          , Str "should"+          , Space+          , Str "not"+          , Space+          , Str "be"+          , Space+          , Str "a"+          , Space+          , Str "block"+          , Space+          , Str "quote:"+          , Space+          , Str "2"+          , Space+          , Str ">"+          , Space+          , Str "1."+          ]+      , Para+          [ Str "And"+          , Space+          , Str "a"+          , Space+          , Str "following"+          , Space+          , Str "paragraph."+          ]+      , HorizontalRule+      ]+  , Div+      ( "code-blocks" , [ "section" ] , [] )+      [ Header+          1 ( "" , [] , [] ) [ Str "Code" , Space , Str "Blocks" ]+      , Para [ Str "Code:" ]+      , CodeBlock+          ( "" , [ "" ] , [] )+          "---- (should be four hyphens)\n\nsub status {\n    print \"working\";\n}\n\nthis code block is indented by one tab\n"+      , Para [ Str "And:" ]+      , CodeBlock+          ( "" , [ "" ] , [] )+          "    this code block is indented by two tabs\n\nThese should not be escaped:  \\$ \\\\ \\> \\[ \\{\n"+      , HorizontalRule+      ]+  , Div+      ( "lists" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Lists" ]+      , Div+          ( "unordered" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Unordered" ]+          , Para [ Str "Asterisks" , Space , Str "tight:" ]+          , BulletList+              [ [ Plain [ Str "asterisk" , Space , Str "1" ] ]+              , [ Plain [ Str "asterisk" , Space , Str "2" ] ]+              , [ Plain [ Str "asterisk" , Space , Str "3" ] ]+              ]+          , Para [ Str "Asterisks" , Space , Str "loose:" ]+          , BulletList+              [ [ Para [ Str "asterisk" , Space , Str "1" ] ]+              , [ Para [ Str "asterisk" , Space , Str "2" ] ]+              , [ Para [ Str "asterisk" , Space , Str "3" ] ]+              ]+          , Para [ Str "Pluses" , Space , Str "tight:" ]+          , BulletList+              [ [ Plain [ Str "Plus" , Space , Str "1" ] ]+              , [ Plain [ Str "Plus" , Space , Str "2" ] ]+              , [ Plain [ Str "Plus" , Space , Str "3" ] ]+              ]+          , Para [ Str "Pluses" , Space , Str "loose:" ]+          , BulletList+              [ [ Para [ Str "Plus" , Space , Str "1" ] ]+              , [ Para [ Str "Plus" , Space , Str "2" ] ]+              , [ Para [ Str "Plus" , Space , Str "3" ] ]+              ]+          , Para [ Str "Minuses" , Space , Str "tight:" ]+          , BulletList+              [ [ Plain [ Str "Minus" , Space , Str "1" ] ]+              , [ Plain [ Str "Minus" , Space , Str "2" ] ]+              , [ Plain [ Str "Minus" , Space , Str "3" ] ]+              ]+          , Para [ Str "Minuses" , Space , Str "loose:" ]+          , BulletList+              [ [ Para [ Str "Minus" , Space , Str "1" ] ]+              , [ Para [ Str "Minus" , Space , Str "2" ] ]+              , [ Para [ Str "Minus" , Space , Str "3" ] ]+              ]+          ]+      , Div+          ( "ordered" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Ordered" ]+          , Para [ Str "Tight:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Plain [ Str "First" ] ]+              , [ Plain [ Str "Second" ] ]+              , [ Plain [ Str "Third" ] ]+              ]+          , Para [ Str "and:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Plain [ Str "One" ] ]+              , [ Plain [ Str "Two" ] ]+              , [ Plain [ Str "Three" ] ]+              ]+          , Para+              [ Str "Loose"+              , Space+              , Str "using"+              , Space+              , Str "tabs:"+              ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Para [ Str "First" ] ]+              , [ Para [ Str "Second" ] ]+              , [ Para [ Str "Third" ] ]+              ]+          , Para+              [ Str "and"+              , Space+              , Str "using"+              , Space+              , Str "spaces:"+              ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Para [ Str "One" ] ]+              , [ Para [ Str "Two" ] ]+              , [ Para [ Str "Three" ] ]+              ]+          , Para [ Str "Multiple" , Space , Str "paragraphs:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Para+                    [ Str "Item"+                    , Space+                    , Str "1,"+                    , Space+                    , Str "graf"+                    , Space+                    , Str "one."+                    ]+                , Para+                    [ Str "Item"+                    , Space+                    , Str "1."+                    , Space+                    , Str "graf"+                    , Space+                    , Str "two."+                    , Space+                    , Str "The"+                    , Space+                    , Str "quick"+                    , Space+                    , Str "brown"+                    , Space+                    , Str "fox"+                    , Space+                    , Str "jumped"+                    , Space+                    , Str "over"+                    , Space+                    , Str "the"+                    , Space+                    , Str "lazy"+                    , Space+                    , Str "dog\8217s"+                    , Space+                    , Str "back."+                    ]+                ]+              , [ Para [ Str "Item" , Space , Str "2." ] ]+              , [ Para [ Str "Item" , Space , Str "3." ] ]+              ]+          ]+      , Div+          ( "nested" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Nested" ]+          , BulletList+              [ [ Plain [ Str "Tab" ]+                , BulletList+                    [ [ Plain [ Str "Tab" ]+                      , BulletList [ [ Plain [ Str "Tab" ] ] ]+                      ]+                    ]+                ]+              ]+          , Para [ Str "Here\8217s" , Space , Str "another:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Plain [ Str "First" ] ]+              , [ Plain [ Str "Second:" ]+                , BulletList+                    [ [ Plain [ Str "Fee" ] ]+                    , [ Plain [ Str "Fie" ] ]+                    , [ Plain [ Str "Foe" ] ]+                    ]+                ]+              , [ Plain [ Str "Third" ] ]+              ]+          , Para+              [ Str "Same"+              , Space+              , Str "thing"+              , Space+              , Str "but"+              , Space+              , Str "with"+              , Space+              , Str "paragraphs:"+              ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Para [ Str "First" ] ]+              , [ Para [ Str "Second:" ]+                , BulletList+                    [ [ Plain [ Str "Fee" ] ]+                    , [ Plain [ Str "Fie" ] ]+                    , [ Plain [ Str "Foe" ] ]+                    ]+                ]+              , [ Para [ Str "Third" ] ]+              ]+          ]+      , Div+          ( "tabs-and-spaces" , [ "section" ] , [] )+          [ Header+              2+              ( "" , [] , [] )+              [ Str "Tabs" , Space , Str "and" , Space , Str "spaces" ]+          , BulletList+              [ [ Para+                    [ Str "this"+                    , Space+                    , Str "is"+                    , Space+                    , Str "a"+                    , Space+                    , Str "list"+                    , Space+                    , Str "item"+                    , Space+                    , Str "indented"+                    , Space+                    , Str "with"+                    , Space+                    , Str "tabs"+                    ]+                ]+              , [ Para+                    [ Str "this"+                    , Space+                    , Str "is"+                    , Space+                    , Str "a"+                    , Space+                    , Str "list"+                    , Space+                    , Str "item"+                    , Space+                    , Str "indented"+                    , Space+                    , Str "with"+                    , Space+                    , Str "spaces"+                    ]+                , BulletList+                    [ [ Para+                          [ Str "this"+                          , Space+                          , Str "is"+                          , Space+                          , Str "an"+                          , Space+                          , Str "example"+                          , Space+                          , Str "list"+                          , Space+                          , Str "item"+                          , Space+                          , Str "indented"+                          , Space+                          , Str "with"+                          , Space+                          , Str "tabs"+                          ]+                      ]+                    , [ Para+                          [ Str "this"+                          , Space+                          , Str "is"+                          , Space+                          , Str "an"+                          , Space+                          , Str "example"+                          , Space+                          , Str "list"+                          , Space+                          , Str "item"+                          , Space+                          , Str "indented"+                          , Space+                          , Str "with"+                          , Space+                          , Str "spaces"+                          ]+                      ]+                    ]+                ]+              ]+          ]+      , Div+          ( "fancy-list-markers" , [ "section" ] , [] )+          [ Header+              2+              ( "" , [] , [] )+              [ Str "Fancy"+              , Space+              , Str "list"+              , Space+              , Str "markers"+              ]+          , OrderedList+              ( 2 , Decimal , TwoParens )+              [ [ Para+                    [ Str "begins"+                    , Space+                    , Str "with"+                    , Space+                    , Str "2"+                    ]+                ]+              , [ Para+                    [ Str "and" , Space , Str "now" , Space , Str "3" ]+                , Para+                    [ Str "with"+                    , Space+                    , Str "a"+                    , Space+                    , Str "continuation"+                    ]+                , OrderedList+                    ( 4 , LowerRoman , Period )+                    [ [ Plain+                          [ Str "sublist"+                          , Space+                          , Str "with"+                          , Space+                          , Str "roman"+                          , Space+                          , Str "numerals,"+                          , Space+                          , Str "starting"+                          , Space+                          , Str "with"+                          , Space+                          , Str "4"+                          ]+                      ]+                    , [ Plain [ Str "more" , Space , Str "items" ]+                      , OrderedList+                          ( 1 , UpperAlpha , TwoParens )+                          [ [ Plain+                                [ Str "a" , Space , Str "subsublist" ]+                            ]+                          , [ Plain+                                [ Str "a" , Space , Str "subsublist" ]+                            ]+                          ]+                      ]+                    ]+                ]+              ]+          , Para [ Str "Nesting:" ]+          , OrderedList+              ( 1 , UpperAlpha , Period )+              [ [ Plain [ Str "Upper" , Space , Str "Alpha" ]+                , OrderedList+                    ( 1 , UpperRoman , Period )+                    [ [ Plain [ Str "Upper" , Space , Str "Roman." ]+                      , OrderedList+                          ( 6 , Decimal , TwoParens )+                          [ [ Plain+                                [ Str "Decimal"+                                , Space+                                , Str "start"+                                , Space+                                , Str "with"+                                , Space+                                , Str "6"+                                ]+                            , OrderedList+                                ( 3 , LowerAlpha , OneParen )+                                [ [ Plain+                                      [ Str "Lower"+                                      , Space+                                      , Str "alpha"+                                      , Space+                                      , Str "with"+                                      , Space+                                      , Str "paren"+                                      ]+                                  ]+                                ]+                            ]+                          ]+                      ]+                    ]+                ]+              ]+          , Para [ Str "Autonumbering:" ]+          , OrderedList+              ( 1 , Decimal , Period )+              [ [ Plain [ Str "Autonumber." ] ]+              , [ Plain [ Str "More." ]+                , OrderedList+                    ( 1 , Decimal , Period )+                    [ [ Plain [ Str "Nested." ] ] ]+                ]+              ]+          , Para+              [ Str "Should"+              , Space+              , Str "not"+              , Space+              , Str "be"+              , Space+              , Str "a"+              , Space+              , Str "list"+              , Space+              , Str "item:"+              ]+          , Para [ Str "M.A.\160\&2007" ]+          , OrderedList+              ( 2 , UpperAlpha , Period )+              [ [ Plain [ Str "Williams" ] ] ]+          , HorizontalRule+          ]+      ]+  , Div+      ( "definition-lists" , [ "section" ] , [] )+      [ Header+          1+          ( "" , [] , [] )+          [ Str "Definition" , Space , Str "Lists" ]+      , Para+          [ Str "Tight"+          , Space+          , Str "using"+          , Space+          , Str "spaces:"+          ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Plain [ Str "red" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "orange" ]+            , [ [ Plain [ Str "orange" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "banana" ]+            , [ [ Plain [ Str "yellow" , Space , Str "fruit" ] ] ]+            )+          ]+      , Para+          [ Str "Tight" , Space , Str "using" , Space , Str "tabs:" ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Plain [ Str "red" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "orange" ]+            , [ [ Plain [ Str "orange" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "banana" ]+            , [ [ Plain [ Str "yellow" , Space , Str "fruit" ] ] ]+            )+          ]+      , Para [ Str "Loose:" ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Para [ Str "red" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "orange" ]+            , [ [ Para [ Str "orange" , Space , Str "fruit" ] ] ]+            )+          , ( [ Str "banana" ]+            , [ [ Para [ Str "yellow" , Space , Str "fruit" ] ] ]+            )+          ]+      , Para+          [ Str "Multiple"+          , Space+          , Str "blocks"+          , Space+          , Str "with"+          , Space+          , Str "italics:"+          ]+      , DefinitionList+          [ ( [ Emph [ Str "apple" ] ]+            , [ [ Para [ Str "red" , Space , Str "fruit" ]+                , Para+                    [ Str "contains"+                    , Space+                    , Str "seeds,"+                    , Space+                    , Str "crisp,"+                    , Space+                    , Str "pleasant"+                    , Space+                    , Str "to"+                    , Space+                    , Str "taste"+                    ]+                ]+              ]+            )+          , ( [ Emph [ Str "orange" ] ]+            , [ [ Para [ Str "orange" , Space , Str "fruit" ]+                , CodeBlock+                    ( "" , [ "" ] , [] ) "{ orange code block }\n"+                , BlockQuote+                    [ Para+                        [ Str "orange"+                        , Space+                        , Str "block"+                        , Space+                        , Str "quote"+                        ]+                    ]+                ]+              ]+            )+          ]+      , Para+          [ Str "Multiple"+          , Space+          , Str "definitions,"+          , Space+          , Str "tight:"+          ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Para [ Str "red" , Space , Str "fruit" ]+                , Para [ Str "computer" ]+                ]+              ]+            )+          , ( [ Str "orange" ]+            , [ [ Para [ Str "orange" , Space , Str "fruit" ]+                , Para [ Str "bank" ]+                ]+              ]+            )+          ]+      , Para+          [ Str "Multiple"+          , Space+          , Str "definitions,"+          , Space+          , Str "loose:"+          ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Para [ Str "red" , Space , Str "fruit" ]+                , Para [ Str "computer" ]+                ]+              ]+            )+          , ( [ Str "orange" ]+            , [ [ Para [ Str "orange" , Space , Str "fruit" ]+                , Para [ Str "bank" ]+                ]+              ]+            )+          ]+      , Para+          [ Str "Blank"+          , Space+          , Str "line"+          , Space+          , Str "after"+          , Space+          , Str "term,"+          , Space+          , Str "indented"+          , Space+          , Str "marker,"+          , Space+          , Str "alternate"+          , Space+          , Str "markers:"+          ]+      , DefinitionList+          [ ( [ Str "apple" ]+            , [ [ Para [ Str "red" , Space , Str "fruit" ]+                , Para [ Str "computer" ]+                ]+              ]+            )+          , ( [ Str "orange" ]+            , [ [ Para [ Str "orange" , Space , Str "fruit" ]+                , OrderedList+                    ( 1 , Decimal , Period )+                    [ [ Plain [ Str "sublist" ] ]+                    , [ Plain [ Str "sublist" ] ]+                    ]+                ]+              ]+            )+          ]+      ]+  , Div+      ( "html-blocks" , [ "section" ] , [] )+      [ Header+          1 ( "" , [] , [] ) [ Str "HTML" , Space , Str "Blocks" ]+      , Para+          [ Str "Simple"+          , Space+          , Str "block"+          , Space+          , Str "on"+          , Space+          , Str "one"+          , Space+          , Str "line:"+          ]+      , Div ( "" , [] , [] ) [ Para [ Str "foo" ] ]+      , Para+          [ Str "And"+          , Space+          , Str "nested"+          , Space+          , Str "without"+          , Space+          , Str "indentation:"+          ]+      , Div+          ( "" , [] , [] )+          [ Div+              ( "" , [] , [] )+              [ Div ( "" , [] , [] ) [ Para [ Str "foo" ] ] ]+          , Div ( "" , [] , [] ) [ Para [ Str "bar" ] ]+          ]+      , Para+          [ Str "Interpreted"+          , Space+          , Str "markdown"+          , Space+          , Str "in"+          , Space+          , Str "a"+          , Space+          , Str "table:"+          ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Emph [ Str "emphasized" ]+          ]+      , Para+          [ Str "And"+          , Space+          , Str "this"+          , Space+          , Str "is"+          , Space+          , Strong [ Str "strong" ]+          ]+      , Para+          [ Str "Here\8217s"+          , Space+          , Str "a"+          , Space+          , Str "simple"+          , Space+          , Str "block:"+          ]+      , Div ( "" , [] , [] ) [ Para [ Str "foo" ] ]+      , Para+          [ Str "This"+          , Space+          , Str "should"+          , Space+          , Str "be"+          , Space+          , Str "a"+          , Space+          , Str "code"+          , Space+          , Str "block,"+          , Space+          , Str "though:"+          ]+      , CodeBlock ( "" , [ "" ] , [] ) "<div>\n    foo\n</div>\n"+      , Para+          [ Str "As" , Space , Str "should" , Space , Str "this:" ]+      , CodeBlock ( "" , [ "" ] , [] ) "<div>foo</div>\n"+      , Para [ Str "Now," , Space , Str "nested:" ]+      , Div+          ( "" , [] , [] )+          [ Div+              ( "" , [] , [] )+              [ Div ( "" , [] , [] ) [ Para [ Str "foo" ] ] ]+          ]+      , Para+          [ Str "This"+          , Space+          , Str "should"+          , Space+          , Str "just"+          , Space+          , Str "be"+          , Space+          , Str "an"+          , Space+          , Str "HTML"+          , Space+          , Str "comment:"+          ]+      , Para [ Str "Multiline:" ]+      , Para [ Str "Code" , Space , Str "block:" ]+      , CodeBlock ( "" , [ "" ] , [] ) "<!-- Comment -->\n"+      , Para+          [ Str "Just"+          , Space+          , Str "plain"+          , Space+          , Str "comment,"+          , Space+          , Str "with"+          , Space+          , Str "trailing"+          , Space+          , Str "spaces"+          , Space+          , Str "on"+          , Space+          , Str "the"+          , Space+          , Str "line:"+          ]+      , Para [ Str "Code:" ]+      , CodeBlock ( "" , [ "" ] , [] ) "<hr />\n"+      , Para [ Str "Hr\8217s:" ]+      , HorizontalRule+      ]+  , Div+      ( "inline-markup" , [ "section" ] , [] )+      [ Header+          1 ( "" , [] , [] ) [ Str "Inline" , Space , Str "Markup" ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Emph [ Str "emphasized" ]+          , Str ","+          , Space+          , Str "and"+          , Space+          , Str "so"+          , Space+          , Emph [ Str "is" , Space , Str "this" ]+          , Str "."+          ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Strong [ Str "strong" ]+          , Str ","+          , Space+          , Str "and"+          , Space+          , Str "so"+          , Space+          , Strong [ Str "is" , Space , Str "this" ]+          , Str "."+          ]+      , Para+          [ Str "An"+          , Space+          , Emph+              [ Link+                  ( "" , [] , [] )+                  [ Str "emphasized" , Space , Str "link" ]+                  ( "/url" , "" )+              ]+          , Str "."+          ]+      , Para+          [ Strong+              [ Emph+                  [ Str "This"+                  , Space+                  , Str "is"+                  , Space+                  , Str "strong"+                  , Space+                  , Str "and"+                  , Space+                  , Str "em."+                  ]+              ]+          ]+      , Para+          [ Str "So"+          , Space+          , Str "is"+          , Space+          , Strong [ Emph [ Str "this" ] ]+          , Space+          , Str "word."+          ]+      , Para+          [ Strong+              [ Emph+                  [ Str "This"+                  , Space+                  , Str "is"+                  , Space+                  , Str "strong"+                  , Space+                  , Str "and"+                  , Space+                  , Str "em."+                  ]+              ]+          ]+      , Para+          [ Str "So"+          , Space+          , Str "is"+          , Space+          , Strong [ Emph [ Str "this" ] ]+          , Space+          , Str "word."+          ]+      , Para+          [ Str "This"+          , Space+          , Str "is"+          , Space+          , Str "code:"+          , Space+          , Code ( "" , [] , [] ) ">"+          , Str ","+          , Space+          , Code ( "" , [] , [] ) "$"+          , Str ","+          , Space+          , Code ( "" , [] , [] ) "\\`, "+          , Str "$"+          , Code ( "" , [] , [] ) ", "+          , Str "<html>"+          , Code ( "" , [] , [] ) "."+          ]+      , Para+          [ Span+              ( "" , [ "deleted" ] , [] )+              [ Str "This"+              , Space+              , Str "is"+              , Space+              , Emph [ Str "strikeout" ]+              , Str "."+              ]+          ]+      , Para+          [ Str "Superscripts:"+          , Space+          , Str "a"+          , Superscript [ Str "bc" ]+          , Str "d"+          , Space+          , Str "a"+          , Superscript [ Emph [ Str "hello" ] ]+          , Space+          , Str "a"+          , Superscript [ Str "hello\160there" ]+          , Str "."+          ]+      , Para+          [ Str "Subscripts:"+          , Space+          , Str "H"+          , Subscript [ Str "2" ]+          , Str "O,"+          , Space+          , Str "H"+          , Subscript [ Str "23" ]+          , Str "O,"+          , Space+          , Str "H"+          , Subscript [ Str "many\160of\160them" ]+          , Str "O."+          ]+      , Para+          [ Str "These"+          , Space+          , Str "should"+          , Space+          , Str "not"+          , Space+          , Str "be"+          , Space+          , Str "superscripts"+          , Space+          , Str "or"+          , Space+          , Str "subscripts,"+          , Space+          , Str "because"+          , Space+          , Str "of"+          , Space+          , Str "the"+          , Space+          , Str "unescaped"+          , Space+          , Str "spaces:"+          , SoftBreak+          , Str "a^b"+          , Space+          , Str "c^d,"+          , Space+          , Str "a~b"+          , Space+          , Str "c~d."+          ]+      , HorizontalRule+      ]+  , Div+      ( "smart-quotes-ellipses-dashes" , [ "section" ] , [] )+      [ Header+          1+          ( "" , [] , [] )+          [ Str "Smart"+          , Space+          , Str "quotes,"+          , Space+          , Str "ellipses,"+          , Space+          , Str "dashes"+          ]+      , Para+          [ Quoted DoubleQuote [ Str "Hello," ]+          , Space+          , Str "said"+          , Space+          , Str "the"+          , Space+          , Str "spider."+          , Space+          , Quoted+              DoubleQuote+              [ Quoted SingleQuote [ Str "Shelob" ]+              , Space+              , Str "is"+              , Space+              , Str "my"+              , Space+              , Str "name."+              ]+          ]+      , Para+          [ Quoted SingleQuote [ Str "A" ]+          , Str ","+          , Space+          , Quoted SingleQuote [ Str "B" ]+          , Str ","+          , Space+          , Str "and"+          , Space+          , Quoted SingleQuote [ Str "C" ]+          , Space+          , Str "are"+          , Space+          , Str "letters."+          ]+      , Para+          [ Quoted SingleQuote [ Str "Oak," ]+          , Space+          , Quoted SingleQuote [ Str "elm," ]+          , Space+          , Str "and"+          , Space+          , Quoted SingleQuote [ Str "beech" ]+          , Space+          , Str "are"+          , Space+          , Str "names"+          , Space+          , Str "of"+          , Space+          , Str "trees."+          , Space+          , Str "So"+          , Space+          , Str "is"+          , Space+          , Quoted SingleQuote [ Str "pine." ]+          ]+      , Para+          [ Quoted+              SingleQuote+              [ Str "He"+              , Space+              , Str "said,"+              , Space+              , Quoted+                  DoubleQuote+                  [ Str "I"+                  , Space+                  , Str "want"+                  , Space+                  , Str "to"+                  , Space+                  , Str "go."+                  ]+              ]+          , Space+          , Str "Were"+          , Space+          , Str "you"+          , Space+          , Str "alive"+          , Space+          , Str "in"+          , Space+          , Str "the"+          , Space+          , Str "70\8217s?"+          ]+      , Para+          [ Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "some"+          , Space+          , Str "quoted"+          , Space+          , Quoted SingleQuote [ Code ( "" , [] , [] ) "code" ]+          , Space+          , Str "and"+          , Space+          , Str "a"+          , Space+          , Quoted+              DoubleQuote+              [ Link+                  ( "" , [] , [] )+                  [ Str "quoted" , SoftBreak , Str "link" ]+                  ( "http://example.com/?foo=1&bar=2" , "" )+              ]+          , Str "."+          ]+      , Para+          [ Str "Some"+          , Space+          , Str "dashes:"+          , Space+          , Str "one\8212two"+          , Space+          , Str "\8212"+          , Space+          , Str "three\8212four"+          , Space+          , Str "\8212"+          , Space+          , Str "five."+          ]+      , Para+          [ Str "Dashes"+          , Space+          , Str "between"+          , Space+          , Str "numbers:"+          , Space+          , Str "5\8211\&7,"+          , Space+          , Str "255\8211\&66,"+          , Space+          , Str "1987\8211\&1999."+          ]+      , Para [ Str "Ellipses\8230and\8230and\8230." ]+      , HorizontalRule+      ]+  , Div+      ( "latex" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "LaTeX" ]+      , BulletList+          [ []+          , [ Plain [ Math InlineMath "2+2=4" ] ]+          , [ Plain [ Math InlineMath "x \\in y" ] ]+          , [ Plain [ Math InlineMath "\\alpha \\wedge \\omega" ] ]+          , [ Plain [ Math InlineMath "223" ] ]+          , [ Plain [ Math InlineMath "p" , Str "-Tree" ] ]+          , [ Plain+                [ Str "Here\8217s"+                , Space+                , Str "some"+                , Space+                , Str "display"+                , Space+                , Str "math:"+                , SoftBreak+                , Math+                    DisplayMath+                    "\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"+                ]+            ]+          , [ Plain+                [ Str "Here\8217s"+                , Space+                , Str "one"+                , Space+                , Str "that"+                , Space+                , Str "has"+                , Space+                , Str "a"+                , Space+                , Str "line"+                , Space+                , Str "break"+                , Space+                , Str "in"+                , Space+                , Str "it:"+                , Space+                , Math InlineMath "\\alpha + \\omega \\times x^2"+                , Str "."+                ]+            ]+          ]+      , Para+          [ Str "These"+          , Space+          , Str "shouldn\8217t"+          , Space+          , Str "be"+          , Space+          , Str "math:"+          ]+      , BulletList+          [ [ Plain+                [ Str "To"+                , Space+                , Str "get"+                , Space+                , Str "the"+                , Space+                , Str "famous"+                , Space+                , Str "equation,"+                , Space+                , Str "write"+                , Space+                , Code ( "" , [] , [] ) "$e = mc^2$"+                , Str "."+                ]+            ]+          , [ Plain+                [ Str "$22,000"+                , Space+                , Str "is"+                , Space+                , Str "a"+                , Space+                , Emph [ Str "lot" ]+                , Space+                , Str "of"+                , Space+                , Str "money."+                , Space+                , Str "So"+                , Space+                , Str "is"+                , Space+                , Str "$34,000."+                , Space+                , Str "(It"+                , Space+                , Str "worked"+                , Space+                , Str "if"+                , Space+                , Quoted DoubleQuote [ Str "lot" ]+                , Space+                , Str "is"+                , SoftBreak+                , Str "emphasized.)"+                ]+            ]+          , [ Plain+                [ Str "Shoes"+                , Space+                , Str "($20)"+                , Space+                , Str "and"+                , Space+                , Str "socks"+                , Space+                , Str "($5)."+                ]+            ]+          , [ Plain+                [ Str "Escaped"+                , Space+                , Code ( "" , [] , [] ) "$"+                , Str ":"+                , Space+                , Str "$73"+                , Space+                , Emph+                    [ Str "this"+                    , Space+                    , Str "should"+                    , Space+                    , Str "be"+                    , Space+                    , Str "emphasized"+                    ]+                , Space+                , Str "23$."+                ]+            ]+          ]+      , Para+          [ Str "Here\8217s"+          , Space+          , Str "a"+          , Space+          , Str "LaTeX"+          , Space+          , Str "table:"+          ]+      , HorizontalRule+      ]+  , Div+      ( "special-characters" , [ "section" ] , [] )+      [ Header+          1+          ( "" , [] , [] )+          [ Str "Special" , Space , Str "Characters" ]+      , Para+          [ Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "some"+          , Space+          , Str "unicode:"+          ]+      , BulletList+          [ [ Plain+                [ Str "I" , Space , Str "hat:" , Space , Str "\206" ]+            ]+          , [ Plain+                [ Str "o" , Space , Str "umlaut:" , Space , Str "\246" ]+            ]+          , [ Plain [ Str "section:" , Space , Str "\167" ] ]+          , [ Plain+                [ Str "set"+                , Space+                , Str "membership:"+                , Space+                , Str "\8712"+                ]+            ]+          , [ Plain [ Str "copyright:" , Space , Str "\169" ] ]+          ]+      , Para+          [ Str "AT&T"+          , Space+          , Str "has"+          , Space+          , Str "an"+          , Space+          , Str "ampersand"+          , Space+          , Str "in"+          , Space+          , Str "their"+          , Space+          , Str "name."+          ]+      , Para+          [ Str "AT&T"+          , Space+          , Str "is"+          , Space+          , Str "another"+          , Space+          , Str "way"+          , Space+          , Str "to"+          , Space+          , Str "write"+          , Space+          , Str "it."+          ]+      , Para+          [ Str "This" , Space , Str "&" , Space , Str "that." ]+      , Para [ Str "4" , Space , Str "<" , Space , Str "5." ]+      , Para [ Str "6" , Space , Str ">" , Space , Str "5." ]+      , Para [ Str "Backslash:" , Space , Str "\\" ]+      , Para [ Str "Backtick:" , Space , Str "`" ]+      , Para [ Str "Asterisk:" , Space , Str "*" ]+      , Para [ Str "Underscore:" , Space , Str "_" ]+      , Para+          [ Str "Left" , Space , Str "brace:" , Space , Str "{" ]+      , Para+          [ Str "Right" , Space , Str "brace:" , Space , Str "}" ]+      , Para+          [ Str "Left" , Space , Str "bracket:" , Space , Str "[" ]+      , Para+          [ Str "Right" , Space , Str "bracket:" , Space , Str "]" ]+      , Para+          [ Str "Left" , Space , Str "paren:" , Space , Str "(" ]+      , Para+          [ Str "Right" , Space , Str "paren:" , Space , Str ")" ]+      , Para [ Str "Greater-than:" , Space , Str ">" ]+      , Para [ Str "Hash:" , Space , Str "#" ]+      , Para [ Str "Period:" , Space , Str "." ]+      , Para [ Str "Bang:" , Space , Str "!" ]+      , Para [ Str "Plus:" , Space , Str "+" ]+      , Para [ Str "Minus:" , Space , Str "-" ]+      , HorizontalRule+      ]+  , Div+      ( "links" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Links" ]+      , Div+          ( "explicit" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Explicit" ]+          , Para+              [ Str "Just"+              , Space+              , Str "a"+              , Space+              , Link ( "" , [] , [] ) [ Str "URL" ] ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Link+                  ( "" , [] , [ ( "title" , "title" ) ] )+                  [ Str "URL"+                  , Space+                  , Str "and"+                  , Space+                  , Str "title"+                  ]+                  ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Link+                  ( ""+                  , []+                  , [ ( "title" , "title preceded by two spaces" ) ]+                  )+                  [ Str "URL"+                  , Space+                  , Str "and"+                  , Space+                  , Str "title"+                  ]+                  ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Link+                  ( ""+                  , []+                  , [ ( "title" , "title preceded by a tab" ) ]+                  )+                  [ Str "URL"+                  , Space+                  , Str "and"+                  , Space+                  , Str "title"+                  ]+                  ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Link+                  ( ""+                  , []+                  , [ ( "title" , "title with \"quotes\" in it" ) ]+                  )+                  [ Str "URL"+                  , Space+                  , Str "and"+                  , Space+                  , Str "title"+                  ]+                  ( "/url/" , "" )+              ]+          , Para+              [ Link+                  ( ""+                  , []+                  , [ ( "title" , "title with single quotes" ) ]+                  )+                  [ Str "URL"+                  , Space+                  , Str "and"+                  , Space+                  , Str "title"+                  ]+                  ( "/url/" , "" )+              ]+          , Para+              [ Link+                  ( "" , [] , [] )+                  [ Str "with_underscore" ]+                  ( "/url/with_underscore" , "" )+              ]+          , Para+              [ Link+                  ( "" , [] , [] )+                  [ Str "Email" , Space , Str "link" ]+                  ( "mailto:nobody@nowhere.net" , "" )+              ]+          , Para+              [ Link ( "" , [] , [] ) [ Str "Empty" ] ( "" , "" )+              , Str "."+              ]+          ]+      , Div+          ( "reference" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Reference" ]+          , Para+              [ Str "Foo"+              , Space+              , Link ( "" , [] , [] ) [ Str "bar" ] ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Str "With"+              , Space+              , Link+                  ( "" , [] , [] )+                  [ Str "embedded" , Space , Str "[brackets]" ]+                  ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Link ( "" , [] , [] ) [ Str "b" ] ( "/url/" , "" )+              , Space+              , Str "by"+              , Space+              , Str "itself"+              , Space+              , Str "should"+              , Space+              , Str "be"+              , Space+              , Str "a"+              , Space+              , Str "link."+              ]+          , Para+              [ Str "Indented"+              , Space+              , Link ( "" , [] , [] ) [ Str "once" ] ( "/url" , "" )+              , Str "."+              ]+          , Para+              [ Str "Indented"+              , Space+              , Link ( "" , [] , [] ) [ Str "twice" ] ( "/url" , "" )+              , Str "."+              ]+          , Para+              [ Str "Indented"+              , Space+              , Link ( "" , [] , [] ) [ Str "thrice" ] ( "/url" , "" )+              , Str "."+              ]+          , Para+              [ Str "This"+              , Space+              , Str "should"+              , Space+              , Str "[not][]"+              , Space+              , Str "be"+              , Space+              , Str "a"+              , Space+              , Str "link."+              ]+          , CodeBlock ( "" , [ "" ] , [] ) "[not]: /url\n"+          , Para+              [ Str "Foo"+              , Space+              , Link+                  ( ""+                  , []+                  , [ ( "title" , "Title with \"quotes\" inside" ) ]+                  )+                  [ Str "bar" ]+                  ( "/url/" , "" )+              , Str "."+              ]+          , Para+              [ Str "Foo"+              , Space+              , Link+                  ( ""+                  , []+                  , [ ( "title" , "Title with \"quote\" inside" ) ]+                  )+                  [ Str "biz" ]+                  ( "/url/" , "" )+              , Str "."+              ]+          ]+      , Div+          ( "with-ampersands" , [ "section" ] , [] )+          [ Header+              2+              ( "" , [] , [] )+              [ Str "With" , Space , Str "ampersands" ]+          , Para+              [ Str "Here\8217s"+              , Space+              , Str "a"+              , Space+              , Link+                  ( "" , [] , [] )+                  [ Str "link"+                  , Space+                  , Str "with"+                  , Space+                  , Str "an"+                  , Space+                  , Str "ampersand"+                  , Space+                  , Str "in"+                  , Space+                  , Str "the"+                  , Space+                  , Str "URL"+                  ]+                  ( "http://example.com/?foo=1&bar=2" , "" )+              , Str "."+              ]+          , Para+              [ Str "Here\8217s"+              , Space+              , Str "a"+              , Space+              , Str "link"+              , Space+              , Str "with"+              , Space+              , Str "an"+              , Space+              , Str "amersand"+              , Space+              , Str "in"+              , Space+              , Str "the"+              , Space+              , Str "link"+              , Space+              , Str "text:"+              , SoftBreak+              , Link+                  ( "" , [] , [ ( "title" , "AT&T" ) ] )+                  [ Str "AT&T" ]+                  ( "http://att.com/" , "" )+              , Str "."+              ]+          , Para+              [ Str "Here\8217s"+              , Space+              , Str "an"+              , Space+              , Link+                  ( "" , [] , [] )+                  [ Str "inline" , Space , Str "link" ]+                  ( "/script?foo=1&bar=2" , "" )+              , Str "."+              ]+          , Para+              [ Str "Here\8217s"+              , Space+              , Str "an"+              , Space+              , Link+                  ( "" , [] , [] )+                  [ Str "inline"+                  , Space+                  , Str "link"+                  , Space+                  , Str "in"+                  , Space+                  , Str "pointy"+                  , Space+                  , Str "braces"+                  ]+                  ( "/script?foo=1&bar=2" , "" )+              , Str "."+              ]+          ]+      , Div+          ( "autolinks" , [ "section" ] , [] )+          [ Header 2 ( "" , [] , [] ) [ Str "Autolinks" ]+          , Para+              [ Str "With"+              , Space+              , Str "an"+              , Space+              , Str "ampersand:"+              , Space+              , Link+                  ( "" , [ "uri" ] , [] )+                  [ Str "http://example.com/?foo=1&bar=2" ]+                  ( "http://example.com/?foo=1&bar=2" , "" )+              ]+          , BulletList+              [ [ Plain+                    [ Str "In" , Space , Str "a" , Space , Str "list?" ]+                ]+              , [ Plain+                    [ Link+                        ( "" , [ "uri" ] , [] )+                        [ Str "http://example.com/" ]+                        ( "http://example.com/" , "" )+                    ]+                ]+              , [ Plain [ Str "It" , Space , Str "should." ] ]+              ]+          , Para+              [ Str "An"+              , Space+              , Str "e-mail"+              , Space+              , Str "address:"+              , Space+              , Link+                  ( "" , [ "email" ] , [] )+                  [ Str "nobody@nowhere.net" ]+                  ( "mailto:nobody@nowhere.net" , "" )+              ]+          , BlockQuote+              [ Para+                  [ Str "Blockquoted:"+                  , Space+                  , Link+                      ( "" , [ "uri" ] , [] )+                      [ Str "http://example.com/" ]+                      ( "http://example.com/" , "" )+                  ]+              ]+          , Para+              [ Str "Auto-links"+              , Space+              , Str "should"+              , Space+              , Str "not"+              , Space+              , Str "occur"+              , Space+              , Str "here:"+              , Space+              , Code ( "" , [] , [] ) "<http://example.com/>"+              ]+          , CodeBlock+              ( "" , [ "" ] , [] ) "or here: <http://example.com/>\n"+          , HorizontalRule+          ]+      ]+  , Div+      ( "images" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Images" ]+      , Para+          [ Str "From"+          , Space+          , Quoted+              DoubleQuote+              [ Str "Voyage"+              , Space+              , Str "dans"+              , Space+              , Str "la"+              , Space+              , Str "Lune"+              ]+          , Space+          , Str "by"+          , Space+          , Str "Georges"+          , Space+          , Str "Melies"+          , Space+          , Str "(1902):"+          ]+      , Div+          ( "" , [] , [] )+          [ Para+              [ Image+                  ( "" , [] , [ ( "title" , "Voyage dans la Lune" ) ] )+                  [ Str "lalune" ]+                  ( "lalune.jpg" , "" )+              ]+          , Div ( "" , [ "caption" ] , [] ) [ Para [ Str "lalune" ] ]+          ]+      , Para+          [ Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "a"+          , Space+          , Str "movie"+          , Space+          , Image+              ( "" , [] , [] ) [ Str "movie" ] ( "movie.jpg" , "" )+          , Space+          , Str "icon."+          ]+      , HorizontalRule+      ]+  , Div+      ( "footnotes" , [ "section" ] , [] )+      [ Header 1 ( "" , [] , [] ) [ Str "Footnotes" ]+      , Para+          [ Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "a"+          , Space+          , Str "footnote"+          , Space+          , Str "reference,"+          , Note+              [ Para+                  [ Str "Here"+                  , Space+                  , Str "is"+                  , Space+                  , Str "the"+                  , Space+                  , Str "footnote."+                  , Space+                  , Str "It"+                  , Space+                  , Str "can"+                  , Space+                  , Str "go"+                  , Space+                  , Str "anywhere"+                  , Space+                  , Str "after"+                  , Space+                  , Str "the"+                  , Space+                  , Str "footnote"+                  , Space+                  , Str "reference."+                  , Space+                  , Str "It"+                  , SoftBreak+                  , Str "need"+                  , Space+                  , Str "not"+                  , Space+                  , Str "be"+                  , Space+                  , Str "placed"+                  , Space+                  , Str "at"+                  , Space+                  , Str "the"+                  , Space+                  , Str "end"+                  , Space+                  , Str "of"+                  , Space+                  , Str "the"+                  , Space+                  , Str "document."+                  ]+              ]+          , Space+          , Str "and"+          , Space+          , Str "another."+          , Note+              [ Para+                  [ Str "Here\8217s"+                  , Space+                  , Str "the"+                  , Space+                  , Str "long"+                  , Space+                  , Str "note."+                  , Space+                  , Str "This"+                  , Space+                  , Str "one"+                  , Space+                  , Str "contains"+                  , Space+                  , Str "multiple"+                  , Space+                  , Str "blocks."+                  ]+              , Para+                  [ Str "Subsequent"+                  , Space+                  , Str "blocks"+                  , Space+                  , Str "are"+                  , Space+                  , Str "indented"+                  , Space+                  , Str "to"+                  , Space+                  , Str "show"+                  , Space+                  , Str "that"+                  , Space+                  , Str "they"+                  , Space+                  , Str "belong"+                  , Space+                  , Str "to"+                  , Space+                  , Str "the"+                  , Space+                  , Str "footnote"+                  , Space+                  , Str "(as"+                  , SoftBreak+                  , Str "with"+                  , Space+                  , Str "list"+                  , Space+                  , Str "items)."+                  ]+              , CodeBlock ( "" , [ "" ] , [] ) "{ <code> }\n"+              , Para+                  [ Str "If"+                  , Space+                  , Str "you"+                  , Space+                  , Str "want,"+                  , Space+                  , Str "you"+                  , Space+                  , Str "can"+                  , Space+                  , Str "indent"+                  , Space+                  , Str "every"+                  , Space+                  , Str "line,"+                  , Space+                  , Str "but"+                  , Space+                  , Str "you"+                  , Space+                  , Str "can"+                  , Space+                  , Str "also"+                  , Space+                  , Str "be"+                  , Space+                  , Str "lazy"+                  , Space+                  , Str "and"+                  , Space+                  , Str "just"+                  , SoftBreak+                  , Str "indent"+                  , Space+                  , Str "the"+                  , Space+                  , Str "first"+                  , Space+                  , Str "line"+                  , Space+                  , Str "of"+                  , Space+                  , Str "each"+                  , Space+                  , Str "block."+                  ]+              ]+          , Space+          , Str "This"+          , Space+          , Str "should"+          , Space+          , Emph [ Str "not" ]+          , Space+          , Str "be"+          , Space+          , Str "a"+          , SoftBreak+          , Str "footnote"+          , Space+          , Str "reference,"+          , Space+          , Str "because"+          , Space+          , Str "it"+          , Space+          , Str "contains"+          , Space+          , Str "a"+          , Space+          , Str "space.[^my"+          , Space+          , Str "note]"+          , Space+          , Str "Here"+          , Space+          , Str "is"+          , Space+          , Str "an"+          , Space+          , Str "inline"+          , SoftBreak+          , Str "note."+          , Note+              [ Para+                  [ Str "This"+                  , Space+                  , Str "is"+                  , Space+                  , Emph [ Str "easier" ]+                  , Space+                  , Str "to"+                  , Space+                  , Str "type."+                  , Space+                  , Str "Inline"+                  , Space+                  , Str "notes"+                  , Space+                  , Str "may"+                  , Space+                  , Str "contain"+                  , SoftBreak+                  , Link+                      ( "" , [] , [] )+                      [ Str "links" ]+                      ( "http://google.com" , "" )+                  , Space+                  , Str "and"+                  , Space+                  , Code ( "" , [] , [] ) "]"+                  , Space+                  , Str "verbatim"+                  , Space+                  , Str "characters,"+                  , Space+                  , Str "as"+                  , Space+                  , Str "well"+                  , Space+                  , Str "as"+                  , SoftBreak+                  , Str "[bracketed"+                  , Space+                  , Str "text]."+                  ]+              ]+          ]+      , BlockQuote+          [ Para+              [ Str "Notes"+              , Space+              , Str "can"+              , Space+              , Str "go"+              , Space+              , Str "in"+              , Space+              , Str "quotes."+              , Note [ Para [ Str "In" , Space , Str "quote." ] ]+              ]+          ]+      , OrderedList+          ( 1 , Decimal , Period )+          [ [ Plain+                [ Str "And"+                , Space+                , Str "in"+                , Space+                , Str "list"+                , Space+                , Str "items."+                , Note [ Para [ Str "In" , Space , Str "list." ] ]+                ]+            ]+          ]+      , Para+          [ Str "This"+          , Space+          , Str "paragraph"+          , Space+          , Str "should"+          , Space+          , Str "not"+          , Space+          , Str "be"+          , Space+          , Str "part"+          , Space+          , Str "of"+          , Space+          , Str "the"+          , Space+          , Str "note,"+          , Space+          , Str "as"+          , Space+          , Str "it"+          , Space+          , Str "is"+          , Space+          , Str "not"+          , Space+          , Str "indented."           ]       ]   ]
+ test/docx/cross_reference.docx view

binary file changed (absent → 14978 bytes)

+ test/docx/cross_reference.native view
@@ -0,0 +1,7 @@+[ Header 1 ( "title" , [] , [] ) [ Str "TITLE" ]+, Para+    [ Str "Cross-reference:"+    , Space+    , Link ( "" , [] , [] ) [ Str "TITLE" ] ( "#title" , "" )+    ]+]
test/docx/mendeley_citations_plus.native view
@@ -7,9 +7,9 @@                 [ MetaMap                     (fromList                        [ ( "DOI"-                         , MetaInlines [ Str "10.1145/1929887.1929902" ]+                         , MetaString "10.1145/1929887.1929902"                          )-                       , ( "ISSN" , MetaInlines [ Str "2153-2184" ] )+                       , ( "ISSN" , MetaString "2153-2184" )                        , ( "author"                          , MetaList                              [ MetaMap
test/docx/table_captions_with_field.native view
@@ -1,8 +1,23 @@ [ Para-    [ Str "See" , Space , Str "Table" , Space , Str "1." ]+    [ Str "See"+    , Space+    , Link+        ( "" , [] , [] )+        [ Str "Table" , Space , Str "1" ]+        ( "#_Ref71265628" , "" )+    , Str "."+    ] , Table     ( "" , [] , [] )-    (Caption Nothing [ Para [ Str "Table" , Space , Str "1" ] ])+    (Caption+       Nothing+       [ Para+           [ Span ( "_Ref71265628" , [ "anchor" ] , [] ) []+           , Str "Table"+           , Space+           , Str "1"+           ]+       ])     [ ( AlignDefault , ColWidth 0.7605739372523824 )     , ( AlignDefault , ColWidth 0.11971303137380876 )     , ( AlignDefault , ColWidth 0.11971303137380876 )@@ -79,7 +94,15 @@ , Header 2 ( "section" , [] , [] ) [] , Table     ( "" , [] , [] )-    (Caption Nothing [ Para [ Str "Table" , Space , Str "2" ] ])+    (Caption+       Nothing+       [ Para+           [ Span ( "_Ref71265695" , [ "anchor" ] , [] ) []+           , Str "Table"+           , Space+           , Str "2"+           ]+       ])     [ ( AlignDefault , ColWidth 0.33329636202307006 )     , ( AlignDefault , ColWidth 0.33329636202307006 )     , ( AlignDefault , ColWidth 0.33340727595385977 )@@ -111,5 +134,12 @@     [ TableBody ( "" , [] , [] ) (RowHeadColumns 0) [] [] ]     (TableFoot ( "" , [] , [] ) []) , Para-    [ Str "See" , Space , Str "Table" , Space , Str "2." ]+    [ Str "See"+    , Space+    , Link+        ( "" , [] , [] )+        [ Str "Table" , Space , Str "2" ]+        ( "#_Ref71265695" , "" )+    , Str "."+    ] ]
test/docx/zotero_citations_plus.native view
@@ -6,9 +6,7 @@             , MetaList                 [ MetaMap                     (fromList-                       [ ( "DOI"-                         , MetaInlines [ Str "10.1002/2016GL069961" ]-                         )+                       [ ( "DOI" , MetaString "10.1002/2016GL069961" )                        , ( "author"                          , MetaList                              [ MetaMap@@ -97,16 +95,9 @@                 , MetaMap                     (fromList                        [ ( "DOI"-                         , MetaInlines-                             [ Str "10.1007/s00382-013-1683-2" ]-                         )-                       , ( "ISSN"-                         , MetaInlines-                             [ Str "0930-7575,"-                             , Space-                             , Str "1432-0894"-                             ]+                         , MetaString "10.1007/s00382-013-1683-2"                          )+                       , ( "ISSN" , MetaString "0930-7575, 1432-0894" )                        , ( "author"                          , MetaList                              [ MetaMap@@ -174,7 +165,7 @@                 , MetaMap                     (fromList                        [ ( "DOI"-                         , MetaInlines [ Str "10.5194/gmd-9-3751-2016" ]+                         , MetaString "10.5194/gmd-9-3751-2016"                          )                        , ( "author"                          , MetaList
+ test/pptx-reader/basic.native view
@@ -0,0 +1,149 @@+[ Header 2 ( "slide-1" , [] , [] ) [ Str "LLMs" ]+, BulletList+    [ [ Plain+          [ Str+              "Provider  \61664 Available LLMs \8211 who manages? How?"+          ]+      ]+    , [ Plain+          [ Str+              "EW maintained list of \8220approved\8221 LLMs for Universal workers"+          ]+      ]+    , [ Plain+          [ Str+              "Rebuilding of UWs to the \8220Newgen\8221 thing completely"+          ]+      ]+    , [ Plain [ Str "Streaming support" ] ]+    , [ Plain [ Str "Multimodal (voice streaming) models?" ] ]+    ]+, Header+    2+    ( "slide-2" , [] , [] )+    [ Str "Everworker   venn   diagram" ]+, Para [ Str "SKILLS" ]+, Para [ Str "" ]+, Para [ Str "Specialized Workers / Workflows:" ]+, Para [ Str "" ]+, Para [ Str "n8n, UI Path, " ]+, Para [ Str "other RPA" ]+, Para [ Str "BRAINS" ]+, Para [ Str "" ]+, Para [ Str "Universal Workers / AI Agents:" ]+, Para [ Str "" ]+, Para [ Str "openai , anthropic," ]+, Para [ Str "Crew AI, other " ]+, Para [ Str "\8220AI natives\8221" ]+, Para [ Str "KNOWLEDGE " ]+, Para [ Str "" ]+, Para [ Str "Data / " ]+, Para [ Str "RAG Pipelines" ]+, Para [ Str "" ]+, Para+    [ Str "Vector DBs, specialized data prep vendors, \8230" ]+, Para [ Str "glean" ]+, Para [ Str "EW" ]+, Header 2 ( "slide-3" , [] , [] ) [ Str "Table" ]+, Table+    ( "" , [] , [] )+    (Caption Nothing [])+    [ ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    , ( AlignDefault , ColWidthDefault )+    ]+    (TableHead+       ( "" , [] , [] )+       [ Row+           ( "" , [] , [] )+           [ Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Col1" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Col2" ] ]+           , Cell+               ( "" , [] , [] )+               AlignDefault+               (RowSpan 1)+               (ColSpan 1)+               [ Plain [ Str "Col3" ] ]+           ]+       ])+    [ TableBody+        ( "" , [] , [] )+        (RowHeadColumns 0)+        []+        [ Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Name" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Anton" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Antich" ] ]+            ]+        , Row+            ( "" , [] , [] )+            [ Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "Age" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "23" ] ]+            , Cell+                ( "" , [] , [] )+                AlignDefault+                (RowSpan 1)+                (ColSpan 1)+                [ Plain [ Str "years" ] ]+            ]+        ]+    ]+    (TableFoot ( "" , [] , [] ) [])+, Para+    [ Image+        ( "" , [] , [] ) [] ( "ppt/media/image1.png" , "Picture 6" )+    ]+, Header 2 ( "slide-4" , [] , [] ) [ Str "Smart Art" ]+, Div+    ( ""+    , [ "smartart" , "chevron2" ]+    , [ ( "layout" , "chevron2" ) ]+    )+    [ Para [ Strong [ Str "First" ] ]+    , BulletList+        [ [ Plain [ Str "another" ] ]+        , [ Plain [ Str "subtitle" ] ]+        ]+    , Para [ Strong [ Str "Second" ] ]+    , BulletList+        [ [ Plain [ Str "and yet again" ] ]+        , [ Plain [ Str "yet more" ] ]+        ]+    ]+]
+ test/pptx-reader/basic.pptx view

binary file changed (absent → 111674 bytes)

+ test/pptx/reference-no-slides.pptx view

binary file changed (absent → 30988 bytes)

+ test/pptx/reference-no-slides/add-slides/input.native view
@@ -0,0 +1,14 @@+[ Header+    2+    ( "first-slide" , [] , [] )+    [ Str "First" , Space , Str "Slide" ]+, Para [ Str "Title" ]+, Header+    2+    ( "second-slide" , [] , [] )+    [ Str "Second" , Space , Str "Slide" ]+, BulletList+    [ [ Plain [ Str "First" , Space , Str "item" ] ]+    , [ Plain [ Str "Second" , Space , Str "item" ] ]+    ]+]
+ test/pptx/reference-no-slides/add-slides/output.pptx view

binary file changed (absent → 28888 bytes)

+ test/pptx/reference-no-slides/with-notes/input.native view
@@ -0,0 +1,70 @@+[ Header+    2+    ( "first-slide" , [] , [] )+    [ Str "First" , Space , Str "Slide" ]+, Para+    [ Str "First"+    , Space+    , Str "slide"+    , Space+    , Str "with"+    , Space+    , Str "notes"+    ]+, Div+    ( "" , [ "notes" ] , [] )+    [ Para+        [ Str "Notes"+        , Space+        , Str "for"+        , Space+        , Str "the"+        , Space+        , Str "first"+        , Space+        , Str "slide"+        ]+    ]+, Header+    2+    ( "second-slide" , [] , [] )+    [ Str "Second" , Space , Str "Slide" ]+, Para+    [ Str "Slide"+    , Space+    , Str "without"+    , Space+    , Str "notes"+    ]+, Header+    2+    ( "third-slide" , [] , [] )+    [ Str "Third" , Space , Str "Slide" ]+, Para+    [ Str "Slide"+    , Space+    , Str "with"+    , Space+    , Str "notes"+    , Space+    , Str "again"+    ]+, BulletList+    [ [ Plain [ Str "First" , Space , Str "item" ] ]+    , [ Plain [ Str "Second" , Space , Str "item" ] ]+    ]+, Div+    ( "" , [ "notes" ] , [] )+    [ Para+        [ Str "Notes"+        , Space+        , Str "for"+        , Space+        , Str "the"+        , Space+        , Str "third"+        , Space+        , Str "slides"+        ]+    ]+]
+ test/pptx/reference-no-slides/with-notes/output.pptx view

binary file changed (absent → 33927 bytes)

test/s5-fancy.html view
@@ -39,7 +39,7 @@   <link rel="stylesheet" href="s5/default/opera.css" type="text/css" media="projection" id="operaFix" />   <!-- S5 JS -->   <script src="s5/default/slides.js" type="text/javascript"></script>-  <script+  <script defer=""   src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js"   type="text/javascript"></script> </head>
+ test/tables.bbcode view
@@ -0,0 +1,60 @@+Simple table with caption:++Demonstration of simple table syntax.+[table]+[tr][th]Right[/th][th]Left[/th][th]Center[/th][th]Default[/th][/tr]+[tr][td]12[/td][td]12[/td][td]12[/td][td]12[/td][/tr]+[tr][td]123[/td][td]123[/td][td]123[/td][td]123[/td][/tr]+[tr][td]1[/td][td]1[/td][td]1[/td][td]1[/td][/tr]+[/table]++Simple table without caption:++[table]+[tr][th]Right[/th][th]Left[/th][th]Center[/th][th]Default[/th][/tr]+[tr][td]12[/td][td]12[/td][td]12[/td][td]12[/td][/tr]+[tr][td]123[/td][td]123[/td][td]123[/td][td]123[/td][/tr]+[tr][td]1[/td][td]1[/td][td]1[/td][td]1[/td][/tr]+[/table]++Simple table indented two spaces:++Demonstration of simple table syntax.+[table]+[tr][th]Right[/th][th]Left[/th][th]Center[/th][th]Default[/th][/tr]+[tr][td]12[/td][td]12[/td][td]12[/td][td]12[/td][/tr]+[tr][td]123[/td][td]123[/td][td]123[/td][td]123[/td][/tr]+[tr][td]1[/td][td]1[/td][td]1[/td][td]1[/td][/tr]+[/table]++Multiline table with caption:++Here's the caption. It may span multiple lines.+[table]+[tr][th]Centered Header[/th][th]Left Aligned[/th][th]Right Aligned[/th][th]Default aligned[/th][/tr]+[tr][td]First[/td][td]row[/td][td]12.0[/td][td]Example of a row that spans multiple lines.[/td][/tr]+[tr][td]Second[/td][td]row[/td][td]5.0[/td][td]Here's another one. Note the blank line between rows.[/td][/tr]+[/table]++Multiline table without caption:++[table]+[tr][th]Centered Header[/th][th]Left Aligned[/th][th]Right Aligned[/th][th]Default aligned[/th][/tr]+[tr][td]First[/td][td]row[/td][td]12.0[/td][td]Example of a row that spans multiple lines.[/td][/tr]+[tr][td]Second[/td][td]row[/td][td]5.0[/td][td]Here's another one. Note the blank line between rows.[/td][/tr]+[/table]++Table without column headers:++[table]+[tr][td]12[/td][td]12[/td][td]12[/td][td]12[/td][/tr]+[tr][td]123[/td][td]123[/td][td]123[/td][td]123[/td][/tr]+[tr][td]1[/td][td]1[/td][td]1[/td][td]1[/td][/tr]+[/table]++Multiline table without column headers:++[table]+[tr][td]First[/td][td]row[/td][td]12.0[/td][td]Example of a row that spans multiple lines.[/td][/tr]+[tr][td]Second[/td][td]row[/td][td]5.0[/td][td]Here's another one. Note the blank line between rows.[/td][/tr]+[/table]
test/test-pandoc.hs view
@@ -12,6 +12,8 @@ import qualified Tests.Old import qualified Tests.Readers.Creole import qualified Tests.Readers.Docx+import qualified Tests.Readers.Pptx+import qualified Tests.Readers.Xlsx import qualified Tests.Readers.DokuWiki import qualified Tests.Readers.EPUB import qualified Tests.Readers.FB2@@ -50,6 +52,7 @@ import qualified Tests.Writers.AnnotatedTable import qualified Tests.Writers.TEI import qualified Tests.Writers.Markua+import qualified Tests.Writers.BBCode import qualified Tests.XML import qualified Tests.MediaBag import Text.Pandoc.Shared (inDirectory)@@ -82,6 +85,7 @@           , testGroup "PowerPoint" Tests.Writers.Powerpoint.tests           , testGroup "Ms" Tests.Writers.Ms.tests           , testGroup "AnnotatedTable" Tests.Writers.AnnotatedTable.tests+          , testGroup "BBCode" Tests.Writers.BBCode.tests           ]         , testGroup "Readers"           [ testGroup "LaTeX" Tests.Readers.LaTeX.tests@@ -93,6 +97,8 @@           , testGroup "RST" Tests.Readers.RST.tests           , testGroup "RTF" Tests.Readers.RTF.tests           , testGroup "Docx" Tests.Readers.Docx.tests+          , testGroup "Pptx" Tests.Readers.Pptx.tests+          , testGroup "Xlsx" Tests.Readers.Xlsx.tests           , testGroup "ODT" Tests.Readers.ODT.tests           , testGroup "Txt2Tags" Tests.Readers.Txt2Tags.tests           , testGroup "EPUB" Tests.Readers.EPUB.tests
test/typst-reader.native view
@@ -3208,7 +3208,7 @@                           [ Para                               [ Span                                   ( "" , [ "box" ] , [] )-                                  [ Math InlineMath "\\hslash"+                                  [ Math InlineMath "\295"                                   , Str "\8192"                                   , Code                                       ( "" , [] , [] ) "planck.reduce"@@ -3610,12 +3610,14 @@                           [ Para                               [ Span                                   ( "" , [ "box" ] , [] )-                                  [ Math InlineMath "\\leftrightarrow"+                                  [ Math+                                      InlineMath "\\longleftrightarrow"                                   , Str "\8192"-                                  , Code ( "" , [] , [] ) "<->"+                                  , Code ( "" , [] , [] ) "<-->"                                   , Str ","                                   , Space-                                  , Code ( "" , [] , [] ) "arrow.l.r"+                                  , Code+                                      ( "" , [] , [] ) "arrow.l.r.long"                                   ]                               ]                           ]
test/undergradmath.typ view
@@ -276,7 +276,7 @@   cell($->$, [`->`, `arrow.r`]), cell($|->$, [`|->`, `arrow.r.bar`]),   cell($arrow.r.not$, `arrow.r.not`), cell($arrow.r.long.bar$, `arrow.r.long.bar`),   cell($arrow.r.long$, `arrow.r.long`), cell($<-$, [`<-`, `arrow.l`]),-  cell($=>$, [`=>`, `arrow.r.double`]), cell($<->$, [`<->`, `arrow.l.r`]),+  cell($=>$, [`=>`, `arrow.r.double`]), cell($<-->$, [`<-->`, `arrow.l.r.long`]),   cell($arrow.r.double.not$, `arrow.r.double.not`), cell($arrow.b$, `arrow.b`),   cell($arrow.r.double.long$, `arrow.r.double.long`), cell($arrow.t$, `arrow.t`),   cell($arrow.squiggly$, `arrow.squiggly`), cell($arrow.t.b$, `arrow.t.b`),
+ test/writer.bbcode view
@@ -0,0 +1,729 @@+This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.++* * *++[u][b]Headers[/b][/u]++[b]Level 2 with an [url=/url]embedded link[/url][/b]++[u]Level 3 with [i]emphasis[/i][/u]++Level 4++Level 5++[u][b]Level 1[/b][/u]++[b]Level 2 with [i]emphasis[/i][/b]++[u]Level 3[/u]++with no blank line++[b]Level 2[/b]++with no blank line++* * *++[u][b]Paragraphs[/b][/u]++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.++* * *++[u][b]Block Quotes[/b][/u]++E-mail style:++[quote]+This is a block quote. It is pretty short.+[/quote]++[quote]+Code in a block quote:++[code]sub status {+    print "working";+}+[/code]++A list:++[list=1]+[*]item one+[*]item two+[/list]++Nested block quotes:++[quote]+nested+[/quote]++[quote]+nested+[/quote]+[/quote]++This should not be a block quote: 2 > 1.++And a following paragraph.++* * *++[u][b]Code Blocks[/b][/u]++Code:++[code]---- (should be four hyphens)++sub status {+    print "working";+}++this code block is indented by one tab+[/code]++And:++[code]    this code block is indented by two tabs++These should not be escaped:  \$ \\ \> \[ \{+[/code]++* * *++[u][b]Lists[/b][/u]++[b]Unordered[/b]++Asterisks tight:++[list]+[*]asterisk 1+[*]asterisk 2+[*]asterisk 3+[/list]++Asterisks loose:++[list]+[*]asterisk 1+[*]asterisk 2+[*]asterisk 3+[/list]++Pluses tight:++[list]+[*]Plus 1+[*]Plus 2+[*]Plus 3+[/list]++Pluses loose:++[list]+[*]Plus 1+[*]Plus 2+[*]Plus 3+[/list]++Minuses tight:++[list]+[*]Minus 1+[*]Minus 2+[*]Minus 3+[/list]++Minuses loose:++[list]+[*]Minus 1+[*]Minus 2+[*]Minus 3+[/list]++[b]Ordered[/b]++Tight:++[list=1]+[*]First+[*]Second+[*]Third+[/list]++and:++[list=1]+[*]One+[*]Two+[*]Three+[/list]++Loose using tabs:++[list=1]+[*]First+[*]Second+[*]Third+[/list]++and using spaces:++[list=1]+[*]One+[*]Two+[*]Three+[/list]++Multiple paragraphs:++[list=1]+[*]Item 1, graf one.++Item 1. graf two. The quick brown fox jumped over the lazy dog's back.+[*]Item 2.+[*]Item 3.+[/list]++[b]Nested[/b]++[list]+[*]Tab++[list]+[*]Tab++[list]+[*]Tab+[/list]+[/list]+[/list]++Here's another:++[list=1]+[*]First+[*]Second:++[list]+[*]Fee+[*]Fie+[*]Foe+[/list]+[*]Third+[/list]++Same thing but with paragraphs:++[list=1]+[*]First+[*]Second:++[list]+[*]Fee+[*]Fie+[*]Foe+[/list]+[*]Third+[/list]++[b]Tabs and spaces[/b]++[list]+[*]this is a list item indented with tabs+[*]this is a list item indented with spaces++[list]+[*]this is an example list item indented with tabs+[*]this is an example list item indented with spaces+[/list]+[/list]++[b]Fancy list markers[/b]++[list=1]+[*]begins with 2+[*]and now 3++with a continuation++[list=i]+[*]sublist with roman numerals, starting with 4+[*]more items++[list=A]+[*]a subsublist+[*]a subsublist+[/list]+[/list]+[/list]++Nesting:++[list=A]+[*]Upper Alpha++[list=I]+[*]Upper Roman.++[list=1]+[*]Decimal start with 6++[list=a]+[*]Lower alpha with paren+[/list]+[/list]+[/list]+[/list]++Autonumbering:++[list=1]+[*]Autonumber.+[*]More.++[list=1]+[*]Nested.+[/list]+[/list]++Should not be a list item:++M.A. 2007++B. Williams++* * *++[u][b]Definition Lists[/b][/u]++Tight using spaces:++apple+[list]+[*]red fruit+[/list]+orange+[list]+[*]orange fruit+[/list]+banana+[list]+[*]yellow fruit+[/list]++Tight using tabs:++apple+[list]+[*]red fruit+[/list]+orange+[list]+[*]orange fruit+[/list]+banana+[list]+[*]yellow fruit+[/list]++Loose:++apple+[list]+[*]red fruit+[/list]+orange+[list]+[*]orange fruit+[/list]+banana+[list]+[*]yellow fruit+[/list]++Multiple blocks with italics:++[i]apple[/i]+[list]+[*]red fruit++contains seeds, crisp, pleasant to taste+[/list]+[i]orange[/i]+[list]+[*]orange fruit++[code]{ orange code block }+[/code]++[quote]+orange block quote+[/quote]+[/list]++Multiple definitions, tight:++apple+[list]+[*]red fruit+[*]computer+[/list]+orange+[list]+[*]orange fruit+[*]bank+[/list]++Multiple definitions, loose:++apple+[list]+[*]red fruit+[*]computer+[/list]+orange+[list]+[*]orange fruit+[*]bank+[/list]++Blank line after term, indented marker, alternate markers:++apple+[list]+[*]red fruit+[*]computer+[/list]+orange+[list]+[*]orange fruit++[list=1]+[*]sublist+[*]sublist+[/list]+[/list]++[u][b]HTML Blocks[/b][/u]++Simple block on one line:++foo++And nested without indentation:++foo++bar++Interpreted markdown in a table:++This is [i]emphasized[/i]++And this is [b]strong[/b]++Here's a simple block:++foo++This should be a code block, though:++[code]<div>+    foo+</div>+[/code]++As should this:++[code]<div>foo</div>+[/code]++Now, nested:++foo++This should just be an HTML comment:++Multiline:++Code block:++[code]<!-- Comment -->+[/code]++Just plain comment, with trailing spaces on the line:++Code:++[code]<hr />+[/code]++Hr's:++* * *++[u][b]Inline Markup[/b][/u]++This is [i]emphasized[/i], and so [i]is this[/i].++This is [b]strong[/b], and so [b]is this[/b].++An [i][url=/url]emphasized link[/url][/i].++[b][i]This is strong and em.[/i][/b]++So is [b][i]this[/i][/b] word.++[b][i]This is strong and em.[/i][/b]++So is [b][i]this[/i][/b] word.++This is code: >, $, \, \$, <html>.++[s]This is [i]strikeout[/i].[/s]++Superscripts: abcd a[i]hello[/i] ahello there.++Subscripts: H2O, H23O, Hmany of themO.++These should not be superscripts or subscripts, because of the unescaped spaces: a^b c^d, a~b c~d.++* * *++[u][b]Smart quotes, ellipses, dashes[/b][/u]++"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 "[url=http://example.com/?foo=1&bar=2]quoted link[/url]".++Some dashes: one---two --- three---four --- five.++Dashes between numbers: 5--7, 255--66, 1987--1999.++Ellipses...and...and....++* * *++[u][b]LaTeX[/b][/u]++[list]+[*]+[*]$2+2=4$+[*]$x \in y$+[*]$\alpha \wedge \omega$+[*]$223$+[*]$p$-Tree+[*]Here's some display math: [code=latex]$$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$$+[/code]+[*]Here's one that has a line break in it: $\alpha + \omega \times x^2$.+[/list]++These shouldn't be math:++[list]+[*]To get the famous equation, write $e = mc^2$.+[*]$22,000 is a [i]lot[/i] of money. So is $34,000. (It worked if "lot" is emphasized.)+[*]Shoes ($20) and socks ($5).+[*]Escaped $: $73 [i]this should be emphasized[/i] 23$.+[/list]++Here's a LaTeX table:++* * *++[u][b]Special Characters[/b][/u]++Here is some unicode:++[list]+[*]I hat: Î+[*]o umlaut: ö+[*]section: §+[*]set membership: ∈+[*]copyright: ©+[/list]++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: -++* * *++[u][b]Links[/b][/u]++[b]Explicit[/b]++Just a [url=/url/]URL[/url].++[url=/url/]URL and title[/url].++[url=/url/]URL and title[/url].++[url=/url/]URL and title[/url].++[url=/url/]URL and title[/url]++[url=/url/]URL and title[/url]++[url=/url/with_underscore]with_underscore[/url]++[email=nobody@nowhere.net]Email link[/email]++[url]Empty[/url].++[b]Reference[/b]++Foo [url=/url/]bar[/url].++With [url=/url/]embedded [brackets][/url].++[url=/url/]b[/url] by itself should be a link.++Indented [url=/url]once[/url].++Indented [url=/url]twice[/url].++Indented [url=/url]thrice[/url].++This should [not][] be a link.++[code][not]: /url+[/code]++Foo [url=/url/]bar[/url].++Foo [url=/url/]biz[/url].++[b]With ampersands[/b]++Here's a [url=http://example.com/?foo=1&bar=2]link with an ampersand in the URL[/url].++Here's a link with an amersand in the link text: [url=http://att.com/]AT&T[/url].++Here's an [url=/script?foo=1&bar=2]inline link[/url].++Here's an [url=/script?foo=1&bar=2]inline link in pointy braces[/url].++[b]Autolinks[/b]++With an ampersand: [url]http://example.com/?foo=1&bar=2[/url]++[list]+[*]In a list?+[*][url]http://example.com/[/url]+[*]It should.+[/list]++An e-mail address: [email]nobody@nowhere.net[/email]++[quote]+Blockquoted: [url]http://example.com/[/url]+[/quote]++Auto-links should not occur here: <http://example.com/>++[code]or here: <http://example.com/>+[/code]++* * *++[u][b]Images[/b][/u]++From "Voyage dans la Lune" by Georges Melies (1902):++[img alt="lalune" title="Voyage dans la Lune"]lalune.jpg[/img]+lalune++Here is a movie [img alt="movie"]movie.jpg[/img] icon.++* * *++[u][b]Footnotes[/b][/u]++Here is a footnote reference,(1) and another.(2) This should [i]not[/i] be a footnote reference, because it contains a space.[^my note] Here is an inline note.(3)++[quote]+Notes can go in quotes.(4)+[/quote]++[list=1]+[*]And in list items.(5)+[/list]++This paragraph should not be part of the note, as it is not indented.++* * *++(1) Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.++(2) 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]  { <code> }+[/code]++If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.++(3) This is [i]easier[/i] to type. Inline notes may contain [url=http://google.com]links[/url] and ] verbatim characters, as well as [bracketed text].++(4) In quote.++(5) In list.
test/writer.typst view
@@ -47,7 +47,7 @@   paper: "us-letter",   lang: "en",   region: "US",-  font: (),+  font: none,   fontsize: 11pt,   mathfont: none,   codefont: none,@@ -70,6 +70,7 @@     paper: paper,     margin: margin,     numbering: pagenumbering,+    columns: cols   )    set par(@@ -78,9 +79,9 @@   )   set text(lang: lang,            region: region,-           font: font,            size: fontsize) +  set text(font: font) if font != none   show math.equation: set text(font: mathfont) if mathfont != none   show raw: set text(font: codefont) if codefont != none 
+ test/xlsx-reader/basic.native view
@@ -0,0 +1,381 @@+Pandoc+  Meta { unMeta = fromList [] }+  [ Header 2 ( "sheet-1" , [] , [] ) [ Str "Main" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [ Strong [ Str "Person" ] ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [ Strong [ Str "Age" ] ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [ Strong [ Str "Location" ] ] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Anton" , Space , Str "Antich" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "23.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Switzerland" ] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "James" , Space , Str "Bond" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "35.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Moscow" ] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain+                      [ Str "Just"+                      , Space+                      , Str "a"+                      , Space+                      , Str "random"+                      , Space+                      , Str "cell"+                      ]+                  ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              ]+          ]+      ]+      (TableFoot ( "" , [] , [] ) [])+  , Header 2 ( "sheet-2" , [] , [] ) [ Str "Secondary" ]+  , Table+      ( "" , [] , [] )+      (Caption Nothing [])+      [ ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      , ( AlignDefault , ColWidthDefault )+      ]+      (TableHead+         ( "" , [] , [] )+         [ Row+             ( "" , [] , [] )+             [ Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain+                     [ Str "Sum"+                     , Space+                     , Str "of"+                     , Space+                     , Str "Age"+                     ]+                 ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [ Str "Column" , Space , Str "Labels" ] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [] ]+             , Cell+                 ( "" , [] , [] )+                 AlignDefault+                 (RowSpan 1)+                 (ColSpan 1)+                 [ Plain [] ]+             ]+         ])+      [ TableBody+          ( "" , [] , [] )+          (RowHeadColumns 0)+          []+          [ Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Row" , Space , Str "Labels" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Moscow" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Switzerland" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "(blank)" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Grand" , Space , Str "Total" ] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Anton" , Space , Str "Antich" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "23.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "23.0" ] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "James" , Space , Str "Bond" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "35.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "35.0" ] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "(blank)" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              ]+          , Row+              ( "" , [] , [] )+              [ Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "Grand" , Space , Str "Total" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "35.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "23.0" ] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [] ]+              , Cell+                  ( "" , [] , [] )+                  AlignDefault+                  (RowSpan 1)+                  (ColSpan 1)+                  [ Plain [ Str "58.0" ] ]+              ]+          ]+      ]+      (TableFoot ( "" , [] , [] ) [])+  ]
+ test/xlsx-reader/basic.xlsx view

binary file changed (absent → 13604 bytes)