Skip to content

fix: preserve inline formatting in promoted document titles - #20

Merged
leonardosalasd merged 2 commits into
leonardosalasd:mainfrom
biggdawg320:codex/markdown-title-formatting
Sep 10, 2026
Merged

leonardosalasd merged 2 commits into
leonardosalasd:mainfrom
biggdawg320:codex/markdown-title-formatting

Conversation

@biggdawg320

Copy link
Copy Markdown
Contributor

Closes #17.

The first H1 is promoted into the template title and removed from the body. Previously, # **Document Title** therefore displayed literal Markdown markers, even though ordinary body headings rendered correctly.

Parse the promoted title into plain text for PDF metadata and rendered inline content for display in all seven built-in templates. Bold, italic, nested emphasis, inline code, and escaped literal characters are covered. Explicit CLI/front-matter title overrides remain literal strings. Custom .typ templates retain the existing string-only title contract and receive the cleaned title, without a new required argument.

Validation:

  • Reproduced the plain-title regression before the fix.
  • 237 tests pass on both Python 3.10 and Python 3.12, including new converter/CLI regression tests and a real compilation using a custom template without an options sink.
  • Ruff lint and formatting checks pass; git diff whitespace check passes.
  • Compiled all seven built-in templates with bold/italic titles and checked PDF text and metadata. Visually checked the minimal template, and verified an end-to-end CLI-generated PDF.

Prepared and validated with OpenAI Codex under the account owner's direction.

@leonardosalasd

Copy link
Copy Markdown
Owner

Thanks — the shape of this is right. A plain string for set document and the PDF metadata, content for display, and custom .typ templates left on the old contract so nothing outside this repo breaks. I checked that the seven templates compile, that the .typ gate matches what template_path does, and that explicit --title and front-matter titles stay literal.

Two things I would like changed.

Parse the title with the same pipeline as the body. _title_tokens builds a bare mistune.InlineParser(), but convert_document parses with plugins=[*_PLUGINS, _math_plugin]. So a promoted title diverges from an ordinary heading:

# ~~struck~~ title     title: \~\~struck\~\~     body: #strike[struck]
# The $x^2$ theorem    title: The \$x^2\$        body: The $x^2$

Citations are in the same boat, since _CITATION only runs over the body. Your docstring says "through the same inline renderer as body headings", and I agree with that goal — it needs the same plugin set to actually get there.

Keep the running header plain. let title = if title_content == none { title } else { title_content } sits above the header definition, so it rebinds the title everywhere, not only on the cover. A document titled # **Reporte** de *Cobertura* con `flags` now gets a running header carrying bold, italics and a code box across every page. I would rather the formatting show up on the cover only: use title_content at the cover site and leave title as the string.

Related, and this one is mine rather than yours: inline code in a title renders at the 9pt hard-coded in show raw.where(block: false), so it comes out tiny against a 38pt cover title. If you would rather not touch the templates, say so and I will handle it separately.

One note that is not a change request. test_nested_formatting only holds on mistune 3.3 and newer. On 3.2.1, which mistune>=3.0 still allows, the inline parser returns literal text tokens and the assertion fails — I hit it before I matched what CI installs. CI is green because it resolves the newest. The floor is too low, and that is mine to fix.

@leonardosalasd leonardosalasd left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the comment above⠀

@biggdawg320

Copy link
Copy Markdown
Contributor Author

Addressed in 490d749. Title extraction now shares the body parser/plugin configuration and rendering/citation post-processing, including document reference-link definitions. Added regression coverage for strike, math, citations, plain metadata and reference links.

The templates keep title as the metadata/header string and use separate content at the cover/title-block site. I also took the cover inline-code sizing fix: it captures the surrounding title size before raw scaling, without changing body code styling.

Validation: all 240 tests pass on Python 3.10 and 3.12; Ruff lint/format and whitespace checks pass. Compiled all seven templates with strike/math/citation titles and a bibliography. For each template, compared running-header text/font/size/style against a plain-title PDF, checked metadata, verified cover code matches the title size, and confirmed body code stays small. Visually checked the academic cover and running header.

The dependency floor is unchanged, as you noted that you are handling it. Thanks for the concrete review examples.

@leonardosalasd
leonardosalasd merged commit 6fa35dc into leonardosalasd:main Sep 10, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

inline markdown (bold/italic) in headings renders as raw asterisks

2 participants