vantage-md 0.6.1 → 0.7.0
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/CHANGELOG.md +211 -0
- package/README.md +3 -2
- package/dist/index.cjs +210 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1128 -95
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1128 -95
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +205 -32
- package/dist/index.js.map +1 -1
- package/dist/prose.css +1 -1
- package/dist/react.cjs +159 -33
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1021 -56
- package/dist/react.d.cts.map +1 -1
- package/dist/react.d.ts +1021 -56
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +159 -33
- package/dist/react.js.map +1 -1
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -116,14 +116,14 @@ const rehypeSourceLines = (options) => {
|
|
|
116
116
|
* `remark-gfm` does not implement alerts, so until this plugin existed a
|
|
117
117
|
* `> [!WARNING]` rendered as an ordinary blockquote with the literal marker
|
|
118
118
|
* visible as its first words. Worse than merely unstyled: `@tailwindcss/typography`
|
|
119
|
-
*
|
|
119
|
+
* italicizes blockquotes and draws `open-quote`/`close-quote` around the first
|
|
120
120
|
* paragraph, so a callout came out as an italic *quotation* whose opening words
|
|
121
121
|
* were `"[!WARNING]`. That was the "Known gaps" entry in
|
|
122
122
|
* `docs/reference/inline-markup.md` and OQ-10, filed rather than fixed, while
|
|
123
123
|
* `styleGuide.ts` went on telling every agent to write them.
|
|
124
124
|
*
|
|
125
125
|
* The tokens are deliberately the ones the `tone` vocabulary already resolves —
|
|
126
|
-
* an alert *is* the six-
|
|
126
|
+
* an alert *is* the six-color light/dark treatment `tone` shipped, which is
|
|
127
127
|
* exactly what the gap entry said whoever fixed this should do rather than
|
|
128
128
|
* building a second palette. `[!WARNING]` and `<!-- vantage: block tone=warning -->`
|
|
129
129
|
* therefore agree by construction, and adding a theme still touches one
|
|
@@ -137,7 +137,7 @@ const rehypeSourceLines = (options) => {
|
|
|
137
137
|
*
|
|
138
138
|
* ## What it does not do
|
|
139
139
|
*
|
|
140
|
-
* It does not touch a blockquote that carries no marker, and an
|
|
140
|
+
* It does not touch a blockquote that carries no marker, and an unrecognized
|
|
141
141
|
* marker (`[!HINT]`) is left exactly as it was — visible literal text, which is
|
|
142
142
|
* the honest rendering of something GitHub also would not style. Silently
|
|
143
143
|
* swallowing it would hide a typo that reads as a callout on neither renderer.
|
|
@@ -421,11 +421,63 @@ const VANTAGE_OQ_HOST_TARGETS = VANTAGE_ANCHOR_TARGETS.filter((tag) => tag !== "
|
|
|
421
421
|
* file, and requiring it everywhere would fire on every single-doc sketch.
|
|
422
422
|
*
|
|
423
423
|
* Three consumers read it from here and none of them may re-spell it: the
|
|
424
|
-
* plugin that stamps the anchor, the
|
|
424
|
+
* plugin that stamps the anchor, the sanitizer that allowlists the value, and
|
|
425
425
|
* the checker's `vantage/oq-id-format`. A fourth copy is how the checker starts
|
|
426
426
|
* calling a working anchor malformed.
|
|
427
427
|
*/
|
|
428
428
|
const VANTAGE_OQ_ID = /^OQ-(?:[A-Z][A-Z0-9]{0,5})?[0-9]+$/;
|
|
429
|
+
/**
|
|
430
|
+
* The status emoji the documentation convention marks an Open Question with, and
|
|
431
|
+
* what each one means to a reader deciding whether the question wants them.
|
|
432
|
+
*
|
|
433
|
+
* These are *prose* — ordinary characters in the question's title, not part of
|
|
434
|
+
* any directive — which is exactly why they need a home that both readers of
|
|
435
|
+
* them can import. Two consumers ask what a marker means and they must not
|
|
436
|
+
* answer differently: the checker's `vantage/oq-missing`, which demands a
|
|
437
|
+
* directive on an open question and must never demand one on a blocked one, and
|
|
438
|
+
* the viewer's contents column, which shows the marker and needs a word for it
|
|
439
|
+
* that a screen reader can say. They were private constants in the checker until
|
|
440
|
+
* the second consumer arrived.
|
|
441
|
+
*
|
|
442
|
+
* `open` is the only state that wants a one-click answer. `settled` and
|
|
443
|
+
* `blocked` deliberately carry no directive at all — a control offering to
|
|
444
|
+
* answer a question that is already decided, or that cannot be answered yet, is
|
|
445
|
+
* a lie — so the checker keys on the distinction rather than on the word
|
|
446
|
+
* "Leaning:" alone. Either non-open marker wins when both appear on one item.
|
|
447
|
+
*/
|
|
448
|
+
const VANTAGE_OQ_STATUS = {
|
|
449
|
+
/** 💬 — an active decision awaiting a ruling. */
|
|
450
|
+
open: "💬",
|
|
451
|
+
/** ✅ — decided, awaiting compaction into a Decision Ledger. */
|
|
452
|
+
settled: "✅",
|
|
453
|
+
/** 🔒 — blocked on an upstream decision or experiment. */
|
|
454
|
+
blocked: "🔒"
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* What a marker says, in words, for somewhere an emoji cannot go.
|
|
458
|
+
*
|
|
459
|
+
* An accessible name is the reason this exists: a contents entry whose whole
|
|
460
|
+
* status is one glyph says nothing to a screen reader, and "speech bubble" —
|
|
461
|
+
* which is what it would otherwise read out — is worse than nothing.
|
|
462
|
+
*/
|
|
463
|
+
const VANTAGE_OQ_STATUS_LABEL = {
|
|
464
|
+
open: "Open question",
|
|
465
|
+
settled: "Answered question",
|
|
466
|
+
blocked: "Blocked question"
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* The state `text` is marked with, or `null` when it carries no marker.
|
|
470
|
+
*
|
|
471
|
+
* Non-open wins over open, the resolution `vantage/oq-missing` has always made:
|
|
472
|
+
* a question marked both 💬 and ✅ has been answered and the stale marker simply
|
|
473
|
+
* has not been cleared yet, so treating it as open would re-open a ruling.
|
|
474
|
+
*/
|
|
475
|
+
function vantageOqStatus(text) {
|
|
476
|
+
if (text.includes(VANTAGE_OQ_STATUS.settled)) return "settled";
|
|
477
|
+
if (text.includes(VANTAGE_OQ_STATUS.blocked)) return "blocked";
|
|
478
|
+
if (text.includes(VANTAGE_OQ_STATUS.open)) return "open";
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
429
481
|
const STYLE_KEYS = {
|
|
430
482
|
tone: VANTAGE_TONES,
|
|
431
483
|
emphasis: VANTAGE_EMPHASIS,
|
|
@@ -589,7 +641,7 @@ const HEADING_DEPTHS = /* @__PURE__ */ new Map([
|
|
|
589
641
|
/**
|
|
590
642
|
* Key → hast property, for the keys that treat a whole run.
|
|
591
643
|
*
|
|
592
|
-
* A camelCase hast property
|
|
644
|
+
* A camelCase hast property serializes to the kebab-case attribute, so
|
|
593
645
|
* `dataVantageTone` is `data-vantage-tone` in every renderer.
|
|
594
646
|
*
|
|
595
647
|
* `tone` and `emphasis` describe what a section *is* and how loud it is, so
|
|
@@ -624,11 +676,11 @@ const LEANING_PROPERTY = "dataVantageLeaning";
|
|
|
624
676
|
* The id, carried as a `data-` attribute rather than written straight to `id`.
|
|
625
677
|
*
|
|
626
678
|
* This plugin runs *before* `rehypeSanitize` — it has to, it reads comments and
|
|
627
|
-
* the
|
|
679
|
+
* the sanitizer deletes them — and the sanitizer's default schema clobbers `id`
|
|
628
680
|
* with the prefix `user-content-`. A bare `id` set here would reach the page as
|
|
629
681
|
* `user-content-OQ-4`, every `#OQ-4` link in every document would land nowhere,
|
|
630
682
|
* and nothing would error. `rehypeVantageAnchors` promotes this to a real `id`
|
|
631
|
-
* on the other side of the
|
|
683
|
+
* on the other side of the sanitizer, which is the same reason `rehypeSlug` is
|
|
632
684
|
* registered there (`pipeline.ts`).
|
|
633
685
|
*/
|
|
634
686
|
const OQ_ID_PROPERTY = "dataVantageOqId";
|
|
@@ -660,7 +712,7 @@ const MAX_LEANING = 500;
|
|
|
660
712
|
* A whitespace-only `text` node always does — measured, with or without a blank
|
|
661
713
|
* line in the source. Comments do too, and an unrelated `<!-- TODO -->` must not
|
|
662
714
|
* break the chain: it is invisible in every renderer and deleted by the
|
|
663
|
-
*
|
|
715
|
+
* sanitizer, so letting it change a directive's meaning would make behavior
|
|
664
716
|
* depend on something no reader can see.
|
|
665
717
|
*/
|
|
666
718
|
function isSkippable(node) {
|
|
@@ -712,7 +764,7 @@ function accepts(name, key, value) {
|
|
|
712
764
|
* two stamped paragraphs — and the section's one continuous vertical rule is
|
|
713
765
|
* drawn per member, so an unstamped member is a hole the height of the block
|
|
714
766
|
* plus its margins. Measured over the real stylesheet: 44px for a one-line
|
|
715
|
-
* `<figure>`, against the 40px a
|
|
767
|
+
* `<figure>`, against the 40px a neighbor can bleed upward, and arbitrarily
|
|
716
768
|
* large for anything taller. `collapsed=true` had the same shape of bug the
|
|
717
769
|
* other way round — it hid the paragraphs and left the figure on the page.
|
|
718
770
|
*
|
|
@@ -894,7 +946,7 @@ function classNames(node) {
|
|
|
894
946
|
* A `<pre>` `rehype-katex` will replace — its own condition, restated.
|
|
895
947
|
*
|
|
896
948
|
* `language-math` is the only class to test: `rehype-katex` keys the
|
|
897
|
-
* pre-as-scope branch on it, and the
|
|
949
|
+
* pre-as-scope branch on it, and the sanitizer strips the `math-display` that
|
|
898
950
|
* `remark-math` also emits (measured — a stamped fence arrives here with
|
|
899
951
|
* `className: ["language-math"]` alone).
|
|
900
952
|
*/
|
|
@@ -1048,7 +1100,7 @@ const COLLAPSE_GROUP_ID = /^[0-9]+$/;
|
|
|
1048
1100
|
* `false` — comments are not elements, so `tagNames` has nothing to do with it.
|
|
1049
1101
|
* `rehypeVantageDirectives` relies on that deletion: it consumes a
|
|
1050
1102
|
* `<!-- vantage: … -->` comment into attributes and deliberately leaves the node
|
|
1051
|
-
* for the
|
|
1103
|
+
* for the sanitizer. Turning the switch on readmits every directive comment —
|
|
1052
1104
|
* valid and malformed alike — into the rendered HTML, which breaks the carrier's
|
|
1053
1105
|
* whole premise. `vantageDirectives.test.ts` ("leaves no comment in the rendered
|
|
1054
1106
|
* markup") is the guard.
|
|
@@ -1271,10 +1323,6 @@ function errorPosition(error) {
|
|
|
1271
1323
|
//#endregion
|
|
1272
1324
|
//#region src/renderMarkdown.ts
|
|
1273
1325
|
/**
|
|
1274
|
-
* Framework-agnostic markdown -> HTML rendering pipeline.
|
|
1275
|
-
* Uses the same remark/rehype chain as the Vantage viewer.
|
|
1276
|
-
*/
|
|
1277
|
-
/**
|
|
1278
1326
|
* Render a markdown string to HTML using the full Vantage pipeline.
|
|
1279
1327
|
*
|
|
1280
1328
|
* Features (all enabled by default):
|
|
@@ -1291,7 +1339,7 @@ function errorPosition(error) {
|
|
|
1291
1339
|
* Use the React `<MarkdownViewer>` component for client-side mermaid rendering.
|
|
1292
1340
|
*/
|
|
1293
1341
|
async function renderMarkdown(content, options = {}) {
|
|
1294
|
-
const { gfm = true, math = true, highlight = true, sourceLines = true, sanitize = true, frontmatter: parseFm = true } = options;
|
|
1342
|
+
const { gfm = true, math = true, highlight = true, sourceLines = true, sanitize = true, frontmatter: parseFm = true, tree } = options;
|
|
1295
1343
|
let parsed;
|
|
1296
1344
|
if (parseFm) parsed = parseFrontmatter(content);
|
|
1297
1345
|
else parsed = {
|
|
@@ -1308,7 +1356,8 @@ async function renderMarkdown(content, options = {}) {
|
|
|
1308
1356
|
sanitize,
|
|
1309
1357
|
bodyLineOffset: parsed.bodyLineOffset
|
|
1310
1358
|
});
|
|
1311
|
-
const
|
|
1359
|
+
const processor = (0, unified.unified)().use(remark_parse.default).use(remarkPlugins).use(remark_rehype.default, { allowDangerousHtml: true }).use(rehypePlugins).use(rehype_stringify.default);
|
|
1360
|
+
const result = tree === void 0 ? String(await processor.process(parsed.body)) : processor.stringify(await processor.run(tree, parsed.body), parsed.body);
|
|
1312
1361
|
return {
|
|
1313
1362
|
html: String(result),
|
|
1314
1363
|
frontmatter: parsed.frontmatter,
|
|
@@ -1322,7 +1371,7 @@ async function renderMarkdown(content, options = {}) {
|
|
|
1322
1371
|
*
|
|
1323
1372
|
* Split out from scrollToLineAnchor.ts so that non-browser consumers — the
|
|
1324
1373
|
* `vantage-check` CLI, which validates `#L42` links against the file on disk —
|
|
1325
|
-
* can share the *same* syntax the viewer
|
|
1374
|
+
* can share the *same* syntax the viewer honors instead of reimplementing it
|
|
1326
1375
|
* and drifting.
|
|
1327
1376
|
*/
|
|
1328
1377
|
/**
|
|
@@ -1439,7 +1488,7 @@ const DOC_STATUSES = [
|
|
|
1439
1488
|
/** Every key this build knows under `vantage:`. Closed. */
|
|
1440
1489
|
const VANTAGE_FRONTMATTER_KEYS = ["status-chip"];
|
|
1441
1490
|
/**
|
|
1442
|
-
* Which tone each status borrows its
|
|
1491
|
+
* Which tone each status borrows its colors from.
|
|
1443
1492
|
*
|
|
1444
1493
|
* The chip has no palette of its own: it reuses the tone chips
|
|
1445
1494
|
* (`.vantage-chip--<tone>` in `styles/directives.css`), which is also what makes
|
|
@@ -1546,6 +1595,49 @@ function currentMermaidTheme() {
|
|
|
1546
1595
|
return typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "default";
|
|
1547
1596
|
}
|
|
1548
1597
|
/**
|
|
1598
|
+
* The attribute on `<html>` naming the active color theme. Absent means the
|
|
1599
|
+
* built-in look. The app sets it only once the theme's stylesheet has loaded,
|
|
1600
|
+
* so a reader of this attribute can trust the theme's variables are in effect.
|
|
1601
|
+
*/
|
|
1602
|
+
const COLOR_THEME_ATTRIBUTE = "data-vantage-theme";
|
|
1603
|
+
/**
|
|
1604
|
+
* The attribute on `<html>` saying where the active theme came from: `"user"`
|
|
1605
|
+
* for a stylesheet in the reader's themes directory, `"built-in"` for one the
|
|
1606
|
+
* app ships. Set with {@link COLOR_THEME_ATTRIBUTE}, and absent with it.
|
|
1607
|
+
*
|
|
1608
|
+
* It exists because an id alone is not a palette. A user theme may share a
|
|
1609
|
+
* built-in's id — that is how a reader tweaks one — and the app applies the
|
|
1610
|
+
* stored built-in synchronously, then swaps in the same-id user file once
|
|
1611
|
+
* /api/themes answers. Keyed on the id, the diagrams drawn in between kept the
|
|
1612
|
+
* built-in's colors: the key did not change, so neither the cache nor
|
|
1613
|
+
* `useSyncExternalStore` saw a reason to redraw.
|
|
1614
|
+
*/
|
|
1615
|
+
const COLOR_THEME_SOURCE_ATTRIBUTE = "data-vantage-theme-source";
|
|
1616
|
+
/** The active color theme's id, or `""` for the built-in look. */
|
|
1617
|
+
function currentColorTheme() {
|
|
1618
|
+
if (typeof document === "undefined") return "";
|
|
1619
|
+
return document.documentElement.getAttribute("data-vantage-theme") ?? "";
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Everything a rendered diagram's colors depend on, as one string: the
|
|
1623
|
+
* light/dark mode, plus the color theme when one is active.
|
|
1624
|
+
*
|
|
1625
|
+
* A diagram is baked at render time, so anything that changes its colors has
|
|
1626
|
+
* to change this key — it is what the SVG cache and the loader's "configured
|
|
1627
|
+
* for" check compare. Under the built-in look it is exactly the mode name,
|
|
1628
|
+
* which is what both keyed on before color themes existed.
|
|
1629
|
+
*/
|
|
1630
|
+
function currentMermaidPalette() {
|
|
1631
|
+
const theme = currentColorTheme();
|
|
1632
|
+
if (!theme) return currentMermaidTheme();
|
|
1633
|
+
const user = document.documentElement.getAttribute(COLOR_THEME_SOURCE_ATTRIBUTE) === "user";
|
|
1634
|
+
return `${currentMermaidTheme()} ${theme}${user ? " user" : ""}`;
|
|
1635
|
+
}
|
|
1636
|
+
/** The mermaid theme name a palette key was built from. */
|
|
1637
|
+
function mermaidThemeOf(palette) {
|
|
1638
|
+
return palette.startsWith("dark") ? "dark" : "default";
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1549
1641
|
* Theme variables per theme. Mermaid derives most of its palette from these, so
|
|
1550
1642
|
* the set is deliberately small: the surfaces, the ink, and the lines.
|
|
1551
1643
|
*/
|
|
@@ -1569,27 +1661,108 @@ const THEME_VARIABLES = {
|
|
|
1569
1661
|
edgeLabelBackground: "#f8fafc"
|
|
1570
1662
|
}
|
|
1571
1663
|
};
|
|
1664
|
+
/**
|
|
1665
|
+
* Where each variable comes from under a color theme: the palette step the
|
|
1666
|
+
* built-in value was chosen from. The hex above IS that step in Tailwind's own
|
|
1667
|
+
* palette, so reading the step back out of the page gives the same diagram
|
|
1668
|
+
* under the built-in look and the theme's colors under any other.
|
|
1669
|
+
*/
|
|
1670
|
+
const THEME_SOURCES = {
|
|
1671
|
+
dark: {
|
|
1672
|
+
background: "--color-slate-800",
|
|
1673
|
+
mainBkg: "--color-slate-700",
|
|
1674
|
+
nodeBorder: "--color-slate-400",
|
|
1675
|
+
nodeTextColor: "--color-slate-100",
|
|
1676
|
+
lineColor: "--color-slate-400",
|
|
1677
|
+
textColor: "--color-slate-200",
|
|
1678
|
+
edgeLabelBackground: "--color-slate-800"
|
|
1679
|
+
},
|
|
1680
|
+
default: {
|
|
1681
|
+
background: "--color-slate-50",
|
|
1682
|
+
mainBkg: "--color-slate-100",
|
|
1683
|
+
nodeBorder: "--color-slate-500",
|
|
1684
|
+
nodeTextColor: "--color-slate-900",
|
|
1685
|
+
lineColor: "--color-slate-500",
|
|
1686
|
+
textColor: "--color-slate-800",
|
|
1687
|
+
edgeLabelBackground: "--color-slate-50"
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1572
1690
|
function mermaidThemeVariables(theme) {
|
|
1573
|
-
|
|
1691
|
+
const fixed = THEME_VARIABLES[theme];
|
|
1692
|
+
if (!currentColorTheme()) return fixed;
|
|
1693
|
+
const out = {};
|
|
1694
|
+
for (const [key, hex] of Object.entries(fixed)) out[key] = resolveCssColor(THEME_SOURCES[theme][key]) ?? hex;
|
|
1695
|
+
return out;
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* A custom property's color as `#rrggbb`, or `null` when it cannot be read.
|
|
1699
|
+
*
|
|
1700
|
+
* Mermaid wants hex at `initialize()` time, and a theme's value can be any CSS
|
|
1701
|
+
* color — `oklch()`, `color-mix()`, a `var()` of another variable. So the
|
|
1702
|
+
* browser does the work: a probe element resolves the property to a computed
|
|
1703
|
+
* color, and a 1×1 canvas turns that into sRGB bytes whatever syntax it came
|
|
1704
|
+
* back in. No canvas (jsdom, a locked-down embed) is `null`, and the caller
|
|
1705
|
+
* falls back to the built-in value.
|
|
1706
|
+
*
|
|
1707
|
+
* A property nobody declared is `null` too, and has to be checked for up
|
|
1708
|
+
* front: `color: var(--unset)` is invalid at computed-value time, so the probe
|
|
1709
|
+
* *inherits* its color instead — the page's text color, which the canvas
|
|
1710
|
+
* would dutifully turn into a plausible hex and mermaid would paint every node
|
|
1711
|
+
* box with.
|
|
1712
|
+
*/
|
|
1713
|
+
function resolveCssColor(property) {
|
|
1714
|
+
if (typeof document === "undefined") return null;
|
|
1715
|
+
if (!getComputedStyle(document.documentElement).getPropertyValue(property).trim()) return null;
|
|
1716
|
+
const probe = document.createElement("span");
|
|
1717
|
+
probe.style.display = "none";
|
|
1718
|
+
probe.style.color = `var(${property})`;
|
|
1719
|
+
document.documentElement.appendChild(probe);
|
|
1720
|
+
const computed = getComputedStyle(probe).color;
|
|
1721
|
+
probe.remove();
|
|
1722
|
+
if (!computed) return null;
|
|
1723
|
+
const ctx = pixelContext();
|
|
1724
|
+
if (!ctx) return null;
|
|
1725
|
+
ctx.fillStyle = computed;
|
|
1726
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
1727
|
+
const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
|
1728
|
+
return `#${[
|
|
1729
|
+
r,
|
|
1730
|
+
g,
|
|
1731
|
+
b
|
|
1732
|
+
].map((v) => v.toString(16).padStart(2, "0")).join("")}`;
|
|
1733
|
+
}
|
|
1734
|
+
/** A 1×1 2D context to read a color back from, or `null` where there is none. */
|
|
1735
|
+
function pixelContext() {
|
|
1736
|
+
try {
|
|
1737
|
+
const canvas = document.createElement("canvas");
|
|
1738
|
+
canvas.width = canvas.height = 1;
|
|
1739
|
+
return canvas.getContext("2d", { willReadFrequently: true });
|
|
1740
|
+
} catch {
|
|
1741
|
+
return null;
|
|
1742
|
+
}
|
|
1574
1743
|
}
|
|
1575
1744
|
//#endregion
|
|
1576
1745
|
//#region src/mermaidCache.ts
|
|
1577
1746
|
const svgCache = /* @__PURE__ */ new Map();
|
|
1578
|
-
const cacheKey = (code, theme) => `${theme}
|
|
1747
|
+
const cacheKey = (code, theme) => `${theme}\u0000${code}`;
|
|
1579
1748
|
/** The SVG for this fence in the theme the page is currently asking for. */
|
|
1580
|
-
function getCachedSvg(code, theme =
|
|
1749
|
+
function getCachedSvg(code, theme = currentMermaidPalette()) {
|
|
1581
1750
|
return svgCache.get(cacheKey(code, theme));
|
|
1582
1751
|
}
|
|
1583
|
-
function setCachedSvg(code, svg, theme =
|
|
1752
|
+
function setCachedSvg(code, svg, theme = currentMermaidPalette()) {
|
|
1584
1753
|
svgCache.set(cacheKey(code, theme), svg);
|
|
1585
1754
|
}
|
|
1586
1755
|
//#endregion
|
|
1587
1756
|
//#region src/mermaidLoader.ts
|
|
1588
1757
|
let mermaidInstance = null;
|
|
1589
1758
|
let mermaidLoading = null;
|
|
1590
|
-
/**
|
|
1759
|
+
/**
|
|
1760
|
+
* The palette key (`currentMermaidPalette`) the loaded instance was last
|
|
1761
|
+
* configured for, `null` until loaded.
|
|
1762
|
+
*/
|
|
1591
1763
|
let configuredTheme = null;
|
|
1592
|
-
function configure(m,
|
|
1764
|
+
function configure(m, palette) {
|
|
1765
|
+
const theme = mermaidThemeOf(palette);
|
|
1593
1766
|
m.initialize({
|
|
1594
1767
|
startOnLoad: false,
|
|
1595
1768
|
theme,
|
|
@@ -1597,7 +1770,7 @@ function configure(m, theme) {
|
|
|
1597
1770
|
securityLevel: "strict",
|
|
1598
1771
|
suppressErrorRendering: true
|
|
1599
1772
|
});
|
|
1600
|
-
configuredTheme =
|
|
1773
|
+
configuredTheme = palette;
|
|
1601
1774
|
}
|
|
1602
1775
|
/**
|
|
1603
1776
|
* The mermaid module, configured for the theme the page is asking for *now*.
|
|
@@ -1611,19 +1784,19 @@ function configure(m, theme) {
|
|
|
1611
1784
|
* served instead (`mermaidCache.ts`).
|
|
1612
1785
|
*/
|
|
1613
1786
|
async function getMermaid() {
|
|
1614
|
-
const theme =
|
|
1787
|
+
const theme = currentMermaidPalette();
|
|
1615
1788
|
if (mermaidInstance) {
|
|
1616
1789
|
if (configuredTheme !== theme) configure(mermaidInstance, theme);
|
|
1617
1790
|
return mermaidInstance;
|
|
1618
1791
|
}
|
|
1619
1792
|
if (!mermaidLoading) mermaidLoading = import("mermaid").then((mod) => {
|
|
1620
1793
|
const m = mod.default;
|
|
1621
|
-
configure(m,
|
|
1794
|
+
configure(m, currentMermaidPalette());
|
|
1622
1795
|
mermaidInstance = m;
|
|
1623
1796
|
return m;
|
|
1624
1797
|
});
|
|
1625
1798
|
const loaded = await mermaidLoading;
|
|
1626
|
-
const wanted =
|
|
1799
|
+
const wanted = currentMermaidPalette();
|
|
1627
1800
|
if (configuredTheme !== wanted) configure(loaded, wanted);
|
|
1628
1801
|
return loaded;
|
|
1629
1802
|
}
|
|
@@ -1825,7 +1998,7 @@ vantage:
|
|
|
1825
1998
|
status-chip: true # show \`status\` as a chip above the metadata card
|
|
1826
1999
|
---
|
|
1827
2000
|
\`\`\`
|
|
1828
|
-
- **Nothing may sit above the opening delimiter** — not a blank line, not an editorial comment, not a \`<!-- vantage: … -->\` directive. Frontmatter is
|
|
2001
|
+
- **Nothing may sit above the opening delimiter** — not a blank line, not an editorial comment, not a \`<!-- vantage: … -->\` directive. Frontmatter is recognized only at the very first byte of the file (in Vantage, on GitHub, and in every other reader), so one line above it turns the whole block into body text: a horizontal rule followed by a heading made of the raw keys, with every field lost. \`vantage-check\` reports it as \`frontmatter/not-at-top\`.
|
|
1829
2002
|
- **\`vantage:\` is Vantage's own reserved key.** It holds chrome that belongs to the file rather than to a section, it never shows up in the metadata card, and every other renderer ignores it. One key today: \`status-chip\`.
|
|
1830
2003
|
- **Prefer \`status-chip: true\`**, which shows the document's own \`status:\` and therefore cannot disagree with it. A literal \`status-chip: accepted\` is accepted too, but it is a second value that goes stale on its own — \`vantage-check\` reports the disagreement.
|
|
1831
2004
|
- The chip's vocabulary is \`status\`'s, exactly: \`draft | in-review | accepted | deprecated\`, lowercase. \`Draft\` renders no chip at all, silently.
|
|
@@ -1877,7 +2050,7 @@ The steps below predate the rewrite.
|
|
|
1877
2050
|
\`\`\`
|
|
1878
2051
|
|
|
1879
2052
|
- **Three names**: \`section\` (the heading and everything under it), \`block\` (the one block after it), \`oq\` (one answerable Open Question).
|
|
1880
|
-
- **The keys and values are a closed set**: \`tone\` = \`note | tip | important | warning | caution | muted\`; \`emphasis\` = \`strong | normal | quiet\`; \`badge\` = \`draft | stale | blocked | done | wip\`; \`collapsed\` = \`true | false\`. Name a *tone*, never a
|
|
2053
|
+
- **The keys and values are a closed set**: \`tone\` = \`note | tip | important | warning | caution | muted\`; \`emphasis\` = \`strong | normal | quiet\`; \`badge\` = \`draft | stale | blocked | done | wip\`; \`collapsed\` = \`true | false\`. Name a *tone*, never a color — the theme decides what a warning looks like, in light mode, in dark mode, and in print.
|
|
1881
2054
|
- **Use them sparingly.** One or two per document, on the sections that genuinely differ. A document where everything is toned says nothing, and a rainbow one is harder to read than a plain one.
|
|
1882
2055
|
- **Anything outside those sets is silently ignored** — nothing breaks, and nothing styles either. Run \`vantage-check\` on the document: the \`vantage/*\` rules are the only thing that will ever tell you a directive did nothing.
|
|
1883
2056
|
- **Always close the comment with \`-->\`.** Never \`--!>\`, and never leave it open: Markdown reads every line below an unclosed \`<!--\` as part of the comment, and the whole rest of the document vanishes from the page. For the same reason \`-->\` cannot appear *inside* a value — it ends the comment early and spills the remainder into the page as literal text.
|
|
@@ -1903,6 +2076,8 @@ The steps below predate the rewrite.
|
|
|
1903
2076
|
`;
|
|
1904
2077
|
//#endregion
|
|
1905
2078
|
exports.ALERT_TITLES = ALERT_TITLES;
|
|
2079
|
+
exports.COLOR_THEME_ATTRIBUTE = COLOR_THEME_ATTRIBUTE;
|
|
2080
|
+
exports.COLOR_THEME_SOURCE_ATTRIBUTE = COLOR_THEME_SOURCE_ATTRIBUTE;
|
|
1906
2081
|
exports.DIRECTIVE_NAMES = DIRECTIVE_NAMES;
|
|
1907
2082
|
exports.DIRECTIVE_VOCABULARY = DIRECTIVE_VOCABULARY;
|
|
1908
2083
|
exports.DOC_STATUSES = DOC_STATUSES;
|
|
@@ -1915,12 +2090,15 @@ exports.VANTAGE_COLLAPSED = VANTAGE_COLLAPSED;
|
|
|
1915
2090
|
exports.VANTAGE_EMPHASIS = VANTAGE_EMPHASIS;
|
|
1916
2091
|
exports.VANTAGE_FRONTMATTER_KEYS = VANTAGE_FRONTMATTER_KEYS;
|
|
1917
2092
|
exports.VANTAGE_OQ_HOST_TARGETS = VANTAGE_OQ_HOST_TARGETS;
|
|
2093
|
+
exports.VANTAGE_OQ_STATUS = VANTAGE_OQ_STATUS;
|
|
2094
|
+
exports.VANTAGE_OQ_STATUS_LABEL = VANTAGE_OQ_STATUS_LABEL;
|
|
1918
2095
|
exports.VANTAGE_RUNS = VANTAGE_RUNS;
|
|
1919
2096
|
exports.VANTAGE_SENTINEL = VANTAGE_SENTINEL;
|
|
1920
2097
|
exports.VANTAGE_TONES = VANTAGE_TONES;
|
|
1921
2098
|
exports.buildPipeline = buildPipeline;
|
|
1922
2099
|
exports.buildRemarkPlugins = buildRemarkPlugins;
|
|
1923
2100
|
exports.clearLineAnchorHighlights = clearLineAnchorHighlights;
|
|
2101
|
+
exports.currentColorTheme = currentColorTheme;
|
|
1924
2102
|
exports.hasVantageSentinel = hasVantageSentinel;
|
|
1925
2103
|
exports.isDocStatus = isDocStatus;
|
|
1926
2104
|
exports.parseFrontmatter = parseFrontmatter;
|
|
@@ -1936,5 +2114,6 @@ exports.renderMermaidBlocks = renderMermaidBlocks;
|
|
|
1936
2114
|
exports.resolveLinks = resolveLinks;
|
|
1937
2115
|
exports.sanitizeSchema = sanitizeSchema;
|
|
1938
2116
|
exports.scrollToLineAnchor = scrollToLineAnchor;
|
|
2117
|
+
exports.vantageOqStatus = vantageOqStatus;
|
|
1939
2118
|
|
|
1940
2119
|
//# sourceMappingURL=index.cjs.map
|