Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,3 @@
Run `make checks` before committing. `test` runs plain PHP scripts
(`php tests/*.php`), not PHPUnit. `phpcs` needs `composer install`, which
`make` does automatically.

`hack/demo/demo.sh` / `make screenshots [demo]` render a demo through a
local Docker MediaWiki and regenerate `docs/screenshots-$MW_VERSION/*.png`
(`MW_VERSION` defaults to `1.43`, e.g. `MW_VERSION=1.45 make screenshots` to
test against a different MediaWiki version). Only run this when asked to,
or when a change affects rendering (`resources/`, `hack/demo/demos.yaml`)
— not for routine changes.
22 changes: 14 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: checks test phpcs local-mathjax screenshots
.PHONY: checks test phpcs local-mathjax screenshots demo down animations

LOCAL_MATHJAX_VERSION ?= 4.1.3

Expand All @@ -18,15 +18,21 @@ local-mathjax: ## Pin the bundled local MathJax submodule, e.g. `make local-math
vendor/autoload.php: composer.json
composer install --no-progress

screenshots: ## Screenshot a demo page, e.g. `make screenshots custom01` (no demo = every demo in hack/demo/demos.yaml); `MW_VERSION=1.45 make screenshots` targets a different mediawiki Docker image tag (default 1.43)
demo: ## Start (or reuse) a local demo wiki at http://localhost:8080 (Admin / demo12345678), e.g. `make demo 1.45`
MW_VERSION=$(or $(filter-out $@,$(MAKECMDGOALS)),1.43) hack/demo/demo.sh up

down: ## Stop the local demo wiki and wipe its data
hack/demo/demo.sh down

screenshots: ## Screenshot a demo page, e.g. `make screenshots custom01` (no demo = every demo)
hack/demo/demo.sh screenshot $(filter-out $@,$(MAKECMDGOALS))

# Swallows the extra word in `make screenshots custom01` so make doesn't
# treat "custom01" as a target of its own and fail with "No rule to make
# target". Scoped to only fire when `screenshots` is actually one of the
# invoked goals, so an unrelated typo like `make cheks` still fails loudly
# instead of silently no-op'ing.
ifneq ($(filter screenshots,$(MAKECMDGOALS)),)
animations: ## Record a VisualEditor insert animation per doc in hack/demo/demo-animations.yaml, e.g. `make animations 1.45`
hack/demo/demo.sh animations $(filter-out $@,$(MAKECMDGOALS))

# Swallows the extra word in `make screenshots custom01` / `make demo 1.45`
# so make doesn't treat it as a target of its own and fail.
ifneq ($(filter screenshots demo animations,$(MAKECMDGOALS)),)
%:
@:
endif
Binary file added docs/animations/1.43/animation-default.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 47 additions & 2 deletions extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "SimpleMathJax",
"version": "1.0.1",
"version": "1.1.0",
"author": "jmnote",
"url": "https://www.mediawiki.org/wiki/Extension:SimpleMathJax",
"description": "render TeX between <code><nowiki><math></nowiki></code> and <code><nowiki></math></nowiki></code>",
Expand Down Expand Up @@ -58,16 +58,61 @@
"ParserFirstCallInit": "MediaWiki\\Extension\\SimpleMathJax\\Hooks::onParserFirstCallInit",
"InternalParseBeforeLinks": "MediaWiki\\Extension\\SimpleMathJax\\Hooks::onInternalParseBeforeLinks"
},
"attributes": {
"VisualEditor": {
"PluginModules": [
"ext.SimpleMathJax.visualEditor"
]
}
},
"MessagesDirs": {
"SimpleMathJax": [
"i18n"
]
},
"ResourceModules": {
"ext.SimpleMathJax": {
"scripts": [
"resources/ext.SimpleMathJax.js"
]
},
"ext.SimpleMathJax.visualEditor": {
"scripts": [
"resources/ve/ve.dm.MWMathNode.js",
"resources/ve/ve.dm.MWChemNode.js",
"resources/ve/ve.ce.MWFormulaNode.js",
"resources/ve/ve.ce.MWMathNode.js",
"resources/ve/ve.ce.MWChemNode.js",
"resources/ve/ve.ui.MWFormulaDialog.js",
"resources/ve/ve.ui.MWMathDialog.js",
"resources/ve/ve.ui.MWChemDialog.js",
"resources/ve/ve.ui.MWMathDialogTool.js",
"resources/ve/ve.ui.MWChemDialogTool.js",
"resources/ve/ve.ui.MWFormulaContextItem.js",
"resources/ve/ve.ui.MWMathContextItem.js",
"resources/ve/ve.ui.MWChemContextItem.js"
],
"styles": [
"resources/ve/ve.ui.MWFormulaDialog.less"
],
"dependencies": [
"ext.visualEditor.mwcore",
"ext.SimpleMathJax"
],
"messages": [
"simplemathjax-visualeditor-mwmathdialog-title",
"simplemathjax-visualeditor-mwchemdialog-title",
"simplemathjax-visualeditor-mwformuladialog-formula",
"simplemathjax-visualeditor-mwformuladialog-display",
"simplemathjax-visualeditor-mwformuladialog-display-default",
"simplemathjax-visualeditor-mwformuladialog-display-inline",
"simplemathjax-visualeditor-mwformuladialog-display-block"
]
}
},
"ResourceFileModulePaths": {
"localBasePath": "",
"remoteExtPath": "SimpleMathJax"
},
"manifest_version": 2
}
}
15 changes: 15 additions & 0 deletions hack/demo/demo-animations.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
mediawiki:
versions:
- 1.43
# - 1.45
viewport:
width: 800
height: 600
docs:
- name: default
content: |
옴(Ohm)의 법칙:
<math display="block">전압 = 전류 \times 저항</math>
Chemical reaction: <chem>H2O + CO2 -> H2CO3</chem>

Mass–energy equivalence: <math>E=mc^2</math>
File renamed without changes.
26 changes: 26 additions & 0 deletions hack/demo/demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Demo tooling

`hack/demo/demo.sh` (driven by the `Makefile` targets below) runs a local
Docker `mediawiki` image + SQLite, with this repo bind-mounted in as the
extension — no MediaWiki core checkout needed. VisualEditor is bundled with
the image, so `?veaction=edit` works too.

- `make demo [version]` / `make down` — start/stop the wiki manually at
`http://localhost:8080` (`Admin` / `demo12345678`), e.g. `make demo 1.45`
to target that MediaWiki version instead of the default `1.43`.

- `make screenshots [demo]` — regenerate `docs/screenshots/$MW_VERSION/*.png`
from `hack/demo/demo-screenshots.yaml` (no `demo` = every demo in that
file). `MW_VERSION=1.45 make screenshots` targets a different MediaWiki
version. Only run this when asked to, or when a change affects rendering
(`resources/`, `demo-screenshots.yaml`) — not for routine changes.

- `make animations [version]` — drives the wiki through VisualEditor's
Insert menu, per doc listed in `hack/demo/demo-animations.yaml`,
inserting each of that doc's formulas then saving, and records
`docs/animations/$MW_VERSION/animation-<name>.gif` per doc.
`make animations 1.45` targets just that version; with none given it
loops over every version in `demo-animations.yaml`'s own
`mediawiki: versions:` list instead of defaulting to one. Only run this
when asked to, or when a change affects `resources/ve/*.js` — not for
routine changes.
141 changes: 85 additions & 56 deletions hack/demo/demo.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
#!/usr/bin/env bash
# Local test wiki: the official `mediawiki` Docker image + SQLite (no
# separate DB container), with this repo bind-mounted in as the extension —
# no MediaWiki core checkout needed. See AGENTS.md.
# Local test wiki: the official `mediawiki` Docker image + SQLite, with this
# repo bind-mounted in as the extension. VisualEditor is also installed
# (bundled with the image) so resources/ve/*.js can be exercised at
# ?veaction=edit.
#
# Usage: hack/demo/demo.sh [up|down] [demo]
# hack/demo/demo.sh screenshot [demo]
# hack/demo/demo.sh animations [version]
# MW_VERSION=1.45 hack/demo/demo.sh screenshot [demo]
# `demo` is a top-level key in hack/demo/demos.yaml (e.g. default01, custom01);
# its capture is saved to docs/screenshots-$MW_VERSION/screenshot-<demo>.png.
# Defaults to `default01`; `screenshot` with no `demo` given screenshots
# every demo in demos.yaml. MW_VERSION selects the `mediawiki` Docker image
# tag to test against (default 1.43) — e.g. to check whether a bug is
# specific to one MediaWiki version.
# `demo` is a top-level key in demo-screenshots.yaml (default: default01);
# `screenshot` with none given screenshots every demo. MW_VERSION selects
# the `mediawiki` Docker image tag (default 1.43). `animations` takes its
# version as a plain argument (like `screenshot`'s demo, not MW_VERSION),
# and with none given loops over demo-animations.yaml's own
# `mediawiki: versions:` list.
set -euo pipefail
DEMO_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$DEMO_DIR/../.."
Expand All @@ -24,7 +26,7 @@ DATA="$PWD/hack/demo/temp"
DOCKER_USER=33:33
PASS=demo12345678
PAGE_TITLE=SimpleMathJax
SCREENSHOT_DIR="$PWD/docs/screenshots-$MW_VERSION"
SCREENSHOT_DIR="$PWD/docs/screenshots/$MW_VERSION"

# Encodes the configured page title for index.php query-string URLs. API
# requests below use curl's --data-urlencode instead.
Expand All @@ -45,34 +47,26 @@ edit_new_revid() {
php -r 'echo json_decode(stream_get_contents(STDIN), true)["edit"]["newrevid"];'
}

# Prints a demo's `settings:` block from docs/demos.yaml — the raw PHP
# Prints a demo's `settings:` block from docs/demo-screenshots.yaml — the raw PHP
# lines appended into LocalSettings.php (see up()) and shown on the demo
# page in a <syntaxhighlight lang="php"> block. See render.php.
local_settings_body() {
php "$DEMO_DIR/render.php" "$DEMO_DIR/demos.yaml" "$1" settings
php "$DEMO_DIR/render.php" "$DEMO_DIR/demo-screenshots.yaml" "$1" settings
}

# Prints a demo's `examples:` list from docs/demos.yaml, each rendered as a
# Prints a demo's `examples:` list from docs/demo-screenshots.yaml, each rendered as a
# syntaxhighlight block next to its live render, in a responsive flex row.
# See render.php.
render_examples() {
php "$DEMO_DIR/render.php" "$DEMO_DIR/demos.yaml" "$1" examples
php "$DEMO_DIR/render.php" "$DEMO_DIR/demo-screenshots.yaml" "$1" examples
}

# Logs in as Admin and edits the configured demo page (not "Main Page", which
# the installer already fills with its own default content) with a small
# demo showing primes inside $...$/$$...$$ surviving wikitext emphasis
# parsing, prefixed with a MediaWiki {{CURRENTVERSION}}/SimpleMathJax
# version line (so a screenshot alone shows what it was captured against —
# useful once screenshots exist for more than one MediaWiki version, see
# MW_VERSION) and the demo's own `settings:` block (wrapped in
# <syntaxhighlight>) for context. Blanks the page first so the demo edit
# always has an empty previous revision to diff against — a real
# two-column diff, not just a "page creation" summary — regardless of how
# many times this runs against the same wiki (see screenshot_one's
# addDiffShot handling). Re-run on every up so editing a demo's entry in
# docs/demos.yaml and re-running `up` (or `screenshot`) always shows the
# latest content.
# Logs in as Admin and edits the configured demo page (not "Main Page") with
# the demo's rendered examples, prefixed with a
# {{CURRENTVERSION}}/SimpleMathJax version line and its `settings:` block.
# Blanks the page first so the edit always has an empty previous revision to
# diff against (see screenshot_one's addDiffShot handling). Re-run on every
# `up` so the page always reflects the latest demo-screenshots.yaml.
seed_demo_page() {
local demo="$1"
local jar url="http://localhost:$PORT/api.php"
Expand Down Expand Up @@ -117,9 +111,8 @@ seed_demo_page() {
}

wait_for_wiki() {
# Main Page, not the configured demo page: it's the installer's own
# default page, so it already exists the moment the wiki responds — unlike
# the demo page, which seed_demo_page hasn't created yet at this point.
# Main Page, not the demo page: it exists as soon as the wiki responds,
# unlike the demo page, which seed_demo_page hasn't created yet.
for _ in $(seq 1 30); do
curl -sf -o /dev/null "http://localhost:$PORT/index.php/Main_Page" && return 0
sleep 1
Expand All @@ -143,7 +136,7 @@ up() {
--dbtype sqlite --dbpath /var/www/html/data \
--scriptpath "" --server "http://localhost:$PORT" \
--pass "$PASS" \
--extensions SyntaxHighlight_GeSHi \
--extensions SyntaxHighlight_GeSHi,VisualEditor \
SimpleMathJax Admin
local_settings_body "$demo" >> "$DATA/LocalSettings.php"
fi
Expand All @@ -158,28 +151,19 @@ up() {
wait_for_wiki && seed_demo_page "$demo"
}

# Stops the container and wipes its data, so the next `up` reinstalls fresh
# (also how you pick up changes to a demo's `settings:` block, which is
# only applied during install).
# Stops the container and wipes its data, so the next `up` reinstalls fresh.
down() {
docker rm -f "$NAME" >/dev/null 2>&1 || true
rm -rf "$DATA"
}

# Screenshots one demo's page with a real browser (Puppeteer); see
# screenshot.mjs. Forces a fresh install (down, then up) so the demo's own
# `settings:` block is guaranteed to be the one in effect, then saves to
# $SCREENSHOT_DIR/screenshot-<demo>.png (docs/screenshots-$MW_VERSION by
# default). A demo with `addRightClickShot: true` (see render.php) gets one
# extra screenshot, screenshot-<demo>-rightclick.png, after right-clicking
# its first mjx-container — needed to show MathJax's context menu, e.g. for
# $wgSmjEnableMenu, since the normal capture never triggers one. A demo with
# `addDiffShot: true` gets a separate extra screenshot,
# screenshot-<demo>-diff.png, of the demo page's diff against the blank
# revision seed_demo_page saves right before its real edit — needed to show
# $wgSmjIgnoreHtmlClass keeping bare-delimiter scanning out of diff views,
# since a diff is a different page/URL entirely, not something a click on
# the normal capture can reveal.
# screenshot.mjs. Forces a fresh install (down, then up), then saves to
# $SCREENSHOT_DIR/screenshot-<demo>.png. `addRightClickShot: true` adds
# screenshot-<demo>-rightclick.png (MathJax's context menu, e.g. for
# $wgSmjEnableMenu). `addDiffShot: true` adds screenshot-<demo>-diff.png,
# the demo page's diff against the blank seed revision (e.g. for
# $wgSmjIgnoreHtmlClass).
screenshot_one() {
local demo="$1"
down
Expand All @@ -189,7 +173,7 @@ screenshot_one() {
( cd "$DEMO_DIR" && npm install )
fi
local right_click=""
if [ "$(php "$DEMO_DIR/render.php" "$DEMO_DIR/demos.yaml" "$demo" addrightclickshot)" = "true" ]; then
if [ "$(php "$DEMO_DIR/render.php" "$DEMO_DIR/demo-screenshots.yaml" "$demo" addrightclickshot)" = "true" ]; then
right_click=mjx-container
fi
mkdir -p "$SCREENSHOT_DIR"
Expand All @@ -201,7 +185,7 @@ screenshot_one() {
RIGHT_CLICK_OUT="$SCREENSHOT_DIR/screenshot-$demo-rightclick.png" \
node screenshot.mjs
)
if [ "$(php "$DEMO_DIR/render.php" "$DEMO_DIR/demos.yaml" "$demo" adddiffshot)" = "true" ]; then
if [ "$(php "$DEMO_DIR/render.php" "$DEMO_DIR/demo-screenshots.yaml" "$demo" adddiffshot)" = "true" ]; then
local revid
revid=$(<"$DATA/last_revid")
(
Expand All @@ -213,29 +197,74 @@ screenshot_one() {
fi
}

# Screenshots every demo in docs/demos.yaml when none is named.
# Screenshots every demo in docs/demo-screenshots.yaml when none is named.
screenshot() {
if [ -n "${1:-}" ]; then
screenshot_one "$1"
return
fi
# Regenerating every demo: clear old captures first so a demo that got
# renamed or removed from demos.yaml doesn't leave a stale screenshot
# behind under its old name.
# Clear old captures first so a renamed/removed demo doesn't leave a
# stale screenshot behind.
mkdir -p "$SCREENSHOT_DIR"
rm -f "$SCREENSHOT_DIR"/screenshot-*.png
local demo
for demo in $(sed -n 's/^- name: //p' "$DEMO_DIR/demos.yaml"); do
for demo in $(sed -n 's/^- name: //p' "$DEMO_DIR/demo-screenshots.yaml"); do
screenshot_one "$demo"
done
}

# demo-animations.yaml's optional top-level `mediawiki: versions:` list,
# consulted only when animations() has no version argument; falls back to
# $MW_VERSION if that block is missing.
animation_versions() {
local versions
versions=$(awk '/^mediawiki:/ { f=1; next } /^[a-zA-Z]/ { f=0 } f' "$DEMO_DIR/demo-animations.yaml" |
sed -n 's/^[[:space:]]*-[[:space:]]*//p')
echo "${versions:-$MW_VERSION}"
}

# Records docs/animations/$MW_VERSION/animation-<name>.gif for each doc in
# demo-animations.yaml: inserting that doc's formulas via VisualEditor's
# Insert menu (see resources/ve/*.js), then saving. Forces a fresh install
# (down, then up).
animations_one() {
IMAGE="mediawiki:$MW_VERSION"
down
up
if [ ! -d "$DEMO_DIR/node_modules" ]; then
echo "==> Installing animation dependencies (npm install)"
( cd "$DEMO_DIR" && npm install )
fi
local animation_dir="$PWD/docs/animations/$MW_VERSION"
mkdir -p "$animation_dir"
(
cd "$DEMO_DIR" &&
URL="http://localhost:$PORT" \
OUT_DIR="$animation_dir" \
node ve_animation.mjs
)
}

# Runs animations_one for a single explicit version (an argument, like
# screenshot's demo), or once per version in animation_versions.
animations() {
if [ -n "${1:-}" ]; then
MW_VERSION="$1" animations_one
return
fi
local v
for v in $(animation_versions); do
MW_VERSION="$v" animations_one
done
}

case "${1:-up}" in
up) up "${2:-}" ;;
down) down ;;
screenshot) screenshot "${2:-}" ;;
animations) animations "${2:-}" ;;
*)
echo "Usage: $0 [up|down] [demo] | $0 screenshot [demo]" >&2
echo "Usage: $0 [up|down] [demo] | $0 screenshot [demo] | $0 animations [version]" >&2
exit 1
;;
esac
Loading
Loading