pandoc 3.12.1 → 3.13
raw patch · 118 files changed
+2243/−721 lines, 118 filesdep +yamletdep +yamlet-aesondep −libyamldep −yamldep ~citeprocdep ~cryptondep ~crypton-x509-systembinary-addedPVP ok
version bump matches the API change (PVP)
Dependencies added: yamlet, yamlet-aeson
Dependencies removed: libyaml, yaml
Dependency ranges changed: citeproc, crypton, crypton-x509-system, gridtables, tasty-bench, texmath
API changes (from Hackage documentation)
Files
- AUTHORS.md +4/−0
- MANUAL.txt +48/−47
- changelog.md +190/−0
- pandoc.cabal +19/−13
- src/Text/Pandoc/App/Opt.hs +14/−11
- src/Text/Pandoc/App/OutputSettings.hs +0/−1
- src/Text/Pandoc/Extensions.hs +0/−1
- src/Text/Pandoc/Filter.hs +0/−1
- src/Text/Pandoc/Image.hs +1/−1
- src/Text/Pandoc/MediaBag.hs +0/−1
- src/Text/Pandoc/Options.hs +0/−1
- src/Text/Pandoc/PDF.hs +5/−5
- src/Text/Pandoc/Readers/Djot.hs +2/−4
- src/Text/Pandoc/Readers/DocBook.hs +1/−5
- src/Text/Pandoc/Readers/Docx.hs +136/−80
- src/Text/Pandoc/Readers/Docx/Lists.hs +9/−0
- src/Text/Pandoc/Readers/Docx/Parse.hs +42/−18
- src/Text/Pandoc/Readers/HTML.hs +1/−3
- src/Text/Pandoc/Readers/LaTeX/Parsing.hs +18/−0
- src/Text/Pandoc/Readers/Markdown.hs +0/−4
- src/Text/Pandoc/Readers/Metadata.hs +29/−38
- src/Text/Pandoc/Readers/ODT/ContentReader.hs +55/−25
- src/Text/Pandoc/Readers/RST.hs +19/−0
- src/Text/Pandoc/Readers/RTF.hs +3/−5
- src/Text/Pandoc/Readers/Vimwiki.hs +0/−1
- src/Text/Pandoc/Shared.hs +7/−3
- src/Text/Pandoc/Translations.hs +15/−15
- src/Text/Pandoc/Translations/Types.hs +0/−1
- src/Text/Pandoc/Version.hs +0/−1
- src/Text/Pandoc/Writers/ANSI.hs +1/−3
- src/Text/Pandoc/Writers/AsciiDoc.hs +1/−8
- src/Text/Pandoc/Writers/BibTeX.hs +4/−10
- src/Text/Pandoc/Writers/ConTeXt.hs +1/−8
- src/Text/Pandoc/Writers/Djot.hs +3/−9
- src/Text/Pandoc/Writers/DocBook.hs +14/−21
- src/Text/Pandoc/Writers/Docx/OpenXML.hs +12/−6
- src/Text/Pandoc/Writers/EPUB.hs +0/−1
- src/Text/Pandoc/Writers/HTML.hs +0/−2
- src/Text/Pandoc/Writers/Haddock.hs +22/−20
- src/Text/Pandoc/Writers/ICML.hs +1/−3
- src/Text/Pandoc/Writers/JATS.hs +32/−34
- src/Text/Pandoc/Writers/JATS/References.hs +3/−3
- src/Text/Pandoc/Writers/JATS/Table.hs +11/−9
- src/Text/Pandoc/Writers/LaTeX.hs +7/−13
- src/Text/Pandoc/Writers/Man.hs +1/−8
- src/Text/Pandoc/Writers/Markdown.hs +23/−21
- src/Text/Pandoc/Writers/Ms.hs +1/−8
- src/Text/Pandoc/Writers/Muse.hs +1/−8
- src/Text/Pandoc/Writers/ODT.hs +13/−2
- src/Text/Pandoc/Writers/OPML.hs +1/−4
- src/Text/Pandoc/Writers/OpenDocument.hs +2/−14
- src/Text/Pandoc/Writers/Org.hs +1/−8
- src/Text/Pandoc/Writers/Powerpoint/Output.hs +23/−4
- src/Text/Pandoc/Writers/Powerpoint/Presentation.hs +2/−0
- src/Text/Pandoc/Writers/RST.hs +15/−13
- src/Text/Pandoc/Writers/Shared.hs +21/−1
- src/Text/Pandoc/Writers/TEI.hs +6/−14
- src/Text/Pandoc/Writers/Texinfo.hs +1/−8
- src/Text/Pandoc/Writers/Typst.hs +10/−14
- test/Tests/Readers/Docx.hs +20/−0
- test/Tests/Readers/ODT.hs +1/−0
- test/Tests/Readers/RST.hs +13/−0
- test/command/11088.md +10/−0
- test/command/11944.docx binary
- test/command/11944.md +14/−0
- test/command/11945.md +34/−0
- test/command/11954.md +12/−0
- test/command/11979.md +6/−0
- test/command/11981.md +14/−0
- test/command/11987.md +9/−0
- test/command/11989.docx binary
- test/command/11989.md +19/−0
- test/command/11991.docx binary
- test/command/11991.md +37/−0
- test/command/4819.md +3/−1
- test/command/9197.md +33/−0
- test/command/nested-notes.md +43/−0
- test/command/pandoc-citeproc-57.md +1/−1
- test/docx/field_no_instrText.docx binary
- test/docx/field_no_instrText.native +24/−0
- test/docx/field_no_instrText_codeblock.docx binary
- test/docx/field_no_instrText_codeblock.native +1/−0
- test/docx/field_tracked_instrText.docx binary
- test/docx/field_tracked_instrText.native +14/−0
- test/docx/golden/lists.docx binary
- test/docx/golden/lists_div_bullets.docx binary
- test/docx/golden/task_list.docx binary
- test/docx/lists_level_override.native +151/−155
- test/docx/sdt_elements.native +1/−1
- test/docx/table_header_rowspan.native +1/−1
- test/docx/track_changes_paragraph_mark_in_note.docx binary
- test/docx/track_changes_paragraph_mark_in_note_accept.native +58/−0
- test/docx/track_changes_paragraph_mark_in_note_reject.native +59/−0
- test/odt/native/listContinueNumbering3.native +814/−0
- test/odt/odt/listContinueNumbering3.odt binary
- test/pptx/background-image/output.pptx binary
- test/pptx/background-image/templated.pptx binary
- test/pptx/blanks/just-speaker-notes/output.pptx binary
- test/pptx/blanks/just-speaker-notes/templated.pptx binary
- test/pptx/document-properties/output.pptx binary
- test/pptx/document-properties/templated.pptx binary
- test/pptx/footer/basic/output.pptx binary
- test/pptx/footer/fixed-date/output.pptx binary
- test/pptx/footer/higher-slide-number/output.pptx binary
- test/pptx/footer/no-title-slide/output.pptx binary
- test/pptx/layouts/deleted.pptx binary
- test/pptx/layouts/moved.pptx binary
- test/pptx/metadata-speaker-notes/output.pptx binary
- test/pptx/metadata-speaker-notes/templated.pptx binary
- test/pptx/reference-no-slides/with-notes/output.pptx binary
- test/pptx/speaker-notes-after-metadata/output.pptx binary
- test/pptx/speaker-notes-after-metadata/templated.pptx binary
- test/pptx/speaker-notes-afterheader/output.pptx binary
- test/pptx/speaker-notes-afterheader/templated.pptx binary
- test/pptx/speaker-notes-afterseps/output.pptx binary
- test/pptx/speaker-notes-afterseps/templated.pptx binary
- test/pptx/speaker-notes/output.pptx binary
- test/pptx/speaker-notes/templated.pptx binary
@@ -29,6 +29,7 @@ - Andreas Deininger - Andreas Lööw - Andreas Scherer+- Andrzej Rybczak - Andres Freund - Andrew Dunning - Andy Morris@@ -345,6 +346,7 @@ - Owen McGrath - Pablo Rodríguez - Pascal Wagler+- Patrick Creighton - Pau RE - Paul Rivier - Paul Tilley@@ -466,6 +468,7 @@ - William Lupton - William Rusnack - Winnie Hellmann+- Wleeaf - Wout Gevaert - Wrong-Code - Xavier Olive@@ -496,6 +499,7 @@ - dbecher-ito - ebiim - ech0+- enieuwy - etclub - favonia - gemmaro
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: 2026-10-07+date: 2026-10-25 --- # Synopsis@@ -146,7 +146,7 @@ [`babel`] (with `lang`). If `CJKmainfont` is set, [`xeCJK`] is needed if `xelatex` is used, else [`luatexja`] is needed if `lualatex` is used. [`framed`] is required if code is highlighted in a-scheme that use a colored background. The use of `xelatex` or+scheme that uses a colored background. The use of `xelatex` or `lualatex` as the PDF engine requires [`fontspec`]. `lualatex` uses [`selnolig`] and [`lua-ul`]. `xelatex` uses [`bidi`] (with the `dir` variable set).@@ -769,7 +769,7 @@ `all` includes all insertions, deletions, and comments, wrapped in spans with `insertion`, `deletion`, `comment-start`, and `comment-end` classes, respectively. The author and time of- change is included. `all` is useful for scripting: only+ change are included. `all` is useful for scripting: only accepting changes from a certain reviewer, say, or before a certain date. If a paragraph is inserted or deleted, `track-changes=all` produces a span with the class@@ -781,7 +781,7 @@ : Extract images and other media contained in or linked from the source document to the path *DIR*, creating it if- necessary, and adjust the images references in the document+ necessary, and adjust the image references in the document so they point to the extracted files. Media are downloaded, read from the file system, or extracted from a binary container (e.g. docx), as needed. The original file paths@@ -1255,7 +1255,7 @@ `--listings[=true|false]` : *Deprecated, use `--syntax-highlighting=idiomatic` or- `--syntax-highlighting=default` instead.+ `--syntax-highlighting=default` instead.* Use the [`listings`] package for LaTeX code blocks. The package does not support multi-byte encoding for source code. To handle UTF-8@@ -1504,7 +1504,7 @@ `<dc:title>` (from the document title), `<dc:creator>` (from the document authors), `<dc:date>` (from the document date, which should be in [ISO 8601 format]), `<dc:language>` (from the `lang`- variable, or, if is not set, the locale), and `<dc:identifier+ variable, or, if it is not set, the locale), and `<dc:identifier id="BookId">` (a randomly generated UUID). Any of these may be overridden by elements in the metadata file. @@ -1635,7 +1635,7 @@ : Set the `bibliography` field in the document's metadata to *FILE*, overriding any value set in the metadata. If you supply this argument multiple times, each *FILE* will be added to- bibliography. If *FILE* is a URL, it will be fetched+ the bibliography. If *FILE* is a URL, it will be fetched via HTTP. If *FILE* is not found relative to the working directory, it will be sought in the resource path (see `--resource-path`).@@ -1689,7 +1689,7 @@ `mathjax`[`:`*URL*] - : Render math using [MathJaX]. TeX math will be put between+ : Render math using [MathJax]. TeX math will be put between `\(...\)` (for inline math) or `\[...\]` (for display math) and wrapped in `<span>` tags with class `math`. Then the MathJax JavaScript will render it. The *URL*@@ -2369,7 +2369,7 @@ | ``` | ``` | +----------------------------------+-----------------------------------+ -If the command line option accepts a URL argument, an `url:` field can+If the command line option accepts a URL argument, a `url:` field can be added to `math-method:`. ## Options for wrapper scripts@@ -2794,7 +2794,7 @@ - `roman`: Converts textual values that can be read as an integer into lowercase roman numerals.- This can be used to get lettered enumeration from array indices.+ This can be used to get roman-numeral enumeration from array indices. To get uppercase roman, chain with `uppercase`. - `left n "leftborder" "rightborder"`: Renders a textual value@@ -2956,7 +2956,7 @@ `quotebordercolor`, `quotebordercolordark` : sets the CSS `border-color` property for the left-border of-: `blockquote` elements.+ `blockquote` elements. `quotecolor`, `quotecolordark` : sets the CSS `color` property for `blockquote` elements.@@ -3492,7 +3492,7 @@ `pdfaintent` : when used in conjunction with `pdfa`, specifies the output intent for- the colors, e.g. `ISO coated v2 300\letterpercent\space (ECI)`+ the colors, e.g. `ISO coated v2 300\letterpercent\space (ECI)`. If left unspecified, `sRGB IEC61966-2.1` is used as default. `toc`@@ -3616,7 +3616,7 @@ ### Variables for ms `fontfamily`-: `A` (Avant Garde), `B` (Bookman), `C` (Helvetica), `HN`+: `A` (Avant Garde), `B` (Bookman), `H` (Helvetica), `HN` (Helvetica Narrow), `P` (Palatino), or `T` (Times New Roman). This setting does not affect source code, which is always displayed using monospace Courier. These built-in fonts are@@ -3658,8 +3658,8 @@ The recognized formats for `date` are: `mm/dd/yyyy`, `mm/dd/yy`, `yyyy-mm-dd` (ISO 8601), `dd MM yyyy` (e.g. either `02 Apr 2018` or `02 April 2018`),- `MM dd, yyyy` (e.g. `Apr. 02, 2018` or `April 02, 2018),- `yyyy[mm[dd]]` (e.g. `20180402, `201804` or `2018`).+ `MM dd, yyyy` (e.g. `Apr. 02, 2018` or `April 02, 2018`),+ `yyyy[mm[dd]]` (e.g. `20180402`, `201804` or `2018`). `header-includes` : contents specified by `-H/--include-in-header` (may have multiple@@ -3771,7 +3771,7 @@ then in reading LaTeX pandoc will parse these characters literally. In writing LaTeX, enabling `smart` tells pandoc to use the ligatures when possible; if `smart` is disabled-pandoc will use unicode quotation mark and dash characters.+pandoc will use Unicode quotation mark and dash characters. ## Headings and sections @@ -4018,9 +4018,9 @@ substituted with cross-references that will use the number of the referenced item. The original link text is discarded. This extension can be combined with `xrefs_name` in which case-the name or caption numbers will appear after the number.+the name or caption will appear after the number. -For the `xrefs_number` to be useful heading numbers must be enabled+For the `xrefs_number` extension to be useful, heading numbers must be enabled in the generated document, also table and figure captions must be enabled using for example the `native_numbering` extension. @@ -4415,7 +4415,7 @@ ### Extension: `fenced_code_attributes` ### -Optionally, you may attach attributes to fenced or backtick code block using+Optionally, you may attach attributes to a fenced or backtick code block using this syntax: ~~~~ {#mycode .haskell .numberLines startFrom="100"}@@ -5090,7 +5090,7 @@ the number of dashes in the line separating the table header from the table body. (For example `---|-` would make the first column 3/4 and the second column 1/4 of the full text width.)-On the other hand, if no lines are wider than column width, then+On the other hand, if no lines are wider than the column width, then cell contents will not be wrapped, and the cells will be sized to their contents. @@ -5595,7 +5595,7 @@ FictionBook2 ~ If `--math-method=webtex` is used, formulas are rendered as images- using CodeCogs or other compatible web service, downloaded+ using CodeCogs or another compatible web service, downloaded and embedded in the e-book. Otherwise, they will appear verbatim. HTML, Slidy, DZSlides, S5, EPUB@@ -5622,12 +5622,13 @@ For a more explicit way of including raw HTML in a Markdown document, see the [`raw_attribute` extension][Extension: `raw_attribute`]. -In the CommonMark format, if `raw_html` is enabled, superscripts,+In commonmark output, if `raw_html` is enabled, superscripts, subscripts, strikeouts and small capitals will be represented as HTML.-Otherwise, plain-text fallbacks will be used. Note that even if-`raw_html` is disabled, tables will be rendered with HTML syntax if-they cannot use pipe syntax.+Otherwise, plain-text fallbacks will be used. +Disabling the `raw_html` extension has no effect on `commonmark` (or+`gfm` or `commonmark_x`) *input*.+ ### Extension: `markdown_in_html_blocks` ### Original Markdown allows you to include HTML "blocks": blocks@@ -5675,7 +5676,7 @@ ### Extension: `native_spans` ### -Use native pandoc `Span` blocks for content inside `<span>` tags.+Use native pandoc `Span` elements for content inside `<span>` tags. For the most part this should give the same output as `raw_html`, but it makes it easier to write pandoc filters to manipulate groups of inlines.@@ -5816,7 +5817,7 @@ The link consists of link text in square brackets, followed by a label in square brackets. (There cannot be space between the two unless the `spaced_reference_links` extension is enabled.) If the label is empty-(`[]`), then it will be implicitly be taken to be the same as the link text;+(`[]`), then it will implicitly be taken to be the same as the link text; thus `[foo][]` is equivalent to `[foo][foo]`. (If the `shortcut_reference_links` extension is enabled, the empty `[]` may be omitted.)@@ -5828,7 +5829,7 @@ extension is enabled): citations take precedence over link labels. -Here are some examples of reference links and link definitions;+Here are some examples of reference links and link definitions: See [the website *I* built][my website]. @@ -5977,7 +5978,7 @@ itself contains dpi information). - The `%` unit is generally relative to some available space. For example the above example will render to the following.- - HTML: `<img href="file.jpg" style="width: 50%;" />`+ - HTML: `<img src="file.jpg" style="width: 50%;" />` - LaTeX: `\includegraphics[width=0.5\textwidth,height=\textheight]{file.jpg}` (If you're using a custom template, you need to configure `graphicx` as in the default template.)@@ -6159,7 +6160,7 @@ In complex cases, you can force something to be treated as a locator by enclosing it in curly braces or prevent parsing-the suffix as locator by prepending curly braces:+the suffix as a locator by prepending curly braces: [@smith{ii, A, D-Z}, with a suffix] [@smith, {pp. iv, vi-xi, (xv)-(xvii)} with suffix here]@@ -6250,7 +6251,7 @@ ### Extension: `mark` ### -To highlight out a section of text, begin and end it with+To highlight a section of text, begin and end it with `==`. Thus, for example, This ==is deleted text.==@@ -6493,7 +6494,7 @@ where `FORMAT` is replaced with the name of the format. Note that the list of extensions for `commonmark`,-`gfm`, and `commonmark_x` are defined relative to default+`gfm`, and `commonmark_x` is defined relative to default commonmark. So, for example, `backtick_code_blocks` does not appear as an extension, since it is enabled by default and cannot be disabled.@@ -6518,8 +6519,8 @@ `bibliography` metadata field in a YAML metadata section or the `--bibliography` command line argument. If you want to use multiple bibliography files, you can supply multiple-`--bibliography` arguments or set `bibliography` metadata field-to YAML array. A bibliography may have any of these formats:+`--bibliography` arguments or set the `bibliography` metadata field+to a YAML array. A bibliography may have any of these formats: Format File extension ------------ --------------@@ -6800,8 +6801,8 @@ For LaTeX output, you can also use [`natbib`] or [`biblatex`] to render the bibliography. In order to do so, specify bibliography-files as outlined above, and add `--natbib` or `--biblatex`-argument to pandoc invocation. Bear in mind that bibliography+files as outlined above, and add the `--natbib` or `--biblatex`+argument to the pandoc invocation. Bear in mind that bibliography files have to be in either BibTeX (for `--natbib`) or BibLaTeX (for `--biblatex`) format. @@ -6815,7 +6816,7 @@ numerical styles only). Defaults to false. `link-bibliography`-: If true, DOIs, PMCIDs, PMID, and URLs in bibliographies will+: If true, DOIs, PMCIDs, PMIDs, and URLs in bibliographies will be rendered as hyperlinks. (If an entry contains a DOI, PMCID, PMID, or URL, but none of these fields are rendered by the style, then the title, or in the absence of a title the whole entry, will@@ -7690,7 +7691,7 @@ # Vimdoc -Vimdoc writer generates Vim help files and makes use of the following metadata+The Vimdoc writer generates Vim help files and makes use of the following metadata variables: ``` yaml@@ -7703,8 +7704,8 @@ vimdoc-prefix: pandoc ``` -Complete header requires `abstract`, `author`, `title` and `filename` to-be set. Compiling file with such metadata produces the following file+A complete header requires `abstract`, `author`, `title` and `filename` to+be set. Compiling a file with such metadata produces the following file (assumes `--standalone`, see [Templates]): ``` vimdoc@@ -7721,7 +7722,7 @@ ``` If `vimdoc-prefix` is set, all non-command tags are prefixed with its-value, it is used to prevent tag collision: all headers have a tag+value; this is used to prevent tag collision: all headers have a tag (either inferred or explicit) and multiple help pages can have the same header names, therefore collision is to be expected. Let our input be the following markdown file:@@ -7759,7 +7760,7 @@ inherently represent anything. ``` -Convert it to vimdoc with metadata variable set (e.g. with+Convert it to vimdoc with the metadata variable set (e.g. with `-M vimdoc-prefix=pandoc`) ``` vimdoc@@ -8073,12 +8074,12 @@ pandoc -t context+tagging doc.md -o doc.pdf A recent `context` version should be used, as older versions-contained a bug that lead to invalid PDF metadata.+contained a bug that led to invalid PDF metadata. ## WeasyPrint The HTML-based engine WeasyPrint includes experimental support for-PDF/A and PDF/UA since version 57. Tagged PDFs can created with+PDF/A and PDF/UA since version 57. Tagged PDFs can be created with pandoc --pdf-engine=weasyprint \ --pdf-engine-opt=--pdf-variant=pdf/ua-1 ...@@ -8151,7 +8152,7 @@ # A note on security 1. Although pandoc itself will not create or modify any files other- than those you explicitly ask it create (with the exception+ than those you explicitly ask it to create (with the exception of temporary files used in producing PDFs), a filter or custom writer could in principle do anything on your file system. Please audit filters and custom writers very carefully before using them.@@ -8190,10 +8191,10 @@ For example, in `wkhtmltopdf` the `footer-html` and `header-html` metadata fields will be passed directly to `wkhtmltopdf` as `--footer-html` and `--header-html` arguments, and by using- a `file:` URIs with these, one could exfiltrate local files.+ a `file:` URI with these, one could exfiltrate local files. In addition, using `--pdf-engine=wkhtmltopdf` with `-f html+raw_html` enables an SSRF vulnerability in wkhtmltopdf ([CVE-2022-35583]).- Note that [`wkhtmltopdf`) is+ Note that [`wkhtmltopdf`] is [deprecated](https://wkhtmltopdf.org/status.html) and its authors recommend not to use it with any untrusted input. However, there may be similar issues with other pdf-engines.
@@ -1,5 +1,195 @@ # Revision history for pandoc +## pandoc 3.13 (2026-10-26)++ * Report the location of errors in defaults files (#8759, Andrzej Rybczak).+ An invalid value in a defaults file gave an error at the start of the+ file, with no indication of the field. The error now names the option and+ points at its value.++ * Use yamlet for YAML parsing. Pandoc parsed YAML with the yaml+ package, which depends on the C library libyaml. It now uses+ yamlet, a pure Haskell YAML 1.2 parser. Values still go+ through the existing aeson instances. Note these behavior changes:++ + `yes`, `no`, `on`, `off`, `y` and `n` are strings,+ not booleans, as in YAML 1.2.+ + YAML errors now show the file, the line and the column, with the+ offending line. In metadata blocks the line is the line in the+ document.+ + Duplicate keys in a mapping are an error. They were a warning.+ + `.5`, `.inf` and `.nan` are numbers.++ * Docx reader:++ + Read `w:fldSimple` fields (#11944, Aslak Hellesøy).+ + Keep grid columns that have no width (#11989, Patrick Creighton).+ `w:w` is optional on `w:gridCol`, but `elemToTblGrid` skipped the grid+ columns that had none. The table then had fewer columns than its rows had+ cells, and the extra cells were dropped. Every grid column is now kept.+ If any of them has no (readable) width, all columns get the default+ width.+ + Fix namespaces in notes and comments (#11991, Patrick Creighton).+ The contents of footnotes, endnotes and comments were read with the+ namespace prefixes declared in word/document.xml rather than in their own+ parts.+ + Records the indentation of each list level and track the open+ list levels; an unnumbered paragraph whose left indentation+ matches the text indentation of an open level is treated as a continuation+ of that level's current item, rather than as a block quote (cf. #9197).+ + Recover from fields with a missing instruction (#11943, enieuwy).+ This fixes a bug that could lead to content being omitted.+ + Fix regression (from 3.11) in parsing column widths (#11969).+ The regression caused only the first column to get+ assigned its alignment; every other column received default alignment.+ In addition, in 3.11 alignment was taken from the header row if present;+ this changed behavior from earlier versions, which took it from the first+ body row. We revert to the earlier behavior, using the header row only if+ there are no body rows. It's common for the header to have different+ alignment than the rest.+ + Keep tracked paragraph marks inside notes (#11971, Aslak Hellesøy).++ * RST reader:++ + Allow inline markup and bare links after `:`, `/`, `'`, `"`, `<`+ (Wleeaf). Fixes a regression since 3.2.1; these characters could no+ longer precede an inline markup start-string or a bare URI or email+ address, although the reStructuredText spec allows them.+ Also implement the rule that a start-character between an opening+ character and its closing counterpart, as in `(*)` or `"*"`,+ does not trigger inline markup.++ * RTF reader:++ + Fix tokenization bug (#11981). We were consuming certain+ symbols after `\uNNNN` during tokenization. This led to an+ *extra* character being consumed as the "fallback," so+ letters went missing after encoded unicode characters.++ * LaTeX reader:++ + Detect macro expansion loops across `doMacros` calls (#11088).++ * ODT reader:++ + Fix start numbers with `text:continue-numbering` (#9595).++ * Markdown writer:++ + Write wide tables as grid tables instead of falling back to HTML+ (#11945, Aslak Hellesøy).+ + Don't drop notes in notes.+ + Fix regression with code block language (#11987). We try to+ identify which class is a language name and emit that as the gfm+ style info string. If none of the classes match a+ recognized language, before 3.10.1 we emitted the first+ class; fater 3.10.1, we emit nothing. This commit reverts to+ the pre-3.10.1 behavior.++ * RST writer:++ + Don't drop notes in notes.++ * Haddock writer:++ + Don't drop notes in notes.++ * Docx writer:++ + Fix multi-paragraph list items (#9197). Previously the docx+ writer gave the second and subsequent paragraphs of a list+ item numbering from a separate list with an invisible bullet.+ This looked right, but semantically these paragraphs were+ items of another list, which is what Word, screen readers,+ and pandoc's own docx reader saw; the list was also split in+ three. The writer now gives these paragraphs no numbering,+ just an indentation that lines them up with the text of the+ list item (as Word's "List Continue" styles do).++ * LaTeX writer:++ + Use braces around term containing `=` (#11954). This is needed for+ the new LaTeX list code, which is triggered by using `pdfstandard`.++ * PowerPoint writer:++ + Add `clrMapOvr` to notes slides (#11935, Gaurav Vijay Jadhav).+ This makes them importable by Keynote.+ + Include `lang` in core document properties.++ * DocBook, JATS, TEI writers:++ + Apply `writerIdentifierPrefix` prefix consistently.++ * Typst writer:++ + Escape `...` and `-?` ligatures (#11979).+ + Use `getLang` to determine lang and region.+ Previously only the `lang` metadata field was consulted, so+ `lang` could not be set properly using a variable.++ * Text.Pandoc.Translations:++ + `readTranslations` now takes the path of the file, for error+ messages [API change].++ * Text.Pandoc.Writers.Shared:++ + Add `wrapColumns`, `renderWithTemplate` [API change].+ These factor out code that was repeated in about 20 writers: computing the+ line length from writerWrapText/writerColumns, and rendering the body with+ or without the template.++ * Text.Pandoc.Shared:++ + Export `plainToPara` and `paraToPlain`. [API change]++ * Text.Pandoc.PDF:++ + Make `--presentational-hints` default for weasyprint.+ This is necessary to get list attributes (start, ordered+ list type, etc.) working properly (#11976).++ * cabal.project:++ + Use bundle C option for zlib by default.+ This allows pandoc to be built without first installing the C library+ zlib. Those who want to use the system zlib can still compile pandoc+ that way by overriding this setting in cabal.project.local, or+ just installing directly from Hackage.+ + Default to `+http` on GHC >= 9.14 (previously done only in+ CI), so local builds behave the same; `-f-http` still overrides it.+ + Pass wasm link flags for `pandoc-cli` as `ghc-options`.+ cabal only passes ld-options along when it finds an `ld` program on the+ PATH. In an environment without one (e.g. `nix shell` with just the+ ghc-wasm-meta toolchain), the flags were silently dropped and linking+ pandoc.wasm failed with undefined `setjmp` and clock symbols.+ Use `-optl- ghc-options` instead, which GHC passes to its+ linker regardless.++ * Makefile:++ + Add `release` target.+ + Improve `make pandoc-templates` so it does the whole job.+ + Use bash as `SHELL` (`check-cabal` uses `pushd`, `check-version-sync`+ uses `==`).+ + Fix `$(id -u)` in `debpkg`, which make expanded to empty.+ - Fix missing `echo` in `validate-docx-golden-tests{,2}`.+ - Ensure pandoc is built before rules that run it to produce files.+ - Use `git ls-files` for `SOURCEFILES`, not the main branch's tree.+ - Drop redundant `embed_data_files` flag in `quick-stack`.++ * Use released citeproc 0.14.1.1, texmath 0.13.3.3,+ gridtables 0.1.1.1 (#9085).++ * MANUAL.txt:++ + Clarify the effect of `raw_html` in commonmark formats (#8305).++ * Bump bounds on crypton, crypton-x509-system, tasty-bench.++ * Add `tools/circleci-build-release.sh`, `tools/github-build-release.sh`.+ ## pandoc 3.12.1 (2026-10-07) * New input and output format: `fodt` (#4010). This is ODF's
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: pandoc-version: 3.12.1+version: 3.13 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -17,18 +17,19 @@ . - light markup formats (many variants of Markdown, reStructuredText, AsciiDoc, Org-mode, Muse, Textile,- txt2tags, djot)- - HTML formats (HTML 4 and 5)+ txt2tags, djot, bbcode)+ - HTML formats (HTML 4 and 5, chunked HTML) - Ebook formats (EPUB v2 and v3, FB2) - Documentation formats (GNU TexInfo, Haddock, Vimdoc)- - Roff formats (man, ms)+ - Roff formats (man, ms, mdoc) - TeX formats (LaTeX, ConTeXt) - Typst+ - ANSI-formatted text - XML formats (DocBook 4 and 5, JATS, TEI Simple, OpenDocument) - Outline formats (OPML) - Bibliography formats (BibTeX, BibLaTeX, CSL JSON, CSL YAML, RIS)- - Word processor formats (Docx, RTF, ODT)+ - Word processor formats (Docx, RTF, ODT, FODT) - Interactive notebook formats (Jupyter notebook ipynb) - Page layout formats (InDesign ICML) - Wiki markup formats (MediaWiki, DokuWiki, TikiWiki, TWiki,@@ -36,6 +37,8 @@ - Slide show formats (LaTeX Beamer, PowerPoint, Slidy, reveal.js, Slideous, S5, DZSlides) - Data formats (CSV and TSV tables, Excel spreadsheets)+ - Serialization formats (Haskell, JSON, or XML representation+ of the AST) - PDF (via external programs such as pdflatex or wkhtmltopdf) . Pandoc can convert mathematical content in documents@@ -227,6 +230,9 @@ test/command/11113.docx test/command/11689.docx test/command/11833.docx+ test/command/11944.docx+ test/command/11989.docx+ test/command/11991.docx test/command/11942.js test/command/biblio.bib test/command/averroes.bib@@ -538,12 +544,12 @@ blaze-markup >= 0.8 && < 0.9, bytestring >= 0.9 && < 0.13, case-insensitive >= 1.2 && < 1.3,- citeproc >= 0.14.1 && < 0.15,+ citeproc >= 0.14.1.1 && < 0.15, commonmark >= 0.3.1 && < 0.4, commonmark-extensions >= 0.2.7.3 && < 0.3, commonmark-pandoc >= 0.3.0.2 && < 0.4, containers >= 0.6.0.1 && < 0.9,- crypton >= 0.30 && < 2.1,+ crypton >= 0.30 && < 2.3, data-default >= 0.4 && < 0.9, deepseq >= 1.3 && < 1.6, directory >= 1.2.5 && < 1.4,@@ -553,7 +559,7 @@ exceptions >= 0.8 && < 0.11, file-embed >= 0.0 && < 0.1, filepath >= 1.1 && < 1.6,- gridtables >= 0.1 && < 0.2,+ gridtables >= 0.1.1.1 && < 0.2, haddock-library >= 1.10 && < 1.12, http-types >= 0.8 && < 0.13, ipynb >= 0.2 && < 0.3,@@ -573,15 +579,15 @@ syb >= 0.1 && < 0.8, tagsoup >= 0.14.6 && < 0.15, temporary >= 1.1 && < 1.4,- texmath >= 0.13.3.1 && < 0.14,+ texmath >= 0.13.3.3 && < 0.14, text >= 2.0 && < 2.2, text-conversions >= 0.3 && < 0.4, time >= 1.5 && < 1.17, unicode-collation >= 0.1.1 && < 0.2, unicode-data >= 0.6 && < 0.10, unicode-transforms >= 0.3 && < 0.5,- yaml >= 0.11 && < 0.12,- libyaml >= 0.1.4 && < 0.2,+ yamlet >= 1.0.0.1 && < 1.1,+ yamlet-aeson >= 1.0.0.1 && < 1.1, zip-archive >= 0.5 && < 0.6, zlib >= 0.6 && < 0.8, xml >= 1.3.12 && < 1.4,@@ -599,7 +605,7 @@ cpp-options: -DPANDOC_HTTP_SUPPORT build-depends: crypton-connection >= 0.3.1 && < 0.5,- crypton-x509-system >= 1.6.7 && < 1.10,+ crypton-x509-system >= 1.6.7 && < 1.11, http-client >= 0.4.30 && < 0.8, http-client-tls >= 0.2.4 && < 0.5, network >= 2.6 && < 3.3,@@ -944,7 +950,7 @@ main-is: benchmark-pandoc.hs hs-source-dirs: benchmark build-depends: bytestring,- tasty-bench >= 0.4 && <= 0.5,+ tasty-bench >= 0.4 && <= 0.6, mtl >= 2.2 && < 2.4, text >= 2.0 && < 2.2, temporary,
@@ -1,6 +1,5 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE TemplateHaskell #-}@@ -67,11 +66,15 @@ import qualified Data.Map as M import qualified Data.ByteString.Char8 as B8 import Text.Pandoc.Definition (Meta(..), MetaValue(..))-import Data.Aeson (defaultOptions, Options(..), Result(..),- genericToJSON, fromJSON, camelTo2, eitherDecodeStrict) import Data.Aeson.TH (deriveJSON) import Control.Applicative ((<|>))-import Data.Yaml+import Data.Aeson+import Data.Aeson.Types+import qualified Data.Aeson.Key as K+import qualified Data.List as L+import qualified Data.List.NonEmpty as NE+import qualified Yamlet as Y+import Yamlet.Aeson -- | The type of line-endings to be used when writing plain-text. data LineEnding = LF | CRLF | Native deriving (Show, Generic)@@ -357,11 +360,11 @@ Success (opts :: M.Map Text Value) -> do dataDir <- case M.lookup "data-dir" opts of Nothing -> return Nothing- Just v -> Just . unpack <$> parseJSON v+ Just v -> Just . unpack <$> parseJSON v <?> Key "data-dir" f <- parseOptions (M.toList opts) case M.lookup "defaults" opts of Just v -> do- g <- parseDefaults v dataDir+ g <- parseDefaults v dataDir <?> Key "defaults" return $ g >=> f >=> resolveVarsInOpt Nothing -> return $ f >=> resolveVarsInOpt parseJSON _ = fail "Expected a mapping"@@ -541,7 +544,7 @@ _ -> doOpt (k,v) doOpt :: (Text, Value) -> Parser (Opt -> Opt)-doOpt (k,v) = do+doOpt (k,v) = (<?> Key (K.fromText k)) $ do case k of "tab-stop" -> parseJSON v >>= \x -> return (\o -> o{ optTabStop = x })@@ -938,11 +941,11 @@ Left err' -> throwError $ PandocParseError $ T.pack $ "Error parsing " <> file <> ":\n" <> err' else- case decodeEither' (B8.unlines . takeWhile (/= "...") . B8.lines $ inp) of- Right f -> f opt- Left err' -> throwError $ PandocParseError $ T.pack $+ case Y.decode (B8.unlines . takeWhile (/= "...") . B8.lines $ inp) of+ Right (ViaAeson f) -> f opt+ Left errs -> throwError $ PandocParseError $ T.pack $ "Error parsing " <> file <> ":\n" <>- Data.Yaml.prettyPrintParseException err'+ L.intercalate "\n" (map (Y.prettyError file) (NE.toList errs)) fullDefaultsPath :: (PandocMonad m, MonadIO m) => Maybe FilePath
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {- |
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, CPP #-}+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-} {- | Module : Text.Pandoc.Image Copyright : Copyright (C) 2020-2024 John MacFarlane
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-}
@@ -112,7 +112,7 @@ >>= writer opts' verbosity <- getVerbosity- let compileHTML mkOutArgs = do+ let compileHTML defaultOpts mkOutArgs = do -- check to see if there is anything in mediabag, and if so, -- make the HTML self contained mediabag <- getMediaBag@@ -120,12 +120,12 @@ [] -> pure source _ -> makeSelfContained source liftIO $- toPdfViaTempFile verbosity program pdfargs mkOutArgs ".html" source'+ toPdfViaTempFile verbosity program (defaultOpts ++ pdfargs) mkOutArgs ".html" source' case takeBaseName program of "wkhtmltopdf" -> makeWithWkhtmltopdf program pdfargs writer opts' doc- "pagedjs-cli" -> compileHTML (\f -> ["-o", f])- "prince" -> compileHTML (\f -> ["-o", f])- "weasyprint" -> compileHTML (:[])+ "pagedjs-cli" -> compileHTML [] (\f -> ["-o", f])+ "prince" -> compileHTML [] (\f -> ["-o", f])+ "weasyprint" -> compileHTML ["--presentational-hints"] (\f -> [f]) "typst" -> liftIO $ toPdfViaTempFile verbosity program ("compile":pdfargs) (:[]) ".typ" source "pdfroff" -> do
@@ -25,7 +25,8 @@ import Text.Parsec.Pos (newPos) import Text.Pandoc.Options import Text.Pandoc.Definition-import Text.Pandoc.Shared (addPandocAttributes, tshow, compactifyTable)+import Text.Pandoc.Shared (addPandocAttributes, tshow, compactifyTable,+ paraToPlain) import qualified Text.Pandoc.UTF8 as UTF8 import Djot (ParseOptions(..), SourcePosOption(..), parseDoc, Pos(..)) import qualified Djot.AST as D@@ -259,9 +260,6 @@ toTight :: Blocks -> Blocks toTight (Many bls) = Many $ paraToPlain <$> bls- where- paraToPlain (Para ils) = Plain ils- paraToPlain x = x toTaskListItem :: PandocMonad m => (D.TaskStatus, D.Blocks) -> ReaderT Env m Blocks
@@ -46,7 +46,7 @@ import Text.Pandoc.Class.PandocMonad (PandocMonad, report) import Text.Pandoc.Options import Text.Pandoc.Logging (LogMessage(..))-import Text.Pandoc.Shared (safeRead, addPandocAttributes)+import Text.Pandoc.Shared (safeRead, addPandocAttributes, paraToPlain) import Text.Pandoc.Sources (ToSources(..), sourcesToText) import Text.Pandoc.Transforms (headerShift) import Text.TeXMath (readMathML, writeTeX)@@ -1481,10 +1481,6 @@ -- | Set the prefix of a name to 'Nothing' removePrefix :: QName -> QName removePrefix elname = elname { qPrefix = Nothing }--paraToPlain :: Block -> Block-paraToPlain (Para ils) = Plain ils-paraToPlain x = x docbookEntityMap :: M.Map Text Text docbookEntityMap = M.fromList
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE FlexibleContexts #-}@@ -60,6 +59,7 @@ ) where import Codec.Archive.Zip+import Control.Applicative ((<|>)) import Control.Monad ( liftM, unless ) import Control.Monad.Reader ( asks,@@ -132,6 +132,11 @@ , docxListState :: M.Map (T.Text, T.Text) Integer , docxPrevPara :: Inlines , docxReferences :: M.Map ItemId (Reference Inlines)+ -- the open list levels, innermost first, as+ -- (text indentation, level, numId); used to+ -- recognize unnumbered paragraphs continuing+ -- a list item+ , docxOpenListLevels :: [(Integer, T.Text, T.Text)] } instance Default DState where@@ -144,6 +149,7 @@ , docxListState = M.empty , docxPrevPara = mempty , docxReferences = mempty+ , docxOpenListLevels = [] } data DEnv = DEnv { docxOptions :: ReaderOptions@@ -270,6 +276,8 @@ T.concat $ map parPartToText children parPartToText (ExternalHyperLink _ _ children) = T.concat $ map parPartToText children+parPartToText (Field _ children) =+ T.concat $ map parPartToText children parPartToText _ = "" blacklistedCharStyles :: [CharStyleName]@@ -343,8 +351,8 @@ let ils = smushInlines (map runElemToInlines runElems) transform <- runStyleToTransform rPr return $ transform ils-runToInlines (Footnote bps) = note . smushBlocks <$> mapM bodyPartToBlocks bps-runToInlines (Endnote bps) = note . smushBlocks <$> mapM bodyPartToBlocks bps+runToInlines (Footnote bps) = note <$> notePartsToBlocks bps+runToInlines (Endnote bps) = note <$> notePartsToBlocks bps runToInlines (InlineDrawing fp title alt bs ext) = do (lift . lift) $ P.insertMedia fp Nothing bs return $ imageWith (extentToAttr ext) (T.pack fp) title $ text alt@@ -358,6 +366,19 @@ showDim d = tshow (d / 914400) <> "in" extentToAttr _ = nullAttr +-- A note is read in the middle of the paragraph that references it.+-- Text held back from a paragraph whose mark is a tracked change+-- (docxPrevPara) must therefore neither flow into the note from the+-- body, nor out of the note into the referencing paragraph.+notePartsToBlocks :: PandocMonad m => [BodyPart] -> DocxContext m Blocks+notePartsToBlocks bps = do+ outerPrevPara <- gets docxPrevPara+ modify $ \s -> s { docxPrevPara = mempty }+ blks <- smushBlocks <$> mapM bodyPartToBlocks bps+ leftover <- gets docxPrevPara+ modify $ \s -> s { docxPrevPara = outerPrevPara }+ return $ if null leftover then blks else blks <> para leftover+ blocksToInlinesWarn :: PandocMonad m => T.Text -> Blocks -> DocxContext m Inlines blocksToInlinesWarn cmtId blks = do let paraOrPlain :: Block -> Bool@@ -694,7 +715,17 @@ | otherwise = c bodyPartToBlocks :: PandocMonad m => BodyPart -> DocxContext m Blocks-bodyPartToBlocks (Heading n style pPr numId lvl mblvlInfo parparts) = do+bodyPartToBlocks bp =+ case bp of+ Paragraph{} -> bodyPartToBlocks' bp+ ListItem{} -> bodyPartToBlocks' bp+ -- anything else ends the open lists:+ _ -> closeListLevels *> bodyPartToBlocks' bp <* closeListLevels+ where+ closeListLevels = modify $ \s -> s{ docxOpenListLevels = [] }++bodyPartToBlocks' :: PandocMonad m => BodyPart -> DocxContext m Blocks+bodyPartToBlocks' (Heading n style pPr numId lvl mblvlInfo parparts) = do ils <- local (\s-> s{docxInHeaderBlock=True}) (smushInlines <$> mapM parPartToInlines parparts) let classes = map normalizeToClassName . delete style@@ -712,7 +743,7 @@ let start = case M.lookup (numId, lvl) listState of Nothing -> case mblvlInfo of Nothing -> 1- Just (Level _ _ _ z) -> fromMaybe 1 z+ Just (Level _ _ _ z _) -> fromMaybe 1 z Just z -> z + 1 modify $ \st -> st{ docxListState = -- expire all the continuation data for lists of level > this one:@@ -722,77 +753,28 @@ in M.insert (numId, lvl) start (M.filterWithKey notExpired listState) } makeHeaderAnchor $ headerWith ("", addNum classes, []) n ils-bodyPartToBlocks (Paragraph pPr parparts) = do- let getMainPar- | Just True <- pBidi pPr = do- let pPr' = pPr { pBidi = Nothing }- local (\s -> s{ docxInBidi = True })- (bodyPartToBlocks (Paragraph pPr' parparts))- | isCodeDiv pPr = do- transform <- paragraphStyleToTransform pPr- return $- transform $- codeBlock $- T.concat $- map parPartToText parparts- | otherwise = do- ils <- trimSps . smushInlines <$> mapM parPartToInlines parparts- prevParaIls <- gets docxPrevPara- dropIls <- gets docxDropCap- let ils' = dropIls <> ils- let (paraOrPlain, pPr')- | hasStylesInheritedFrom ["Compact"] pPr = (plain, removeStyleNamed "Compact" pPr)- | otherwise = (para, pPr)- if dropCap pPr'- then do modify $ \s -> s { docxDropCap = ils' }- return mempty- else do modify $ \s -> s { docxDropCap = mempty }- let ils'' = (if null prevParaIls then mempty- else prevParaIls <> space) <> ils'- handleInsertion = do- modify $ \s -> s {docxPrevPara = mempty}- transform <- paragraphStyleToTransform pPr'- return $ transform $ paraOrPlain ils''- opts <- asks docxOptions- case (pChange pPr', readerTrackChanges opts) of- _ | null ils'', not (isEnabled Ext_empty_paragraphs opts) ->- return mempty- (Just (TrackedChange Insertion _), AcceptChanges) ->- handleInsertion- (Just (TrackedChange Insertion _), RejectChanges) -> do- modify $ \s -> s {docxPrevPara = ils''}- return mempty- (Just (TrackedChange Insertion (ChangeInfo _ cAuthor cDate))- , AllChanges) -> do- let attr = ("", ["paragraph-insertion"], addAuthorAndDate cAuthor cDate)- insertMark = spanWith attr mempty- transform <- paragraphStyleToTransform pPr'- return $ transform $- paraOrPlain $ ils'' <> insertMark- (Just (TrackedChange Deletion _), AcceptChanges) -> do- modify $ \s -> s {docxPrevPara = ils''}- return mempty- (Just (TrackedChange Deletion _), RejectChanges) ->- handleInsertion- (Just (TrackedChange Deletion (ChangeInfo _ cAuthor cDate))- , AllChanges) -> do- let attr = ("", ["paragraph-deletion"], addAuthorAndDate cAuthor cDate)- insertMark = spanWith attr mempty- transform <- paragraphStyleToTransform pPr'- return $ transform $- paraOrPlain $ ils'' <> insertMark- _ -> handleInsertion- (if pBottomBorder pPr- then (<> horizontalRule)- else id)- <$> getMainPar-bodyPartToBlocks (ListItem pPr numId lvl isRestart (Just levelInfo) parparts) = do+bodyPartToBlocks' (Paragraph pPr parparts) = do+ openLevels <- gets docxOpenListLevels+ let leftIndent = (indentation pPr >>= leftParIndent) <|>+ (pStyleIndentation pPr >>= leftParIndent)+ -- An unnumbered paragraph indented like the text of an open list+ -- item continues that item (this is how pandoc's docx writer and+ -- Word's "List Continue" styles do multi-paragraph list items):+ case break (\(ind, _, _) -> Just ind == leftIndent) openLevels of+ (_, levels@((_, lvl, numId) : _)) | not (numbered pPr) -> do+ modify $ \s -> s{ docxOpenListLevels = levels }+ divWith ("", ["list-continuation"], [("level", lvl), ("num-id", numId)])+ <$> paragraphToBlocks pPr{ indentation = Nothing } parparts+ _ -> do+ modify $ \s -> s{ docxOpenListLevels = [] }+ paragraphToBlocks pPr parparts+bodyPartToBlocks' (ListItem pPr numId lvl isRestart (Just levelInfo) parparts) = do -- We check whether this current abstract numbering id has previously been -- used, since Docx expects us to pick up where we left off -- unless this -- item explicitly restarts numbering (see #8367). listState <- gets docxListState let startFromState = M.lookup (numId, lvl) listState- Level _ fmt txt startFromLevelInfo = levelInfo+ Level _ fmt txt startFromLevelInfo lvlIndent = levelInfo start = case startFromState of Just n | not isRestart -> n + 1 _ -> fromMaybe 1 startFromLevelInfo@@ -807,13 +789,20 @@ -- a new level 1 list item resets continuation for level 2+ let notExpired (_, lvl') _ = lvl' <= lvl in M.insert (numId, lvl) start (M.filterWithKey notExpired listState) }- blks <- bodyPartToBlocks (Paragraph pPr parparts)+ -- record the indentation of the item's text, so that we can recognize+ -- unnumbered paragraphs continuing this item:+ let textIndent = (indentation pPr >>= leftParIndent) <|> lvlIndent <|>+ (pStyleIndentation pPr >>= leftParIndent)+ modify $ \st -> st{ docxOpenListLevels =+ maybe id (\ind -> ((ind, lvl, numId) :)) textIndent+ (filter (\(_, lvl', _) -> lvl' < lvl) (docxOpenListLevels st)) }+ blks <- paragraphToBlocks pPr parparts return $ divWith ("", ["list-item"], kvs) blks-bodyPartToBlocks (ListItem pPr _ _ _ _ parparts) =+bodyPartToBlocks' (ListItem pPr _ _ _ _ parparts) = let pPr' = pPr {pStyle = constructBogusParStyleData "list-paragraph": pStyle pPr} in bodyPartToBlocks $ Paragraph pPr' parparts-bodyPartToBlocks (Captioned parstyle parparts bpart) = do+bodyPartToBlocks' (Captioned parstyle parparts bpart) = do bs <- bodyPartToBlocks bpart captContents <- bodyPartToBlocks (Paragraph parstyle parparts) let capt = Caption Nothing (toList captContents)@@ -830,9 +819,9 @@ -> toCaptioned attr' bls' _ -> captContents pure $ toCaptioned nullAttr (toList bs)-bodyPartToBlocks (Tbl _ _ _ _ []) =+bodyPartToBlocks' (Tbl _ _ _ _ []) = return mempty-bodyPartToBlocks (Tbl mbsty cap grid look parts) = do+bodyPartToBlocks' (Tbl mbsty cap grid look parts) = do let fullCaption = if T.null cap then mempty else plain (text cap) let shortCaption = if T.null cap then Nothing else Just (toList (text cap)) cap' = caption shortCaption fullCaption@@ -847,11 +836,10 @@ -- Horizontal column alignment is taken from the first row's cells. numcols = length widths getAlignment (Docx.Cell al colspan _ _) =- take numcols $ replicate (fromIntegral colspan) (convertAlign al) ++- repeat Pandoc.AlignDefault+ replicate (fromIntegral colspan) (convertAlign al) getAlignments (Docx.Row _ cs) = concatMap getAlignment cs alignments = take numcols $- case hdr ++ rows of+ case rows ++ hdr of [] -> repeat Pandoc.AlignDefault r : _ -> getAlignments r @@ -865,7 +853,75 @@ (TableHead nullAttr headerCells) [TableBody nullAttr 0 [] bodyCells] (TableFoot nullAttr [])-bodyPartToBlocks HRule = pure Pandoc.horizontalRule+bodyPartToBlocks' HRule = pure Pandoc.horizontalRule++-- | Convert a paragraph (also used for the text of list items).+paragraphToBlocks :: PandocMonad m+ => ParagraphStyle -> [ParPart] -> DocxContext m Blocks+paragraphToBlocks pPr parparts = do+ let getMainPar+ | Just True <- pBidi pPr = do+ let pPr' = pPr { pBidi = Nothing }+ local (\s -> s{ docxInBidi = True })+ (paragraphToBlocks pPr' parparts)+ | isCodeDiv pPr = do+ transform <- paragraphStyleToTransform pPr+ return $+ transform $+ codeBlock $+ T.concat $+ map parPartToText parparts+ | otherwise = do+ ils <- trimSps . smushInlines <$> mapM parPartToInlines parparts+ prevParaIls <- gets docxPrevPara+ dropIls <- gets docxDropCap+ let ils' = dropIls <> ils+ let (paraOrPlain, pPr')+ | hasStylesInheritedFrom ["Compact"] pPr = (plain, removeStyleNamed "Compact" pPr)+ | otherwise = (para, pPr)+ if dropCap pPr'+ then do modify $ \s -> s { docxDropCap = ils' }+ return mempty+ else do modify $ \s -> s { docxDropCap = mempty }+ let ils'' = (if null prevParaIls then mempty+ else prevParaIls <> space) <> ils'+ handleInsertion = do+ modify $ \s -> s {docxPrevPara = mempty}+ transform <- paragraphStyleToTransform pPr'+ return $ transform $ paraOrPlain ils''+ opts <- asks docxOptions+ case (pChange pPr', readerTrackChanges opts) of+ _ | null ils'', not (isEnabled Ext_empty_paragraphs opts) ->+ return mempty+ (Just (TrackedChange Insertion _), AcceptChanges) ->+ handleInsertion+ (Just (TrackedChange Insertion _), RejectChanges) -> do+ modify $ \s -> s {docxPrevPara = ils''}+ return mempty+ (Just (TrackedChange Insertion (ChangeInfo _ cAuthor cDate))+ , AllChanges) -> do+ let attr = ("", ["paragraph-insertion"], addAuthorAndDate cAuthor cDate)+ insertMark = spanWith attr mempty+ transform <- paragraphStyleToTransform pPr'+ return $ transform $+ paraOrPlain $ ils'' <> insertMark+ (Just (TrackedChange Deletion _), AcceptChanges) -> do+ modify $ \s -> s {docxPrevPara = ils''}+ return mempty+ (Just (TrackedChange Deletion _), RejectChanges) ->+ handleInsertion+ (Just (TrackedChange Deletion (ChangeInfo _ cAuthor cDate))+ , AllChanges) -> do+ let attr = ("", ["paragraph-deletion"], addAuthorAndDate cAuthor cDate)+ insertMark = spanWith attr mempty+ transform <- paragraphStyleToTransform pPr'+ return $ transform $+ paraOrPlain $ ils'' <> insertMark+ _ -> handleInsertion+ (if pBottomBorder pPr+ then (<> horizontalRule)+ else id)+ <$> getMainPar -- replace targets with generated anchors. rewriteLink' :: PandocMonad m => Inline -> DocxContext m Inline
@@ -32,6 +32,11 @@ isListItem (Div (_, classes, _) _) | "list-item" `elem` classes = True isListItem _ = False +-- | An unnumbered paragraph continuing a list item.+isListContinuation :: Block -> Bool+isListContinuation (Div (_, classes, _) _) = "list-continuation" `elem` classes+isListContinuation _ = False+ getLevel :: Block -> Maybe Integer getLevel (Div (_, _, kvs) _) = lookup "level" kvs >>= safeRead getLevel _ = Nothing@@ -115,6 +120,8 @@ separateBlocks' b@(OrderedList _ _) acc = init acc ++ [last acc ++ [b]] -- The following is for the invisible bullet lists. This is how -- pandoc-generated ooxml does multiparagraph item lists.+separateBlocks' b acc | isListContinuation b =+ init acc ++ [last acc ++ [b]] separateBlocks' b acc | fmap trim (getText b) == Just "" = init acc ++ [last acc ++ [b]] separateBlocks' b acc = acc ++ [[b]]@@ -219,6 +226,8 @@ case delete "list-item" classes of [] -> blks classes' -> [Div (ident, classes', kvs) blks]+removeListDivs' b@(Div _ blks)+ | isListContinuation b = blks removeListDivs' (Div (ident, classes, kvs) blks) | not $ null $ listParagraphDivs `intersect` classes = case classes \\ listParagraphDivs of
@@ -249,8 +249,8 @@ data AbstractNumb = AbstractNumb T.Text [Level] deriving Show --- ilvl format string start-data Level = Level T.Text T.Text T.Text (Maybe Integer)+-- ilvl format string start left indent+data Level = Level T.Text T.Text T.Text (Maybe Integer) (Maybe Integer) deriving Show data DocumentLocation = InDocument | InFootnote | InEndnote@@ -620,9 +620,9 @@ case lvlOverride of Just (LevelOverride _ _ (Just lvl')) -> Just lvl' Just (LevelOverride _ (Just strt) _) ->- lookup ilvl $ map (\(Level i fmt s _) -> (i, Level i fmt s (Just strt))) lvls+ lookup ilvl $ map (\(Level i fmt s _ ind) -> (i, Level i fmt s (Just strt) ind)) lvls _ ->- lookup ilvl $ map (\l@(Level i _ _ _) -> (i, l)) lvls+ lookup ilvl $ map (\l@(Level i _ _ _ _) -> (i, l)) lvls -- | Given a @numId@ and level, return the abstract numbering id (the stable -- identifier shared by all numbering instances based on the same abstract@@ -690,7 +690,8 @@ let start = findChildByName ns "w" "start" element >>= findAttrByName ns "w" "val" >>= stringToInteger- return (Level ilvl fmt txt start)+ let ind = getIndentation ns element >>= leftParIndent+ return (Level ilvl fmt txt start ind) levelElemToLevel _ _ = Nothing archiveToNumbering' :: Archive -> Maybe Numbering@@ -763,9 +764,13 @@ case sum xs of tot | tot > 1.0 -> map (/ tot) xs _ -> xs- normalizeFractions <$>- mapD (\e -> maybeToD (findAttrByName ns "w" "w" e >>=- fmap toFraction . safeRead)) cols+ -- w:w is optional. If a column has no width, we keep it but leave+ -- every column's width unspecified (0), since writers don't handle+ -- a mix of specified and unspecified widths well.+ return $+ case mapM (findAttrByName ns "w" "w" >=> safeRead) cols of+ Just widths -> normalizeFractions (map toFraction widths)+ Nothing -> replicate (length cols) 0 elemToTblGrid _ _ = throwError WrongElem elemToTblLook :: NameSpaces -> Element -> D TblLook@@ -1109,18 +1114,28 @@ info <- eitherToD $ parseFieldInfo t modify $ \st -> st {stateFldCharState = FldCharContent info [] : ancestors} return []+ -- A field with no instruction (e.g. a dead cross-reference, or+ -- one whose w:instrText sits inside a tracked change):+ FldCharOpen : ancestors | fldCharType == "separate" -> do+ modify $ \st -> st {stateFldCharState = FldCharContent UnknownField [] : ancestors}+ return [] -- Some fields have no content, e.g. index XE: FldCharFieldInfo t : ancestors | fldCharType == "end" -> do modify $ \st -> st {stateFldCharState = ancestors} info <- eitherToD $ parseFieldInfo t return [Field info []]- [FldCharContent info children] | fldCharType == "end" -> do- modify $ \st -> st {stateFldCharState = []}- return [Field info $ reverse children]+ FldCharOpen : ancestors | fldCharType == "end" -> do+ modify $ \st -> st {stateFldCharState = ancestors}+ return [Field UnknownField []] FldCharContent info children : FldCharContent parentInfo siblings : ancestors | fldCharType == "end" -> let parent = FldCharContent parentInfo $ (Field info (reverse children)) : siblings in do modify $ \st -> st {stateFldCharState = parent : ancestors} return []+ -- Always pop the field, even if the enclosing field is not+ -- (yet) in its content, so that the state cannot get stuck:+ FldCharContent info children : ancestors | fldCharType == "end" -> do+ modify $ \st -> st {stateFldCharState = ancestors}+ return [Field info $ reverse children] _ -> throwError WrongElem elemToParPart ns element | isElem ns "w" "r" element@@ -1212,6 +1227,12 @@ runs <- mconcat <$> mapD (elemToParPart' ns) (elChildren element) return [ChangedRuns change runs] elemToParPart' ns element+ | isElem ns "w" "fldSimple" element+ , Just instr <- findAttrByName ns "w" "instr" element = do+ info <- eitherToD $ parseFieldInfo instr+ children <- mconcat <$> mapD (elemToParPart ns) (elChildren element)+ return [Field info children]+elemToParPart' ns element | isElem ns "w" "bookmarkStart" element , Just bmId <- findAttrByName ns "w" "id" element , Just bmName <- findAttrByName ns "w" "name" element =@@ -1239,9 +1260,9 @@ elemToParPart' ns element | isElem ns "w" "commentRangeStart" element , Just cmtId <- findAttrByName ns "w" "id" element = do- (Comments _ commentMap) <- asks envComments+ (Comments cmtNs commentMap) <- asks envComments case M.lookup cmtId commentMap of- Just cmtElem -> elemToCommentStart ns cmtElem+ Just cmtElem -> elemToCommentStart cmtNs cmtElem Nothing -> throwError WrongElem elemToParPart' ns element | isElem ns "w" "commentRangeEnd" element@@ -1310,17 +1331,17 @@ childElemToRun ns element | isElem ns "w" "footnoteReference" element , Just fnId <- findAttrByName ns "w" "id" element = do- notes <- asks envNotes+ notes@(Notes notesNs _ _) <- asks envNotes case lookupFootnote fnId notes of- Just e -> do bps <- local (\r -> r {envLocation=InFootnote}) $ mapD (elemToBodyPart ns) (elChildren e)+ Just e -> do bps <- local (\r -> r {envLocation=InFootnote}) $ mapD (elemToBodyPart notesNs) (elChildren e) return [Footnote bps] Nothing -> return [Footnote []] childElemToRun ns element | isElem ns "w" "endnoteReference" element , Just enId <- findAttrByName ns "w" "id" element = do- notes <- asks envNotes+ notes@(Notes notesNs _ _) <- asks envNotes case lookupEndnote enId notes of- Just e -> do bps <- local (\r -> r {envLocation=InEndnote}) $ mapD (elemToBodyPart ns) (elChildren e)+ Just e -> do bps <- local (\r -> r {envLocation=InEndnote}) $ mapD (elemToBodyPart notesNs) (elChildren e) return [Endnote bps] Nothing -> return [Endnote []] childElemToRun _ _ = throwError WrongElem@@ -1513,11 +1534,14 @@ stripCaptionLabel els = if null afters then els- else filter isBookmark befores <> afters+ else filter isBookmark befores <> dropNumber afters where (befores, afters) = break isNumberElt els isBookmark (Element name _ _ _) = qName name == "bookmarkStart" || qName name == "bookmarkEnd"+ -- A w:fldSimple carries the number as its result: drop it with the label.+ dropNumber (el:rest) | qName (elName el) == "fldSimple" = rest+ dropNumber rest = rest isNumberElt el@(Element name attribs _ _) = (qName name == "fldSimple" && case lookupAttrBy ((== "instr") . qName) attribs of
@@ -66,7 +66,7 @@ import Text.Pandoc.Parsing hiding ((<|>)) import Text.Pandoc.Shared ( addMetaField, extractSpaces, htmlSpanLikeElements, renderTags',- safeRead, tshow, formatCode)+ safeRead, tshow, formatCode, plainToPara) import Text.Pandoc.URI (escapeURI) import Text.Pandoc.Walk import Text.TeXMath (readMathML, writeTeX)@@ -485,8 +485,6 @@ isParaish OrderedList{} = not inList isParaish DefinitionList{} = not inList isParaish _ = False- plainToPara (Plain xs) = Para xs- plainToPara x = x bs' = B.toList bs pRawTag :: PandocMonad m => TagParser m Text
@@ -191,6 +191,11 @@ , sCaseExclusions :: M.Map Text (Set.Set Text) -- ^ words excluded from case changing -- (keys: @upper@, @lower@, @title@)+ , sLastExpansion :: Maybe (Text, SourcePos, Int)+ -- ^ name and position of the last macro+ -- expanded, and the number of consecutive+ -- times it has been expanded there+ -- (used to detect expansion loops) } deriving Show @@ -225,6 +230,7 @@ , sRawScopes = 0 , sLigatures = True , sCaseExclusions = M.empty+ , sLastExpansion = Nothing } instance PandocMonad m => HasQuoteContext LaTeXState m where@@ -752,6 +758,18 @@ -- macro call, so we continue expanding: Nothing -> trySpecialMacro name ts >>= doMacros' (n' + 1) Just (Macro _scope expansionPoint argspecs optarg newtoks) -> do+ -- A macro whose expansion contains itself after an+ -- unknown command (e.g. \def\small{\@setfontsize\small..})+ -- would be expanded again and again at the same position,+ -- each time in a fresh call to doMacros (#11088):+ lastExp <- sLastExpansion <$> getState+ let expCount = case lastExp of+ Just (name', spos', i)+ | name' == name, spos' == spos -> i + 1+ _ -> 1 :: Int+ when (expCount > 1000) $ throwError $ PandocMacroLoop name+ updateState $ \st -> st{ sLastExpansion =+ Just (name, spos, expCount) } let getargs' = do args <- (case expansionPoint of
@@ -1039,10 +1039,6 @@ then fmap (fmap (fmap paraToPlain)) else id) (sequence contents)) -paraToPlain :: Block -> Block-paraToPlain (Para ils) = Plain ils-paraToPlain x = x- definitionList :: PandocMonad m => MarkdownParser m (F Blocks) definitionList = try $ do guardEnabled Ext_definition_lists
@@ -1,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} {- | Module : Text.Pandoc.Readers.Metadata Copyright : Copyright (C) 2006-2024 John MacFarlane@@ -20,24 +21,22 @@ import Control.Monad.Except (throwError) import qualified Data.ByteString as B+import qualified Data.List as L import qualified Data.Map as M import qualified Data.Vector as V import Data.Text (Text) import qualified Data.Text as T-import qualified Data.Yaml as Yaml-import qualified Data.Yaml.Internal as Yaml-import qualified Text.Libyaml as Y-import Data.Aeson (Value(..), Object, Result(..), fromJSON, (.:?), withObject,- FromJSON)-import Data.Aeson.Types (formatRelativePath, parse)+import qualified Data.List.NonEmpty as NE+import qualified Yamlet as Y+import Yamlet.Aeson ()+import Data.Aeson (Value(..), Object, Result(..), fromJSON, (.:?), withObject)+import Data.Aeson.Types (parse) import Text.Pandoc.Shared (tshow, blocksToInlines)-import Text.Pandoc.Class (PandocMonad (..), report)+import Text.Pandoc.Class (PandocMonad (..)) import Text.Pandoc.Definition import Text.Pandoc.Error-import Text.Pandoc.Logging (LogMessage(YamlWarning)) import Text.Pandoc.Parsing hiding (tableWith, parse) import qualified Text.Pandoc.UTF8 as UTF8-import System.IO.Unsafe (unsafePerformIO) yamlBsToMeta :: (PandocMonad m, HasLastStrPosition st) => ParsecT Sources st m (Future st MetaValue)@@ -45,37 +44,28 @@ -> ParsecT Sources st m (Future st Meta) yamlBsToMeta pMetaValue bstr = do pos <- getPosition- case decodeAllWithWarnings bstr of- Right (warnings, xs) -> do- mapM_ (\(Yaml.DuplicateKey jpath) ->- report (YamlWarning pos $ "Duplicate key: " <>- T.pack (formatRelativePath jpath)))- warnings+ case Y.decodeAll @Value bstr of+ Right xs -> case xs of (Object o : _) -> fmap Meta <$> yamlMap pMetaValue o [Null] -> return . return $ mempty [] -> return . return $ mempty _ -> Prelude.fail "expected YAML object"- Left err' -> do- let msg = T.pack $ "Error parsing YAML metadata at " <>- show pos <> ":\n" <>- Yaml.prettyPrintParseException err'- throwError $ PandocParseError $- if "did not find expected key" `T.isInfixOf` msg- then msg <>- "\nConsider enclosing the entire field in 'single quotes'"- else msg+ Left errs -> throwError $ PandocParseError $ T.pack $+ "Error parsing YAML metadata at " <> show pos <> ":\n" <>+ renderYamlErrors pos errs -decodeAllWithWarnings :: FromJSON a- => B.ByteString- -> (Either Yaml.ParseException ([Yaml.Warning], [a]))-decodeAllWithWarnings = either Left (\(ws,res)- -> case res of- Left s -> Left (Yaml.AesonException s)- Right v -> Right (ws, v))- . unsafePerformIO- . Yaml.decodeAllHelper- . Y.decode+-- | Render the errors with their lines in the source, given the position of+-- the first line of the YAML input.+renderYamlErrors :: SourcePos -> NE.NonEmpty Y.Error -> String+renderYamlErrors pos =+ L.intercalate "\n" . map (Y.prettyError (sourceName pos) . shift) . NE.toList+ where+ shift :: Y.Error -> Y.Error+ shift err@Y.Error{Y.location = loc@Y.Location{Y.line = l}}+ -- Line 0 means that the error has no position.+ | l == 0 = err+ | otherwise = err{Y.location = loc{Y.line = l + sourceLine pos - 1}} -- Returns filtered list of references. yamlBsToRefs :: (PandocMonad m, HasLastStrPosition st)@@ -83,8 +73,9 @@ -> (Text -> Bool) -- ^ Filter for id -> B.ByteString -> ParsecT Sources st m (Future st [MetaValue])-yamlBsToRefs pMetaValue idpred bstr =- case Yaml.decodeAllEither' bstr of+yamlBsToRefs pMetaValue idpred bstr = do+ pos <- getPosition+ case Y.decodeAll @Value bstr of Right (Object m : _) -> do case parse (withObject "metadata" (.:? "references")) (Object m) of Success (Just refs) -> sequence <$>@@ -94,8 +85,8 @@ let refs = filter hasSelectedId $ V.toList v sequence <$> mapM (yamlToMetaValue pMetaValue) (filter hasSelectedId refs) Right _ -> return . return $ []- Left err' -> throwError $ PandocParseError- $ T.pack $ Yaml.prettyPrintParseException err'+ Left errs -> throwError $ PandocParseError+ $ T.pack $ renderYamlErrors pos errs where isSelected (String t) = idpred t isSelected _ = False
@@ -74,18 +74,21 @@ , styleTrace :: [Style] -- | Keeps track of the current depth in nested lists , currentListLevel :: ListLevel- -- | Keeps track of the previous list start counters,- -- so whenever a new list continues numbering,- -- we know what number to start from.- -- If list does not continue numbering, the counter- -- is being reset.- , listContinuationStartCounters :: M.Map ListLevel Int+ -- | Keeps track of the previous list start counters+ -- for each list style and level, so whenever a new+ -- list continues numbering, we know what number to+ -- start from. The counters for deeper levels are+ -- reset whenever a new list item starts.+ , listContinuationStartCounters+ :: M.Map (Maybe StyleName, ListLevel) Int -- | Lists may provide their own style, but they don't have -- to. If they do not, the style of a parent list may be used -- or even a default list style from the paragraph style. -- This value keeps track of the closest list style there -- currently is. , currentListStyle :: Maybe ListStyle+ -- | The name of 'currentListStyle', if known.+ , currentListStyleName :: Maybe StyleName -- | A map from internal anchor names to "pretty" ones. -- The mapping is a purely cosmetic one. , bookmarkAnchors :: M.Map Anchor Anchor@@ -103,7 +106,7 @@ readerState :: Styles -> [(FilePath, B.ByteString)] -> ReaderState readerState styles media =- ReaderState styles [] 0 M.empty Nothing M.empty Set.empty+ ReaderState styles [] 0 M.empty Nothing Nothing M.empty Set.empty (M.fromList media) mempty --@@ -120,10 +123,21 @@ modifyListLevel f state = state { currentListLevel = f (currentListLevel state) } ---modifyListContinuationStartCounter :: ListLevel -> Int -> (ReaderState -> ReaderState)-modifyListContinuationStartCounter listLevel count state =- state { listContinuationStartCounters = M.insert listLevel count (listContinuationStartCounters state) }+modifyListContinuationStartCounter :: Maybe StyleName -> ListLevel -> Int+ -> (ReaderState -> ReaderState)+modifyListContinuationStartCounter mStyleName listLevel count state =+ state { listContinuationStartCounters =+ M.insert (mStyleName, listLevel) count+ (listContinuationStartCounters state) } +-- | Reset the counters of all list levels deeper than the given one.+resetDeeperListContinuationStartCounters :: ListLevel+ -> (ReaderState -> ReaderState)+resetDeeperListContinuationStartCounters listLevel state =+ state { listContinuationStartCounters =+ M.filterWithKey (\(_, lvl) _ -> lvl <= listLevel)+ (listContinuationStartCounters state) }+ -- shiftListLevel :: ListLevel -> (ReaderState -> ReaderState) shiftListLevel diff = modifyListLevel (+ diff)@@ -169,11 +183,13 @@ lookupListStyle name = getStyles >>= fromMaybeF . lookupListStyleByName name ---switchCurrentListStyle :: Maybe ListStyle -> ODTReader (Maybe ListStyle)+switchCurrentListStyle :: Maybe (StyleName, ListStyle)+ -> ODTReader (Maybe (StyleName, ListStyle)) switchCurrentListStyle mListStyle = do state <- getExtraState- setExtraState $ state { currentListStyle = mListStyle }- return $ currentListStyle state+ setExtraState $ state { currentListStyle = snd <$> mListStyle+ , currentListStyleName = fst <$> mListStyle }+ return $ (,) <$> currentListStyleName state <*> currentListStyle state -- pushStyle :: Style -> ODTReader ()@@ -188,9 +204,10 @@ getCurrentListLevel = currentListLevel <$> getExtraState ---getPreviousListStartCounter :: ListLevel -> ODTReader Int-getPreviousListStartCounter listLevel =- M.findWithDefault 0 listLevel . listContinuationStartCounters+getPreviousListStartCounter :: Maybe StyleName -> ListLevel+ -> ODTReader (Maybe Int)+getPreviousListStartCounter mStyleName listLevel =+ M.lookup (mStyleName, listLevel) . listContinuationStartCounters <$> getExtraState --@@ -415,22 +432,28 @@ constructList reader = do modifyExtraState (shiftListLevel 1) listLevel <- getCurrentListLevel- listContinuationStartCounter <- getPreviousListStartCounter listLevel fStyleName <- tryC (findAttr NsText "style-name") fContNumbering <- tryC (findAttr NsText "continue-numbering")+ inheritedStyleName <- currentListStyleName <$> getExtraState + -- Numbering is continued from the previous list with the same+ -- list style (and level), if there is one:+ let mStyleName = either (const inheritedStyleName) Just fStyleName+ listContinuationStartCounter <- getPreviousListStartCounter mStyleName+ listLevel+ let continueNumbering = fContNumbering == Right "true" startNumForListLevelStyle mListLevelStyle- | continueNumbering = listContinuationStartCounter- | isJust mListLevelStyle = listItemStart (fromJust mListLevelStyle)- | otherwise = 1+ | continueNumbering+ , Just n <- listContinuationStartCounter = n+ | otherwise = maybe 1 listItemStart mListLevelStyle constructWith startNum constructor = do items <- reader modifyExtraState (shiftListLevel (-1))- modifyExtraState (modifyListContinuationStartCounter listLevel- (startNum + length items))+ modifyExtraState (modifyListContinuationStartCounter mStyleName+ listLevel (startNum + length items)) return $ constructor items constructOrderedList =@@ -449,7 +472,8 @@ Right listStyle -> case getListLevelStyle listLevel listStyle of Just listLevelStyle -> do- oldListStyle <- switchCurrentListStyle (Just listStyle)+ oldListStyle <- switchCurrentListStyle+ (Just (styleName, listStyle)) blocks <- constructListWith listLevelStyle _ <- switchCurrentListStyle oldListStyle return blocks@@ -681,8 +705,14 @@ read_list_element :: ElementName -> Matcher [Blocks] read_list_element listElement = matchingElement NsText listElement- $ compactify . (:[])- <$> matchBlockContent+ $ do+ -- a new item restarts the numbering+ -- of nested lists:+ listLevel <- getCurrentListLevel+ modifyExtraState+ (resetDeeperListContinuationStartCounters+ listLevel)+ compactify . (:[]) <$> matchBlockContent ---------------------- -- Sections
@@ -1570,6 +1570,7 @@ inline :: PandocMonad m => RSTParser m Inlines inline = (note -- can start with whitespace, so try before ws+ <|> quotedSymbol <|> do notAfterString >>= guard (link <|> inlineAnchor <|> strong <|> emph) <|> code@@ -1599,8 +1600,11 @@ unless (canPrecedeOpener c) updateLastStrPos return $ B.str $ T.singleton c +-- Characters that may precede an inline markup start-string: the ASCII+-- characters - : / ' " < ( [ { and similar non-ASCII punctuation. canPrecedeOpener :: Char -> Bool canPrecedeOpener c =+ c == ':' || c == '/' || c == '\'' || c == '"' || c == '<' || generalCategory c `elem` [OpenPunctuation, InitialQuote, FinalQuote, DashPunctuation, OtherSymbol] @@ -1609,6 +1613,21 @@ c <- satisfy isSpecialChar unless (canPrecedeOpener c) updateLastStrPos return $ B.str $ T.singleton c++-- A start-string between an opening character and the matching closing+-- character, as in (*) or "*", is not inline markup.+quotedSymbol :: Monad m => RSTParser m Inlines+quotedSymbol = try $ do+ opener <- oneOf "([{<\"'\8216\8220"+ case lookup opener openersClosers of+ Nothing -> mzero+ Just closer ->+ B.text . (\c -> T.pack [opener, c, closer])+ <$> try (oneOf "*`|" <* char closer)+ where+ openersClosers = [('(', ')'), ('[', ']'), ('{', '}'), ('<', '>'),+ ('"', '"'), ('\'', '\''),+ ('\8216', '\8217'), ('\8220', '\8221')] -- parses inline code, between codeStart and codeEnd code :: Monad m => RSTParser m Inlines
@@ -34,7 +34,7 @@ import Text.Pandoc.Parsing import Text.Pandoc.Logging (LogMessage(UnsupportedCodePage)) import Text.Pandoc.Shared (tshow)-import Data.Char (isAlphaNum, chr, isAscii, isLetter, isSpace, ord)+import Data.Char (chr, isAscii, isLetter, isSpace, ord) import qualified Data.ByteString.Lazy as BL import Data.Maybe (mapMaybe, fromMaybe) import Safe (lastMay, initSafe, headDef)@@ -261,7 +261,8 @@ <|> (ControlSymbol <$> anyChar) ) controlWord = do name <- letterSequence- param <- parameter <* optional delimChar+ param <- parameter+ optional (char ' ') case name of "bin" -> do let n = fromMaybe 0 param@@ -318,9 +319,6 @@ isSpecial '\\' = True isSpecial '\n' = True isSpecial _ = False--delimChar :: PandocMonad m => RTFParser m Char-delimChar = satisfy (\c -> not (isAlphaNum c || isSpecial c)) modifyGroup :: PandocMonad m => (Properties -> Properties)
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-} {- | Module : Text.Pandoc.Readers.Vimwiki Copyright : Copyright (C) 2017-2020 Yuchen Pei
@@ -1,5 +1,4 @@ {-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -50,6 +49,8 @@ compactify, compactifyDL, compactifyTable,+ plainToPara,+ paraToPlain, linesToPara, figureDiv, makeSections,@@ -457,10 +458,15 @@ -> items _ -> map (fmap plainToPara) items +-- | Convert a @Plain@ block to a @Para@; leave other blocks unchanged. plainToPara :: Block -> Block plainToPara (Plain ils) = Para ils plainToPara x = x +-- | Convert a @Para@ block to a @Plain@; leave other blocks unchanged.+paraToPlain :: Block -> Block+paraToPlain (Para ils) = Plain ils+paraToPlain x = x -- | Like @compactify@, but acts on items of definition lists. compactifyDL :: [(Inlines, [Blocks])] -> [(Inlines, [Blocks])]@@ -490,8 +496,6 @@ isSimpleCell [Plain _] = All True isSimpleCell _ = All False isSimpleTable = getAll . query isSimpleCell- paraToPlain (Para ils) = Plain ils- paraToPlain b = b -- walk descends into the notes, so we need to fix them back up: fixNotes (Note [Plain ils]) = Note [Para ils] fixNotes i = i
@@ -1,5 +1,5 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-} {- | Module : Text.Pandoc.Translations Copyright : Copyright (C) 2017-2024 John MacFarlane@@ -27,18 +27,19 @@ import Text.Pandoc.Logging (LogMessage(..)) import Control.Monad.Except (catchError) import qualified Data.Text as T-import qualified Data.Yaml as Yaml-import qualified Text.Pandoc.UTF8 as UTF8-import Data.Yaml (prettyPrintParseException)+import qualified Data.List.NonEmpty as NE+import qualified Yamlet as Y+import Yamlet.Aeson import Text.Collate.Lang (Lang(..), renderLang) --- | Parse YAML translations.-readTranslations :: T.Text -> Either T.Text Translations-readTranslations s =- case Yaml.decodeAllEither' $ UTF8.fromText s of- Left err' -> Left $ T.pack $ prettyPrintParseException err'- Right (t:_) -> Right t- Right [] -> Left "empty YAML document"+-- | Parse YAML translations. The file path is used in error messages.+readTranslations :: FilePath -> T.Text -> Either T.Text Translations+readTranslations fp s =+ case Y.decodeAllText @(ViaAeson Translations) s of+ Left errs -> Left $ T.intercalate "\n" $+ map (T.pack . Y.prettyError fp) (NE.toList errs)+ Right (ViaAeson t:_) -> Right t+ Right [] -> Left $ T.pack fp <> ": empty YAML document" -- | Select the language to use with 'translateTerm'. -- Note that this does not read a translation file;@@ -68,12 +69,11 @@ let getTrans [] = return mempty getTrans (fp:fps) = do result <- catchError (Right <$> (readDataFile fp >>= toTextM fp))- (\_ -> pure (Left ""))- case result >>= readTranslations of+ (\_ -> pure (Left (T.pack fp)))+ case result >>= readTranslations fp of Left e | null fps -> do- report $ CouldNotLoadTranslations (renderLang lang)- (T.pack fp <> ": " <> e)+ report $ CouldNotLoadTranslations (renderLang lang) e -- make sure we don't try again... modifyCommonState $ \st -> st{ stTranslations = Nothing }
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-}
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- | Module : Text.Pandoc.Version Copyright : Copyright (C) 2022-2024 John MacFarlane
@@ -79,9 +79,7 @@ metadata <- metaToContext opts (blockListToANSI opts) (inlineListToANSI opts) meta- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts let title = titleBlock colwidth metadata let blocks' = makeSections (writerNumberSections opts) Nothing blocks body <- blockListToANSI opts blocks'
@@ -53,7 +53,6 @@ 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) @@ -111,9 +110,6 @@ pandocToAsciiDoc opts (Pandoc meta blocks) = do let titleblock = not $ null (docTitle meta) && null (docAuthors meta) && null (docDate meta)- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing metadata <- metaToContext opts (blockListToAsciiDoc opts) (fmap chomp . inlineListToAsciiDoc opts)@@ -126,10 +122,7 @@ isJust (writerTemplate opts)) $ defField "math" (hasMath st && not (legacy st)) $ defField "titleblock" titleblock metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main data EscContext = Normal | InTable deriving (Show, Eq)
@@ -26,10 +26,10 @@ import Text.Pandoc.Citeproc.BibTeX as BibTeX import Text.Pandoc.Citeproc.MetaValue (metaValueToReference) import Text.Pandoc.Writers.Shared (lookupMetaString, defField,- addVariablesToContext)-import Text.DocLayout (render, vcat)+ addVariablesToContext,+ renderWithTemplate)+import Text.DocLayout (vcat) import Text.DocTemplates (Context(..))-import Text.Pandoc.Templates (renderTemplate) -- | Write BibTeX based on the references metadata from a Pandoc document. writeBibTeX :: PandocMonad m => WriterOptions -> Pandoc -> m Text@@ -50,10 +50,4 @@ let main = vcat $ map (BibTeX.writeBibtexString opts variant mblang) refs let context = defField "body" main $ addVariablesToContext opts (mempty :: Context Text)- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main
@@ -37,7 +37,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI (isURI)-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Walk (query) import Text.Pandoc.Writers.Shared import Text.Printf (printf)@@ -86,9 +85,6 @@ pandocToConTeXt :: PandocMonad m => WriterOptions -> Pandoc -> WM m Text pandocToConTeXt options (Pandoc meta blocks) = do- let colwidth = if writerWrapText options == WrapAuto- then Just $ writerColumns options- else Nothing metadata <- metaToContext options blockListToConTeXt (fmap chomp . inlineListToConTeXt)@@ -144,10 +140,7 @@ _ -> id) metadata let context' = defField "context-dir" (maybe mempty toContextDir $ getField "dir" context) context- return $ render colwidth $- case writerTemplate options of- Nothing -> main- Just tpl -> renderTemplate tpl context'+ return $ renderWithTemplate options context' main -- change rtl to r2l, ltr to l2r toContextDir :: Doc Text -> Doc Text
@@ -27,11 +27,11 @@ import qualified Data.Text as T import qualified Data.Map as M import qualified Text.Pandoc.UTF8 as UTF8-import Text.Pandoc.Writers.Shared ( metaToContext, defField, toLegacyTable )+import Text.Pandoc.Writers.Shared ( metaToContext, defField, toLegacyTable,+ renderWithTemplate ) import Text.Pandoc.Shared (isTightList, tshow, stringifyInlines, onlySimpleTableCells, makeSections) import Text.DocLayout-import Text.DocTemplates (renderTemplate) import Control.Monad.State (StateT(..), gets, modify) import Control.Monad (zipWithM, when)@@ -43,9 +43,6 @@ -- | Convert Pandoc to Djot. writeDjot :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeDjot opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing let ropts = RenderOptions{ preserveSoftBreaks = writerWrapText opts == WrapPreserve } metadata <- metaToContext opts@@ -56,10 +53,7 @@ main <- renderDjot ropts <$> bodyToDjot opts (makeSections False Nothing blocks) let context = defField "body" main metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main data DjotState = DjotState
@@ -66,9 +66,7 @@ authorToDocBook :: PandocMonad m => WriterOptions -> [Inline] -> DB m B.Inlines authorToDocBook opts name' = do name <- render Nothing <$> inlinesToDocBook opts name'- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts return $ B.rawInline "docbook" $ render colwidth $ inTags True "personname" [] $ if T.any (== ',') name@@ -99,9 +97,7 @@ writeDocBook :: PandocMonad m => WriterOptions -> Pandoc -> DB m Text writeDocBook opts doc = do let Pandoc meta blocks = ensureValidXmlIdentifiers doc- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts let startLvl = getStartLvl opts let fromBlocks = blocksToDocBook opts . makeSections False (Just startLvl)@@ -126,11 +122,6 @@ blocksToDocBook :: PandocMonad m => WriterOptions -> [Block] -> DB m (Doc Text) blocksToDocBook opts = fmap vcat . mapM (blockToDocBook opts) --- | Auxiliary function to convert Plain block to Para.-plainToPara :: Block -> Block-plainToPara (Plain x) = Para x-plainToPara x = x- -- | Convert a list of pairs of terms and definitions into a list of -- DocBook varlistentrys. deflistItemsToDocBook :: PandocMonad m@@ -162,8 +153,8 @@ inTagsIndented "listitem" <$> blocksToDocBook opts (map plainToPara item) imageToDocBook :: WriterOptions -> Attr -> Text -> Doc Text-imageToDocBook _ attr src = selfClosingTag "imagedata" $- ("fileref", src) : idAndRole attr <> dims+imageToDocBook opts attr src = selfClosingTag "imagedata" $+ ("fileref", src) : idAndRole opts attr <> dims where dims = go Width "width" <> go Height "depth" go dir dstr = case dimension dir attr of@@ -206,7 +197,8 @@ return $ inTags True tag attribs $ inTagsSimple "title" title' $$ contents blockToDocBook opts (Div (ident,classes,_) bs) = do version <- ask- let identAttribs = [(idName version, ident) | not (T.null ident)]+ let identAttribs = [(idName version, writerIdentifierPrefix opts <> ident)+ | not (T.null ident)] admonitions = ["caution","danger","important","note","tip","warning"] case classes of (l:_) | l `elem` admonitions -> do@@ -396,7 +388,8 @@ version <- ask ((if T.null ident then mempty- else selfClosingTag "anchor" [(idName version, ident)]) <>) <$>+ else selfClosingTag "anchor"+ [(idName version, writerIdentifierPrefix opts <> ident)]) <>) <$> inlinesToDocBook opts ils inlineToDocBook _ (Code _ str) = return $ inTagsSimple "literal" $ literal (escapeStringForXML str)@@ -444,10 +437,10 @@ then let tag = if null txt then "xref" else "link" in inTags False tag $ ("linkend", writerIdentifierPrefix opts <> T.drop 1 src) :- idAndRole attr+ idAndRole opts attr else if version == DocBook5- then inTags False "link" $ ("xlink:href", src) : idAndRole attr- else inTags False "ulink" $ ("url", src) : idAndRole attr )+ then inTags False "link" $ ("xlink:href", src) : idAndRole opts attr+ else inTags False "ulink" $ ("url", src) : idAndRole opts attr ) <$> inlinesToDocBook opts txt inlineToDocBook opts (Image attr ils (src, tit)) = return $ let titleDoc = if T.null tit@@ -469,10 +462,10 @@ isMathML MathML = True isMathML _ = False -idAndRole :: Attr -> [(Text, Text)]-idAndRole (id',cls,_) = ident <> role+idAndRole :: WriterOptions -> Attr -> [(Text, Text)]+idAndRole opts (id',cls,_) = ident <> role where- ident = [("id", id') | not (T.null id')]+ ident = [("id", writerIdentifierPrefix opts <> id') | not (T.null id')] role = [("role", T.unwords cls) | not (null cls)] -- Used in blockToDocBook for Header (section) to create or extend
@@ -790,13 +790,19 @@ listLevel <- asks envListLevel numid <- asks envListNumId numIdUsed <- gets stNumIdUsed- -- clear numId after first use to support multiple paragraphs in the same bullet- -- baseListId is the code for no list marker- let numid' = if numIdUsed then baseListId else numid modify $ \st -> st{ stNumIdUsed = True }- let listPr = [mknode "w:numPr" []- [ mknode "w:ilvl" [("w:val",tshow listLevel)] ()- , mknode "w:numId" [("w:val",tshow numid')] () ] | listLevel >= 0 && not displayMathPara]+ -- Only the first paragraph of a list item gets numbering. Subsequent+ -- paragraphs in the same item are not numbered, but indented to line+ -- up with the item's text (see the w:ind in mkLvl), so that they are+ -- not mistaken for items of another list (#9197):+ let listPr+ | listLevel < 0 || displayMathPara = []+ | numIdUsed = [mknode "w:ind"+ [ ("w:left", tshow (listLevel * 720 + 720))+ , ("w:firstLine", "0") ] ()]+ | otherwise = [mknode "w:numPr" []+ [ mknode "w:ilvl" [("w:val",tshow listLevel)] ()+ , mknode "w:numId" [("w:val",tshow numid)] () ]] return $ case squashProps pPrTagOrder (EnvProps Nothing listPr <> props) of [] -> [] ps -> [mknode "w:pPr" [] ps]
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE OverloadedStrings #-}
@@ -960,8 +960,6 @@ classes' = case slideVariant of NoSlides -> classes _ -> filter (\k -> k /= "incremental" && k /= "nonincremental") classes- let paraToPlain (Para ils) = Plain ils- paraToPlain x = x let bs' = if "csl-entry" `elem` classes' then walk paraToPlain bs else bs
@@ -16,7 +16,7 @@ module Text.Pandoc.Writers.Haddock (writeHaddock) where import Control.Monad (zipWithM) import Control.Monad.State.Strict- ( StateT, MonadState(get), modify, evalStateT )+ ( StateT, MonadState(get), gets, modify, evalStateT ) import Data.Char (isAlphaNum) import Data.Default import Data.Text (Text)@@ -28,7 +28,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Shared type Notes = [[Block]]@@ -46,32 +45,35 @@ pandocToHaddock :: PandocMonad m => WriterOptions -> Pandoc -> StateT WriterState m Text pandocToHaddock opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing body <- blockListToHaddock opts blocks- st <- get- notes' <- notesToHaddock opts (reverse $ stNotes st)+ notes' <- notesToHaddock opts let main = body <> (if isEmpty notes' then empty else blankline <> notes') metadata <- metaToContext opts (blockListToHaddock opts) (fmap chomp . inlineListToHaddock opts) meta let context = defField "body" main metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main --- | Return haddock representation of notes.+-- | Return haddock representation of the collected notes. Rendering a+-- note may add further notes to the state (notes nested inside+-- notes); keep going until all of them have been rendered. notesToHaddock :: PandocMonad m- => WriterOptions -> [[Block]] -> StateT WriterState m (Doc Text)-notesToHaddock opts notes =- if null notes- then return empty- else do- contents <- blockToHaddock opts $ OrderedList (1,DefaultStyle,DefaultDelim) notes- return $ text "#notes#" <> blankline <> contents+ => WriterOptions -> StateT WriterState m (Doc Text)+notesToHaddock opts = do+ contents <- go 0+ return $ if null contents+ then empty+ else text "#notes#" <> blankline <> vcat contents+ where+ go done = do+ notes <- gets (drop done . reverse . stNotes)+ if null notes+ then return []+ else do+ contents <- blockToHaddock opts $+ OrderedList (done + 1, DefaultStyle, DefaultDelim) notes+ (contents :) <$> go (done + length notes) -- | Escape special characters for Haddock. escapeString :: Text -> Text@@ -170,7 +172,7 @@ -> StateT WriterState m (Doc Text) orderedListItemToHaddock opts marker items = do contents <- blockListToHaddock opts items- let sps = case T.length marker - writerTabStop opts of+ let sps = case writerTabStop opts - T.length marker of n | n > 0 -> text $ replicate n ' ' _ -> text " " let start = literal marker <> sps
@@ -138,9 +138,7 @@ writeICML :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeICML opts doc = do let Pandoc meta blocks = ensureValidXmlIdentifiers doc- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts renderBlockMeta f s = fst <$> runStateT (f opts [] s) defaultWriterState renderInlineMeta f s = fst <$> runStateT (f opts [] "" s) defaultWriterState metadata <- metaToContext opts
@@ -170,9 +170,7 @@ (Header lev (ident,hcls,hkvs) hils : rs) : bs) splitBackBlocks b (fs, bs) = (b:fs, bs) let (bodyblocks, backblocks) = foldr splitBackBlocks ([],[]) blocks- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts metadata <- metaToContext opts (blocksToJATS opts . makeSections False (Just startLvl)) (fmap chomp . inlinesToJATS opts)@@ -240,11 +238,6 @@ then inTags True "p" [("specific-use","wrapper")] inner else inner --- | Auxiliary function to convert Plain block to Para.-plainToPara :: Block -> Block-plainToPara (Plain x) = Para x-plainToPara x = x- -- | Convert a list of pairs of terms and definitions into a list of -- JATS varlistentrys. deflistItemsToJATS :: PandocMonad m@@ -302,7 +295,7 @@ codeAttr :: WriterOptions -> Attr -> (Text, [(Text, Text)]) codeAttr opts (ident,classes,kvs) = (lang, attr) where- attr = [("id", escapeNCName ident) | not (T.null ident)] +++ attr = idAttr opts ident ++ [("language",lang) | not (T.null lang)] ++ [(k,v) | (k,v) <- kvs, k `elem` ["code-type", "code-version", "executable",@@ -310,6 +303,12 @@ "platforms", "position", "specific-use"]] lang = languageFor opts classes +-- | The id attribute for an element, with the identifier prefix added.+idAttr :: WriterOptions -> Text -> [(Text, Text)]+idAttr opts ident =+ [("id", writerIdentifierPrefix opts <> escapeNCName ident)+ | not (T.null ident)]+ -- <break/> is only allowed as a direct child of <td> or <title> or -- <article-title> fixLineBreak :: Inline -> Inline@@ -319,10 +318,8 @@ -- | Convert a Pandoc block element to JATS. blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m (Doc Text) blockToJATS opts (Div (id',"section":_,kvs) (Header _lvl (_,_,hkvs) ils : xs)) = do- let idAttr = [ ("id", writerIdentifierPrefix opts <> escapeNCName id')- | not (T.null id')] let otherAttrs = ["sec-type", "specific-use"]- let attribs = idAttr ++ [(k,v) | (k,v) <- kvs, k `elem` otherAttrs]+ let attribs = idAttr opts id' ++ [(k,v) | (k,v) <- kvs, k `elem` otherAttrs] title' <- inlinesToJATS opts (map fixLineBreak ils) let label = if writerNumberSections opts then@@ -336,7 +333,7 @@ inTagsSimple "title" title' $$ contents -- Bibliography reference: blockToJATS opts (Div (ident,_,_) [Para lst]) | "ref-" `T.isPrefixOf` ident =- inTags True "ref" [("id", escapeNCName ident)] .+ inTags True "ref" (idAttr opts ident) . inTagsSimple "mixed-citation" <$> inlinesToJATS opts lst blockToJATS opts (Div ("refs",_,_) xs) = do@@ -353,7 +350,7 @@ return $ inTagsIndented "ref-list" contents blockToJATS opts (Div (ident,[cls],kvs) bs) | cls `elem` ["fig", "caption", "table-wrap"] = do contents <- blocksToJATS opts bs- let attr = [("id", escapeNCName ident) | not (T.null ident)] +++ let attr = idAttr opts ident ++ [("xml:lang",l) | ("lang",l) <- kvs] ++ [(k,v) | (k,v) <- kvs, k `elem` ["specific-use", "content-type", "orientation", "position"]]@@ -361,7 +358,7 @@ blockToJATS opts (Div (ident,_,kvs) bs) = do contents <- blocksToJATS opts bs -- Attributes that are allowed on both @<p>@ and @<boxed-text>@ elements- let generic_attr = [("id", escapeNCName ident) | not (T.null ident)] +++ let generic_attr = idAttr opts ident ++ [("xml:lang",l) | ("lang",l) <- kvs] ++ [(k,v) | (k,v) <- kvs, k `elem` ["specific-use", "content-type"]]@@ -380,10 +377,10 @@ title' <- inlinesToJATS opts (map fixLineBreak title) return $ inTagsSimple "title" title' -- Special cases for bare images, which are rendered as graphics-blockToJATS _opts (Plain [Image attr alt tgt]) =- return $ graphic attr alt tgt-blockToJATS _opts (Para [Image attr alt tgt]) =- return $ graphic attr alt tgt+blockToJATS opts (Plain [Image attr alt tgt]) =+ return $ graphic opts attr alt tgt+blockToJATS opts (Para [Image attr alt tgt]) =+ return $ graphic opts attr alt tgt -- No Plain, everything needs to be in a block-level tag blockToJATS opts (Plain lst) = blockToJATS opts (Para lst) blockToJATS opts (Para lst) =@@ -476,7 +473,7 @@ else ("fig" , ["fig-type", "orientation", "position", "specific-use"] )- let xmlattr = [("id", escapeNCName ident) | not (T.null ident)] +++ let xmlattr = idAttr opts ident ++ [(k,v) | (k,v) <- kvs , k `elem` allowedAttributes] return $ inTags True tag xmlattr $ capt $$ children@@ -544,19 +541,20 @@ let notenum = case notes of (n, _):_ -> n + 1 [] -> 1- thenote <- inTags True "fn" [("id", "fn" <> tshow notenum)]+ thenote <- inTags True "fn" (idAttr opts ("fn" <> tshow notenum)) . (inTagsSimple "label" (literal $ tshow notenum) <>) <$> wrappedBlocksToJATS (not . isPara) opts (walk demoteHeaderAndRefs contents) modify $ \st -> st{ jatsNotes = (notenum, thenote) : notes } return $ inTags False "xref" [("ref-type", "fn"),- ("rid", "fn" <> tshow notenum)]+ ("rid", writerIdentifierPrefix opts <>+ "fn" <> tshow notenum)] $ text (show notenum) inlineToJATS opts (Cite _ lst) = inlinesToJATS opts lst inlineToJATS opts (Span (ident,classes,kvs) ils) = do contents <- inlinesToJATS opts ils- let commonAttr = [("id", escapeNCName ident) | not (T.null ident)] +++ let commonAttr = idAttr opts ident ++ [("xml:lang",l) | ("lang",l) <- kvs] ++ [(k,v) | (k,v) <- kvs, k `elem` ["alt", "specific-use"]] -- A named-content element is a good fit for spans, but requires a@@ -615,9 +613,9 @@ return $ inTagsSimple "email" $ literal (escapeStringForXML email) inlineToJATS opts (Link (ident,_,kvs) txt (T.uncons -> Just ('#', src), _)) = do let attr = mconcat- [ [("id", escapeNCName ident) | not (T.null ident)]+ [ idAttr opts ident , [("alt", stringifyInlines txt) | not (null txt)]- , [("rid", escapeNCName src)]+ , [("rid", writerIdentifierPrefix opts <> escapeNCName src)] , [(k,v) | (k,v) <- kvs, k `elem` ["ref-type", "specific-use"]] , [("ref-type", "bibr") | "ref-" `T.isPrefixOf` src] ]@@ -627,7 +625,7 @@ contents <- inlinesToJATS opts txt return $ inTags False "xref" attr contents inlineToJATS opts (Link (ident,_,kvs) txt (src, tit)) = do- let attr = [("id", escapeNCName ident) | not (T.null ident)] +++ let attr = idAttr opts ident ++ [("ext-link-type", "uri"), ("xlink:href", src)] ++ [("xlink:title", tit) | not (T.null tit)] ++@@ -637,23 +635,23 @@ "xlink:type"]] contents <- inlinesToJATS opts txt return $ inTags False "ext-link" attr contents-inlineToJATS _ (Image attr alt tgt) = do- let elattr = graphicAttr attr alt tgt+inlineToJATS opts (Image attr alt tgt) = do+ let elattr = graphicAttr opts attr alt tgt return $ case altToJATS alt of Nothing -> selfClosingTag "inline-graphic" elattr Just altTag -> inTags True "inline-graphic" elattr altTag -graphic :: Attr -> [Inline] -> Target -> (Doc Text)-graphic attr alt tgt =- let elattr = graphicAttr attr alt tgt+graphic :: WriterOptions -> Attr -> [Inline] -> Target -> (Doc Text)+graphic opts attr alt tgt =+ let elattr = graphicAttr opts attr alt tgt in case altToJATS alt of Nothing -> selfClosingTag "graphic" elattr Just altTag -> inTags True "graphic" elattr altTag -graphicAttr :: Attr -> [Inline] -> Target -> [(Text, Text)]-graphicAttr (ident, _, kvs) _alt (src, tit) =+graphicAttr :: WriterOptions -> Attr -> [Inline] -> Target -> [(Text, Text)]+graphicAttr opts (ident, _, kvs) _alt (src, tit) = let (maintype, subtype) = imageMimeType src kvs- in [("id", escapeNCName ident) | not (T.null ident)] +++ in idAttr opts ident ++ [ ("mimetype", maintype) , ("mime-subtype", subtype) , ("xlink:href", src)
@@ -26,7 +26,7 @@ import Text.DocLayout (Doc, empty, isEmpty, literal, vcat) import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Builder (Inlines)-import Text.Pandoc.Options (WriterOptions)+import Text.Pandoc.Options (WriterOptions (..)) import Text.Pandoc.Shared (tshow) import Text.Pandoc.Writers.JATS.Types import Text.Pandoc.XML (escapeNCName, escapeStringForXML, inTags)@@ -43,11 +43,11 @@ => WriterOptions -> Reference Inlines -> JATS m (Doc Text)-referenceToJATS _opts ref = do+referenceToJATS opts ref = do let refType = referenceType ref let pubType = [("publication-type", refType) | not (T.null refType)] let ident = escapeNCName $ "ref-" <> unItemId (referenceId ref)- let wrap = inTags True "ref" [("id", ident)]+ let wrap = inTags True "ref" [("id", writerIdentifierPrefix opts <> ident)] . inTags True "element-citation" pubType return . wrap . vcat $ [ authors
@@ -21,7 +21,7 @@ import Text.DocLayout (Doc, empty, vcat, ($$)) import Text.Pandoc.Class.PandocMonad (PandocMonad) import Text.Pandoc.Definition-import Text.Pandoc.Options (WriterOptions)+import Text.Pandoc.Options (WriterOptions (..)) import Text.Pandoc.Shared (tshow) import Text.Pandoc.Writers.JATS.Types import Text.Pandoc.XML (escapeNCName, inTags, inTagsIndented, selfClosingTag)@@ -65,7 +65,7 @@ , "frame", "rules", "specific-use", "style", "summary" , "width" ]- let attribs = toAttribs attr validAttribs+ let attribs = toAttribs opts attr validAttribs return $ inTags True "table" attribs $ vcat [ colSpecListToJATS colspecs , head'@@ -82,7 +82,7 @@ -> Ann.TableBody -> JATS m (Doc Text) tableBodyToJats opts (Ann.TableBody attr _rowHeadCols inthead rows) = do- let attribs = toAttribs attr validTablePartAttribs+ let attribs = toAttribs opts attr validTablePartAttribs intermediateHead <- if null inthead then return mempty else headerRowsToJats opts Thead inthead@@ -117,7 +117,7 @@ Thead -> "thead" Tfoot -> "tfoot" Tbody -> "tbody" -- this would be unexpected- let attribs = toAttribs attr validTablePartAttribs+ let attribs = toAttribs opts attr validTablePartAttribs inTags True tag' attribs <$> headerRowsToJats opts tblpart rows where isEmptyRow (Ann.HeaderRow _attr _rownum cells) = all isEmptyCell cells@@ -183,7 +183,7 @@ let validAttribs = [ "align", "char", "charoff", "content-type" , "style", "valign" ]- let attr' = toAttribs attr validAttribs+ let attr' = toAttribs opts attr validAttribs let celltype = case tblpart of Thead -> HeaderCell _ -> BodyCell@@ -220,9 +220,11 @@ let align = fst colspec in tableCellToJats opts celltype align cell -toAttribs :: Attr -> [Text] -> [(Text, Text)]-toAttribs (ident, _classes, kvs) knownAttribs =- (if T.null ident then id else (("id", escapeNCName ident) :)) $+toAttribs :: WriterOptions -> Attr -> [Text] -> [(Text, Text)]+toAttribs opts (ident, _classes, kvs) knownAttribs =+ (if T.null ident+ then id+ else (("id", writerIdentifierPrefix opts <> escapeNCName ident) :)) $ filter ((`elem` knownAttribs) . fst) kvs tableCellToJats :: PandocMonad m@@ -255,7 +257,7 @@ let attribs = maybeCons (alignmentAttrib align') . maybeCons (rowspanAttrib rowspan) . maybeCons (colspanAttrib colspan)- $ toAttribs attr validAttribs+ $ toAttribs opts attr validAttribs inTags False tag' attribs <$> cellContents item -- | Whether the JATS produced from this block should be wrapped in a
@@ -40,7 +40,7 @@ import Data.Text (Text) import qualified Data.Text as T import Network.URI (unEscapeString)-import Text.DocTemplates (Context(..), FromContext(lookupContext), Val(..), renderTemplate)+import Text.DocTemplates (Context(..), FromContext(lookupContext), Val(..)) import qualified Data.Map as M import Text.Collate.Lang (renderLang) import Text.Pandoc.Class.PandocMonad (PandocMonad, getPOSIXTime, lookupEnv,@@ -128,9 +128,6 @@ let blocks' = if method == Biblatex || method == Natbib then filter (not . isRefsDiv) blocks else blocks- let colwidth = if writerWrapText options == WrapAuto- then Just $ writerColumns options- else Nothing docLangs <- catMaybes <$> mapM (toLang . Just) (nubOrd (query (extract "lang") blocks)) mblang <- toLang $ case getLang options meta of@@ -326,10 +323,7 @@ $ defField "latex-dir-rtl" ((render Nothing <$> getField "dir" context) == Just ("rtl" :: Text)) context- return $ render colwidth $- case writerTemplate options of- Nothing -> main- Just tpl -> renderTemplate tpl context'+ return $ renderWithTemplate options context' main -- Commas in title-meta need to be put in braces; see #10501 escapeCommas :: Text -> Text@@ -771,12 +765,12 @@ modify $ \s -> s{ stInItem = True } term' <- withExternalNotes $ inlineListToLaTeX term modify $ \s -> s{ stInItem = False }- -- put braces around term if it contains an internal link,- -- since otherwise we get bad bracket interactions: \item[\hyperref[..]- let isInternalLink (Link _ _ (src,_))+ -- put braces around term if it contains an internal link or an =:+ let needsBraces (Link _ _ (src,_)) | Just ('#', _) <- T.uncons src = True- isInternalLink _ = False- let term'' = if any isInternalLink term+ needsBraces (Str t) = T.any (=='=') t+ needsBraces _ = False+ let term'' = if any needsBraces term then braces term' else term' def' <- case concat defs of
@@ -31,7 +31,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared import Text.Pandoc.Writers.Roff@@ -48,9 +47,6 @@ -- | Return roff man representation of document. pandocToMan :: PandocMonad m => WriterOptions -> Pandoc -> StateT WriterState m Text pandocToMan opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing titleText <- inlineListToMan opts $ docTitle meta let title' = render Nothing titleText let setFieldsFromTitle =@@ -80,10 +76,7 @@ $ setFieldsFromTitle $ defField "has-tables" hasTables metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main escString :: WriterOptions -> Text -> Text escString opts = escapeString True (if writerPreferAscii opts
@@ -43,7 +43,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.Writers.Shared-import Text.Pandoc.Templates (renderTemplate) import Text.DocTemplates (Val(..), Context(..), FromContext(..)) import Text.Pandoc.Walk import Text.Pandoc.Writers.HTML (writeHtml5String)@@ -222,9 +221,6 @@ -- | Return markdown representation of document. pandocToMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> MD m Text pandocToMarkdown opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing variant <- asks envVariant metadata <- metaToContext' (blockListToMarkdown opts)@@ -272,10 +268,7 @@ then id else defField "titleblock" titleblock) $ addVariablesToContext opts metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main -- | Return markdown representation of reference key table. refsToMarkdown :: PandocMonad m => WriterOptions -> Refs -> MD m (Doc Text)@@ -295,13 +288,22 @@ (literal (linkDestination src) <> tit') <+> linkAttributes opts attr --- | Return markdown representation of notes.-notesToMarkdown :: PandocMonad m => WriterOptions -> [[Block]] -> MD m (Doc Text)-notesToMarkdown opts notes = do- n <- gets stNoteNum- notes' <- zipWithM (noteToMarkdown opts) [n..] notes- modify $ \st -> st { stNoteNum = stNoteNum st + length notes }- return $ vsep notes'+-- | Return markdown representation of the collected notes, clearing+-- them from the state. Rendering a note may add further notes to the+-- state (notes nested inside notes); keep going until all of them+-- have been rendered.+notesToMarkdown :: PandocMonad m => WriterOptions -> MD m (Doc Text)+notesToMarkdown opts = vsep <$> go+ where+ go = do+ notes <- gets (reverse . stNotes)+ if null notes+ then return []+ else do+ n <- gets stNoteNum+ modify $ \st -> st { stNotes = [], stNoteNum = n + length notes }+ docs <- zipWithM (noteToMarkdown opts) [n..] notes+ (docs ++) <$> go -- | Return markdown representation of a note. noteToMarkdown :: PandocMonad m => WriterOptions -> Int -> [Block] -> MD m (Doc Text)@@ -347,8 +349,7 @@ notesAndRefs :: PandocMonad m => WriterOptions -> MD m (Doc Text) notesAndRefs opts = do- notes' <- gets stNotes >>= notesToMarkdown opts . reverse- modify $ \s -> s { stNotes = [] }+ notes' <- notesToMarkdown opts refs' <- gets stRefs >>= refsToMarkdown opts . reverse modify $ \s -> s { stPrevRefs = stPrevRefs s ++ stRefs s , stRefs = []}@@ -621,7 +622,10 @@ let (_,cls,_) = attribs in case getLangFromClasses opts cls of Just l -> " " <> literal l- Nothing -> empty+ Nothing -> -- see #11987+ case cls of+ l:_ -> literal l+ [] -> empty blockToMarkdown' opts (BlockQuote blocks) = do variant <- asks envVariant -- if we're writing literate haskell, put a space before the bird tracks@@ -689,9 +693,7 @@ isEnabled Ext_multiline_tables opts -> do tbl <- mkTable (pandocTable opts True) return $ nest 2 (tbl $$ caption''') $$ blankline- | isEnabled Ext_grid_tables opts &&- (hasColRowSpans || writerColumns opts >= 8 * numcols- || hasFooter) -> do+ | isEnabled Ext_grid_tables opts -> do tbl <- gridTable opts blockListToMarkdown specs thead tbody tfoot return $ (tbl $$ caption''') $$ blankline
@@ -44,7 +44,6 @@ import Text.DocLayout hiding (Color) import Text.DocTemplates (lookupContext) import Text.Pandoc.Shared-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared import Text.Pandoc.Writers.Roff@@ -62,9 +61,6 @@ -- | Return roff ms representation of document. pandocToMs :: PandocMonad m => WriterOptions -> Pandoc -> MS m Text pandocToMs opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing title <- chomp <$> inlineListToMs' opts (lookupMetaInlines "title" meta) metadata <- metaToContext opts (blockListToMs opts)@@ -91,10 +87,7 @@ $ defField "author-meta" (T.intercalate "; " authorsMeta) $ defField "highlighting-macros" highlightingMacros $ resetField "title" title metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main escapeStr :: WriterOptions -> Text -> Text escapeStr opts =
@@ -47,7 +47,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared @@ -108,9 +107,6 @@ -> Muse m Text pandocToMuse (Pandoc meta blocks) = do opts <- asks envOptions- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing metadata <- metaToContext opts blockListToMuse (fmap chomp . inlineListToMuse)@@ -119,10 +115,7 @@ notes <- currentNotesToMuse let main = body $+$ notes let context = defField "body" main metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main -- | Helper function for flatBlockListToMuse -- | Render all blocks and insert blank lines between the first two
@@ -305,10 +305,21 @@ lang <- toLang (getLang opts meta) refArchive <- case writerReferenceDoc opts of- Just f -> lift $ toArchive . B.fromStrict . fst <$>+ Just f -> do+ arch <- lift $ toArchiveOrFail . B.fromStrict . fst <$> (P.fetchItem (T.pack f))- Nothing -> lift $ toArchive . B.fromStrict <$>+ case arch of+ Left err -> throwError $ PandocParseError $+ "Could not parse reference-doc " <>+ tshow f <> ": " <> T.pack err+ Right x -> pure x+ Nothing -> do+ arch <- lift $ toArchiveOrFail . B.fromStrict <$> readDataFile "reference.odt"+ case arch of+ Left err -> throwError $ PandocParseError $+ "Could not parse reference.odt: " <> T.pack err+ Right x -> pure x -- handle formulas and pictures -- picEntriesRef <- P.newIORef ([] :: [Entry]) let refTextWidth = referenceTextWidthPt opts refArchive
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-} {- | Module : Text.Pandoc.Writers.OPML Copyright : Copyright (C) 2013-2024 John MacFarlane@@ -30,9 +29,7 @@ -- | Convert Pandoc document to string in OPML format. writeOPML :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeOPML opts (Pandoc meta blocks) = do- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing+ let colwidth = wrapColumns opts meta' = B.setMeta "date" (B.str $ convertDate $ docDate meta) meta metadata <- metaToContext opts (fmap literal . writeMarkdown' opts . Pandoc nullMeta)
@@ -32,8 +32,7 @@ import Text.Pandoc.Logging import Text.Pandoc.Options import Text.DocLayout hiding (link)-import Text.Pandoc.Shared (linesToPara, tshow, blocksToInlines)-import Text.Pandoc.Templates (renderTemplate)+import Text.Pandoc.Shared (linesToPara, plainToPara, tshow, blocksToInlines) import qualified Text.Pandoc.Translations as Term (Term(Figure, Table)) import Text.Pandoc.Walk import Text.Pandoc.Writers.Math@@ -44,11 +43,6 @@ import Text.Pandoc.Highlighting (highlight) import Skylighting (FormatOptions(..), SourceLine, Token) --- | Auxiliary function to convert Plain block to Para.-plainToPara :: Block -> Block-plainToPara (Plain x) = Para x-plainToPara x = x- -- Names of predefined styles in the reference.odt; see data/odt/styles.xml. defaultBulletListStyleName, defaultNumberedListStyleName :: Text defaultBulletListStyleName = "List_20_1"@@ -302,9 +296,6 @@ writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeOpenDocument opts (Pandoc meta blocks) = do setupTranslations meta- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing -- The abstract is the one template field that takes block-level -- content, so it is rendered separately; everything else in the -- metadata goes in a context where only inlines are allowed.@@ -358,10 +349,7 @@ then id else defField "abstract" abstract) $ metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> body- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context body withParagraphStyle :: PandocMonad m => WriterOptions -> Text -> [Block] -> OD m (Doc Text)
@@ -33,7 +33,6 @@ import Text.Pandoc.Options import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Citeproc.Locator (parseLocator, LocatorMap(..), LocatorInfo(..)) import Text.Pandoc.Walk (query) import Text.Pandoc.Writers.Shared@@ -60,9 +59,6 @@ pandocToOrg :: PandocMonad m => Pandoc -> Org m Text pandocToOrg (Pandoc meta blocks) = do opts <- gets stOptions- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing metadata <- metaToContext opts blockListToOrg (fmap chomp . inlineListToOrg)@@ -85,10 +81,7 @@ . defField "option-special-strings" (isEnabled Ext_special_strings opts) $ metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main -- | Return Org representation of the collected notes. Rendering a -- note may add further notes to the state (notes nested inside
@@ -593,13 +593,29 @@ presentationToArchive :: PandocMonad m => WriterOptions -> Meta -> Presentation -> m Archive presentationToArchive opts meta pres = do+ -- ensure that the default reference doc isn't built from+ -- pptx/ files in the user data directory:+ oldUserDataDir <- P.getUserDataDir+ P.setUserDataDir Nothing distArchive <- toArchive . BL.fromStrict <$> readDefaultDataFile "reference.pptx"+ P.setUserDataDir oldUserDataDir refArchive <- case writerReferenceDoc opts of- Just f -> toArchive . BL.fromStrict . fst- <$> P.fetchItem (T.pack f)- Nothing -> toArchive . BL.fromStrict <$>- readDataFile "reference.pptx"+ Just f -> do+ arch <- toArchiveOrFail . BL.fromStrict . fst+ <$> P.fetchItem (T.pack f)+ case arch of+ Left err -> throwError $ PandocParseError $+ "Could not parse reference-doc " <>+ tshow f <> ": " <> T.pack err+ Right x -> pure x+ Nothing -> do+ arch <- toArchiveOrFail . BL.fromStrict <$>+ readDataFile "reference.pptx"+ case arch of+ Left err -> throwError $ PandocParseError $+ "Could not parse reference.pptx: " <> T.pack err+ Right x -> pure x let (referenceLayouts, defaultReferenceLayouts) = (getLayoutsFromArchive refArchive, getLayoutsFromArchive distArchive)@@ -2295,6 +2311,8 @@ , sldNumShape ] ]+ -- required by Keynote, see #11935+ , mknode "p:clrMapOvr" [] $ mknode "a:masterClrMapping" [] () ] -----------------------------------------------------------------------@@ -2768,6 +2786,7 @@ : ( [mknode "dc:subject" [] $ fromMaybe "" $ dcSubject docProps | isJust (dcSubject docProps)]) <> ( [mknode "dc:description" [] $ fromMaybe "" $ dcDescription docProps | isJust (dcDescription docProps)]) <> ( [mknode "cp:category" [] $ fromMaybe "" $ cpCategory docProps | isJust (cpCategory docProps)])+ <> ( [mknode "dc:language" [] $ fromMaybe "" $ dcLanguage docProps | isJust (dcLanguage docProps)]) <> (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x ]) (T.pack $ formatTime defaultTimeLocale "%FT%XZ" utctime)
@@ -188,6 +188,7 @@ , dcKeywords :: Maybe [T.Text] , dcDescription :: Maybe T.Text , cpCategory :: Maybe T.Text+ , dcLanguage :: Maybe T.Text , dcDate :: Maybe T.Text , customProperties :: Maybe [(T.Text, T.Text)] } deriving (Show, Eq)@@ -1189,6 +1190,7 @@ , dcKeywords = keywords , dcDescription = description , cpCategory = Shared.stringify <$> lookupMeta "category" meta+ , dcLanguage = Shared.stringify <$> lookupMeta "lang" meta , dcDate = let t = Shared.stringifyInlines (docDate meta) in if T.null t
@@ -35,7 +35,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Shared import Text.Pandoc.Walk import Safe (lastMay, headMay)@@ -68,9 +67,6 @@ pandocToRST :: PandocMonad m => Pandoc -> RST m Text pandocToRST (Pandoc meta blocks) = do opts <- gets stOptions- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing let subtit = lookupMetaInlines "subtitle" meta title <- titleToRST (docTitle meta) subtit metadata <- metaToContext opts@@ -80,7 +76,7 @@ body <- blockListToRST' True $ case writerTemplate opts of Just _ -> normalizeHeadings 1 blocks Nothing -> blocks- notes <- gets (reverse . stNotes) >>= notesToRST+ notes <- notesToRST -- note that the notes may contain refs, so we do them first refs <- gets (reverse . stLinks) >>= refsToRST pics <- gets (reverse . stImages) >>= pictRefsToRST@@ -95,10 +91,7 @@ $ defField "titleblock" (render Nothing title :: Text) $ defField "math" hasMath $ defField "rawtex" rawTeX metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main where normalizeHeadings lev (Header l a i:bs) = Header lev a i:normalizeHeadings (lev+1) cont ++ normalizeHeadings lev bs'@@ -126,10 +119,19 @@ else label' return $ nowrap $ ".. _" <> label'' <> ": " <> literal src --- | Return RST representation of notes.-notesToRST :: PandocMonad m => [[Block]] -> RST m (Doc Text)-notesToRST notes =- vsep <$> zipWithM noteToRST [1..] notes+-- | Return RST representation of the collected notes. Rendering a+-- note may add further notes to the state (notes nested inside+-- notes); keep going until all of them have been rendered.+notesToRST :: PandocMonad m => RST m (Doc Text)+notesToRST = vsep <$> go 0+ where+ go done = do+ notes <- gets (drop done . reverse . stNotes)+ if null notes+ then return []+ else do+ docs <- zipWithM noteToRST [done + 1 ..] notes+ (docs ++) <$> go (done + length notes) -- | Return RST representation of a note. noteToRST :: PandocMonad m => Int -> [Block] -> RST m (Doc Text)
@@ -55,6 +55,8 @@ , insertCurrentSpansAtColumn , takePreviousSpansAtColumn , decrementTrailingRowSpans+ , wrapColumns+ , renderWithTemplate ) where import Safe (lastMay, maximumMay)@@ -83,7 +85,7 @@ import qualified Text.Pandoc.UTF8 as UTF8 import Text.Pandoc.XML (escapeStringForXML, rdfaAttributes, html5Attributes) import Text.DocTemplates (Context(..), Val(..), TemplateTarget,- ToContext(..), FromContext(..))+ ToContext(..), FromContext(..), renderTemplate) import Text.Pandoc.Chunks (tocToList, toTOCTree) import Text.Collate.Lang (Lang (..)) import Text.Pandoc.Class (PandocMonad, toLang)@@ -110,6 +112,24 @@ Nothing -> return mempty Just _ -> addVariablesToContext opts <$> metaToContext' blockWriter inlineWriter meta++-- | The line length to use in rendering: 'writerColumns' if+-- 'writerWrapText' is 'WrapAuto', otherwise 'Nothing' (no wrapping).+wrapColumns :: WriterOptions -> Maybe Int+wrapColumns opts =+ if writerWrapText opts == WrapAuto+ then Just $ writerColumns opts+ else Nothing++-- | Render a document body, inserting it into 'writerTemplate'+-- (with the given context) if there is a template, and wrapping+-- lines according to 'wrapColumns'.+renderWithTemplate :: WriterOptions -> Context Text -> Doc Text -> Text+renderWithTemplate opts context main =+ render (wrapColumns opts) $+ case writerTemplate opts of+ Nothing -> main+ Just tpl -> renderTemplate tpl context -- | Like 'metaToContext, but does not include variables and is -- not sensitive to 'writerTemplate'.
@@ -23,7 +23,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Shared import Text.Pandoc.XML @@ -31,9 +30,6 @@ writeTEI :: PandocMonad m => WriterOptions -> Pandoc -> m Text writeTEI opts doc = do let Pandoc meta blocks = ensureValidXmlIdentifiers doc- let colwidth = if writerWrapText opts == WrapAuto- then Just $ writerColumns opts- else Nothing let startLvl = case writerTopLevelDivision opts of TopLevelPart -> -1 TopLevelChapter -> 0@@ -49,20 +45,12 @@ $ defField "mathml" (case writerMathMethod opts of MathML -> True _ -> False) metadata- return $ render colwidth $- case writerTemplate opts of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate opts context main -- | Convert a list of Pandoc blocks to TEI. blocksToTEI :: PandocMonad m => WriterOptions -> [Block] -> m (Doc Text) blocksToTEI opts bs = vcat <$> mapM (blockToTEI opts) bs --- | Auxiliary function to convert Plain block to Para.-plainToPara :: Block -> Block-plainToPara (Plain x) = Para x-plainToPara x = x- -- | Convert a list of pairs of terms and definitions into a TEI -- list with labels and items. deflistItemsToTEI :: PandocMonad m@@ -275,8 +263,12 @@ linktext <- inlinesToTEI opts txt return $ linktext <+> char '(' <> emailLink <> char ')' | otherwise =- inTags False "ref" (("target", src) : idFromAttr opts attr)+ inTags False "ref" (("target", src') : idFromAttr opts attr) <$> inlinesToTEI opts txt+ where+ src' = case T.stripPrefix "#" src of+ Just ident -> "#" <> writerIdentifierPrefix opts <> ident+ Nothing -> src inlineToTEI opts (Image attr description (src, tit)) = do let titleDoc = if T.null tit then empty
@@ -36,7 +36,6 @@ import Text.DocLayout import Text.Pandoc.Shared import Text.Pandoc.URI-import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Writers.Shared import Text.Printf (printf) @@ -105,9 +104,6 @@ blocks <- walkM addNodeText blocks' let titlePage = not $ all null $ docTitle meta : docDate meta : docAuthors meta- let colwidth = if writerWrapText options == WrapAuto- then Just $ writerColumns options- else Nothing metadata <- metaToContext options blockListToTexinfo (fmap chomp .inlineListToTexinfo)@@ -118,10 +114,7 @@ $ defField "toc" (writerTableOfContents options) $ defField "titlepage" titlePage $ defField "strikeout" (stStrikeout st) metadata- return $ render colwidth $- case writerTemplate options of- Nothing -> body- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate options context body -- | Escape things as needed for Texinfo. stringToTexinfo :: PandocMonad m => Text -> TI m Text
@@ -32,7 +32,8 @@ import Control.Monad.State ( StateT, evalStateT, gets, modify ) import Text.Pandoc.Writers.Shared ( lookupMetaInlines, lookupMetaString, metaToContext, defField, resetField,- setupTranslations )+ setupTranslations, getLang,+ renderWithTemplate ) import Text.Pandoc.Shared (isTightList, orderedListMarkers, tshow, stringifyInlines) import Text.Pandoc.Highlighting (highlight, formatTypstBlock, formatTypstInline,@@ -43,7 +44,6 @@ import Text.Pandoc.Writers.Math (convertMath) import qualified Text.TeXMath as TM import Text.DocLayout-import Text.DocTemplates (renderTemplate) import Text.Pandoc.Extensions (Extension(..)) import Text.Pandoc.Logging (LogMessage(..)) import qualified Text.Pandoc.UTF8 as UTF8@@ -85,9 +85,6 @@ pandocToTypst :: PandocMonad m => WriterOptions -> Pandoc -> TW m Text pandocToTypst options (Pandoc meta blocks) = do- let colwidth = if writerWrapText options == WrapAuto- then Just $ writerColumns options- else Nothing setupTranslations meta metadata <- metaToContext options blocksToTypst@@ -113,9 +110,9 @@ . defField "nocite-ids" (filter (/= "*") nociteIds) . defField "full-bibliography" ("*" `elem` nociteIds) else id)- $ (case lookupMetaString "lang" meta of- "" -> id- lang ->+ $ (case getLang options meta of+ Nothing -> id+ Just lang -> case parseLang lang of Left _ -> id Right l ->@@ -144,10 +141,7 @@ then defField "section-numbering" ("1.1.1.1.1" :: Text) else id) metadata- return $ render colwidth $- case writerTemplate options of- Nothing -> main- Just tpl -> renderTemplate tpl context+ return $ renderWithTemplate options context main pickTypstAttrs :: [(Text, Text)] -> ([(Text, Text)],[(Text, Text)]) pickTypstAttrs = foldr go ([],[])@@ -220,7 +214,7 @@ RawBlock fmt str -> case fmt of Format "typst" -> return $ literal str- _ -> return mempty+ _ -> mempty <$ report (BlockNotRendered block) CodeBlock (ident,cls,kvs) code -> do let go :: Char -> (Int, Int) -> (Int, Int) go '`' (longest, current) =@@ -522,7 +516,7 @@ RawInline fmt str -> case fmt of Format "typst" -> return $ literal str- _ -> return mempty+ _ -> mempty <$ report (InlineNotRendered inline) Strikeout inlines -> textstyle "#strike" inlines Emph inlines -> textstyle "#emph" inlines Underline inlines -> textstyle "#underline" inlines@@ -659,6 +653,8 @@ go (lastc, t') c | needsEscape c = (c, t' <> escapeChar c) | c == '-', lastc == '-', smart = (c, t' <> T.pack ['\\',c])+ | c == '?', lastc == '-', smart = (c, t' <> T.pack ['\\',c])+ | c == '.', lastc == '.', smart = (c, t' <> T.pack ['\\',c]) | c == '/', lastc == '/' = (c, t' <> T.pack ['\\',c]) | otherwise = (c, T.snoc t' c) escapeChar c
@@ -136,6 +136,18 @@ "docx/empty_field.docx" "docx/empty_field.native" , testCompare+ "field without <w:instrText> does not corrupt later lists"+ "docx/field_no_instrText.docx"+ "docx/field_no_instrText.native"+ , testCompare+ "field with <w:instrText> in tracked change does not corrupt later lists"+ "docx/field_tracked_instrText.docx"+ "docx/field_tracked_instrText.native"+ , testCompare+ "field without <w:instrText> in a code block keeps its text"+ "docx/field_no_instrText_codeblock.docx"+ "docx/field_no_instrText_codeblock.native"+ , testCompare "pageref hyperlinks in <w:instrText> tag" "docx/pageref.docx" "docx/pageref.native"@@ -459,6 +471,14 @@ "spaces at the edges of changes (reject)" "docx/track_changes_edge_spaces.docx" "docx/track_changes_edge_spaces_reject.native"+ , testCompareWithOpts def{readerTrackChanges=AcceptChanges}+ "paragraph marks in notes stay in their notes (accept)"+ "docx/track_changes_paragraph_mark_in_note.docx"+ "docx/track_changes_paragraph_mark_in_note_accept.native"+ , testCompareWithOpts def{readerTrackChanges=RejectChanges}+ "paragraph marks in notes stay in their notes (reject)"+ "docx/track_changes_paragraph_mark_in_note.docx"+ "docx/track_changes_paragraph_mark_in_note_reject.native" , testCompareWithOpts def{readerTrackChanges=AcceptChanges} "comments (accept -- no comments)" "docx/comments.docx"
@@ -259,6 +259,7 @@ , "inlinedCode" , "listContinueNumbering" , "listContinueNumbering2"+ , "listContinueNumbering3" , "orderedListMixed" , "orderedListRoman" , "orderedListSimple"
@@ -217,6 +217,19 @@ , "bare URI parsing disabled inside emphasis (#4561)" =: "*http://location*" =?> para (emph (text "http://location"))+ , "bare URI and email address in angle brackets" =:+ "See <https://example.com> or <jane-doe@example.com>." =?>+ para ("See <" <> link "https://example.com" "" "https://example.com" <>+ "> or <" <>+ link "mailto:jane-doe@example.com" "" "jane-doe@example.com" <>+ ">.")+ , "inline markup after a colon, a slash or a quote" =:+ "key:*a* path/*b* \"*c*\"" =?>+ para ("key:" <> emph "a" <> " path/" <> emph "b" <> " \"" <>+ emph "c" <> "\"")+ , "quoted start-strings are not inline markup" =:+ "(*) and (*), [*] and [*], \"*\" or \"x*\"" =?>+ para (text "(*) and (*), [*] and [*], \"*\" or \"x*\"") , "include newlines" =: "**before\nafter**" =?> para (strong (text "before\nafter"))
@@ -0,0 +1,10 @@+```+% pandoc -f latex -t native 2>&1+\makeatletter+\def\small{\@setfontsize\small\@ixpt{10}}+\makeatother+\small test+^D+Loop encountered in expanding macro small+=> 91+```
binary file changed (absent → 11719 bytes)
@@ -0,0 +1,14 @@+A `w:fldSimple` keeps its result text; a REF field with `\h` becomes a+link to the bookmark it refers to. A caption whose label is not `Figure`+or `Table` keeps its label and number.++```+% pandoc command/11944.docx -t html+^D+<p>See figure <a href="#_Ref1">1</a>.</p>+<figure>+<img src="media/image1.png" style="width:1.09702in;height:1.09702in" />+<figcaption><p><span id="_Ref1" class="anchor"></span>Figur 1 Blue+square.</p></figcaption>+</figure>+```
@@ -0,0 +1,34 @@+A table with more columns than `columns / 8` is still written as a grid+table, rather than falling back to raw HTML.++```+% pandoc -f html -t markdown-simple_tables-multiline_tables-pipe_tables+<table>+<tr><th>H1</th><th>H2</th><th>H3</th><th>H4</th><th>H5</th><th>H6</th><th>H7</th><th>H8</th><th>H9</th><th>H10</th></tr>+<tr><td>c1</td><td>c2</td><td>c3</td><td>c4</td><td>c5</td><td>c6</td><td>c7</td><td>c8</td><td>c9</td><td>c10</td></tr>+</table>+^D++----+----+----+----+----+----+----+----+----+-----++| H1 | H2 | H3 | H4 | H5 | H6 | H7 | H8 | H9 | H10 |++====+====+====+====+====+====+====+====+====+=====++| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 |++----+----+----+----+----+----+----+----+----+-----++```++This includes a table with block content in a cell, which has no other+markdown representation.++```+% pandoc -f html -t markdown+<table>+<tr><th>H1</th><th>H2</th><th>H3</th><th>H4</th><th>H5</th><th>H6</th><th>H7</th><th>H8</th><th>H9</th><th>H10</th></tr>+<tr><td><ul><li>a</li><li>b</li></ul></td><td>c2</td><td>c3</td><td>c4</td><td>c5</td><td>c6</td><td>c7</td><td>c8</td><td>c9</td><td>c10</td></tr>+</table>+^D++------+------+------+------+------+------+------+------+------+------++| H1 | H2 | H3 | H4 | H5 | H6 | H7 | H8 | H9 | H10 |++======+======+======+======+======+======+======+======+======+======++| - a | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 |+| - b | | | | | | | | | |++------+------+------+------+------+------+------+------+------+------++```
@@ -0,0 +1,12 @@+```+% pandoc -t latex+key = value+: Definition+^D+\begin{description}+\tightlist+\item[{key = value}]+Definition+\end{description}++```
@@ -0,0 +1,6 @@+```+% pandoc -f native -t typst+[Str "-?", Space, Str "...", Space, Str "a-b."]+^D+\-\? \.\.\. a-b.+```
@@ -0,0 +1,14 @@+```+% pandoc -f native -t rtf | pandoc -f rtf -t native+[ Para [ Str "abc\8217def" ]+, Para [ Str "\8220abc\8221" , Space , Str "\8216abc\8217" ]+, Para [ Str "abc\8217def" ]+, Para [ Str "abc\8212def" ]+]+^D+[ Para [ Str "abc\8217def" ]+, Para [ Str "\8220abc\8221" , Space , Str "\8216abc\8217" ]+, Para [ Str "abc\8217def" ]+, Para [ Str "abc\8212def" ]+]+```
@@ -0,0 +1,9 @@+If no class matches a language, we just use the first one.+````+% pandoc -f native -t markdown+[ CodeBlock ( "" , [ "text" ] , [] ) "x" ]+^D+``` text+x+```+````
binary file changed (absent → 970 bytes)
@@ -0,0 +1,19 @@+A `w:gridCol` need not have a width (`w:w`). Such a column is kept,+and since its width is missing, every column gets the default width.++```+% pandoc command/11989.docx -t html+^D+<table>+<tbody>+<tr>+<td>a</td>+<td>b</td>+</tr>+<tr>+<td>c</td>+<td>d</td>+</tr>+</tbody>+</table>+```
binary file changed (absent → 2687 bytes)
@@ -0,0 +1,37 @@+Notes and comments are read with the namespace prefixes declared in+their own parts (word/footnotes.xml, word/endnotes.xml,+word/comments.xml). Here word/document.xml declares only `w`; the+footnote's hyperlink uses `r`, and the equations in the endnote and+the comment use `m`.++```+% pandoc command/11991.docx -t native --track-changes=all+^D+[ Para+ [ Span+ ( ""+ , [ "comment-start" ]+ , [ ( "comment-id" , "0" )+ , ( "author" , "A" )+ , ( "date" , "2026-01-01T00:00:00Z" )+ ]+ )+ [ Str "Math:" , Space , Math InlineMath "x" ]+ , Str "Text"+ , Span+ ( "" , [ "comment-end" ] , [ ( "comment-id" , "0" ) ] ) []+ , Note+ [ Para+ [ Str "See"+ , Space+ , Link+ ( "" , [] , [] )+ [ Str "example" ]+ ( "https://example.com/" , "" )+ ]+ ]+ , Note+ [ Para [ Str "Math:" , Space , Math InlineMath "x" ] ]+ ]+]+```
@@ -49,7 +49,9 @@ ... ^D Pandoc- Meta { unMeta = fromList [ ( "foo" , MetaBool False ) ] }+ Meta+ { unMeta = fromList [ ( "foo" , MetaInlines [ Str "no" ] ) ]+ } [] ```
@@ -0,0 +1,33 @@+Paragraphs after the first in a list item should not be turned+into items of a separate list, and should round-trip:++```+% pandoc -f native -t docx -o - | pandoc -f docx -t native+[ BulletList+ [ [ Para [ Str "one" ]+ , Para [ Str "sub" ]+ , BulletList+ [ [ Para [ Str "nested" ]+ , Para [ Str "nested" , Space , Str "sub" ]+ ]+ ]+ , Para [ Str "back" ]+ ]+ , [ Para [ Str "two" ] ]+ ]+]+^D+[ BulletList+ [ [ Para [ Str "one" ]+ , Para [ Str "sub" ]+ , BulletList+ [ [ Para [ Str "nested" ]+ , Para [ Str "nested" , Space , Str "sub" ]+ ]+ ]+ , Para [ Str "back" ]+ ]+ , [ Para [ Str "two" ] ]+ ]+]+```
@@ -0,0 +1,43 @@+```+% pandoc -f native -t markdown+[Para [Str "a", Note [Para [Str "outer", Note [Para [Str "inner"]]]], Str "b", Note [Para [Str "second"]]]]+^D+a[^1]b[^2]++[^1]: outer[^3]++[^2]: second++[^3]: inner+```++```+% pandoc -f native -t rst+[Para [Str "a", Note [Para [Str "outer", Note [Para [Str "inner"]]]], Str "b", Note [Para [Str "second"]]]]+^D+a [1]_b [2]_++.. [1]+ outer [3]_++.. [2]+ second++.. [3]+ inner+```++```+% pandoc -f native -t haddock+[Para [Str "a", Note [Para [Str "outer", Note [Para [Str "inner"]]]], Str "b", Note [Para [Str "second"]]]]+^D+a<#notes [1]>b<#notes [2]>++#notes#++1. outer<#notes [3]>++2. second++3. inner+```
@@ -30,7 +30,7 @@ :::: {#refs .references .csl-bib-body .hanging-indent entry-spacing="0"} ::: {#ref-Faraday-forthcoming .csl-entry} Faraday, Carry. Forthcoming. "Protean Photography." In *Seven Trips-Beyond the Asteroid Belt*, edited by James Oring. Cape Canaveral, FL:+beyond the Asteroid Belt*, edited by James Oring. Cape Canaveral, FL: Launch Press. ::: ::::
binary file changed (absent → 1751 bytes)
@@ -0,0 +1,24 @@+[ Para+ [ Str "Error!"+ , Space+ , Str "Reference"+ , Space+ , Str "source"+ , Space+ , Str "not"+ , Space+ , Str "found."+ ]+, Para+ [ Link+ ( "" , [] , [] )+ [ Str "Target" , Space , Str "B" ]+ ( "#_Ref2" , "" )+ ]+, BulletList+ [ [ Para [ Str "Item" , Space , Str "one" ] ]+ , [ Para [ Str "Item" , Space , Str "two" ] ]+ ]+, Para+ [ Str "After" , Space , Str "the" , Space , Str "list." ]+]
binary file changed (absent → 1986 bytes)
@@ -0,0 +1,1 @@+[ CodeBlock ( "" , [] , [] ) "int x;" ]
binary file changed (absent → 1780 bytes)
@@ -0,0 +1,14 @@+[ Para [ Str "Target" , Space , Str "A" ]+, Para+ [ Link+ ( "" , [] , [] )+ [ Str "Target" , Space , Str "B" ]+ ( "#_Ref2" , "" )+ ]+, BulletList+ [ [ Para [ Str "Item" , Space , Str "one" ] ]+ , [ Para [ Str "Item" , Space , Str "two" ] ]+ ]+, Para+ [ Str "After" , Space , Str "the" , Space , Str "list." ]+]
binary file changed (11039 → 11058 bytes)
binary file changed (10660 → 10681 bytes)
binary file changed (10763 → 10781 bytes)
@@ -77,93 +77,91 @@ , Space , Str "Documentation" ]+ , Para+ [ Strong+ [ Str "Goal:"+ , Space+ , Str "Baseline"+ , Space+ , Str "and"+ , Space+ , Str "ongoing"+ , Space+ , Str "metrics"+ , Space+ , Str "tracking"+ , Space+ , Str "doc"+ , Space+ , Str "usefulness"+ , Space+ , Str "and"+ , Space+ , Str "completeness."+ ]+ ]+ , Para [ Str "\160" ] ] ]- , BlockQuote- [ Para- [ Strong- [ Str "Goal:"- , Space- , Str "Baseline"- , Space- , Str "and"- , Space- , Str "ongoing"- , Space- , Str "metrics"- , Space- , Str "tracking"- , Space- , Str "doc"- , Space- , Str "usefulness"- , Space- , Str "and"- , Space- , Str "completeness."- ]- ]- , Para [ Str "\160" ]- ] , OrderedList ( 2 , Decimal , Period )- [ [ Para [ Str "Content" , Space , Str "Migration" ] ] ]- , BlockQuote- [ Para- [ Str "Goal:"- , Space- , Str "Content"- , Space- , Str "is"- , Space- , Str "accessible"- , Space- , Str "to"- , Space- , Str "new"- , Space- , Str "employees"- , Space- , Str "and"- , Space- , Str "is"- , Space- , Str "better"- , Space- , Str "organized/archived."- ]- , Para [ Str "\160" ]+ [ [ Para [ Str "Content" , Space , Str "Migration" ]+ , Para+ [ Str "Goal:"+ , Space+ , Str "Content"+ , Space+ , Str "is"+ , Space+ , Str "accessible"+ , Space+ , Str "to"+ , Space+ , Str "new"+ , Space+ , Str "employees"+ , Space+ , Str "and"+ , Space+ , Str "is"+ , Space+ , Str "better"+ , Space+ , Str "organized/archived."+ ]+ , Para [ Str "\160" ]+ ] ] , OrderedList ( 3 , Decimal , Period )- [ [ Para [ Str "Wiki" , Space , Str "(xl)" ] ] ]- , BlockQuote- [ Para- [ Strong- [ Str "Goal:"- , Space- , Str "Useful"- , Space- , Str "documentation"- , Space- , Str "that"- , Space- , Str "is"- , Space- , Str "archived,"- , Space- , Str "searchable"- , Space- , Str "and"- , Space- , Str "easy"- , Space- , Str "to"- , Space- , Str "create"- ]- ]- , Para [ Str "\160\160" ]+ [ [ Para [ Str "Wiki" , Space , Str "(xl)" ]+ , Para+ [ Strong+ [ Str "Goal:"+ , Space+ , Str "Useful"+ , Space+ , Str "documentation"+ , Space+ , Str "that"+ , Space+ , Str "is"+ , Space+ , Str "archived,"+ , Space+ , Str "searchable"+ , Space+ , Str "and"+ , Space+ , Str "easy"+ , Space+ , Str "to"+ , Space+ , Str "create"+ ]+ ]+ , Para [ Str "\160\160" ]+ ] ] , OrderedList ( 4 , Decimal , Period )@@ -178,89 +176,87 @@ , Space , Str "(XLCRBot)." ]+ , Para+ [ Strong+ [ Str "Goal:"+ , Space+ , Str "Feedback"+ , Space+ , Str "on"+ , Space+ , Str "basic"+ , Space+ , Str "violations"+ , Space+ , Str "in"+ , Space+ , Str "seconds"+ , Space+ , Str "or"+ , Space+ , Str "minutes"+ , Space+ , Str "at"+ , Space+ , Str "most"+ , Space+ , Str "in"+ , Space+ , Str "either"+ , Space+ , Str "VS"+ , Space+ , Str "or"+ , Space+ , Str "Codeflow."+ ]+ ] ] ]- , BlockQuote- [ Para- [ Strong- [ Str "Goal:"- , Space- , Str "Feedback"- , Space- , Str "on"- , Space- , Str "basic"- , Space- , Str "violations"- , Space- , Str "in"- , Space- , Str "seconds"- , Space- , Str "or"- , Space- , Str "minutes"- , Space- , Str "at"- , Space- , Str "most"- , Space- , Str "in"- , Space- , Str "either"- , Space- , Str "VS"- , Space- , Str "or"- , Space- , Str "Codeflow."- ]- ]- ] , OrderedList ( 5 , Decimal , Period )- [ [ Para [ Str "Code" , Space , Str "documentation" ] ] ]- , BlockQuote- [ Para- [ Strong- [ Str "Goal:"- , Space- , Str "Useful,"- , Space- , Str "consistent,"- , Space- , Str "tool"- , Space- , Str "supported"- , Space- , Str "comments"- ]- ]+ [ [ Para [ Str "Code" , Space , Str "documentation" ]+ , Para+ [ Strong+ [ Str "Goal:"+ , Space+ , Str "Useful,"+ , Space+ , Str "consistent,"+ , Space+ , Str "tool"+ , Space+ , Str "supported"+ , Space+ , Str "comments"+ ]+ ]+ ] ] , Para [ Strong [ Str "\160" ] , Str "\160" ] , OrderedList ( 6 , Decimal , Period )- [ [ Para [ Str "Education" , Space , Str "efforts" ] ] ]- , BlockQuote- [ Para- [ Strong- [ Str "Goal:"- , Space- , Str "Broad,"- , Space- , Str "discoverable"- , Space- , Str "channels"- , Space- , Str "for"- , Space- , Str "updates"- , Space- , Str "and"- , Space- , Str "news"- ]- ]+ [ [ Para [ Str "Education" , Space , Str "efforts" ]+ , Para+ [ Strong+ [ Str "Goal:"+ , Space+ , Str "Broad,"+ , Space+ , Str "discoverable"+ , Space+ , Str "channels"+ , Space+ , Str "for"+ , Space+ , Str "updates"+ , Space+ , Str "and"+ , Space+ , Str "news"+ ]+ ]+ ] ] , Para [ Strong [ Str "\160" ] ] ]
@@ -3,7 +3,7 @@ [ Table ( "" , [] , [] ) (Caption Nothing [])- [ ( AlignCenter , ColWidth 0.16167023554603854 )+ [ ( AlignDefault , ColWidth 0.16167023554603854 ) , ( AlignDefault , ColWidth 0.16167023554603854 ) , ( AlignDefault , ColWidth 0.40920770877944324 ) ]
@@ -3,7 +3,7 @@ [ Table ( "" , [] , [] ) (Caption Nothing [])- [ ( AlignDefault , ColWidth 0.30701754385964913 )+ [ ( AlignLeft , ColWidth 0.30701754385964913 ) , ( AlignDefault , ColWidth 0.13645224171539963 ) , ( AlignDefault , ColWidth 0.10009746588693959 ) , ( AlignDefault , ColWidth 9.707602339181289e-2 )
binary file changed (absent → 1863 bytes)
@@ -0,0 +1,58 @@+[ Para+ [ Str "A"+ , Space+ , Str "note"+ , Space+ , Str "whose"+ , Space+ , Str "paragraph"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "deleted"+ , Note [ Para [ Str "First" , Space , Str "note." ] ]+ , Str "."+ ]+, Para+ [ Str "A"+ , Space+ , Str "note"+ , Space+ , Str "whose"+ , Space+ , Str "paragraph"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "inserted"+ , Note [ Para [ Str "Second" , Space , Str "note." ] ]+ , Str "."+ ]+, Para+ [ Str "A"+ , Space+ , Str "paragraph"+ , Space+ , Str "whose"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "deleted."+ , Space+ , Str "The"+ , Space+ , Str "paragraph"+ , Space+ , Str "it"+ , Space+ , Str "joins"+ , Note [ Para [ Str "Third" , Space , Str "note." ] ]+ , Str "."+ ]+]
@@ -0,0 +1,59 @@+[ Para+ [ Str "A"+ , Space+ , Str "note"+ , Space+ , Str "whose"+ , Space+ , Str "paragraph"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "deleted"+ , Note [ Para [ Str "First" , Space , Str "note." ] ]+ , Str "."+ ]+, Para+ [ Str "A"+ , Space+ , Str "note"+ , Space+ , Str "whose"+ , Space+ , Str "paragraph"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "inserted"+ , Note [ Para [ Str "Second" , Space , Str "note." ] ]+ , Str "."+ ]+, Para+ [ Str "A"+ , Space+ , Str "paragraph"+ , Space+ , Str "whose"+ , Space+ , Str "mark"+ , Space+ , Str "is"+ , Space+ , Str "deleted."+ ]+, Para+ [ Str "The"+ , Space+ , Str "paragraph"+ , Space+ , Str "it"+ , Space+ , Str "joins"+ , Note [ Para [ Str "Third" , Space , Str "note." ] ]+ , Str "."+ ]+]
@@ -0,0 +1,814 @@+[ Para+ [ Str "An" , Space , Str "example" , Space , Str "list" ]+, Para []+, OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "a"+ , Space+ , Str "list,"+ ]+ ]+ , [ Para [ Str "With" , Space , Str "numbers" ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Plain+ [ Str "A"+ , Space+ , Str "sublist"+ , Space+ , Str "from"+ , Space+ , Str "word,"+ , Space+ , Str "starts"+ , Space+ , Str "with"+ ]+ ]+ , [ Para [ Str "Alphabetic" , Space , Str "characters" ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Plain+ [ Str "A"+ , Space+ , Str "sub-sub-list"+ , Space+ , Str "will"+ , Space+ , Str "be"+ ]+ ]+ , [ Para+ [ Str "With"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman"+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "And"+ , Space+ , Str "here"+ , Space+ , Str "we"+ , Space+ , Str "are"+ , Space+ , Str "back"+ , Space+ , Str "with"+ , Space+ , Str "numbers"+ ]+ ]+ , [ Para+ [ Str "And"+ , Space+ , Str "another"+ , Space+ , Str "number"+ ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Plain+ [ Str "And"+ , Space+ , Str "back"+ , Space+ , Str "to"+ , Space+ , Str "lowercase"+ , Space+ , Str "alphabetical"+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "ORIGINAL"+ , Space+ , Str "LEVEL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "Wow"+ , Space+ , Str "that"+ , Space+ , Str "was"+ , Space+ , Str "cool!"+ , Space+ , Str "AMAZING"+ ]+, Para []+, OrderedList+ ( 1 , UpperAlpha , Period )+ [ [ Plain+ [ Str "But"+ , Space+ , Str "we"+ , Space+ , Str "also"+ , Space+ , Str "have"+ , Space+ , Str "lists"+ ]+ ]+ , [ Para+ [ Str "With"+ , Space+ , Str "uppercase"+ , Space+ , Str "alphabet"+ ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Plain+ [ Str "And"+ , Space+ , Str "the"+ , Space+ , Str "sublist"+ , Space+ , Str "here"+ , Space+ , Str "again"+ ]+ ]+ , [ Para+ [ Str "Is"+ , Space+ , Str "lowercase"+ , Space+ , Str "alphabet"+ ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Plain+ [ Str "And"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman"+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "ORIGINAL"+ , Space+ , Str "LEVEL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "And"+ , Space+ , Str "foremost,"+ , Space+ , Str "we"+ , Space+ , Str "have"+ , Space+ , Str "lists"+ , Space+ , Str "starting"+ , Space+ , Str "with"+ , Space+ , Str "uppercase"+ , Space+ , Str "roman."+ ]+, Para []+, OrderedList+ ( 1 , UpperRoman , Period )+ [ [ Plain [ Str "Like" , Space , Str "this" ] ]+ , [ Plain+ [ Str "This"+ , Space+ , Str "list"+ , Space+ , Str "has"+ , Space+ , Str "uppercase"+ , Space+ , Str "roman"+ ]+ ]+ , [ Para+ [ Str "And"+ , Space+ , Str "that"+ , Space+ , Str "is"+ , Space+ , Str "very"+ , Space+ , Str "OK"+ ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Para+ [ Str "And"+ , Space+ , Str "again,"+ , Space+ , Str "the"+ , Space+ , Str "sublist"+ , Space+ , Str "starts"+ , Space+ , Str "with"+ , Space+ , Str "lowercase"+ , Space+ , Str "alphabet"+ ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Para+ [ Str "And"+ , Space+ , Str "a"+ , Space+ , Str "sub-sub-list"+ , Space+ , Str "with"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman"+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "But"+ , Space+ , Str "the"+ , Space+ , Str "sub-sub-sub-list"+ , Space+ , Str "starts"+ , Space+ , Str "with"+ , Space+ , Str "numbers"+ , Space+ , Str "here"+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "ORIGINAL"+ , Space+ , Str "LEVEL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "And"+ , Space+ , Str "a"+ , Space+ , Str "list"+ , Space+ , Str "in"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman"+ ]+, Para []+, OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Para+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "an"+ , Space+ , Str "example"+ , Space+ , Str "of"+ , Space+ , Str "that"+ ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Para+ [ Str "And"+ , Space+ , Str "this"+ , Space+ , Str "will"+ , Space+ , Str "be"+ , Space+ , Str "lowercase"+ , Space+ , Str "alphabetic"+ ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Para+ [ Str "And"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman??"+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain [ Str "And" , Space , Str "numeric" ] ]+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "ORIGINAL"+ , Space+ , Str "LEVEL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "And"+ , Space+ , Str "an"+ , Space+ , Str "odd"+ , Space+ , Str "list,"+ , Space+ , Str "using"+ , Space+ , Str "1),"+ , Space+ , Str "2),"+ , Space+ , Str "etc:"+ ]+, Para []+, OrderedList+ ( 1 , Decimal , OneParen )+ [ [ Para [ Str "Hello" , Space , Str "there" ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Para+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "a"+ , Space+ , Str "sublist"+ , Space+ , Str "(lowercase"+ , Space+ , Str "alphabetic)"+ ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Para+ [ Str "Sub-sub-list"+ , Space+ , Str "(lowercase"+ , Space+ , Str "roman)"+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "Numeric,"+ , Space+ , Str "but"+ , Space+ , Str "without"+ , Space+ , Str "the"+ , Space+ , Str ")"+ , Space+ , Str "but"+ , Space+ , Str "with"+ , Space+ , Str "the"+ , Space+ , Str "."+ ]+ ]+ ]+ ]+ , [ Plain [ Str "Lower" , Space , Str "level" ] ]+ ]+ ]+ , [ Plain [ Str "Lower" , Space , Str "level" ] ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "ORIGINAL"+ , Space+ , Str "LEVEL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "Some"+ , Space+ , Str "list"+ , Space+ , Str "do"+ , Space+ , Str "the"+ , Space+ , Str "same"+ , Space+ , Str "but"+ , Space+ , Str "with"+ , Space+ , Str "alphabetic:"+ , Space+ , Str "a),"+ , Space+ , Str "b),"+ , Space+ , Str "etc."+ ]+, Para []+, OrderedList+ ( 1 , LowerAlpha , OneParen )+ [ [ Para [ Str "Hello" , Space , Str "there" ]+ , OrderedList+ ( 1 , LowerAlpha , Period )+ [ [ Para+ [ Str "Sub-list,"+ , Space+ , Str "normal"+ , Space+ , Str "alphabetic"+ , Space+ , Str "with"+ , Space+ , Str "dot"+ ]+ , OrderedList+ ( 1 , LowerRoman , Period )+ [ [ Plain+ [ Str "Sub-sub-list,"+ , Space+ , Str "lowercase"+ , Space+ , Str "roman"+ , Space+ , Str "again!"+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "BACK"+ , Space+ , Str "TO"+ , Space+ , Str "THE"+ , Space+ , Str "ORIGINAL"+ ]+ ]+ ]+, Para []+, Para+ [ Str "We"+ , Space+ , Str "also"+ , Space+ , Str "can"+ , Space+ , Str "have"+ , Space+ , Str "list"+ , Space+ , Str "functioning"+ , Space+ , Str "with"+ , Space+ , Str "1.,"+ , Space+ , Str "1.1.,"+ , Space+ , Str "1.1.1,"+ , Space+ , Str "etc."+ ]+, Para []+, OrderedList+ ( 1 , Decimal , Period )+ [ [ Para+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "an"+ , Space+ , Str "example"+ , Space+ , Str "of"+ , Space+ , Str "that"+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "This"+ , Space+ , Str "is"+ , Space+ , Str "the"+ , Space+ , Str "1.1"+ ]+ ]+ , [ Para+ [ Str "And"+ , Space+ , Str "this"+ , Space+ , Str "is"+ , Space+ , Str "the"+ , Space+ , Str "1.2."+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Para+ [ Str "And"+ , Space+ , Str "this"+ , Space+ , Str "is"+ , Space+ , Str "a"+ , Space+ , Str "1.2.1."+ ]+ , OrderedList+ ( 1 , Decimal , Period )+ [ [ Plain+ [ Str "And"+ , Space+ , Str "so"+ , Space+ , Str "forth,"+ , Space+ , Str "this"+ , Space+ , Str "will"+ , Space+ , Str "be"+ , Space+ , Str "a"+ , Space+ , Str "1.2.1.1"+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ ]+ , [ Plain+ [ Str "Back"+ , Space+ , Str "to"+ , Space+ , Str "the"+ , Space+ , Str "original"+ , Space+ , Str "leven"+ , Space+ , Str "(2.)"+ ]+ ]+ ]+, Para []+, Para+ [ Str "Some"+ , Space+ , Str "other"+ , Space+ , Str "interesting"+ , Space+ , Str "list"+ , Space+ , Str "as"+ , Space+ , Str "follows,"+ , Space+ , Str "these"+ , Space+ , Str "are"+ , Space+ , Str "headings,"+ , Space+ , Str "but"+ , Space+ , Str "not"+ , Space+ , Str "really"+ , Space+ , Str "lists,"+ , Space+ , Str "but"+ , Space+ , Str "Microsoft"+ , Space+ , Str "Word"+ , Space+ , Str "pretends"+ , Space+ , Str "they"+ , Space+ , Str "are.."+ ]+, Para []+, Header+ 1+ ( "it-seems-like-this-list-has-headings-1." , [] , [] )+ [ Str "It"+ , Space+ , Str "seems"+ , Space+ , Str "like"+ , Space+ , Str "this"+ , Space+ , Str "list"+ , Space+ , Str "has"+ , Space+ , Str "headings??"+ , Space+ , Str "(1.)"+ ]+, Para []+, Header+ 2+ ( "i-wonder-how-this-is-converted-1.1" , [] , [] )+ [ Str "I"+ , Space+ , Str "wonder"+ , Space+ , Str "how"+ , Space+ , Str "this"+ , Space+ , Str "is"+ , Space+ , Str "converted"+ , Space+ , Str "(1.1)"+ ]+, Para []+, Para []+, Para [ Strong [ Str "And" , Space , Str "finally:" ] ]+, Para []+, Para+ [ Str "We"+ , Space+ , Str "can"+ , Space+ , Str "also"+ , Space+ , Str "have"+ , Space+ , Str "lists"+ , Space+ , Str "with"+ , Space+ , Str "text"+ , Space+ , Str "in"+ , Space+ , Str "between."+ , Space+ ]+, Para []+, Para+ [ Str "Things"+ , Space+ , Str "in"+ , Space+ , Str "life"+ , Space+ , Str "I"+ , Space+ , Str "like:"+ ]+, Para []+, OrderedList+ ( 1 , Decimal , Period ) [ [ Plain [ Str "Cookies" ] ] ]+, Para []+, Para+ [ Str "Cookies"+ , Space+ , Str "are"+ , Space+ , Str "just"+ , Space+ , Str "delicious"+ ]+, Para []+, OrderedList+ ( 2 , Decimal , Period ) [ [ Plain [ Str "Alcohol" ] ] ]+, Para []+, Para+ [ Str "It\8217s"+ , Space+ , Str "really"+ , Space+ , Str "nice."+ ]+, Para []+, OrderedList+ ( 3 , Decimal , Period ) [ [ Plain [ Str "CENSORED" ] ] ]+, Para []+, Para+ [ Str "Yeah"+ , Space+ , Str "we"+ , Space+ , Str "all"+ , Space+ , Str "know"+ , Space+ , Str "what"+ , Space+ , Str "I"+ , Space+ , Str "mean"+ , Space+ , Str "by"+ , Space+ , Str "that."+ ]+]
binary file changed (absent → 10880 bytes)
binary file changed (53336 → 53357 bytes)
binary file changed (66427 → 64576 bytes)
binary file changed (32231 → 32251 bytes)
binary file changed (45326 → 43474 bytes)
binary file changed (28988 → 28991 bytes)
binary file changed (42073 → 42053 bytes)
binary file changed (52690 → 51952 bytes)
binary file changed (51318 → 50588 bytes)
binary file changed (52701 → 51966 bytes)
binary file changed (52277 → 51546 bytes)
binary file changed (55633 → 55548 bytes)
binary file changed (66368 → 65696 bytes)
binary file changed (31689 → 31711 bytes)
binary file changed (44773 → 42923 bytes)
binary file changed (33927 → 33483 bytes)
binary file changed (31575 → 31596 bytes)
binary file changed (44659 → 42808 bytes)
binary file changed (30593 → 30614 bytes)
binary file changed (43687 → 41836 bytes)
binary file changed (51466 → 51528 bytes)
binary file changed (64559 → 62749 bytes)
binary file changed (35293 → 35356 bytes)
binary file changed (48386 → 46577 bytes)