Skip to content

feat(web): mystmd vertical slice — first-order chapter (MIC-125)#483

Open
mtiller wants to merge 2 commits into
masterfrom
michaeltiller/mic-84-mystmd-vertical-slice
Open

feat(web): mystmd vertical slice — first-order chapter (MIC-125)#483
mtiller wants to merge 2 commits into
masterfrom
michaeltiller/mic-84-mystmd-vertical-slice

Conversation

@mtiller

@mtiller mtiller commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Implements the MIC-84 decision (mystmd) as a one-chapter vertical slice (MIC-125), in a new web/ directory that stands alongside the existing Sphinx/nextgen build without touching it.

What to review

The goal is to validate the pipeline and data contract, not the visual design (default book-theme; Jony's design lands later and is orthogonal).

Working end-to-end (cd web && npm install && npm run build)

  • text/source/behavior/equations/first_order.rstweb/content/first-order.md: prose, headings, cross-refs, admonitions, KaTeX math, and Modelica source via {literalinclude} (:lines: / :emphasize-lines:).
  • Custom {mbe-figure} directive (web/plugins/mbe-figure.mjs) renders all four static plots and replaces the legacy .. plot:: + :class: interactive + nextgen interactiveInjector — which recovered the model id by string-slicing an image src (src.slice(16, src.length-4)). Figures are now backed by the structured contract in web/public/cases/<id>.json.
  • Byte-verified the contract: FO → ModelicaByExample.BasicEquations.SimpleExample.FirstOrder, FOE → …FirstOrderExperiment (matches text/specs.py:13,24).

Deliberately deferred (documented in web/README.md)

  • Interactive island hydration. mystmd's book-theme sanitizes raw HTML (strips data-* / <script>) and doesn't auto-serve public/, so the island can't be drop-injected — it needs a theme component. Groundwork is in place: sanitizer-safe mbe-plot-<id> class marker, the contract JSON, and a ready public/mbe-island.{js,css}. This is being co-designed with Jony (UI/UX).
  • Bulk conversion of the other 91 chapters; i18n (MIC-92); live sim API (MIC-86); final visual design.

Notes

  • Does not modify the existing build or CI; web/ is self-contained.
  • No secrets/API needed to build or preview.

Closes MIC-125.

🤖 Generated with Claude Code

mtiller and others added 2 commits July 1, 2026 12:37
Implements the MIC-84 decision (mystmd) as a one-chapter vertical slice
in a new /web directory, standing alongside the existing Sphinx/nextgen
build without touching it.

Working end-to-end (npm run build → static HTML):
- first_order.rst converted to MyST Markdown (content/first-order.md):
  prose, headings, cross-refs, admonitions, KaTeX math, and Modelica
  source via {literalinclude} (:lines:/:emphasize-lines:).
- Custom {mbe-figure} directive (plugins/mbe-figure.mjs) renders all four
  static plots and replaces the legacy .. plot:: + :class: interactive +
  nextgen interactiveInjector (which recovered the model id by slicing an
  image src). Figures are backed by the structured contract in
  public/cases/<id>.json — the data _generate_casedata already emits.
- Byte-verified: FO -> ...SimpleExample.FirstOrder, FOE -> ...FirstOrderExperiment
  (matches text/specs.py). The new data contract is provably correct.

Deferred (documented in web/README.md):
- Interactive island hydration: mystmd sanitizes raw HTML and doesn't
  auto-serve public/, so it needs a theme-component hook. Groundwork is in
  place (sanitizer-safe mbe-plot-<id> class marker, contract JSON,
  public/mbe-island.{js,css}); paired with Jony's figure-interaction design.
- Bulk chapter conversion, i18n (MIC-92), live sim API (MIC-86), final design.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…path (MIC-125)

Spike outcome (web/SPIKE.md): mystmd sanitizes raw HTML (strips data-* and
<script>) and has no page-script config hook, so the island can't be emitted
from the directive. Two viable mechanisms identified:

  A. Post-build injection (scripts/postbuild.mjs) — copies island assets into
     the built site + injects <link>/<script> after mystmd runs. Demonstrated
     working end-to-end for the static build (assets served, figures carry a
     sanitizer-safe mbe-plot-<id> class, contract fetchable at /cases/<id>.json).
     Caveat: enhancement over a hydrating React app (mounts post-load); no dev.
  B. Custom local theme extending @myst-theme/book with a React renderer for the
     figure node — robust, dev+prod, but means forking/maintaining the theme.

Recommendation: A for the slice/preview now, B for production if dev-mode and
full hydration-safety are required. Skeleton is mechanism-agnostic either way.

Also: editable-param contract per Michael's call — explicit `params` field in
case.json, computed as editable iff variability=='parameter' (parity with the
legacy ParameterPanel categories.parameter). FO/FOE are parameter-free, so
params: [] (correct degenerate case).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant