, object>(Object),\n },\n setup: (props, { slots }) => {\n return () => (\n \n {slots[\"default\"]?.()}\n
\n );\n },\n});\n\nfunction computeKindClass(kind: string | undefined): string[] {\n if (kind === \"details\") {\n return [\"display-contents\", \"details\"];\n } else if (kind) {\n return [\"content-block\", \"callout-block\", kind];\n } else {\n return [\"content-block\", \"callout-block\"];\n }\n}\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/custom-block/dist/index.js b/packages/@starbeam-docs/custom-block/dist/index.js
new file mode 100644
index 0000000..6f5fc17
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/dist/index.js
@@ -0,0 +1,4 @@
+export { default as CustomBlock } from "./CustomBlock.js";
+
+
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/custom-block/dist/index.js.map b/packages/@starbeam-docs/custom-block/dist/index.js.map
new file mode 100644
index 0000000..9edf8bc
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS,WAAW,WAAW,QAAQ,mBAAmB","file":"index.js","sourcesContent":["export { default as CustomBlock } from \"./CustomBlock.js\";\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/custom-block/package.json b/packages/@starbeam-docs/custom-block/package.json
new file mode 100644
index 0000000..2c5d654
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "@starbeam-docs/custom-block",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "types": "./src/index.ts",
+ "default": "./dist/index.js"
+ },
+ "dependencies": {
+ "@wycatsjs/utils": "workspace:^",
+ "vue": "*"
+ }
+}
diff --git a/packages/@starbeam-docs/custom-block/src/CustomBlock.css.ts b/packages/@starbeam-docs/custom-block/src/CustomBlock.css.ts
new file mode 100644
index 0000000..1af005a
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/src/CustomBlock.css.ts
@@ -0,0 +1,8 @@
+export const customBlock = "_custom-block_qdbrd_2";
+if (globalThis.document !== undefined) {
+ const style = document.createElement('style');
+ style.setAttribute("type", "text/css");
+ const text = document.createTextNode("@layer custom-block {\n ._custom-block_qdbrd_2:has(details) {\n display: contents;\n }\n\n ._custom-block_qdbrd_2 > details {\n padding-left: var(--sbdoc-ui-inner-padding);\n padding-right: var(--sbdoc-ui-inner-padding);\n }\n\n ._custom-block_qdbrd_2:not(:has(details)) {\n display: grid;\n grid-template-columns: var(--sbdoc-ui-inner-padding) -webkit-min-content 1fr var(\n --sbdoc-ui-inner-padding\n );\n grid-template-columns: var(--sbdoc-ui-inner-padding) min-content 1fr var(\n --sbdoc-ui-inner-padding\n );\n -webkit-box-align: first baseline;\n -ms-flex-align: first baseline;\n align-items: first baseline;\n grid-row-gap: var(--sbdoc-default-line-spacing);\n row-gap: var(--sbdoc-default-line-spacing);\n padding-top: var(--sbdoc-ui-inner-padding);\n padding-bottom: var(--sbdoc-ui-inner-padding);\n border-width: 0;\n border-style: solid;\n }\n\n ._custom-block_qdbrd_2:not(:has(details)) > * {\n grid-column: 2;\n }\n\n ._custom-block_qdbrd_2:not(:has(details)) ._custom-block_qdbrd_2 {\n border: 0;\n grid-column: 1 / span 4;\n /* border-radius: 0; */\n background-color: var(--sbdoc-local-bg);\n }\n\n /* .custom-block:not(.north) > :first-child {\n margin-block-start: 0;\n }\n\n .custom-block:not(.south) > :last-child {\n margin-block-end: 0;\n } */\n\n /* .custom-block.west {\n border-inline-start-width: var(--sbdoc-local-border-width);\n }\n\n .custom-block.east {\n border-inline-end-width: var(--sbdoc-local-border-width);\n }\n\n .custom-block.north {\n border-block-start-width: var(--sbdoc-local-border-width);\n }\n\n .custom-block.south {\n border-block-end-width: var(--sbdoc-local-border-width);\n } */\n}\n");
+ style.appendChild(text);
+ document.head.appendChild(style);
+}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/custom-block/src/CustomBlock.postcss b/packages/@starbeam-docs/custom-block/src/CustomBlock.postcss
new file mode 100644
index 0000000..c5ee8ef
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/src/CustomBlock.postcss
@@ -0,0 +1,56 @@
+@layer custom-block {
+ .custom-block:has(details) {
+ display: contents;
+ }
+
+ .custom-block > details {
+ padding-inline: var(--sbdoc-ui-inner-padding);
+ }
+
+ .custom-block:not(:has(details)) {
+ display: grid;
+ grid-template-columns: var(--sbdoc-ui-inner-padding) min-content 1fr var(
+ --sbdoc-ui-inner-padding
+ );
+ align-items: first baseline;
+ row-gap: var(--sbdoc-default-line-spacing);
+ padding-block: var(--sbdoc-ui-inner-padding);
+ border-width: 0;
+ border-style: solid;
+
+ > * {
+ grid-column: 2;
+ }
+
+ .custom-block {
+ border: 0;
+ grid-column: 1 / span 4;
+ /* border-radius: 0; */
+ background-color: var(--sbdoc-local-bg);
+ }
+ }
+
+ /* .custom-block:not(.north) > :first-child {
+ margin-block-start: 0;
+ }
+
+ .custom-block:not(.south) > :last-child {
+ margin-block-end: 0;
+ } */
+
+ /* .custom-block.west {
+ border-inline-start-width: var(--sbdoc-local-border-width);
+ }
+
+ .custom-block.east {
+ border-inline-end-width: var(--sbdoc-local-border-width);
+ }
+
+ .custom-block.north {
+ border-block-start-width: var(--sbdoc-local-border-width);
+ }
+
+ .custom-block.south {
+ border-block-end-width: var(--sbdoc-local-border-width);
+ } */
+}
diff --git a/packages/@starbeam-docs/custom-block/src/CustomBlock.tsx b/packages/@starbeam-docs/custom-block/src/CustomBlock.tsx
new file mode 100644
index 0000000..c819ce0
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/src/CustomBlock.tsx
@@ -0,0 +1,98 @@
+import {
+ defineComponent,
+ type Prop,
+ type PropType,
+ type StyleValue,
+} from "vue";
+import { customBlock } from "./CustomBlock.css.js";
+
+export interface Props {
+ readonly color?: string;
+ readonly border?: Border;
+}
+
+type BorderPosition =
+ | `${"n" | "s" | "ns" | ""}${"e" | "w" | "ew" | ""}`
+ | "-";
+
+const north = "north";
+const south = "south";
+const east = "east";
+const west = "west";
+
+type BorderClass =
+ | typeof north
+ | typeof south
+ | typeof east
+ | typeof west;
+
+const MAPPING = {
+ n: north,
+ s: south,
+ e: east,
+ w: west,
+} as const;
+
+function computeBorder(position: BorderPosition): BorderClass[] {
+ const classes: BorderClass[] = [];
+
+ for (const [input, className] of Object.entries(MAPPING)) {
+ if (position.includes(input)) {
+ classes.push(className);
+ }
+ }
+
+ return classes;
+}
+
+type Border = `${BorderPosition}`;
+
+function prop(
+ type: PropType,
+ options?: { default: U }
+): Prop {
+ if (options && "default" in options) {
+ return {
+ type,
+ default: options?.default,
+ } as Prop;
+ } else {
+ return {
+ type,
+ } as Prop;
+ }
+}
+
+export default defineComponent({
+ props: {
+ kind: prop(String),
+ border: prop(String),
+ color: prop(String),
+ style: prop, object>(Object),
+ },
+ setup: (props, { slots }) => {
+ return () => (
+
+ {slots["default"]?.()}
+
+ );
+ },
+});
+
+function computeKindClass(kind: string | undefined): string[] {
+ if (kind === "details") {
+ return ["display-contents", "details"];
+ } else if (kind) {
+ return ["content-block", "callout-block", kind];
+ } else {
+ return ["content-block", "callout-block"];
+ }
+}
diff --git a/packages/@starbeam-docs/custom-block/src/index.ts b/packages/@starbeam-docs/custom-block/src/index.ts
new file mode 100644
index 0000000..505d09d
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/src/index.ts
@@ -0,0 +1 @@
+export { default as CustomBlock } from "./CustomBlock.js";
diff --git a/packages/@starbeam-docs/custom-block/tsconfig.json b/packages/@starbeam-docs/custom-block/tsconfig.json
new file mode 100644
index 0000000..fd2c88e
--- /dev/null
+++ b/packages/@starbeam-docs/custom-block/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "verbatimModuleSyntax": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "strict": true,
+ "noUncheckedIndexedAccess": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "exactOptionalPropertyTypes": true,
+ "noImplicitOverride": true,
+ "allowJs": true,
+ "jsx": "preserve",
+ "types": ["@vue/runtime-dom"]
+ },
+ "include": ["./src/**/*"]
+}
diff --git a/packages/@starbeam-docs/fenced-container/dist/builtins.js b/packages/@starbeam-docs/fenced-container/dist/builtins.js
new file mode 100644
index 0000000..5fbf8f9
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/builtins.js
@@ -0,0 +1,206 @@
+import { parserPlugin } from "@jsergo/mdit";
+import "@mdit-vue/plugin-sfc";
+import parseFence from "fenceparser";
+import { Builtins, CUSTOM_EL, CustomEl, Title, UnparsedContent } from "./define.js";
+import { Do, El } from "./nodes.js";
+const BUILTINS = Builtins.empty().basic("info", {
+ defaultTitle: "INFO",
+ color: "blue"
+}).basic("construction", {
+ defaultTitle: "Under Construction",
+ color: "orange"
+}).basic("warning", {
+ color: "yellow"
+}).basic("error", {
+ color: "red"
+}).basic("tip", {
+ defaultTitle: null,
+ color: "green"
+}).basic("callout", {
+ defaultTitle: null
+}).custom("💡", ({ title , content })=>CustomEl("lightbulb", {
+ border: "se",
+ color: "yellow",
+ style: {
+ "padding-block": "0.5em"
+ }
+ }, [
+ title,
+ content
+ ])).custom("lang-ts", ({ content })=>CustomEl("lang-ts", {
+ color: "neutral"
+ }, [
+ content
+ ])).custom("em", ({ title , content })=>CustomEl("em", {
+ color: "orange",
+ border: "w",
+ style: {
+ "font-size": `calc(1em * var(--sbdoc-ratio))`,
+ "font-weight": "600",
+ "border-size": "2px",
+ "line-height": "1"
+ }
+ }, [
+ title.withDefault("Key Point").map((title)=>El("h5", [
+ title
+ ])),
+ content
+ ])).custom("persona", ({ title , content })=>El("aside", {
+ class: [
+ "persona",
+ String(title)
+ ]
+ }, [
+ content
+ ])).custom("details", ({ title , content , attrs })=>{
+ return El(CUSTOM_EL, {
+ kind: "details",
+ color: "gray"
+ }, [
+ El("details", {
+ class: [
+ "content-block",
+ "callout-block",
+ "container",
+ ...normalizePart(attrs["type"])
+ ]
+ }, [
+ Do(()=>{
+ function titleChild() {
+ switch(attrs["type"]){
+ case "deep-dive":
+ // TODO:: Generalize
+ return [
+ El("span", [
+ "Deep Dive"
+ ]),
+ title
+ ];
+ default:
+ return [
+ title.withDefault("Details")
+ ];
+ }
+ }
+ return [
+ El("summary", {
+ class: "custom-block-title"
+ }, titleChild())
+ ];
+ }),
+ content
+ ])
+ ]);
+});
+export const fencedContainerPlugin = parserPlugin({
+ name: "fenced-container",
+ before: "fence"
+}).block((line, md)=>{
+ var _matched_raw_groups;
+ const matched = line.matchStart(RegExp("^(?````*)md "));
+ if (matched.type === "error") {
+ return ()=>(render)=>render.html(md.error(matched.error));
+ } else if (matched.type === "unmatched") {
+ return false;
+ }
+ const ticks = (_matched_raw_groups = matched.raw.groups) === null || _matched_raw_groups === void 0 ? void 0 : _matched_raw_groups["ticks"];
+ const fenceline = line.string();
+ const info = fenceline.slice(matched.fragment.length);
+ // split the fenceline into the part before the first space (kind) and the
+ // part after it (params).
+ const [kind, params] = split2(info, " ");
+ if (kind === undefined) {
+ return false;
+ }
+ const builtin = BUILTINS.tryGet(kind);
+ if (builtin === undefined) {
+ return false;
+ }
+ return ()=>{
+ var _line_next;
+ const fenceContent = (_line_next = line.next) === null || _line_next === void 0 ? void 0 : _line_next.until((line)=>{
+ var _line_slice;
+ return ((_line_slice = line.slice()) === null || _line_slice === void 0 ? void 0 : _line_slice.trim()) === ticks;
+ });
+ return (render)=>{
+ const { title , attrs ={} } = parseTitle(params);
+ const rendered = builtin.render({
+ md,
+ kind,
+ title: Title.provided(title),
+ attrs,
+ content: UnparsedContent.of(fenceContent)
+ });
+ return render.tokens(rendered);
+ };
+ };
+});
+function parseTitle(params) {
+ if (params === undefined) {
+ return {};
+ }
+ const trimmed = params.trim();
+ if (trimmed.length === 0) {
+ return {};
+ }
+ const quotedString = trimmed.match(/^\s*"(.*)"\s*$/);
+ if (quotedString === null || quotedString === void 0 ? void 0 : quotedString[1]) {
+ return {
+ title: quotedString[1]
+ };
+ }
+ if (trimmed.match(/[{=]/)) {
+ const parsed = parseFence(trimmed);
+ const title = getTitle(parsed["title"]);
+ return {
+ title,
+ attrs: parsed
+ };
+ }
+ return {
+ title: trimmed
+ };
+}
+function getTitle(title) {
+ if (title === undefined) {
+ return undefined;
+ } else if (title === false || title === null) {
+ return false;
+ } else {
+ return String(title);
+ }
+}
+function split2(string, delimiter) {
+ const index = string.indexOf(delimiter);
+ const p0 = index === -1 ? string : string.substring(0, index);
+ const p1 = index === -1 ? "" : string.substring(index + 1);
+ return [
+ p0,
+ p1
+ ];
+}
+function normalizePart(value) {
+ if (value === null || value === undefined) {
+ return [];
+ } else if (Array.isArray(value)) {
+ return value.flatMap(normalizePart).filter(isPresent);
+ } else if (typeof value === "string") {
+ return [
+ value
+ ];
+ } else if (typeof value === "number") {
+ return [
+ String(value)
+ ];
+ } else if (typeof value === "boolean") {
+ throw Error(`Booleans are not supported as part of an attr array.`);
+ } else {
+ throw Error(`Object are not supported as part of an attr array. You passed ${JSON.stringify(value)}`);
+ }
+}
+function isPresent(value) {
+ return value !== undefined && value !== null;
+}
+
+
+//# sourceMappingURL=builtins.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/builtins.js.map b/packages/@starbeam-docs/fenced-container/dist/builtins.js.map
new file mode 100644
index 0000000..e18bed9
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/builtins.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/builtins.ts"],"names":[],"mappings":"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","file":"builtins.js","sourcesContent":["import { parserPlugin } from \"@jsergo/mdit\";\nimport \"@mdit-vue/plugin-sfc\";\nimport parseFence from \"fenceparser\";\nimport {\n Builtins,\n CUSTOM_EL,\n CustomEl,\n Title,\n UnparsedContent,\n} from \"./define.js\";\nimport { Do, El } from \"./nodes.js\";\nimport type { AttrPart } from \"./tokens.js\";\n\ntype OBJECT = ReturnType;\ntype VALUE = OBJECT[keyof OBJECT];\n\nconst BUILTINS = Builtins.empty()\n .basic(\"info\", {\n defaultTitle: \"INFO\",\n color: \"blue\",\n })\n .basic(\"construction\", {\n defaultTitle: \"Under Construction\",\n color: \"orange\",\n })\n .basic(\"warning\", {\n color: \"yellow\",\n })\n .basic(\"error\", {\n color: \"red\",\n })\n .basic(\"tip\", {\n defaultTitle: null,\n color: \"green\",\n })\n .basic(\"callout\", { defaultTitle: null })\n .custom(\"💡\", ({ title, content }) =>\n CustomEl(\n \"lightbulb\",\n {\n border: \"se\",\n color: \"yellow\",\n style: {\n \"padding-block\": \"0.5em\",\n },\n },\n [title, content]\n )\n )\n .custom(\"lang-ts\", ({ content }) =>\n CustomEl(\"lang-ts\", { color: \"neutral\" }, [content])\n )\n .custom(\"em\", ({ title, content }) =>\n CustomEl(\n \"em\",\n {\n color: \"orange\",\n border: \"w\",\n style: {\n \"font-size\": `calc(1em * var(--sbdoc-ratio))`,\n \"font-weight\": \"600\",\n \"border-size\": \"2px\",\n \"line-height\": \"1\",\n },\n },\n [\n title\n .withDefault(\"Key Point\")\n .map((title) => El(\"h5\", [title])),\n content,\n ]\n )\n )\n .custom(\"persona\", ({ title, content }) =>\n El(\"aside\", { class: [\"persona\", String(title)] }, [content])\n )\n .custom(\"details\", ({ title, content, attrs }) => {\n return El(CUSTOM_EL, { kind: \"details\", color: \"gray\" }, [\n El(\n \"details\",\n {\n class: [\n \"content-block\",\n \"callout-block\",\n \"container\",\n ...normalizePart(attrs[\"type\"]),\n ],\n },\n [\n Do(() => {\n function titleChild() {\n switch (attrs[\"type\"]) {\n case \"deep-dive\":\n // TODO:: Generalize\n return [El(\"span\", [\"Deep Dive\"]), title];\n default:\n return [title.withDefault(\"Details\")];\n }\n }\n\n return [\n El(\n \"summary\",\n { class: \"custom-block-title\" },\n titleChild()\n ),\n ];\n }),\n content,\n ]\n ),\n ]);\n });\n\nexport const fencedContainerPlugin = parserPlugin({\n name: \"fenced-container\",\n before: \"fence\",\n}).block((line, md) => {\n const matched = line.matchStart(/^(?````*)md /);\n\n if (matched.type === \"error\") {\n return () => (render) =>\n render.html(md.error(matched.error));\n } else if (matched.type === \"unmatched\") {\n return false;\n }\n\n const ticks = matched.raw.groups?.[\"ticks\"] as string;\n const fenceline = line.string();\n const info = fenceline.slice(matched.fragment.length);\n\n // split the fenceline into the part before the first space (kind) and the\n // part after it (params).\n const [kind, params] = split2(info, \" \");\n\n if (kind === undefined) {\n return false;\n }\n\n const builtin = BUILTINS.tryGet(kind);\n\n if (builtin === undefined) {\n return false;\n }\n\n return () => {\n const fenceContent = line.next?.until(\n (line) => line.slice()?.trim() === ticks\n );\n\n return (render) => {\n const { title, attrs = {} } = parseTitle(params);\n\n const rendered = builtin.render({\n md,\n kind,\n title: Title.provided(title),\n attrs,\n content: UnparsedContent.of(fenceContent),\n });\n\n return render.tokens(rendered);\n };\n };\n});\n\nfunction parseTitle(params: string | undefined): {\n /**\n * false means \"no title\"\n * undefined means \"default title\"\n *\n * if no title is provided, the value will be undefined\n */\n title?: string | false | undefined;\n attrs?: Record | undefined;\n} {\n if (params === undefined) {\n return {};\n }\n\n const trimmed = params.trim();\n\n if (trimmed.length === 0) {\n return {};\n }\n\n const quotedString = trimmed.match(/^\\s*\"(.*)\"\\s*$/);\n\n if (quotedString?.[1]) {\n return { title: quotedString[1] };\n }\n\n if (trimmed.match(/[{=]/)) {\n const parsed = parseFence(trimmed);\n\n const title = getTitle(parsed[\"title\"]);\n\n return { title, attrs: parsed };\n }\n\n return { title: trimmed };\n}\n\nfunction getTitle(title: VALUE): string | false | undefined {\n if (title === undefined) {\n return undefined;\n } else if (title === false || title === null) {\n return false;\n } else {\n return String(title);\n }\n}\n\nfunction split2(\n string: string,\n delimiter: string\n): [string, string | undefined] {\n const index = string.indexOf(delimiter);\n const p0 = index === -1 ? string : string.substring(0, index);\n const p1 = index === -1 ? \"\" : string.substring(index + 1);\n\n return [p0, p1];\n}\n\nfunction normalizePart(value: VALUE): AttrPart[] {\n if (value === null || value === undefined) {\n return [];\n } else if (Array.isArray(value)) {\n return value.flatMap(normalizePart).filter(isPresent);\n } else if (typeof value === \"string\") {\n return [value];\n } else if (typeof value === \"number\") {\n return [String(value)];\n } else if (typeof value === \"boolean\") {\n throw Error(\n `Booleans are not supported as part of an attr array.`\n );\n } else {\n throw Error(\n `Object are not supported as part of an attr array. You passed ${JSON.stringify(\n value\n )}`\n );\n }\n}\n\nfunction isPresent(value: T | undefined | null): value is T {\n return value !== undefined && value !== null;\n}\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/define.js b/packages/@starbeam-docs/fenced-container/dist/define.js
new file mode 100644
index 0000000..4d41ac8
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/define.js
@@ -0,0 +1,341 @@
+function _checkPrivateRedeclaration(obj, privateCollection) {
+ if (privateCollection.has(obj)) {
+ throw new TypeError("Cannot initialize the same private elements twice on an object");
+ }
+}
+function _classApplyDescriptorGet(receiver, descriptor) {
+ if (descriptor.get) {
+ return descriptor.get.call(receiver);
+ }
+ return descriptor.value;
+}
+function _classApplyDescriptorSet(receiver, descriptor, value) {
+ if (descriptor.set) {
+ descriptor.set.call(receiver, value);
+ } else {
+ if (!descriptor.writable) {
+ throw new TypeError("attempted to set read only private field");
+ }
+ descriptor.value = value;
+ }
+}
+function _classExtractFieldDescriptor(receiver, privateMap, action) {
+ if (!privateMap.has(receiver)) {
+ throw new TypeError("attempted to " + action + " private field on non-instance");
+ }
+ return privateMap.get(receiver);
+}
+function _classPrivateFieldGet(receiver, privateMap) {
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
+ return _classApplyDescriptorGet(receiver, descriptor);
+}
+function _classPrivateFieldInit(obj, privateMap, value) {
+ _checkPrivateRedeclaration(obj, privateMap);
+ privateMap.set(obj, value);
+}
+function _classPrivateFieldSet(receiver, privateMap, value) {
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
+ _classApplyDescriptorSet(receiver, descriptor, value);
+ return value;
+}
+function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+ return obj;
+}
+function _objectSpread(target) {
+ for(var i = 1; i < arguments.length; i++){
+ var source = arguments[i] != null ? arguments[i] : {};
+ var ownKeys = Object.keys(source);
+ if (typeof Object.getOwnPropertySymbols === 'function') {
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
+ }));
+ }
+ ownKeys.forEach(function(key) {
+ _defineProperty(target, key, source[key]);
+ });
+ }
+ return target;
+}
+function ownKeys(object, enumerableOnly) {
+ var keys = Object.keys(object);
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(object);
+ if (enumerableOnly) {
+ symbols = symbols.filter(function(sym) {
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+ });
+ }
+ keys.push.apply(keys, symbols);
+ }
+ return keys;
+}
+function _objectSpreadProps(target, source) {
+ source = source != null ? source : {};
+ if (Object.getOwnPropertyDescriptors) {
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
+ } else {
+ ownKeys(Object(source)).forEach(function(key) {
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
+ });
+ }
+ return target;
+}
+import "@mdit-vue/plugin-sfc";
+import { mapEntries } from "@wycatsjs/utils";
+import { El, InlineHtml } from "./nodes.js";
+import { BasicFragment, CustomBuiltin } from "./tokens.js";
+export const CUSTOM_EL = "CustomBlock";
+var _content = /*#__PURE__*/ new WeakMap();
+export class UnparsedContent {
+ static of(content) {
+ return new UnparsedContent(content);
+ }
+ get raw() {
+ return _classPrivateFieldGet(this, _content);
+ }
+ render(tokens) {
+ if (_classPrivateFieldGet(this, _content)) {
+ return tokens.blockHtml(_classPrivateFieldGet(this, _content));
+ }
+ return tokens;
+ }
+ constructor(content){
+ _classPrivateFieldInit(this, _content, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _content, content);
+ }
+}
+const DEFAULT_COLOR = "theme";
+function ToBuiltinConfig(config) {
+ if (config === undefined || typeof config === "string") {
+ return {
+ defaultTitle: config !== null && config !== void 0 ? config : null,
+ color: DEFAULT_COLOR
+ };
+ } else {
+ return _objectSpread({
+ color: "theme"
+ }, config);
+ }
+}
+var _config = /*#__PURE__*/ new WeakMap(), _renderFn = /*#__PURE__*/ new WeakMap(), _defaultTitle = /*#__PURE__*/ new WeakMap();
+class Builtin {
+ render(options) {
+ const result = _classPrivateFieldGet(this, _renderFn).call(this, _objectSpreadProps(_objectSpread({}, options), {
+ define: new CustomBuiltin(options.md)
+ }));
+ const fragment = BasicFragment.empty(options.md);
+ if (Array.isArray(result)) {
+ fragment.push(...result);
+ } else {
+ fragment.push(result);
+ }
+ return fragment.done();
+ }
+ constructor(config){
+ _classPrivateFieldInit(this, _renderFn, {
+ get: get_renderFn,
+ set: void 0
+ });
+ _classPrivateFieldInit(this, _defaultTitle, {
+ get: get_defaultTitle,
+ set: void 0
+ });
+ _classPrivateFieldInit(this, _config, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _config, config);
+ }
+}
+function get_renderFn() {
+ if (typeof _classPrivateFieldGet(this, _config) === "object" && "render" in _classPrivateFieldGet(this, _config)) {
+ return _classPrivateFieldGet(this, _config).render;
+ }
+ const color = _classPrivateFieldGet(this, _config).color;
+ return ({ kind , title: providedTitle , content })=>{
+ var _classPrivateFieldGet1;
+ const title = providedTitle.withDefault((_classPrivateFieldGet1 = _classPrivateFieldGet(this, _defaultTitle)) !== null && _classPrivateFieldGet1 !== void 0 ? _classPrivateFieldGet1 : undefined);
+ return CustomEl(kind, {
+ color: color !== null && color !== void 0 ? color : DEFAULT_COLOR
+ }, [
+ title.map((t)=>El("p", {
+ class: "custom-block-title"
+ }, [
+ InlineHtml(t)
+ ])),
+ content
+ ]);
+ };
+}
+function get_defaultTitle() {
+ if (typeof _classPrivateFieldGet(this, _config) === "object" && "defaultTitle" in _classPrivateFieldGet(this, _config) && typeof _classPrivateFieldGet(this, _config).defaultTitle === "string") {
+ return _classPrivateFieldGet(this, _config).defaultTitle;
+ }
+}
+var _provided = /*#__PURE__*/ new WeakMap(), _default = /*#__PURE__*/ new WeakMap();
+let _Symbol_for = Symbol.for("nodejs.util.inspect.custom");
+export class Title {
+ static provided(provided) {
+ return new Title(provided, undefined);
+ }
+ static create(provided, defaultValue) {
+ return new Title(provided, defaultValue);
+ }
+ [_Symbol_for]() {
+ return `Title(${JSON.stringify(String(this))})`;
+ }
+ withDefault(defaultValue) {
+ return new Title(_classPrivateFieldGet(this, _provided), defaultValue);
+ }
+ render(tokens) {
+ return tokens.append(InlineHtml(this));
+ }
+ isBlank() {
+ return _classPrivateFieldGet(this, _provided) === false;
+ }
+ map(callback) {
+ const title = String(this);
+ if (title === "") {
+ return null;
+ } else {
+ return callback(title);
+ }
+ }
+ exists() {
+ if (_classPrivateFieldGet(this, _provided) === false) {
+ return false;
+ } else if (_classPrivateFieldGet(this, _provided) === undefined) {
+ return _classPrivateFieldGet(this, _default) !== undefined;
+ } else {
+ return true;
+ }
+ }
+ get provided() {
+ return _classPrivateFieldGet(this, _provided);
+ }
+ stringify() {
+ if (_classPrivateFieldGet(this, _provided) === false) {
+ return "";
+ } else if (_classPrivateFieldGet(this, _provided) === undefined) {
+ var _classPrivateFieldGet1;
+ return (_classPrivateFieldGet1 = _classPrivateFieldGet(this, _default)) !== null && _classPrivateFieldGet1 !== void 0 ? _classPrivateFieldGet1 : "";
+ } else {
+ return _classPrivateFieldGet(this, _provided);
+ }
+ }
+ toString() {
+ return this.stringify();
+ }
+ constructor(provided, defaultValue){
+ _classPrivateFieldInit(this, _provided, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldInit(this, _default, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _provided, provided);
+ _classPrivateFieldSet(this, _default, defaultValue);
+ }
+}
+var _builtins = /*#__PURE__*/ new WeakMap();
+export class Builtins {
+ static empty() {
+ return new Builtins({});
+ }
+ static from(config) {
+ return new Builtins(mapEntries(config, (config, name)=>[
+ name,
+ new Builtin(config)
+ ]));
+ }
+ custom(name, render) {
+ return new Builtins(_objectSpreadProps(_objectSpread({}, _classPrivateFieldGet(this, _builtins)), {
+ [name]: new Builtin({
+ render
+ })
+ }));
+ }
+ basic(name, config) {
+ return new Builtins(_objectSpreadProps(_objectSpread({}, _classPrivateFieldGet(this, _builtins)), {
+ [name]: new Builtin(ToBuiltinConfig(config))
+ }));
+ }
+ tryGet(name) {
+ return _classPrivateFieldGet(this, _builtins)[name];
+ }
+ get(name) {
+ return _classPrivateFieldGet(this, _builtins)[name];
+ }
+ constructor(builtins){
+ _classPrivateFieldInit(this, _builtins, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _builtins, builtins);
+ }
+}
+export function styles(color, otherStyles = {}) {
+ return encode(_objectSpread({}, namespaceStyle({
+ "border-color": fg(color),
+ fg: fg(color),
+ bg: bg(color, "ultramuted"),
+ "accent-fg": fg(color, "dim"),
+ "accent-hover-bg": bg(color, "strong"),
+ "code-border": fg(color, "muted"),
+ "code-bg": bg(color, "muted"),
+ "code-fg": bg(color, "dim")
+ }), otherStyles));
+}
+export function namespaceStyle(styles) {
+ return Object.fromEntries(Object.entries(styles).map(([k, v])=>[
+ `--sbdoc-block-${k}`,
+ `var(--sb-${v})`
+ ]));
+}
+export function fg(color, style) {
+ if (style) {
+ return `fg-${color}-${style}`;
+ } else {
+ return `fg-${color}`;
+ }
+}
+export function bg(color, style) {
+ if (style) {
+ return `bg-${color}-${style}`;
+ } else {
+ return `bg-${color}`;
+ }
+}
+export function encode(attrs) {
+ if (attrs === undefined) {
+ return "";
+ }
+ return JSON.stringify(attrs).replace(/\"/g, "'");
+}
+export function CustomEl(kind, options, children) {
+ var _options_border;
+ return El(CUSTOM_EL, {
+ kind,
+ border: (_options_border = options.border) !== null && _options_border !== void 0 ? _options_border : "nsew",
+ color: options.color,
+ ":style": encode(options.style)
+ }, children);
+}
+
+
+//# sourceMappingURL=define.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/define.js.map b/packages/@starbeam-docs/fenced-container/dist/define.js.map
new file mode 100644
index 0000000..ef27446
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/define.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/define.ts"],"names":[],"mappings":"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","file":"define.js","sourcesContent":["import type { PluginHelper } from \"@jsergo/mdit\";\nimport \"@mdit-vue/plugin-sfc\";\nimport { mapEntries } from \"@wycatsjs/utils\";\nimport parseFence from \"fenceparser\";\nimport Token from \"markdown-it/lib/token.js\";\nimport { El, InlineHtml, type LazyChildren } from \"./nodes.js\";\nimport {\n BasicFragment,\n CustomBuiltin,\n MarkdownElement,\n type Children,\n type LazyChild,\n type TextLike,\n} from \"./tokens.js\";\n\ntype OBJECT = ReturnType;\ntype VALUE = OBJECT[keyof OBJECT];\nexport const CUSTOM_EL = \"CustomBlock\";\n\ninterface RenderOptions {\n kind: string;\n /**\n * false means \"leave out the title\"\n * undefined means \"use the default title\"\n */\n title: Title;\n attrs: Record;\n content: UnparsedContent | undefined;\n md: PluginHelper;\n}\n\nexport class UnparsedContent implements LazyChild {\n static of(content: string | undefined): UnparsedContent {\n return new UnparsedContent(content);\n }\n\n readonly #content: string | undefined;\n\n private constructor(content: string | undefined) {\n this.#content = content;\n }\n\n get raw(): string | undefined {\n return this.#content;\n }\n\n render(tokens: MarkdownElement): MarkdownElement {\n if (this.#content) {\n return tokens.blockHtml(this.#content);\n }\n return tokens;\n }\n}\n\ntype RenderContainer = ({\n title,\n kind,\n attrs,\n content,\n md,\n define,\n}: {\n title: Title;\n kind: string;\n attrs: Record;\n content: UnparsedContent | undefined;\n md: PluginHelper;\n define: CustomBuiltin;\n}) => LazyChildren;\n\ntype BuiltinConfig =\n | {\n defaultTitle?: string | null | undefined;\n color: string;\n }\n | CustomConfig;\n\n/**\n * A bare string is the default title.\n */\ntype BasicConfig =\n | {\n defaultTitle?: string | null | undefined;\n color?: string;\n }\n | string;\n\nconst DEFAULT_COLOR = \"theme\";\n\nfunction ToBuiltinConfig(\n config: BasicConfig | undefined\n): BuiltinConfig {\n if (config === undefined || typeof config === \"string\") {\n return {\n defaultTitle: config ?? null,\n color: DEFAULT_COLOR,\n };\n } else {\n return {\n color: \"theme\",\n ...config,\n };\n }\n}\n\ninterface CustomConfig {\n render: RenderContainer;\n options?: {} | undefined;\n}\n\nclass Builtin {\n readonly #config: BuiltinConfig;\n\n constructor(config: BuiltinConfig) {\n this.#config = config;\n }\n\n render(options: RenderOptions): Token[] {\n const result = this.#renderFn({\n ...options,\n define: new CustomBuiltin(options.md),\n });\n\n const fragment = BasicFragment.empty(options.md);\n\n if (Array.isArray(result)) {\n fragment.push(...result);\n } else {\n fragment.push(result);\n }\n\n return fragment.done();\n }\n\n get #renderFn(): RenderContainer {\n if (\n typeof this.#config === \"object\" &&\n \"render\" in this.#config\n ) {\n return this.#config.render;\n }\n\n const color = this.#config.color;\n\n return ({ kind, title: providedTitle, content }) => {\n const title = providedTitle.withDefault(\n this.#defaultTitle ?? undefined\n );\n\n return CustomEl(\n kind,\n {\n color: color ?? DEFAULT_COLOR,\n },\n [\n title.map((t) =>\n El(\"p\", { class: \"custom-block-title\" }, [\n InlineHtml(t),\n ])\n ),\n content,\n ]\n );\n };\n }\n\n get #defaultTitle(): string | void {\n if (\n typeof this.#config === \"object\" &&\n \"defaultTitle\" in this.#config &&\n typeof this.#config.defaultTitle === \"string\"\n ) {\n return this.#config.defaultTitle;\n }\n }\n}\n\nexport class Title implements LazyChild, TextLike {\n static provided(provided: string | false | undefined): Title {\n return new Title(provided, undefined);\n }\n\n static create(\n provided: string | false | undefined,\n defaultValue: string | undefined\n ): Title {\n return new Title(provided, defaultValue);\n }\n\n readonly #provided: string | undefined | false;\n readonly #default: string | undefined;\n\n private constructor(\n provided: string | false | undefined,\n defaultValue: string | undefined\n ) {\n this.#provided = provided;\n this.#default = defaultValue;\n }\n\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return `Title(${JSON.stringify(String(this))})`;\n }\n\n withDefault(defaultValue: string | undefined): Title {\n return new Title(this.#provided, defaultValue);\n }\n\n render(tokens: MarkdownElement): MarkdownElement {\n return tokens.append(InlineHtml(this));\n }\n\n isBlank(): boolean {\n return this.#provided === false;\n }\n\n map(callback: (title: string) => T): T | null {\n const title = String(this);\n\n if (title === \"\") {\n return null;\n } else {\n return callback(title);\n }\n }\n\n exists(): boolean {\n if (this.#provided === false) {\n return false;\n } else if (this.#provided === undefined) {\n return this.#default !== undefined;\n } else {\n return true;\n }\n }\n\n get provided(): string | undefined | false {\n return this.#provided;\n }\n\n stringify(): string {\n if (this.#provided === false) {\n return \"\";\n } else if (this.#provided === undefined) {\n return this.#default ?? \"\";\n } else {\n return this.#provided;\n }\n }\n\n toString(): string {\n return this.stringify();\n }\n}\n\nexport class Builtins {\n static empty(): Builtins {\n return new Builtins({});\n }\n\n static from(\n config: Record\n ) {\n return new Builtins(\n mapEntries(config, (config, name) => [\n name,\n new Builtin(config),\n ])\n );\n }\n\n readonly #builtins: Record;\n\n constructor(builtins: Record) {\n this.#builtins = builtins;\n }\n\n custom(\n name: NewName,\n render: RenderContainer\n ): Builtins {\n return new Builtins({\n ...this.#builtins,\n [name]: new Builtin({\n render,\n }),\n } as Record);\n }\n\n basic(\n name: NewName,\n config?: BasicConfig\n ): Builtins {\n return new Builtins({\n ...this.#builtins,\n [name]: new Builtin(ToBuiltinConfig(config)),\n });\n }\n\n tryGet(name: string): Builtin | undefined {\n return (this.#builtins as Record)[name];\n }\n\n get(name: N): Builtin {\n return this.#builtins[name];\n }\n}\n\nexport function styles(\n color: string,\n otherStyles: Record = {}\n) {\n return encode({\n ...namespaceStyle({\n \"border-color\": fg(color),\n fg: fg(color),\n bg: bg(color, \"ultramuted\"),\n \"accent-fg\": fg(color, \"dim\"),\n \"accent-hover-bg\": bg(color, \"strong\"),\n \"code-border\": fg(color, \"muted\"),\n \"code-bg\": bg(color, \"muted\"),\n \"code-fg\": bg(color, \"dim\"),\n }),\n ...otherStyles,\n });\n}\n\nexport function namespaceStyle(styles: Record) {\n return Object.fromEntries(\n Object.entries(styles).map(([k, v]) => [\n `--sbdoc-block-${k}`,\n `var(--sb-${v})`,\n ])\n );\n}\n\nexport function fg(color: string, style?: string) {\n if (style) {\n return `fg-${color}-${style}`;\n } else {\n return `fg-${color}`;\n }\n}\n\nexport function bg(color: string, style?: string) {\n if (style) {\n return `bg-${color}-${style}`;\n } else {\n return `bg-${color}`;\n }\n}\n\nexport function encode(\n attrs?: Record<\n string,\n string | number | boolean | null | undefined\n >\n): string {\n if (attrs === undefined) {\n return \"\";\n }\n return JSON.stringify(attrs).replace(/\\\"/g, \"'\");\n}\n\ntype BlockBorder = \"n\" | \"s\" | \"ns\" | \"\";\ntype InlineBorder = \"e\" | \"w\" | \"ew\" | \"\";\ntype Border = `${BlockBorder}${InlineBorder}`;\n\nexport function CustomEl(\n kind: string,\n options: {\n color: string;\n border?: Border;\n style?: Record;\n },\n children?: Children\n) {\n return El(\n CUSTOM_EL,\n {\n kind,\n border: options.border ?? \"nsew\",\n color: options.color,\n \":style\": encode(options.style),\n },\n children\n );\n}\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/index.js b/packages/@starbeam-docs/fenced-container/dist/index.js
new file mode 100644
index 0000000..c1fb1e3
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/index.js
@@ -0,0 +1,4 @@
+export { fencedContainerPlugin as default } from "./builtins.js";
+
+
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/index.js.map b/packages/@starbeam-docs/fenced-container/dist/index.js.map
new file mode 100644
index 0000000..2e5bd5e
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS,yBAAyB,OAAO,QAAQ,gBAAgB","file":"index.js","sourcesContent":["export { fencedContainerPlugin as default } from \"./builtins.js\";\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/nodes.js b/packages/@starbeam-docs/fenced-container/dist/nodes.js
new file mode 100644
index 0000000..2a9e2ae
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/nodes.js
@@ -0,0 +1,69 @@
+import Token from "markdown-it/lib/token.js";
+export function Fragment(...children) {
+ return {
+ render: (fragment)=>fragment.push(...children)
+ };
+}
+export function El(...args) {
+ return {
+ render: (fragment)=>fragment.el(...args)
+ };
+}
+export function BlockHtml(text) {
+ return {
+ render: (fragment)=>fragment.blockHtml(text)
+ };
+}
+export function InlineHtml(text) {
+ return {
+ render: (fragment)=>fragment.inlineHtml(String(text))
+ };
+}
+export function HtmlEl(...args) {
+ return {
+ render: (fragment)=>fragment.htmlEl(...args)
+ };
+}
+export function Do(then) {
+ return {
+ render: (fragment)=>render(fragment, then())
+ };
+}
+export function Let(values, then) {
+ return {
+ render: (fragment)=>render(fragment, then(values))
+ };
+}
+export function If(condition, then, options) {
+ return {
+ render: (fragment)=>{
+ if (condition) {
+ return render(fragment, then(condition));
+ } else if (options === null || options === void 0 ? void 0 : options.else) {
+ return render(fragment, options.else());
+ } else {
+ return fragment;
+ }
+ }
+ };
+}
+export function HTML(value) {
+ const html = new Token("html_block", value, 0);
+ html.content = value;
+ return {
+ render: (tokens)=>tokens.append(html)
+ };
+}
+function render(fragment, children) {
+ if (Array.isArray(children)) {
+ for (const child of children){
+ child.render(fragment);
+ }
+ } else {
+ children.render(fragment);
+ }
+ return fragment;
+}
+
+
+//# sourceMappingURL=nodes.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/nodes.js.map b/packages/@starbeam-docs/fenced-container/dist/nodes.js.map
new file mode 100644
index 0000000..b8e9bd6
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/nodes.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,2BAA2B;AAU7C,OAAO,SAAS,SAAS,GAAG,QAAiB,EAAa;IACxD,OAAO;QACL,QAAQ,CAAC,WAAa,SAAS,IAAI,IAAI;IACzC;AACF,CAAC;AAED,OAAO,SAAS,GACd,GAAG,IAAwC,EAChC;IACX,OAAO;QACL,QAAQ,CAAC,WAAa,SAAS,EAAE,IAAI;IACvC;AACF,CAAC;AAED,OAAO,SAAS,UAAU,IAAc,EAAa;IACnD,OAAO;QACL,QAAQ,CAAC,WAAa,SAAS,SAAS,CAAC;IAC3C;AACF,CAAC;AAED,OAAO,SAAS,WAAW,IAAc,EAAa;IACpD,OAAO;QACL,QAAQ,CAAC,WAAa,SAAS,UAAU,CAAC,OAAO;IACnD;AACF,CAAC;AAED,OAAO,SAAS,OACd,GAAG,IAAwC,EAChC;IACX,OAAO;QACL,QAAQ,CAAC,WAAa,SAAS,MAAM,IAAI;IAC3C;AACF,CAAC;AAED,OAAO,SAAS,GAAG,IAAuB,EAAa;IACrD,OAAO;QACL,QAAQ,CAAC,WAAa,OAAO,UAAU;IACzC;AACF,CAAC;AAED,OAAO,SAAS,IACd,MAAS,EACT,IAAiC,EACtB;IACX,OAAO;QACL,QAAQ,CAAC,WAAa,OAAO,UAAU,KAAK;IAC9C;AACF,CAAC;AAED,OAAO,SAAS,GACd,SAAY,EACZ,IAAgD,EAChD,OAEC,EACU;IACX,OAAO;QACL,QAAQ,CAAC,WAAa;YACpB,IAAI,WAAW;gBACb,OAAO,OACL,UACA,KAAK;YAET,OAAO,IAAI,oBAAA,qBAAA,KAAA,IAAA,QAAS,IAAI,EAAE;gBACxB,OAAO,OAAO,UAAU,QAAQ,IAAI;YACtC,OAAO;gBACL,OAAO;YACT,CAAC;QACH;IACF;AACF,CAAC;AAED,OAAO,SAAS,KAAK,KAAa,EAAa;IAC7C,MAAM,OAAO,IAAI,MAAM,cAAc,OAAO;IAC5C,KAAK,OAAO,GAAG;IACf,OAAO;QACL,QAAQ,CAAC,SAAW,OAAO,MAAM,CAAC;IACpC;AACF,CAAC;AAID,SAAS,OACP,QAA0B,EAC1B,QAAsB,EACJ;IAClB,IAAI,MAAM,OAAO,CAAC,WAAW;QAC3B,KAAK,MAAM,SAAS,SAAU;YAC5B,MAAM,MAAM,CAAC;QACf;IACF,OAAO;QACL,SAAS,MAAM,CAAC;IAClB,CAAC;IACD,OAAO;AACT","file":"nodes.js","sourcesContent":["import Token from \"markdown-it/lib/token.js\";\nimport {\n MarkdownFragment,\n type Child,\n type LazyChild,\n type ToString,\n} from \"./tokens.js\";\n\nexport type Falsy = null | undefined | false | 0 | \"\";\n\nexport function Fragment(...children: Child[]): LazyChild {\n return {\n render: (fragment) => fragment.push(...children),\n };\n}\n\nexport function El(\n ...args: Parameters\n): LazyChild {\n return {\n render: (fragment) => fragment.el(...args),\n };\n}\n\nexport function BlockHtml(text: ToString): LazyChild {\n return {\n render: (fragment) => fragment.blockHtml(text),\n };\n}\n\nexport function InlineHtml(text: ToString): LazyChild {\n return {\n render: (fragment) => fragment.inlineHtml(String(text)),\n };\n}\n\nexport function HtmlEl(\n ...args: Parameters\n): LazyChild {\n return {\n render: (fragment) => fragment.htmlEl(...args),\n };\n}\n\nexport function Do(then: () => LazyChild[]): LazyChild {\n return {\n render: (fragment) => render(fragment, then()),\n };\n}\n\nexport function Let(\n values: T,\n then: (values: T) => LazyChildren\n): LazyChild {\n return {\n render: (fragment) => render(fragment, then(values)),\n };\n}\n\nexport function If(\n condition: T,\n then: (value: Exclude) => LazyChildren,\n options?: {\n else: () => LazyChildren;\n }\n): LazyChild {\n return {\n render: (fragment) => {\n if (condition) {\n return render(\n fragment,\n then(condition as Exclude)\n );\n } else if (options?.else) {\n return render(fragment, options.else());\n } else {\n return fragment;\n }\n },\n } satisfies LazyChild;\n}\n\nexport function HTML(value: string): LazyChild {\n const html = new Token(\"html_block\", value, 0);\n html.content = value;\n return {\n render: (tokens) => tokens.append(html),\n };\n}\n\nexport type LazyChildren = LazyChild | LazyChild[];\n\nfunction render(\n fragment: MarkdownFragment,\n children: LazyChildren\n): MarkdownFragment {\n if (Array.isArray(children)) {\n for (const child of children) {\n child.render(fragment);\n }\n } else {\n children.render(fragment);\n }\n return fragment;\n}\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/tokens.js b/packages/@starbeam-docs/fenced-container/dist/tokens.js
new file mode 100644
index 0000000..2be4862
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/tokens.js
@@ -0,0 +1,322 @@
+function _checkPrivateRedeclaration(obj, privateCollection) {
+ if (privateCollection.has(obj)) {
+ throw new TypeError("Cannot initialize the same private elements twice on an object");
+ }
+}
+function _classApplyDescriptorGet(receiver, descriptor) {
+ if (descriptor.get) {
+ return descriptor.get.call(receiver);
+ }
+ return descriptor.value;
+}
+function _classApplyDescriptorSet(receiver, descriptor, value) {
+ if (descriptor.set) {
+ descriptor.set.call(receiver, value);
+ } else {
+ if (!descriptor.writable) {
+ throw new TypeError("attempted to set read only private field");
+ }
+ descriptor.value = value;
+ }
+}
+function _classExtractFieldDescriptor(receiver, privateMap, action) {
+ if (!privateMap.has(receiver)) {
+ throw new TypeError("attempted to " + action + " private field on non-instance");
+ }
+ return privateMap.get(receiver);
+}
+function _classPrivateFieldGet(receiver, privateMap) {
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
+ return _classApplyDescriptorGet(receiver, descriptor);
+}
+function _classPrivateFieldInit(obj, privateMap, value) {
+ _checkPrivateRedeclaration(obj, privateMap);
+ privateMap.set(obj, value);
+}
+function _classPrivateFieldSet(receiver, privateMap, value) {
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
+ _classApplyDescriptorSet(receiver, descriptor, value);
+ return value;
+}
+function _classPrivateMethodGet(receiver, privateSet, fn) {
+ if (!privateSet.has(receiver)) {
+ throw new TypeError("attempted to get private field on non-instance");
+ }
+ return fn;
+}
+function _classPrivateMethodInit(obj, privateSet) {
+ _checkPrivateRedeclaration(obj, privateSet);
+ privateSet.add(obj);
+}
+import Token from "markdown-it/lib/token.js";
+var _md = /*#__PURE__*/ new WeakMap();
+export class CustomBuiltin {
+ el(tag, attrs, children) {
+ return ParagraphElement.tag(tag, _classPrivateFieldGet(this, _md)).attrs(attrs).push(...children);
+ }
+ constructor(md){
+ _classPrivateFieldInit(this, _md, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _md, md);
+ }
+}
+var _md1 = /*#__PURE__*/ new WeakMap();
+export class MarkdownFragment {
+ render(tokens) {
+ return tokens.push(...this.done());
+ }
+ get md() {
+ return _classPrivateFieldGet(this, _md1);
+ }
+ blockHtml(markdown) {
+ this.push(...this.md.parseBlock(ToString(markdown)));
+ return this;
+ }
+ inlineHtml(markdown) {
+ this.push(...this.md.parseInline(ToString(markdown)));
+ return this;
+ }
+ append(child) {
+ if (child === undefined || child === null) {
+ // do nothing
+ } else if (typeof child === "string") {
+ this.appendToken(text(child));
+ } else if ("render" in child) {
+ child.render(this);
+ } else {
+ this.appendToken(child);
+ }
+ return this;
+ }
+ push(...children) {
+ for (const child of children){
+ this.append(child);
+ }
+ return this;
+ }
+ element({ tag , attrs , children }, { create }) {
+ let el = create.tag(tag, this.md).attrs(attrs);
+ if (Array.isArray(children)) {
+ for (const child of children){
+ el.append(child);
+ }
+ } else if (typeof children === "function") {
+ children(this);
+ }
+ this.push(...el.done());
+ return this;
+ }
+ htmlEl(...elArgs) {
+ return this.element(normalizeElArgs(elArgs), {
+ create: HtmlElement
+ });
+ }
+ el(...elArgs) {
+ return this.element(normalizeElArgs(elArgs), {
+ create: ParagraphElement
+ });
+ }
+ constructor(md){
+ _classPrivateFieldInit(this, _md1, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _md1, md);
+ }
+}
+export class MarkdownElement extends MarkdownFragment {
+ attrs(attrs) {
+ for (const [key, value] of Object.entries(attrs)){
+ this.attr(key, value);
+ }
+ return this;
+ }
+ renderInline(text) {
+ return this.md.renderInline(text);
+ }
+ constructor(_tag, md){
+ super(md);
+ }
+}
+var _tokens = /*#__PURE__*/ new WeakMap();
+export class BasicFragment extends MarkdownFragment {
+ static empty(md) {
+ return new BasicFragment(md);
+ }
+ appendToken(token) {
+ _classPrivateFieldGet(this, _tokens).push(token);
+ }
+ done() {
+ return _classPrivateFieldGet(this, _tokens);
+ }
+ constructor(...args){
+ super(...args);
+ _classPrivateFieldInit(this, _tokens, {
+ writable: true,
+ value: []
+ });
+ }
+}
+var _tag = /*#__PURE__*/ new WeakMap(), _open = /*#__PURE__*/ new WeakMap(), _children = /*#__PURE__*/ new WeakMap(), _attrValue = /*#__PURE__*/ new WeakSet();
+export class HtmlElement extends MarkdownElement {
+ static tag(tag, md) {
+ return new HtmlElement(tag, md);
+ }
+ attr(key, value) {
+ const valueString = _classPrivateMethodGet(this, _attrValue, attrValue).call(this, value);
+ if (valueString !== null) {
+ _classPrivateFieldSet(this, _open, _classPrivateFieldGet(this, _open) + ` ${key}=${valueString}`);
+ }
+ return this;
+ }
+ done() {
+ const open = new Token("html_block", "", 0);
+ open.content = `${_classPrivateFieldGet(this, _open)}\n\n`;
+ const tokens = [
+ open
+ ];
+ tokens.push(..._classPrivateFieldGet(this, _children));
+ const close = new Token("html_block", "", 0);
+ close.content = `\n\n${_classPrivateFieldGet(this, _tag)}>`;
+ tokens.push(close);
+ return tokens;
+ }
+ appendToken(token) {
+ if (!_classPrivateFieldGet(this, _open).endsWith(">")) _classPrivateFieldSet(this, _open, _classPrivateFieldGet(this, _open) + ">");
+ _classPrivateFieldGet(this, _children).push(token);
+ }
+ constructor(tag, md){
+ super(tag, md);
+ _classPrivateMethodInit(this, _attrValue);
+ _classPrivateFieldInit(this, _tag, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldInit(this, _open, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldInit(this, _children, {
+ writable: true,
+ value: []
+ });
+ _classPrivateFieldSet(this, _tag, tag);
+ _classPrivateFieldSet(this, _open, `<${_classPrivateFieldGet(this, _tag)}`);
+ }
+}
+function attrValue(value) {
+ if (Array.isArray(value)) {
+ return `"${value.join(" ")}`;
+ } else if (typeof value === "string") {
+ return JSON.stringify(value);
+ } else if (typeof value === "number") {
+ return `"${value}"`;
+ } else if (value === true) {
+ return `""`;
+ } else {
+ return null;
+ }
+}
+var _tag1 = /*#__PURE__*/ new WeakMap(), _token = /*#__PURE__*/ new WeakMap(), _children1 = /*#__PURE__*/ new WeakMap();
+export class ParagraphElement extends MarkdownElement {
+ static tag(tag, md) {
+ return new ParagraphElement(md, tag, new Token("paragraph_open", tag, 1), []);
+ }
+ appendToken(token) {
+ _classPrivateFieldGet(this, _children1).push(token);
+ }
+ done() {
+ return [
+ _classPrivateFieldGet(this, _token),
+ ..._classPrivateFieldGet(this, _children1),
+ new Token("paragraph_close", _classPrivateFieldGet(this, _tag1), -1)
+ ];
+ }
+ attr(name, value) {
+ if (value === undefined || value === false) {
+ // do nothing
+ } else if (Array.isArray(value)) {
+ for (const val of attrListValue(value)){
+ _classPrivateFieldGet(this, _token).attrJoin(name, val);
+ }
+ } else if (value === true) {
+ _classPrivateFieldGet(this, _token).attrSet(name, "");
+ } else {
+ const val = attrPart(value);
+ if (val) {
+ _classPrivateFieldGet(this, _token).attrSet(name, val);
+ }
+ }
+ return this;
+ }
+ constructor(md, tag, token, children){
+ super(tag, md);
+ _classPrivateFieldInit(this, _tag1, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldInit(this, _token, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldInit(this, _children1, {
+ writable: true,
+ value: void 0
+ });
+ _classPrivateFieldSet(this, _tag1, tag);
+ _classPrivateFieldSet(this, _token, token);
+ _classPrivateFieldSet(this, _children1, children);
+ }
+}
+function ToString(stringlike) {
+ if (typeof stringlike !== "object") {
+ return String(stringlike);
+ } else {
+ return stringlike.stringify();
+ }
+}
+export function text(string) {
+ const token = new Token("text", "", 0);
+ token.content = ToString(string);
+ return token;
+}
+function attrListValue(value) {
+ return value.map(attrPart).filter(isPresent);
+}
+function attrPart(value) {
+ if (value === undefined || value === null) {
+ return undefined;
+ } else if (typeof value === "number") {
+ return String(value);
+ } else if (typeof value === "string") {
+ return value;
+ } else {
+ throw unreachable(value);
+ }
+}
+function isPresent(value) {
+ return value !== null && value !== undefined;
+}
+function unreachable(_value, message = "unreachable") {
+ throw new Error(message);
+}
+function normalizeElArgs([tag, attrs, children]) {
+ if (attrs === undefined || Array.isArray(attrs) || typeof attrs === "function") {
+ return {
+ tag,
+ attrs: {},
+ children: attrs
+ };
+ } else {
+ return {
+ tag,
+ attrs,
+ children
+ };
+ }
+}
+
+
+//# sourceMappingURL=tokens.js.map
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/dist/tokens.js.map b/packages/@starbeam-docs/fenced-container/dist/tokens.js.map
new file mode 100644
index 0000000..456dfb8
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/dist/tokens.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/tokens.ts"],"names":[],"mappings":"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","file":"tokens.js","sourcesContent":["import type { PluginHelper } from \"@jsergo/mdit\";\nimport Token from \"markdown-it/lib/token.js\";\n\nexport type SingleAttrValue = AttrPart | boolean;\nexport type AttrPart = string | number | null | undefined;\nexport type AttrValue = SingleAttrValue | AttrPart[];\n\nexport class CustomBuiltin {\n readonly #md: PluginHelper;\n\n constructor(md: PluginHelper) {\n this.#md = md;\n }\n\n el(\n tag: string,\n attrs: Record,\n children: Child[]\n ): MarkdownElement {\n return ParagraphElement.tag(tag, this.#md)\n .attrs(attrs)\n .push(...children);\n }\n}\n\nexport abstract class MarkdownFragment implements LazyChild {\n abstract done(): Token[];\n protected abstract appendToken(token: Token): void;\n\n #md: PluginHelper;\n\n constructor(md: PluginHelper) {\n this.#md = md;\n }\n\n render(tokens: MarkdownFragment): MarkdownFragment {\n return tokens.push(...this.done());\n }\n\n protected get md(): PluginHelper {\n return this.#md;\n }\n\n blockHtml(markdown: ToString): this {\n this.push(...this.md.parseBlock(ToString(markdown)));\n return this;\n }\n\n inlineHtml(markdown: ToString): this {\n this.push(...this.md.parseInline(ToString(markdown)));\n return this;\n }\n\n append(child: Child): this {\n if (child === undefined || child === null) {\n // do nothing\n } else if (typeof child === \"string\") {\n this.appendToken(text(child));\n } else if (\"render\" in child) {\n child.render(this);\n } else {\n this.appendToken(child);\n }\n\n return this;\n }\n\n push(...children: Child[]): this {\n for (const child of children) {\n this.append(child);\n }\n return this;\n }\n\n element(\n {\n tag,\n attrs,\n children,\n }: {\n tag: string;\n attrs: Record;\n children: Children | undefined;\n },\n {\n create,\n }: {\n create: {\n tag: (tag: string, md: PluginHelper) => MarkdownElement;\n };\n }\n ): this {\n let el = create.tag(tag, this.md).attrs(attrs);\n\n if (Array.isArray(children)) {\n for (const child of children) {\n el.append(child);\n }\n } else if (typeof children === \"function\") {\n children(this);\n }\n\n this.push(...el.done());\n\n return this;\n }\n\n htmlEl(...elArgs: ElArgs): this {\n return this.element(normalizeElArgs(elArgs), {\n create: HtmlElement,\n });\n }\n\n el(...elArgs: ElArgs): this {\n return this.element(normalizeElArgs(elArgs), {\n create: ParagraphElement,\n });\n }\n}\n\nexport abstract class MarkdownElement extends MarkdownFragment {\n abstract attr(key: string, value: AttrValue): this;\n\n constructor(_tag: string, md: PluginHelper) {\n super(md);\n }\n\n attrs(attrs: Record): this {\n for (const [key, value] of Object.entries(attrs)) {\n this.attr(key, value);\n }\n return this;\n }\n\n renderInline(text: string): string {\n return this.md.renderInline(text);\n }\n}\n\nexport class BasicFragment extends MarkdownFragment {\n static empty(md: PluginHelper): MarkdownFragment {\n return new BasicFragment(md);\n }\n\n readonly #tokens: Token[] = [];\n\n protected override appendToken(token: Token): void {\n this.#tokens.push(token);\n }\n\n override done(): Token[] {\n return this.#tokens;\n }\n}\n\nexport class HtmlElement extends MarkdownElement {\n static tag(tag: string, md: PluginHelper): MarkdownElement {\n return new HtmlElement(tag, md);\n }\n\n readonly #tag: string;\n #open: string;\n readonly #children: Token[] = [];\n\n private constructor(tag: string, md: PluginHelper) {\n super(tag, md);\n this.#tag = tag;\n\n this.#open = `<${this.#tag}`;\n }\n\n override attr(key: string, value: AttrValue): this {\n const valueString = this.#attrValue(value);\n\n if (valueString !== null) {\n this.#open += ` ${key}=${valueString}`;\n }\n\n return this;\n }\n\n #attrValue(value: AttrValue): string | null {\n if (Array.isArray(value)) {\n return `\"${value.join(\" \")}`;\n } else if (typeof value === \"string\") {\n return JSON.stringify(value);\n } else if (typeof value === \"number\") {\n return `\"${value}\"`;\n } else if (value === true) {\n return `\"\"`;\n } else {\n return null;\n }\n }\n\n override done(): Token[] {\n const open = new Token(\"html_block\", \"\", 0);\n open.content = `${this.#open}\\n\\n`;\n const tokens: Token[] = [open];\n tokens.push(...this.#children);\n\n const close = new Token(\"html_block\", \"\", 0);\n close.content = `\\n\\n${this.#tag}>`;\n tokens.push(close);\n\n return tokens;\n }\n\n protected override appendToken(token: Token): void {\n if (!this.#open.endsWith(\">\")) this.#open += \">\";\n\n this.#children.push(token);\n }\n}\n\nexport class ParagraphElement extends MarkdownElement {\n static tag(tag: string, md: PluginHelper): ParagraphElement {\n return new ParagraphElement(\n md,\n tag,\n new Token(\"paragraph_open\", tag, 1),\n []\n );\n }\n\n readonly #tag: string;\n readonly #token: Token;\n readonly #children: Token[];\n\n private constructor(\n md: PluginHelper,\n tag: string,\n token: Token,\n children: Token[]\n ) {\n super(tag, md);\n this.#tag = tag;\n this.#token = token;\n this.#children = children;\n }\n\n protected override appendToken(token: Token): void {\n this.#children.push(token);\n }\n\n done(): Token[] {\n return [\n this.#token,\n ...this.#children,\n new Token(\"paragraph_close\", this.#tag, -1),\n ];\n }\n\n attr(name: string, value: AttrValue): this {\n if (value === undefined || value === false) {\n // do nothing\n } else if (Array.isArray(value)) {\n for (const val of attrListValue(value)) {\n this.#token.attrJoin(name, val);\n }\n } else if (value === true) {\n this.#token.attrSet(name, \"\");\n } else {\n const val = attrPart(value);\n if (val) {\n this.#token.attrSet(name, val);\n }\n }\n\n return this;\n }\n}\n\nexport type Child =\n | LazyChild\n | Token\n | string\n | null\n | undefined;\n\nexport type Children =\n | Child[]\n | ((el: MarkdownFragment) => MarkdownFragment);\n\nexport interface LazyChild {\n render(tokens: MarkdownFragment): MarkdownFragment;\n}\n\nexport interface TextLike {\n stringify(): string;\n}\n\nexport type ToString = TextLike | string | number | boolean;\n\nfunction ToString(stringlike: ToString): string {\n if (typeof stringlike !== \"object\") {\n return String(stringlike);\n } else {\n return stringlike.stringify();\n }\n}\n\nexport function text(string: ToString): Token {\n const token = new Token(\"text\", \"\", 0);\n token.content = ToString(string);\n return token;\n}\n\nfunction attrListValue(value: AttrPart[]) {\n return value.map(attrPart).filter(isPresent);\n}\n\nfunction attrPart(value: AttrPart): string | undefined {\n if (value === undefined || value === null) {\n return undefined;\n } else if (typeof value === \"number\") {\n return String(value);\n } else if (typeof value === \"string\") {\n return value;\n } else {\n throw unreachable(value);\n }\n}\n\nfunction isPresent(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\nfunction unreachable(_value: never, message = \"unreachable\") {\n throw new Error(message);\n}\n\ntype ElArgs = [\n tag: string,\n attrs?: Record | Children | undefined,\n children?: Children\n];\n\nfunction normalizeElArgs([tag, attrs, children]: ElArgs): {\n tag: string;\n attrs: Record;\n children: Children | undefined;\n} {\n if (\n attrs === undefined ||\n Array.isArray(attrs) ||\n typeof attrs === \"function\"\n ) {\n return { tag, attrs: {}, children: attrs };\n } else {\n return { tag, attrs, children };\n }\n}\n"]}
\ No newline at end of file
diff --git a/packages/@starbeam-docs/fenced-container/package.json b/packages/@starbeam-docs/fenced-container/package.json
new file mode 100644
index 0000000..99f474f
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "@starbeam-docs/fenced-container",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "types": "./src/index.ts",
+ "default": "./dist/index.js"
+ },
+ "dependencies": {
+ "@wycatsjs/utils": "workspace:^"
+ }
+}
diff --git a/packages/@starbeam-docs/fenced-container/src/builtins.ts b/packages/@starbeam-docs/fenced-container/src/builtins.ts
new file mode 100644
index 0000000..e23e20f
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/src/builtins.ts
@@ -0,0 +1,249 @@
+import { parserPlugin } from "@jsergo/mdit";
+import "@mdit-vue/plugin-sfc";
+import parseFence from "fenceparser";
+import {
+ Builtins,
+ CUSTOM_EL,
+ CustomEl,
+ Title,
+ UnparsedContent,
+} from "./define.js";
+import { Do, El } from "./nodes.js";
+import type { AttrPart } from "./tokens.js";
+
+type OBJECT = ReturnType;
+type VALUE = OBJECT[keyof OBJECT];
+
+const BUILTINS = Builtins.empty()
+ .basic("info", {
+ defaultTitle: "INFO",
+ color: "blue",
+ })
+ .basic("construction", {
+ defaultTitle: "Under Construction",
+ color: "orange",
+ })
+ .basic("warning", {
+ color: "yellow",
+ })
+ .basic("error", {
+ color: "red",
+ })
+ .basic("tip", {
+ defaultTitle: null,
+ color: "green",
+ })
+ .basic("callout", { defaultTitle: null })
+ .custom("💡", ({ title, content }) =>
+ CustomEl(
+ "lightbulb",
+ {
+ border: "se",
+ color: "yellow",
+ style: {
+ "padding-block": "0.5em",
+ },
+ },
+ [title, content]
+ )
+ )
+ .custom("lang-ts", ({ content }) =>
+ CustomEl("lang-ts", { color: "neutral" }, [content])
+ )
+ .custom("em", ({ title, content }) =>
+ CustomEl(
+ "em",
+ {
+ color: "orange",
+ border: "w",
+ style: {
+ "font-size": `calc(1em * var(--sbdoc-ratio))`,
+ "font-weight": "600",
+ "border-size": "2px",
+ "line-height": "1",
+ },
+ },
+ [
+ title
+ .withDefault("Key Point")
+ .map((title) => El("h5", [title])),
+ content,
+ ]
+ )
+ )
+ .custom("persona", ({ title, content }) =>
+ El("aside", { class: ["persona", String(title)] }, [content])
+ )
+ .custom("details", ({ title, content, attrs }) => {
+ return El(CUSTOM_EL, { kind: "details", color: "gray" }, [
+ El(
+ "details",
+ {
+ class: [
+ "content-block",
+ "callout-block",
+ "container",
+ ...normalizePart(attrs["type"]),
+ ],
+ },
+ [
+ Do(() => {
+ function titleChild() {
+ switch (attrs["type"]) {
+ case "deep-dive":
+ // TODO:: Generalize
+ return [El("span", ["Deep Dive"]), title];
+ default:
+ return [title.withDefault("Details")];
+ }
+ }
+
+ return [
+ El(
+ "summary",
+ { class: "custom-block-title" },
+ titleChild()
+ ),
+ ];
+ }),
+ content,
+ ]
+ ),
+ ]);
+ });
+
+export const fencedContainerPlugin = parserPlugin({
+ name: "fenced-container",
+ before: "fence",
+}).block((line, md) => {
+ const matched = line.matchStart(/^(?````*)md /);
+
+ if (matched.type === "error") {
+ return () => (render) =>
+ render.html(md.error(matched.error));
+ } else if (matched.type === "unmatched") {
+ return false;
+ }
+
+ const ticks = matched.raw.groups?.["ticks"] as string;
+ const fenceline = line.string();
+ const info = fenceline.slice(matched.fragment.length);
+
+ // split the fenceline into the part before the first space (kind) and the
+ // part after it (params).
+ const [kind, params] = split2(info, " ");
+
+ if (kind === undefined) {
+ return false;
+ }
+
+ const builtin = BUILTINS.tryGet(kind);
+
+ if (builtin === undefined) {
+ return false;
+ }
+
+ return () => {
+ const fenceContent = line.next?.until(
+ (line) => line.slice()?.trim() === ticks
+ );
+
+ return (render) => {
+ const { title, attrs = {} } = parseTitle(params);
+
+ const rendered = builtin.render({
+ md,
+ kind,
+ title: Title.provided(title),
+ attrs,
+ content: UnparsedContent.of(fenceContent),
+ });
+
+ return render.tokens(rendered);
+ };
+ };
+});
+
+function parseTitle(params: string | undefined): {
+ /**
+ * false means "no title"
+ * undefined means "default title"
+ *
+ * if no title is provided, the value will be undefined
+ */
+ title?: string | false | undefined;
+ attrs?: Record | undefined;
+} {
+ if (params === undefined) {
+ return {};
+ }
+
+ const trimmed = params.trim();
+
+ if (trimmed.length === 0) {
+ return {};
+ }
+
+ const quotedString = trimmed.match(/^\s*"(.*)"\s*$/);
+
+ if (quotedString?.[1]) {
+ return { title: quotedString[1] };
+ }
+
+ if (trimmed.match(/[{=]/)) {
+ const parsed = parseFence(trimmed);
+
+ const title = getTitle(parsed["title"]);
+
+ return { title, attrs: parsed };
+ }
+
+ return { title: trimmed };
+}
+
+function getTitle(title: VALUE): string | false | undefined {
+ if (title === undefined) {
+ return undefined;
+ } else if (title === false || title === null) {
+ return false;
+ } else {
+ return String(title);
+ }
+}
+
+function split2(
+ string: string,
+ delimiter: string
+): [string, string | undefined] {
+ const index = string.indexOf(delimiter);
+ const p0 = index === -1 ? string : string.substring(0, index);
+ const p1 = index === -1 ? "" : string.substring(index + 1);
+
+ return [p0, p1];
+}
+
+function normalizePart(value: VALUE): AttrPart[] {
+ if (value === null || value === undefined) {
+ return [];
+ } else if (Array.isArray(value)) {
+ return value.flatMap(normalizePart).filter(isPresent);
+ } else if (typeof value === "string") {
+ return [value];
+ } else if (typeof value === "number") {
+ return [String(value)];
+ } else if (typeof value === "boolean") {
+ throw Error(
+ `Booleans are not supported as part of an attr array.`
+ );
+ } else {
+ throw Error(
+ `Object are not supported as part of an attr array. You passed ${JSON.stringify(
+ value
+ )}`
+ );
+ }
+}
+
+function isPresent(value: T | undefined | null): value is T {
+ return value !== undefined && value !== null;
+}
diff --git a/packages/@starbeam-docs/fenced-container/src/define.ts b/packages/@starbeam-docs/fenced-container/src/define.ts
new file mode 100644
index 0000000..565c436
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/src/define.ts
@@ -0,0 +1,388 @@
+import type { PluginHelper } from "@jsergo/mdit";
+import "@mdit-vue/plugin-sfc";
+import { mapEntries } from "@wycatsjs/utils";
+import parseFence from "fenceparser";
+import Token from "markdown-it/lib/token.js";
+import { El, InlineHtml, type LazyChildren } from "./nodes.js";
+import {
+ BasicFragment,
+ CustomBuiltin,
+ MarkdownElement,
+ type Children,
+ type LazyChild,
+ type TextLike,
+} from "./tokens.js";
+
+type OBJECT = ReturnType;
+type VALUE = OBJECT[keyof OBJECT];
+export const CUSTOM_EL = "CustomBlock";
+
+interface RenderOptions {
+ kind: string;
+ /**
+ * false means "leave out the title"
+ * undefined means "use the default title"
+ */
+ title: Title;
+ attrs: Record;
+ content: UnparsedContent | undefined;
+ md: PluginHelper;
+}
+
+export class UnparsedContent implements LazyChild {
+ static of(content: string | undefined): UnparsedContent {
+ return new UnparsedContent(content);
+ }
+
+ readonly #content: string | undefined;
+
+ private constructor(content: string | undefined) {
+ this.#content = content;
+ }
+
+ get raw(): string | undefined {
+ return this.#content;
+ }
+
+ render(tokens: MarkdownElement): MarkdownElement {
+ if (this.#content) {
+ return tokens.blockHtml(this.#content);
+ }
+ return tokens;
+ }
+}
+
+type RenderContainer = ({
+ title,
+ kind,
+ attrs,
+ content,
+ md,
+ define,
+}: {
+ title: Title;
+ kind: string;
+ attrs: Record;
+ content: UnparsedContent | undefined;
+ md: PluginHelper;
+ define: CustomBuiltin;
+}) => LazyChildren;
+
+type BuiltinConfig =
+ | {
+ defaultTitle?: string | null | undefined;
+ color: string;
+ }
+ | CustomConfig;
+
+/**
+ * A bare string is the default title.
+ */
+type BasicConfig =
+ | {
+ defaultTitle?: string | null | undefined;
+ color?: string;
+ }
+ | string;
+
+const DEFAULT_COLOR = "theme";
+
+function ToBuiltinConfig(
+ config: BasicConfig | undefined
+): BuiltinConfig {
+ if (config === undefined || typeof config === "string") {
+ return {
+ defaultTitle: config ?? null,
+ color: DEFAULT_COLOR,
+ };
+ } else {
+ return {
+ color: "theme",
+ ...config,
+ };
+ }
+}
+
+interface CustomConfig {
+ render: RenderContainer;
+ options?: {} | undefined;
+}
+
+class Builtin {
+ readonly #config: BuiltinConfig;
+
+ constructor(config: BuiltinConfig) {
+ this.#config = config;
+ }
+
+ render(options: RenderOptions): Token[] {
+ const result = this.#renderFn({
+ ...options,
+ define: new CustomBuiltin(options.md),
+ });
+
+ const fragment = BasicFragment.empty(options.md);
+
+ if (Array.isArray(result)) {
+ fragment.push(...result);
+ } else {
+ fragment.push(result);
+ }
+
+ return fragment.done();
+ }
+
+ get #renderFn(): RenderContainer {
+ if (
+ typeof this.#config === "object" &&
+ "render" in this.#config
+ ) {
+ return this.#config.render;
+ }
+
+ const color = this.#config.color;
+
+ return ({ kind, title: providedTitle, content }) => {
+ const title = providedTitle.withDefault(
+ this.#defaultTitle ?? undefined
+ );
+
+ return CustomEl(
+ kind,
+ {
+ color: color ?? DEFAULT_COLOR,
+ },
+ [
+ title.map((t) =>
+ El("p", { class: "custom-block-title" }, [
+ InlineHtml(t),
+ ])
+ ),
+ content,
+ ]
+ );
+ };
+ }
+
+ get #defaultTitle(): string | void {
+ if (
+ typeof this.#config === "object" &&
+ "defaultTitle" in this.#config &&
+ typeof this.#config.defaultTitle === "string"
+ ) {
+ return this.#config.defaultTitle;
+ }
+ }
+}
+
+export class Title implements LazyChild, TextLike {
+ static provided(provided: string | false | undefined): Title {
+ return new Title(provided, undefined);
+ }
+
+ static create(
+ provided: string | false | undefined,
+ defaultValue: string | undefined
+ ): Title {
+ return new Title(provided, defaultValue);
+ }
+
+ readonly #provided: string | undefined | false;
+ readonly #default: string | undefined;
+
+ private constructor(
+ provided: string | false | undefined,
+ defaultValue: string | undefined
+ ) {
+ this.#provided = provided;
+ this.#default = defaultValue;
+ }
+
+ [Symbol.for("nodejs.util.inspect.custom")]() {
+ return `Title(${JSON.stringify(String(this))})`;
+ }
+
+ withDefault(defaultValue: string | undefined): Title {
+ return new Title(this.#provided, defaultValue);
+ }
+
+ render(tokens: MarkdownElement): MarkdownElement {
+ return tokens.append(InlineHtml(this));
+ }
+
+ isBlank(): boolean {
+ return this.#provided === false;
+ }
+
+ map(callback: (title: string) => T): T | null {
+ const title = String(this);
+
+ if (title === "") {
+ return null;
+ } else {
+ return callback(title);
+ }
+ }
+
+ exists(): boolean {
+ if (this.#provided === false) {
+ return false;
+ } else if (this.#provided === undefined) {
+ return this.#default !== undefined;
+ } else {
+ return true;
+ }
+ }
+
+ get provided(): string | undefined | false {
+ return this.#provided;
+ }
+
+ stringify(): string {
+ if (this.#provided === false) {
+ return "";
+ } else if (this.#provided === undefined) {
+ return this.#default ?? "";
+ } else {
+ return this.#provided;
+ }
+ }
+
+ toString(): string {
+ return this.stringify();
+ }
+}
+
+export class Builtins {
+ static empty(): Builtins {
+ return new Builtins({});
+ }
+
+ static from(
+ config: Record
+ ) {
+ return new Builtins(
+ mapEntries(config, (config, name) => [
+ name,
+ new Builtin(config),
+ ])
+ );
+ }
+
+ readonly #builtins: Record;
+
+ constructor(builtins: Record) {
+ this.#builtins = builtins;
+ }
+
+ custom(
+ name: NewName,
+ render: RenderContainer
+ ): Builtins {
+ return new Builtins({
+ ...this.#builtins,
+ [name]: new Builtin({
+ render,
+ }),
+ } as Record);
+ }
+
+ basic(
+ name: NewName,
+ config?: BasicConfig
+ ): Builtins {
+ return new Builtins({
+ ...this.#builtins,
+ [name]: new Builtin(ToBuiltinConfig(config)),
+ });
+ }
+
+ tryGet(name: string): Builtin | undefined {
+ return (this.#builtins as Record)[name];
+ }
+
+ get(name: N): Builtin {
+ return this.#builtins[name];
+ }
+}
+
+export function styles(
+ color: string,
+ otherStyles: Record = {}
+) {
+ return encode({
+ ...namespaceStyle({
+ "border-color": fg(color),
+ fg: fg(color),
+ bg: bg(color, "ultramuted"),
+ "accent-fg": fg(color, "dim"),
+ "accent-hover-bg": bg(color, "strong"),
+ "code-border": fg(color, "muted"),
+ "code-bg": bg(color, "muted"),
+ "code-fg": bg(color, "dim"),
+ }),
+ ...otherStyles,
+ });
+}
+
+export function namespaceStyle(styles: Record) {
+ return Object.fromEntries(
+ Object.entries(styles).map(([k, v]) => [
+ `--sbdoc-block-${k}`,
+ `var(--sb-${v})`,
+ ])
+ );
+}
+
+export function fg(color: string, style?: string) {
+ if (style) {
+ return `fg-${color}-${style}`;
+ } else {
+ return `fg-${color}`;
+ }
+}
+
+export function bg(color: string, style?: string) {
+ if (style) {
+ return `bg-${color}-${style}`;
+ } else {
+ return `bg-${color}`;
+ }
+}
+
+export function encode(
+ attrs?: Record<
+ string,
+ string | number | boolean | null | undefined
+ >
+): string {
+ if (attrs === undefined) {
+ return "";
+ }
+ return JSON.stringify(attrs).replace(/\"/g, "'");
+}
+
+type BlockBorder = "n" | "s" | "ns" | "";
+type InlineBorder = "e" | "w" | "ew" | "";
+type Border = `${BlockBorder}${InlineBorder}`;
+
+export function CustomEl(
+ kind: string,
+ options: {
+ color: string;
+ border?: Border;
+ style?: Record;
+ },
+ children?: Children
+) {
+ return El(
+ CUSTOM_EL,
+ {
+ kind,
+ border: options.border ?? "nsew",
+ color: options.color,
+ ":style": encode(options.style),
+ },
+ children
+ );
+}
diff --git a/packages/@starbeam-docs/fenced-container/src/index.ts b/packages/@starbeam-docs/fenced-container/src/index.ts
new file mode 100644
index 0000000..60ba2d0
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/src/index.ts
@@ -0,0 +1 @@
+export { fencedContainerPlugin as default } from "./builtins.js";
diff --git a/packages/@starbeam-docs/fenced-container/src/nodes.ts b/packages/@starbeam-docs/fenced-container/src/nodes.ts
new file mode 100644
index 0000000..91b1206
--- /dev/null
+++ b/packages/@starbeam-docs/fenced-container/src/nodes.ts
@@ -0,0 +1,105 @@
+import Token from "markdown-it/lib/token.js";
+import {
+ MarkdownFragment,
+ type Child,
+ type LazyChild,
+ type ToString,
+} from "./tokens.js";
+
+export type Falsy = null | undefined | false | 0 | "";
+
+export function Fragment(...children: Child[]): LazyChild {
+ return {
+ render: (fragment) => fragment.push(...children),
+ };
+}
+
+export function El(
+ ...args: Parameters
+): LazyChild {
+ return {
+ render: (fragment) => fragment.el(...args),
+ };
+}
+
+export function BlockHtml(text: ToString): LazyChild {
+ return {
+ render: (fragment) => fragment.blockHtml(text),
+ };
+}
+
+export function InlineHtml(text: ToString): LazyChild {
+ return {
+ render: (fragment) => fragment.inlineHtml(String(text)),
+ };
+}
+
+export function HtmlEl(
+ ...args: Parameters
+): LazyChild {
+ return {
+ render: (fragment) => fragment.htmlEl(...args),
+ };
+}
+
+export function Do(then: () => LazyChild[]): LazyChild {
+ return {
+ render: (fragment) => render(fragment, then()),
+ };
+}
+
+export function Let(
+ values: T,
+ then: (values: T) => LazyChildren
+): LazyChild {
+ return {
+ render: (fragment) => render(fragment, then(values)),
+ };
+}
+
+export function If(
+ condition: T,
+ then: (value: Exclude