1.0.0 config redesign, docs rewrite, and demo tooling - #75
Conversation
Config (breaking — wiki admins using these must update LocalSettings.php):
- SmjDirectMathJax ('full'/'env'/'none') -> SmjDirectMath
{enabled, inlineMath, displayMath}, merging what was three separate
globals (SmjDirectMathJax/SmjDisplayMath/SmjExtraInlineMath) into one
- SmjWrapDisplaystyle -> SmjDisplaystyle
- SmjConfigByRevision -> SmjRevisionOverrides (and its per-entry
upto/since keys -> max/min, now supporting dotted paths like
"SmjDirectMath.enabled")
- SmjUseChem dropped: <chem> is always enabled (it was never a rendering
behavior switch, just gated whether the tag was registered at all)
- SmjEnableHtmlAttributes -> SmjEnableRenderAttributes, now gating only
SimpleMathJax's own display=/inline-block attributes; a new
SmjAllowedAttributes replaces the previous fixed
class/id/title/lang/dir allowlist for generic HTML attribute passthrough
Rendering features:
- display="linebreak": same block layout as display="block", but also
turns on MathJax's automatic line-breaking (chtml.displayOverflow,
a MathJax 4+ feature — see the prior MathJax v4 upgrade) for equations
wider than their container
- <math chem> and <chem> now set the smjPreloadChem JS config var (was
wgSmjPreloadChem) to preload the mhchem package, independent of
$wgSmjEnableRenderAttributes since it's a load-time optimization, not
a rendering-behavior switch
- inline-block and display can no longer both be set on the same <math>
(returns a texerror instead of silently picking one)
README's config table and usage docs are updated to match (rewritten to
match what's already in the eventual full docs rewrite, so a later PR
adding docs/config.md etc. doesn't need to touch README's config section
again) — main would otherwise document config variables that no longer
exist for however long it takes to merge the follow-up docs PR.
Version bump to 1.0.0 in extension.json reflects the breaking config
surface. Adds tests/RevisionOverridesTest.php covering mergeDirectMath()
and applyRevisionOverrides() (dotted-path overrides, min/max ranges).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
- README.md rewritten for the new config surface and features - docs/config.md: full config reference; docs/demos.yaml: demo page definitions for hack/demo/demo.sh - docs/screenshots/: reference screenshots for the README and config docs - hack/mathjax.sh: pins the resources/MathJax submodule to a tag (make mathjax MATHJAX_VERSION=x.y.z) - hack/demo/: spins up a throwaway local wiki to screenshot/demo config combinations (make screenshots) - Makefile: adds the mathjax/screenshots targets now that the scripts they call exist. Scopes the catch-all pattern rule (which swallows the extra word in `make screenshots directMath`) to only fire when `screenshots` is actually one of the invoked goals, so a typo like `make cheks` still fails with "No rule to make target" instead of silently no-op'ing. Co-Authored-By: Claude Sonnet 5 <[email protected]>
- Hooks.php: drop the PHPCS-flagged @preg_match() suppression and pick a
safe regex delimiter for $wgSmjIgnoreHtmlClass instead of assuming '~'
never appears in it; fix <chem> exposing its internal \ce{} wrapper
(instead of the editor's original TeX) when ignored via
$wgSmjIgnoreHtmlClass, by moving the wrapping after the ignore check.
- render.php: fail loudly with a clear error on an unknown demo name
instead of silently producing an empty settings/examples block; lay
out examples in a two-column CSS layout with a rule between columns,
and keep each example's wikitext to as few lines as possible so
addDiffShot screenshots stay short.
- demo.sh: seed a dedicated "Demo" page instead of overwriting Main
Page, blanking it first so addDiffShot always captures a real
two-column diff (not a "page creation" summary, and not diffed
against the installer's own unrelated default content); fix the
default demo name and usage examples that no longer matched
demos.yaml/Makefile after prior renames.
- demos.yaml: rename demos to default01/02, custom01/02; add inline
comments illustrating $wgSmjIgnoreHtmlClass's trade-offs (including a
deliberate "don't" example showing bare-delimiter math leaking into
diffs when the default pattern is overwritten).
- docs/configuration.md: rewrite the $wgSmjIgnoreHtmlClass section to
fix a description that contradicted itself (its always-on per-element
skip vs. its diff/comment protection, which only matters with
$wgSmjExtraDelimiters enabled) and a wrong claim that the `chem`
attribute behaves like <chem>...</chem>; general accuracy and
readability passes (chem attribute, extra delimiters, scale,
revision overrides, code-fence formatting) verified against the
actual code and MediaWiki's own Math extension docs where relevant.
- Remove an unused debug script (hack/demo/test_pre_fix.mjs).
- Regenerate docs/screenshots/ to match the above.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
git diff --check origin/main failed on a stray blank line at EOF. Co-Authored-By: Claude Fable 5.1 <[email protected]>
…k line
- Flatten the two array-shaped settings into plain globals, matching
every other $wgSmj* setting and common MediaWiki extension convention
(e.g. Cite's extension.json has no array-valued config at all):
$wgSmjCdn['enabled']/['version']
-> $wgSmjCdnEnabled / $wgSmjCdnVersion
$wgSmjExtraDelimiters['enabled']/['inlineMath']/['displayMath']
-> $wgSmjExtraDelimitersEnabled / ...InlineMath / ...DisplayMath
This removes the partial-override footgun entirely (previously,
`$wgSmjCdn = [ 'version' => '4.1.3' ]` silently dropped 'enabled' and
disabled the CDN) along with the hand-rolled merge functions and the
$wgSmjRevisionOverrides dot-path mechanism that existed only to reach
into these two array settings — both gone now that every setting is a
top-level key.
- Update extension.json, Hooks.php, ext.SimpleMathJax.js,
RevisionOverridesTest.php, demos.yaml, README.md, and
docs/{configuration,mig-1.0}.md accordingly; regenerate the affected
demo screenshots.
- docs/configuration.md: move the `chem` attribute's behavior (preloads
mhchem but doesn't auto-wrap in \ce{}, unlike <chem>) and the
'[math][/math]' internal-marker note out to docs/displaystyle.md and
docs/development.md respectively, and tighten the $wgSmjIgnoreHtmlClass
and $wgSmjRevisionOverrides sections (value-then-explanation ordering
where the value is simple enough to read at a glance, symmetric
Don't/Do examples that both actually demonstrate their claim).
- Trim a trailing blank line docs/configuration.md that made
`git diff --check origin/main` fail.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
… shape
The sed pattern still matched the old "value": { "enabled": true,
"version": ... } array shape, which no longer exists after flattening
into /. It silently matched
nothing while still printing a success message, so a local MathJax bump
could end up paired with a stale, unchanged CDN version.
Update the pattern for the new SmjCdnVersion: { "value": "..." }
shape, and fail loudly beforehand if that key's value can't be found at
all, so a future extension.json reshape breaks loudly here too instead
of silently no-op'ing again.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Recurring "No license specified" warning in review checks. The extension itself is MIT (see extension.json's license-name), so match that here. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Local MathJax (a git submodule tag) and the CDN MathJax version ($wgSmjCdnVersion's default in extension.json) are two independent settings that don't need to move together, so pinning both from one command with two positional args was more confusing than convenient — and it's what motivated hack/mathjax.sh's fragile manifest sed in the first place. - Rename hack/mathjax.sh -> hack/local-mathjax.sh, now taking just the local version and updating only the submodule. Drop the extension.json sed entirely. - Rename the `mathjax` Make target -> `local-mathjax`, and MATHJAX_VERSION_LOCAL/MATHJAX_VERSION_CDN -> LOCAL_MATHJAX_VERSION (the CDN one is gone; there's nothing left for it to configure). - To change the CDN default, edit extension.json's SmjCdnVersion.value directly, the same as any other config default. - Update docs/development.md and docs/configuration.md accordingly. No prior release used the old `make mathjax`/hack/mathjax.sh names, so this is a plain rename with no compatibility alias. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Shorter without colliding with the old pre-1.0.0 $wgSmjExtraInlineMath
name (which $wgSmjDelimitersInlineMath doesn't, unlike alternatives
that kept the 'Extra' + bare 'InlineMath'/'DisplayMath' combination).
All three keep the same $wgSmjDelimiters* prefix for grouping.
Updates extension.json, Hooks.php, ext.SimpleMathJax.js,
RevisionOverridesTest.php, demos.yaml, README.md, and
docs/{configuration,mig-1.0,development}.md; regenerates the affected
demo screenshots.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Leftover from the $wgSmjExtraDelimitersEnabled -> $wgSmjDelimitersEnabled rename; the heading's own anchor changed but this cross-reference didn't. Co-Authored-By: Claude Fable 5.1 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 110282ce0a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // An ignored element is never typeset, so it skips smj-container and | ||
| // the delimiter wrapping instead of showing them as literal text. | ||
| $isIgnored = self::$ignoreHtmlClass !== '' | ||
| && self::matchesIgnoreHtmlClass( self::$ignoreHtmlClass, $attributes["class"] ); |
There was a problem hiding this comment.
Anchor ignore patterns to complete class names
When class passthrough is enabled, this raw preg_match() treats the configured alternatives as substrings, so classes such as commentary, diff-contextual, or notmathjax_ignoreable match the default pattern and cause the formula to be emitted as untypeset text. MathJax's ignoreHtmlClass semantics apply the pattern to complete space-delimited class names, so wrap the fragment with equivalent class-token boundaries here.
Useful? React with 👍 / 👎.
| $isIgnored = self::$ignoreHtmlClass !== '' | ||
| && self::matchesIgnoreHtmlClass( self::$ignoreHtmlClass, $attributes["class"] ); | ||
| if ( $isIgnored ) { | ||
| unset( $attributes["style"] ); |
There was a problem hiding this comment.
Preserve allowed styles on ignored formulas
If an administrator includes style and class in $wgSmjAllowedAttributes and an editor uses both a matching ignore class and a style, this removes the sanitized editor-supplied style along with the placeholder opacity. For example, <math class="mathjax_ignore" style="color:red">...</math> loses color:red, contradicting the allow-list's passthrough behavior; remove only the extension's temporary opacity rather than unsetting the entire attribute.
Useful? React with 👍 / 👎.
| selection. Normal extension packages already include the bundled MathJax | ||
| resources and do not require Git commands. |
There was a problem hiding this comment.
Do not promise MathJax files in source packages
The repository stores resources/MathJax only as a gitlink, while the release workflow merely invokes gh release create and uploads no archive containing initialized submodule contents. Consequently, users of the generated GitHub source packages who follow this paragraph and set $wgSmjCdnEnabled = false will not have resources/MathJax/tex-chtml.js and local rendering will fail; either package the submodule contents or instruct package users to obtain them.
Useful? React with 👍 / 👎.
Summary
Redesigns every
$wgSmj*setting for 1.0.0 (flat globals throughout, noarray-shaped settings), rewrites the configuration/migration docs against
the actual code, reworks the local demo tooling, and fixes several
correctness bugs found along the way. See
docs/mig-1.0.mdfor the fullupgrade guide — this is a breaking config change with no backward
compatibility for admins upgrading from before 1.0.0.
Config changes
$wgSmj*global — no array-shaped settings,no dot-path overrides.
$wgSmjCdn/$wgSmjExtraDelimiters(brieflyarray-shaped) are split into
$wgSmjCdnEnabled/$wgSmjCdnVersionand$wgSmjDelimitersEnabled/$wgSmjDelimitersInlineMath/$wgSmjDelimitersDisplayMath.$wgSmjDirectMathJax/$wgSmjDisplayMath/$wgSmjExtraInlineMathmergeinto the three
$wgSmjDelimiters*settings above; the'full'/'env'/'none'three-way mode collapses into a boolean.
$wgSmjUseCdn→$wgSmjCdnEnabled;$wgSmjConfigByRevision→$wgSmjRevisionOverrides(itsupto/sincekeys →max/min).$wgSmjEnableHtmlAttributes→$wgSmjAllowedAttributes, an explicitattribute allow-list instead of an on/off switch.
$wgSmjUseChemremoved —<chem>is always registered.Bug fixes found while writing the docs
Hooks.php: dropped a PHPCS-flagged@preg_match()suppression and aregex-delimiter collision in
$wgSmjIgnoreHtmlClassmatching.Hooks.php: an ignored<chem class="mathjax_ignore">showed itsinternal
\ce{...}wrapper instead of the editor's original TeX.hack/demo/render.php: an unknown demo name silently produced an emptypage instead of failing.
hack/mathjax.sh→hack/local-mathjax.sh: the CDN-versionsedmatchedonly the old array-shaped manifest entry and silently no-op'd against the
new flat one while still printing success. Split into a local-only
script/make-target; the CDN default is edited directly in
extension.jsonlike any other setting now.composer.json: added the missinglicensefield.Docs and demo tooling
docs/configuration.md: full rewrite, verified against the actual code(and MediaWiki's own Math extension docs for the
chem/<math>overlap).docs/mig-1.0.md: step-by-step upgrade guide from pre-1.0.0.docs/development.md,docs/displaystyle.md: new — internals notes and<math>display-mode reference.hack/demo/: demos renamed/reorganized,demo.shseeds a dedicated"Demo" page (blanked first, so
addDiffShotcaptures a real diff) insteadof overwriting Main Page, and
docs/screenshots/regenerated to match.Verification
make checks(parallel-lint, minus-x, phpcs, unit tests) passes.git diff --checkagainstorigin/mainpasses.confirm actual rendered behavior, not just the code reading right.
🤖 Generated with Claude Code