@elabs-ai/components-editor 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/chunk-LBC5VJBD.js +3748 -0
- package/dist/chunk-LBC5VJBD.js.map +1 -0
- package/dist/index.css +233 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +199 -0
- package/dist/index.js +362 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/monaco-environment.d.ts +2 -0
- package/dist/lib/monaco-environment.js +44 -0
- package/dist/lib/monaco-environment.js.map +1 -0
- package/dist/markdown/frontmatter.d.ts +11 -0
- package/dist/markdown/frontmatter.js +33 -0
- package/dist/markdown/frontmatter.js.map +1 -0
- package/dist/markdown/index.css +233 -0
- package/dist/markdown/index.css.map +1 -0
- package/dist/markdown/index.d.ts +1486 -0
- package/dist/markdown/index.js +4882 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +25 -0
- package/dist/markdown/parse.js +14 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown-editor-DfBZibAn.d.ts +702 -0
- package/package.json +101 -0
- package/src/ai-objects/ai-objects-integration.test.tsx +128 -0
- package/src/ai-objects/ai-objects.stories.tsx +233 -0
- package/src/ai-objects/ai-objects.test.tsx +205 -0
- package/src/ai-objects/decision-card.tsx +178 -0
- package/src/ai-objects/directives.ts +136 -0
- package/src/ai-objects/entity.tsx +181 -0
- package/src/ai-objects/index.ts +34 -0
- package/src/ai-objects/knowledge-card.tsx +143 -0
- package/src/calc-block/calc-block.stories.tsx +297 -0
- package/src/calc-block/calc-block.test.tsx +164 -0
- package/src/calc-block/calc-block.tsx +398 -0
- package/src/calc-block/calc-editor-monaco.ts +214 -0
- package/src/calc-block/calc-editor-prose.ts +128 -0
- package/src/calc-block/calc-editor.css +80 -0
- package/src/calc-block/calc-editor.stories.tsx +272 -0
- package/src/calc-block/calc-editor.test.ts +228 -0
- package/src/calc-block/calc-editor.ts +270 -0
- package/src/calc-block/calc-inline.stories.tsx +44 -0
- package/src/calc-block/calc-inline.test.tsx +44 -0
- package/src/calc-block/calc-inline.tsx +75 -0
- package/src/calc-block/index.ts +20 -0
- package/src/calc-block/types.ts +164 -0
- package/src/code-editor/code-editor.stories.tsx +218 -0
- package/src/code-editor/code-editor.test.tsx +134 -0
- package/src/code-editor/code-editor.tsx +250 -0
- package/src/code-editor/index.ts +6 -0
- package/src/code-workspace/code-workspace.stories.tsx +51 -0
- package/src/code-workspace/code-workspace.test.tsx +146 -0
- package/src/code-workspace/code-workspace.tsx +253 -0
- package/src/code-workspace/index.ts +6 -0
- package/src/copy-button/copy-button.tsx +51 -0
- package/src/copy-button/index.ts +1 -0
- package/src/css.d.ts +3 -0
- package/src/diff-editor/diff-editor.stories.tsx +44 -0
- package/src/diff-editor/diff-editor.test.tsx +68 -0
- package/src/diff-editor/diff-editor.tsx +151 -0
- package/src/diff-editor/index.ts +1 -0
- package/src/editor-context-menu/editor-context-menu.tsx +120 -0
- package/src/editor-context-menu/index.ts +1 -0
- package/src/editor-toolbar/editor-toolbar.tsx +83 -0
- package/src/editor-toolbar/index.ts +1 -0
- package/src/index.ts +48 -0
- package/src/lib/editor-completions-monaco.test.ts +206 -0
- package/src/lib/editor-completions-monaco.ts +127 -0
- package/src/lib/editor-completions.test.ts +156 -0
- package/src/lib/editor-completions.ts +153 -0
- package/src/lib/editor-content-access-prose.test.ts +411 -0
- package/src/lib/editor-content-access-prose.ts +172 -0
- package/src/lib/editor-content-access.test.ts +182 -0
- package/src/lib/editor-content-access.ts +109 -0
- package/src/lib/languages.ts +32 -0
- package/src/lib/markdown/diff.test.ts +80 -0
- package/src/lib/markdown/diff.ts +194 -0
- package/src/lib/markdown/directives.ts +342 -0
- package/src/lib/markdown/frontmatter.ts +50 -0
- package/src/lib/markdown/markdown-scale.test.ts +65 -0
- package/src/lib/markdown/markdown-scale.ts +62 -0
- package/src/lib/markdown/merge.test.ts +64 -0
- package/src/lib/markdown/merge.ts +158 -0
- package/src/lib/markdown/slugify.test.ts +156 -0
- package/src/lib/markdown/slugify.ts +47 -0
- package/src/lib/monaco-environment.ts +103 -0
- package/src/lib/monaco-theme-bridge.ts +293 -0
- package/src/lib/use-data-theme.ts +61 -0
- package/src/markdown/frontmatter.ts +14 -0
- package/src/markdown/index.ts +323 -0
- package/src/markdown/parse.test.ts +60 -0
- package/src/markdown/parse.ts +38 -0
- package/src/markdown-academic/citations.test.ts +77 -0
- package/src/markdown-academic/citations.tsx +442 -0
- package/src/markdown-academic/footnotes.tsx +235 -0
- package/src/markdown-academic/index.ts +32 -0
- package/src/markdown-academic/math.tsx +163 -0
- package/src/markdown-academic/toc.tsx +88 -0
- package/src/markdown-editor/completions/completions-menu.tsx +96 -0
- package/src/markdown-editor/completions/completions-prose.test.ts +356 -0
- package/src/markdown-editor/completions/completions-prose.ts +313 -0
- package/src/markdown-editor/completions/completions-widget.tsx +75 -0
- package/src/markdown-editor/completions/index.ts +37 -0
- package/src/markdown-editor/directive-nodes.ts +151 -0
- package/src/markdown-editor/directive-views.test.tsx +189 -0
- package/src/markdown-editor/directive-views.tsx +795 -0
- package/src/markdown-editor/exit-keymap.test.ts +88 -0
- package/src/markdown-editor/exit-keymap.ts +87 -0
- package/src/markdown-editor/index.ts +6 -0
- package/src/markdown-editor/markdown-editor.css +250 -0
- package/src/markdown-editor/markdown-editor.directives.test.tsx +105 -0
- package/src/markdown-editor/markdown-editor.fill.test.ts +34 -0
- package/src/markdown-editor/markdown-editor.paste-embed.test.tsx +297 -0
- package/src/markdown-editor/markdown-editor.stories.tsx +560 -0
- package/src/markdown-editor/markdown-editor.strictmode.test.tsx +38 -0
- package/src/markdown-editor/markdown-editor.table.test.tsx +287 -0
- package/src/markdown-editor/markdown-editor.tsx +560 -0
- package/src/markdown-editor/milkdown-react/editor.tsx +33 -0
- package/src/markdown-editor/milkdown-react/index.ts +8 -0
- package/src/markdown-editor/milkdown-react/types.ts +27 -0
- package/src/markdown-editor/milkdown-react/use-editor.ts +27 -0
- package/src/markdown-editor/milkdown-react/use-get-editor.ts +56 -0
- package/src/markdown-editor/milkdown-react/use-instance.ts +23 -0
- package/src/markdown-editor/paste-embed.ts +355 -0
- package/src/markdown-editor/slash/brand-slash-commands.test.ts +194 -0
- package/src/markdown-editor/slash/brand-slash-commands.ts +324 -0
- package/src/markdown-editor/slash/brand-slash-plugin.test.ts +254 -0
- package/src/markdown-editor/slash/brand-slash-plugin.ts +385 -0
- package/src/markdown-editor/slash/index.ts +107 -0
- package/src/markdown-editor/slash/insert-directive.test.ts +263 -0
- package/src/markdown-editor/slash/insert-directive.ts +345 -0
- package/src/markdown-editor/slash/monaco-slash-menu.test.tsx +198 -0
- package/src/markdown-editor/slash/monaco-slash-menu.tsx +356 -0
- package/src/markdown-editor/slash/shortcut-monaco.ts +69 -0
- package/src/markdown-editor/slash/shortcut.test.ts +157 -0
- package/src/markdown-editor/slash/shortcut.ts +57 -0
- package/src/markdown-editor/slash/slash-menu.stories.tsx +139 -0
- package/src/markdown-editor/slash/slash-menu.tsx +115 -0
- package/src/markdown-editor/slash/slash-scroll.test.tsx +52 -0
- package/src/markdown-editor/slash/slash-widget.tsx +97 -0
- package/src/markdown-editor/slash/source-slash-trigger.test.ts +42 -0
- package/src/markdown-editor/slash/source-slash-trigger.ts +46 -0
- package/src/markdown-editor/table-view.tsx +249 -0
- package/src/markdown-iteration/directive.tsx +92 -0
- package/src/markdown-iteration/edit-context.ts +56 -0
- package/src/markdown-iteration/index.ts +24 -0
- package/src/markdown-iteration/iteration-block.test.tsx +138 -0
- package/src/markdown-iteration/iteration-builder-dialog.stories.tsx +293 -0
- package/src/markdown-iteration/iteration-builder-dialog.tsx +312 -0
- package/src/markdown-iteration/iteration-builder.test.ts +252 -0
- package/src/markdown-iteration/iteration-builder.ts +303 -0
- package/src/markdown-iteration/iteration.test.ts +56 -0
- package/src/markdown-iteration/iteration.tsx +333 -0
- package/src/markdown-iteration/template-dialog.stories.tsx +63 -0
- package/src/markdown-iteration/template-dialog.test.tsx +104 -0
- package/src/markdown-iteration/template-dialog.tsx +116 -0
- package/src/markdown-outline/document-outline.stories.tsx +76 -0
- package/src/markdown-outline/document-outline.tsx +83 -0
- package/src/markdown-outline/index.ts +2 -0
- package/src/markdown-outline/markdown-outline.test.ts +49 -0
- package/src/markdown-outline/markdown-outline.ts +60 -0
- package/src/markdown-preview/code-fence.tsx +193 -0
- package/src/markdown-preview/index.ts +8 -0
- package/src/markdown-preview/markdown-preview-academic.stories.tsx +203 -0
- package/src/markdown-preview/markdown-preview-academic.test.tsx +257 -0
- package/src/markdown-preview/markdown-preview-iteration-calc.test.tsx +71 -0
- package/src/markdown-preview/markdown-preview-iteration-nested.test.tsx +58 -0
- package/src/markdown-preview/markdown-preview-iteration.stories.tsx +187 -0
- package/src/markdown-preview/markdown-preview-iteration.test.tsx +90 -0
- package/src/markdown-preview/markdown-preview-linking.test.tsx +61 -0
- package/src/markdown-preview/markdown-preview-transclusion.test.tsx +33 -0
- package/src/markdown-preview/markdown-preview.stories.tsx +108 -0
- package/src/markdown-preview/markdown-preview.test.tsx +411 -0
- package/src/markdown-preview/markdown-preview.tsx +1541 -0
- package/src/markdown-toolbar/index.ts +8 -0
- package/src/markdown-toolbar/markdown-commands.test.ts +84 -0
- package/src/markdown-toolbar/markdown-commands.ts +104 -0
- package/src/markdown-toolbar/markdown-toolbar.stories.tsx +56 -0
- package/src/markdown-toolbar/markdown-toolbar.tsx +263 -0
- package/src/markdown-workspace/focus-writing.test.ts +52 -0
- package/src/markdown-workspace/focus-writing.ts +38 -0
- package/src/markdown-workspace/index.ts +6 -0
- package/src/markdown-workspace/markdown-workspace.stories.tsx +688 -0
- package/src/markdown-workspace/markdown-workspace.test.tsx +326 -0
- package/src/markdown-workspace/markdown-workspace.tsx +787 -0
- package/src/mermaid-diagram/index.ts +1 -0
- package/src/mermaid-diagram/mermaid-diagram.stories.tsx +42 -0
- package/src/mermaid-diagram/mermaid-diagram.test.tsx +86 -0
- package/src/mermaid-diagram/mermaid-diagram.tsx +318 -0
- package/src/mermaid-diagram/mermaid-viewer.test.tsx +89 -0
- package/src/mermaid-diagram/mermaid-viewer.tsx +367 -0
- package/src/mermaid-diagram/real-parse.test.ts +42 -0
- package/src/mermaid-diagram/remediate.test.ts +60 -0
- package/src/mermaid-diagram/remediate.ts +124 -0
- package/src/mermaid-workspace/index.ts +1 -0
- package/src/mermaid-workspace/mermaid-workspace.stories.tsx +28 -0
- package/src/mermaid-workspace/mermaid-workspace.tsx +71 -0
- package/src/metric-block/index.ts +1 -0
- package/src/metric-block/metric-block.stories.tsx +40 -0
- package/src/metric-block/metric-block.tsx +14 -0
- package/src/monaco-workers.d.ts +10 -0
- package/src/prose/index.ts +14 -0
- package/src/prose/prose.stories.tsx +44 -0
- package/src/prose/prose.test.tsx +44 -0
- package/src/prose/prose.tsx +21 -0
- package/src/timeline/index.ts +18 -0
|
@@ -0,0 +1,1486 @@
|
|
|
1
|
+
import { S as SlashCommand, I as IterationEditHandler, c as EditorSelection, E as EditorContentAccess, h as EditorCompletionProvider, M as MonacoCodeEditor, i as CalcEditorHooks, d as EmbedAssetFn, j as EvaluateCalc, k as CalcValue, l as CalcTokenKind } from '../markdown-editor-DfBZibAn.js';
|
|
2
|
+
export { B as BRAND_SLASH_COMMANDS, n as BasicBlockId, o as CALC_FENCE_SEED, p as CalcComplete, q as CalcCompletion, r as CalcCompletionContext, s as CalcCompletionKind, t as CalcContext, u as CalcLineResult, v as CalcRule, w as CalcSheet, x as CalcTint, y as CalcToken, z as CalcTokenize, A as CalcValueKind, D as CompletionMatch, F as CompletionReplaceRange, G as EditorCompletionContext, H as EditorCompletionItem, J as InsertableDirective, K as IterationEditContext, L as IterationEditRequest, e as MarkdownEditor, f as MarkdownEditorHandle, g as MarkdownEditorProps, N as SlashInsertContext, O as SlashRange, P as SourceSlashContext, Q as collectCompletions, R as filterSlashCommands, T as groupSlashCommands, U as insertBasicBlock, V as insertBrandDirective, W as insertCalcFence, m as monacoContentAccess, X as resolveCalcInsert, Y as resolveReplaceRange, Z as triggerQueryStart } from '../markdown-editor-DfBZibAn.js';
|
|
3
|
+
import { MilkdownPlugin } from '@milkdown/kit/ctx';
|
|
4
|
+
import { EditorView } from '@milkdown/kit/prose/view';
|
|
5
|
+
import * as monaco from 'monaco-editor';
|
|
6
|
+
import { IRange } from 'monaco-editor';
|
|
7
|
+
import { useWidgetViewFactory } from '@prosemirror-adapter/react';
|
|
8
|
+
import * as react from 'react';
|
|
9
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
10
|
+
import { MetricCardProps, BentoGridSize, ProseHeadingLevel } from '@elabs-ai/components-ui';
|
|
11
|
+
export { ProseBlockquote as Blockquote, ProseHeading as Heading, ProseHeadingLevel as HeadingLevel, ProseHeadingProps as HeadingProps, ProseInlineCode as InlineCode, ProseLink as Link, ProseLinkProps as LinkProps, ProseList as List, ProseListItem as ListItem, ProseListProps as ListProps, ProseText as Text, ProseTextProps as TextProps, Timeline, TimelineEntry as TimelineItem, TimelineProps } from '@elabs-ai/components-ui';
|
|
12
|
+
import { PluggableList } from 'unified';
|
|
13
|
+
import { Root } from 'mdast';
|
|
14
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
15
|
+
import '@milkdown/kit/prose/model';
|
|
16
|
+
import '@milkdown/kit/prose/state';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The brand slash-menu Milkdown plugin (the ProseMirror half).
|
|
20
|
+
*
|
|
21
|
+
* A self-owned raw ProseMirror plugin (`$prose`) — NOT `@milkdown/kit/plugin/slash`
|
|
22
|
+
* — so the editor pulls zero new dependencies and we keep full control of the
|
|
23
|
+
* interaction. It owns the STATE and the KEYBOARD; the React widget
|
|
24
|
+
* (slash-widget.tsx) owns the rendered popup. They share one
|
|
25
|
+
* {@link SlashController} (the command list + a Milkdown `Ctx` getter + the
|
|
26
|
+
* insert/close helpers), built once in `MarkdownEditorView` so both the plugin's
|
|
27
|
+
* Enter handler and the widget's click handler run a command the SAME way.
|
|
28
|
+
*
|
|
29
|
+
* Responsibilities here:
|
|
30
|
+
* 1. Detect a `/` typed at a textblock START or after whitespace; track
|
|
31
|
+
* `{ active, from, query, index }` as the user keeps typing (a literal `/`
|
|
32
|
+
* mid-word is never hijacked; a space ends the query).
|
|
33
|
+
* 2. Render the React `<SlashMenu>` as a ProseMirror WIDGET decoration at the
|
|
34
|
+
* caret (via the `useWidgetViewFactory()` factory passed in).
|
|
35
|
+
* 3. ↑/↓ move the selection, Enter inserts the active command (replacing the
|
|
36
|
+
* `/query` range), Esc / deleting the `/` closes.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The factory `useWidgetViewFactory()` returns: `(options) => (pos, spec?) =>
|
|
41
|
+
* Decoration`. We borrow the exact type from the hook so we never name the
|
|
42
|
+
* (un-re-exported) `@prosemirror-adapter/core` internals.
|
|
43
|
+
*/
|
|
44
|
+
type SlashWidgetFactory = ReturnType<typeof useWidgetViewFactory>;
|
|
45
|
+
|
|
46
|
+
interface SlashMenuProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
|
|
47
|
+
/** The (already filtered) commands to show. */
|
|
48
|
+
commands: SlashCommand[];
|
|
49
|
+
/** The id of the active (highlighted) command, for `aria-selected`. */
|
|
50
|
+
activeId?: string;
|
|
51
|
+
/** Called when a command is chosen (click or via the plugin's Enter). */
|
|
52
|
+
onSelect: (command: SlashCommand) => void;
|
|
53
|
+
/** DOM id prefix so each option id is stable + unique (matches `aria-activedescendant`). */
|
|
54
|
+
idPrefix?: string;
|
|
55
|
+
/** Shown when the query matches nothing. */
|
|
56
|
+
emptyLabel?: string;
|
|
57
|
+
}
|
|
58
|
+
declare const SlashMenu: react.ForwardRefExoticComponent<SlashMenuProps & react.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Brand slash-menu — public surface for the WYSIWYG markdown editor.
|
|
62
|
+
*
|
|
63
|
+
* Typing `/` at a block start (or after whitespace) opens a branded command menu
|
|
64
|
+
* that inserts the brand `:::` directives + basic blocks live in the editor. The
|
|
65
|
+
* load-bearing pieces:
|
|
66
|
+
* - `brand-slash-commands` — the typed, tree-shakeable command registry.
|
|
67
|
+
* - `insert-directive` — the pure ProseMirror insertion commands (unit-tested).
|
|
68
|
+
* - `brand-slash-plugin` — the `$prose` plugin (state + keyboard).
|
|
69
|
+
* - `slash-widget` / `slash-menu` — the React widget + the branded popup.
|
|
70
|
+
*
|
|
71
|
+
* `brandSlashViewPlugins(widgetFactory, options)` wires it all together — call it
|
|
72
|
+
* with the factory from `useWidgetViewFactory()` (so it runs under
|
|
73
|
+
* `<ProsemirrorAdapterProvider>`), exactly like `directiveViewPlugins`.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/** Options for {@link brandSlashViewPlugins}. */
|
|
77
|
+
interface BrandSlashViewOptions {
|
|
78
|
+
/** Override the default command list. */
|
|
79
|
+
commands?: SlashCommand[];
|
|
80
|
+
/** The trigger character. Defaults to `"/"`. */
|
|
81
|
+
trigger?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Keyboard shortcut that opens the menu at the caret in BOTH panes (#271).
|
|
84
|
+
* Defaults to `DEFAULT_SLASH_SHORTCUT` (`"Mod-Shift-O"`). Set to `undefined` or
|
|
85
|
+
* an empty string to disable the shortcut binding.
|
|
86
|
+
*/
|
|
87
|
+
shortcut?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the live `IterationEditContext` handler (#223, internal —
|
|
90
|
+
* `MarkdownEditorView` wires this from `useContext`). When present, a
|
|
91
|
+
* `guided` command (`/iterate` `/pivot`) opens its modal instead of a bare
|
|
92
|
+
* insert. Not part of the public `slashMenu` prop surface.
|
|
93
|
+
*/
|
|
94
|
+
getIterationEditHandler?: () => IterationEditHandler | null | undefined;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Build the slash-menu Milkdown plugins. Call with the widget factory from
|
|
98
|
+
* `useWidgetViewFactory()` (must run inside a `<ProsemirrorAdapterProvider>`),
|
|
99
|
+
* then `.use()` the result on the editor.
|
|
100
|
+
*/
|
|
101
|
+
declare function brandSlashViewPlugins(widgetFactory: SlashWidgetFactory, options?: BrandSlashViewOptions): MilkdownPlugin[];
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* ProseMirror / Milkdown adapter for the engine-agnostic EditorContentAccess.
|
|
105
|
+
*
|
|
106
|
+
* ISOLATION: this file is MARKDOWN-ONLY — it imports `@milkdown/kit/*` at runtime.
|
|
107
|
+
* It is exported ONLY from `packages/editor/src/markdown/index.ts` (`./markdown`
|
|
108
|
+
* subpath) and NEVER from `src/index.ts` (`.` barrel), so `@milkdown` never leaks
|
|
109
|
+
* into the Monaco-only graph (#271-inverse). The TYPES from `editor-content-access`
|
|
110
|
+
* are type-erased imports — no runtime edge back to the monaco file.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
interface ProseMirrorContentAccessOptions {
|
|
114
|
+
/** "markdown" (default) round-trips formatting; "plainText" uses raw text only. */
|
|
115
|
+
fidelity?: "markdown" | "plainText";
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Dependency-injected shape for the Milkdown content-access adapter.
|
|
119
|
+
*
|
|
120
|
+
* The handle owns the serialize/parse closures (built via `getInstance().action(ctx
|
|
121
|
+
* => ...)`) and passes them here. This keeps the adapter free of `Ctx` token
|
|
122
|
+
* plumbing and matches the `readBodyMarkdown`/`writeBodyMarkdown` technique in
|
|
123
|
+
* `directive-views.tsx` exactly.
|
|
124
|
+
*/
|
|
125
|
+
interface ProseMirrorContentAccessDeps {
|
|
126
|
+
/** Return the live `EditorView`, or null while the engine is booting. */
|
|
127
|
+
getView: () => EditorView | null;
|
|
128
|
+
/** Return the full document serialized to markdown. */
|
|
129
|
+
getText: () => string;
|
|
130
|
+
/**
|
|
131
|
+
* Serialize the CURRENT selection's slice to markdown (or "" for a collapsed
|
|
132
|
+
* selection). Built by the handle from `serializerCtx`.
|
|
133
|
+
*/
|
|
134
|
+
serializeSlice: (view: EditorView) => string;
|
|
135
|
+
/**
|
|
136
|
+
* Parse `md` as a markdown fragment and replace the current selection with the
|
|
137
|
+
* parsed content. On parse failure degrades to a plain-text insert. Built by
|
|
138
|
+
* the handle from `parserCtx`.
|
|
139
|
+
*/
|
|
140
|
+
parseAndReplace: (view: EditorView, md: string) => void;
|
|
141
|
+
/**
|
|
142
|
+
* The registered `onSelectionChange` listeners set. Shared between the adapter
|
|
143
|
+
* and the `selectionWatchPlugin` so the plugin can notify subscribers without
|
|
144
|
+
* coupling to the adapter instance.
|
|
145
|
+
*/
|
|
146
|
+
listeners: Set<(sel: EditorSelection) => void>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Build the ProseMirror selection-watch plugin as a Milkdown `$prose` plugin.
|
|
150
|
+
* Compares `prevState.selection` to `view.state.selection` on every transaction and
|
|
151
|
+
* notifies listeners in the shared `listeners` set when they differ.
|
|
152
|
+
*
|
|
153
|
+
* Add to the editor `.use(...)` chain ONCE (always-present; the listeners set is
|
|
154
|
+
* populated / depopulated at subscription time — no per-subscription state in the
|
|
155
|
+
* plugin). Follows the `calcProsePlugins` pattern exactly.
|
|
156
|
+
*
|
|
157
|
+
* @param getListeners - Thunk returning the current listener set. Using a thunk
|
|
158
|
+
* (rather than the set directly) lets the adapter swap the set out if needed —
|
|
159
|
+
* in practice the set is stable; the thunk keeps this composable.
|
|
160
|
+
* @param getSerializeSlice - Thunk: serialize the current selection → markdown.
|
|
161
|
+
*/
|
|
162
|
+
declare function selectionWatchPlugin(getListeners: () => Set<(sel: EditorSelection) => void>, getSerializeSlice: () => (view: EditorView) => string): MilkdownPlugin;
|
|
163
|
+
/**
|
|
164
|
+
* Wrap a Milkdown ProseMirror view as {@link EditorContentAccess}.
|
|
165
|
+
*
|
|
166
|
+
* Receives dependency-injected closures (`serializeSlice`, `parseAndReplace`) that
|
|
167
|
+
* the `MarkdownEditorHandle` builds via `getInstance().action(ctx => ...)`, reusing
|
|
168
|
+
* the `serializerCtx`/`parserCtx` round-trip already shipped in `directive-views.tsx`.
|
|
169
|
+
*
|
|
170
|
+
* The `selectionWatchPlugin` must be added to the editor's `.use(...)` chain so it
|
|
171
|
+
* is installed when the editor boots. The `deps.listeners` set is shared between the
|
|
172
|
+
* plugin and this adapter.
|
|
173
|
+
*
|
|
174
|
+
* Markdown fidelity (default): selection → markdown, incoming text parsed as
|
|
175
|
+
* markdown fragment, with a graceful plain-text fallback on parse failure.
|
|
176
|
+
* Normalization (the WI-1 lesson): the serializer may re-emit formatting differently
|
|
177
|
+
* (e.g. `*` vs `_`). This is the same normalization the WYSIWYG editor applies on
|
|
178
|
+
* every keystroke — consistent, not new. For raw text use `plainText`.
|
|
179
|
+
*
|
|
180
|
+
* D5: content manipulation only — no model/transport.
|
|
181
|
+
*/
|
|
182
|
+
declare function proseMirrorContentAccess(deps: ProseMirrorContentAccessDeps, options?: ProseMirrorContentAccessOptions): EditorContentAccess;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Monaco registration lifecycle for the declarative completion-provider API
|
|
186
|
+
* (#283) — the engine that backs the `completions` prop on `MarkdownWorkspace`.
|
|
187
|
+
*
|
|
188
|
+
* `monaco.languages.registerCompletionItemProvider` is GLOBAL PER LANGUAGE, not
|
|
189
|
+
* per editor instance (the root cause #283 exists to fix — see the issue). So
|
|
190
|
+
* this module owns a single, REFCOUNTED registration for the "markdown"
|
|
191
|
+
* language: the first `attachCompletionsMonaco` call registers it, each
|
|
192
|
+
* subsequent call (a second mounted `MarkdownWorkspace`) bumps the refcount,
|
|
193
|
+
* and the registration is disposed ONLY when the LAST attached editor's
|
|
194
|
+
* disposer runs — no leak, no double-registration (#283 acceptance).
|
|
195
|
+
*
|
|
196
|
+
* Suggestions are scoped to the models THIS module attached (a `REGISTRY` keyed
|
|
197
|
+
* by `ITextModel`) — any other "markdown" model in the app (one the host built
|
|
198
|
+
* itself, outside `@elabs-ai/components-editor`) is ignored, never suggested into.
|
|
199
|
+
*
|
|
200
|
+
* `getProviders` is read fresh from the registry on every `provideCompletionItems`
|
|
201
|
+
* call — NOT captured as a closure at registration time — so a rebuilt provider
|
|
202
|
+
* list (a new `completions` array identity from React state/props) is picked up
|
|
203
|
+
* WITHOUT re-registering (#283 acceptance). Mirrors the calc layer's
|
|
204
|
+
* `REGISTRY`/`getHooks` pattern in `calc-block/calc-editor-monaco.ts`.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/** Resolver of the latest provider list for a model (read fresh on every call). */
|
|
208
|
+
type ProvidersGetter = () => EditorCompletionProvider[] | undefined;
|
|
209
|
+
/**
|
|
210
|
+
* Attach the declarative completion providers to a Monaco editor instance.
|
|
211
|
+
* `getProviders` is read live on every suggestion request (see module doc) —
|
|
212
|
+
* pass a ref-backed getter so a fresh `completions` array identity on every
|
|
213
|
+
* render never forces a re-attach.
|
|
214
|
+
*
|
|
215
|
+
* Also force-opens Monaco's native suggest widget (`editor.action.triggerSuggest`)
|
|
216
|
+
* whenever the user types a character matching one of the CURRENTLY-configured
|
|
217
|
+
* providers' `triggerCharacters` — read live, so changing that set never needs a
|
|
218
|
+
* re-registration either. Markdown punctuation like `[` doesn't extend a "word",
|
|
219
|
+
* so without this Monaco's own quick-suggestions heuristic would never invoke a
|
|
220
|
+
* provider on it.
|
|
221
|
+
*
|
|
222
|
+
* Returns a disposer. Call it on unmount / when `completions` is removed —
|
|
223
|
+
* refcounted, so the GLOBAL "markdown" registration is only torn down once the
|
|
224
|
+
* LAST attached editor calls its disposer (#283 acceptance: no leak, no
|
|
225
|
+
* double-registration with two workspaces mounted).
|
|
226
|
+
*/
|
|
227
|
+
declare function attachCompletionsMonaco(editor: monaco.editor.IStandaloneCodeEditor, getProviders: ProvidersGetter): () => void;
|
|
228
|
+
|
|
229
|
+
interface MonacoSlashMenuProps {
|
|
230
|
+
/** The live Monaco editor instance (source pane). */
|
|
231
|
+
editor: MonacoCodeEditor;
|
|
232
|
+
/**
|
|
233
|
+
* Commands to show in the source pane — filtered by the workspace to
|
|
234
|
+
* `snippet != null || typeof runInSource === "function"` (#299): a command
|
|
235
|
+
* needs a text snippet, a source-pane handler, or both to appear here (a
|
|
236
|
+
* run-only WYSIWYG command with neither is Milkdown-only and stays excluded).
|
|
237
|
+
*/
|
|
238
|
+
commands: SlashCommand[];
|
|
239
|
+
/** Controlled open state — the workspace toggles it via the Layer-1 action. */
|
|
240
|
+
open: boolean;
|
|
241
|
+
onOpenChange: (open: boolean) => void;
|
|
242
|
+
/**
|
|
243
|
+
* Insert the selected snippet at the Monaco caret + refocus.
|
|
244
|
+
* Defaults to `insertDirective` from `markdown-commands.ts`.
|
|
245
|
+
*/
|
|
246
|
+
onInsert?: (editor: MonacoCodeEditor, snippet: string) => void;
|
|
247
|
+
/**
|
|
248
|
+
* When the menu was opened by typing `/` (not the hotkey), the model range of
|
|
249
|
+
* that `/`. On select the `/` is REPLACED by the inserted block; on cancel
|
|
250
|
+
* (Escape / Backspace past the trigger) it is removed. `null`/omitted = the
|
|
251
|
+
* hotkey path, which inserts via `onInsert`/`insertDirective` and leaves the
|
|
252
|
+
* document otherwise untouched.
|
|
253
|
+
*/
|
|
254
|
+
triggerRange?: IRange | null;
|
|
255
|
+
/** Merged onto the positioned popup container (the inline `position:fixed` anchor stays). */
|
|
256
|
+
className?: string;
|
|
257
|
+
}
|
|
258
|
+
declare function MonacoSlashMenu({ editor, commands, open, onOpenChange, onInsert, triggerRange, className, }: MonacoSlashMenuProps): react.JSX.Element | null;
|
|
259
|
+
|
|
260
|
+
type MarkdownWorkspaceMode = "source" | "wysiwyg" | "split";
|
|
261
|
+
/**
|
|
262
|
+
* Imperative handle exposed via `MarkdownWorkspace`'s `ref` (#273, DECISION A).
|
|
263
|
+
*
|
|
264
|
+
* Migration note: the forwarded ref type changed from `HTMLDivElement` to this
|
|
265
|
+
* handle. Replace any `ref.current` DOM access with `ref.current?.getElement()`.
|
|
266
|
+
*
|
|
267
|
+
* Extends {@link EditorContentAccess} — all AI content-access methods delegate to
|
|
268
|
+
* the active engine: Monaco (source/split) or the Milkdown WYSIWYG handle.
|
|
269
|
+
*
|
|
270
|
+
* **`onSelectionChange` caveat:** the subscription is scoped to the engine active at
|
|
271
|
+
* call time. A mode switch (source ↔ wysiwyg) does NOT auto-rebind the listener —
|
|
272
|
+
* re-subscribe from an effect whose deps include the mode. A self-rebinding v2 is a
|
|
273
|
+
* noted future enhancement, out of v1 scope.
|
|
274
|
+
*/
|
|
275
|
+
interface MarkdownWorkspaceHandle extends EditorContentAccess {
|
|
276
|
+
/**
|
|
277
|
+
* Scroll the active editor so FULL-SOURCE 1-based `line` is visible (Monaco
|
|
278
|
+
* coordinates). No-op (never throws) while the engine is booting or `line` is
|
|
279
|
+
* out of range. In WYSIWYG it is best-effort: resolves the nearest preceding
|
|
280
|
+
* heading via `parseMarkdownOutline` + `fmOffset`, then delegates to
|
|
281
|
+
* `scrollToHeading`. No-op if no preceding heading found.
|
|
282
|
+
*/
|
|
283
|
+
revealLine(line: number, opts?: {
|
|
284
|
+
center?: boolean;
|
|
285
|
+
}): void;
|
|
286
|
+
/**
|
|
287
|
+
* Scroll to a heading by its outline slug (same slugs as `DocumentOutline` /
|
|
288
|
+
* `useMarkdownOutline` / `parseMarkdownOutline`). In Source/Split mode
|
|
289
|
+
* resolves the line via `parseMarkdownOutline` then calls `revealLine`. In
|
|
290
|
+
* WYSIWYG delegates to the `MarkdownEditorHandle.scrollToHeading`.
|
|
291
|
+
*/
|
|
292
|
+
scrollToHeading(slug: string): void;
|
|
293
|
+
/**
|
|
294
|
+
* The live Monaco source editor instance, or `null` when not mounted or when
|
|
295
|
+
* the active mode is `"wysiwyg"` (source pane not rendered).
|
|
296
|
+
*/
|
|
297
|
+
getEditor(): MonacoCodeEditor | null;
|
|
298
|
+
/**
|
|
299
|
+
* The workspace root DOM element. Preserves the old `HTMLDivElement` ref
|
|
300
|
+
* access that existed before DECISION A (ref type change in #273).
|
|
301
|
+
*/
|
|
302
|
+
getElement(): HTMLDivElement | null;
|
|
303
|
+
}
|
|
304
|
+
interface MarkdownWorkspaceProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
305
|
+
value?: string;
|
|
306
|
+
defaultValue?: string;
|
|
307
|
+
onChange?: (markdown: string) => void;
|
|
308
|
+
mode?: MarkdownWorkspaceMode;
|
|
309
|
+
defaultMode?: MarkdownWorkspaceMode;
|
|
310
|
+
onModeChange?: (mode: MarkdownWorkspaceMode) => void;
|
|
311
|
+
/**
|
|
312
|
+
* Start with FOCUS WRITING on (wysiwyg mode): typewriter scrolling keeps
|
|
313
|
+
* the caret vertically centered and inactive paragraphs dim. Toggleable in
|
|
314
|
+
* the editor's mode row.
|
|
315
|
+
*/
|
|
316
|
+
defaultFocusWriting?: boolean;
|
|
317
|
+
/**
|
|
318
|
+
* The `/` command menu in the WYSIWYG (preview-edit) pane AND the Monaco source
|
|
319
|
+
* pane. `true` (default) uses the built-in brand commands; pass a config to
|
|
320
|
+
* extend/replace them, or `false` to disable. Forwarded to {@link MarkdownEditor}.
|
|
321
|
+
*
|
|
322
|
+
* `shortcut` (default `"Mod-Shift-O"`) opens the menu at the caret in BOTH panes —
|
|
323
|
+
* in the WYSIWYG pane via the ProseMirror plugin's `handleKeyDown`, and in the
|
|
324
|
+
* source/split pane via a `CodeEditor` action (no `/` is inserted into the
|
|
325
|
+
* doc). (#271)
|
|
326
|
+
*/
|
|
327
|
+
slashMenu?: boolean | {
|
|
328
|
+
commands?: SlashCommand[];
|
|
329
|
+
trigger?: string;
|
|
330
|
+
shortcut?: string;
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
333
|
+
* Customize the source / split toolbar's **Insert** menu (A4). Defaults to the
|
|
334
|
+
* same commands as the WYSIWYG slash menu (so `/calc`, `/iterate`, `/pivot` and
|
|
335
|
+
* any consumer commands are insertable in source mode too). Only commands with
|
|
336
|
+
* a `snippet` appear; pass your own list to override.
|
|
337
|
+
*/
|
|
338
|
+
insertCommands?: SlashCommand[];
|
|
339
|
+
/**
|
|
340
|
+
* Opt-in calc authoring inside ```calc fences (off by default). Wired to BOTH
|
|
341
|
+
* surfaces: the Monaco source pane (highlight + autocomplete + result inlays)
|
|
342
|
+
* and the WYSIWYG pane (highlight + result inlays). Supply the consumer's
|
|
343
|
+
* `tokenize` / `evaluate` / `complete` hooks; the library bundles no calc engine.
|
|
344
|
+
*/
|
|
345
|
+
calc?: CalcEditorHooks;
|
|
346
|
+
/**
|
|
347
|
+
* Declarative completion providers (#283) — e.g. `[[wikilink]]` autocomplete.
|
|
348
|
+
* Off by default; mirrors the `slashMenu`/`calc` opt-in pattern. The library
|
|
349
|
+
* owns the Monaco `registerCompletionItemProvider` registration lifecycle
|
|
350
|
+
* (registered once, refcounted across mounted workspaces, disposed with the
|
|
351
|
+
* last one — see `lib/editor-completions-monaco.ts`) for the Source/Split
|
|
352
|
+
* panes, and mirrors providers into the WYSIWYG pane via `MarkdownEditor`'s
|
|
353
|
+
* `completions` prop (a deliberately minimal mirror — see
|
|
354
|
+
* `markdown-editor/completions/completions-prose.ts` for the exact gaps).
|
|
355
|
+
* Zero `monaco-editor` imports needed in consumer code.
|
|
356
|
+
*/
|
|
357
|
+
completions?: EditorCompletionProvider[];
|
|
358
|
+
/**
|
|
359
|
+
* Host-provided callback for image paste/drop embedding in the WYSIWYG pane.
|
|
360
|
+
* Forwarded to {@link MarkdownEditor}. See `MarkdownEditorProps.onEmbedAsset`
|
|
361
|
+
* for the full contract.
|
|
362
|
+
*/
|
|
363
|
+
onEmbedAsset?: EmbedAssetFn;
|
|
364
|
+
/**
|
|
365
|
+
* Show the built-in "Focus writing" toggle in the WYSIWYG (preview-edit)
|
|
366
|
+
* toolbar row. `false` HIDES and DISABLES it (no keyboard path) and forces
|
|
367
|
+
* focus-writing OFF. `undefined`/`true` keep current behavior. The INITIAL
|
|
368
|
+
* on/off state still comes from `defaultFocusWriting`. (#270)
|
|
369
|
+
*/
|
|
370
|
+
focusWriting?: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Show the built-in Source / Split / Preview-edit mode switch. `false` hides
|
|
373
|
+
* it in both toolbar branches so the host owns the view switch (controlled
|
|
374
|
+
* `mode`/`onModeChange` still drive the panes). Default `true`. (#272)
|
|
375
|
+
*/
|
|
376
|
+
modeSwitch?: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Host-supplied controls rendered in the toolbar's trailing slot (where the
|
|
379
|
+
* built-in mode switch sits). Use with `modeSwitch={false}` to supply your
|
|
380
|
+
* own switch / actions. (#272)
|
|
381
|
+
*/
|
|
382
|
+
toolbarActions?: ReactNode;
|
|
383
|
+
}
|
|
384
|
+
declare const MarkdownWorkspace: react.ForwardRefExoticComponent<MarkdownWorkspaceProps & react.RefAttributes<MarkdownWorkspaceHandle>>;
|
|
385
|
+
|
|
386
|
+
interface MarkdownToolbarProps extends HTMLAttributes<HTMLDivElement> {
|
|
387
|
+
/** The Monaco editor instance to act on (from CodeEditor ref/onMount). */
|
|
388
|
+
editor: MonacoCodeEditor | null;
|
|
389
|
+
/** Extra controls rendered on the right (e.g. a mode switch). */
|
|
390
|
+
actions?: ReactNode;
|
|
391
|
+
/**
|
|
392
|
+
* Drives the **Insert** menu. When set, the menu lists every command that
|
|
393
|
+
* carries a `snippet` (grouped by `group`), inserting that markdown at the
|
|
394
|
+
* caret — so the source / split pane reaches the SAME blocks as the WYSIWYG
|
|
395
|
+
* slash menu (`/calc`, `/iterate`, `/pivot`, plus any consumer commands).
|
|
396
|
+
* When omitted, the menu falls back to the four built-in directive snippets.
|
|
397
|
+
* (A4)
|
|
398
|
+
*/
|
|
399
|
+
insertCommands?: SlashCommand[];
|
|
400
|
+
}
|
|
401
|
+
declare const MarkdownToolbar: react.ForwardRefExoticComponent<MarkdownToolbarProps & react.RefAttributes<HTMLDivElement>>;
|
|
402
|
+
|
|
403
|
+
/** Wrap the current selection (or insert a placeholder) with `before`/`after`. */
|
|
404
|
+
declare function wrapSelection(editor: MonacoCodeEditor, before: string, after?: string, placeholder?: string): void;
|
|
405
|
+
/** Toggle a line prefix (`# `, `> `, `- `, `1. `) on every selected line. */
|
|
406
|
+
declare function toggleLinePrefix(editor: MonacoCodeEditor, prefix: string): void;
|
|
407
|
+
/** Insert `[selection](url)` (or a placeholder link). */
|
|
408
|
+
declare function insertLink(editor: MonacoCodeEditor): void;
|
|
409
|
+
/** Insert a horizontal rule on its own line below the cursor. */
|
|
410
|
+
declare function insertHorizontalRule(editor: MonacoCodeEditor): void;
|
|
411
|
+
/** Insert a brand directive block at the cursor (e.g. card/callout/metric/timeline). */
|
|
412
|
+
declare function insertDirective(editor: MonacoCodeEditor, snippet: string): void;
|
|
413
|
+
|
|
414
|
+
type MarkdownHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
415
|
+
/**
|
|
416
|
+
* Canonical heading font-size per level, in rem — derived from the @elabs-ai/components-ui
|
|
417
|
+
* prose reading scale (h2/h4/h5/h6 == the title/subtitle/body role rems;
|
|
418
|
+
* h1/h3 are intermediate reading rungs).
|
|
419
|
+
*/
|
|
420
|
+
declare const MARKDOWN_HEADING_REM: Record<MarkdownHeadingLevel, number>;
|
|
421
|
+
/** Canonical heading weight (Tailwind `font-semibold`) — derived from @elabs-ai/components-ui. */
|
|
422
|
+
declare const MARKDOWN_HEADING_WEIGHT = 600;
|
|
423
|
+
/** Canonical heading letter-spacing (Tailwind `tracking-tight`) — derived from @elabs-ai/components-ui. */
|
|
424
|
+
declare const MARKDOWN_HEADING_TRACKING = "-0.025em";
|
|
425
|
+
/** Canonical reading measure (max content width). Mirrors `max-w-3xl`. */
|
|
426
|
+
declare const MARKDOWN_MEASURE = "48rem";
|
|
427
|
+
/**
|
|
428
|
+
* The scale as CSS custom properties, to set on the editor host (`.milkdown-host`)
|
|
429
|
+
* so `markdown-editor.css` reads the SAME numbers as the prose components instead of
|
|
430
|
+
* hardcoding its own. Spread onto a `style` prop:
|
|
431
|
+
* `<div className="milkdown-host" style={markdownScaleVars()} />`
|
|
432
|
+
*/
|
|
433
|
+
declare function markdownScaleVars(): Record<string, string>;
|
|
434
|
+
|
|
435
|
+
type MetricBlockProps = MetricCardProps;
|
|
436
|
+
declare const MetricBlock: react.ForwardRefExoticComponent<MetricCardProps & react.RefAttributes<HTMLDivElement>>;
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Shared remark pipeline for the brand markdown dialect.
|
|
440
|
+
*
|
|
441
|
+
* `remark-directive` parses generic container/leaf/text directives (`:::name`,
|
|
442
|
+
* `::name`, `:name`). `remarkBrandDirectives` then rewrites the four brand blocks
|
|
443
|
+
* — :::card / :::callout / ::metric / :::timeline — into a single `<brand-directive>`
|
|
444
|
+
* element carrying a JSON `data-brand` payload, which the preview's components map
|
|
445
|
+
* turns into real @brand components. Unknown directive names are preserved + flagged
|
|
446
|
+
* so the preview can surface an "unknown block" error instead of silently dropping.
|
|
447
|
+
*
|
|
448
|
+
* One JSON attribute (not many) keeps it robust against Streamdown's HTML
|
|
449
|
+
* sanitization (we only need to allow a single attribute through). The SAME plugin
|
|
450
|
+
* array is fed to Streamdown (preview) and can be fed to Milkdown via `$remark`
|
|
451
|
+
* (editor), so both sides parse `:::card` identically.
|
|
452
|
+
*/
|
|
453
|
+
|
|
454
|
+
declare const BRAND_DIRECTIVES: readonly ["card", "callout", "metric", "timeline"];
|
|
455
|
+
type BrandDirectiveName = (typeof BRAND_DIRECTIVES)[number];
|
|
456
|
+
/** Which directive syntax produced a node: `:::block`, `::leaf`, or `:inline`. */
|
|
457
|
+
type MarkdownDirectiveKind = "container" | "leaf" | "inline";
|
|
458
|
+
/** Context handed to a consumer directive renderer. */
|
|
459
|
+
interface MarkdownDirectiveContext {
|
|
460
|
+
name: string;
|
|
461
|
+
/** Which syntax matched — a renderer can branch (e.g. inline chip vs block card). */
|
|
462
|
+
kind: MarkdownDirectiveKind;
|
|
463
|
+
/** Directive attributes (`{key=value}`), strings only. */
|
|
464
|
+
attributes: Record<string, string>;
|
|
465
|
+
/** Rendered body (container), label (inline), or empty (leaf). */
|
|
466
|
+
children: ReactNode;
|
|
467
|
+
/**
|
|
468
|
+
* RAW label text for inline/leaf directives (markdown-significant characters
|
|
469
|
+
* preserved). Use this — not `children` — when you need the verbatim source
|
|
470
|
+
* (e.g. a calc expression `85 * 32`). `undefined` for container directives.
|
|
471
|
+
*/
|
|
472
|
+
textValue?: string;
|
|
473
|
+
/**
|
|
474
|
+
* RAW container body markdown (the source between the `:::name` fences). Only
|
|
475
|
+
* populated for directives registered with `rawBodyNames` (e.g. `iterate` /
|
|
476
|
+
* `pivot`), where the body is a TEMPLATE to interpolate + render per cell, not
|
|
477
|
+
* to display pre-rendered. `undefined` otherwise.
|
|
478
|
+
*/
|
|
479
|
+
rawBody?: string;
|
|
480
|
+
}
|
|
481
|
+
/** Register a custom `:::name` / `::name` / `:name` directive renderer. */
|
|
482
|
+
interface MarkdownDirectiveRenderer {
|
|
483
|
+
/** Directive name, e.g. `"decision"`, `"entity"`. */
|
|
484
|
+
name: string;
|
|
485
|
+
/** Accepted syntaxes. Default: all three. */
|
|
486
|
+
kinds?: readonly MarkdownDirectiveKind[];
|
|
487
|
+
render: (ctx: MarkdownDirectiveContext) => ReactNode;
|
|
488
|
+
}
|
|
489
|
+
/** Context handed to a consumer fence renderer. */
|
|
490
|
+
interface MarkdownFenceContext {
|
|
491
|
+
/** The fence body (trailing newline stripped). */
|
|
492
|
+
source: string;
|
|
493
|
+
/** The info-string language, e.g. `"calc"`. */
|
|
494
|
+
lang: string;
|
|
495
|
+
}
|
|
496
|
+
/** Register a custom ```lang fenced-block renderer (the mermaid/calc seam). */
|
|
497
|
+
interface MarkdownFenceRenderer {
|
|
498
|
+
/** Info-string this renderer claims, e.g. `"calc"`. */
|
|
499
|
+
lang: string;
|
|
500
|
+
render: (ctx: MarkdownFenceContext) => ReactNode;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Consumer extensions to the brand markdown dialect — passed to `MarkdownPreview`
|
|
504
|
+
* via the `extensions` prop. Registered directive NAMES are also fed to the parser
|
|
505
|
+
* (so `:entity[…]` is rewritten, while an unregistered `:foo` in prose stays
|
|
506
|
+
* literal text), and the renderers drive the preview's dispatch. The engine is
|
|
507
|
+
* never forked: new blocks register here.
|
|
508
|
+
*/
|
|
509
|
+
interface MarkdownExtensions {
|
|
510
|
+
directives?: readonly MarkdownDirectiveRenderer[];
|
|
511
|
+
fences?: readonly MarkdownFenceRenderer[];
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* remark transform: brand directives → `<brand-directive data-brand="{json}">`
|
|
515
|
+
* (block/leaf) or `<brand-directive-inline …>` (inline).
|
|
516
|
+
*
|
|
517
|
+
* `knownNames` is the set of directive names to TREAT AS KNOWN — i.e. rewrite
|
|
518
|
+
* rather than restore. It defaults to the four built-ins; `MarkdownPreview`
|
|
519
|
+
* extends it with the names a consumer registered via `extensions`, so a
|
|
520
|
+
* registered `:entity[…]` is rewritten while an unregistered `:foo` (or a stray
|
|
521
|
+
* prose colon) is still restored to literal text.
|
|
522
|
+
*/
|
|
523
|
+
declare function remarkBrandDirectives(knownNames?: readonly string[], rawBodyNames?: readonly string[]): (tree: unknown, file?: {
|
|
524
|
+
value?: unknown;
|
|
525
|
+
}) => void;
|
|
526
|
+
/** Options for {@link buildMarkdownPlugins}. */
|
|
527
|
+
interface BuildMarkdownPluginsOptions {
|
|
528
|
+
/**
|
|
529
|
+
* Extra directive names to treat as known (rewritten, not restored as literal
|
|
530
|
+
* text). The four built-ins are always known; pass the names a consumer
|
|
531
|
+
* registered via `extensions.directives`.
|
|
532
|
+
*/
|
|
533
|
+
directiveNames?: readonly string[];
|
|
534
|
+
/**
|
|
535
|
+
* Container directive names whose RAW body should be captured (as
|
|
536
|
+
* `payload.body` / `ctx.rawBody`) instead of pre-rendered — for templated
|
|
537
|
+
* blocks like `iterate` / `pivot` whose body is interpolated per cell.
|
|
538
|
+
*/
|
|
539
|
+
rawBodyNames?: readonly string[];
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* The shared remark plugin array (directive parsing + brand mapping). Pass
|
|
543
|
+
* `directiveNames` to recognize consumer-registered directives without forking
|
|
544
|
+
* the engine; with no options it parses exactly the four built-ins (backward
|
|
545
|
+
* compatible).
|
|
546
|
+
*/
|
|
547
|
+
declare function buildMarkdownPlugins(options?: BuildMarkdownPluginsOptions): PluggableList;
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Line-level markdown diff → block annotations for `MarkdownPreview` (#L18).
|
|
551
|
+
*
|
|
552
|
+
* `computeMarkdownAnnotations(before, after)` diffs two markdown sources and
|
|
553
|
+
* returns the annotation set the preview renders as a "ghost diff": added /
|
|
554
|
+
* modified blocks get a wash + accent rail, pure deletions become a slim
|
|
555
|
+
* "removed here" marker before the next surviving block.
|
|
556
|
+
*
|
|
557
|
+
* Lines are 1-based and refer to the AFTER source **including** any YAML
|
|
558
|
+
* frontmatter — `MarkdownPreview` shifts them when it strips frontmatter, so
|
|
559
|
+
* callers never have to think about the offset.
|
|
560
|
+
*
|
|
561
|
+
* The diff is a classic LCS (O(n·m) DP) — markdown documents are
|
|
562
|
+
* authoring-sized. Inputs beyond {@link MAX_DIFF_LINES} lines fall back to an
|
|
563
|
+
* empty annotation set (the UI simply shows no wash) instead of freezing.
|
|
564
|
+
*/
|
|
565
|
+
type MarkdownAnnotationKind = "added" | "modified" | "removed-before";
|
|
566
|
+
interface MarkdownAnnotation {
|
|
567
|
+
kind: MarkdownAnnotationKind;
|
|
568
|
+
/**
|
|
569
|
+
* For `added`/`modified`: the 1-based inclusive line range in the AFTER
|
|
570
|
+
* source. For `removed-before`: `startLine === endLine` is the line in the
|
|
571
|
+
* AFTER source that now sits where the removed content used to be.
|
|
572
|
+
*/
|
|
573
|
+
startLine: number;
|
|
574
|
+
endLine: number;
|
|
575
|
+
/** For `removed-before`: how many lines were removed. */
|
|
576
|
+
removedCount?: number;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Diff two markdown sources into preview annotations.
|
|
580
|
+
*
|
|
581
|
+
* Hunk semantics: a run of only-added lines → `added`; a run that replaces
|
|
582
|
+
* removed lines → `modified`; a run of only-removed lines → `removed-before`
|
|
583
|
+
* anchored on the first surviving AFTER line at-or-after the removal.
|
|
584
|
+
*/
|
|
585
|
+
declare function computeMarkdownAnnotations(before: string, after: string): MarkdownAnnotation[];
|
|
586
|
+
/** Honest "+a −r" totals for an annotation set (commit churn, drift rows). */
|
|
587
|
+
declare function summarizeAnnotations(annotations: MarkdownAnnotation[]): {
|
|
588
|
+
added: number;
|
|
589
|
+
removed: number;
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* Shift annotation lines by `-offset` (used when frontmatter is stripped before
|
|
593
|
+
* rendering). Annotations that fall entirely inside the stripped region drop out.
|
|
594
|
+
*/
|
|
595
|
+
declare function shiftAnnotations(annotations: MarkdownAnnotation[], offset: number): MarkdownAnnotation[];
|
|
596
|
+
/** Does the annotation set wash the given block line range? Most specific wins. */
|
|
597
|
+
declare function annotationForRange(annotations: MarkdownAnnotation[], startLine: number, endLine: number): MarkdownAnnotation | undefined;
|
|
598
|
+
/** The removed-marker (if any) anchored exactly at this block's first line. */
|
|
599
|
+
declare function removedMarkerAt(annotations: MarkdownAnnotation[], startLine: number): MarkdownAnnotation | undefined;
|
|
600
|
+
|
|
601
|
+
interface CalcBlockProps extends Omit<HTMLAttributes<HTMLElement>, "children" | "title"> {
|
|
602
|
+
/** The ```calc fence body. */
|
|
603
|
+
source: string;
|
|
604
|
+
/** Consumer-supplied evaluator (sync). The library bundles no math engine. */
|
|
605
|
+
evaluate: EvaluateCalc;
|
|
606
|
+
/**
|
|
607
|
+
* Block title shown in the header bar. By default a leading `# Heading` line in
|
|
608
|
+
* `source` is lifted here; with neither prop nor heading the header shows the
|
|
609
|
+
* neutral `calc` code-label. Pass `title` to override the displayed text.
|
|
610
|
+
*/
|
|
611
|
+
title?: ReactNode;
|
|
612
|
+
/** Show the running-total footer. Default true. */
|
|
613
|
+
showTotal?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Override the footer total. Defaults to `sheet.total`. Pass a `CalcValue`
|
|
616
|
+
* (rendered tabular via its `.display`) or any ReactNode to replace the
|
|
617
|
+
* computed total — e.g. a different aggregate the evaluator didn't surface.
|
|
618
|
+
*/
|
|
619
|
+
total?: CalcValue | ReactNode;
|
|
620
|
+
/** Footer label. Default `Total`. */
|
|
621
|
+
totalLabel?: ReactNode;
|
|
622
|
+
/**
|
|
623
|
+
* Parse trailing author markers (`@success`, `@line`, …) out of each source
|
|
624
|
+
* line — applying the row's tint/rule and stripping the marker from the
|
|
625
|
+
* rendered text. Default `true`. Set `false` if your calc dialect uses a
|
|
626
|
+
* trailing `@token` for something else.
|
|
627
|
+
*/
|
|
628
|
+
markers?: boolean;
|
|
629
|
+
/** Reserved for the editing variant (CalcWorkspace); preview is read-only. */
|
|
630
|
+
readOnly?: boolean;
|
|
631
|
+
}
|
|
632
|
+
declare const CalcBlock: react.ForwardRefExoticComponent<CalcBlockProps & react.RefAttributes<HTMLDivElement>>;
|
|
633
|
+
|
|
634
|
+
interface CalcInlineProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
635
|
+
/** The inline expression, e.g. `85 USD * 32`. */
|
|
636
|
+
source: string;
|
|
637
|
+
/** Consumer-supplied evaluator (sync). The library bundles no math engine. */
|
|
638
|
+
evaluate: EvaluateCalc;
|
|
639
|
+
}
|
|
640
|
+
declare const CalcInline: react.ForwardRefExoticComponent<CalcInlineProps & react.RefAttributes<HTMLSpanElement>>;
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Resolved citation data, returned by the consumer's `resolveCitation` hook.
|
|
644
|
+
* Provide `formatted` (your CSL/citeproc output) for a verbatim bibliography
|
|
645
|
+
* entry; otherwise the built-in assembler uses `author` / `year` / `title` /
|
|
646
|
+
* `container`. The library does NOT format CSL.
|
|
647
|
+
*/
|
|
648
|
+
interface CitationData {
|
|
649
|
+
/** The citation key (echoed back; optional). */
|
|
650
|
+
key?: string;
|
|
651
|
+
/** Inline author label for author-year + bibliography lead (e.g. `"Smith et al."`). */
|
|
652
|
+
author?: string;
|
|
653
|
+
/** Publication year. */
|
|
654
|
+
year?: string | number;
|
|
655
|
+
/** Work title. */
|
|
656
|
+
title?: string;
|
|
657
|
+
/** Container — journal, book, publisher, or site. */
|
|
658
|
+
container?: string;
|
|
659
|
+
/** Canonical URL (the bibliography link). */
|
|
660
|
+
url?: string;
|
|
661
|
+
/** DOI — linked as `https://doi.org/<doi>` when no `url` is given. */
|
|
662
|
+
doi?: string;
|
|
663
|
+
/** Fully-formatted reference (app's CSL output) — rendered verbatim when set. */
|
|
664
|
+
formatted?: string;
|
|
665
|
+
}
|
|
666
|
+
/** Consumer hook: citation key → data, or `null` when unknown (renders `[?]`). */
|
|
667
|
+
type ResolveCitation = (key: string) => CitationData | null;
|
|
668
|
+
/** Inline citation rendering style. */
|
|
669
|
+
type CitationStyle = "numeric" | "author-year";
|
|
670
|
+
/** One resolved citation with its assigned number (numbers skip unresolved keys). */
|
|
671
|
+
interface ResolvedCitation {
|
|
672
|
+
key: string;
|
|
673
|
+
/** 1-based number (numeric style + bibliography); `undefined` when unresolved. */
|
|
674
|
+
n?: number;
|
|
675
|
+
data: CitationData | null;
|
|
676
|
+
}
|
|
677
|
+
/** A single `@key` reference inside a citation bracket. */
|
|
678
|
+
interface CiteItem {
|
|
679
|
+
key: string;
|
|
680
|
+
/** Locator text after the key, e.g. `"p. 5"`. */
|
|
681
|
+
locator?: string;
|
|
682
|
+
/** `-@key` → suppress the author in author-year style. */
|
|
683
|
+
suppressAuthor?: boolean;
|
|
684
|
+
/** Prose before the key, e.g. `"see"`. */
|
|
685
|
+
prefix?: string;
|
|
686
|
+
}
|
|
687
|
+
interface CollectedCitations {
|
|
688
|
+
/** Resolved citations in first-appearance order (the bibliography list). */
|
|
689
|
+
order: ResolvedCitation[];
|
|
690
|
+
/** Lookup by key — both resolved and unresolved keys. */
|
|
691
|
+
byKey: Map<string, ResolvedCitation>;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Scan the markdown body once, in document order, resolving each unique citation
|
|
695
|
+
* key and numbering the resolved ones. The inline transform stays numbering-free
|
|
696
|
+
* and reads back from `byKey`, so inline `[1]` and bibliography entry 1 agree.
|
|
697
|
+
*/
|
|
698
|
+
declare function collectCitations(markdown: string, resolve: ResolveCitation): CollectedCitations;
|
|
699
|
+
interface BibliographyProps extends Omit<HTMLAttributes<HTMLElement>, "children" | "style"> {
|
|
700
|
+
/** Resolved citations; defaults to the citations collected by `MarkdownPreview`. */
|
|
701
|
+
entries?: ResolvedCitation[];
|
|
702
|
+
/** Numbering style; defaults to the preview's `citationStyle`. */
|
|
703
|
+
style?: CitationStyle;
|
|
704
|
+
/** Section heading label. Default `"References"`. */
|
|
705
|
+
title?: string;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* The generated reference list. Reads the preview's collected citations by default
|
|
709
|
+
* (the `::bibliography` block), or accepts an explicit `entries` array standalone.
|
|
710
|
+
* One focal separation gesture — a top `Separator` — over a quiet label + list.
|
|
711
|
+
*/
|
|
712
|
+
declare const Bibliography: react.ForwardRefExoticComponent<BibliographyProps & react.RefAttributes<HTMLElement>>;
|
|
713
|
+
|
|
714
|
+
type IterationLayout = "stacked" | "grid" | "matrix" | "bento";
|
|
715
|
+
/** The parsed `:::iterate` / `:::pivot` specification handed to `evaluate`. */
|
|
716
|
+
interface IterationSpec {
|
|
717
|
+
/** `iterate` (1D repeat) or `pivot` (2D cross-tab). */
|
|
718
|
+
kind: "iterate" | "pivot";
|
|
719
|
+
/** How the cells are laid out. */
|
|
720
|
+
layout: IterationLayout;
|
|
721
|
+
/** The per-cell markdown template (the directive body). */
|
|
722
|
+
template: string;
|
|
723
|
+
/** Loop-variable name exposed to `interpolate` (default `"item"`). */
|
|
724
|
+
as: string;
|
|
725
|
+
/** Opaque data-source reference; resolved by the consumer's `evaluate`. */
|
|
726
|
+
source?: string;
|
|
727
|
+
/** Pivot row / column dimension field names (`pivot`). */
|
|
728
|
+
rows?: string;
|
|
729
|
+
cols?: string;
|
|
730
|
+
/** Explicit grid column count (`grid`). */
|
|
731
|
+
columns?: number;
|
|
732
|
+
/** All raw directive attributes (escape hatch for `evaluate`). */
|
|
733
|
+
attributes: Record<string, string>;
|
|
734
|
+
}
|
|
735
|
+
/** One resolved cell. */
|
|
736
|
+
interface IterationCell {
|
|
737
|
+
/** Interpolation context (the row record / pivot-cell scope). */
|
|
738
|
+
context: Record<string, unknown>;
|
|
739
|
+
/** Stable key (defaults to the index). */
|
|
740
|
+
key?: string;
|
|
741
|
+
/** `matrix`: the row / column header this cell sits at. */
|
|
742
|
+
row?: string;
|
|
743
|
+
col?: string;
|
|
744
|
+
/** `bento`: tile size preset. Defaults to a deterministic per-index rhythm. */
|
|
745
|
+
size?: BentoGridSize;
|
|
746
|
+
/** Pre-rendered markdown — skips `interpolate` when the app already templated. */
|
|
747
|
+
markdown?: string;
|
|
748
|
+
}
|
|
749
|
+
/** What the consumer's `evaluate` returns. */
|
|
750
|
+
interface IterationData {
|
|
751
|
+
/** Cells in render order. */
|
|
752
|
+
cells: IterationCell[];
|
|
753
|
+
/** `matrix`: ordered row + column header labels. */
|
|
754
|
+
rowHeaders?: string[];
|
|
755
|
+
colHeaders?: string[];
|
|
756
|
+
/** `grid`: column header labels (also sets the column count). */
|
|
757
|
+
columns?: string[];
|
|
758
|
+
}
|
|
759
|
+
/** Consumer hook: resolve a spec to its data, or `null` when unavailable. */
|
|
760
|
+
type EvaluateIteration = (spec: IterationSpec) => IterationData | null;
|
|
761
|
+
/** Consumer hook: fill a template with a cell context. */
|
|
762
|
+
type InterpolateTemplate = (template: string, context: Record<string, unknown>) => string;
|
|
763
|
+
/**
|
|
764
|
+
* Minimal `{{ path.to.value }}` substitution over the cell context (dot paths).
|
|
765
|
+
* Safe (no eval). An UNRESOLVED token is left **literal** — so a nested
|
|
766
|
+
* `:::iterate`'s tokens survive the outer pass and resolve in the inner one (use
|
|
767
|
+
* the `as` loop variable in nested templates to avoid scope collisions). Replace
|
|
768
|
+
* it with your own engine (Mustache/Handlebars/…) via the `interpolate` prop.
|
|
769
|
+
*/
|
|
770
|
+
declare function defaultInterpolate(template: string, context: Record<string, unknown>): string;
|
|
771
|
+
interface IterationBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
772
|
+
/** The parsed iteration spec (from the directive, or hand-built). */
|
|
773
|
+
spec: IterationSpec;
|
|
774
|
+
/** Resolve the spec to data (consumer data source). */
|
|
775
|
+
evaluate: EvaluateIteration;
|
|
776
|
+
/** Fill a template with a cell context. Default: `{{path}}` substitution. */
|
|
777
|
+
interpolate?: InterpolateTemplate;
|
|
778
|
+
/** Render a resolved cell's markdown → node (e.g. a nested `MarkdownPreview`). */
|
|
779
|
+
render: (markdown: string) => ReactNode;
|
|
780
|
+
/** Override `spec.layout`. */
|
|
781
|
+
layout?: IterationLayout;
|
|
782
|
+
/** Empty-state message when there are no cells. */
|
|
783
|
+
emptyLabel?: string;
|
|
784
|
+
}
|
|
785
|
+
declare const IterationBlock: react.ForwardRefExoticComponent<IterationBlockProps & react.RefAttributes<HTMLDivElement>>;
|
|
786
|
+
|
|
787
|
+
/** Build an `IterationSpec` from a directive's name + attributes + raw body. */
|
|
788
|
+
declare function specFromDirective(name: "iterate" | "pivot", attributes: Record<string, string>, rawBody: string | undefined): IterationSpec;
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Hover affordances beside headings (#L6 companion): a generic render-prop —
|
|
792
|
+
* the preview knows nothing about what the action does (pinning, anchors,
|
|
793
|
+
* copy-link…). Revealed on heading hover / focus, and kept visible while the
|
|
794
|
+
* slot contains a pressed toggle (`aria-pressed="true"`).
|
|
795
|
+
*/
|
|
796
|
+
interface MarkdownHeadingInfo {
|
|
797
|
+
level: ProseHeadingLevel;
|
|
798
|
+
/** Plain text content of the heading. */
|
|
799
|
+
text: string;
|
|
800
|
+
/** 1-based start line in the frontmatter-STRIPPED source (= `data-sourcepos`). */
|
|
801
|
+
line?: number;
|
|
802
|
+
}
|
|
803
|
+
type MarkdownUrlKind = "image" | "link";
|
|
804
|
+
/**
|
|
805
|
+
* Options passed to `resolveWikilink` for each wikilink found in the document.
|
|
806
|
+
*/
|
|
807
|
+
interface WikilinkResolveOptions {
|
|
808
|
+
/** The `#anchor` fragment, if present — e.g. `[[target#Section 1]]` → `"Section 1"`. */
|
|
809
|
+
anchor?: string;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Options passed to `resolveTransclusion` for each transclusion embed found.
|
|
813
|
+
*/
|
|
814
|
+
interface TransclusionResolveOptions {
|
|
815
|
+
/**
|
|
816
|
+
* A `#section` heading, if present — e.g. `![[target#Introduction]]` → `"Introduction"`.
|
|
817
|
+
* The consumer can use this to extract only that section from the document.
|
|
818
|
+
*/
|
|
819
|
+
section?: string;
|
|
820
|
+
}
|
|
821
|
+
interface MarkdownPreviewProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
822
|
+
/** Markdown source. */
|
|
823
|
+
children: string;
|
|
824
|
+
/** Strip a leading YAML frontmatter block before rendering. Default true. */
|
|
825
|
+
stripFrontmatter?: boolean;
|
|
826
|
+
/**
|
|
827
|
+
* Ghost-diff annotations (#L18) — typically from `computeMarkdownAnnotations`.
|
|
828
|
+
* Lines are 1-based relative to the FULL `children` source (frontmatter
|
|
829
|
+
* included); the preview shifts them when `stripFrontmatter` removes lines.
|
|
830
|
+
*/
|
|
831
|
+
annotations?: MarkdownAnnotation[];
|
|
832
|
+
/**
|
|
833
|
+
* Rewrite image/link URLs (#L4) — e.g. resolve repo-relative paths or swap
|
|
834
|
+
* private-repo asset URLs for authenticated blob URLs. Synchronous by design:
|
|
835
|
+
* async consumers cache upstream and re-render when the URL is ready.
|
|
836
|
+
*/
|
|
837
|
+
resolveUrl?: (url: string, kind: MarkdownUrlKind) => string;
|
|
838
|
+
/**
|
|
839
|
+
* In-document search term (≥2 chars): mermaid diagrams mark matching nodes.
|
|
840
|
+
* Pair with an app-side text highlighter (CSS Custom Highlight API) for the
|
|
841
|
+
* prose occurrences.
|
|
842
|
+
*/
|
|
843
|
+
searchTerm?: string;
|
|
844
|
+
/**
|
|
845
|
+
* 1-based line of the ACTIVE search hit, relative to the FULL `children`
|
|
846
|
+
* source (same convention as `annotations`). Its block gets a primary wash;
|
|
847
|
+
* in a mermaid fence the matching node gets the active stroke.
|
|
848
|
+
*/
|
|
849
|
+
activeSearchLine?: number;
|
|
850
|
+
/**
|
|
851
|
+
* Render hover affordances beside each heading (pin/anchor/copy-link…).
|
|
852
|
+
* Presentational slot — revealed on heading hover/focus and kept visible
|
|
853
|
+
* while it contains a pressed toggle. `line` is in frontmatter-STRIPPED
|
|
854
|
+
* coordinates (the same space as `data-sourcepos` / `parseMarkdownOutline`).
|
|
855
|
+
*/
|
|
856
|
+
headingActions?: (heading: MarkdownHeadingInfo) => ReactNode;
|
|
857
|
+
/**
|
|
858
|
+
* Evaluate a ```calc fence to a `CalcSheet` (the library renders, the app
|
|
859
|
+
* computes — mirrors `resolveUrl`). With no `evaluate`, a ```calc fence renders
|
|
860
|
+
* as a normal code block; the math engine stays in the consumer.
|
|
861
|
+
*
|
|
862
|
+
* Sugar over `extensions.fences`: it registers a built-in `calc` fence renderer.
|
|
863
|
+
* Register your own `calc` fence via `extensions` to override it.
|
|
864
|
+
*/
|
|
865
|
+
evaluate?: EvaluateCalc;
|
|
866
|
+
/**
|
|
867
|
+
* Extend the markdown dialect without forking the engine: register custom
|
|
868
|
+
* `:::`/`::`/`:` directive renderers and ```lang fence renderers. Registered
|
|
869
|
+
* directive names are also fed to the parser (so `:entity[…]` is recognized
|
|
870
|
+
* while an unregistered prose colon stays literal). Domain logic stays in the
|
|
871
|
+
* consumer's renderer (the library renders; the app computes).
|
|
872
|
+
*/
|
|
873
|
+
extensions?: MarkdownExtensions;
|
|
874
|
+
/**
|
|
875
|
+
* Resolve an Obsidian-style wikilink (`[[target]]`, `[[target|alias]]`,
|
|
876
|
+
* `[[target#anchor]]`, `[[target#anchor|alias]]`) to a URL.
|
|
877
|
+
*
|
|
878
|
+
* - Return a string href to produce a real `<a>` (flows through `resolveUrl`
|
|
879
|
+
* and `renderLinkPreview` like any other link).
|
|
880
|
+
* - Return `null` to leave the wikilink as literal plain text `[[target]]`
|
|
881
|
+
* (graceful — never a broken link).
|
|
882
|
+
*
|
|
883
|
+
* Supported forms:
|
|
884
|
+
* - `[[target]]` → `resolveWikilink("target", {})`
|
|
885
|
+
* - `[[target|alias]]` → `resolveWikilink("target", {})`, link text = alias
|
|
886
|
+
* - `[[target#anchor]]` → `resolveWikilink("target", { anchor: "anchor" })`
|
|
887
|
+
* - `[[target#anchor|alias]]` → `resolveWikilink("target", { anchor: "anchor" })`, text = alias
|
|
888
|
+
*/
|
|
889
|
+
resolveWikilink?: (target: string, opts: WikilinkResolveOptions) => string | null;
|
|
890
|
+
/**
|
|
891
|
+
* Resolve an Obsidian-style transclusion embed (`![[target]]`,
|
|
892
|
+
* `![[target#section]]`) to the markdown TEXT to embed.
|
|
893
|
+
*
|
|
894
|
+
* - Return the markdown string to embed; it will be recursively rendered as a
|
|
895
|
+
* visually-nested, AT-labelled block (depth cap: 3 levels).
|
|
896
|
+
* - Return `null` to leave the embed as literal plain text `![[target]]`.
|
|
897
|
+
*
|
|
898
|
+
* The library never fetches — the consumer owns the vault index and resolution.
|
|
899
|
+
*/
|
|
900
|
+
resolveTransclusion?: (target: string, opts: TransclusionResolveOptions) => string | null;
|
|
901
|
+
/**
|
|
902
|
+
* Wrap every rendered `<a>` to attach a hover/inline link preview (e.g. a
|
|
903
|
+
* `@elabs-ai/components-ui` HoverCard showing metadata). The library does NOT fetch; the
|
|
904
|
+
* consumer owns the preview content.
|
|
905
|
+
*
|
|
906
|
+
* Return `children` unchanged if the href should not trigger a preview.
|
|
907
|
+
* Default (not supplied) → the plain `Link` component.
|
|
908
|
+
*/
|
|
909
|
+
renderLinkPreview?: (href: string, children: ReactNode) => ReactNode;
|
|
910
|
+
/**
|
|
911
|
+
* Branded GFM footnotes (`[^1]` … `[^1]: definition`) — quiet superscript refs
|
|
912
|
+
* + a footnote section at the document end with working same-page back-refs.
|
|
913
|
+
* Default `false` (footnotes parse but render with the plain GFM treatment).
|
|
914
|
+
*/
|
|
915
|
+
footnotes?: boolean;
|
|
916
|
+
/**
|
|
917
|
+
* Math via `remark-math` + KaTeX — `$inline$` and `$$block$$` (on their own
|
|
918
|
+
* lines). KaTeX runs untrusted-safe (`trust:false`, bounded macro expansion);
|
|
919
|
+
* MathML is emitted for assistive tech. **The consumer must load KaTeX CSS once**
|
|
920
|
+
* (`import "katex/dist/katex.min.css"`). Default `false`.
|
|
921
|
+
*/
|
|
922
|
+
math?: boolean;
|
|
923
|
+
/**
|
|
924
|
+
* Resolve a Pandoc / Better-BibTeX citation key (`[@smith2020]`,
|
|
925
|
+
* `[@a; @b]`, `[@a, p. 5]`, `[-@a]`) to {@link CitationData}, or `null` when
|
|
926
|
+
* unknown. The BibTeX/CSL database + any CSL formatting live in the app — the
|
|
927
|
+
* library renders inline cites + the `::bibliography` / `::references` block with
|
|
928
|
+
* consistent numbering. Setting this enables citations (the same way `evaluate`
|
|
929
|
+
* enables calc).
|
|
930
|
+
*/
|
|
931
|
+
resolveCitation?: ResolveCitation;
|
|
932
|
+
/** Inline citation style: `"numeric"` `[1]` (default) or `"author-year"` `(Smith 2020)`. */
|
|
933
|
+
citationStyle?: CitationStyle;
|
|
934
|
+
/**
|
|
935
|
+
* Enable the generated `::toc` block (a quiet in-flow table of contents) and
|
|
936
|
+
* stamp stable slug `id`s on headings so the anchors resolve. Reuses the same
|
|
937
|
+
* heading extractor as `DocumentOutline`. Default `false`.
|
|
938
|
+
*/
|
|
939
|
+
toc?: boolean;
|
|
940
|
+
/**
|
|
941
|
+
* Resolve a `:::iterate` / `:::pivot` block's {@link IterationSpec} (parsed from
|
|
942
|
+
* the directive's attributes + body template) to its data. The data source +
|
|
943
|
+
* any query live in the app — the library renders the repeated/cross-tabbed
|
|
944
|
+
* cells. Setting this enables the `iterate` + `pivot` directives (the way
|
|
945
|
+
* `evaluate` enables calc).
|
|
946
|
+
*/
|
|
947
|
+
evaluateIteration?: EvaluateIteration;
|
|
948
|
+
/**
|
|
949
|
+
* Fill a `:::iterate` cell template with its row/cell context. Default: a
|
|
950
|
+
* minimal `{{path}}` substitution — pass your own engine for anything richer.
|
|
951
|
+
*/
|
|
952
|
+
interpolate?: InterpolateTemplate;
|
|
953
|
+
}
|
|
954
|
+
declare const MarkdownPreview: react.ForwardRefExoticComponent<MarkdownPreviewProps & react.RefAttributes<HTMLDivElement>>;
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* `@elabs-ai/components-editor/markdown/parse` — a Monaco-free markdown parser.
|
|
958
|
+
*
|
|
959
|
+
* `parseMarkdown(md)` returns the mdast `Root` for the SAME dialect the branded
|
|
960
|
+
* preview parses: GitHub-flavored markdown + `:::`/`::`/`:` directives + YAML
|
|
961
|
+
* frontmatter. Split onto its own leaf subpath (like `./markdown/frontmatter`) so
|
|
962
|
+
* SERVER, RSC, and unit-test consumers can parse markdown WITHOUT pulling the
|
|
963
|
+
* editor engines (Milkdown, Monaco, Streamdown) into their bundle — the whole
|
|
964
|
+
* reason the `.` vs `./markdown` split exists. Depends only on `unified` +
|
|
965
|
+
* `remark-*` (no React, no Monaco).
|
|
966
|
+
*
|
|
967
|
+
* It returns RAW directive mdast (`containerDirective` / `leafDirective` /
|
|
968
|
+
* `textDirective` nodes) — it does NOT run `remarkBrandDirectives` (that rewrites
|
|
969
|
+
* directives into the `<brand-directive>` hast tag, which is a RENDER concern).
|
|
970
|
+
* Walk the tree by `node.type` + `node.name` yourself. The match is at the
|
|
971
|
+
* DIALECT level (same plugins/extensions); it is not byte-identical to the tree
|
|
972
|
+
* Streamdown builds internally (which also applies a streaming block-splitter).
|
|
973
|
+
*/
|
|
974
|
+
|
|
975
|
+
/** Parse markdown to mdast (gfm + directives + frontmatter). Monaco-free. */
|
|
976
|
+
declare function parseMarkdown(md: string): Root;
|
|
977
|
+
|
|
978
|
+
interface ParsedDocument {
|
|
979
|
+
/** Parsed frontmatter object ({} when there is no frontmatter block). */
|
|
980
|
+
frontmatter: Record<string, unknown>;
|
|
981
|
+
/** Markdown body with the frontmatter block removed. */
|
|
982
|
+
content: string;
|
|
983
|
+
hasFrontmatter: boolean;
|
|
984
|
+
}
|
|
985
|
+
declare function parseFrontmatter(source: string): ParsedDocument;
|
|
986
|
+
declare function serializeFrontmatter(frontmatter: Record<string, unknown>, content: string): string;
|
|
987
|
+
|
|
988
|
+
interface MermaidDiagramProps extends HTMLAttributes<HTMLDivElement> {
|
|
989
|
+
/** Mermaid source (the fence body). */
|
|
990
|
+
chart: string;
|
|
991
|
+
/** Accessible name for the rendered diagram. Default "Diagram". */
|
|
992
|
+
label?: string;
|
|
993
|
+
/** Show the hover copy-source button. Default true. */
|
|
994
|
+
copyable?: boolean;
|
|
995
|
+
/** Show the hover expand-to-modal button. Default true. */
|
|
996
|
+
expandable?: boolean;
|
|
997
|
+
/**
|
|
998
|
+
* In-document search term (≥2 chars): nodes/edge labels whose text contains
|
|
999
|
+
* it get the hit stroke — the diagram participates in document search.
|
|
1000
|
+
*/
|
|
1001
|
+
highlightTerm?: string;
|
|
1002
|
+
/**
|
|
1003
|
+
* Source text of the ACTIVE search hit (the clicked finding's line). The
|
|
1004
|
+
* matching hit is promoted to the primary "active" stroke.
|
|
1005
|
+
*/
|
|
1006
|
+
activeText?: string;
|
|
1007
|
+
}
|
|
1008
|
+
declare const MermaidDiagram: react.ForwardRefExoticComponent<MermaidDiagramProps & react.RefAttributes<HTMLDivElement>>;
|
|
1009
|
+
|
|
1010
|
+
interface MermaidWorkspaceProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
1011
|
+
value?: string;
|
|
1012
|
+
defaultValue?: string;
|
|
1013
|
+
onChange?: (source: string) => void;
|
|
1014
|
+
/** Debounce (ms) before the diagram re-renders while typing. Default 350. */
|
|
1015
|
+
debounceMs?: number;
|
|
1016
|
+
}
|
|
1017
|
+
declare const MermaidWorkspace: react.ForwardRefExoticComponent<MermaidWorkspaceProps & react.RefAttributes<HTMLDivElement>>;
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Shared, engine-agnostic helpers for the calc AUTHORING surfaces (#220).
|
|
1021
|
+
*
|
|
1022
|
+
* Both editor surfaces — the Monaco source editor and the Milkdown WYSIWYG
|
|
1023
|
+
* editor — need the same things: find the ```calc fences, ask the consumer's
|
|
1024
|
+
* hooks for highlight tokens + results, and turn those into decorations. The
|
|
1025
|
+
* decoration *application* differs per engine (Monaco `inlineClassName` vs a
|
|
1026
|
+
* ProseMirror `DecorationSet`), but the *logic* here is pure and shared, so it is
|
|
1027
|
+
* unit-testable without rendering either engine (Monaco can't render in jsdom).
|
|
1028
|
+
*
|
|
1029
|
+
* Governing rule (D5): the library decorates, the consumer computes. Nothing here
|
|
1030
|
+
* does any math — it only calls the consumer-supplied {@link CalcEditorHooks} and
|
|
1031
|
+
* shapes the results. A throwing hook degrades to "no decorations" rather than
|
|
1032
|
+
* blanking the editor (mirrors how `CalcBlock` never throws on a bad block).
|
|
1033
|
+
*/
|
|
1034
|
+
|
|
1035
|
+
/** A located ```calc fence within a markdown document. Lines are 1-based. */
|
|
1036
|
+
interface CalcFence {
|
|
1037
|
+
/** 1-based line of the opening fence (` ```calc `). */
|
|
1038
|
+
openLine: number;
|
|
1039
|
+
/** 1-based line of the closing fence, or `lines + 1` when unterminated. */
|
|
1040
|
+
closeLine: number;
|
|
1041
|
+
/** 1-based line of the first body line (`openLine + 1`). */
|
|
1042
|
+
bodyStartLine: number;
|
|
1043
|
+
/** 1-based line of the last body line (`closeLine - 1`); `< bodyStartLine` if empty. */
|
|
1044
|
+
bodyEndLine: number;
|
|
1045
|
+
/** The fence body (body lines joined by `"\n"`). */
|
|
1046
|
+
source: string;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Scan a markdown string for ```calc fences. Tolerant of leading indentation,
|
|
1050
|
+
* `~~~` fences, and an unterminated trailing fence (treated as running to EOF) —
|
|
1051
|
+
* which is the normal state while the author is still typing the block.
|
|
1052
|
+
*/
|
|
1053
|
+
declare function findCalcFences(text: string): CalcFence[];
|
|
1054
|
+
/**
|
|
1055
|
+
* Class string for a highlight token. Hue comes from the `--calc-*` tokens (via
|
|
1056
|
+
* `calc-editor.css`), but — exactly like `CalcBlock.tokenClass` — hue is never
|
|
1057
|
+
* the SOLE cue: a `var-def` carries weight and an unresolved token a dotted
|
|
1058
|
+
* underline, so roles stay distinct in the high-contrast theme (where the calc
|
|
1059
|
+
* colors collapse toward the foreground).
|
|
1060
|
+
*/
|
|
1061
|
+
declare function calcTokenClassName(kind: CalcTokenKind, resolved: boolean): string;
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Monaco calc layer (#220) — live highlighting + autocomplete + result inlays for
|
|
1065
|
+
* ```calc fences inside a markdown Monaco model.
|
|
1066
|
+
*
|
|
1067
|
+
* - HIGHLIGHT is a decoration pass (not a Monarch language): the model is markdown,
|
|
1068
|
+
* so we tokenize each calc fence body via the consumer's `tokenize` hook and apply
|
|
1069
|
+
* `inlineClassName` decorations colored from the `--calc-*` tokens (calc-editor.css).
|
|
1070
|
+
* - COMPLETIONS come from a markdown `CompletionItemProvider` scoped to calc fences,
|
|
1071
|
+
* delegating to the consumer's `complete` hook.
|
|
1072
|
+
* - INLAYS are Monaco inlay hints (themed via the theme bridge's `editorInlayHint.*`
|
|
1073
|
+
* colors, so they re-apply on theme change), built from the consumer's `evaluate`.
|
|
1074
|
+
*
|
|
1075
|
+
* The providers register ONCE per language and look the active hooks up per-model via
|
|
1076
|
+
* a registry, so any number of markdown editors can be wired independently. All the
|
|
1077
|
+
* column/position math lives in `calc-editor.ts` (engine-neutral + unit-tested);
|
|
1078
|
+
* this module only maps those specs to Monaco objects and owns the lifecycle.
|
|
1079
|
+
*/
|
|
1080
|
+
|
|
1081
|
+
/** Resolver of the latest hooks for a model (read through a ref so prop-identity churn is free). */
|
|
1082
|
+
type HooksGetter = () => CalcEditorHooks | undefined;
|
|
1083
|
+
/**
|
|
1084
|
+
* Wire calc highlighting + completion + inlays onto a markdown Monaco editor.
|
|
1085
|
+
* `getHooks` is read fresh on each update, so changing the `calc` prop's identity
|
|
1086
|
+
* never forces a re-attach. Returns a disposer; call it on unmount / when `calc`
|
|
1087
|
+
* is removed.
|
|
1088
|
+
*/
|
|
1089
|
+
declare function attachCalcMonaco(editor: monaco.editor.IStandaloneCodeEditor, getHooks: HooksGetter): () => void;
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Milkdown / ProseMirror calc layer (#220) — live highlighting + result inlays for
|
|
1093
|
+
* ```calc fences inside the WYSIWYG editor.
|
|
1094
|
+
*
|
|
1095
|
+
* A self-owned raw `$prose` plugin (zero new deps) that builds a `DecorationSet`
|
|
1096
|
+
* over every `code_block` whose language is `calc`:
|
|
1097
|
+
* - inline decorations color each token from the `--calc-*` tokens (calc-editor.css);
|
|
1098
|
+
* - a widget decoration after each line shows the computed result inlay.
|
|
1099
|
+
* The set is recomputed when the document changes. Hooks are read through a getter
|
|
1100
|
+
* so a fresh `calc` prop identity never rebuilds the editor (mirrors `slashConfigRef`).
|
|
1101
|
+
*
|
|
1102
|
+
* The position math reuses the engine-neutral helpers in `calc-editor.ts`; a
|
|
1103
|
+
* ProseMirror code block stores its body as plain text with literal `\n`, so a
|
|
1104
|
+
* line's absolute position is `codeBlockContentStart + lineOffset + column`.
|
|
1105
|
+
*/
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Build the calc decoration plugin. `getHooks` is read on every recompute so the
|
|
1109
|
+
* editor never rebuilds when the `calc` prop identity changes. Returns a Milkdown
|
|
1110
|
+
* plugin array to `.use()` (only when calc authoring is enabled).
|
|
1111
|
+
*/
|
|
1112
|
+
declare function calcProsePlugins(getHooks: () => CalcEditorHooks | undefined): MilkdownPlugin[];
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
* Normalization-aware merge for WYSIWYG markdown editing (review WI-1).
|
|
1116
|
+
*
|
|
1117
|
+
* Problem: Milkdown serializes the WHOLE document on every edit, normalizing
|
|
1118
|
+
* formatting it never touched (list markers, wrapping, spacing). Feeding that
|
|
1119
|
+
* back into the buffer turns a one-line edit into a whole-file rewrite —
|
|
1120
|
+
* destroying git blame and making PR review impossible.
|
|
1121
|
+
*
|
|
1122
|
+
* Fix: three-way line merge.
|
|
1123
|
+
* - `original` — the byte-exact source the editor was opened with.
|
|
1124
|
+
* - `baseline` — the editor's serialization of `original` BEFORE any edit
|
|
1125
|
+
* (pure normalization drift).
|
|
1126
|
+
* - `edited` — the editor's serialization after user edits.
|
|
1127
|
+
*
|
|
1128
|
+
* `diff(baseline, edited)` isolates what the USER changed; an
|
|
1129
|
+
* `original ↔ baseline` alignment maps those hunks back onto `original`.
|
|
1130
|
+
* Everything the user didn't touch keeps its original bytes. Granularity is
|
|
1131
|
+
* the contiguous normalized run — markdown's blank lines survive
|
|
1132
|
+
* serialization byte-exact, so in practice that's a single block.
|
|
1133
|
+
*
|
|
1134
|
+
* Guarantees:
|
|
1135
|
+
* - no user edit (`baseline === edited`) → returns `original` byte-exact;
|
|
1136
|
+
* - no normalization drift (`original === baseline`) → returns `edited`;
|
|
1137
|
+
* - a user hunk inside a normalized block replaces exactly that block;
|
|
1138
|
+
* - oversized inputs (> {@link MAX_DIFF_LINES}) fall back to `edited`.
|
|
1139
|
+
*/
|
|
1140
|
+
/**
|
|
1141
|
+
* Merge a WYSIWYG serialization back onto the original source, keeping
|
|
1142
|
+
* original bytes for everything the user didn't touch.
|
|
1143
|
+
*/
|
|
1144
|
+
declare function mergeNormalizedEdit(original: string, baseline: string, edited: string): string;
|
|
1145
|
+
|
|
1146
|
+
interface MarkdownOutlineItem {
|
|
1147
|
+
/** Stable slug (GitHub-style, deduped with `-n` suffixes). */
|
|
1148
|
+
id: string;
|
|
1149
|
+
/** Plain heading text (inline markdown stripped). */
|
|
1150
|
+
text: string;
|
|
1151
|
+
/** Heading level 1–6. */
|
|
1152
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
1153
|
+
/** 1-based line in the frontmatter-stripped source (matches `data-sourcepos`). */
|
|
1154
|
+
line: number;
|
|
1155
|
+
}
|
|
1156
|
+
declare function parseMarkdownOutline(markdown: string): MarkdownOutlineItem[];
|
|
1157
|
+
|
|
1158
|
+
/** Memoized outline of a markdown source. */
|
|
1159
|
+
declare function useMarkdownOutline(markdown: string): MarkdownOutlineItem[];
|
|
1160
|
+
interface DocumentOutlineProps extends Omit<HTMLAttributes<HTMLElement>, "onSelect"> {
|
|
1161
|
+
items: MarkdownOutlineItem[];
|
|
1162
|
+
/** The outline item currently in view. */
|
|
1163
|
+
activeId?: string;
|
|
1164
|
+
onSelect?: (item: MarkdownOutlineItem) => void;
|
|
1165
|
+
/**
|
|
1166
|
+
* Per-entry hover affordances (pin/copy-link…), rendered at the row end.
|
|
1167
|
+
* Revealed on row hover/focus; stays visible while it contains a pressed
|
|
1168
|
+
* toggle (`aria-pressed="true"`).
|
|
1169
|
+
*/
|
|
1170
|
+
itemActions?: (item: MarkdownOutlineItem) => ReactNode;
|
|
1171
|
+
}
|
|
1172
|
+
declare const DocumentOutline: react.ForwardRefExoticComponent<DocumentOutlineProps & react.RefAttributes<HTMLElement>>;
|
|
1173
|
+
|
|
1174
|
+
declare const DECISION_STATUSES: readonly ["accepted", "rejected", "proposed", "superseded"];
|
|
1175
|
+
type DecisionStatus = (typeof DECISION_STATUSES)[number];
|
|
1176
|
+
declare const decisionCardVariants: (props?: ({
|
|
1177
|
+
status?: "accepted" | "rejected" | "proposed" | "superseded" | null | undefined;
|
|
1178
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
1179
|
+
interface DecisionCardProps extends HTMLAttributes<HTMLElement> {
|
|
1180
|
+
/**
|
|
1181
|
+
* Decision outcome. One of the four canonical states; anything unrecognised
|
|
1182
|
+
* renders as "proposed".
|
|
1183
|
+
*/
|
|
1184
|
+
status?: string;
|
|
1185
|
+
/**
|
|
1186
|
+
* ISO date or human-readable date of the decision
|
|
1187
|
+
* (e.g. `"2026-06-15"` or `"June 2026"`).
|
|
1188
|
+
*/
|
|
1189
|
+
date?: string;
|
|
1190
|
+
/**
|
|
1191
|
+
* Comma-separated alternative options considered before this decision.
|
|
1192
|
+
* E.g. `"Redis cache, in-memory map, SQLite"`.
|
|
1193
|
+
*/
|
|
1194
|
+
alternatives?: string;
|
|
1195
|
+
/** The rationale body (rendered markdown children of the directive). */
|
|
1196
|
+
children?: ReactNode;
|
|
1197
|
+
}
|
|
1198
|
+
declare const DecisionCard: react.ForwardRefExoticComponent<DecisionCardProps & react.RefAttributes<HTMLElement>>;
|
|
1199
|
+
|
|
1200
|
+
declare const ENTITY_KINDS: readonly ["org", "person", "place", "product", "concept"];
|
|
1201
|
+
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
1202
|
+
declare const entityChipVariants: (props?: ({
|
|
1203
|
+
kind?: "default" | "product" | "org" | "person" | "place" | "concept" | null | undefined;
|
|
1204
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
1205
|
+
interface EntityChipProps extends HTMLAttributes<HTMLSpanElement> {
|
|
1206
|
+
/** Entity kind — drives icon and tone. */
|
|
1207
|
+
kind?: string;
|
|
1208
|
+
/** Display label (the directive's label text or `name` attribute). */
|
|
1209
|
+
children?: ReactNode;
|
|
1210
|
+
}
|
|
1211
|
+
declare const EntityChip: react.ForwardRefExoticComponent<EntityChipProps & react.RefAttributes<HTMLSpanElement>>;
|
|
1212
|
+
interface EntityCardProps extends HTMLAttributes<HTMLElement> {
|
|
1213
|
+
/** Entity kind — drives the icon and header tone. */
|
|
1214
|
+
kind?: string;
|
|
1215
|
+
/** Entity name. Falls back to children when absent. */
|
|
1216
|
+
name?: string;
|
|
1217
|
+
/** Description body (rendered markdown children of the directive). */
|
|
1218
|
+
children?: ReactNode;
|
|
1219
|
+
}
|
|
1220
|
+
declare const EntityCard: react.ForwardRefExoticComponent<EntityCardProps & react.RefAttributes<HTMLElement>>;
|
|
1221
|
+
|
|
1222
|
+
interface KnowledgeSourceResolved {
|
|
1223
|
+
href: string;
|
|
1224
|
+
title?: string;
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Consumer-supplied resolver: path → link data, or `null` when the path cannot
|
|
1228
|
+
* be resolved (stale vault link, missing file, etc.). The card degrades
|
|
1229
|
+
* gracefully — the source renders as a plain label rather than a broken link.
|
|
1230
|
+
*/
|
|
1231
|
+
type KnowledgeSourceResolver = (path: string) => KnowledgeSourceResolved | null;
|
|
1232
|
+
interface KnowledgeCardProps extends HTMLAttributes<HTMLElement> {
|
|
1233
|
+
/**
|
|
1234
|
+
* Comma-separated source paths (e.g. `"notes/a.md, notes/b.md"`).
|
|
1235
|
+
* Each path is handed to `resolve`; unresolved paths render as plain labels.
|
|
1236
|
+
*/
|
|
1237
|
+
sources?: string;
|
|
1238
|
+
/**
|
|
1239
|
+
* Consumer-supplied resolver. `undefined` → all sources render as plain labels
|
|
1240
|
+
* (safe default — never throws, never reads files).
|
|
1241
|
+
*/
|
|
1242
|
+
resolve?: KnowledgeSourceResolver;
|
|
1243
|
+
/** The fact body (rendered markdown children of the directive). */
|
|
1244
|
+
children?: ReactNode;
|
|
1245
|
+
}
|
|
1246
|
+
declare const KnowledgeCard: react.ForwardRefExoticComponent<KnowledgeCardProps & react.RefAttributes<HTMLElement>>;
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* `decisionDirective()` — registers the `:::decision` container renderer.
|
|
1250
|
+
*
|
|
1251
|
+
* Authoring shape:
|
|
1252
|
+
* :::decision{status=accepted date=2026-06-15 alternatives="Redis, SQLite"}
|
|
1253
|
+
* We chose PostgreSQL because it already runs in prod.
|
|
1254
|
+
* :::
|
|
1255
|
+
*/
|
|
1256
|
+
declare function decisionDirective(): MarkdownDirectiveRenderer;
|
|
1257
|
+
/**
|
|
1258
|
+
* `entityDirective()` — registers the `entity` directive for BOTH container
|
|
1259
|
+
* (block card) and inline (chip) syntaxes.
|
|
1260
|
+
*
|
|
1261
|
+
* Authoring shapes:
|
|
1262
|
+
* Container: :::entity{kind=org name="Acme Corp"}
|
|
1263
|
+
* Acme Corp is the primary vendor.
|
|
1264
|
+
* :::
|
|
1265
|
+
* Inline: :entity[Acme Corp]{kind=org}
|
|
1266
|
+
*/
|
|
1267
|
+
declare function entityDirective(): MarkdownDirectiveRenderer;
|
|
1268
|
+
/**
|
|
1269
|
+
* `knowledgeDirective({ resolve })` — registers the `:::knowledge` container
|
|
1270
|
+
* renderer. The `resolve` hook is consumer-supplied; omitting it causes all
|
|
1271
|
+
* sources to render as plain unlinked labels (safe default).
|
|
1272
|
+
*
|
|
1273
|
+
* Authoring shape:
|
|
1274
|
+
* :::knowledge{sources="notes/a.md, notes/b.md"}
|
|
1275
|
+
* PostgreSQL was chosen because …
|
|
1276
|
+
* :::
|
|
1277
|
+
*/
|
|
1278
|
+
declare function knowledgeDirective(options?: {
|
|
1279
|
+
resolve?: KnowledgeSourceResolver;
|
|
1280
|
+
}): MarkdownDirectiveRenderer;
|
|
1281
|
+
interface AiObjectDirectivesOptions {
|
|
1282
|
+
/** Consumer-supplied resolver for `:::knowledge` source paths. */
|
|
1283
|
+
resolveKnowledge?: KnowledgeSourceResolver;
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* `aiObjectDirectives(options)` — returns all three directive renderers as an
|
|
1287
|
+
* array ready to pass to `extensions.directives`:
|
|
1288
|
+
* - `decisionDirective()`
|
|
1289
|
+
* - `entityDirective()`
|
|
1290
|
+
* - `knowledgeDirective({ resolve: options.resolveKnowledge })`
|
|
1291
|
+
*
|
|
1292
|
+
* @example
|
|
1293
|
+
* <MarkdownPreview
|
|
1294
|
+
* extensions={{ directives: aiObjectDirectives({ resolveKnowledge }) }}
|
|
1295
|
+
* />
|
|
1296
|
+
*/
|
|
1297
|
+
declare function aiObjectDirectives(options?: AiObjectDirectivesOptions): MarkdownDirectiveRenderer[];
|
|
1298
|
+
|
|
1299
|
+
interface MathProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
1300
|
+
/** Raw TeX source. */
|
|
1301
|
+
tex: string;
|
|
1302
|
+
}
|
|
1303
|
+
/** Inline math (`$…$`) → KaTeX, in the text flow. */
|
|
1304
|
+
declare function MathInline({ tex, className, ...props }: MathProps): react.JSX.Element;
|
|
1305
|
+
/** Block math (`$$…$$`) → centered display KaTeX. */
|
|
1306
|
+
declare function MathBlock({ tex, className, ...props }: MathProps): react.JSX.Element;
|
|
1307
|
+
|
|
1308
|
+
type FootnoteListProps = HTMLAttributes<HTMLElement>;
|
|
1309
|
+
/**
|
|
1310
|
+
* The branded footnote-definition section. One focal separation gesture — a top
|
|
1311
|
+
* `Separator` (the classic footnote rule) — over a quiet label + the definition
|
|
1312
|
+
* list; no fill, no border box. The label id is per-instance (`useId`) so two
|
|
1313
|
+
* previews on one page don't collide.
|
|
1314
|
+
*/
|
|
1315
|
+
declare const FootnoteList: react.ForwardRefExoticComponent<FootnoteListProps & react.RefAttributes<HTMLElement>>;
|
|
1316
|
+
|
|
1317
|
+
interface TableOfContentsProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
1318
|
+
/** Heading outline; defaults to the outline collected by `MarkdownPreview`. */
|
|
1319
|
+
items?: MarkdownOutlineItem[];
|
|
1320
|
+
/** Section heading label. Default `"Contents"`. */
|
|
1321
|
+
title?: string;
|
|
1322
|
+
/** Deepest heading level to include (1–6). Default 3. */
|
|
1323
|
+
maxLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
1324
|
+
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Quiet generated TOC. Standalone with an explicit `items` array, or fed from the
|
|
1327
|
+
* preview context inside a `::toc` block. Indentation tracks heading depth; no
|
|
1328
|
+
* fill or border — the indent + links are the only gestures.
|
|
1329
|
+
*/
|
|
1330
|
+
declare const TableOfContents: react.ForwardRefExoticComponent<TableOfContentsProps & react.RefAttributes<HTMLElement>>;
|
|
1331
|
+
|
|
1332
|
+
interface IterationTemplateDialogProps {
|
|
1333
|
+
/** Whether the dialog is open. */
|
|
1334
|
+
open: boolean;
|
|
1335
|
+
/** Open-state change handler (Radix Dialog contract). */
|
|
1336
|
+
onOpenChange: (open: boolean) => void;
|
|
1337
|
+
/** The initial template markdown (the directive body). */
|
|
1338
|
+
template: string;
|
|
1339
|
+
/** Called with the edited template when the user saves. */
|
|
1340
|
+
onSave: (template: string) => void;
|
|
1341
|
+
/** Tunes the title + helper copy. Default `"iterate"`. */
|
|
1342
|
+
kind?: "iterate" | "pivot";
|
|
1343
|
+
/** Initial workspace mode. Default `"split"`. */
|
|
1344
|
+
mode?: MarkdownWorkspaceMode;
|
|
1345
|
+
}
|
|
1346
|
+
declare function IterationTemplateDialog({ open, onOpenChange, template, onSave, kind, mode, }: IterationTemplateDialogProps): react.JSX.Element;
|
|
1347
|
+
/**
|
|
1348
|
+
* One-liner wiring for the node-view `⋯` re-edit: provides the
|
|
1349
|
+
* {@link IterationEditContext} handler AND renders the `IterationTemplateDialog`
|
|
1350
|
+
* it opens. Wrap your `MarkdownEditor` / `MarkdownWorkspace` in it to enable the
|
|
1351
|
+
* `⋯` "Edit template…" affordance on `:::iterate` / `:::pivot` node-views.
|
|
1352
|
+
*/
|
|
1353
|
+
declare function IterationTemplateProvider({ children }: {
|
|
1354
|
+
children: ReactNode;
|
|
1355
|
+
}): react.JSX.Element;
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* Iteration BUILDER model (A5) — the data layer behind the guided
|
|
1359
|
+
* `:::iterate` / `:::pivot` authoring dialog.
|
|
1360
|
+
*
|
|
1361
|
+
* The existing `IterationTemplateDialog` only edits the per-cell TEMPLATE. The
|
|
1362
|
+
* guided builder also collects the DATA (the value list(s) + bind name + the
|
|
1363
|
+
* pivot's second axis + layout) and writes a **fully-bound** directive whose
|
|
1364
|
+
* value lists live in its attributes — so the block renders a populated result
|
|
1365
|
+
* with the built-in {@link evaluateEmbedded} (no consumer data engine needed) and
|
|
1366
|
+
* the `⋯` re-edit can reopen it losslessly.
|
|
1367
|
+
*
|
|
1368
|
+
* Pure + React-free so it is unit-testable on its own:
|
|
1369
|
+
* serialize → `:::iterate{as="item" layout="stacked" values="A, B, C"}\n…\n:::`
|
|
1370
|
+
* `:::pivot{layout="matrix" rows="Q1, Q2" cols="N, S"}\n…\n:::`
|
|
1371
|
+
* parse ← the inverse (for the `⋯` reopen)
|
|
1372
|
+
* evaluate → {@link evaluateEmbedded} turns the embedded lists into cells.
|
|
1373
|
+
*
|
|
1374
|
+
* Value lists are comma-separated in the attribute (values containing a literal
|
|
1375
|
+
* comma aren't supported — the dialog enters one value per line and joins them).
|
|
1376
|
+
*/
|
|
1377
|
+
|
|
1378
|
+
/** The dialog's working value — the collected data + template for one directive. */
|
|
1379
|
+
interface IterationBuilderValue {
|
|
1380
|
+
kind: "iterate" | "pivot";
|
|
1381
|
+
/** Loop-variable name (iterate). Default `"item"`. */
|
|
1382
|
+
as: string;
|
|
1383
|
+
layout: IterationLayout;
|
|
1384
|
+
/** iterate: the list of items. pivot: the ROW values. */
|
|
1385
|
+
values: string[];
|
|
1386
|
+
/** pivot: the COLUMN values. */
|
|
1387
|
+
cols?: string[];
|
|
1388
|
+
/** The per-cell markdown template (directive body). */
|
|
1389
|
+
template: string;
|
|
1390
|
+
}
|
|
1391
|
+
/** Default per-cell template per kind (so a fresh block renders something). */
|
|
1392
|
+
declare const DEFAULT_TEMPLATE: Record<"iterate" | "pivot", string>;
|
|
1393
|
+
/** Split a comma-separated attribute into trimmed, non-empty values. */
|
|
1394
|
+
declare function splitList(value: string | undefined): string[];
|
|
1395
|
+
/** Parse a directive attribute string (`a="x" b="y"`) into a record. */
|
|
1396
|
+
declare function parseAttributes(attrString: string): Record<string, string>;
|
|
1397
|
+
/** Build the `{ attributes, template }` for a builder value (the write-back shape). */
|
|
1398
|
+
declare function directivePartsFromValue(value: IterationBuilderValue): {
|
|
1399
|
+
attributes: Record<string, string>;
|
|
1400
|
+
template: string;
|
|
1401
|
+
};
|
|
1402
|
+
/** Serialize a builder value to a fully-bound `:::iterate` / `:::pivot` directive. */
|
|
1403
|
+
declare function serializeIterationDirective(value: IterationBuilderValue): string;
|
|
1404
|
+
/** Build a builder value from a directive's kind + attributes + body template. */
|
|
1405
|
+
declare function builderValueFromParts(kind: "iterate" | "pivot", attributes: Record<string, string>, template: string): IterationBuilderValue;
|
|
1406
|
+
/**
|
|
1407
|
+
* Parse a full `:::iterate` / `:::pivot` directive string into a builder value.
|
|
1408
|
+
*
|
|
1409
|
+
* The fence length is variable (`:{3,}`) and the close is matched by BACKREFERENCE
|
|
1410
|
+
* (`\1`) to the same length as the open, so a directive whose body contains a
|
|
1411
|
+
* nested `:::card` (3 colons) is opened/closed with `::::` (4) and the inner fence
|
|
1412
|
+
* is not mistaken for the outer close. The non-greedy body anchored to end-of-input
|
|
1413
|
+
* keeps the canonical 3-colon form round-tripping unchanged.
|
|
1414
|
+
*/
|
|
1415
|
+
declare function parseIterationDirective(markdown: string): IterationBuilderValue | null;
|
|
1416
|
+
/** An empty builder value for a fresh insert. */
|
|
1417
|
+
declare function emptyBuilderValue(kind: "iterate" | "pivot"): IterationBuilderValue;
|
|
1418
|
+
/**
|
|
1419
|
+
* Built-in iteration evaluator: resolve the value list(s) embedded in the
|
|
1420
|
+
* directive attributes into cells — so a block authored with the guided builder
|
|
1421
|
+
* renders a populated result with no consumer data engine. iterate reads
|
|
1422
|
+
* `values=`; pivot reads `rows=` × `cols=`. Assignable to `EvaluateIteration`
|
|
1423
|
+
* (it never returns null — it degrades to an empty cell list).
|
|
1424
|
+
*/
|
|
1425
|
+
declare function evaluateEmbedded(spec: IterationSpec): IterationData;
|
|
1426
|
+
/**
|
|
1427
|
+
* Swap a pivot's ROW and COLUMN value lists (the node-menu "Transpose" action).
|
|
1428
|
+
* A no-op for `iterate` (it has no second axis) — the menu item hides itself in
|
|
1429
|
+
* that case, but the function stays total (never throws) so a stale/misrouted
|
|
1430
|
+
* call is harmless. `transposeIterationValue(transposeIterationValue(v)) === v`
|
|
1431
|
+
* for any pivot value (a lossless round-trip).
|
|
1432
|
+
*/
|
|
1433
|
+
declare function transposeIterationValue(value: IterationBuilderValue): IterationBuilderValue;
|
|
1434
|
+
/**
|
|
1435
|
+
* Render a builder value's RESOLVED cells as plain, static markdown — the
|
|
1436
|
+
* "Convert to static" node-menu action. Reuses {@link evaluateEmbedded} (the same
|
|
1437
|
+
* resolver the live preview renders through), so the output matches what the
|
|
1438
|
+
* block currently shows, with no ProseMirror/dialog dependency:
|
|
1439
|
+
* - `matrix` (with both header axes present) → a GFM table.
|
|
1440
|
+
* - anything else (`stacked` / `grid` / `bento`) → cells joined as sequential
|
|
1441
|
+
* markdown blocks, separated by a blank line.
|
|
1442
|
+
* An empty result set (no values entered yet) returns an empty string.
|
|
1443
|
+
*/
|
|
1444
|
+
declare function staticMarkdownFromValue(value: IterationBuilderValue, interpolate?: InterpolateTemplate): string;
|
|
1445
|
+
|
|
1446
|
+
interface IterationBuilderDialogProps {
|
|
1447
|
+
open: boolean;
|
|
1448
|
+
onOpenChange: (open: boolean) => void;
|
|
1449
|
+
/** Which block to author. Default `"iterate"`. Ignored when `value` is set. */
|
|
1450
|
+
kind?: "iterate" | "pivot";
|
|
1451
|
+
/** Seed the whole builder (the `⋯` re-edit path). */
|
|
1452
|
+
value?: IterationBuilderValue;
|
|
1453
|
+
/** Seed the value list of a fresh block (e.g. a selection split to lines). */
|
|
1454
|
+
initialValues?: string[];
|
|
1455
|
+
/** Receives the fully-bound directive markdown when the user saves. */
|
|
1456
|
+
onSave: (directiveMarkdown: string) => void;
|
|
1457
|
+
/**
|
|
1458
|
+
* Resolve a ```calc fence to a `CalcSheet` so calc cells COMPUTE in the live
|
|
1459
|
+
* preview (the same hook `MarkdownPreview` takes — the library renders, the app
|
|
1460
|
+
* computes). Without it a calc cell still renders as a code block; with it, the
|
|
1461
|
+
* preview matches production. Pass your app's calc engine.
|
|
1462
|
+
*/
|
|
1463
|
+
evaluate?: EvaluateCalc;
|
|
1464
|
+
/** Fill a cell template with its context. Defaults to `{{path}}` substitution. */
|
|
1465
|
+
interpolate?: InterpolateTemplate;
|
|
1466
|
+
}
|
|
1467
|
+
declare function IterationBuilderDialog({ open, onOpenChange, kind: kindProp, value, initialValues, onSave, evaluate, interpolate, }: IterationBuilderDialogProps): react.JSX.Element;
|
|
1468
|
+
/**
|
|
1469
|
+
* One-liner wiring for the node-view `⋯` re-edit using the GUIDED builder (A5).
|
|
1470
|
+
* Drop it above a `MarkdownEditor` / `MarkdownWorkspace` to make the `⋯` on a
|
|
1471
|
+
* `:::iterate` / `:::pivot` reopen the full builder seeded with the block's DATA
|
|
1472
|
+
* (value lists + bind name + layout) and template, writing both back losslessly.
|
|
1473
|
+
*
|
|
1474
|
+
* Prefer this over {@link IterationTemplateProvider} when the consumer authors
|
|
1475
|
+
* blocks with embedded value lists (the builder flow); the template-only provider
|
|
1476
|
+
* remains for the lighter "edit just the template" affordance.
|
|
1477
|
+
*/
|
|
1478
|
+
declare function IterationBuilderProvider({ children, evaluate, interpolate, }: {
|
|
1479
|
+
children: ReactNode;
|
|
1480
|
+
/** Forwarded to the builder's live preview so calc cells COMPUTE on re-edit. */
|
|
1481
|
+
evaluate?: EvaluateCalc;
|
|
1482
|
+
/** Forwarded to the builder's live preview cell interpolation. */
|
|
1483
|
+
interpolate?: InterpolateTemplate;
|
|
1484
|
+
}): react.JSX.Element;
|
|
1485
|
+
|
|
1486
|
+
export { type AiObjectDirectivesOptions, BRAND_DIRECTIVES, Bibliography, type BibliographyProps, type BrandDirectiveName, type BrandSlashViewOptions, type BuildMarkdownPluginsOptions, CalcBlock, type CalcBlockProps, CalcEditorHooks, type CalcFence, CalcInline, type CalcInlineProps, CalcTokenKind, CalcValue, type CitationData, type CitationStyle, type CiteItem, type CollectedCitations, DECISION_STATUSES, DEFAULT_TEMPLATE, DecisionCard, type DecisionCardProps, type DecisionStatus, DocumentOutline, type DocumentOutlineProps, ENTITY_KINDS, EditorCompletionProvider, EditorContentAccess, EditorSelection, EmbedAssetFn, EntityCard, type EntityCardProps, EntityChip, type EntityChipProps, type EntityKind, EvaluateCalc, type EvaluateIteration, FootnoteList, type FootnoteListProps, type InterpolateTemplate, IterationBlock, type IterationBlockProps, IterationBuilderDialog, type IterationBuilderDialogProps, IterationBuilderProvider, type IterationBuilderValue, type IterationCell, type IterationData, IterationEditHandler, type IterationLayout, type IterationSpec, IterationTemplateDialog, type IterationTemplateDialogProps, IterationTemplateProvider, KnowledgeCard, type KnowledgeCardProps, type KnowledgeSourceResolved, type KnowledgeSourceResolver, MARKDOWN_HEADING_REM, MARKDOWN_HEADING_TRACKING, MARKDOWN_HEADING_WEIGHT, MARKDOWN_MEASURE, type MarkdownAnnotation, type MarkdownAnnotationKind, type MarkdownDirectiveContext, type MarkdownDirectiveKind, type MarkdownDirectiveRenderer, type MarkdownExtensions, type MarkdownFenceContext, type MarkdownFenceRenderer, type MarkdownHeadingInfo, type MarkdownHeadingLevel, type MarkdownOutlineItem, MarkdownPreview, type MarkdownPreviewProps, MarkdownToolbar, type MarkdownToolbarProps, type MarkdownUrlKind, MarkdownWorkspace, type MarkdownWorkspaceHandle, type MarkdownWorkspaceMode, type MarkdownWorkspaceProps, MathBlock, MathInline, type MathProps, MermaidDiagram, type MermaidDiagramProps, MermaidWorkspace, type MermaidWorkspaceProps, MetricBlock, type MetricBlockProps, MonacoSlashMenu, type MonacoSlashMenuProps, type ParsedDocument, type ProseMirrorContentAccessDeps, type ProseMirrorContentAccessOptions, type ResolveCitation, type ResolvedCitation, SlashCommand, SlashMenu, type SlashMenuProps, TableOfContents, type TableOfContentsProps, aiObjectDirectives, annotationForRange, attachCalcMonaco, attachCompletionsMonaco, brandSlashViewPlugins, buildMarkdownPlugins, builderValueFromParts, calcProsePlugins, calcTokenClassName, collectCitations, computeMarkdownAnnotations, decisionCardVariants, decisionDirective, defaultInterpolate, directivePartsFromValue, emptyBuilderValue, entityChipVariants, entityDirective, evaluateEmbedded, findCalcFences, insertDirective, insertHorizontalRule, insertLink, knowledgeDirective, markdownScaleVars, mergeNormalizedEdit, parseAttributes, parseFrontmatter, parseIterationDirective, parseMarkdown, parseMarkdownOutline, proseMirrorContentAccess, remarkBrandDirectives, removedMarkerAt, selectionWatchPlugin, serializeFrontmatter, serializeIterationDirective, shiftAnnotations, specFromDirective, splitList, staticMarkdownFromValue, summarizeAnnotations, toggleLinePrefix, transposeIterationValue, useMarkdownOutline, wrapSelection };
|