@threadlabs/looma 0.28.15 → 0.28.17
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/editor/chunks/extensions.js +897 -112
- package/editor/extensions/callout.d.ts +2 -9
- package/editor/extensions/chip.d.ts +3 -2
- package/editor/extensions/figure.d.ts +12 -0
- package/editor/extensions/index.d.ts +2 -0
- package/editor/extensions/index.js +2 -2
- package/editor/extensions/markdown.d.ts +8 -10
- package/editor/extensions/table-of-contents.d.ts +1 -1
- package/editor/extensions/tabs.d.ts +13 -0
- package/editor/index.js +2 -2
- package/markdown/fixtures.d.ts +27 -0
- package/markdown/fixtures.js +224 -0
- package/markdown/index.d.ts +109 -0
- package/markdown/index.js +232 -0
- package/markdown/markdown-it.d.ts +13 -0
- package/markdown/markdown-it.js +397 -0
- package/package.json +17 -1
- package/vue/editor/index.js +61 -19
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* vocabulary of Callout, Markdown `:::` containers and GitHub alerts.
|
|
5
|
-
*/
|
|
6
|
-
export declare const LOOMA_CALLOUT_TONES: readonly ["note", "tip", "info", "important", "warning", "danger"];
|
|
7
|
-
/** A serialized callout tone; unsupported input is normalized to `note`. */
|
|
8
|
-
export type LoomaCalloutTone = (typeof LOOMA_CALLOUT_TONES)[number];
|
|
2
|
+
import { LOOMA_CALLOUT_TONES, normalizeLoomaCalloutTone, type LoomaCalloutTone } from "../../markdown/index.js";
|
|
3
|
+
export { LOOMA_CALLOUT_TONES, normalizeLoomaCalloutTone, type LoomaCalloutTone };
|
|
9
4
|
declare module "@tiptap/core" {
|
|
10
5
|
interface Commands<ReturnType> {
|
|
11
6
|
loomaCallout: {
|
|
@@ -14,8 +9,6 @@ declare module "@tiptap/core" {
|
|
|
14
9
|
};
|
|
15
10
|
}
|
|
16
11
|
}
|
|
17
|
-
/** Maps a tone name, alias, or unknown value onto a persisted tone. */
|
|
18
|
-
export declare function normalizeLoomaCalloutTone(value: unknown): LoomaCalloutTone;
|
|
19
12
|
/**
|
|
20
13
|
* A durable block container for informational editor content, saved as Looma's Callout.
|
|
21
14
|
*
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
|
-
|
|
2
|
+
import { type LoomaChipTone } from "../../markdown/index.js";
|
|
3
|
+
/** The six palette values a chip may persist, Looma Markdown's chip tones; other values fall back to neutral. */
|
|
3
4
|
export declare const LOOMA_CHIP_COLORS: readonly ["neutral", "blue", "green", "yellow", "red", "purple"];
|
|
4
5
|
/** A persisted chip color shared by the headless extension and its editor UI. */
|
|
5
|
-
export type LoomaChipColor =
|
|
6
|
+
export type LoomaChipColor = LoomaChipTone;
|
|
6
7
|
/** Keep imported or programmatic colors within the supported palette. */
|
|
7
8
|
export declare function normalizeLoomaChipColor(value: unknown): LoomaChipColor;
|
|
8
9
|
declare module "@tiptap/core" {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Node } from "@tiptap/core";
|
|
2
|
+
/**
|
|
3
|
+
* An image with a caption, saved as `<figure><img><figcaption>` and written in Looma Markdown as
|
|
4
|
+
* `::: figure Caption`. The caption is inline content the author edits in place.
|
|
5
|
+
* @invariant A figure holds exactly one block image and one caption; an empty caption stays empty.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LoomaFigure: Node<any, any>;
|
|
8
|
+
/**
|
|
9
|
+
* A figure's caption: inline content under its image.
|
|
10
|
+
* @invariant It exists only as the second child of `LoomaFigure`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const LoomaFigcaption: Node<any, any>;
|
|
@@ -10,6 +10,8 @@ export { LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIV
|
|
|
10
10
|
export { LoomaCallout, LOOMA_CALLOUT_TONES, type LoomaCalloutTone, } from "./callout.js";
|
|
11
11
|
export { LoomaChip, LOOMA_CHIP_COLORS, normalizeLoomaChipColor, type LoomaChipColor } from "./chip.js";
|
|
12
12
|
export { LoomaExpand, revealLoomaExpandAt, type LoomaExpandAttributes } from "./expand.js";
|
|
13
|
+
export { LoomaFigcaption, LoomaFigure } from "./figure.js";
|
|
14
|
+
export { LoomaTab, LoomaTabs } from "./tabs.js";
|
|
13
15
|
export { LoomaTableOfContents, getTableOfContentsEntries, normalizeTableOfContentsConfig, type LoomaTableOfContentsConfig, type LoomaTableOfContentsEntry, type LoomaTableOfContentsFormat, } from "./table-of-contents.js";
|
|
14
16
|
export { getDefaultEditorExtensions, getLoomaTableExtensions, LoomaTableKit, type DefaultEditorExtensionsOptions, type LoomaCodeLanguages, } from "./preset.js";
|
|
15
17
|
export { LoomaSmartPaste } from "./smart-paste.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as TABLE_CELL_BACKGROUND_PRESETS } from "../chunks/table-backgrounds.js";
|
|
2
|
-
import { A as filterLoomaMentionItems, B as
|
|
3
|
-
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaSlashCommand, LoomaSmartPaste, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getTableOfContentsEntries, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaMarkdownFromDoc, loomaMarkdownToHtml, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
2
|
+
import { $ as LoomaActiveBlockPluginKey, A as filterLoomaMentionItems, B as LoomaFigcaption, C as loomaMarkdownToHtml, D as createLoomaMentionExtension, E as LoomaMentionSuggestionPluginKey, F as LoomaTableOfContents, G as LoomaChip, H as LoomaExpand, I as getTableOfContentsEntries, J as LOOMA_CALLOUT_TONES, K as normalizeLoomaChipColor, L as normalizeTableOfContentsConfig, M as LoomaImage, N as normalizeImageDimension, O as DEFAULT_MENTION_RESULT_LIMIT, P as normalizeImagePlacement, Q as LoomaActiveBlock, R as LoomaTab, S as loomaMarkdownFromDoc, T as siteRelativeHref, U as revealLoomaExpandAt, V as LoomaFigure, W as LOOMA_CHIP_COLORS, X as LOOMA_ACTIVE_BLOCK_CLASS, Y as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, Z as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, _ as getActiveTableCellAlignment, a as getActiveTableUiState, b as setActiveTableCellBackground, c as insertTableAtRange, d as LoomaTableKit, f as getDefaultEditorExtensions, g as LoomaTableHeader, h as LoomaTableCell, i as getDefaultSlashCommands, j as normalizeMentionResultLimit, k as MAX_MENTION_RESULT_LIMIT, l as normalizeActiveTableColumnWidths, m as LoomaTable, n as createLoomaSlashCommandExtension, o as handleTableAction, p as getLoomaTableExtensions, q as LoomaCallout, r as filterLoomaSlashCommands, s as handleTableOverlayAction, t as LoomaSlashCommand, u as shouldShowTextFormattingToolbar, v as getActiveTableCellBackground, w as createSiteRelativeLinks, x as LoomaSmartPaste, y as setActiveTableCellAlignment, z as LoomaTabs } from "../chunks/extensions.js";
|
|
3
|
+
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getTableOfContentsEntries, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaMarkdownFromDoc, loomaMarkdownToHtml, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import MarkdownIt from "markdown-it";
|
|
2
1
|
import { type Node as ProseMirrorNode } from "@tiptap/pm/model";
|
|
3
|
-
/** The markdown-it instance LoomaEditor
|
|
4
|
-
export declare const loomaMarkdown:
|
|
2
|
+
/** The markdown-it instance LoomaEditor reads Looma Markdown with. */
|
|
3
|
+
export declare const loomaMarkdown: import("markdown-it").default;
|
|
5
4
|
/**
|
|
6
|
-
* Renders Markdown
|
|
5
|
+
* Renders Looma Markdown as the HTML the editor parses.
|
|
7
6
|
* @contract The result is not sanitized; pass it to the editor's `setContent`, whose schema
|
|
8
|
-
* keeps only content it knows.
|
|
7
|
+
* keeps only content it knows. Front matter renders nothing.
|
|
9
8
|
*/
|
|
10
9
|
export declare function loomaMarkdownToHtml(source: string): string;
|
|
11
10
|
/**
|
|
12
|
-
* Writes an editor document as Markdown,
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Marks without a Markdown form other than underline and highlight are dropped.
|
|
11
|
+
* Writes an editor document as Looma Markdown, the form `loomaMarkdownToHtml` and Markupress read.
|
|
12
|
+
* @contract Every node in the default preset has a Markdown form. A table that fits GFM is a GFM
|
|
13
|
+
* table and any other is HTML. Content from extensions outside the preset is written as its saved
|
|
14
|
+
* HTML, and marks without a Markdown form other than underline and highlight are dropped.
|
|
17
15
|
*/
|
|
18
16
|
export declare function loomaMarkdownFromDoc(doc: ProseMirrorNode): string;
|
|
@@ -10,7 +10,7 @@ export interface LoomaTableOfContentsConfig {
|
|
|
10
10
|
/**
|
|
11
11
|
* One current heading for navigation or host projections.
|
|
12
12
|
* @lifecycle Positions belong to the supplied document; recompute after edits.
|
|
13
|
-
*
|
|
13
|
+
* An ID derived from a heading's text follows the text; a custom ID stays with its heading.
|
|
14
14
|
*/
|
|
15
15
|
export interface LoomaTableOfContentsEntry {
|
|
16
16
|
id: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from "@tiptap/core";
|
|
2
|
+
/**
|
|
3
|
+
* Tabs or a code group, kept whole so Looma Markdown's `::: tabs` and `::: code-group` survive
|
|
4
|
+
* editing. Saved as `<ui-tabs group>` with a `<section aria-label>` per panel.
|
|
5
|
+
* @contract While editing, panels show one after another under their labels; the Tabs component
|
|
6
|
+
* draws them only where the saved HTML renders.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LoomaTabs: Node<any, any>;
|
|
9
|
+
/**
|
|
10
|
+
* One panel of `LoomaTabs`, labelled by `label`.
|
|
11
|
+
* @invariant It exists only inside `LoomaTabs`; its label is the tab Tabs shows and the `== Label` line Markdown writes.
|
|
12
|
+
*/
|
|
13
|
+
export declare const LoomaTab: Node<any, any>;
|
package/editor/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as TABLE_CELL_BACKGROUND_PRESETS, t as TABLE_CELL_BACKGROUND_OPTIONS } from "./chunks/table-backgrounds.js";
|
|
2
2
|
import { n as resolveTableCellAt, t as measureTableOverlayGeometry } from "./chunks/ui.js";
|
|
3
|
-
import { A as filterLoomaMentionItems, B as
|
|
3
|
+
import { $ as LoomaActiveBlockPluginKey, A as filterLoomaMentionItems, B as LoomaFigcaption, C as loomaMarkdownToHtml, D as createLoomaMentionExtension, E as LoomaMentionSuggestionPluginKey, F as LoomaTableOfContents, G as LoomaChip, H as LoomaExpand, I as getTableOfContentsEntries, J as LOOMA_CALLOUT_TONES, K as normalizeLoomaChipColor, L as normalizeTableOfContentsConfig, M as LoomaImage, N as normalizeImageDimension, O as DEFAULT_MENTION_RESULT_LIMIT, P as normalizeImagePlacement, Q as LoomaActiveBlock, R as LoomaTab, S as loomaMarkdownFromDoc, T as siteRelativeHref, U as revealLoomaExpandAt, V as LoomaFigure, W as LOOMA_CHIP_COLORS, X as LOOMA_ACTIVE_BLOCK_CLASS, Y as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, Z as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, _ as getActiveTableCellAlignment, a as getActiveTableUiState, b as setActiveTableCellBackground, c as insertTableAtRange, d as LoomaTableKit, f as getDefaultEditorExtensions, g as LoomaTableHeader, h as LoomaTableCell, i as getDefaultSlashCommands, j as normalizeMentionResultLimit, k as MAX_MENTION_RESULT_LIMIT, l as normalizeActiveTableColumnWidths, m as LoomaTable, n as createLoomaSlashCommandExtension, o as handleTableAction, p as getLoomaTableExtensions, q as LoomaCallout, r as filterLoomaSlashCommands, s as handleTableOverlayAction, t as LoomaSlashCommand, u as shouldShowTextFormattingToolbar, v as getActiveTableCellBackground, w as createSiteRelativeLinks, x as LoomaSmartPaste, y as setActiveTableCellAlignment, z as LoomaTabs } from "./chunks/extensions.js";
|
|
4
4
|
import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bell, Bold, BookUser, Braces, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleDot, CircleQuestionMark, CircleX, CodeXml, Columns3, Compass, CreditCard, Ellipsis, Eraser, ExternalLink, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, History, Image, Info, Italic, LayoutDashboard, Lightbulb, Link, List, ListOrdered, ListTodo, LoaderCircle, Merge, MessageSquareWarning, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pencil, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Search, Settings, Split, Strikethrough, Table2, Tag, Trash2, TriangleAlert, Truck, Underline, Undo2, Unlink, UserRound, Users, X } from "lucide";
|
|
5
5
|
//#region src/editor/icons.ts
|
|
6
6
|
/** The opinionated Lucide set used by Looma's shipped interaction surfaces. */
|
|
@@ -123,4 +123,4 @@ function getVisualViewportRect(owner = window) {
|
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
125
|
//#endregion
|
|
126
|
-
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LOOMA_ICONS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaSlashCommand, LoomaSmartPaste, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_OPTIONS, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaIconMarkup, loomaMarkdownFromDoc, loomaMarkdownToHtml, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, resolveTableCellAt, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
126
|
+
export { DEFAULT_MENTION_RESULT_LIMIT, LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, LOOMA_ACTIVE_BLOCK_CLASS, LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, LOOMA_CALLOUT_TONES, LOOMA_CHIP_COLORS, LOOMA_ICONS, LoomaActiveBlock, LoomaActiveBlockPluginKey, LoomaCallout, LoomaChip, LoomaExpand, LoomaFigcaption, LoomaFigure, LoomaImage, LoomaMentionSuggestionPluginKey, LoomaSlashCommand, LoomaSmartPaste, LoomaTab, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, LoomaTableOfContents, LoomaTabs, MAX_MENTION_RESULT_LIMIT, TABLE_CELL_BACKGROUND_OPTIONS, TABLE_CELL_BACKGROUND_PRESETS, createLoomaMentionExtension, createLoomaSlashCommandExtension, createSiteRelativeLinks, filterLoomaMentionItems, filterLoomaSlashCommands, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, getTableOfContentsEntries, getVisualViewportRect, handleTableAction, handleTableOverlayAction, insertTableAtRange, loomaIconMarkup, loomaMarkdownFromDoc, loomaMarkdownToHtml, measureTableOverlayGeometry, normalizeActiveTableColumnWidths, normalizeImageDimension, normalizeImagePlacement, normalizeLoomaChipColor, normalizeMentionResultLimit, normalizeTableOfContentsConfig, resolveTableCellAt, revealLoomaExpandAt, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar, siteRelativeHref };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Looma Markdown's conformance fixtures and the HTML normalizer that compares renderings of them.
|
|
3
|
+
* Every reader and writer runs the same cases: LoomaEditor's round-trip suite, renderers and
|
|
4
|
+
* applications that store Looma Markdown.
|
|
5
|
+
*/
|
|
6
|
+
/** One conformance case: Markdown in, canonical HTML out, and the Markdown a writer produces. */
|
|
7
|
+
export interface LoomaMarkdownFixture {
|
|
8
|
+
/** The folder, named after a row of the spec's Support table. */
|
|
9
|
+
feature: string;
|
|
10
|
+
name: string;
|
|
11
|
+
markdown: string;
|
|
12
|
+
/** The canonical HTML: what LoomaEditor saves and the markdown-it plugin renders. */
|
|
13
|
+
html: string;
|
|
14
|
+
/** What a writer produces from the document; the input itself when the case has no `case.canonical.md`. */
|
|
15
|
+
canonical: string;
|
|
16
|
+
}
|
|
17
|
+
/** Every conformance case, ordered by feature and name. */
|
|
18
|
+
export declare const LOOMA_MARKDOWN_FIXTURES: readonly LoomaMarkdownFixture[];
|
|
19
|
+
/**
|
|
20
|
+
* Normalizes HTML so two renderings of a fixture compare as strings.
|
|
21
|
+
* @contract Sorts attributes, writes empty attributes bare, collapses whitespace outside `pre` and
|
|
22
|
+
* drops it at block edges, and unwraps renderer presentation (heading self-links, the code
|
|
23
|
+
* `figure.code` wrapper and its actions, markup inside code).
|
|
24
|
+
* @ownership Uses the supplied document, or the global one when a DOM is present; it never reads
|
|
25
|
+
* the DOM at import.
|
|
26
|
+
*/
|
|
27
|
+
export declare function normalizeLoomaHtml(html: string, document?: Document): string;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
//#endregion
|
|
2
|
+
//#region src/markdown/fixtures.ts
|
|
3
|
+
var files = /* #__PURE__ */ Object.assign({
|
|
4
|
+
"../../markdown-fixtures/autolinks/bare.canonical.md": "Read <https://example.com/docs> and [www.example.com](http://www.example.com), or <https://example.com/start>.\n",
|
|
5
|
+
"../../markdown-fixtures/autolinks/bare.html": "<p>Read <a href=\"https://example.com/docs\">https://example.com/docs</a> and <a href=\"http://www.example.com\">www.example.com</a>, or <a href=\"https://example.com/start\">https://example.com/start</a>.</p>\n",
|
|
6
|
+
"../../markdown-fixtures/autolinks/bare.md": "Read https://example.com/docs and www.example.com, or <https://example.com/start>.\n",
|
|
7
|
+
"../../markdown-fixtures/callouts/alert.canonical.md": "::: warning\nDeletes data.\n:::\n",
|
|
8
|
+
"../../markdown-fixtures/callouts/alert.html": "<ui-callout tone=\"warning\">\n<p>Deletes data.</p>\n</ui-callout>\n",
|
|
9
|
+
"../../markdown-fixtures/callouts/alert.md": "> [!WARNING]\n> Deletes data.\n",
|
|
10
|
+
"../../markdown-fixtures/callouts/caution-alias.canonical.md": "::: danger Stop\nThis cannot be undone.\n:::\n",
|
|
11
|
+
"../../markdown-fixtures/callouts/caution-alias.html": "<ui-callout tone=\"danger\" heading=\"Stop\">\n<p>This cannot be undone.</p>\n</ui-callout>\n",
|
|
12
|
+
"../../markdown-fixtures/callouts/caution-alias.md": "::: CAUTION Stop\nThis cannot be undone.\n:::\n",
|
|
13
|
+
"../../markdown-fixtures/callouts/open-in-title.html": "<ui-callout tone=\"tip\" heading=\"Keep {open}\">\n<p>A callout title keeps its braces.</p>\n</ui-callout>\n",
|
|
14
|
+
"../../markdown-fixtures/callouts/open-in-title.md": "::: tip Keep {open}\nA callout title keeps its braces.\n:::\n",
|
|
15
|
+
"../../markdown-fixtures/callouts/titled.html": "<ui-callout tone=\"tip\" heading=\"Before you start\">\n<p>Install <strong>first</strong>.</p>\n</ui-callout>\n",
|
|
16
|
+
"../../markdown-fixtures/callouts/titled.md": "::: tip Before you start\nInstall **first**.\n:::\n",
|
|
17
|
+
"../../markdown-fixtures/chips/escaped-label.html": "<p><span data-looma-chip data-label=\"Draft ] v2\" data-color=\"red\">Draft ] v2</span></p>\n",
|
|
18
|
+
"../../markdown-fixtures/chips/escaped-label.md": ":chip[Draft \\] v2]{tone=red}\n",
|
|
19
|
+
"../../markdown-fixtures/chips/tones.html": "<p>Status <span data-looma-chip data-label=\"Ready\" data-color=\"green\">Ready</span> and <span data-looma-chip data-label=\"Draft\" data-color=\"neutral\">Draft</span>.</p>\n",
|
|
20
|
+
"../../markdown-fixtures/chips/tones.md": "Status :chip[Ready]{tone=green} and :chip[Draft].\n",
|
|
21
|
+
"../../markdown-fixtures/code-blocks/fences.canonical.md": "```ts\nconst answer = 42;\n```\n\n```\nplain text\n```\n\n```\nindented\n```\n",
|
|
22
|
+
"../../markdown-fixtures/code-blocks/fences.html": "<pre><code class=\"language-ts\">const answer = 42;</code></pre>\n<pre><code>plain text</code></pre>\n<pre><code>indented</code></pre>\n",
|
|
23
|
+
"../../markdown-fixtures/code-blocks/fences.md": "```ts\nconst answer = 42;\n```\n\n```\nplain text\n```\n\n indented\n",
|
|
24
|
+
"../../markdown-fixtures/code-blocks/long-fence.html": "<pre><code class=\"language-md\">```ts\nconst a = 1;\n```</code></pre>\n",
|
|
25
|
+
"../../markdown-fixtures/code-blocks/long-fence.md": "````md\n```ts\nconst a = 1;\n```\n````\n",
|
|
26
|
+
"../../markdown-fixtures/code-meta/notation.html": "<pre><code class=\"language-ts\">const port = 8080; // [!code highlight]</code></pre>\n",
|
|
27
|
+
"../../markdown-fixtures/code-meta/notation.md": "```ts\nconst port = 8080; // [!code highlight]\n```\n",
|
|
28
|
+
"../../markdown-fixtures/code-meta/title-lines.html": "<pre><code class=\"language-ts\" data-meta=\"title="config.ts" {1,3-4} :line-numbers\">export default {\n name: "docs",\n base: "/docs/",\n};</code></pre>\n",
|
|
29
|
+
"../../markdown-fixtures/code-meta/title-lines.md": "```ts title=\"config.ts\" {1,3-4} :line-numbers\nexport default {\n name: \"docs\",\n base: \"/docs/\",\n};\n```\n",
|
|
30
|
+
"../../markdown-fixtures/containers/escaped-marker.html": "<p>::: tip is text here</p>\n",
|
|
31
|
+
"../../markdown-fixtures/containers/escaped-marker.md": "\\::: tip is text here\n",
|
|
32
|
+
"../../markdown-fixtures/containers/fence-inside.html": "<ui-callout tone=\"tip\">\n<pre><code class=\"language-md\">:::</code></pre>\n</ui-callout>\n",
|
|
33
|
+
"../../markdown-fixtures/containers/fence-inside.md": "::: tip\n```md\n:::\n```\n:::\n",
|
|
34
|
+
"../../markdown-fixtures/containers/nesting.canonical.md": ":::: details More\n::: warning\nNested.\n:::\n::::\n",
|
|
35
|
+
"../../markdown-fixtures/containers/nesting.html": "<details><summary>More</summary>\n<ui-callout tone=\"warning\">\n<p>Nested.</p>\n</ui-callout>\n</details>\n",
|
|
36
|
+
"../../markdown-fixtures/containers/nesting.md": "::: details More\n::: warning\nNested.\n:::\n:::\n",
|
|
37
|
+
"../../markdown-fixtures/containers/unclosed.canonical.md": "::: note\nNo closing line.\n:::\n",
|
|
38
|
+
"../../markdown-fixtures/containers/unclosed.html": "<ui-callout tone=\"note\">\n<p>No closing line.</p>\n</ui-callout>\n",
|
|
39
|
+
"../../markdown-fixtures/containers/unclosed.md": "::: note\nNo closing line.\n",
|
|
40
|
+
"../../markdown-fixtures/containers/unknown-name.canonical.md": "::: aside Text :::\n",
|
|
41
|
+
"../../markdown-fixtures/containers/unknown-name.html": "<p>::: aside\nText\n:::</p>\n",
|
|
42
|
+
"../../markdown-fixtures/containers/unknown-name.md": "::: aside\nText\n:::\n",
|
|
43
|
+
"../../markdown-fixtures/details/default-summary.canonical.md": "::: details Details\nHidden until opened.\n:::\n",
|
|
44
|
+
"../../markdown-fixtures/details/default-summary.html": "<details><summary>Details</summary>\n<p>Hidden until opened.</p>\n</details>\n",
|
|
45
|
+
"../../markdown-fixtures/details/default-summary.md": "::: details\nHidden until opened.\n:::\n",
|
|
46
|
+
"../../markdown-fixtures/details/open.html": "<details open><summary>Show the full log</summary>\n<p>The build finished in 42 seconds.</p>\n</details>\n",
|
|
47
|
+
"../../markdown-fixtures/details/open.md": "::: details Show the full log {open}\nThe build finished in 42 seconds.\n:::\n",
|
|
48
|
+
"../../markdown-fixtures/figures/caption.html": "<figure>\n<img src=\"./pipeline.svg\" alt=\"The build pipeline\">\n<figcaption>The build, from <em>source</em> to release</figcaption>\n</figure>\n",
|
|
49
|
+
"../../markdown-fixtures/figures/caption.md": "::: figure The build, from *source* to release\n\n:::\n",
|
|
50
|
+
"../../markdown-fixtures/front-matter/metadata.canonical.md": "# Notes\n",
|
|
51
|
+
"../../markdown-fixtures/front-matter/metadata.html": "<h1 id=\"notes\">Notes</h1>\n",
|
|
52
|
+
"../../markdown-fixtures/front-matter/metadata.md": "---\ntitle: Release notes\n---\n\n# Notes\n",
|
|
53
|
+
"../../markdown-fixtures/heading-ids/accented.html": "<h2 id=\"über-uns\">Über uns</h2>\n<h2 id=\"café-crème\">Café crème</h2>\n",
|
|
54
|
+
"../../markdown-fixtures/heading-ids/accented.md": "## Über uns\n\n## Café crème\n",
|
|
55
|
+
"../../markdown-fixtures/heading-ids/cjk.html": "<h2 id=\"はじめに\">はじめに</h2>\n<h2 id=\"設定-と-使い方\">設定 と 使い方</h2>\n",
|
|
56
|
+
"../../markdown-fixtures/heading-ids/cjk.md": "## はじめに\n\n## 設定 と 使い方\n",
|
|
57
|
+
"../../markdown-fixtures/heading-ids/custom.html": "<h2 id=\"setup\">Install</h2>\n<h2 id=\"install\">Install</h2>\n<h2 id=\"setup-1\">Setup</h2>\n",
|
|
58
|
+
"../../markdown-fixtures/heading-ids/custom.md": "## Install {#setup}\n\n## Install\n\n## Setup\n",
|
|
59
|
+
"../../markdown-fixtures/heading-ids/duplicates.html": "<h2 id=\"setup\">Setup</h2>\n<h2 id=\"setup-1\">Setup</h2>\n<h2 id=\"setup-1-1\">Setup 1</h2>\n",
|
|
60
|
+
"../../markdown-fixtures/heading-ids/duplicates.md": "## Setup\n\n## Setup\n\n## Setup 1\n",
|
|
61
|
+
"../../markdown-fixtures/heading-ids/emoji-only.html": "<h2 id=\"heading\">🚀</h2>\n<h2 id=\"heading-1\">🎉 🎉</h2>\n",
|
|
62
|
+
"../../markdown-fixtures/heading-ids/emoji-only.md": "## 🚀\n\n## 🎉 🎉\n",
|
|
63
|
+
"../../markdown-fixtures/heading-ids/generated.html": "<h2 id=\"getting-started\">Getting started</h2>\n<h2 id=\"getting-started-1\">Getting started</h2>\n<h2 id=\"über-code-more\">Über <code>code</code> & more</h2>\n",
|
|
64
|
+
"../../markdown-fixtures/heading-ids/generated.md": "## Getting started\n\n## Getting started\n\n## Über `code` & more\n",
|
|
65
|
+
"../../markdown-fixtures/heading-ids/literal-braces.html": "<h2 id=\"price-usd\">Price {#usd}</h2>\n",
|
|
66
|
+
"../../markdown-fixtures/heading-ids/literal-braces.md": "## Price \\{#usd}\n",
|
|
67
|
+
"../../markdown-fixtures/headings/levels.html": "<h1 id=\"one\">One</h1>\n<h2 id=\"two\">Two</h2>\n<h3 id=\"three\">Three</h3>\n<h4 id=\"four\">Four</h4>\n<h5 id=\"five\">Five</h5>\n<h6 id=\"six\">Six</h6>\n",
|
|
68
|
+
"../../markdown-fixtures/headings/levels.md": "# One\n\n## Two\n\n### Three\n\n#### Four\n\n##### Five\n\n###### Six\n",
|
|
69
|
+
"../../markdown-fixtures/image-attributes/placed.html": "<img src=\"./pipeline.svg\" alt=\"Pipeline\" width=\"640\" height=\"360\" data-placement=\"wrap-left\" data-looma-responsive>\n",
|
|
70
|
+
"../../markdown-fixtures/image-attributes/placed.md": "{width=640 height=360 placement=wrap-left responsive}\n",
|
|
71
|
+
"../../markdown-fixtures/images/block.html": "<img src=\"./pipeline.svg\" alt=\"The build pipeline\" title=\"Build pipeline\">\n",
|
|
72
|
+
"../../markdown-fixtures/images/block.md": "\n",
|
|
73
|
+
"../../markdown-fixtures/lists/blocks.html": "<ul>\n<li>One\n<ul>\n<li>Nested</li>\n</ul>\n</li>\n<li>Two</li>\n</ul>\n<ol start=\"3\">\n<li>Three</li>\n<li>Four</li>\n</ol>\n<blockquote>\n<p>Quoted</p>\n</blockquote>\n<hr>\n",
|
|
74
|
+
"../../markdown-fixtures/lists/blocks.md": "- One\n - Nested\n- Two\n\n3. Three\n4. Four\n\n> Quoted\n\n---\n",
|
|
75
|
+
"../../markdown-fixtures/mentions/person.html": "<p>Thanks, <span data-type=\"mention\" class=\"looma-mention\" data-id=\"u1\" data-label=\"Ada Lovelace\">@Ada Lovelace</span>.</p>\n",
|
|
76
|
+
"../../markdown-fixtures/mentions/person.md": "Thanks, :mention[Ada Lovelace]{id=u1}.\n",
|
|
77
|
+
"../../markdown-fixtures/tables/gfm.html": "<table>\n<thead>\n<tr>\n<th>Package</th>\n<th style=\"text-align:right\">Version</th>\n<th style=\"text-align:center\">Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>looma</td>\n<td style=\"text-align:right\">0.28</td>\n<td style=\"text-align:center\">Components</td>\n</tr>\n</tbody>\n</table>\n",
|
|
78
|
+
"../../markdown-fixtures/tables/gfm.md": "| Package | Version | Notes |\n| --- | ---: | :---: |\n| looma | 0.28 | Components |\n",
|
|
79
|
+
"../../markdown-fixtures/tables/left-aligned.html": "<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">Name</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">a | b</td>\n<td><code>x | y</code></td>\n</tr>\n</tbody>\n</table>\n",
|
|
80
|
+
"../../markdown-fixtures/tables/left-aligned.md": "| Name | Notes |\n| :--- | --- |\n| a \\| b | `x \\| y` |\n",
|
|
81
|
+
"../../markdown-fixtures/tables/rich.canonical.md": "<table><tbody><tr><th><p>Status</p></th><th><p>Owner</p></th></tr><tr><td style=\"background-color: rgb(220, 252, 231);\"><p>Done</p><ul><li><p>Shipped</p></li></ul></td><td style=\"text-align: center;\"><p>Ada</p></td></tr></tbody></table>\n",
|
|
82
|
+
"../../markdown-fixtures/tables/rich.html": "<table><tbody><tr><th><p>Status</p></th><th><p>Owner</p></th></tr><tr><td style=\"background-color: #dcfce7\"><p>Done</p><ul><li><p>Shipped</p></li></ul></td><td colspan=\"1\" rowspan=\"1\" style=\"text-align: center\"><p>Ada</p></td></tr></tbody></table>\n",
|
|
83
|
+
"../../markdown-fixtures/tables/rich.md": "<table><tbody><tr><th><p>Status</p></th><th><p>Owner</p></th></tr><tr><td style=\"background-color: #dcfce7\"><p>Done</p><ul><li><p>Shipped</p></li></ul></td><td colspan=\"1\" rowspan=\"1\" style=\"text-align: center\"><p>Ada</p></td></tr></tbody></table>\n",
|
|
84
|
+
"../../markdown-fixtures/tabs/code-group.html": "<ui-tabs class=\"code-group\" group=\"code-group\">\n<section aria-label=\"looma.config.js\">\n<pre><code class=\"language-js\" data-meta=\"title="looma.config.js"\">export default { theme: "light" };</code></pre>\n</section>\n<section aria-label=\"ts\">\n<pre><code class=\"language-ts\">export default { theme: "light" } satisfies Config;</code></pre>\n</section>\n</ui-tabs>\n",
|
|
85
|
+
"../../markdown-fixtures/tabs/code-group.md": "::: code-group\n```js title=\"looma.config.js\"\nexport default { theme: \"light\" };\n```\n```ts\nexport default { theme: \"light\" } satisfies Config;\n```\n:::\n",
|
|
86
|
+
"../../markdown-fixtures/tabs/labelled.html": "<ui-tabs group=\"install\">\n<section aria-label=\"npm\">\n<pre><code class=\"language-sh\">npm install @threadlabs/looma</code></pre>\n</section>\n<section aria-label=\"pnpm\">\n<pre><code class=\"language-sh\">pnpm add @threadlabs/looma</code></pre>\n</section>\n</ui-tabs>\n",
|
|
87
|
+
"../../markdown-fixtures/tabs/labelled.md": "::: tabs install\n== npm\n```sh\nnpm install @threadlabs/looma\n```\n== pnpm\n```sh\npnpm add @threadlabs/looma\n```\n:::\n",
|
|
88
|
+
"../../markdown-fixtures/task-lists/checked.html": "<ul data-type=\"taskList\">\n<li data-type=\"taskItem\" data-checked=\"true\"><input type=\"checkbox\" disabled checked>Read the changelog</li>\n<li data-type=\"taskItem\" data-checked=\"false\"><input type=\"checkbox\" disabled>Run the migration</li>\n</ul>\n",
|
|
89
|
+
"../../markdown-fixtures/task-lists/checked.md": "- [x] Read the changelog\n- [ ] Run the migration\n",
|
|
90
|
+
"../../markdown-fixtures/task-lists/mixed.canonical.md": "- \\[x\\] Done\n- Not a task\n",
|
|
91
|
+
"../../markdown-fixtures/task-lists/mixed.html": "<ul>\n<li>[x] Done</li>\n<li>Not a task</li>\n</ul>\n",
|
|
92
|
+
"../../markdown-fixtures/task-lists/mixed.md": "- [x] Done\n- Not a task\n",
|
|
93
|
+
"../../markdown-fixtures/text/marks.html": "<p><strong>bold</strong> <em>italic</em> <s>struck</s> <code>code</code> <u>underlined</u> <mark>highlighted</mark></p>\n<p><a href=\"https://example.com/looma\">Looma</a> ends a line<br>\nhere.</p>\n",
|
|
94
|
+
"../../markdown-fixtures/text/marks.md": "**bold** *italic* ~~struck~~ `code` <u>underlined</u> <mark>highlighted</mark>\n\n[Looma](https://example.com/looma) ends a line\\\nhere.\n",
|
|
95
|
+
"../../markdown-fixtures/toc/default.html": "<nav data-looma-toc data-format=\"plain\" data-depth=\"3\" aria-label=\"Table of contents\"><strong>Table of contents</strong><div role=\"list\"><div role=\"listitem\"><a href=\"#guide\">Guide</a><div role=\"list\"><div role=\"listitem\"><a href=\"#install\">Install</a></div></div></div></div></nav>\n<h1 id=\"guide\">Guide</h1>\n<h2 id=\"install\">Install</h2>\n",
|
|
96
|
+
"../../markdown-fixtures/toc/default.md": "::toc\n\n# Guide\n\n## Install\n",
|
|
97
|
+
"../../markdown-fixtures/toc/numbered.html": "<nav data-looma-toc data-format=\"numbered\" data-depth=\"2\" aria-label=\"Table of contents\"><strong>Table of contents</strong><ol role=\"list\"><li role=\"listitem\"><a href=\"#install\">Install</a></li><li role=\"listitem\"><a href=\"#use\">Use</a></li></ol></nav>\n<h2 id=\"install\">Install</h2>\n<h3 id=\"options\">Options</h3>\n<h2 id=\"use\">Use</h2>\n",
|
|
98
|
+
"../../markdown-fixtures/toc/numbered.md": "::toc{depth=2 format=numbered}\n\n## Install\n\n### Options\n\n## Use\n"
|
|
99
|
+
});
|
|
100
|
+
function fixtures() {
|
|
101
|
+
const cases = /* @__PURE__ */ new Map();
|
|
102
|
+
for (const [path, content] of Object.entries(files)) {
|
|
103
|
+
const [, feature, name, kind] = /\/markdown-fixtures\/([^/]+)\/([^/.]+)\.(md|html|canonical\.md)$/.exec(path);
|
|
104
|
+
const fixture = cases.get(`${feature}/${name}`) ?? {
|
|
105
|
+
feature,
|
|
106
|
+
name
|
|
107
|
+
};
|
|
108
|
+
cases.set(`${feature}/${name}`, fixture);
|
|
109
|
+
if (kind === "md") fixture.markdown = content;
|
|
110
|
+
else if (kind === "html") fixture.html = content;
|
|
111
|
+
else fixture.canonical = content;
|
|
112
|
+
}
|
|
113
|
+
return [...cases.values()].map((fixture) => {
|
|
114
|
+
if (fixture.markdown === void 0 || fixture.html === void 0) throw new Error(`${fixture.feature}/${fixture.name} needs case.md and case.html`);
|
|
115
|
+
return {
|
|
116
|
+
...fixture,
|
|
117
|
+
canonical: fixture.canonical ?? fixture.markdown
|
|
118
|
+
};
|
|
119
|
+
}).sort((a, b) => `${a.feature}/${a.name}`.localeCompare(`${b.feature}/${b.name}`, "en"));
|
|
120
|
+
}
|
|
121
|
+
/** Every conformance case, ordered by feature and name. */
|
|
122
|
+
var LOOMA_MARKDOWN_FIXTURES = Object.freeze(fixtures());
|
|
123
|
+
var BLOCKS = /* @__PURE__ */ new Set([
|
|
124
|
+
"address",
|
|
125
|
+
"article",
|
|
126
|
+
"aside",
|
|
127
|
+
"blockquote",
|
|
128
|
+
"details",
|
|
129
|
+
"div",
|
|
130
|
+
"dl",
|
|
131
|
+
"dd",
|
|
132
|
+
"dt",
|
|
133
|
+
"figcaption",
|
|
134
|
+
"figure",
|
|
135
|
+
"footer",
|
|
136
|
+
"h1",
|
|
137
|
+
"h2",
|
|
138
|
+
"h3",
|
|
139
|
+
"h4",
|
|
140
|
+
"h5",
|
|
141
|
+
"h6",
|
|
142
|
+
"header",
|
|
143
|
+
"hr",
|
|
144
|
+
"li",
|
|
145
|
+
"main",
|
|
146
|
+
"nav",
|
|
147
|
+
"ol",
|
|
148
|
+
"p",
|
|
149
|
+
"pre",
|
|
150
|
+
"section",
|
|
151
|
+
"summary",
|
|
152
|
+
"table",
|
|
153
|
+
"tbody",
|
|
154
|
+
"td",
|
|
155
|
+
"tfoot",
|
|
156
|
+
"th",
|
|
157
|
+
"thead",
|
|
158
|
+
"tr",
|
|
159
|
+
"ul",
|
|
160
|
+
"ui-callout",
|
|
161
|
+
"ui-disclosure",
|
|
162
|
+
"ui-tabs"
|
|
163
|
+
]);
|
|
164
|
+
var VOID = /* @__PURE__ */ new Set([
|
|
165
|
+
"br",
|
|
166
|
+
"hr",
|
|
167
|
+
"img",
|
|
168
|
+
"input",
|
|
169
|
+
"col",
|
|
170
|
+
"wbr"
|
|
171
|
+
]);
|
|
172
|
+
var escapeText = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
173
|
+
function unwrapPresentation(root) {
|
|
174
|
+
for (const link of root.querySelectorAll(":is(h1, h2, h3, h4, h5, h6) > a[href^='#']:only-child")) link.replaceWith(...link.childNodes);
|
|
175
|
+
for (const figure of root.querySelectorAll("figure.code")) {
|
|
176
|
+
const pre = figure.querySelector("pre");
|
|
177
|
+
if (pre) figure.replaceWith(pre);
|
|
178
|
+
else figure.remove();
|
|
179
|
+
}
|
|
180
|
+
for (const pre of root.querySelectorAll("pre")) {
|
|
181
|
+
for (const name of pre.getAttributeNames()) pre.removeAttribute(name);
|
|
182
|
+
const code = pre.querySelector("code");
|
|
183
|
+
if (code) code.textContent = code.textContent;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function serialize(node, inPre) {
|
|
187
|
+
if (node.nodeType === 3) {
|
|
188
|
+
const text = node.textContent ?? "";
|
|
189
|
+
if (inPre) return escapeText(text);
|
|
190
|
+
const parent = node.parentNode;
|
|
191
|
+
let value = text.replace(/\s+/g, " ");
|
|
192
|
+
const isBlockEdge = (sibling) => sibling === null || sibling.nodeType === 1 && BLOCKS.has(sibling.localName);
|
|
193
|
+
if (!parent || parent.nodeType !== 1 || BLOCKS.has(parent.localName)) {
|
|
194
|
+
if (isBlockEdge(node.previousSibling)) value = value.trimStart();
|
|
195
|
+
if (isBlockEdge(node.nextSibling)) value = value.trimEnd();
|
|
196
|
+
}
|
|
197
|
+
return escapeText(value);
|
|
198
|
+
}
|
|
199
|
+
if (node.nodeType !== 1) return [...node.childNodes].map((child) => serialize(child, inPre)).join("");
|
|
200
|
+
const element = node;
|
|
201
|
+
const name = element.localName;
|
|
202
|
+
const attributes = element.getAttributeNames().sort().map((attribute) => {
|
|
203
|
+
const value = element.getAttribute(attribute) ?? "";
|
|
204
|
+
return value ? ` ${attribute}="${value.replace(/&/g, "&").replace(/"/g, """)}"` : ` ${attribute}`;
|
|
205
|
+
}).join("");
|
|
206
|
+
if (VOID.has(name)) return `<${name}${attributes}>`;
|
|
207
|
+
return `<${name}${attributes}>${[...element.childNodes].map((child) => serialize(child, inPre || name === "pre")).join("")}</${name}>`;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Normalizes HTML so two renderings of a fixture compare as strings.
|
|
211
|
+
* @contract Sorts attributes, writes empty attributes bare, collapses whitespace outside `pre` and
|
|
212
|
+
* drops it at block edges, and unwraps renderer presentation (heading self-links, the code
|
|
213
|
+
* `figure.code` wrapper and its actions, markup inside code).
|
|
214
|
+
* @ownership Uses the supplied document, or the global one when a DOM is present; it never reads
|
|
215
|
+
* the DOM at import.
|
|
216
|
+
*/
|
|
217
|
+
function normalizeLoomaHtml(html, document = globalThis.document) {
|
|
218
|
+
const template = document.createElement("template");
|
|
219
|
+
template.innerHTML = html;
|
|
220
|
+
unwrapPresentation(template.content);
|
|
221
|
+
return serialize(template.content, false).trim();
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { LOOMA_MARKDOWN_FIXTURES, normalizeLoomaHtml };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Looma Markdown's vocabulary and pure rules, shared by every reader and writer.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here touches the DOM or a Markdown parser, so it is safe to import during SSR. The
|
|
5
|
+
* markdown-it plugin is `@threadlabs/looma/markdown/markdown-it`; conformance fixtures are
|
|
6
|
+
* `@threadlabs/looma/markdown/fixtures`.
|
|
7
|
+
*/
|
|
8
|
+
/** The meanings Callout and Badge share. Callout adds `note`, `tip` and `important`; Badge adds `accent`. */
|
|
9
|
+
export declare const LOOMA_MEANING_TONES: readonly ["neutral", "info", "success", "warning", "danger"];
|
|
10
|
+
/** Badge's tones: the shared meanings and `accent`. */
|
|
11
|
+
export declare const LOOMA_BADGE_TONES: readonly ["neutral", "accent", "info", "success", "warning", "danger"];
|
|
12
|
+
/**
|
|
13
|
+
* Callout tones a document stores, in the order the editor offers them. The Callout component also
|
|
14
|
+
* takes `neutral` and `success`, which Markdown and the editor store as `note`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const LOOMA_CALLOUT_TONES: readonly ["note", "tip", "info", "important", "warning", "danger"];
|
|
17
|
+
/** A stored callout tone. */
|
|
18
|
+
export type LoomaCalloutTone = (typeof LOOMA_CALLOUT_TONES)[number];
|
|
19
|
+
/** Names that read as a stored tone: `caution` is `danger`, and `neutral` is the same muted aside as `note`. */
|
|
20
|
+
export declare const LOOMA_CALLOUT_TONE_ALIASES: Readonly<Record<string, LoomaCalloutTone>>;
|
|
21
|
+
/**
|
|
22
|
+
* Maps a tone name or alias, in any case, onto a stored tone.
|
|
23
|
+
* @failure Unknown and non-string values become `note`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeLoomaCalloutTone(value: unknown): LoomaCalloutTone;
|
|
26
|
+
/** The hues chips and swatches take as their tone, written `:chip[Label]{tone=green}`. */
|
|
27
|
+
export declare const LOOMA_CHIP_TONES: readonly ["neutral", "blue", "green", "yellow", "red", "purple"];
|
|
28
|
+
/** A stored chip tone. */
|
|
29
|
+
export type LoomaChipTone = (typeof LOOMA_CHIP_TONES)[number];
|
|
30
|
+
/**
|
|
31
|
+
* Keeps a chip tone within the palette.
|
|
32
|
+
* @failure Unknown values become `neutral`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function normalizeLoomaChipTone(value: unknown): LoomaChipTone;
|
|
35
|
+
/**
|
|
36
|
+
* Names that open a `:::` container, matched without regard to case. A container with any other
|
|
37
|
+
* name is ordinary text.
|
|
38
|
+
*/
|
|
39
|
+
export declare const LOOMA_CONTAINER_NAMES: ReadonlySet<string>;
|
|
40
|
+
/** Brace attributes: `{#id}` sets `id`, `key=value` and `key="quoted value"` set values, and a bare key is `true`. */
|
|
41
|
+
export type LoomaAttributes = Record<string, string | true>;
|
|
42
|
+
/**
|
|
43
|
+
* Reads a brace attribute list starting at `source[start]`, which must be `{`.
|
|
44
|
+
* @contract Returns the attributes and the index just past the closing brace.
|
|
45
|
+
* @failure Returns null for anything that is not a complete, well-formed list, so the text stays literal.
|
|
46
|
+
*/
|
|
47
|
+
export declare function readLoomaAttributes(source: string, start?: number): {
|
|
48
|
+
attributes: LoomaAttributes;
|
|
49
|
+
end: number;
|
|
50
|
+
} | null;
|
|
51
|
+
/**
|
|
52
|
+
* Reads a whole string as one brace attribute list.
|
|
53
|
+
* @failure Returns null unless the string is exactly one well-formed list.
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseLoomaAttributes(source: string): LoomaAttributes | null;
|
|
56
|
+
/**
|
|
57
|
+
* Writes attributes as a brace list, `id` first as `#id`, then the rest in order.
|
|
58
|
+
* @contract `true` writes a bare key; values are quoted only when they need it. `false`, null and
|
|
59
|
+
* undefined values are left out, and an empty set writes an empty string. An ID that `#` cannot
|
|
60
|
+
* carry, or any ID when `hashId` is false, is written `id=…`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatLoomaAttributes(attributes: Readonly<Record<string, string | number | boolean | null | undefined>>, { hashId }?: {
|
|
63
|
+
hashId?: boolean | undefined;
|
|
64
|
+
}): string;
|
|
65
|
+
/**
|
|
66
|
+
* The anchor a heading's text derives: NFC, lowercase, keeping letters, numbers and combining
|
|
67
|
+
* marks, with every other run of characters one hyphen.
|
|
68
|
+
* @failure Text with no letters or numbers, such as only emoji, derives `heading`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function loomaHeadingSlug(text: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Gives every heading of a document its anchor, in document order.
|
|
73
|
+
* @contract A custom ID is kept unless an earlier heading already has it. Any other heading takes
|
|
74
|
+
* its slug, or the slug's first free suffix (`-1`, `-2`…), never one a later custom ID reserves.
|
|
75
|
+
*/
|
|
76
|
+
export declare function assignLoomaHeadingIds(headings: ReadonlyArray<{
|
|
77
|
+
readonly text: string;
|
|
78
|
+
readonly id?: string | null;
|
|
79
|
+
}>): string[];
|
|
80
|
+
/** A code fence's info string, read into its parts. */
|
|
81
|
+
export interface LoomaFenceInfo {
|
|
82
|
+
/** The first word, up to a space, `{` or `:`. */
|
|
83
|
+
language?: string;
|
|
84
|
+
/** Everything after the language, as written. */
|
|
85
|
+
meta: string;
|
|
86
|
+
/** `title="…"`. */
|
|
87
|
+
title?: string;
|
|
88
|
+
/** Lines `{1,3-5}` highlights, ascending. */
|
|
89
|
+
lines: number[];
|
|
90
|
+
/** `:line-numbers` is true and `:no-line-numbers` false; absent means the site default. */
|
|
91
|
+
lineNumbers?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/** Reads a fence's info string: ```` ```ts title="a.ts" {1,3-5} :line-numbers ````. */
|
|
94
|
+
export declare function parseLoomaFenceInfo(info: string): LoomaFenceInfo;
|
|
95
|
+
/**
|
|
96
|
+
* Splits YAML front matter from the start of a document.
|
|
97
|
+
* @contract Front matter opens with a `---` line at the very start, holds at least one `key: value`
|
|
98
|
+
* line, and closes at a `---` or `...` line. `source` is the block as written, delimiters included.
|
|
99
|
+
* @failure Returns null when the document has none.
|
|
100
|
+
*/
|
|
101
|
+
export declare function splitLoomaFrontmatter(document: string): {
|
|
102
|
+
source: string;
|
|
103
|
+
yaml: string;
|
|
104
|
+
body: string;
|
|
105
|
+
} | null;
|
|
106
|
+
/** The colons a container opens and closes with, given how deeply containers nest inside it. */
|
|
107
|
+
export declare function loomaContainerMarker(nestedDepth: number): string;
|
|
108
|
+
/** A backtick fence longer than any run of backticks in the code, and at least three long. */
|
|
109
|
+
export declare function loomaCodeFence(code: string): string;
|