Commit Graph

2779 Commits

Author SHA1 Message Date
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
John MacFarlane 656a6704a5 RTF writer: emit real RTF lists with a list table.
Lists were written as plain paragraphs with a literal marker and a
hanging indent, carrying none of the `\ls`/`\ilvl` references or the
`\listtable`/`\listoverridetable` that the RTF list model (and pandoc's
own reader) expect, so lists could not round-trip.

Walk the document tagging each list with a unique id and nesting level
(`prepareLists`), build a `\listtable`/`\listoverridetable` describing
each list (`listTableRTF`, exposed via the `listtable` template
variable), and render every list paragraph with its `\ls`/`\ilvl`
reference.  The first paragraph of each item gets a `{\listtext}`
marker; continuation paragraphs keep the reference but omit it, so
multi-paragraph items round-trip.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 00:17:57 +02:00
John MacFarlane 9312f1da1b RTF reader: support multi-paragraph list items.
The reader treated every list paragraph as a new list item, so a list
item containing several paragraphs was split into one item per
paragraph.  In the RTF list model a new item is marked by a
`{\listtext ...}` destination group; a list paragraph lacking one is a
continuation of the current item.

Track whether a `{\listtext}` group was seen (`sListText`) and, in
`emitBlocks`, append a continuation paragraph (no `\listtext`) to the
current item rather than starting a new one.

Adds a `list_multiparagraph` reader test.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 00:17:20 +02:00
John MacFarlane 5566a6bf3c Docx reader: improve horizontal rule detection.
Previously we failed to detect horizontal rules when the
underlying XML contained text elements for semantically
insignificant whitespace. We also failed to handle the case
where a paragraph contains text and has a bottom border
property: this seems to be what Word does when you insert
a horizontal rule, e.g. by typing a series of hyphens or #
characters.

Closes #11689.
2026-06-08 23:49:22 +02:00
John MacFarlane aafcfa14b0 LaTeX reader: handle \hypertarget with one braced parameter.
This seems to work in LaTeX, no doubt because a single token
is consumed as the target text parameter.

Closes #7418.
2026-06-08 19:22:24 +02:00
John MacFarlane 16d66edb2a Typst writer: fold lang into pickTypstAttributes.
This ensures that `lang` attributes will be set for both
Divs and Spans. Closes #11673.
2026-06-06 22:49:45 +02:00
John MacFarlane 9d68bb83a7 T.P.Writers.Shared; htmlAttrs - don't add data- prefix for markdown.
This is necessary for the `markdown_attribute` extension to
work properly. Closes #11685.
2026-06-05 17:17:22 +02:00
John MacFarlane 098c48d79f RTF reader: fix tables parsed as deeply nested tables.
Closes #11682.

Fixes two bugs that caused a simple table to be read as a cascade of
nested tables:

* `\plain` reset the entire property record (including the in-table
  flag) via `const def`.  When a cell paragraph used `\plain` after
  `\intbl`, the in-table flag was cleared, so the next `\cell` closed
  the partially-built table and embedded it inside a new cell.  Per the
  RTF spec, `\plain` should reset only character formatting, so it now
  preserves paragraph/context properties (in-table, list level, outline
  level, hyperlink, anchor).

* `\row` was ignored and only `\trowd` started a new row.  Real-world
  RTF often emits a single `\trowd` and separates rows with `\row`, so
  every cell ended up in one row.  Both `\trowd` and `\row` now begin a
  fresh row (only when the current one has cells), and empty trailing
  rows are dropped when closing the table.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-03 16:36:29 +02:00
John MacFarlane 676ccdc904 T.P.Writers.Shared: htmlAttrs: use data- prefix when needed.
This now behaves like the HTML writer, adding the `data-`
prefix for custom attributes.  This will affect, e.g.,
the mediawiki writer.

Closes #11680.
2026-06-03 12:23:44 +02:00
Meher Chaitanya 1ffeb856ee Add auto_identifiers support to Man Reader (#11675)
Add support for the `auto_identifiers`, `gfm_auto_identifiers`, and
`ascii_identifiers` extensions in the man reader. Section headings
parsed from .SH and .SS macros now receive auto-generated id
attributes when the extension is enabled, enabling `--toc` to
produce working anchor links.

- Add `autoIdExtensions` to default man extensions [behavior change]
- Add `HasReaderOptions`, `HasLogMessages` and `HasIdentifierList` to
  `ManState` to run `registerHeader`

Closes #8852.
2026-05-30 19:11:14 +02:00
Johan Larsson 41f829c43d Markdown reader: allow grid tables to be indented. (#11671)
Like the other table syntaxes (pipe, simple, and multiline tables) and
block-level constructs generally, a grid table may now be indented by up
to three spaces and still be recognized as a table.  Previously the
grid-table parser required the table to begin at the left margin, so an
indented grid table was parsed as a paragraph.

The leading indentation is stripped uniformly from each line before the
table is parsed, so an indented grid table produces the same AST as its
non-indented equivalent.

Adds a command test.
2026-05-28 00:07:29 +02:00
John MacFarlane 1c7cfb2a2a OpenDocument/ODT writer: use predefined styles. (#11672)
Previously the OpenDocument writer emitted a fresh automatic style
(L1..Ln, P1..Pn, T1..Tn) for nearly every list, list-item paragraph,
block quote, preformatted block, and inline text style.  This produced
large ODT files, made `--reference-doc` customization ineffective (the
user's predefined styles were never referenced), and gave each list its
own indentation independent of any containing block quote.

This commit teaches the writer to reference the predefined styles that
LibreOffice ships and that pandoc's reference.odt now exports:

- Bullet lists use `List_20_1`; ordered lists with default start and
  decimal format use `Numbering_20_1`.  Non-default ordered lists
  generate a single named override style (`Pandoc_Numbering_N`)
  memoised by (ListNumberStyle, ListNumberDelim); a non-default start
  value with the default format is expressed via `text:start-value`
  on the `text:list` element instead of a new style.
- List-item paragraphs use `List_20_Bullet[_Tight]` and
  `List_20_Number[_Tight]`.  The Tight variants are pandoc-specific
  (zero top/bottom margin) and are injected into the user's
  reference.odt if missing, just like the Skylighting token styles.
- Block quotes use the predefined `Quotations` paragraph style
  directly.  Nested block quotes use a single automatic style that
  inherits from Quotations and only adds extra margin-left, so a list
  inside a block quote now inherits its container's indent (#2747).
- Preformatted blocks use `Preformatted_20_Text` directly.
- Emphasis, Strong, Strikeout, Subscript, Superscript and Code spans
  use the predefined `Emphasis`, `Strong_20_Emphasis`, `Strikeout`,
  `Subscript`, `Superscript` and `Source_20_Text` text styles.
- `paraStyle`/`paraStyleFromParent` no longer emit a wrapper automatic
  style when its only attribute would be `parent-style-name`; the
  parent name is returned directly.

Closes #9136.
Closes #5086.
Closes #2747.
Closes #3426.
Closes #7336.

Co-authored by: Claude Opus 4.7.
2026-05-27 17:35:39 +02:00
John MacFarlane 9c83002851 Use MathJax v4 in default HTML templates.
See #11669.
2026-05-26 22:44:17 +02:00
John MacFarlane d37f306299 Man reader: better handling of .TP macro.
We parse these as DefinitionList items, but we previously
sometimes stopped prematurely in including material in the
definition.  We should include everything until we hit a new
indentation-changing macro.

Closes #11668.
2026-05-26 12:57:29 +02:00
John MacFarlane 646eeb6614 gridTable: fix calculation of column widths for default columns.
This fixes a bug which produced too-narrow columns in some cases.

Closes #11664.
2026-05-23 18:09:46 +02:00
nibras shami 0640c4c985 EPUB writer: support multiple EPUB versions for raw content (#11628).
This change ensures that raw content marked `epub2` will appear in (only) EPUBv2 output
and content marked `epub3` will appear in (only) EPUBv3 output.
2026-05-17 11:02:34 +02:00
John MacFarlane 73a48d2670 HTML reader: parse aside as a Div.
(Instead of using raw HTML.)

The "aside" class is added to the Div.
Also, add "header" class to Divs created from headers.

See #11626.
2026-05-14 11:58:19 +02:00
John MacFarlane b43762cdc4 Error messages: use single quotes around paths and format names.
Closes #11645.
2026-05-13 17:15:34 +02:00
John MacFarlane b8a0e5e85d Roff reader: handle \ line continuation in table cells.
Closes #11635.
2026-05-11 12:30:20 +02:00
John MacFarlane 859f62685a HTML templates: include pandoc-version in generator meta tag.
Closes #11624.
2026-05-07 12:39:06 +02:00
John MacFarlane 7825bd001c Markdown reader: don't produce empty Raw element with --strip-comments.
Closes #11625.
2026-05-07 12:10:23 +02:00
Andrew Dunning 8e6aecfebc Markdown reader: fix quotes in inline notes (#11614)
When parsing an inline note (`^[...]`) inside a quoted span,
`stateQuoteContext` was still set to `InSingleQuote`/`InDoubleQuote`,
so quotes within notes failed to parse as `Quoted` nodes.
Fix this by wrapping the note body parser in
`withQuoteContext NoQuote`.

Closes #11613.
2026-05-04 12:56:56 +02:00
John MacFarlane 45c31661b2 LaTeX reader: evaluate theorem name when used...
rather than evaluating it when the `\newtheorem` command
is encountered. It may include macros only defined later.
Closes #11608.
2026-05-02 13:07:00 +02:00
Keenan Brock 2b5600fd0c HTML styles: make screen-only CSS conditional (#11606)
Styles unconditionally emits css that uses screen-only properties.
Paged-media engines (weasyprint, prince, pagedjs) have no viewport
and issue warnings. Fix it to hide these properties from the engines.

Closes #11524.
2026-05-02 12:43:40 +02:00
John MacFarlane 672e745839 LaTeX reader: put identifier from label on table attributes...
rather than adding an enclosing Div.

Closes #11604.
2026-05-01 00:15:40 +02:00
John MacFarlane f74179a5d8 Typst reader: Fix issue parsing figure inside rotate or box.
Closes #11598.
2026-04-24 10:55:52 +02:00
John MacFarlane c15e062867 Markdown reader: allow spaces inside attributes in super/sub.
Closes #11589.
2026-04-18 23:19:15 +02:00
John MacFarlane aa571d2c41 Add --typst-input CLI option.
This allows one to pass parameters to typst, which are available
at `sys.inputs`, just as `typst` itself does with its `--input`
option.

[API changes]

* ReaderOptions has a new field `readerTypstInputs`.
* Opt has a new field `optTypstInputs`.

Closes #11588.
2026-04-18 13:05:35 +02:00
John MacFarlane 38a23550bb Typst writer: newline after #set text directive.
This ensures that blocks such as lists are parsed correctly
after a `set text`.

Closes #11583.
2026-04-15 22:25:11 +02:00
John MacFarlane 3fc374908c Docx reader: don't look to ext tags for image extent.
This was added in 7ff1b798c4
but was mistaken and could cause images to be parsed with
the wrong sizes.

Closes  #11580.
2026-04-13 12:04:02 +02:00
John MacFarlane 381b82e4a3 Docx writer: fix FirstParagraph style lost after heading with footnote.
When a heading contained a footnote, processing the footnote's block
content would consume the stFirstPara flag, causing the following
paragraph to incorrectly receive BodyText style instead of
FirstParagraph. Fix by saving and restoring stFirstPara around
footnote block processing.

Closes #11573.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-09 21:13:28 +00:00
John MacFarlane a6486391e1 Markdown writer: escape ::: to avoid triggering unintended divs.
Closes #11571.
2026-04-09 10:51:15 +02:00
John MacFarlane 134296c541 Fix test suite parallel execution failures.
MediaBag test used `inDirectory` (which calls `setCurrentDirectory`),
changing the process-wide CWD and causing other parallel tests
to fail with "does not exist" errors on relative paths.
Replace with absolute paths so the test no longer changes CWD.

Closes #11566.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-07 11:18:49 +02:00
John MacFarlane 7aca987b95 MediaWiki writer: handle some technically malformed URLs.
E.g. `http://example.com/#/#room` and `http://example.com/##`. Closes #11562.
2026-04-04 15:27:01 -04:00
John MacFarlane df61b8b1a9 MediaWiki writer: fix escaping to avoid lists.
For paragraphs beginning with literal `#`, `*`, or other things
that would otherwise produce lists, we insert `<nowiki></nowiki>`
rather than (as previously) `\`. `\` does not work to escape
these.

Closes #11563.
2026-04-04 15:12:23 -04:00
John MacFarlane 7777de6adb BibLaTeX inbook should be CSL book, not chapter.
Closes #11552.
2026-03-27 23:56:08 -04:00
John MacFarlane fcd8eae940 Man writer: don't run together successive definitions...
in a tight definition list with multiple definitions
after a term. Closes #11547.
2026-03-22 15:41:37 +01:00
John MacFarlane 397fef7900 LaTeX template: Define \xmpquote if not defined.
`\xmpquote` is defined by the hyperref driver hyperxmp; we need a
fallback for those who aren't using that.

Closes #11528.
2026-03-22 10:36:15 +01:00
John MacFarlane 8ce63ffe28 Mardkown writer: fix spacing issues with definition lists.
- Properly handle the case where the first item is an indented
  code block.  (Closes #11542.)
- Use correct indentation when `four_space_rule` extension is
  disabled.
2026-03-20 11:39:01 +01:00
John MacFarlane 3769d0cbf4 Typst template: fix regression introduced in 3.9.0.1.
This introduced a bug that will produce the error message
`the character `#` is not valid in code`.

Closes #11538.
2026-03-19 09:17:46 +01:00
John MacFarlane ef6b669e25 Markdown reader: Fix bug with lists_without_preceding_blankline.
This was not properly implemented, causing some unintended
results. Closes #11534.
2026-03-17 19:37:08 +01:00
John MacFarlane 4fbe52f4c1 Update typst tests for template change. 2026-03-17 11:00:39 +01:00
John MacFarlane bf45205b8a Update typst test for math changes. 2026-03-15 18:12:01 +01:00
John MacFarlane c8ee9dc545 Docx reader: preserve non-textbox content when unwrapping textboxes.
Previously, when a w:p paragraph contained runs with textboxes,
the entire paragraph was replaced by just the textbox content,
discarding all other runs (including image-bearing runs).
Now we walk the paragraph's children in order, grouping
non-textbox content into copies of the original w:p and splicing
unwrapped textbox content in place, preserving the original order.

We also treat text inside a textbox containing an image as a
figure caption.  (One often finds captioned images of this
kind in docx files.)

Closes #11510.
Closes #6893.
Closes #11412.
Closes #5394.
Closes #9633.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-14 20:12:34 +00:00