edytor 2.0.0 → 3.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/README.md +19 -4
- package/dist/block/block.svelte.js +2 -4
- package/dist/clipboard/htmlFlow.d.ts +20 -7
- package/dist/clipboard/htmlFlow.js +23 -15
- package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
- package/dist/clipboard/serializeClipboardFragment.js +6 -4
- package/dist/clipboard/textBlocks.d.ts +8 -0
- package/dist/clipboard/textBlocks.js +6 -2
- package/dist/cloudflare/room/admission.js +3 -3
- package/dist/cloudflare/room/context.d.ts +1 -1
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +53 -0
- package/dist/collaboration/comments/client.d.ts +1 -1
- package/dist/collaboration/comments/client.js +1 -1
- package/dist/collaboration/remoteSelection.js +3 -3
- package/dist/components/Edytor.svelte +2 -10
- package/dist/components/Edytor.svelte.d.ts +1 -3
- package/dist/crdt/admission.d.ts +5 -10
- package/dist/crdt/admission.js +5 -11
- package/dist/crdt/doc/funnel.d.ts +7 -6
- package/dist/crdt/doc/funnel.js +10 -9
- package/dist/crdt/doc/gate.d.ts +0 -17
- package/dist/crdt/doc/gate.js +2 -41
- package/dist/crdt/doc/history.js +2 -2
- package/dist/crdt/document.d.ts +5 -14
- package/dist/crdt/document.js +5 -19
- package/dist/crdt/edytor-doc.d.ts +4 -4
- package/dist/crdt/edytor-doc.js +3 -7
- package/dist/crdt/index.d.ts +3 -3
- package/dist/crdt/index.js +2 -2
- package/dist/crdt/protocol.d.ts +2 -2
- package/dist/crdt/protocol.js +2 -2
- package/dist/crdt/providers/index.d.ts +1 -1
- package/dist/crdt/providers/room.d.ts +10 -9
- package/dist/crdt/providers/room.js +13 -10
- package/dist/crdt/providers/websocket.d.ts +1 -1
- package/dist/crdt/providers/websocket.js +28 -29
- package/dist/crdt/semantics.js +3 -1
- package/dist/dnd/autoScroll.d.ts +15 -7
- package/dist/dnd/autoScroll.js +10 -15
- package/dist/dnd/dropIndicator.js +2 -5
- package/dist/dnd/external.d.ts +6 -0
- package/dist/dnd/external.js +17 -0
- package/dist/dnd/geometry.d.ts +2 -0
- package/dist/dnd/geometry.js +3 -4
- package/dist/dnd/placement.d.ts +1 -1
- package/dist/dnd/pragmatic.d.ts +3 -1
- package/dist/dnd/pragmatic.js +12 -2
- package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
- package/dist/edytor.svelte.d.ts +2 -5
- package/dist/edytor.svelte.js +17 -31
- package/dist/events/onBeforeInput.js +1 -1
- package/dist/events/onDrop.d.ts +0 -6
- package/dist/events/onDrop.js +10 -23
- package/dist/events/onInput.d.ts +0 -12
- package/dist/events/onInput.js +1 -67
- package/dist/export/forms.d.ts +627 -0
- package/dist/export/forms.js +749 -0
- package/dist/export/index.d.ts +170 -0
- package/dist/export/index.js +161 -0
- package/dist/export/markdown.d.ts +41 -0
- package/dist/export/markdown.js +585 -0
- package/dist/export/markdownWriter.d.ts +9 -0
- package/dist/export/markdownWriter.js +133 -0
- package/dist/export/mdx.d.ts +15 -0
- package/dist/export/mdx.js +33 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/kinds.js +1 -1
- package/dist/plugins/anchored.svelte.d.ts +21 -25
- package/dist/plugins/anchored.svelte.js +23 -39
- package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
- package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
- package/dist/plugins/blockHandles/dragPreview.js +33 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
- package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
- package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
- package/dist/plugins/chrome.d.ts +27 -5
- package/dist/plugins/chrome.js +24 -9
- package/dist/plugins/code/CodePlugin.svelte +12 -9
- package/dist/plugins/code/header.svelte.js +7 -11
- package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
- package/dist/plugins/code/languageMenu.svelte.js +13 -20
- package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
- package/dist/plugins/columns/resize.svelte.d.ts +2 -3
- package/dist/plugins/columns/resize.svelte.js +2 -5
- package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
- package/dist/plugins/comments/CommentsController.svelte.js +20 -0
- package/dist/plugins/equation/EquationPlugin.svelte +12 -22
- package/dist/plugins/equation/equation.svelte.d.ts +7 -15
- package/dist/plugins/equation/equation.svelte.js +13 -50
- package/dist/plugins/equation/tex.d.ts +17 -0
- package/dist/plugins/equation/tex.js +42 -0
- package/dist/plugins/fileDrop.d.ts +38 -23
- package/dist/plugins/fileDrop.js +82 -76
- package/dist/plugins/find/FindController.svelte.d.ts +5 -0
- package/dist/plugins/find/FindController.svelte.js +14 -14
- package/dist/plugins/find/findPlugin.js +1 -15
- package/dist/plugins/image/ImageChrome.svelte +8 -2
- package/dist/plugins/image/ImagePlugin.svelte +15 -52
- package/dist/plugins/image/controls.svelte.js +16 -2
- package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
- package/dist/plugins/image/toolbar.svelte.js +21 -31
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/list.svelte.d.ts +9 -0
- package/dist/plugins/list.svelte.js +18 -0
- package/dist/plugins/marquee/marqueePlugin.js +0 -4
- package/dist/plugins/media/AudioPlugin.svelte +1 -1
- package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
- package/dist/plugins/media/EmbedPlugin.svelte +5 -90
- package/dist/plugins/media/EmptySlot.svelte +36 -20
- package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
- package/dist/plugins/media/FilePlugin.svelte +1 -19
- package/dist/plugins/media/MediaEmpty.svelte +2 -55
- package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
- package/dist/plugins/media/SourceBlock.svelte +142 -52
- package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
- package/dist/plugins/media/VideoPlugin.svelte +1 -1
- package/dist/plugins/media/empty.svelte.js +2 -7
- package/dist/plugins/media/media.d.ts +2 -63
- package/dist/plugins/media/media.js +1 -194
- package/dist/plugins/media/sources.d.ts +60 -0
- package/dist/plugins/media/sources.js +165 -0
- package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
- package/dist/plugins/media/urlPaste.svelte.js +12 -21
- package/dist/plugins/mention/MentionPlugin.svelte +8 -35
- package/dist/plugins/page/PagePlugin.svelte +2 -9
- package/dist/plugins/page/page.js +1 -1
- package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
- package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
- package/dist/plugins/richtext/body.js +1 -1
- package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
- package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
- package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
- package/dist/plugins/richtext/richTextOperations.js +3 -49
- package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
- package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
- package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
- package/dist/plugins/table/TableChrome.svelte +2 -3
- package/dist/plugins/table/TablePlugin.svelte +20 -54
- package/dist/plugins/table/chrome.svelte.d.ts +5 -2
- package/dist/plugins/table/chrome.svelte.js +30 -54
- package/dist/plugins/table/table.js +3 -3
- package/dist/plugins/toc/TocPlugin.svelte +2 -4
- package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
- package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
- package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
- package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
- package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
- package/dist/plugins/triggers/place.js +1 -2
- package/dist/plugins/triggers/triggers.d.ts +6 -1
- package/dist/plugins/triggers/triggers.js +12 -13
- package/dist/plugins/uploads.svelte.d.ts +5 -2
- package/dist/plugins/uploads.svelte.js +25 -15
- package/dist/plugins.d.ts +26 -0
- package/dist/plugins.js +0 -24
- package/dist/selection/replaceSelection.js +2 -2
- package/dist/selection/selection.svelte.d.ts +4 -10
- package/dist/selection/selection.svelte.js +7 -11
- package/dist/session/bindings.js +1 -1
- package/dist/session/commands.d.ts +7 -11
- package/dist/session/commands.js +13 -19
- package/dist/session/inputRules.js +1 -1
- package/dist/session/navigation.js +1 -1
- package/dist/session/suggestions.svelte.d.ts +0 -11
- package/dist/session/suggestions.svelte.js +15 -3
- package/dist/session/uploads.d.ts +8 -8
- package/dist/surface/lines.js +1 -3
- package/dist/surface/observer.svelte.d.ts +17 -1
- package/dist/surface/observer.svelte.js +72 -17
- package/dist/surface/overlay.d.ts +0 -14
- package/dist/surface/overlay.js +0 -25
- package/dist/surface/projector.svelte.js +1 -1
- package/dist/text/text.svelte.js +3 -13
- package/dist/utils/sanitize.d.ts +38 -0
- package/dist/utils/sanitize.js +82 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +5 -0
- package/package.json +18 -1
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
- package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
- package/dist/plugins/code/LanguageMenu.svelte +0 -25
- package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
- package/dist/plugins/equation/EquationEditor.svelte +0 -27
- package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
- package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
- package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
- package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
- package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `edytor/export`: a document as HTML or Markdown, and HTML or Markdown
|
|
3
|
+
* as a document, by each kind's own forms (the clipboard's: `html`,
|
|
4
|
+
* `plain`, `markdown`, `parse`). Svelte-free and Worker-safe: it runs in a
|
|
5
|
+
* browser, in Node and in a Worker. Without `kinds` it reads the bundled
|
|
6
|
+
* kinds' forms ({@link bundledForms}); in a view, pass the view
|
|
7
|
+
* (`kinds: edytor`) to read its own records, your kinds included.
|
|
8
|
+
*/
|
|
9
|
+
import type { JSONBlock, JSONDoc } from '../utils/json.js';
|
|
10
|
+
import { type ExportKinds } from '../clipboard/serializeClipboardFragment.js';
|
|
11
|
+
import { type HtmlParser } from '../clipboard/htmlFlow.js';
|
|
12
|
+
import { bundledRead, type KindForms } from './forms.js';
|
|
13
|
+
import { type MarkdownComponents, type MarkdownOptions } from './markdown.js';
|
|
14
|
+
import type { BlockForms } from './forms.js';
|
|
15
|
+
export { escapeHtml } from '../clipboard/serializeClipboardFragment.js';
|
|
16
|
+
export { textToBlocks, type MarkdownComponents, type MarkdownIssue, type MarkdownOptions } from './markdown.js';
|
|
17
|
+
export { mdxComponent } from './mdx.js';
|
|
18
|
+
export { codeForms, columnsForms, equationForms, imageForms, mediaForms, mentionForms, pageForms, pageLinkForms, richTextForms, richTextMarkForms, tableForms, tocForms, type AtomForms, type BlockForms, type KindForms, type MarkForms, type MathML } from './forms.js';
|
|
19
|
+
export type { ExportKinds, HtmlParser };
|
|
20
|
+
export type { MarkdownContext } from '../plugins.js';
|
|
21
|
+
/**
|
|
22
|
+
* Every bundled kind's, mark's and atom's forms, with each plugin's
|
|
23
|
+
* default options: what `toHTML`, `toMarkdown` and `fromHTML` read when
|
|
24
|
+
* given no `kinds` (each its own direction of them). A view's own records
|
|
25
|
+
* (`kinds: edytor`) carry its options (its callout icon, its embed
|
|
26
|
+
* providers, its page links).
|
|
27
|
+
*/
|
|
28
|
+
export declare const bundledForms: {
|
|
29
|
+
blocks: Record<keyof ReturnType<typeof bundledRead>["blocks"], BlockForms>;
|
|
30
|
+
marks: {
|
|
31
|
+
bold: {
|
|
32
|
+
tag: string;
|
|
33
|
+
parse: (el: HTMLElement) => true | undefined;
|
|
34
|
+
};
|
|
35
|
+
italic: {
|
|
36
|
+
tag: string;
|
|
37
|
+
parse: (el: HTMLElement) => true | undefined;
|
|
38
|
+
};
|
|
39
|
+
underline: {
|
|
40
|
+
tag: string;
|
|
41
|
+
parse: (el: HTMLElement) => true | undefined;
|
|
42
|
+
};
|
|
43
|
+
strike: {
|
|
44
|
+
tag: string;
|
|
45
|
+
parse: (el: HTMLElement) => true | undefined;
|
|
46
|
+
};
|
|
47
|
+
code: {
|
|
48
|
+
tag: string;
|
|
49
|
+
};
|
|
50
|
+
link: {
|
|
51
|
+
tag: string;
|
|
52
|
+
attributes: (mark: {
|
|
53
|
+
href?: unknown;
|
|
54
|
+
target?: string;
|
|
55
|
+
}) => {
|
|
56
|
+
href: string | undefined;
|
|
57
|
+
target: string | undefined;
|
|
58
|
+
};
|
|
59
|
+
parse: (el: HTMLElement) => {
|
|
60
|
+
target?: string | undefined;
|
|
61
|
+
href: string;
|
|
62
|
+
} | undefined;
|
|
63
|
+
edge: "side-dependent";
|
|
64
|
+
};
|
|
65
|
+
superscript: {
|
|
66
|
+
tag: string;
|
|
67
|
+
};
|
|
68
|
+
subscript: {
|
|
69
|
+
tag: string;
|
|
70
|
+
};
|
|
71
|
+
color: {
|
|
72
|
+
tag: string;
|
|
73
|
+
attributes: (value: unknown) => {
|
|
74
|
+
style: string | undefined;
|
|
75
|
+
};
|
|
76
|
+
parse: (el: HTMLElement) => string | undefined;
|
|
77
|
+
};
|
|
78
|
+
highlight: {
|
|
79
|
+
tag: string;
|
|
80
|
+
attributes: (value: unknown) => {
|
|
81
|
+
style: string | undefined;
|
|
82
|
+
};
|
|
83
|
+
parse: (el: HTMLElement) => string | undefined;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
inlineBlocks: {
|
|
87
|
+
inlineEquation: {
|
|
88
|
+
html?: (data: import("../utils/json.js").JSONInlineBlock["data"]) => string;
|
|
89
|
+
markdown?: (data: import("../utils/json.js").JSONInlineBlock["data"]) => string;
|
|
90
|
+
plain?: (data: import("../utils/json.js").JSONInlineBlock["data"]) => string;
|
|
91
|
+
parse?: (element: HTMLElement) => Record<string, import("../utils/json.js").SerializableContent> | undefined;
|
|
92
|
+
};
|
|
93
|
+
mention: import("../clipboard/serializeClipboardFragment.js").AtomForms;
|
|
94
|
+
pageLink: import("../clipboard/serializeClipboardFragment.js").AtomForms;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
/** Which forms a conversion reads. */
|
|
98
|
+
export type ExportOptions = {
|
|
99
|
+
/**
|
|
100
|
+
* The kinds, marks and atoms to read: a view (`edytor`, its own records),
|
|
101
|
+
* or forms by name. A section left out is the bundled one; listed, it is
|
|
102
|
+
* exactly those (`{ blocks: { ...bundledForms.blocks, mine } }` adds yours;
|
|
103
|
+
* a shorter list allows only those). Default {@link bundledForms}.
|
|
104
|
+
*/
|
|
105
|
+
kinds?: KindForms | ExportKinds;
|
|
106
|
+
/**
|
|
107
|
+
* MDX-lite, for `toMarkdown`: the tags to write, each the kind it stands
|
|
108
|
+
* for (`{ Endpoint: 'endpoint' }`), the map `fromMarkdown` reads. A block
|
|
109
|
+
* of a listed kind is its tag, its data the attributes (see
|
|
110
|
+
* {@link mdxComponent}); its kind's own `markdown` form is not used.
|
|
111
|
+
*/
|
|
112
|
+
components?: MarkdownComponents;
|
|
113
|
+
};
|
|
114
|
+
/** What {@link fromHTML} reads. */
|
|
115
|
+
export type ImportOptions = ExportOptions & {
|
|
116
|
+
/**
|
|
117
|
+
* The HTML parser: the browser's `DOMParser` by default. On a server pass
|
|
118
|
+
* one (`import { DOMParser } from 'linkedom'`, or jsdom's
|
|
119
|
+
* `new JSDOM().window.DOMParser`). It only parses: nothing in the HTML
|
|
120
|
+
* runs or loads.
|
|
121
|
+
*/
|
|
122
|
+
DOMParser?: HtmlParser;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* A document (or blocks) as HTML: each block by its kind's `html` form, a
|
|
126
|
+
* run of list items in their list's element, text by its marks' elements.
|
|
127
|
+
* Values are escaped and links through the link sanitizer; ids and empty
|
|
128
|
+
* data are never written.
|
|
129
|
+
*
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { toHTML } from 'edytor/export';
|
|
132
|
+
* const html = toHTML(value);
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare const toHTML: (doc: JSONDoc | readonly JSONBlock[], options?: ExportOptions) => string;
|
|
136
|
+
/**
|
|
137
|
+
* A document (or blocks) as Markdown (CommonMark with GFM tables, task
|
|
138
|
+
* lists and strikethrough): each block by its kind's `markdown` form (else
|
|
139
|
+
* its `plain` form), marks by theirs, atoms by theirs (else their `plain`
|
|
140
|
+
* form). A toggle is a `<details>` disclosure, a callout a `> [!NOTE]`
|
|
141
|
+
* alert; `textToBlocks` reads both back.
|
|
142
|
+
*/
|
|
143
|
+
export declare const toMarkdown: (doc: JSONDoc | readonly JSONBlock[], options?: ExportOptions) => string;
|
|
144
|
+
/**
|
|
145
|
+
* Markdown as a document: {@link textToBlocks}'s reading, as a `JSONDoc`.
|
|
146
|
+
* With `components`, MDX-lite tags (`<Endpoint operationId="getPet" />`)
|
|
147
|
+
* are blocks of the kinds they name; a tag it does not name, an
|
|
148
|
+
* expression, an import or an export stays text and is told to `onUnknown`.
|
|
149
|
+
*
|
|
150
|
+
* ```ts
|
|
151
|
+
* import { fromMarkdown } from 'edytor/export';
|
|
152
|
+
* const value = fromMarkdown(source, { components: { Endpoint: 'endpoint' } });
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare const fromMarkdown: (source: string, options?: MarkdownOptions) => JSONDoc;
|
|
156
|
+
/**
|
|
157
|
+
* HTML as a document, the paste's reading (`flow.html.*`): only the kinds,
|
|
158
|
+
* marks and atoms of `kinds` survive (an unknown element is its text, a
|
|
159
|
+
* `script` or `style` nothing), every value through its record's `parse`
|
|
160
|
+
* hook (a link's href through the link sanitizer: `javascript:` drops the
|
|
161
|
+
* link, an image's source through the image's), and nothing executes: the
|
|
162
|
+
* parser only parses, no attribute is copied (`onerror`, `style`).
|
|
163
|
+
*
|
|
164
|
+
* ```ts
|
|
165
|
+
* import { DOMParser } from 'linkedom'; // on a server; the browser has its own
|
|
166
|
+
* import { fromHTML } from 'edytor/export';
|
|
167
|
+
* const value = fromHTML(html, { DOMParser });
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export declare const fromHTML: (html: string, options?: ImportOptions) => JSONDoc;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { blocksToHtml } from '../clipboard/serializeClipboardFragment.js';
|
|
2
|
+
import { blocksToMarkdown } from './markdownWriter.js';
|
|
3
|
+
import { linesOfHtml } from '../clipboard/htmlFlow.js';
|
|
4
|
+
import { bundledMarkdown, bundledRead, bundledWrite, codeForms, columnsForms, equationForms, htmlExtras, imageForms, listSiblings, markdownExtras, mediaForms, mentionForms, pageForms, pageLinkForms, parseExtras, richTextForms, richTextMarkForms, tableForms, tocForms } from './forms.js';
|
|
5
|
+
import { textToBlocks } from './markdown.js';
|
|
6
|
+
import { mdxComponent } from './mdx.js';
|
|
7
|
+
import { iconOf } from '../plugins/richtext/callouts.js';
|
|
8
|
+
export { escapeHtml } from '../clipboard/serializeClipboardFragment.js';
|
|
9
|
+
export { textToBlocks } from './markdown.js';
|
|
10
|
+
export { mdxComponent } from './mdx.js';
|
|
11
|
+
export { codeForms, columnsForms, equationForms, imageForms, mediaForms, mentionForms, pageForms, pageLinkForms, richTextForms, richTextMarkForms, tableForms, tocForms } from './forms.js';
|
|
12
|
+
/**
|
|
13
|
+
* Every bundled kind's, mark's and atom's forms, with each plugin's
|
|
14
|
+
* default options: what `toHTML`, `toMarkdown` and `fromHTML` read when
|
|
15
|
+
* given no `kinds` (each its own direction of them). A view's own records
|
|
16
|
+
* (`kinds: edytor`) carry its options (its callout icon, its embed
|
|
17
|
+
* providers, its page links).
|
|
18
|
+
*/
|
|
19
|
+
export const bundledForms = /* @__PURE__ */ (() => {
|
|
20
|
+
const read = bundledRead().blocks;
|
|
21
|
+
const rich = { paragraph: {}, ...richTextForms(iconOf) };
|
|
22
|
+
// A rich text kind's presets' data, as its plugin lists them: HTML import finds a kind by a
|
|
23
|
+
// preset's tag (an `h2`, a `blockquote`). A view's records carry their own.
|
|
24
|
+
for (const type in rich)
|
|
25
|
+
if (read[type]?.presets)
|
|
26
|
+
rich[type] = { ...rich[type], presets: read[type].presets };
|
|
27
|
+
const equation = equationForms();
|
|
28
|
+
return {
|
|
29
|
+
blocks: {
|
|
30
|
+
...rich,
|
|
31
|
+
...codeForms(),
|
|
32
|
+
...tableForms(),
|
|
33
|
+
...imageForms(),
|
|
34
|
+
...mediaForms(),
|
|
35
|
+
...pageForms(),
|
|
36
|
+
...tocForms(),
|
|
37
|
+
...equation.blocks,
|
|
38
|
+
...columnsForms()
|
|
39
|
+
},
|
|
40
|
+
marks: richTextMarkForms,
|
|
41
|
+
inlineBlocks: { mention: mentionForms(), pageLink: pageLinkForms(), ...equation.inlineBlocks }
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
const isView = (kinds) => kinds.blocks instanceof Map;
|
|
45
|
+
/**
|
|
46
|
+
* `kinds` as the records a conversion reads, each with the forms of
|
|
47
|
+
* `extras` (by name) it lacks: its own win. A section left out is the
|
|
48
|
+
* direction's bundled one.
|
|
49
|
+
*/
|
|
50
|
+
const recordsOf = (kinds, defaults, extras) => {
|
|
51
|
+
const own = kinds && isView(kinds) ? kinds : undefined;
|
|
52
|
+
const forms = (kinds ?? {});
|
|
53
|
+
let bundled;
|
|
54
|
+
const section = (key) => new Map([...(own?.[key] ?? Object.entries(forms[key] ?? (bundled ??= defaults())[key]))].map(([name, form]) => [
|
|
55
|
+
name,
|
|
56
|
+
{
|
|
57
|
+
...(Object.hasOwn(extras[key], name) && extras[key][name]),
|
|
58
|
+
...Object.fromEntries(Object.entries(form).filter(([, value]) => value !== undefined))
|
|
59
|
+
}
|
|
60
|
+
]));
|
|
61
|
+
return {
|
|
62
|
+
blocks: section('blocks'),
|
|
63
|
+
marks: section('marks'),
|
|
64
|
+
inlineBlocks: section('inlineBlocks')
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
const blocksOf = (doc) => (Array.isArray(doc) ? doc : doc.children) ?? [];
|
|
68
|
+
/**
|
|
69
|
+
* A document (or blocks) as HTML: each block by its kind's `html` form, a
|
|
70
|
+
* run of list items in their list's element, text by its marks' elements.
|
|
71
|
+
* Values are escaped and links through the link sanitizer; ids and empty
|
|
72
|
+
* data are never written.
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { toHTML } from 'edytor/export';
|
|
76
|
+
* const html = toHTML(value);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export const toHTML = (doc, options = {}) => {
|
|
80
|
+
const records = recordsOf(options.kinds, bundledWrite, {
|
|
81
|
+
blocks: htmlExtras(),
|
|
82
|
+
marks: {},
|
|
83
|
+
inlineBlocks: {}
|
|
84
|
+
});
|
|
85
|
+
return blocksToHtml([...blocksOf(doc)], records, listSiblings(records));
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* A document (or blocks) as Markdown (CommonMark with GFM tables, task
|
|
89
|
+
* lists and strikethrough): each block by its kind's `markdown` form (else
|
|
90
|
+
* its `plain` form), marks by theirs, atoms by theirs (else their `plain`
|
|
91
|
+
* form). A toggle is a `<details>` disclosure, a callout a `> [!NOTE]`
|
|
92
|
+
* alert; `textToBlocks` reads both back.
|
|
93
|
+
*/
|
|
94
|
+
export const toMarkdown = (doc, options = {}) => {
|
|
95
|
+
const records = recordsOf(options.kinds, bundledMarkdown, markdownExtras());
|
|
96
|
+
// Each kind `components` lists written as its tag (the first tag naming it).
|
|
97
|
+
for (const [tag, type] of Object.entries(options.components ?? {}).reverse())
|
|
98
|
+
records.blocks.set(type, {
|
|
99
|
+
...records.blocks.get(type),
|
|
100
|
+
markdown: (block, content, children) => mdxComponent(tag, block.data, content, children)
|
|
101
|
+
});
|
|
102
|
+
const md = blocksToMarkdown([...blocksOf(doc)], records);
|
|
103
|
+
return md ? `${md}\n` : '';
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Markdown as a document: {@link textToBlocks}'s reading, as a `JSONDoc`.
|
|
107
|
+
* With `components`, MDX-lite tags (`<Endpoint operationId="getPet" />`)
|
|
108
|
+
* are blocks of the kinds they name; a tag it does not name, an
|
|
109
|
+
* expression, an import or an export stays text and is told to `onUnknown`.
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { fromMarkdown } from 'edytor/export';
|
|
113
|
+
* const value = fromMarkdown(source, { components: { Endpoint: 'endpoint' } });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export const fromMarkdown = (source, options = {}) => ({
|
|
117
|
+
children: textToBlocks(source, options)
|
|
118
|
+
});
|
|
119
|
+
/** A parsed line's type resolved (its parent's default child), its empty data and children dropped. */
|
|
120
|
+
const settle = (line, parent, defaultChild) => {
|
|
121
|
+
const type = line.type ?? defaultChild(parent);
|
|
122
|
+
const block = { type, content: line.content ?? [] };
|
|
123
|
+
if (line.data && Object.keys(line.data).length)
|
|
124
|
+
block.data = line.data;
|
|
125
|
+
if (line.children?.length)
|
|
126
|
+
block.children = line.children.map((child) => settle(child, type, defaultChild));
|
|
127
|
+
return block;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* HTML as a document, the paste's reading (`flow.html.*`): only the kinds,
|
|
131
|
+
* marks and atoms of `kinds` survive (an unknown element is its text, a
|
|
132
|
+
* `script` or `style` nothing), every value through its record's `parse`
|
|
133
|
+
* hook (a link's href through the link sanitizer: `javascript:` drops the
|
|
134
|
+
* link, an image's source through the image's), and nothing executes: the
|
|
135
|
+
* parser only parses, no attribute is copied (`onerror`, `style`).
|
|
136
|
+
*
|
|
137
|
+
* ```ts
|
|
138
|
+
* import { DOMParser } from 'linkedom'; // on a server; the browser has its own
|
|
139
|
+
* import { fromHTML } from 'edytor/export';
|
|
140
|
+
* const value = fromHTML(html, { DOMParser });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export const fromHTML = (html, options = {}) => {
|
|
144
|
+
const records = recordsOf(options.kinds, bundledRead, {
|
|
145
|
+
blocks: parseExtras(),
|
|
146
|
+
marks: {},
|
|
147
|
+
inlineBlocks: {}
|
|
148
|
+
});
|
|
149
|
+
const own = options.kinds?.document;
|
|
150
|
+
const defaultChild = own?.defaultChild.bind(own) ??
|
|
151
|
+
((parent) => (parent !== null && records.blocks.get(parent)?.defaultChild) || 'paragraph');
|
|
152
|
+
const parser = options.DOMParser ?? globalThis.DOMParser;
|
|
153
|
+
if (!parser)
|
|
154
|
+
throw new Error("fromHTML: no DOMParser here; pass one (`import { DOMParser } from 'linkedom'`).");
|
|
155
|
+
// A fragment as a document's body: a server parser (linkedom) reads only whole documents.
|
|
156
|
+
const whole = /<(?:html|body)[\s>]/i.test(html)
|
|
157
|
+
? html
|
|
158
|
+
: `<!doctype html><html><head></head><body>${html}</body></html>`;
|
|
159
|
+
const lines = linesOfHtml({ ...records, document: { defaultChild } }, whole, parser) ?? [];
|
|
160
|
+
return { children: lines.map((line) => settle(line, null, defaultChild)) };
|
|
161
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { JSONBlock } from '../utils/json.js';
|
|
2
|
+
/** MDX-lite tags by name, each the kind it reads as: `{ Endpoint: 'endpoint' }`. */
|
|
3
|
+
export type MarkdownComponents = Readonly<Record<string, string>>;
|
|
4
|
+
/** A tag or line `fromMarkdown` kept as text, with why. */
|
|
5
|
+
export type MarkdownIssue = {
|
|
6
|
+
/**
|
|
7
|
+
* `component`: a tag `components` does not name; `expression`: an
|
|
8
|
+
* attribute whose value is not a string, a number, `true` or `false`
|
|
9
|
+
* (`{a + b}`, `{...props}`); `unclosed`: a tag without its closing tag;
|
|
10
|
+
* `import` / `export`: an MDX import or export line.
|
|
11
|
+
*/
|
|
12
|
+
reason: 'component' | 'expression' | 'unclosed' | 'import' | 'export';
|
|
13
|
+
/** The line kept as text. */
|
|
14
|
+
source: string;
|
|
15
|
+
/** The tag's name, for a tag. */
|
|
16
|
+
name?: string;
|
|
17
|
+
};
|
|
18
|
+
export type MarkdownOptions = {
|
|
19
|
+
/** Read markdown (default `true`); `false` keeps every character as text. */
|
|
20
|
+
markdown?: boolean;
|
|
21
|
+
/** The kind of a paragraph (default `paragraph`). */
|
|
22
|
+
type?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The text is still arriving (default `false`): hold back an unfinished
|
|
25
|
+
* last line's block marker or unclosed inline marker, and a table header
|
|
26
|
+
* row without its separator yet, so a streamed preview never shows raw
|
|
27
|
+
* markdown that the next chunk turns into a kind or a mark.
|
|
28
|
+
*/
|
|
29
|
+
streaming?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* MDX-lite: the tags to read, each as the kind it names
|
|
32
|
+
* (`{ Endpoint: 'endpoint', Callout: 'callout' }`). Literal attributes
|
|
33
|
+
* (`"text"`, `{1}`, `{true}`) become the block's data; the tag's
|
|
34
|
+
* markdown its text (one line) or its text and children (lines).
|
|
35
|
+
*/
|
|
36
|
+
components?: MarkdownComponents;
|
|
37
|
+
/** Told of each tag, expression, import or export kept as text. */
|
|
38
|
+
onUnknown?: (issue: MarkdownIssue) => void;
|
|
39
|
+
};
|
|
40
|
+
/** `text` as blocks (see the module comment). */
|
|
41
|
+
export declare const textToBlocks: (text: string, { markdown, type, streaming, components, onUnknown }?: MarkdownOptions) => JSONBlock[];
|