diff options
| author | LalleSX | 2026-10-24 14:18:00 +0200 |
|---|---|---|
| committer | LalleSX | 2026-10-24 14:18:00 +0200 |
| commit | 389fb3a592832092835da0c2cc1608a57ba5f629 (patch) | |
| tree | ad1f89333ec3c84b906fb6546cee7824f58236fa /src/math.ts | |
| parent | init (diff) | |
| download | 3D-Electrophysics-389fb3a592832092835da0c2cc1608a57ba5f629.tar.gz 3D-Electrophysics-389fb3a592832092835da0c2cc1608a57ba5f629.zip | |
Add tests for math rendering and interactive scenes; update navigation and viewport handling
- Updated `lab.spec.ts` to navigate directly to the field lesson.
- Created `math.spec.ts` with tests for math rendering, error checking, and responsive design.
- Added `test4.spec.ts` for interactive scenes, ensuring all questions are functional and accessible.
- Modified `vite.config.ts` to keep original question/answer links navigable in production.
Diffstat (limited to 'src/math.ts')
| -rw-r--r-- | src/math.ts | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/math.ts b/src/math.ts new file mode 100644 index 0000000..71403f4 --- /dev/null +++ b/src/math.ts @@ -0,0 +1,42 @@ +import katex from 'katex'; +import 'katex/dist/katex.min.css'; + +const options = { output: 'htmlAndMathml', throwOnError: false, strict: 'error', trust: false } as const; + +/** Render authored TeX with bundled fonts and a MathML equivalent for assistive technology. */ +export function renderEquation(element: HTMLElement, tex: string) { + element.classList.add('math-display'); + element.tabIndex = 0; // Long equations can be scrolled with the keyboard on narrow screens. + katex.render(tex, element, { ...options, displayMode: true }); +} + +/** Plain prose with explicit $...$ inline math; everything outside delimiters stays text. */ +export function renderProse(element: HTMLElement, text: string) { + element.replaceChildren(); + let offset = 0; + for (const match of text.matchAll(/\$([^$\n]+)\$/g)) { + element.append(document.createTextNode(text.slice(offset, match.index))); + const math = document.createElement('span'); + katex.render(match[1], math, { ...options, displayMode: false }); + element.append(math); + offset = match.index + match[0].length; + } + element.append(document.createTextNode(text.slice(offset))); +} + +// Short UI labels retain their plain accessible names while sharing the lesson notation. +const notation: Record<string, string> = { + 'log₁₀(N / m⁻³)': String.raw`\log_{10}(N/\mathrm m^{-3})`, + 'EF − Ei': 'E_F-E_i', 'U₁₂₃': 'U_{123}', 'ΔU₀': String.raw`\Delta U_0`, + 'K + U': 'K+U', 'q₀': 'q_0', 'q₁': 'q_1', 'q₂': 'q_2', 'q₃': 'q_3', + 'Uₐ': 'U_a', 'Uᵦ': 'U_b', 'Kₐ': 'K_a', 'rₐ': 'r_a', 'rᵦ': 'r_b', + 'θₐ': String.raw`\theta_a`, 'θᵦ': String.raw`\theta_b`, 'τz': String.raw`\tau_z`, + '|Q|': '|Q|', '|P|': '|P|', '|E|': String.raw`|\vec E|`, 'Ex': 'E_x', + 'Δx': String.raw`\Delta x`, 'θ': String.raw`\theta`, 'α': String.raw`\alpha`, + 'κ': String.raw`\kappa`, 'σ': String.raw`\sigma`, '90°': String.raw`90^\circ`, +}; +const notationPattern = new RegExp(Object.keys(notation).sort((a, b) => b.length - a.length).map(key => key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') + '|\\b[EqdnpUVK]\\b', 'g'); + +export function renderNotation(element: HTMLElement, text: string) { + renderProse(element, text.replace(notationPattern, token => `$${notation[token] ?? token}$`)); +} |