Skip to content

🐛 FIX: topmatter config merging, and source lines in included files#1169

Draft
chrisjsewell wants to merge 2 commits into
masterfrom
claude/myst-parser-triage-u28jxh
Draft

🐛 FIX: topmatter config merging, and source lines in included files#1169
chrisjsewell wants to merge 2 commits into
masterfrom
claude/myst-parser-triage-u28jxh

Conversation

@chrisjsewell

Copy link
Copy Markdown
Member

Two independent fixes. Closes #1165, closes #1167.

⚠️ One judgment call for review first

Enforcing global_only in topmatter (below) removes two undocumented but previously functioning behaviours, found by the review's old-vs-new probes:

  • inventories in topmatter worked per-document in docutils-standalone (inv: links resolved against it). Now: a myst.topmatter warning and the field is ignored (the documented routes — docutils.conf myst-inventories, CLI flag — are unaffected). Sphinx was never affected (intersphinx).
  • update_mathjax: false in topmatter half-worked under sphinx (suppressed the tex2jax_ignore classes on that page, though never the MathJax config override). Now warned-and-ignored.

Both fields are already marked global-only in the generated configuration docs, the break is loud rather than silent, and blessing them as per-document would create sphinx/docutils divergence — so this PR enforces. If you'd rather deprecate first (apply + warn "will be ignored in future"), that's a two-line change; say the word. Note also that any document carrying a global-only key in topmatter now emits a warning where it was previously silent, so strict (-W) builds may surface them (suppressible via myst.topmatter).

Topmatter config merging (#1167)

merge_file_level re-assigned the raw topmatter value after validation, clobbering values that converting validators had set:

  • heading_slug_func: github in topmatter crashed at every heading ('str' object is not callable) — now it warns once as global-only.
  • enable_extensions survived as a raw list instead of the validated set; url_schemes in list form crashed the publish outright, and its dict form skipped URL templating (raw refuri="wiki:Hobbit"). All now keep their validated/converted values.

Fields with global_only metadata are rejected in topmatter with a warning naming the field; everything else keeps the validator's converted value via a before/after identity check (with a documented contract note for future validator authors).

Source lines in included files (#1165)

Every warning inside an {include}d markdown file was attributed one line too low (startline + 1 double-counted the renderer's 0-based→1-based conversion). Also fixed while there: start-after advanced the offset by characters rather than lines, and negative start-line passed through unresolved. All shapes now map exactly — plain, start-line (including negative), start-after (including a multi-line marker and marker-at-EOF), combined with end-before, and nested includes — with mock_include_errors.md's regenerated expectation hand-verified against the included file. The :literal:/:code: branches are untouched (docutils line parity from #1164 preserved).

Review

Adversarial + behavior-regression pass with old-vs-new probes against master: a 7-page sphinx include-project renders byte-identical HTML with only line-number corrections in warnings/gettext locations (each hand-verified against the physical file); all five global-only fields probed individually in both docutils and sphinx paths (results above); adversarial include options (negative/beyond-EOF start-line, CRLF, multi-line markers) crash-free with exact lines. Two pre-existing items noted, not touched: sphinx console warnings show the parent page's path with the included file's line (location=(env.docname, line) — warning-taxonomy territory), and a few other nested_render_text callers share the same off-by-one family (substitutions already carry a TODO).

Full suite: 1247 passed.


Generated by Claude Code

Two fixes:

- `merge_file_level` re-assigned the raw topmatter value after
  validation, clobbering values set by converting validators - most
  visibly, a `heading_slug_func` preset name crashed at every heading
  with "'str' object is not callable", and `enable_extensions` survived
  as a raw list instead of a set. Validated values are now kept, and
  fields marked global-only are rejected in topmatter with a
  `myst.topmatter` warning instead of being silently (mis)applied.

- every warning inside an `{include}`d markdown file was attributed one
  line too low: the include directive passed `startline + 1` to the
  nested renderer, double-counting its 0-based to 1-based conversion.
  Additionally `start-after` advanced the line offset by *characters*
  rather than lines, and a negative `start-line` was passed through
  unresolved; both now map exactly.

Closes #1165, closes #1167
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant