@lexical/mdast 0.0.0-bootstrap.0 → 0.47.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/README.md +207 -2
- package/dist/LexicalMdast.dev.js +2620 -0
- package/dist/LexicalMdast.dev.mjs +2594 -0
- package/dist/LexicalMdast.js +11 -0
- package/dist/LexicalMdast.js.flow +228 -0
- package/dist/LexicalMdast.mjs +36 -0
- package/dist/LexicalMdast.node.mjs +34 -0
- package/dist/LexicalMdast.prod.js +11 -0
- package/dist/LexicalMdast.prod.mjs +11 -0
- package/dist/MdastExport.d.ts +20 -0
- package/dist/MdastExportExtension.d.ts +80 -0
- package/dist/MdastExtension.d.ts +21 -0
- package/dist/MdastGfmExtension.d.ts +20 -0
- package/dist/MdastImport.d.ts +48 -0
- package/dist/MdastImportExtension.d.ts +264 -0
- package/dist/MdastShortcuts.d.ts +27 -0
- package/dist/MdastStream.d.ts +70 -0
- package/dist/MdastTableExtension.d.ts +29 -0
- package/dist/compile.d.ts +18 -0
- package/dist/handlers.d.ts +84 -0
- package/dist/index.d.ts +15 -0
- package/dist/state.d.ts +58 -0
- package/dist/types.d.ts +165 -0
- package/dist/typescript-too-old.d.ts +18 -0
- package/package.json +90 -6
- package/src/MdastExport.ts +545 -0
- package/src/MdastExportExtension.ts +122 -0
- package/src/MdastExtension.ts +30 -0
- package/src/MdastGfmExtension.ts +38 -0
- package/src/MdastImport.ts +236 -0
- package/src/MdastImportExtension.ts +635 -0
- package/src/MdastShortcuts.ts +453 -0
- package/src/MdastStream.ts +187 -0
- package/src/MdastTableExtension.ts +144 -0
- package/src/compile.ts +44 -0
- package/src/handlers.ts +648 -0
- package/src/index.ts +69 -0
- package/src/state.ts +124 -0
- package/src/types.ts +197 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { CompiledMdast, MdastNode, MdastParent } from './types';
|
|
9
|
+
import type { ElementNode, LexicalNode } from 'lexical';
|
|
10
|
+
import type { Root } from 'mdast';
|
|
11
|
+
/** A resolved `[identifier]: url "title"` definition. */
|
|
12
|
+
export type ResolvedDefinition = {
|
|
13
|
+
url: string;
|
|
14
|
+
title?: string | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Collects the document's definitions (`[id]: url "title"`) so link/image
|
|
18
|
+
* references can be resolved during the import walk. Identifiers on mdast
|
|
19
|
+
* `definition` nodes are already normalized.
|
|
20
|
+
*/
|
|
21
|
+
export declare function collectDefinitions(tree: Root): Map<string, ResolvedDefinition>;
|
|
22
|
+
/**
|
|
23
|
+
* Builds the recursive importer for a compiled set of transformers. The
|
|
24
|
+
* returned function converts a single mdast node into Lexical nodes, threading
|
|
25
|
+
* the accumulated text-format bitmask through inline marks.
|
|
26
|
+
*
|
|
27
|
+
* Exported so the streaming shortcut engine can reuse the exact same mdast ->
|
|
28
|
+
* Lexical mapping when materializing an inline construct it detected.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createNodeImporter(compiled: CompiledMdast, source?: string, definitions?: ReadonlyMap<string, ResolvedDefinition>): {
|
|
31
|
+
$importChildren: (parent: MdastParent, format: number) => LexicalNode[];
|
|
32
|
+
$importNode: (node: MdastNode, format: number) => LexicalNode[];
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Creates the import entry points for a compiled registry. The `Markdown`
|
|
36
|
+
* variants parse a source string (recovering literal syntax like the list
|
|
37
|
+
* bullet or link style from it); the `Mdast` variants walk a pre-parsed
|
|
38
|
+
* tree, where no source string exists so syntax-preservation is skipped.
|
|
39
|
+
* `$generateNodesFrom*` return an array of detached block-level Lexical
|
|
40
|
+
* nodes without touching the document or the selection; `$import*` replace
|
|
41
|
+
* the contents of the root (or a supplied element) with that result.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createMdastImport(compiled: CompiledMdast): {
|
|
44
|
+
$generateNodesFromMarkdown: (markdown: string) => LexicalNode[];
|
|
45
|
+
$generateNodesFromMdast: (tree: Root) => LexicalNode[];
|
|
46
|
+
$importMarkdown: (markdown: string, node?: ElementNode) => void;
|
|
47
|
+
$importMdast: (tree: Root, node?: ElementNode) => void;
|
|
48
|
+
};
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { CompiledMdast, FromMarkdownExtension, MdastExportRule, MdastImportRule, MicromarkExtension, ToMarkdownExtension } from './types';
|
|
9
|
+
import type { ElementNode, LexicalNode } from 'lexical';
|
|
10
|
+
import type { Root } from 'mdast';
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the core {@link MdastImportExtension} registry. Feature
|
|
13
|
+
* extensions contribute to these arrays via `configExtension(MdastImportExtension,
|
|
14
|
+
* …)`; you rarely need to set them by hand. The shape mirrors
|
|
15
|
+
* `@lexical/html`'s `DOMImportExtension` config: raw contribution arrays that
|
|
16
|
+
* `mergeConfig` concatenates and `build` compiles.
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
19
|
+
export interface MdastConfig {
|
|
20
|
+
/** mdast `type` -> Lexical mapping rules used while importing. */
|
|
21
|
+
readonly importRules: readonly MdastImportRule[];
|
|
22
|
+
/** Lexical `getType()` -> mdast mapping rules used while exporting. */
|
|
23
|
+
readonly exportRules: readonly MdastExportRule[];
|
|
24
|
+
/** micromark syntax extensions (the tokenizer layer). */
|
|
25
|
+
readonly micromarkExtensions: readonly MicromarkExtension[];
|
|
26
|
+
/** `mdast-util-from-markdown` extensions (tokens -> mdast). */
|
|
27
|
+
readonly mdastExtensions: readonly FromMarkdownExtension[];
|
|
28
|
+
/** `mdast-util-to-markdown` extensions (mdast -> Markdown string). */
|
|
29
|
+
readonly toMarkdownExtensions: readonly ToMarkdownExtension[];
|
|
30
|
+
/**
|
|
31
|
+
* mdast inline `type`s that the streaming shortcuts may materialize when
|
|
32
|
+
* their closing delimiter is typed. Extensions that contribute a new inline
|
|
33
|
+
* construct add its type here (with a matching import rule) so shortcuts
|
|
34
|
+
* stay in lock-step with the parser.
|
|
35
|
+
*/
|
|
36
|
+
readonly inlineShortcutTypes: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* Characters that can close an inline construct; typing one triggers an
|
|
39
|
+
* inline re-scan. Extensions add their construct's closing character here
|
|
40
|
+
* (e.g. `'='` for `==highlight==`).
|
|
41
|
+
*/
|
|
42
|
+
readonly inlineShortcutTriggers: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The runtime API exposed by {@link MdastImportExtension}. Obtain it inside a
|
|
46
|
+
* read/update with `$getExtensionOutput(MdastImportExtension)`, or use the
|
|
47
|
+
* {@link $convertFromMarkdownString} shorthand. Serialization lives in
|
|
48
|
+
* `MdastExportExtension` so import-only editors don't bundle the
|
|
49
|
+
* serializer (`mdast-util-to-markdown`).
|
|
50
|
+
* @experimental
|
|
51
|
+
*/
|
|
52
|
+
export interface MdastImportExtensionOutput {
|
|
53
|
+
/**
|
|
54
|
+
* Parses `markdown` with micromark/mdast and replaces the contents of the
|
|
55
|
+
* editor root (or `node`). Must be called inside an `editor.update()`.
|
|
56
|
+
*/
|
|
57
|
+
$convertFromMarkdownString(markdown: string, node?: ElementNode): void;
|
|
58
|
+
/**
|
|
59
|
+
* Imports an already-parsed mdast `Root` tree (e.g. produced or
|
|
60
|
+
* transformed by unified/remark tooling) and replaces the contents of the
|
|
61
|
+
* editor root (or `node`). Must be called inside an `editor.update()`.
|
|
62
|
+
* Source-based syntax preservation does not apply (there is no source
|
|
63
|
+
* text to recover literal markers from).
|
|
64
|
+
*/
|
|
65
|
+
$convertFromMdast(tree: Root, node?: ElementNode): void;
|
|
66
|
+
/**
|
|
67
|
+
* Parses `markdown` and returns the resulting block-level nodes as a
|
|
68
|
+
* detached array, without modifying the document or the selection — e.g.
|
|
69
|
+
* for insertion at an arbitrary position via `selection.insertNodes()`.
|
|
70
|
+
* Must be called inside an `editor.update()`.
|
|
71
|
+
*/
|
|
72
|
+
$generateNodesFromMarkdownString(markdown: string): LexicalNode[];
|
|
73
|
+
/**
|
|
74
|
+
* Walks an already-parsed mdast `Root` tree and returns the resulting
|
|
75
|
+
* block-level nodes as a detached array, without modifying the document
|
|
76
|
+
* or the selection. Must be called inside an `editor.update()`. As with
|
|
77
|
+
* {@link MdastImportExtensionOutput.$convertFromMdast}, source-based
|
|
78
|
+
* syntax preservation does not apply.
|
|
79
|
+
*/
|
|
80
|
+
$generateNodesFromMdast(tree: Root): LexicalNode[];
|
|
81
|
+
/**
|
|
82
|
+
* The compiled registry assembled from every contributing extension.
|
|
83
|
+
*
|
|
84
|
+
* @internal consumed by {@link MdastShortcutsExtension}.
|
|
85
|
+
*/
|
|
86
|
+
readonly registry: CompiledMdast;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The core Markdown registry for `@lexical/mdast`, modeled on
|
|
90
|
+
* `@lexical/html`'s `DOMImportExtension`. It assembles the import/export rules
|
|
91
|
+
* and micromark/mdast extensions contributed by feature extensions into a
|
|
92
|
+
* compiled registry, and exposes Markdown import through its
|
|
93
|
+
* {@link MdastImportExtensionOutput}. Markdown export is provided separately by
|
|
94
|
+
* `MdastExportExtension`, so editors that never serialize back to Markdown
|
|
95
|
+
* don't bundle the serializer.
|
|
96
|
+
*
|
|
97
|
+
* You normally do not depend on this directly — depend on a feature extension
|
|
98
|
+
* (e.g. {@link MdastCommonMarkExtension}) which contributes its rules here and
|
|
99
|
+
* ships the nodes those rules need.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import {$convertFromMarkdownString, MdastCommonMarkExtension}
|
|
104
|
+
* from '@lexical/mdast';
|
|
105
|
+
* import {buildEditorFromExtensions} from '@lexical/extension';
|
|
106
|
+
* import {defineExtension} from 'lexical';
|
|
107
|
+
*
|
|
108
|
+
* const editor = buildEditorFromExtensions(
|
|
109
|
+
* defineExtension({dependencies: [MdastCommonMarkExtension], name: '[root]'}),
|
|
110
|
+
* );
|
|
111
|
+
* editor.update(() => $convertFromMarkdownString('# Hi'));
|
|
112
|
+
* ```
|
|
113
|
+
* @experimental
|
|
114
|
+
*/
|
|
115
|
+
export declare const MdastImportExtension: import("lexical").LexicalExtension<MdastConfig, "@lexical/mdast/Import", MdastImportExtensionOutput, void>;
|
|
116
|
+
/**
|
|
117
|
+
* ATX (`# …`) and setext headings, shipping {@link HeadingNode}.
|
|
118
|
+
* @experimental
|
|
119
|
+
*/
|
|
120
|
+
export declare const MdastHeadingExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Heading", unknown, unknown>;
|
|
121
|
+
/**
|
|
122
|
+
* Block quotes (`> …`), shipping {@link QuoteNode}. For blockquotes that hold
|
|
123
|
+
* block-level children (nested lists, code, quotes) with full fidelity, add
|
|
124
|
+
* {@link MdastShadowRootQuoteExtension}.
|
|
125
|
+
* @experimental
|
|
126
|
+
*/
|
|
127
|
+
export declare const MdastBlockquoteExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Blockquote", unknown, unknown>;
|
|
128
|
+
/**
|
|
129
|
+
* Convenience bundle of {@link MdastHeadingExtension} and
|
|
130
|
+
* {@link MdastBlockquoteExtension} — the constructs backed by
|
|
131
|
+
* `@lexical/rich-text` nodes.
|
|
132
|
+
* @experimental
|
|
133
|
+
*/
|
|
134
|
+
export declare const MdastRichTextExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/RichText", unknown, unknown>;
|
|
135
|
+
/**
|
|
136
|
+
* Ordered and unordered lists, shipping {@link ListNode} and
|
|
137
|
+
* {@link ListItemNode}. For GFM task lists (`- [x] …`) add
|
|
138
|
+
* {@link MdastTaskListExtension}.
|
|
139
|
+
* @experimental
|
|
140
|
+
*/
|
|
141
|
+
export declare const MdastListExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/List", unknown, unknown>;
|
|
142
|
+
/**
|
|
143
|
+
* Opt-in: GFM task lists (`- [x] done`), layered on
|
|
144
|
+
* {@link MdastListExtension}. Contributes the `gfmTaskListItem` grammar; the
|
|
145
|
+
* list import/export handlers already understand `checked`, and the typing
|
|
146
|
+
* shortcut (`[ ] ` / `[x] ` in a list item) is enabled by the grammar's
|
|
147
|
+
* presence in the registry.
|
|
148
|
+
* @experimental
|
|
149
|
+
*/
|
|
150
|
+
export declare const MdastTaskListExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/TaskList", unknown, unknown>;
|
|
151
|
+
/**
|
|
152
|
+
* Fenced and indented code blocks, shipping {@link CodeNode}.
|
|
153
|
+
* @experimental
|
|
154
|
+
*/
|
|
155
|
+
export declare const MdastCodeExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Code", unknown, unknown>;
|
|
156
|
+
/**
|
|
157
|
+
* Inline links, CommonMark autolinks (`<https://…>`), and CommonMark
|
|
158
|
+
* reference links (`[text][id]` resolved against `[id]: url` definitions),
|
|
159
|
+
* shipping {@link LinkNode}. Reference links are resolved to their target on
|
|
160
|
+
* import and serialize back as inline links. For GFM *literal* autolinks
|
|
161
|
+
* (bare `https://…` in prose) add {@link MdastAutolinkLiteralExtension}.
|
|
162
|
+
* @experimental
|
|
163
|
+
*/
|
|
164
|
+
export declare const MdastLinkExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Link", unknown, unknown>;
|
|
165
|
+
/**
|
|
166
|
+
* Opt-in: GFM literal autolinks — bare `https://…` / `www.…` URLs and email
|
|
167
|
+
* addresses in prose become links, the way GitHub renders them. This is a GFM
|
|
168
|
+
* extension rather than CommonMark, so it is not part of
|
|
169
|
+
* {@link MdastCommonMarkExtension}; add it alongside to opt in:
|
|
170
|
+
* ```ts
|
|
171
|
+
* dependencies: [MdastCommonMarkExtension, MdastAutolinkLiteralExtension]
|
|
172
|
+
* ```
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
export declare const MdastAutolinkLiteralExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/AutolinkLiteral", unknown, unknown>;
|
|
176
|
+
/**
|
|
177
|
+
* Opt-in: import Markdown blockquotes as *shadow root* {@link QuoteNode}s
|
|
178
|
+
* (`$createQuoteNode({shadowRoot: true})`), which hold block-level children
|
|
179
|
+
* like a table cell. Structured blockquotes — multiple paragraphs, nested
|
|
180
|
+
* lists, code blocks, nested quotes — then round-trip with full fidelity
|
|
181
|
+
* instead of being reassembled from inline content.
|
|
182
|
+
*
|
|
183
|
+
* Not part of {@link MdastCommonMarkExtension}; add it alongside to opt in:
|
|
184
|
+
* ```ts
|
|
185
|
+
* dependencies: [MdastCommonMarkExtension, MdastShadowRootQuoteExtension]
|
|
186
|
+
* ```
|
|
187
|
+
* The quote *export* handler supports both forms per node, so legacy quotes
|
|
188
|
+
* (e.g. created by the `> ` shortcut) and shadow root quotes can coexist.
|
|
189
|
+
* @experimental
|
|
190
|
+
*/
|
|
191
|
+
export declare const MdastShadowRootQuoteExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/ShadowRootQuote", unknown, unknown>;
|
|
192
|
+
/**
|
|
193
|
+
* Thematic breaks (`---`, `***`, `___`), mapped to
|
|
194
|
+
* {@link HorizontalRuleExtension}'s `HorizontalRuleNode`. The original marker
|
|
195
|
+
* character is preserved on round-trip.
|
|
196
|
+
* @experimental
|
|
197
|
+
*/
|
|
198
|
+
export declare const MdastHorizontalRuleExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/HorizontalRule", unknown, unknown>;
|
|
199
|
+
/**
|
|
200
|
+
* GFM `~~strikethrough~~`, mapped to the Lexical `strikethrough` text format.
|
|
201
|
+
* Needs no extra nodes (the core text handlers carry the format bit).
|
|
202
|
+
* @experimental
|
|
203
|
+
*/
|
|
204
|
+
export declare const MdastStrikethroughExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Strikethrough", unknown, unknown>;
|
|
205
|
+
/**
|
|
206
|
+
* Convenience bundle of every CommonMark construct: headings, block quotes,
|
|
207
|
+
* lists, code blocks, links, and thematic breaks. GFM features
|
|
208
|
+
* (strikethrough, task lists, literal autolinks, tables) are bundled
|
|
209
|
+
* separately as `MdastGfmExtension`, and `MdastExportExtension` (or the
|
|
210
|
+
* `MdastExtension` bundle) adds serialization back to Markdown.
|
|
211
|
+
* @experimental
|
|
212
|
+
*/
|
|
213
|
+
export declare const MdastCommonMarkExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/CommonMark", unknown, unknown>;
|
|
214
|
+
export interface MdastShortcutsConfig {
|
|
215
|
+
/** Disable the streaming shortcuts without removing the extension. */
|
|
216
|
+
disabled: boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Streaming Markdown shortcuts (block markers convert on space, fenced code on
|
|
220
|
+
* Enter, inline constructs on their closing delimiter). Each keystroke is fed
|
|
221
|
+
* back through micromark, so shortcut recognition uses the same grammar and
|
|
222
|
+
* the same enabled extensions as import: shortcuts exist for exactly the
|
|
223
|
+
* feature extensions in the editor and no others. Combine with
|
|
224
|
+
* {@link MdastCommonMarkExtension} (and `MdastGfmExtension`) — this extension
|
|
225
|
+
* only wires up the behavior, it does not pull in any grammar of its own.
|
|
226
|
+
* @experimental
|
|
227
|
+
*/
|
|
228
|
+
export declare const MdastShortcutsExtension: import("lexical").LexicalExtension<MdastShortcutsConfig, "@lexical/mdast/Shortcuts", import("@lexical/extension").NamedSignalsOutput<MdastShortcutsConfig>, unknown>;
|
|
229
|
+
/**
|
|
230
|
+
* Shorthand for `$getExtensionOutput(MdastImportExtension).$convertFromMarkdownString`.
|
|
231
|
+
* Must be called inside an `editor.update()`. Throws if the editor was not
|
|
232
|
+
* built with {@link MdastImportExtension} (or an extension that depends on it).
|
|
233
|
+
* @experimental
|
|
234
|
+
*/
|
|
235
|
+
export declare function $convertFromMarkdownString(markdown: string, node?: ElementNode): void;
|
|
236
|
+
/**
|
|
237
|
+
* Shorthand for `$getExtensionOutput(MdastImportExtension).$convertFromMdast`.
|
|
238
|
+
* Must be called inside an `editor.update()`. Throws if the editor was not
|
|
239
|
+
* built with {@link MdastImportExtension} (or an extension that depends on
|
|
240
|
+
* it).
|
|
241
|
+
* @experimental
|
|
242
|
+
*/
|
|
243
|
+
export declare function $convertFromMdast(tree: Root, node?: ElementNode): void;
|
|
244
|
+
/**
|
|
245
|
+
* Shorthand for
|
|
246
|
+
* `$getExtensionOutput(MdastImportExtension).$generateNodesFromMarkdownString`.
|
|
247
|
+
* Parses `markdown` and returns the resulting block-level nodes as a
|
|
248
|
+
* detached array, without modifying the document or the selection. Must be
|
|
249
|
+
* called inside an `editor.update()`. Throws if the editor was not built
|
|
250
|
+
* with {@link MdastImportExtension} (or an extension that depends on it).
|
|
251
|
+
* @experimental
|
|
252
|
+
*/
|
|
253
|
+
export declare function $generateNodesFromMarkdownString(markdown: string): LexicalNode[];
|
|
254
|
+
/**
|
|
255
|
+
* Shorthand for
|
|
256
|
+
* `$getExtensionOutput(MdastImportExtension).$generateNodesFromMdast`.
|
|
257
|
+
* Walks an already-parsed mdast `Root` tree and returns the resulting
|
|
258
|
+
* block-level nodes as a detached array, without modifying the document or
|
|
259
|
+
* the selection. Must be called inside an `editor.update()`. Throws if the
|
|
260
|
+
* editor was not built with {@link MdastImportExtension} (or an extension
|
|
261
|
+
* that depends on it).
|
|
262
|
+
* @experimental
|
|
263
|
+
*/
|
|
264
|
+
export declare function $generateNodesFromMdast(tree: Root): LexicalNode[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { CompiledMdast } from './types';
|
|
9
|
+
import type { LexicalEditor } from 'lexical';
|
|
10
|
+
/**
|
|
11
|
+
* Registers streaming Markdown shortcuts on `editor` from the
|
|
12
|
+
* {@link CompiledMdast} registry. As the user types, the current line/inline
|
|
13
|
+
* buffer is fed back through micromark (the same parser as full-document
|
|
14
|
+
* import) and recognized constructs are transformed in place:
|
|
15
|
+
*
|
|
16
|
+
* - Block markers (`# `, `> `, `- `, `1. `, `- [ ] `) convert the paragraph
|
|
17
|
+
* into the matching Lexical block as soon as the trailing space is typed.
|
|
18
|
+
* - A marker-only line (`` ```lang ``, `## `, `- `) converts on
|
|
19
|
+
* <kbd>Enter</kbd>.
|
|
20
|
+
* - Inline constructs (`*em*`, `**strong**`, `` `code` ``, `~~del~~`,
|
|
21
|
+
* `[text](url)`, plus registered `inlineShortcutTypes`) convert when their
|
|
22
|
+
* closing delimiter is typed.
|
|
23
|
+
*
|
|
24
|
+
* Wired up by {@link MdastShortcutsExtension}; this is an internal helper, not
|
|
25
|
+
* part of the package's public API.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerMarkdownShortcuts(editor: LexicalEditor, compiled: CompiledMdast): () => void;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { CompiledMdast, MdastNode } from './types';
|
|
9
|
+
import type { LexicalNode } from 'lexical';
|
|
10
|
+
import type { Blockquote, Code, Heading, List, PhrasingContent } from 'mdast';
|
|
11
|
+
export type MdastBlockMatch = {
|
|
12
|
+
kind: 'heading';
|
|
13
|
+
node: Heading;
|
|
14
|
+
markerLength: number;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'blockquote';
|
|
17
|
+
node: Blockquote;
|
|
18
|
+
markerLength: number;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'list';
|
|
21
|
+
node: List;
|
|
22
|
+
markerLength: number;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'code';
|
|
25
|
+
node: Code;
|
|
26
|
+
markerLength: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* `MarkdownStreamScanner` is the streaming heart of the shortcut engine. Each
|
|
30
|
+
* keystroke feeds the growing line/inline buffer back through micromark (via
|
|
31
|
+
* `mdast-util-from-markdown`), so shortcut recognition uses the *exact* same
|
|
32
|
+
* grammar — and the same enabled extensions — as full-document import. There
|
|
33
|
+
* is no second, divergent set of regular expressions to keep in sync.
|
|
34
|
+
*
|
|
35
|
+
* It is constructed from the {@link CompiledMdast} registry assembled by
|
|
36
|
+
* {@link MdastImportExtension}, so it stays in lock-step with whatever feature
|
|
37
|
+
* extensions are enabled — including the inline construct types and trigger
|
|
38
|
+
* characters contributed via `inlineShortcutTypes` / `inlineShortcutTriggers`.
|
|
39
|
+
*/
|
|
40
|
+
export declare class MarkdownStreamScanner {
|
|
41
|
+
private readonly compiled;
|
|
42
|
+
private readonly importNode;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the registry's grammar recognizes GFM task-list items (i.e.
|
|
45
|
+
* `MdastTaskListExtension` contributed `gfmTaskListItem`). Probed by
|
|
46
|
+
* parsing rather than configured, so it can never drift from the grammar.
|
|
47
|
+
*/
|
|
48
|
+
readonly supportsTaskListItems: boolean;
|
|
49
|
+
constructor(compiled: CompiledMdast);
|
|
50
|
+
/** Characters that can close an inline construct for this registry. */
|
|
51
|
+
get inlineTriggers(): ReadonlySet<string>;
|
|
52
|
+
private parse;
|
|
53
|
+
/**
|
|
54
|
+
* Materializes an mdast inline node into Lexical nodes using the same
|
|
55
|
+
* import handlers as the full-document importer.
|
|
56
|
+
*/
|
|
57
|
+
importInline(node: MdastNode): LexicalNode[];
|
|
58
|
+
/**
|
|
59
|
+
* Recognizes a block-level construct at the start of `line`. Returns the
|
|
60
|
+
* matched construct together with the marker length, or `null`.
|
|
61
|
+
*/
|
|
62
|
+
scanBlock(line: string): MdastBlockMatch | null;
|
|
63
|
+
/**
|
|
64
|
+
* Recognizes an inline construct (emphasis, strong, strikethrough, inline
|
|
65
|
+
* code, link, plus any registered `inlineShortcutTypes`) whose closing
|
|
66
|
+
* delimiter falls exactly at the end of `value` (the text up to the caret).
|
|
67
|
+
* Returns the mdast node, or `null`.
|
|
68
|
+
*/
|
|
69
|
+
scanInline(value: string): PhrasingContent | null;
|
|
70
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* GFM tables, mapped to `@lexical/table` nodes. Opt-in (not part of
|
|
10
|
+
* {@link MdastCommonMarkExtension}) because it pulls in the `@lexical/table`
|
|
11
|
+
* nodes it ships. The first table row is treated as the header row in both
|
|
12
|
+
* directions.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import {MdastShortcutsExtension, MdastTableExtension} from '@lexical/mdast';
|
|
17
|
+
* import {buildEditorFromExtensions} from '@lexical/extension';
|
|
18
|
+
* import {defineExtension} from 'lexical';
|
|
19
|
+
*
|
|
20
|
+
* const editor = buildEditorFromExtensions(
|
|
21
|
+
* defineExtension({
|
|
22
|
+
* dependencies: [MdastShortcutsExtension, MdastTableExtension],
|
|
23
|
+
* name: '[root]',
|
|
24
|
+
* }),
|
|
25
|
+
* );
|
|
26
|
+
* ```
|
|
27
|
+
* @experimental
|
|
28
|
+
*/
|
|
29
|
+
export declare const MdastTableExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/mdast/Table", unknown, unknown>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { MdastConfig } from './MdastImportExtension';
|
|
9
|
+
import type { CompiledMdast } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Compiles the raw contribution arrays held in {@link MdastConfig} into the
|
|
12
|
+
* indexed registry used at runtime. Rules earlier in the arrays win for a
|
|
13
|
+
* given node `type`; since {@link MdastImportExtension}'s `mergeConfig` prepends the
|
|
14
|
+
* rules contributed by extensions merged later (closer to the editor root),
|
|
15
|
+
* those higher-priority rules take precedence — mirroring the dispatch order
|
|
16
|
+
* of `@lexical/html`'s `DOMImportExtension`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function compileMdast(config: MdastConfig): CompiledMdast;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { MdastExportHandler, MdastImportContext, MdastImportHandler, MdastParent } from './types';
|
|
9
|
+
import type { ListType } from '@lexical/list';
|
|
10
|
+
import type { ElementNode, LexicalNode } from 'lexical';
|
|
11
|
+
import type { Blockquote, Break, Code, Delete, Emphasis, Heading, Html, InlineCode, Link, LinkReference, List, ListItem, Paragraph, PhrasingContent, Strong, Text as MdastText } from 'mdast';
|
|
12
|
+
/**
|
|
13
|
+
* Appends `nodes` to `element` via {@link ElementNode.splice} (the primitive
|
|
14
|
+
* `append` delegates to, taking an array directly), returning the element.
|
|
15
|
+
*/
|
|
16
|
+
export declare function $append<T extends ElementNode>(element: T, nodes: LexicalNode[]): T;
|
|
17
|
+
/**
|
|
18
|
+
* Prepends `nodes` to `element` via {@link ElementNode.splice} (the primitive
|
|
19
|
+
* `append` delegates to, taking an array directly), returning the element.
|
|
20
|
+
*/
|
|
21
|
+
export declare function $prepend<T extends ElementNode>(element: T, nodes: LexicalNode[]): T;
|
|
22
|
+
/**
|
|
23
|
+
* Whether `node` is a block-level node: a non-inline element *or* a non-inline
|
|
24
|
+
* decorator (e.g. a horizontal rule).
|
|
25
|
+
*/
|
|
26
|
+
export declare function $isBlockLevelNode(node: LexicalNode): boolean;
|
|
27
|
+
export declare const TEXT_FORMAT_MASK: number;
|
|
28
|
+
export declare const $importParagraph: MdastImportHandler<Paragraph>;
|
|
29
|
+
export declare const $importHeading: MdastImportHandler<Heading>;
|
|
30
|
+
export declare const $importBlockquote: MdastImportHandler<Blockquote>;
|
|
31
|
+
/**
|
|
32
|
+
* Imports each mdast flow child of `parent` as block-level Lexical nodes,
|
|
33
|
+
* wrapping any stray inline output (e.g. from the `html` fallback) in a
|
|
34
|
+
* paragraph — the same normalization the top-level importer applies.
|
|
35
|
+
*/
|
|
36
|
+
export declare function $importBlockChildren(parent: MdastParent, ctx: MdastImportContext): LexicalNode[];
|
|
37
|
+
/**
|
|
38
|
+
* Opt-in replacement for {@link $importBlockquote} that imports the quote as a
|
|
39
|
+
* shadow root {@link QuoteNode} holding block-level children, so structured
|
|
40
|
+
* blockquotes (multiple paragraphs, nested lists, code) round-trip without
|
|
41
|
+
* being flattened to inline content. See `MdastShadowRootQuoteExtension`.
|
|
42
|
+
*/
|
|
43
|
+
export declare const $importShadowRootBlockquote: MdastImportHandler<Blockquote>;
|
|
44
|
+
/** Maps an mdast `list` node to the Lexical {@link ListType} it represents. */
|
|
45
|
+
export declare function $listTypeFromMdast(node: List): ListType;
|
|
46
|
+
export declare const $importList: MdastImportHandler<List>;
|
|
47
|
+
export declare const $importListItem: MdastImportHandler<ListItem>;
|
|
48
|
+
export declare const $importCode: MdastImportHandler<Code>;
|
|
49
|
+
export declare const importText: MdastImportHandler<MdastText>;
|
|
50
|
+
export declare const importHtml: MdastImportHandler<Html>;
|
|
51
|
+
export declare const importInlineCode: MdastImportHandler<InlineCode>;
|
|
52
|
+
export declare const $importEmphasis: MdastImportHandler<Emphasis | Strong>;
|
|
53
|
+
export declare const $importStrong: MdastImportHandler<Emphasis | Strong>;
|
|
54
|
+
export declare const importDelete: MdastImportHandler<Delete>;
|
|
55
|
+
export declare const $importBreak: MdastImportHandler<Break>;
|
|
56
|
+
export declare const $importLink: MdastImportHandler<Link>;
|
|
57
|
+
/**
|
|
58
|
+
* CommonMark reference links (`[text][id]`, `[id][]`, `[id]`) resolve against
|
|
59
|
+
* the document's definitions. An unresolved reference is literal text per the
|
|
60
|
+
* spec, so it is re-emitted verbatim.
|
|
61
|
+
*/
|
|
62
|
+
export declare const $importLinkReference: MdastImportHandler<LinkReference>;
|
|
63
|
+
/**
|
|
64
|
+
* Definitions (`[id]: url "title"`) are consumed by {@link collectDefinitions}
|
|
65
|
+
* before the walk; the node itself produces no content.
|
|
66
|
+
*/
|
|
67
|
+
export declare const importDefinition: MdastImportHandler;
|
|
68
|
+
export declare const exportParagraph: MdastExportHandler;
|
|
69
|
+
export declare const $exportHeading: MdastExportHandler;
|
|
70
|
+
export declare const exportQuote: MdastExportHandler;
|
|
71
|
+
export declare const $exportCode: MdastExportHandler;
|
|
72
|
+
export declare const $exportLink: MdastExportHandler;
|
|
73
|
+
export declare const $exportList: MdastExportHandler;
|
|
74
|
+
/**
|
|
75
|
+
* Wraps a plain string in the mdast phrasing nodes implied by a Lexical text
|
|
76
|
+
* format bitmask (code span innermost, then emphasis, strong, strikethrough).
|
|
77
|
+
* The emphasis/strong *delimiter* (`*` vs `_`) is a document-level to-markdown
|
|
78
|
+
* option (see the exporter) rather than per-node, because mixing delimiters in
|
|
79
|
+
* one document desyncs to-markdown's character escaping.
|
|
80
|
+
*/
|
|
81
|
+
export declare function phrasingFromFormattedText(value: string, format: number): PhrasingContent;
|
|
82
|
+
export declare const exportText: (node: LexicalNode) => PhrasingContent | null;
|
|
83
|
+
export declare const $exportLineBreak: (node: LexicalNode) => Break | null;
|
|
84
|
+
export declare const exportTab: (node: LexicalNode) => MdastText | null;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
export type { MdastExportExtensionOutput } from './MdastExportExtension';
|
|
9
|
+
export { $convertSelectionToMarkdownString, $convertToMarkdownString, $convertToMdast, MdastExportExtension, } from './MdastExportExtension';
|
|
10
|
+
export { MdastExtension } from './MdastExtension';
|
|
11
|
+
export { MdastGfmExtension } from './MdastGfmExtension';
|
|
12
|
+
export type { MdastConfig, MdastImportExtensionOutput, MdastShortcutsConfig, } from './MdastImportExtension';
|
|
13
|
+
export { $convertFromMarkdownString, $convertFromMdast, $generateNodesFromMarkdownString, $generateNodesFromMdast, MdastAutolinkLiteralExtension, MdastBlockquoteExtension, MdastCodeExtension, MdastCommonMarkExtension, MdastHeadingExtension, MdastHorizontalRuleExtension, MdastImportExtension, MdastLinkExtension, MdastListExtension, MdastRichTextExtension, MdastShadowRootQuoteExtension, MdastShortcutsExtension, MdastStrikethroughExtension, MdastTaskListExtension, } from './MdastImportExtension';
|
|
14
|
+
export { MdastTableExtension } from './MdastTableExtension';
|
|
15
|
+
export type { CompiledMdast, MdastExportContext, MdastExportHandler, MdastExportRule, MdastImportContext, MdastImportHandler, MdastImportRule, MdastNode, MdastParent, } from './types';
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Per-node state used to round-trip the *exact* Markdown syntax a construct was
|
|
10
|
+
* parsed from, so re-serializing produces minimally different output. This is
|
|
11
|
+
* the same technique `@lexical/markdown` uses; the state lives on the Lexical
|
|
12
|
+
* nodes (and therefore survives serialization), and the exporter reads it to
|
|
13
|
+
* reproduce the original marker/fence/break.
|
|
14
|
+
*
|
|
15
|
+
* All of these default to the empty sentinel (`''` / `false`) meaning
|
|
16
|
+
* "unknown" — i.e. the node was not created by a Markdown import. The exporter
|
|
17
|
+
* only pins a node's syntax when the marker is known, so nodes created in the
|
|
18
|
+
* editor defer to the document-level serialization options.
|
|
19
|
+
*/
|
|
20
|
+
/** The bullet character (`-`, `*`, `+`) an unordered/check `ListNode` used. */
|
|
21
|
+
export declare const listMarkerState: import("lexical").StateConfig<"mdastListMarker", "" | "*" | "+" | "-">;
|
|
22
|
+
/** The delimiter (`.` or `)`) an ordered `ListNode` used. */
|
|
23
|
+
export declare const orderedMarkerState: import("lexical").StateConfig<"mdastOrderedMarker", "" | ")" | ".">;
|
|
24
|
+
/** The marker (`_`) an italic run used when it was not the default `*`. */
|
|
25
|
+
export declare const emphasisMarkerState: import("lexical").StateConfig<"mdastEmphasisMarker", string>;
|
|
26
|
+
/** The marker (`_`) a bold run used when it was not the default `*`. */
|
|
27
|
+
export declare const strongMarkerState: import("lexical").StateConfig<"mdastStrongMarker", string>;
|
|
28
|
+
/** Whether a (level 1/2) `HeadingNode` was written in setext style. */
|
|
29
|
+
export declare const setextState: import("lexical").StateConfig<"mdastSetext", boolean>;
|
|
30
|
+
/** The fence a `CodeNode` used (e.g. ```` ``` ````, ````` ```` `````, `~~~`). */
|
|
31
|
+
export declare const codeFenceState: import("lexical").StateConfig<"mdastCodeFence", string>;
|
|
32
|
+
/**
|
|
33
|
+
* The info-string tail after a `CodeNode`'s language (e.g. `title=x` in
|
|
34
|
+
* ```` ```js title=x ````). `CodeNode` itself only models the language;
|
|
35
|
+
* this keeps the rest of the info string so it survives the round-trip.
|
|
36
|
+
*/
|
|
37
|
+
export declare const codeMetaState: import("lexical").StateConfig<"mdastCodeMeta", string>;
|
|
38
|
+
/**
|
|
39
|
+
* The hard-line-break marker a `LineBreakNode` used (`\` or trailing spaces).
|
|
40
|
+
* The empty sentinel means the break is *soft* (a source newline or an
|
|
41
|
+
* editor-created line break) and serializes as a plain newline.
|
|
42
|
+
*/
|
|
43
|
+
export declare const hardLineBreakState: import("lexical").StateConfig<"mdastHardLineBreak", string>;
|
|
44
|
+
/**
|
|
45
|
+
* Marks a `LineBreakNode` that stands for a *paragraph boundary* inside a
|
|
46
|
+
* container whose Lexical children are inline (blockquote, list item). Set by
|
|
47
|
+
* the import handlers when they join sibling mdast paragraphs; the exporter
|
|
48
|
+
* splits on it to reconstruct the paragraphs.
|
|
49
|
+
*/
|
|
50
|
+
export declare const paragraphBreakState: import("lexical").StateConfig<"mdastParagraphBreak", boolean>;
|
|
51
|
+
/** The marker (`-`, `*`, `_`) a thematic break / `HorizontalRuleNode` used. */
|
|
52
|
+
export declare const hrMarkerState: import("lexical").StateConfig<"mdastHrMarker", string>;
|
|
53
|
+
/**
|
|
54
|
+
* The syntax a `LinkNode` was written in: `'inline'` (`[text](url)`),
|
|
55
|
+
* `'autolink'` (`<url>`), or `'literal'` (a bare GFM autolink literal,
|
|
56
|
+
* `https://…` in prose).
|
|
57
|
+
*/
|
|
58
|
+
export declare const linkStyleState: import("lexical").StateConfig<"mdastLinkStyle", "" | "inline" | "autolink" | "literal">;
|