wiki-formant 0.82.0 → 0.83.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/base.css +3 -1
- package/dist/react.d.ts +10 -2
- package/dist/react.js +29 -2
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -698,7 +698,7 @@ const off = onTweetResize((h, source) => sizeTweetEmbed(el, h, source));
|
|
|
698
698
|
|
|
699
699
|
`addCopyButton` was **byte-identical** in two BlockRenderers, down to the SVG path data. Its idempotence guard now lives inside the function rather than in a `pre:not(:has(…))` at the call site, where it can be — and was — retyped.
|
|
700
700
|
|
|
701
|
-
In React, `useArticlePasses(ref, [blocks])` (`wiki-formant/react`) runs them all, the embed pair included. Three renderers had the effect written out and disagreed on its dependencies: two ran once on mount, so a page swapped in without a remount kept its old tables unsortable.
|
|
701
|
+
In React, `useArticlePasses(ref, [blocks])` (`wiki-formant/react`) runs them all, the embed pair included, and typesets maths: `renderMath` (also `wiki-formant/react`, since its stylesheet import cannot sit in a module server code reaches) sets `$$…$$` and `\[…\]` as a display and `\(…\)` inline. KaTeX is an optional peer: an app installs `katex`, and a page with no delimiter never fetches it. There is no single-`$` delimiter, since prose writes $XRD. Three renderers had the effect written out and disagreed on its dependencies: two ran once on mount, so a page swapped in without a remount kept its old tables unsortable.
|
|
702
702
|
|
|
703
703
|
`activateTabGroups` turns stored `[data-tabs]` markup into a working tab group. The editor persists tabs as nested divs, which is the right thing to store — it survives a markdown twin, a plain HTML render and a reader with JavaScript off, all of which show every tab in order. Making one of them pressable is a reader-side job, and it sits beside the other passes rather than inside a component.
|
|
704
704
|
|
package/dist/base.css
CHANGED
|
@@ -200,7 +200,6 @@ html[data-sidebar='closed'] .wiki-sidebar { width: 0; }
|
|
|
200
200
|
.tabs-editor .tab-button { display: inline-flex; align-items: center; padding: 0.15em 0.3em; border-bottom: 0; border-radius: 0.3rem; }
|
|
201
201
|
.tabs-editor .tab-button.active { background: color-mix(in srgb, currentColor 10%, transparent); }
|
|
202
202
|
.tab-title { width: 7em; outline: none; }
|
|
203
|
-
.tab-remove, .tab-add { opacity: 0.7; }
|
|
204
203
|
.tabs-content { padding: 1rem; }
|
|
205
204
|
.tabs-editor [data-tab-item] { display: none; }
|
|
206
205
|
[data-tabs][data-active-tab='0'] .tabs-editor [data-tab-item]:nth-of-type(1),
|
|
@@ -212,6 +211,9 @@ html[data-sidebar='closed'] .wiki-sidebar { width: 0; }
|
|
|
212
211
|
[data-tabs][data-active-tab='6'] .tabs-editor [data-tab-item]:nth-of-type(7),
|
|
213
212
|
[data-tabs][data-active-tab='7'] .tabs-editor [data-tab-item]:nth-of-type(8) { display: block; }
|
|
214
213
|
|
|
214
|
+
/* ---- maths (renderMath): a display wider than its column scrolls rather than spilling. */
|
|
215
|
+
.katex-display { overflow-x: auto; overflow-y: hidden; }
|
|
216
|
+
|
|
215
217
|
/* ---- one-line fields (WikiLine) --------------------------------------------- */
|
|
216
218
|
[data-wiki-line] { outline: none; cursor: text; white-space: pre-wrap; }
|
|
217
219
|
[data-wiki-line]:is(:empty, :has(> .ProseMirror-trailingBreak))::before { content: attr(data-placeholder); opacity: 0.6; }
|
package/dist/react.d.ts
CHANGED
|
@@ -477,10 +477,18 @@ export declare function RailShell({ children, prefix, label, className }: RailSh
|
|
|
477
477
|
*/
|
|
478
478
|
export declare function isRailLinkActive(activePath: string, href: string, tree?: boolean): boolean;
|
|
479
479
|
export type { WikiLinkComponent, WikiLinkProps } from './react-server.js';
|
|
480
|
+
/**
|
|
481
|
+
* Typeset the maths under `root` with KaTeX: `$$…$$` and `\[…\]` as a display,
|
|
482
|
+
* `\(…\)` inline. KaTeX and its stylesheet load only when the text holds a
|
|
483
|
+
* delimiter, so a page with no maths fetches nothing. KaTeX is an optional peer
|
|
484
|
+
* the app installs. Typeset maths carries no delimiter, so a second pass finds
|
|
485
|
+
* nothing to do.
|
|
486
|
+
*/
|
|
487
|
+
export declare function renderMath(root: HTMLElement): Promise<void>;
|
|
480
488
|
/**
|
|
481
489
|
* The `wiki-formant/dom` passes over a rendered article: tab groups, copy
|
|
482
|
-
* buttons, sortable tables, and each post on X hydrated and kept
|
|
483
|
-
* it posts. All three renderers ran the same passes in an effect, and they
|
|
490
|
+
* buttons, sortable tables, maths typeset, and each post on X hydrated and kept
|
|
491
|
+
* at the height it posts. All three renderers ran the same passes in an effect, and they
|
|
484
492
|
* disagreed on when: two ran it once on mount, so a page swapped in without a
|
|
485
493
|
* remount kept its old tables unsortable. Each pass is idempotent, so running
|
|
486
494
|
* on every `deps` change is safe.
|
package/dist/react.js
CHANGED
|
@@ -880,11 +880,37 @@ const decodePath = (path) => {
|
|
|
880
880
|
return path;
|
|
881
881
|
}
|
|
882
882
|
};
|
|
883
|
+
// ---- maths ------------------------------------------------------------------
|
|
884
|
+
// Here rather than in `dom.ts` because of its stylesheet import: `dom.ts` is
|
|
885
|
+
// reached from server modules (`headings.ts`), and a bundler cannot chunk a
|
|
886
|
+
// CSS import from plain server code. This module is a client one.
|
|
887
|
+
/** What marks maths in stored prose. No single `$`: prose writes $XRD, and two cashtags in one block would read as a formula. */
|
|
888
|
+
const MATH = /\$\$|\\\(|\\\[/;
|
|
889
|
+
/**
|
|
890
|
+
* Typeset the maths under `root` with KaTeX: `$$…$$` and `\[…\]` as a display,
|
|
891
|
+
* `\(…\)` inline. KaTeX and its stylesheet load only when the text holds a
|
|
892
|
+
* delimiter, so a page with no maths fetches nothing. KaTeX is an optional peer
|
|
893
|
+
* the app installs. Typeset maths carries no delimiter, so a second pass finds
|
|
894
|
+
* nothing to do.
|
|
895
|
+
*/
|
|
896
|
+
export async function renderMath(root) {
|
|
897
|
+
if (!MATH.test(root.textContent ?? ''))
|
|
898
|
+
return;
|
|
899
|
+
const [{ default: render }] = await Promise.all([import('katex/contrib/auto-render'), import('katex/dist/katex.min.css')]);
|
|
900
|
+
render(root, {
|
|
901
|
+
delimiters: [
|
|
902
|
+
{ left: '$$', right: '$$', display: true },
|
|
903
|
+
{ left: '\\(', right: '\\)', display: false },
|
|
904
|
+
{ left: '\\[', right: '\\]', display: true },
|
|
905
|
+
],
|
|
906
|
+
throwOnError: false,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
883
909
|
// ---- rendered-article passes --------------------------------------------------
|
|
884
910
|
/**
|
|
885
911
|
* The `wiki-formant/dom` passes over a rendered article: tab groups, copy
|
|
886
|
-
* buttons, sortable tables, and each post on X hydrated and kept
|
|
887
|
-
* it posts. All three renderers ran the same passes in an effect, and they
|
|
912
|
+
* buttons, sortable tables, maths typeset, and each post on X hydrated and kept
|
|
913
|
+
* at the height it posts. All three renderers ran the same passes in an effect, and they
|
|
888
914
|
* disagreed on when: two ran it once on mount, so a page swapped in without a
|
|
889
915
|
* remount kept its old tables unsortable. Each pass is idempotent, so running
|
|
890
916
|
* on every `deps` change is safe.
|
|
@@ -897,6 +923,7 @@ export function useArticlePasses(ref, deps) {
|
|
|
897
923
|
activateTabGroups(root);
|
|
898
924
|
addCopyButtons(root);
|
|
899
925
|
sortTables(root);
|
|
926
|
+
void renderMath(root);
|
|
900
927
|
hydrateTweetEmbeds(root);
|
|
901
928
|
return onTweetResize((height, source) => sizeTweetEmbed(root, height, source));
|
|
902
929
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wiki-formant",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.1",
|
|
4
4
|
"description": "The portable half of a wiki: derived taxonomy and facet controls, a version-negotiating MCP transport, markdown twins, block rendering, a rich-text editor engine, conditional-GET plumbing, and the headers and CSP every origin sends.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -328,12 +328,14 @@
|
|
|
328
328
|
"devDependencies": {
|
|
329
329
|
"@electric-sql/pglite": "^0.3.9",
|
|
330
330
|
"@radixdlt/rola": "^2.1.0",
|
|
331
|
+
"@types/katex": "^0.16.8",
|
|
331
332
|
"@types/node": "^22.0.0",
|
|
332
333
|
"@types/react": "^19.0.0",
|
|
333
334
|
"@types/sanitize-html": "^2.16.1",
|
|
334
335
|
"@vercel/blob": "^2.8.2",
|
|
335
336
|
"jose": "^6.2.12",
|
|
336
337
|
"jsdom": "^30.1.0",
|
|
338
|
+
"katex": "^0.16.47",
|
|
337
339
|
"react": "^19.2.4",
|
|
338
340
|
"sharp": "^0.35.5",
|
|
339
341
|
"typescript": "^5.9.0"
|
|
@@ -344,7 +346,8 @@
|
|
|
344
346
|
"jose": ">=6",
|
|
345
347
|
"pg": ">=8",
|
|
346
348
|
"react": ">=18",
|
|
347
|
-
"sharp": ">=0.33"
|
|
349
|
+
"sharp": ">=0.33",
|
|
350
|
+
"katex": "^0.16.0"
|
|
348
351
|
},
|
|
349
352
|
"peerDependenciesMeta": {
|
|
350
353
|
"react": {
|
|
@@ -364,6 +367,9 @@
|
|
|
364
367
|
},
|
|
365
368
|
"@vercel/blob": {
|
|
366
369
|
"optional": true
|
|
370
|
+
},
|
|
371
|
+
"katex": {
|
|
372
|
+
"optional": true
|
|
367
373
|
}
|
|
368
374
|
}
|
|
369
375
|
}
|