@haklex/rich-headless 0.0.11 → 0.0.13
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -1
- package/dist/transformers.d.ts +26 -0
- package/dist/transformers.d.ts.map +1 -0
- package/dist/transformers.mjs +349 -0
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -93,4 +93,5 @@ export declare class GridContainerNode extends DecoratorNode<null> {
|
|
|
93
93
|
}
|
|
94
94
|
export declare const customHeadlessNodes: Klass<LexicalNode>[];
|
|
95
95
|
export declare const allHeadlessNodes: Klass<LexicalNode>[];
|
|
96
|
+
export { $toMarkdown, allHeadlessTransformers } from './transformers';
|
|
96
97
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EACL,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,8 @@ import { LinkNode, AutoLinkNode } from "@lexical/link";
|
|
|
4
4
|
import { ListNode, ListItemNode } from "@lexical/list";
|
|
5
5
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
6
6
|
import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
|
|
7
|
-
import {
|
|
7
|
+
import { DecoratorNode, ElementNode } from "lexical";
|
|
8
|
+
import { $toMarkdown, allHeadlessTransformers } from "./transformers.mjs";
|
|
8
9
|
const builtinNodes = [
|
|
9
10
|
HeadingNode,
|
|
10
11
|
QuoteNode,
|
|
@@ -378,6 +379,7 @@ const allHeadlessNodes = [
|
|
|
378
379
|
...customHeadlessNodes
|
|
379
380
|
];
|
|
380
381
|
export {
|
|
382
|
+
$toMarkdown,
|
|
381
383
|
AlertQuoteNode,
|
|
382
384
|
BannerNode,
|
|
383
385
|
CodeBlockNode,
|
|
@@ -398,6 +400,7 @@ export {
|
|
|
398
400
|
TldrawNode,
|
|
399
401
|
VideoNode,
|
|
400
402
|
allHeadlessNodes,
|
|
403
|
+
allHeadlessTransformers,
|
|
401
404
|
builtinNodes,
|
|
402
405
|
customHeadlessNodes
|
|
403
406
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ElementTransformer, TextFormatTransformer, TextMatchTransformer } from '@lexical/markdown';
|
|
2
|
+
export declare const SPOILER_TRANSFORMER: TextMatchTransformer;
|
|
3
|
+
export declare const MENTION_TRANSFORMER: TextMatchTransformer;
|
|
4
|
+
export declare const FOOTNOTE_TRANSFORMER: TextMatchTransformer;
|
|
5
|
+
export declare const KATEX_INLINE_TRANSFORMER: TextMatchTransformer;
|
|
6
|
+
export declare const INSERT_TRANSFORMER: TextFormatTransformer;
|
|
7
|
+
export declare const FOOTNOTE_SECTION_TRANSFORMER: ElementTransformer;
|
|
8
|
+
export declare const CONTAINER_TRANSFORMER: ElementTransformer;
|
|
9
|
+
export declare const GIT_ALERT_TRANSFORMER: ElementTransformer;
|
|
10
|
+
export declare const KATEX_BLOCK_TRANSFORMER: TextMatchTransformer;
|
|
11
|
+
export declare const IMAGE_BLOCK_TRANSFORMER: ElementTransformer;
|
|
12
|
+
export declare const VIDEO_BLOCK_TRANSFORMER: ElementTransformer;
|
|
13
|
+
export declare const CODE_BLOCK_NODE_TRANSFORMER: ElementTransformer;
|
|
14
|
+
export declare const LINK_CARD_BLOCK_TRANSFORMER: ElementTransformer;
|
|
15
|
+
export declare const MERMAID_BLOCK_TRANSFORMER: ElementTransformer;
|
|
16
|
+
export declare const GRID_CONTAINER_BLOCK_TRANSFORMER: ElementTransformer;
|
|
17
|
+
export declare const HORIZONTAL_RULE_BLOCK_TRANSFORMER: ElementTransformer;
|
|
18
|
+
export declare const TABLE_BLOCK_TRANSFORMER: ElementTransformer;
|
|
19
|
+
export declare const CODE_SNIPPET_BLOCK_TRANSFORMER: ElementTransformer;
|
|
20
|
+
export declare const EMBED_BLOCK_TRANSFORMER: ElementTransformer;
|
|
21
|
+
export declare const GALLERY_BLOCK_TRANSFORMER: ElementTransformer;
|
|
22
|
+
export declare const TLDRAW_BLOCK_TRANSFORMER: ElementTransformer;
|
|
23
|
+
export declare const allHeadlessTransformers: import('@lexical/markdown').Transformer[];
|
|
24
|
+
/** Call inside editor.read() to convert current state to Markdown. */
|
|
25
|
+
export declare function $toMarkdown(): string;
|
|
26
|
+
//# sourceMappingURL=transformers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.d.ts","sourceRoot":"","sources":["../src/transformers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAE1B,MAAM,mBAAmB,CAAA;AAsC1B,eAAO,MAAM,mBAAmB,EAAE,oBASjC,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,oBAajC,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,oBAWlC,CAAA;AAED,eAAO,MAAM,wBAAwB,EAAE,oBAWtC,CAAA;AAID,eAAO,MAAM,kBAAkB,EAAE,qBAIhC,CAAA;AAID,eAAO,MAAM,4BAA4B,EAAE,kBAY1C,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,kBAiBnC,CAAA;AAUD,eAAO,MAAM,qBAAqB,EAAE,kBAWnC,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,oBAWrC,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAWrC,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAcrC,CAAA;AAED,eAAO,MAAM,2BAA2B,EAAE,kBAWzC,CAAA;AAED,eAAO,MAAM,2BAA2B,EAAE,kBAUzC,CAAA;AAED,eAAO,MAAM,yBAAyB,EAAE,kBAWvC,CAAA;AAED,eAAO,MAAM,gCAAgC,EAAE,kBAa9C,CAAA;AAED,eAAO,MAAM,iCAAiC,EAAE,kBAM/C,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAuBrC,CAAA;AAID,eAAO,MAAM,8BAA8B,EAAE,kBAsB5C,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAOrC,CAAA;AAED,eAAO,MAAM,yBAAyB,EAAE,kBAUvC,CAAA;AAED,eAAO,MAAM,wBAAwB,EAAE,kBAStC,CAAA;AAID,eAAO,MAAM,uBAAuB,2CA2BnC,CAAA;AAED,sEAAsE;AACtE,wBAAgB,WAAW,IAAI,MAAM,CAEpC"}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { CHECK_LIST, TRANSFORMERS, $convertToMarkdownString } from "@lexical/markdown";
|
|
2
|
+
import { $isTableNode, $isTableRowNode, $isTableCellNode } from "@lexical/table";
|
|
3
|
+
const NEVER = /a^/;
|
|
4
|
+
const NOOP = () => {
|
|
5
|
+
};
|
|
6
|
+
function qA(v) {
|
|
7
|
+
return v.replaceAll('"', '\\"');
|
|
8
|
+
}
|
|
9
|
+
function escCell(v) {
|
|
10
|
+
return v.replaceAll("|", "\\|").replaceAll("\n", "<br/>");
|
|
11
|
+
}
|
|
12
|
+
function fence(content) {
|
|
13
|
+
const m = content.match(/`+/g);
|
|
14
|
+
const max = m?.reduce((a, r) => Math.max(a, r.length), 0) ?? 0;
|
|
15
|
+
return "`".repeat(Math.max(3, max + 1));
|
|
16
|
+
}
|
|
17
|
+
function walkText(node) {
|
|
18
|
+
const children = node.children;
|
|
19
|
+
if (!children) return node.text ?? "";
|
|
20
|
+
return children.map(walkText).join("\n");
|
|
21
|
+
}
|
|
22
|
+
function stateText(state) {
|
|
23
|
+
if (!state || typeof state !== "object") return "";
|
|
24
|
+
const root = state.root;
|
|
25
|
+
return root ? walkText(root) : "";
|
|
26
|
+
}
|
|
27
|
+
const SPOILER_TRANSFORMER = {
|
|
28
|
+
dependencies: [],
|
|
29
|
+
export: (node) => node.getType() === "spoiler" ? `||${node.getTextContent()}||` : null,
|
|
30
|
+
importRegExp: /\|\|(.+?)\|\|/,
|
|
31
|
+
regExp: /\|\|(.+?)\|\|$/,
|
|
32
|
+
replace: NOOP,
|
|
33
|
+
trigger: "|",
|
|
34
|
+
type: "text-match"
|
|
35
|
+
};
|
|
36
|
+
const MENTION_TRANSFORMER = {
|
|
37
|
+
dependencies: [],
|
|
38
|
+
export: (node) => {
|
|
39
|
+
if (node.getType() !== "mention") return null;
|
|
40
|
+
const j = node.exportJSON();
|
|
41
|
+
const base = `{${j.platform}@${j.handle}}`;
|
|
42
|
+
return j.displayName ? `[${j.displayName}]${base}` : base;
|
|
43
|
+
},
|
|
44
|
+
importRegExp: /(?:\[([^\]]+)\])?\{(\w+)@(\w[\w.-]*)\}/,
|
|
45
|
+
regExp: /(?:\[([^\]]+)\])?\{(\w+)@(\w[\w.-]*)\}$/,
|
|
46
|
+
replace: NOOP,
|
|
47
|
+
trigger: "}",
|
|
48
|
+
type: "text-match"
|
|
49
|
+
};
|
|
50
|
+
const FOOTNOTE_TRANSFORMER = {
|
|
51
|
+
dependencies: [],
|
|
52
|
+
export: (node) => node.getType() === "footnote" ? `[^${node.__identifier ?? ""}]` : null,
|
|
53
|
+
importRegExp: /\[\^(\w+)\]/,
|
|
54
|
+
regExp: /\[\^(\w+)\]$/,
|
|
55
|
+
replace: NOOP,
|
|
56
|
+
trigger: "]",
|
|
57
|
+
type: "text-match"
|
|
58
|
+
};
|
|
59
|
+
const KATEX_INLINE_TRANSFORMER = {
|
|
60
|
+
dependencies: [],
|
|
61
|
+
export: (node) => node.getType() === "katex-inline" ? `$${node.__equation ?? ""}$` : null,
|
|
62
|
+
importRegExp: /\$([^$\n]+)\$/,
|
|
63
|
+
regExp: /\$([^$\n]+)\$$/,
|
|
64
|
+
replace: NOOP,
|
|
65
|
+
trigger: "$",
|
|
66
|
+
type: "text-match"
|
|
67
|
+
};
|
|
68
|
+
const INSERT_TRANSFORMER = {
|
|
69
|
+
format: ["underline"],
|
|
70
|
+
tag: "++",
|
|
71
|
+
type: "text-format"
|
|
72
|
+
};
|
|
73
|
+
const FOOTNOTE_SECTION_TRANSFORMER = {
|
|
74
|
+
dependencies: [],
|
|
75
|
+
export: (node) => {
|
|
76
|
+
if (node.getType() !== "footnote-section") return null;
|
|
77
|
+
const defs = node.__definitions ?? {};
|
|
78
|
+
return Object.entries(defs).map(([id, content]) => `[^${id}]: ${content}`).join("\n");
|
|
79
|
+
},
|
|
80
|
+
regExp: NEVER,
|
|
81
|
+
replace: NOOP,
|
|
82
|
+
type: "element"
|
|
83
|
+
};
|
|
84
|
+
const CONTAINER_TRANSFORMER = {
|
|
85
|
+
dependencies: [],
|
|
86
|
+
export: (node) => {
|
|
87
|
+
const t = node.getType();
|
|
88
|
+
if (t === "banner") {
|
|
89
|
+
const type = node.__bannerType ?? "note";
|
|
90
|
+
return `::: ${type}
|
|
91
|
+
${node.getTextContent()}
|
|
92
|
+
:::`;
|
|
93
|
+
}
|
|
94
|
+
if (t === "details") {
|
|
95
|
+
const summary = node.__summary ?? "";
|
|
96
|
+
return `::: details{summary="${qA(summary)}"}
|
|
97
|
+
${node.getTextContent()}
|
|
98
|
+
:::`;
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
},
|
|
102
|
+
regExp: NEVER,
|
|
103
|
+
replace: NOOP,
|
|
104
|
+
type: "element"
|
|
105
|
+
};
|
|
106
|
+
const ALERT_KEY = {
|
|
107
|
+
note: "NOTE",
|
|
108
|
+
tip: "TIP",
|
|
109
|
+
important: "IMPORTANT",
|
|
110
|
+
warning: "WARNING",
|
|
111
|
+
caution: "CAUTION"
|
|
112
|
+
};
|
|
113
|
+
const GIT_ALERT_TRANSFORMER = {
|
|
114
|
+
dependencies: [],
|
|
115
|
+
export: (node) => {
|
|
116
|
+
if (node.getType() !== "alert-quote") return null;
|
|
117
|
+
const key = ALERT_KEY[node.__alertType ?? "note"] ?? "NOTE";
|
|
118
|
+
const lines = node.getTextContent().split("\n");
|
|
119
|
+
return [`> [!${key}]`, ...lines.map((l) => `> ${l}`)].join("\n");
|
|
120
|
+
},
|
|
121
|
+
regExp: NEVER,
|
|
122
|
+
replace: NOOP,
|
|
123
|
+
type: "element"
|
|
124
|
+
};
|
|
125
|
+
const KATEX_BLOCK_TRANSFORMER = {
|
|
126
|
+
dependencies: [],
|
|
127
|
+
export: (node) => node.getType() === "katex-block" ? `$$${node.__equation ?? ""}$$` : null,
|
|
128
|
+
importRegExp: /\$\$([^$]+)\$\$/,
|
|
129
|
+
regExp: /\$\$([^$]+)\$\$$/,
|
|
130
|
+
replace: NOOP,
|
|
131
|
+
trigger: "$",
|
|
132
|
+
type: "text-match"
|
|
133
|
+
};
|
|
134
|
+
const IMAGE_BLOCK_TRANSFORMER = {
|
|
135
|
+
dependencies: [],
|
|
136
|
+
export: (node) => {
|
|
137
|
+
if (node.getType() !== "image") return null;
|
|
138
|
+
const j = node.exportJSON();
|
|
139
|
+
const title = j.caption ? ` "${qA(j.caption)}"` : "";
|
|
140
|
+
return ``;
|
|
141
|
+
},
|
|
142
|
+
regExp: NEVER,
|
|
143
|
+
replace: NOOP,
|
|
144
|
+
type: "element"
|
|
145
|
+
};
|
|
146
|
+
const VIDEO_BLOCK_TRANSFORMER = {
|
|
147
|
+
dependencies: [],
|
|
148
|
+
export: (node) => {
|
|
149
|
+
if (node.getType() !== "video") return null;
|
|
150
|
+
const j = node.exportJSON();
|
|
151
|
+
const attrs = [`src="${qA(j.src)}"`];
|
|
152
|
+
if (j.poster) attrs.push(`poster="${qA(j.poster)}"`);
|
|
153
|
+
if (j.width) attrs.push(`width=${j.width}`);
|
|
154
|
+
if (j.height) attrs.push(`height=${j.height}`);
|
|
155
|
+
return `<video ${attrs.join(" ")} controls></video>`;
|
|
156
|
+
},
|
|
157
|
+
regExp: NEVER,
|
|
158
|
+
replace: NOOP,
|
|
159
|
+
type: "element"
|
|
160
|
+
};
|
|
161
|
+
const CODE_BLOCK_NODE_TRANSFORMER = {
|
|
162
|
+
dependencies: [],
|
|
163
|
+
export: (node) => {
|
|
164
|
+
if (node.getType() !== "code-block") return null;
|
|
165
|
+
const j = node.exportJSON();
|
|
166
|
+
const f = fence(j.code || "");
|
|
167
|
+
return `${f}${j.language || ""}
|
|
168
|
+
${j.code || ""}
|
|
169
|
+
${f}`;
|
|
170
|
+
},
|
|
171
|
+
regExp: NEVER,
|
|
172
|
+
replace: NOOP,
|
|
173
|
+
type: "element"
|
|
174
|
+
};
|
|
175
|
+
const LINK_CARD_BLOCK_TRANSFORMER = {
|
|
176
|
+
dependencies: [],
|
|
177
|
+
export: (node) => {
|
|
178
|
+
if (node.getType() !== "link-card") return null;
|
|
179
|
+
const j = node.exportJSON();
|
|
180
|
+
return j.title ? `[${j.title}](${j.url})` : `<${j.url}>`;
|
|
181
|
+
},
|
|
182
|
+
regExp: NEVER,
|
|
183
|
+
replace: NOOP,
|
|
184
|
+
type: "element"
|
|
185
|
+
};
|
|
186
|
+
const MERMAID_BLOCK_TRANSFORMER = {
|
|
187
|
+
dependencies: [],
|
|
188
|
+
export: (node) => {
|
|
189
|
+
if (node.getType() !== "mermaid") return null;
|
|
190
|
+
const d = node.__diagram ?? "";
|
|
191
|
+
const f = fence(d);
|
|
192
|
+
return `${f}mermaid
|
|
193
|
+
${d}
|
|
194
|
+
${f}`;
|
|
195
|
+
},
|
|
196
|
+
regExp: NEVER,
|
|
197
|
+
replace: NOOP,
|
|
198
|
+
type: "element"
|
|
199
|
+
};
|
|
200
|
+
const GRID_CONTAINER_BLOCK_TRANSFORMER = {
|
|
201
|
+
dependencies: [],
|
|
202
|
+
export: (node) => {
|
|
203
|
+
if (node.getType() !== "grid-container") return null;
|
|
204
|
+
const j = node.exportJSON();
|
|
205
|
+
const cells = (j.cells ?? []).map((c) => `::: cell
|
|
206
|
+
${stateText(c)}
|
|
207
|
+
:::`).join("\n");
|
|
208
|
+
return `::: grid{cols=${j.cols ?? 2} gap="${qA(String(j.gap ?? "16px"))}"}
|
|
209
|
+
${cells}
|
|
210
|
+
:::`;
|
|
211
|
+
},
|
|
212
|
+
regExp: NEVER,
|
|
213
|
+
replace: NOOP,
|
|
214
|
+
type: "element"
|
|
215
|
+
};
|
|
216
|
+
const HORIZONTAL_RULE_BLOCK_TRANSFORMER = {
|
|
217
|
+
dependencies: [],
|
|
218
|
+
export: (node) => node.getType() === "horizontalrule" ? "---" : null,
|
|
219
|
+
regExp: NEVER,
|
|
220
|
+
replace: NOOP,
|
|
221
|
+
type: "element"
|
|
222
|
+
};
|
|
223
|
+
const TABLE_BLOCK_TRANSFORMER = {
|
|
224
|
+
dependencies: [],
|
|
225
|
+
export: (node) => {
|
|
226
|
+
if (!$isTableNode(node)) return null;
|
|
227
|
+
const rows = node.getChildren().filter($isTableRowNode);
|
|
228
|
+
if (rows.length === 0) return "| |\n| --- |";
|
|
229
|
+
const data = rows.map(
|
|
230
|
+
(row) => row.getChildren().filter($isTableCellNode).map((c) => escCell(c.getTextContent()))
|
|
231
|
+
);
|
|
232
|
+
const hdr = data[0];
|
|
233
|
+
const sep = hdr.map(() => "---");
|
|
234
|
+
return [
|
|
235
|
+
`| ${hdr.join(" | ")} |`,
|
|
236
|
+
`| ${sep.join(" | ")} |`,
|
|
237
|
+
...data.slice(1).map((r) => `| ${r.join(" | ")} |`)
|
|
238
|
+
].join("\n");
|
|
239
|
+
},
|
|
240
|
+
regExp: NEVER,
|
|
241
|
+
replace: NOOP,
|
|
242
|
+
type: "element"
|
|
243
|
+
};
|
|
244
|
+
const CODE_SNIPPET_BLOCK_TRANSFORMER = {
|
|
245
|
+
dependencies: [],
|
|
246
|
+
export: (node) => {
|
|
247
|
+
if (node.getType() !== "code-snippet") return null;
|
|
248
|
+
const j = node.exportJSON();
|
|
249
|
+
const body = (j.files ?? []).map((f) => {
|
|
250
|
+
const fc = fence(f.code || "");
|
|
251
|
+
return [
|
|
252
|
+
`::: file{name="${qA(f.filename || "untitled")}" lang="${qA(f.language || "")}"}`,
|
|
253
|
+
`${fc}${f.language || ""}`,
|
|
254
|
+
f.code || "",
|
|
255
|
+
fc,
|
|
256
|
+
":::"
|
|
257
|
+
].join("\n");
|
|
258
|
+
}).join("\n");
|
|
259
|
+
return `::: code-snippet
|
|
260
|
+
${body}
|
|
261
|
+
:::`;
|
|
262
|
+
},
|
|
263
|
+
regExp: NEVER,
|
|
264
|
+
replace: NOOP,
|
|
265
|
+
type: "element"
|
|
266
|
+
};
|
|
267
|
+
const EMBED_BLOCK_TRANSFORMER = {
|
|
268
|
+
dependencies: [],
|
|
269
|
+
export: (node) => node.getType() === "embed" ? `<${node.__url || ""}>` : null,
|
|
270
|
+
regExp: NEVER,
|
|
271
|
+
replace: NOOP,
|
|
272
|
+
type: "element"
|
|
273
|
+
};
|
|
274
|
+
const GALLERY_BLOCK_TRANSFORMER = {
|
|
275
|
+
dependencies: [],
|
|
276
|
+
export: (node) => {
|
|
277
|
+
if (node.getType() !== "gallery") return null;
|
|
278
|
+
const imgs = node.exportJSON().images ?? [];
|
|
279
|
+
return imgs.map((i) => ``).join("\n");
|
|
280
|
+
},
|
|
281
|
+
regExp: NEVER,
|
|
282
|
+
replace: NOOP,
|
|
283
|
+
type: "element"
|
|
284
|
+
};
|
|
285
|
+
const TLDRAW_BLOCK_TRANSFORMER = {
|
|
286
|
+
dependencies: [],
|
|
287
|
+
export: (node) => node.getType() === "tldraw" ? `<tldraw>
|
|
288
|
+
${node.__snapshot || ""}
|
|
289
|
+
</tldraw>` : null,
|
|
290
|
+
regExp: NEVER,
|
|
291
|
+
replace: NOOP,
|
|
292
|
+
type: "element"
|
|
293
|
+
};
|
|
294
|
+
const allHeadlessTransformers = [
|
|
295
|
+
// Inline
|
|
296
|
+
SPOILER_TRANSFORMER,
|
|
297
|
+
MENTION_TRANSFORMER,
|
|
298
|
+
FOOTNOTE_TRANSFORMER,
|
|
299
|
+
INSERT_TRANSFORMER,
|
|
300
|
+
KATEX_INLINE_TRANSFORMER,
|
|
301
|
+
// Block (specific first)
|
|
302
|
+
FOOTNOTE_SECTION_TRANSFORMER,
|
|
303
|
+
CONTAINER_TRANSFORMER,
|
|
304
|
+
GIT_ALERT_TRANSFORMER,
|
|
305
|
+
CHECK_LIST,
|
|
306
|
+
KATEX_BLOCK_TRANSFORMER,
|
|
307
|
+
IMAGE_BLOCK_TRANSFORMER,
|
|
308
|
+
VIDEO_BLOCK_TRANSFORMER,
|
|
309
|
+
CODE_BLOCK_NODE_TRANSFORMER,
|
|
310
|
+
LINK_CARD_BLOCK_TRANSFORMER,
|
|
311
|
+
MERMAID_BLOCK_TRANSFORMER,
|
|
312
|
+
GRID_CONTAINER_BLOCK_TRANSFORMER,
|
|
313
|
+
HORIZONTAL_RULE_BLOCK_TRANSFORMER,
|
|
314
|
+
TABLE_BLOCK_TRANSFORMER,
|
|
315
|
+
CODE_SNIPPET_BLOCK_TRANSFORMER,
|
|
316
|
+
EMBED_BLOCK_TRANSFORMER,
|
|
317
|
+
GALLERY_BLOCK_TRANSFORMER,
|
|
318
|
+
TLDRAW_BLOCK_TRANSFORMER,
|
|
319
|
+
// Standard (heading, quote, list, code, bold, italic, strikethrough, link…)
|
|
320
|
+
...TRANSFORMERS
|
|
321
|
+
];
|
|
322
|
+
function $toMarkdown() {
|
|
323
|
+
return $convertToMarkdownString(allHeadlessTransformers);
|
|
324
|
+
}
|
|
325
|
+
export {
|
|
326
|
+
$toMarkdown,
|
|
327
|
+
CODE_BLOCK_NODE_TRANSFORMER,
|
|
328
|
+
CODE_SNIPPET_BLOCK_TRANSFORMER,
|
|
329
|
+
CONTAINER_TRANSFORMER,
|
|
330
|
+
EMBED_BLOCK_TRANSFORMER,
|
|
331
|
+
FOOTNOTE_SECTION_TRANSFORMER,
|
|
332
|
+
FOOTNOTE_TRANSFORMER,
|
|
333
|
+
GALLERY_BLOCK_TRANSFORMER,
|
|
334
|
+
GIT_ALERT_TRANSFORMER,
|
|
335
|
+
GRID_CONTAINER_BLOCK_TRANSFORMER,
|
|
336
|
+
HORIZONTAL_RULE_BLOCK_TRANSFORMER,
|
|
337
|
+
IMAGE_BLOCK_TRANSFORMER,
|
|
338
|
+
INSERT_TRANSFORMER,
|
|
339
|
+
KATEX_BLOCK_TRANSFORMER,
|
|
340
|
+
KATEX_INLINE_TRANSFORMER,
|
|
341
|
+
LINK_CARD_BLOCK_TRANSFORMER,
|
|
342
|
+
MENTION_TRANSFORMER,
|
|
343
|
+
MERMAID_BLOCK_TRANSFORMER,
|
|
344
|
+
SPOILER_TRANSFORMER,
|
|
345
|
+
TABLE_BLOCK_TRANSFORMER,
|
|
346
|
+
TLDRAW_BLOCK_TRANSFORMER,
|
|
347
|
+
VIDEO_BLOCK_TRANSFORMER,
|
|
348
|
+
allHeadlessTransformers
|
|
349
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-headless",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Headless Lexical node registry for server-side parsing (no React)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
".": {
|
|
9
9
|
"import": "./dist/index.mjs",
|
|
10
10
|
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./transformers": {
|
|
13
|
+
"import": "./dist/transformers.mjs",
|
|
14
|
+
"types": "./dist/transformers.d.ts"
|
|
11
15
|
}
|
|
12
16
|
},
|
|
13
17
|
"main": "./dist/index.mjs",
|
|
@@ -19,6 +23,7 @@
|
|
|
19
23
|
"@lexical/extension": "^0.40.0",
|
|
20
24
|
"@lexical/link": "^0.40.0",
|
|
21
25
|
"@lexical/list": "^0.40.0",
|
|
26
|
+
"@lexical/markdown": "^0.40.0",
|
|
22
27
|
"@lexical/rich-text": "^0.40.0",
|
|
23
28
|
"@lexical/table": "^0.40.0"
|
|
24
29
|
},
|