2822 Commits

Author SHA1 Message Date
John MacFarlane 2f103b3c76 Docx reader: handle case where non-header rows come before header rows.
In this case we'll treat them all as the header in order to
preserve the order.

Added test case for #11833.
2026-08-27 14:51:13 -07:00
John MacFarlane 75982322cf Docx reader: improve handling of tables with uneven rows.
Previously if a table started with a 1-column row, only 1 column
would be included, even if other rows had more  columns.

Closes #11833.
2026-08-27 14:39:26 -07:00
John MacFarlane 9260d17d21 Make mathml the default math-method.
Closes #11751.
2026-08-26 09:51:03 -07:00
John MacFarlane c73a35a2e7 Add --math-method option.
This replaces (now deprecated but still functional) options
`--mathml`, `--mathjax`, `--gladtex`, `--katex`, `--webtex`.

The `plain` style can now be specified explicitly.

In defaults files, `html-math-method` is now
`math-method` (though `html-math-method` will still work).

Text.Pandoc.App.Opt:

- In unexported type CompletionKind, add MathMethods.
- In Opt, change `optHTMLMathMethod` to `optMathMethod`. [API  change]

Text.Pandoc.Options:

- Rename HTMLMathMethod type to MathMethod. [API change]
- Rename `writerHTMLMathMethod` field of WriterOptions to
  `writerMathMethod`. [API change]

Text.Pandoc.App.Completion:

- Clean up code.
- Add support for `--math-method`.
2026-08-26 09:46:48 -07:00
John MacFarlane 7b866613f6 ODT/OpenDocument writers: support RTL text direction.
RTL is now properly handled in these cases:

- `dir: rtl` (or `ltr`) in document metadata
- an RTL `lang` in metadata (e.g. `he`, `ar`), unless overridden
  by `dir`
- a `dir` attribute on a Div

The OpenDocument writer tracks the active writing mode and, when it
is RTL, emits automatic paragraph styles with
`style:writing-mode="rl-tb"` derived from the usual named styles
(deduplicated per parent style).  `fo:text-align` is also used
to get the matching text alignment.

Code blocks remain ltr regardless.

Closes #11301.

With some help from Claude Fable.
2026-08-26 08:49:07 -07:00
John MacFarlane 5727e10827 Markdown reader: Add a syntax for resetting example list counter.
This is needed often at the beginning of a chapter.

Closes #10940.
2026-08-24 12:07:19 -07:00
John MacFarlane 0a9a2f2615 Avoid a deprecation warning relating to QuickCheck. 2026-08-22 11:00:45 -07:00
John MacFarlane 65e6d995f9 Docx writer: initialize envLang from lang metadata.
This ensures that setting `lang` will affect the whole document.
Previously, setting `lang` to `he` was not sufficient to make
the document RTL.

See #11301.
2026-08-22 10:26:07 -07:00
John MacFarlane 965e9e7d0d Revert "Use withNumTests and require QuickCheck >= 2.18."
This reverts commit b38743d218.
2026-08-22 09:50:06 -07:00
John MacFarlane b38743d218 Use withNumTests and require QuickCheck >= 2.18. 2026-08-21 23:27:19 -07:00
wzy 0ce83fb133 Add --completion={bash,zsh,fish} (#11818)
Make `--bash-completion` an alias of `--completion=bash`.

Reorganize option parsing code using a new data structure OptionSpec,
which can encode the type of completion needed by each option.

Add new unexported module Text.Pandoc.Completion.

Unexported module Text.Pandoc.CommandLineOptions: export OptionSpec.

Closes #8542.
2026-08-20 13:46:25 -07:00
Alex 6658e94511 RTF Reader: nested table support (#11790)
Closes #11218.
2026-08-18 10:24:49 -07:00
John MacFarlane 5f37c6781b Typst reader: 'block' should also be block-level.
See 185c29b4b2 which claims that
`block` can occur in inline contexts. I can no longer confirm
this and suspect that it may have been an unintended behavior
of earlier versions of typst, now fixed.

Closes #11814.
2026-08-17 10:01:58 -07:00
John MacFarlane dd970030ba HTML reader: handle pre without code.
We preserve whitespace as nonbreaking spaces.

Closes #11810.
2026-08-17 09:27:38 -07:00
John MacFarlane 8139d6bc1c Use dev version of djoths. 2026-08-16 16:25:00 -07:00
John MacFarlane 6107a26945 JATS writer: fix illegal use of p inside p.
Closes #11809.
2026-08-16 10:44:18 -07:00
John MacFarlane 3acfe775e6 LaTeX writer: omit empty caption on unnumbered tables.
(Even if they have an identifier.)

Closes #11795.
2026-08-11 11:22:12 -07:00
John MacFarlane 7c35a540d1 Revert "Typst writer: fix escaping of quotes."
This reverts commit 04848401d5.

However, we retain the test for #11463, which didn't actually
need the reverted commit.

Closes #11788.
2026-08-11 09:35:17 -07:00
John MacFarlane d38c8594ae Update asciidoc reader tests.
In light of changes in asciidoc-hs.
2026-08-11 09:32:06 -07:00
John MacFarlane 87bc462713 Typst writer: make writer sensitive to typst-label attribute.
If this attribute is set, the writer will output a label.
(This overrides labels based on identifiers, when identifiers
are present.)

Note that labels in typst need not be unique and may be used to
style elements using show rules.  For example, one can attach
an `excerpt` label to all Divs that are excerpts, and style this
using a show rule like `#show <excerpt>: set text(blue)`.

See discussion at #11794.
2026-08-07 10:39:33 -07:00
John MacFarlane 12a44fbb98 Markdown raw HTML: fix handling of void hr element.
Closes #11793.

Added `voidTags` to unexported module
Text.Pandoc.Readers.HTML.TagCategories.
2026-08-05 07:18:12 -07:00
Ian Max Andolina c198e7e3cc Typst template: rename horizontalrule to horizontalRule (#11784)
The polyfill calls a camelCase `horizontalRule` yet the function is not cameCase.
2026-07-30 12:30:04 +02:00
John MacFarlane db8d64fe6f Markdown writer: Fix ordered list bug.
Previously ordered lists starting with a code block did not
round trip. Pandoc uses an indented code block, and according
to commonmark rules only one space is gobbled after the list
marker; however, pandoc added two.  This has now been fixed.
An incidental change fixes an oddity in markua list indentation.

Closes #11762.
2026-07-14 17:34:15 +02:00
Tobias Deiminger 5dd191098d RST reader: Fix nested placeholder resolution for inline elements (#11753)
Given RST like

    .. _target:

    See |sub|.

    .. |sub| replace:: `text <target_>`_

'pandoc -f rst -t html' produces

    <div id="target">
    <p>See <a href="##REF##target">text</a>.</p>
    </div>

instead of the expected

    <div id="target">
    <p>See <a href="#target">text</a>.</p>
    </div>

It formerly worked and regressed with c8fda8f4d ("RST reader: Use a new
one-pass parsing strategy."), release 3.6.

What happens is that during parsing pass 1 the `replace::` value `text
<target_>`_ is parsed to

    Link nullAttr [Str "text"] ("##REF##target", "")

and is stored in ParserState's substitution table. Separately, '|sub|'
usage is parsed to

    Link nullAttr [Str "|sub|"] ("##SUBST##|sub|", "")

and is stored in the document tree. resolveReferences then replaces the
placeholder in the document node with substitution table node during
walkM. However, the freshly substituted ##REF## placeholder was not
revisited further, and appeared unresolved in the output.

To fix it, we resolve the node recursively until the result contains no
more placeholder. We must protect from self-references to avoid
endless recursion.
2026-07-12 16:35:37 +02:00
Chris Callison-Burch ce37e24c6a PPTX writer: keep tables and surrounding text on same slide (#11411)
Previously, when a slide contained bullet points before and after a
table, content would be split across multiple slides or use a two-column
layout that didn't preserve the source order.

This change:

1. Modified `splitBlocks'` in Presentation.hs to continue accumulating
   content after tables instead of immediately splitting to a new slide.

2. When a slide has a table with surrounding text, use ContentSlide
   (single column) instead of ContentWithCaptionSlide (two columns)
   to preserve content order.

3. Added vertical stacking in Output.hs (shapesToElementsStacked) to
   properly position multiple shapes (tables + text) within a content
   area. Space is allocated proportionally based on content size
   (paragraphs and table rows).

Closes #11433.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Chris Callison-Burch <ccb+github@upenn.edu>
2026-07-12 12:51:11 +02:00
luginf c645e57dc8 Add Txt2Tags writer (#11699).
`t2t` is now supported as an output format, producing Txt2Tags
markup (<https://txt2tags.org>). The writer covers headers, lists
(bullet, ordered, definition), tables, links, images, code blocks,
inline formatting, and raw txt2tags/HTML passthrough.

[API change]
Adds a new module Text.Pandoc.Writers.Txt2Tags, exporting
`writeTxt2Tags`. Also exported from Text.Pandoc.Writers.

Co-authored-by: luginf <alan@luginf>
2026-07-12 12:50:54 +02:00
Chirag Dhamange 432414c236 Fix: GFM empty task list conversion to ballot (#11744)
Extend `taskListItemToAscii` to cover empty task lists.
Closes #11599.
2026-07-12 12:01:23 +02:00
John MacFarlane 780e605c95 Texinfo writer: fix escaping in links.
Previously we dropped periods, commas, etc. This was a regression
from 2024. All we really need to do is escape the comma.

Closes #11758.
2026-07-11 10:57:33 +02:00
John MacFarlane ce1327e0b8 Use dev version of djoths.
Update test for djot parser fix.
2026-07-10 22:42:10 +02:00
John MacFarlane 3ecd95bf00 LaTeX writer: Provide a way to use table instead of longtable.
When the `float` class is attached to a table, a standard
floating `table` will be generated instead of a `longtable`.
Placement can be specified via the `latex-placement` attribute.
This will help, especially, those who use two-column layouts,
since `longtable` is incompatible with these.

Small change to the default LaTeX template: the `caption`
package is included and a default spacing set between the caption
and the table.

Closes #1023.
2026-07-10 16:38:03 +02:00
John MacFarlane d982f9f5ec Typst template: polyfill divider for typst < 0.15. 2026-07-09 01:28:43 +02:00
John MacFarlane d2f33e5b53 Typst reader/writer: use divider() for horizontal rule.
Remove old `horizontalRule` definition from default template.

Modify tests to use non-deprecated symbols.

Closes #11540.
2026-07-09 01:12:18 +02:00
John MacFarlane 1d6f33b897 Typst: further tight term list improvements.
Modified default template to remove custom show rule for
terms. Instead, we use a set rule to set hanging-indent.

For tight list items consisting of just one Plain block,
we no longer create a `#block` for the definition; this allows
it to remain on the same line as the term.
2026-07-08 11:18:31 +02:00
Amir Dekel 59c5eab2a0 Add support for tight terms in Typst writer (#11748)
This just affects whether a blank line is emitted in the markup.
Note that pandoc's default template contains a show rule for
terms that will make these blank lines irrelevant, but this change
allows one to use tight lists with custom templates.
2026-07-08 10:42:56 +02:00
John MacFarlane 9ebf79dd4b RTF writer: allow fontsize to be specified.
The fontsize is specified in a variable or metadata field
and passed through the renderer via a Reader monad.

Closes #11750.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-08 00:41:30 +02:00
John MacFarlane f6edf03303 Shared: Improve makeSections.
Previously it would sometimes create doubled section divs.
By leaving the inner heading's id on the heading itself, and
then consolidating the inner and outer section divs, we can
avoid this undesirable result.

Closes #11745.
2026-07-07 20:58:33 +02:00
John MacFarlane db7efddf74 Texinfo writer: fix spacing bug around HorizontalRule.
Closes #11749.
2026-07-07 16:58:44 +02:00
Can H. Tartanoglu 57639391fc ODT writer: image anchoring, percent dimensions, text width resolution (#11746)
Inline images now emit `text:anchor-type=as-char` on their `draw:frame`,
anchoring the frame as a character so it flows with the surrounding text.
Without this, consumers default to paragraph anchoring and float the frame
beside (or after) the following paragraph.

When both width and height are given and the width is a percentage,
the width is now resolved against the reference document text area width,
mirroring how the docx writer derives its print width from the reference docx
section properties. The height follows the aspect ratio.
2026-07-04 18:52:14 +02:00
John MacFarlane d8ea25c10e HTML styles: remove hard-coded font-size for print CSS.
Print CSS now uses the inherited font-size.
2026-07-01 13:54:24 +02:00
John MacFarlane 8547196b44 Markdown reader: ordered sublists must start with 1
(or equivalent, e.g. 'i').  This brings the markdown
parser in line with commonmark, and avoids a lot of
unintended list starts.  Closes #11735.

Note that ordered lists that are not sublists may
still start with numbers other than 1.
2026-07-01 11:17:21 +02:00
John MacFarlane 612e143fbe DokuWiki reader: skip non-cell content after table row.
Closes #11739.
2026-06-29 19:28:54 +02:00
John MacFarlane 1c22498269 LaTeX writer: fix footnotes in def list headings.
Closes #8240.
2026-06-29 11:40:30 +02:00
John MacFarlane 197ea8e8bd RST reader: treat undefined substitution references as plain text.
This mirrors rst2html behavior. Closes #11727.
2026-06-23 12:06:27 +02:00
John MacFarlane 58929eb70c Markdown writer: in YAML metadata, put double quotes around...
...strings that are numbers beginning with 0 or ending with 0 and
having a decimal point.  Otherwise they will read as YAML numbers
and potentially be modified (e.g. 3.10 -> 3.1).

It would be better to fix this on the reader side, but since
we use a standard YAML parser it's hard to see how.

Closes #11715.
2026-06-21 15:15:42 +02:00
John MacFarlane ec4fb91049 Typst reader: support auto_identifiers extension.
Headings without an explicit label can now be assigned automatic
identifiers based on the heading text, making them linkable in a
generated table of contents.  The extension is available for the
typst reader but is off by default; enable it with
`-f typst+auto_identifiers`.  The related `gfm_auto_identifiers` and
`ascii_identifiers` extensions are also made available.

Closes #11041.

Text.Pandoc.Readers.Typst.Parsing: PState gains sOptions,
sIdentifiers, and sLogMessages fields, and now has
HasReaderOptions, HasIdentifierList, and HasLogMessages
instances, allowing reuse of the shared registerHeader. (Not an
API change.)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 23:38:51 +02:00
John MacFarlane 8a52ac1493 Markdown writer: improve identification of code language class...
...by looking it up in the syntax map. (Previously we just used
the first, excepting `sourceCode`.)

Closes #11701 (together with previous commit).
2026-06-12 21:01:25 +02:00
Robertas 06af643730 Docx writer: use namespace URI instead of prefix in extractPageLayout (#11697)
When a reference document uses a non-standard namespace prefix for the
WordprocessingML namespace (e.g. `ns0` instead of `w`), `sectPr` elements
copied from the reference would retain the non-`w` prefix, producing
malformed XML in the output document.  Similarly,
`extractPageLayout` only matched elements with prefix `w`, missing
`sectPr` elements with other prefixes.  This is fixed by matching on the
namespace URI rather than the prefix, and normalizing the prefix to `w`
on all elements and attributes copied from reference-doc `sectPr`.

Some new tests have been added, and the test suite has been streamlined
using helper functions.
2026-06-12 18:13:10 +02:00
John MacFarlane 1b4a5356b4 Docx reader: key list numbering off abstractNumId.
Word represents "restart numbering" on a style-based list by pointing
only the first item of the restarted list at a new `numId` that shares the
original list's abstract numbering definition but carries a
`w:startOverride`; the remaining items keep using the original `numId`.

Pandoc keyed list continuation and grouping on the `numId`, so the
restarted items continued the stale count from the earlier list (and
were split into a separate ordered list with the wrong start).

Key continuation and grouping off the `abstractNumId` instead (the real
running counter in Word), and treat `startOverride` as a restart that
resets the count.

Closes #8367.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 11:59:10 +02:00
John MacFarlane 3a5f7ecee1 RTF reader: support legacy \pn/\pntext paragraph numbering (#11686).
Word-95-style numbered and bulleted lists are encoded with a
`{\pntext ...}` auto-number destination at the start of each list
paragraph plus a `{\*\pn ...}` destination describing the numbering,
rather than the modern `\listtext`/`\listtable` mechanism.  Two problems:

1. The `\pntext` marker text ("1.", "·", etc.) was captured as the
   paragraph's first text run, which sits before the paragraph's
   `\ls`/`\ilvl`, so emitBlocks (which reads list properties from the first
   run) misclassified the paragraph as an ordinary paragraph.  The first
   item of each list therefore came out as a stray paragraph.

2. The numbering style was ignored, so numbered lists defaulted to
   bullets.

Treat `\pntext` like `\listtext`: drop its visible marker text and flag the
start of a new list item.  Parse the `{\*\pn ...}` destination
(`\pnlvlbody`/`\pnlvlblt`, `\pndec`, `\pnucltr`, `\pnlcltr`,
`\pnucrm`, `\pnlcrm`, `\pnstart`, and the `\ls`/`\ilvl` keys it
carries) into the list override table so numbered lists are
emitted as ordered lists with the right number style.

`\pn` is a paragraph property that remains in effect until reset
by `\pard`, auto-numbering every paragraph in scope. Track
this (`sPnActive`) so each paragraph becomes its own list item,
rather than merging markerless continuation paragraphs as is done
for modern `\listtext` lists.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 08:49:17 +02:00
John MacFarlane 888a0062f1 Fix test for #11689 (use native) 2026-06-09 08:42:09 +02:00