@andesine/converters 0.1.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.
@@ -0,0 +1,185 @@
1
+ //#region src/types.d.ts
2
+ interface ContentMark {
3
+ type: string;
4
+ attrs?: Record<string, unknown>;
5
+ }
6
+ interface ContentNode {
7
+ type: string;
8
+ attrs?: Record<string, unknown>;
9
+ content?: ContentNode[];
10
+ marks?: ContentMark[];
11
+ text?: string;
12
+ }
13
+ interface ImageReference {
14
+ url: string;
15
+ alt: string;
16
+ title?: string;
17
+ }
18
+ interface EncodeContext<T> {
19
+ /** Generated heading anchor for this node, when available. Stable within the full document. */
20
+ anchor?: string;
21
+ /** Merged factory defaults and per-call options. */
22
+ options: ExportConverterOptions<T>;
23
+ /** Child indexes identifying the current node in the source document. */
24
+ path: readonly number[];
25
+ /** Encode another node at the current path, applying custom handlers and marks. */
26
+ encode(node: ContentNode): Promise<T[]>;
27
+ /** Encode child nodes in order, updating their paths and awaiting async handlers. */
28
+ children(node: ContentNode): Promise<T[]>;
29
+ /** Resolve an image through imageURL; throws ConversionError if no URL is supplied. */
30
+ imageURL(node: ContentNode): Promise<string>;
31
+ }
32
+ interface DecodeContext<T> {
33
+ /** Merged factory defaults and per-call options. */
34
+ options: ImportConverterOptions<T>;
35
+ /** Child indexes identifying the current node in the parsed tree. */
36
+ path: readonly number[];
37
+ /** Decode another format node at the current path, applying custom handlers. */
38
+ decode(node: T): Promise<ContentNode[]>;
39
+ /** Decode child nodes in order, updating their paths and awaiting async handlers. */
40
+ children(nodes: readonly T[]): Promise<ContentNode[]>;
41
+ /** Resolve a URL through imageAssetID and create an image node; does not upload assets. */
42
+ image(reference: ImageReference): Promise<ContentNode>;
43
+ }
44
+ interface EncodeHandlers<T> {
45
+ /** Handlers keyed by ProseMirror node type. "*" handles otherwise unmatched node types. */
46
+ nodes?: Record<string, (node: ContentNode, context: EncodeContext<T>) => Awaitable<HandlerResult<T>>>;
47
+ /** Handlers keyed by Andesine element name; exact and "*" matches precede node handlers. */
48
+ elements?: Record<string, (node: ContentNode, context: EncodeContext<T>) => Awaitable<HandlerResult<T>>>;
49
+ /** Handlers keyed by mark type, with "*" as fallback. Receives already encoded children. */
50
+ marks?: Record<string, (mark: ContentMark, children: T[], context: EncodeContext<T>) => Awaitable<HandlerResult<T>>>;
51
+ }
52
+ interface DecodeHandlers<T> {
53
+ /** Handlers keyed by adapter node type, with "*" as fallback. */
54
+ nodes?: Record<string, (node: T, context: DecodeContext<T>) => Awaitable<HandlerResult<ContentNode>>>;
55
+ /** Element-name handlers, including "*", checked before mark-name and node-type handlers. */
56
+ elements?: Record<string, (node: T, context: DecodeContext<T>) => Awaitable<HandlerResult<ContentNode>>>;
57
+ /** Mark-name handlers, including "*", checked after element handlers and before node handlers. */
58
+ marks?: Record<string, (node: T, context: DecodeContext<T>) => Awaitable<HandlerResult<ContentNode>>>;
59
+ }
60
+ interface BaseConverterOptions {
61
+ /** Map the title to an H1 by default, omit it, or use frontmatter in supported formats. */
62
+ title?: "heading" | "omit" | {
63
+ as: "frontmatter";
64
+ key?: string;
65
+ };
66
+ /** Omit properties by default, or map labels and values to frontmatter. Duplicate keys throw. */
67
+ properties?: "omit" | {
68
+ as: "frontmatter";
69
+ };
70
+ /** Fragment mappings. Defaults to unwrapping content; unwrapped boundaries cannot be restored. */
71
+ fragments?: {
72
+ /** Fallback for fragments without a named mapping. Defaults to "unwrap". */
73
+ default?: FragmentMapping;
74
+ /** Overrides keyed by fragment name, merged by key with factory defaults. */
75
+ named?: Record<string, FragmentMapping>;
76
+ };
77
+ }
78
+ /** Options used only when exporting ProseMirror JSON to another format. */
79
+ interface ExportConverterOptions<T> extends BaseConverterOptions {
80
+ /** Resolve an image asset to a URL during export. Required for image output except plain text. */
81
+ imageURL?: (node: ContentNode) => Awaitable<string>;
82
+ /** Export handlers. Return one node, multiple nodes, or null to omit; async handlers are awaited. */
83
+ encode?: EncodeHandlers<T>;
84
+ }
85
+ /** Options used only when importing another format as ProseMirror JSON. */
86
+ interface ImportConverterOptions<T> extends BaseConverterOptions {
87
+ /** Import an entry with a title by default, or a fragment without consuming an H1 as title. */
88
+ document?: "entry" | "fragment";
89
+ /** On import, wrap body content in this named fragment. Defaults to leaving it unwrapped. */
90
+ targetFragment?: string;
91
+ /** Resolve an imported image URL to an existing asset ID. Uploading/saving is the caller's job. */
92
+ imageAssetID?: (image: ImageReference) => Awaitable<string>;
93
+ /** Import handlers. Handler maps merge by key with factory defaults; async handlers are awaited. */
94
+ decode?: DecodeHandlers<T>;
95
+ }
96
+ /** Defaults for a converter that supports both directions. */
97
+ interface ConverterOptions<T> extends ExportConverterOptions<T>, ImportConverterOptions<T> {}
98
+ interface ConvertedAST<T> {
99
+ /** Target format tree, without serialized frontmatter. */
100
+ tree: T;
101
+ /** Metadata extracted or supplied through title and property mappings. */
102
+ frontmatter: Record<string, unknown>;
103
+ }
104
+ /** Export-only methods. Import methods are absent both in TypeScript and at runtime. */
105
+ interface ExportConverter<T> {
106
+ /**
107
+ * Export ProseMirror JSON as a format string.
108
+ * @param document - An entry or fragment document.
109
+ * @param options - Per-call overrides; handler maps and named fragments merge with defaults.
110
+ * @returns Serialized content, including mapped frontmatter when supported.
111
+ * @throws ConversionError for unsupported content, unresolved images, or invalid mappings.
112
+ * Custom handler and serializer failures pass through unchanged.
113
+ */
114
+ encode(document: ContentNode, options?: ExportConverterOptions<T>): Promise<string>;
115
+ /**
116
+ * Export a document as the target format's AST and separate frontmatter.
117
+ * @param document - Source ProseMirror document.
118
+ * @param options - Per-call mappings and handlers merged over factory defaults.
119
+ * @returns The converted tree and metadata without string serialization.
120
+ * @throws The same conversion errors as encode(), including unsupported frontmatter mappings.
121
+ */
122
+ toAST(document: ContentNode, options?: ExportConverterOptions<T>): Promise<ConvertedAST<T>>;
123
+ }
124
+ /** Import-only methods. Export methods are absent both in TypeScript and at runtime. */
125
+ interface ImportConverter<T> {
126
+ /**
127
+ * Import a format string as ProseMirror JSON.
128
+ * @param source - Text in the adapter's format, with optional supported frontmatter.
129
+ * @param options - Per-call overrides; imageAssetID resolves imported images without uploading.
130
+ * @returns An entry document by default; document: "fragment" omits the title node.
131
+ * @throws ConversionError for unsupported content or mappings; parser/handler errors pass through.
132
+ */
133
+ decode(source: string, options?: ImportConverterOptions<T>): Promise<ContentNode>;
134
+ /**
135
+ * Import an already parsed AST and its metadata.
136
+ * @param input - Format tree and frontmatter object; use an empty object when metadata is absent.
137
+ * @param options - Per-call mappings and handlers merged over factory defaults.
138
+ * @returns ProseMirror JSON without parsing a string or saving content.
139
+ * @throws The same conversion errors as decode(), excluding string-parser errors.
140
+ */
141
+ fromAST(input: ConvertedAST<T>, options?: ImportConverterOptions<T>): Promise<ContentNode>;
142
+ }
143
+ /** Shared conversion methods returned by the full format factories. No method saves or uploads content. */
144
+ interface Converter<T> extends ExportConverter<T>, ImportConverter<T> {}
145
+ interface BaseFormatAdapter {
146
+ /** Human-readable format name used in errors. */
147
+ name: string;
148
+ /** Whether the format supports frontmatter mappings. Defaults to false. */
149
+ frontmatter?: boolean;
150
+ }
151
+ /** Export adapter: no parser, decode handler, or format-node lookup is required. */
152
+ interface ExportFormatAdapter<T> extends BaseFormatAdapter {
153
+ /** Wrap converted child nodes in the format's root node. */
154
+ root(children: T[]): T;
155
+ /** Serialize the format tree; the shared converter writes frontmatter separately. */
156
+ stringify(tree: T): Awaitable<string>;
157
+ /** Encode a node without a custom handler. Shared title/property/fragment mappings run first. */
158
+ encode(node: ContentNode, context: EncodeContext<T>): Awaitable<HandlerResult<T>>;
159
+ /** Apply a mark to encoded children when no custom mark handler matches. */
160
+ mark(mark: ContentMark, children: T[], context: EncodeContext<T>): Awaitable<HandlerResult<T>>;
161
+ }
162
+ /** Import adapter: no root builder, serializer, encode handler, or mark writer is required. */
163
+ interface ImportFormatAdapter<T> extends BaseFormatAdapter {
164
+ /** Return the format node type used to select decode node handlers. */
165
+ type(node: T): string;
166
+ /** Return a custom element name for decode element-handler lookup, if present. */
167
+ elementName?(node: T): string | undefined;
168
+ /** Return a mark name for decode mark-handler lookup, if present. */
169
+ markName?(node: T): string | undefined;
170
+ /** Parse source text after the shared converter removes supported frontmatter. */
171
+ parse(source: string): Awaitable<T>;
172
+ /** Decode a format node when no custom decode handler matches. */
173
+ decode(node: T, context: DecodeContext<T>): Awaitable<HandlerResult<ContentNode>>;
174
+ }
175
+ /** Adapter contract for a format supporting both import and export. */
176
+ interface FormatAdapter<T> extends ExportFormatAdapter<T>, ImportFormatAdapter<T> {}
177
+ type Awaitable<T> = T | Promise<T>;
178
+ type HandlerResult<T> = T | T[] | null;
179
+ type FragmentMapping = "unwrap" | "omit" | {
180
+ as: "element";
181
+ name: string;
182
+ };
183
+ //#endregion
184
+ export { ImageReference as _, Converter as a, ImportFormatAdapter as b, DecodeHandlers as c, ExportConverter as d, ExportConverterOptions as f, HandlerResult as g, FragmentMapping as h, ConvertedAST as i, EncodeContext as l, FormatAdapter as m, ContentMark as n, ConverterOptions as o, ExportFormatAdapter as p, ContentNode as r, DecodeContext as s, Awaitable as t, EncodeHandlers as u, ImportConverter as v, ImportConverterOptions as y };
185
+ //# sourceMappingURL=types-SDFWRP3z.d.ts.map
package/dist/html.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { a as Converter, f as ExportConverterOptions, i as ConvertedAST, m as FormatAdapter, o as ConverterOptions, r as ContentNode, y as ImportConverterOptions } from "./chunks/types-SDFWRP3z.js";
2
+ import { Root, RootContent } from "hast";
3
+ //#region src/html.d.ts
4
+ type HTMLNode = Root | RootContent;
5
+ type HTMLOptions = ConverterOptions<HTMLNode>;
6
+ /** HTML adapter for createConverter(), including its parser and node/mark mappings. */
7
+ declare const htmlAdapter: FormatAdapter<HTMLNode>;
8
+ /**
9
+ * Create a reusable async HTML converter with application-specific defaults.
10
+ * @param options - Default mappings and handlers; per-call maps merge by key and callbacks may be async.
11
+ * @returns String and AST import/export methods. Defaults use an H1 title, unwrap fragments, and omit properties.
12
+ * Custom elements use Andesine data attributes; frontmatter mappings are not supported.
13
+ */
14
+ declare const createHTMLConverter: (options?: HTMLOptions) => Converter<HTMLNode>;
15
+ /**
16
+ * Export ProseMirror JSON as HTML.
17
+ * @param document - Entry or fragment document. Fragment wrappers are removed by default.
18
+ * @param options - Title/property/fragment mappings and async handlers; imageURL resolves images.
19
+ * @returns Serialized HTML. Omitted metadata and unwrapped fragment boundaries are not recoverable.
20
+ * @throws ConversionError for unsupported content, unresolved images, or invalid mappings; handler errors pass through.
21
+ */
22
+ declare const toHTML: (document: ContentNode, options?: ExportConverterOptions<HTMLNode> | undefined) => Promise<string>;
23
+ /**
24
+ * Import HTML as ProseMirror JSON without saving content or uploading assets.
25
+ * @param source - Source text to parse. Custom elements use Andesine data attributes; frontmatter mappings are not supported.
26
+ * @param options - Import mappings and async handlers. imageAssetID must resolve image URLs.
27
+ * @returns An entry document; use document: "fragment" to omit the title and retain the first H1 as body content.
28
+ * @throws ConversionError for unsupported content/mappings; parser and handler errors pass through.
29
+ */
30
+ declare const fromHTML: (source: string, options?: ImportConverterOptions<HTMLNode> | undefined) => Promise<ContentNode>;
31
+ /**
32
+ * Export ProseMirror JSON as a HTML AST with separate frontmatter.
33
+ * @param document - Source entry or fragment document.
34
+ * @param options - Export mappings and async handlers, including imageURL for images.
35
+ * @returns The format tree and metadata without string serialization.
36
+ * @throws The same conversion errors as toHTML(), including unsupported frontmatter mappings.
37
+ */
38
+ declare const toHTMLAST: (document: ContentNode, options?: ExportConverterOptions<HTMLNode> | undefined) => Promise<ConvertedAST<HTMLNode>>;
39
+ /**
40
+ * Import a parsed HTML AST and its frontmatter as ProseMirror JSON.
41
+ * @param input - Tree and frontmatter object; use an empty object when metadata is absent.
42
+ * @param options - Import mappings and async handlers, including imageAssetID for images.
43
+ * @returns An entry document by default, or a fragment document when requested.
44
+ * @throws The same conversion errors as fromHTML(), excluding string-parser errors.
45
+ */
46
+ declare const fromHTMLAST: (input: ConvertedAST<HTMLNode>, options?: ImportConverterOptions<HTMLNode> | undefined) => Promise<ContentNode>;
47
+ //#endregion
48
+ export { type HTMLNode, type HTMLOptions, createHTMLConverter, fromHTML, fromHTMLAST, htmlAdapter, toHTML, toHTMLAST };
49
+ //# sourceMappingURL=html.d.ts.map
package/dist/html.js ADDED
@@ -0,0 +1,252 @@
1
+ import { a as element, c as textContent, i as ConversionError, l as textNode, s as lookup, t as createConverter, u as withMark } from "./chunks/core-DC64ddB7.js";
2
+ import { n as paragraphContent } from "./chunks/decode-B-xzTJFV.js";
3
+ import { fromHtml } from "hast-util-from-html";
4
+ import { toHtml } from "hast-util-to-html";
5
+ //#region src/html.ts
6
+ const tag = (tagName, children = [], properties = {}) => ({
7
+ type: "element",
8
+ tagName,
9
+ properties,
10
+ children
11
+ });
12
+ const htmlText = (node) => node.type === "text" ? node.value : "children" in node ? node.children.map(htmlText).join("") : "";
13
+ const safeURL = (value, image = false) => {
14
+ const url = new URL(value, "https://example.com");
15
+ if (!(image ? ["http:", "https:"] : [
16
+ "http:",
17
+ "https:",
18
+ "mailto:",
19
+ "tel:"
20
+ ]).includes(url.protocol)) throw new ConversionError(`Unsupported URL protocol: ${url.protocol}`);
21
+ return value;
22
+ };
23
+ const htmlMarks = {
24
+ strong: "bold",
25
+ b: "bold",
26
+ em: "italic",
27
+ i: "italic",
28
+ s: "strike",
29
+ del: "strike",
30
+ code: "code",
31
+ a: "link",
32
+ sub: "subscript",
33
+ sup: "superscript",
34
+ mark: "highlight"
35
+ };
36
+ /** HTML adapter for createConverter(), including its parser and node/mark mappings. */
37
+ const htmlAdapter = {
38
+ name: "HTML",
39
+ type: (node) => node.type === "element" ? node.tagName : node.type,
40
+ elementName: (node) => node.type === "element" ? String(node.properties.dataAndesineElement || node.tagName) : void 0,
41
+ markName: (node) => node.type === "element" ? lookup(htmlMarks, node.tagName) : void 0,
42
+ root: (children) => ({
43
+ type: "root",
44
+ children
45
+ }),
46
+ parse: (source) => fromHtml(source, { fragment: true }),
47
+ stringify: (tree) => toHtml(tree),
48
+ async encode(node, context) {
49
+ const attrs = node.attrs || {};
50
+ const children = await context.children(node);
51
+ switch (node.type) {
52
+ case "text": return {
53
+ type: "text",
54
+ value: node.text || ""
55
+ };
56
+ case "paragraph": return tag("p", children);
57
+ case "heading": return tag(`h${Math.max(1, Math.min(6, Number(attrs.level || 1)))}`, children, context.anchor ? { id: context.anchor } : {});
58
+ case "blockquote": return tag("blockquote", children);
59
+ case "bulletList": return tag("ul", children);
60
+ case "orderedList": return tag("ol", children, { start: Number(attrs.start || 1) });
61
+ case "taskList": return tag("ul", children, { dataType: "taskList" });
62
+ case "listItem": return tag("li", children);
63
+ case "taskItem": return tag("li", children, {
64
+ dataType: "taskItem",
65
+ dataChecked: Boolean(attrs.checked) ? "true" : "false"
66
+ });
67
+ case "hardBreak": return tag("br");
68
+ case "horizontalRule": return tag("hr");
69
+ case "codeBlock": return tag("pre", [tag("code", [{
70
+ type: "text",
71
+ value: textContent(node)
72
+ }], { dataLanguage: String(attrs.language || "") })]);
73
+ case "image": {
74
+ const image = tag("img", [], {
75
+ src: safeURL(await context.imageURL(node), true),
76
+ alt: String(attrs.alt || "")
77
+ });
78
+ return attrs.caption ? tag("figure", [image, tag("figcaption", [{
79
+ type: "text",
80
+ value: String(attrs.caption)
81
+ }])]) : image;
82
+ }
83
+ case "table": return tag("table", [tag("tbody", children)]);
84
+ case "tableRow": return tag("tr", children);
85
+ case "tableCell":
86
+ case "tableHeader": return tag(node.type === "tableHeader" ? "th" : "td", children, {
87
+ colSpan: Number(attrs.colspan || 1),
88
+ rowSpan: Number(attrs.rowspan || 1)
89
+ });
90
+ case "element": return tag("div", children, {
91
+ dataAndesineElement: String(attrs.name || "Element"),
92
+ dataAndesineProps: JSON.stringify(attrs.props || {})
93
+ });
94
+ default: throw new ConversionError(`Unsupported HTML node: ${node.type}`, context.path);
95
+ }
96
+ },
97
+ mark(mark, children, context) {
98
+ const name = Object.entries(htmlMarks).find(([, type]) => type === mark.type)?.[0];
99
+ if (!name) throw new ConversionError(`Unsupported HTML mark: ${mark.type}`, context.path);
100
+ return tag(name, children, mark.type === "link" ? { href: safeURL(String(mark.attrs?.href || "")) } : {});
101
+ },
102
+ async decode(node, context) {
103
+ if (node.type === "text") return textNode(node.value.replace(/[ \t\r\n\f]+/g, " "));
104
+ if (node.type !== "root" && node.type !== "element") throw new ConversionError(`Unsupported HTML syntax: ${node.type}`, context.path);
105
+ const name = node.type === "element" ? node.tagName : "root";
106
+ const props = node.type === "element" ? node.properties : {};
107
+ if (name === "pre") {
108
+ const code = node.children.find((child) => child.type === "element" && child.tagName === "code");
109
+ return {
110
+ type: "codeBlock",
111
+ attrs: { language: (code?.type === "element" ? code.properties.dataLanguage || String(code.properties.className || "").match(/language-([\w+-]+)/)?.[1] : void 0) || null },
112
+ content: textNode(htmlText(node))
113
+ };
114
+ }
115
+ if (name === "img") return context.image({
116
+ url: safeURL(String(props.src || ""), true),
117
+ alt: String(props.alt || ""),
118
+ title: props.title ? String(props.title) : void 0
119
+ });
120
+ if (name === "figure") {
121
+ const image = node.children.find((child) => child.type === "element" && child.tagName === "img");
122
+ const caption = node.children.find((child) => child.type === "element" && child.tagName === "figcaption");
123
+ if (!image || image.type !== "element") throw new ConversionError("HTML figures require an image", context.path);
124
+ return context.image({
125
+ url: safeURL(String(image.properties.src || ""), true),
126
+ alt: String(image.properties.alt || ""),
127
+ title: caption ? htmlText(caption) : void 0
128
+ });
129
+ }
130
+ const blockContainer = [
131
+ "root",
132
+ "div",
133
+ "section",
134
+ "article",
135
+ "main",
136
+ "ul",
137
+ "ol",
138
+ "table",
139
+ "thead",
140
+ "tbody",
141
+ "tfoot",
142
+ "tr",
143
+ "blockquote"
144
+ ].includes(name);
145
+ const decoded = await context.children(node.children);
146
+ const children = blockContainer ? decoded.filter((child, index) => {
147
+ if (child.type !== "text" || /[^ \t\r\n\f]/.test(child.text || "")) return true;
148
+ return [decoded[index - 1], decoded[index + 1]].every((sibling) => sibling && ["text", "hardBreak"].includes(sibling.type));
149
+ }) : decoded;
150
+ const mark = lookup(htmlMarks, name);
151
+ if (props.dataAndesineElement) return element(String(props.dataAndesineElement), JSON.parse(String(props.dataAndesineProps || "{}")), children);
152
+ if (mark) return withMark(children, {
153
+ type: mark,
154
+ ...mark === "link" ? { attrs: { href: safeURL(String(props.href || "")) } } : {}
155
+ });
156
+ if (/^h[1-6]$/.test(name)) return {
157
+ type: "heading",
158
+ attrs: { level: Number(name[1]) },
159
+ content: children
160
+ };
161
+ switch (name) {
162
+ case "root":
163
+ case "div":
164
+ case "section":
165
+ case "article":
166
+ case "main": return paragraphContent(children);
167
+ case "thead":
168
+ case "tbody":
169
+ case "tfoot": return children;
170
+ case "p": return paragraphContent(children);
171
+ case "blockquote": return {
172
+ type: "blockquote",
173
+ content: paragraphContent(children)
174
+ };
175
+ case "ul":
176
+ case "ol": return {
177
+ type: name === "ol" ? "orderedList" : props.dataType === "taskList" ? "taskList" : "bulletList",
178
+ ...name === "ol" ? { attrs: { start: Number(props.start || 1) } } : {},
179
+ content: children
180
+ };
181
+ case "li": return {
182
+ type: props.dataType === "taskItem" ? "taskItem" : "listItem",
183
+ ...props.dataType === "taskItem" ? { attrs: { checked: props.dataChecked === "true" } } : {},
184
+ content: paragraphContent(children)
185
+ };
186
+ case "br": return { type: "hardBreak" };
187
+ case "hr": return { type: "horizontalRule" };
188
+ case "table": return {
189
+ type: "table",
190
+ content: children
191
+ };
192
+ case "tr": return {
193
+ type: "tableRow",
194
+ content: children
195
+ };
196
+ case "th":
197
+ case "td": return {
198
+ type: name === "th" ? "tableHeader" : "tableCell",
199
+ attrs: {
200
+ colspan: Number(props.colSpan || 1),
201
+ rowspan: Number(props.rowSpan || 1)
202
+ },
203
+ content: paragraphContent(children)
204
+ };
205
+ default: throw new ConversionError(`Unsupported HTML element: ${name}`, context.path);
206
+ }
207
+ }
208
+ };
209
+ /**
210
+ * Create a reusable async HTML converter with application-specific defaults.
211
+ * @param options - Default mappings and handlers; per-call maps merge by key and callbacks may be async.
212
+ * @returns String and AST import/export methods. Defaults use an H1 title, unwrap fragments, and omit properties.
213
+ * Custom elements use Andesine data attributes; frontmatter mappings are not supported.
214
+ */
215
+ const createHTMLConverter = (options) => createConverter(htmlAdapter, options);
216
+ const converter = createHTMLConverter();
217
+ /**
218
+ * Export ProseMirror JSON as HTML.
219
+ * @param document - Entry or fragment document. Fragment wrappers are removed by default.
220
+ * @param options - Title/property/fragment mappings and async handlers; imageURL resolves images.
221
+ * @returns Serialized HTML. Omitted metadata and unwrapped fragment boundaries are not recoverable.
222
+ * @throws ConversionError for unsupported content, unresolved images, or invalid mappings; handler errors pass through.
223
+ */
224
+ const toHTML = converter.encode;
225
+ /**
226
+ * Import HTML as ProseMirror JSON without saving content or uploading assets.
227
+ * @param source - Source text to parse. Custom elements use Andesine data attributes; frontmatter mappings are not supported.
228
+ * @param options - Import mappings and async handlers. imageAssetID must resolve image URLs.
229
+ * @returns An entry document; use document: "fragment" to omit the title and retain the first H1 as body content.
230
+ * @throws ConversionError for unsupported content/mappings; parser and handler errors pass through.
231
+ */
232
+ const fromHTML = converter.decode;
233
+ /**
234
+ * Export ProseMirror JSON as a HTML AST with separate frontmatter.
235
+ * @param document - Source entry or fragment document.
236
+ * @param options - Export mappings and async handlers, including imageURL for images.
237
+ * @returns The format tree and metadata without string serialization.
238
+ * @throws The same conversion errors as toHTML(), including unsupported frontmatter mappings.
239
+ */
240
+ const toHTMLAST = converter.toAST;
241
+ /**
242
+ * Import a parsed HTML AST and its frontmatter as ProseMirror JSON.
243
+ * @param input - Tree and frontmatter object; use an empty object when metadata is absent.
244
+ * @param options - Import mappings and async handlers, including imageAssetID for images.
245
+ * @returns An entry document by default, or a fragment document when requested.
246
+ * @throws The same conversion errors as fromHTML(), excluding string-parser errors.
247
+ */
248
+ const fromHTMLAST = converter.fromAST;
249
+ //#endregion
250
+ export { createHTMLConverter, fromHTML, fromHTMLAST, htmlAdapter, toHTML, toHTMLAST };
251
+
252
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","names":[],"sources":["../src/html.ts"],"sourcesContent":["import { fromHtml } from \"hast-util-from-html\";\nimport { toHtml } from \"hast-util-to-html\";\nimport type { Element, ElementContent, Properties, Root, RootContent } from \"hast\";\nimport { createConverter } from \"./core\";\nimport { paragraphContent } from \"./markdown/decode\";\nimport { ConversionError, lookup, element, textContent, textNode, withMark } from \"./utils\";\nimport type { ConverterOptions, FormatAdapter } from \"./types\";\n\ntype HTMLNode = Root | RootContent;\ntype HTMLOptions = ConverterOptions<HTMLNode>;\n\nconst tag = (tagName: string, children: HTMLNode[] = [], properties: Properties = {}): Element => ({\n type: \"element\",\n tagName,\n properties,\n children: children as ElementContent[]\n});\nconst htmlText = (node: HTMLNode): string =>\n node.type === \"text\"\n ? node.value\n : \"children\" in node\n ? node.children.map(htmlText).join(\"\")\n : \"\";\nconst safeURL = (value: string, image = false): string => {\n const url = new URL(value, \"https://example.com\");\n const allowed = image ? [\"http:\", \"https:\"] : [\"http:\", \"https:\", \"mailto:\", \"tel:\"];\n\n if (!allowed.includes(url.protocol))\n throw new ConversionError(`Unsupported URL protocol: ${url.protocol}`);\n\n return value;\n};\nconst htmlMarks: Record<string, string> = {\n strong: \"bold\",\n b: \"bold\",\n em: \"italic\",\n i: \"italic\",\n s: \"strike\",\n del: \"strike\",\n code: \"code\",\n a: \"link\",\n sub: \"subscript\",\n sup: \"superscript\",\n mark: \"highlight\"\n};\n/** HTML adapter for createConverter(), including its parser and node/mark mappings. */\nconst htmlAdapter: FormatAdapter<HTMLNode> = {\n name: \"HTML\",\n type: (node) => (node.type === \"element\" ? node.tagName : node.type),\n elementName: (node) =>\n node.type === \"element\"\n ? String(node.properties.dataAndesineElement || node.tagName)\n : undefined,\n markName: (node) => (node.type === \"element\" ? lookup(htmlMarks, node.tagName) : undefined),\n root: (children) => ({ type: \"root\", children: children as RootContent[] }),\n parse: (source) => fromHtml(source, { fragment: true }),\n stringify: (tree) => toHtml(tree),\n async encode(node, context) {\n const attrs = node.attrs || {};\n const children = await context.children(node);\n\n switch (node.type) {\n case \"text\":\n return { type: \"text\", value: node.text || \"\" };\n case \"paragraph\":\n return tag(\"p\", children);\n case \"heading\":\n return tag(\n `h${Math.max(1, Math.min(6, Number(attrs.level || 1)))}`,\n children,\n context.anchor ? { id: context.anchor } : {}\n );\n case \"blockquote\":\n return tag(\"blockquote\", children);\n case \"bulletList\":\n return tag(\"ul\", children);\n case \"orderedList\":\n return tag(\"ol\", children, { start: Number(attrs.start || 1) });\n case \"taskList\":\n return tag(\"ul\", children, { dataType: \"taskList\" });\n case \"listItem\":\n return tag(\"li\", children);\n case \"taskItem\":\n return tag(\"li\", children, {\n dataType: \"taskItem\",\n dataChecked: Boolean(attrs.checked) ? \"true\" : \"false\"\n });\n case \"hardBreak\":\n return tag(\"br\");\n case \"horizontalRule\":\n return tag(\"hr\");\n case \"codeBlock\":\n return tag(\"pre\", [\n tag(\"code\", [{ type: \"text\", value: textContent(node) }], {\n dataLanguage: String(attrs.language || \"\")\n })\n ]);\n case \"image\": {\n const image = tag(\"img\", [], {\n src: safeURL(await context.imageURL(node), true),\n alt: String(attrs.alt || \"\")\n });\n\n return attrs.caption\n ? tag(\"figure\", [\n image,\n tag(\"figcaption\", [{ type: \"text\", value: String(attrs.caption) }])\n ])\n : image;\n }\n case \"table\":\n return tag(\"table\", [tag(\"tbody\", children)]);\n case \"tableRow\":\n return tag(\"tr\", children);\n case \"tableCell\":\n case \"tableHeader\":\n return tag(node.type === \"tableHeader\" ? \"th\" : \"td\", children, {\n colSpan: Number(attrs.colspan || 1),\n rowSpan: Number(attrs.rowspan || 1)\n });\n case \"element\":\n return tag(\"div\", children, {\n dataAndesineElement: String(attrs.name || \"Element\"),\n dataAndesineProps: JSON.stringify(attrs.props || {})\n });\n default:\n throw new ConversionError(`Unsupported HTML node: ${node.type}`, context.path);\n }\n },\n mark(mark, children, context) {\n const name = Object.entries(htmlMarks).find(([, type]) => type === mark.type)?.[0];\n\n if (!name) throw new ConversionError(`Unsupported HTML mark: ${mark.type}`, context.path);\n\n return tag(\n name,\n children,\n mark.type === \"link\" ? { href: safeURL(String(mark.attrs?.href || \"\")) } : {}\n );\n },\n async decode(node, context) {\n if (node.type === \"text\") return textNode(node.value.replace(/[ \\t\\r\\n\\f]+/g, \" \"));\n if (node.type !== \"root\" && node.type !== \"element\")\n throw new ConversionError(`Unsupported HTML syntax: ${node.type}`, context.path);\n\n const name = node.type === \"element\" ? node.tagName : \"root\";\n const props = node.type === \"element\" ? node.properties : {};\n\n if (name === \"pre\") {\n const code = node.children.find(\n (child) => child.type === \"element\" && child.tagName === \"code\"\n );\n const language =\n code?.type === \"element\"\n ? code.properties.dataLanguage ||\n String(code.properties.className || \"\").match(/language-([\\w+-]+)/)?.[1]\n : undefined;\n\n return {\n type: \"codeBlock\",\n attrs: { language: language || null },\n content: textNode(htmlText(node))\n };\n }\n if (name === \"img\")\n return context.image({\n url: safeURL(String(props.src || \"\"), true),\n alt: String(props.alt || \"\"),\n title: props.title ? String(props.title) : undefined\n });\n if (name === \"figure\") {\n const image = node.children.find(\n (child) => child.type === \"element\" && child.tagName === \"img\"\n );\n const caption = node.children.find(\n (child) => child.type === \"element\" && child.tagName === \"figcaption\"\n );\n\n if (!image || image.type !== \"element\")\n throw new ConversionError(\"HTML figures require an image\", context.path);\n\n return context.image({\n url: safeURL(String(image.properties.src || \"\"), true),\n alt: String(image.properties.alt || \"\"),\n title: caption ? htmlText(caption) : undefined\n });\n }\n const blockContainer = [\n \"root\",\n \"div\",\n \"section\",\n \"article\",\n \"main\",\n \"ul\",\n \"ol\",\n \"table\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"tr\",\n \"blockquote\"\n ].includes(name);\n const decoded = await context.children(node.children);\n const children = blockContainer\n ? decoded.filter((child, index) => {\n if (child.type !== \"text\" || /[^ \\t\\r\\n\\f]/.test(child.text || \"\")) return true;\n\n // Keep word separators inside inline runs, but omit indentation around blocks.\n return [decoded[index - 1], decoded[index + 1]].every(\n (sibling) => sibling && [\"text\", \"hardBreak\"].includes(sibling.type)\n );\n })\n : decoded;\n const mark = lookup(htmlMarks, name);\n\n if (props.dataAndesineElement) {\n return element(\n String(props.dataAndesineElement),\n JSON.parse(String(props.dataAndesineProps || \"{}\")),\n children\n );\n }\n if (mark)\n return withMark(children, {\n type: mark,\n ...(mark === \"link\" ? { attrs: { href: safeURL(String(props.href || \"\")) } } : {})\n });\n if (/^h[1-6]$/.test(name))\n return { type: \"heading\", attrs: { level: Number(name[1]) }, content: children };\n\n switch (name) {\n case \"root\":\n case \"div\":\n case \"section\":\n case \"article\":\n case \"main\":\n return paragraphContent(children);\n case \"thead\":\n case \"tbody\":\n case \"tfoot\":\n return children;\n case \"p\":\n return paragraphContent(children);\n case \"blockquote\":\n return { type: \"blockquote\", content: paragraphContent(children) };\n case \"ul\":\n case \"ol\":\n return {\n type:\n name === \"ol\"\n ? \"orderedList\"\n : props.dataType === \"taskList\"\n ? \"taskList\"\n : \"bulletList\",\n ...(name === \"ol\" ? { attrs: { start: Number(props.start || 1) } } : {}),\n content: children\n };\n case \"li\":\n return {\n type: props.dataType === \"taskItem\" ? \"taskItem\" : \"listItem\",\n ...(props.dataType === \"taskItem\"\n ? { attrs: { checked: props.dataChecked === \"true\" } }\n : {}),\n content: paragraphContent(children)\n };\n case \"br\":\n return { type: \"hardBreak\" };\n case \"hr\":\n return { type: \"horizontalRule\" };\n case \"table\":\n return { type: \"table\", content: children };\n case \"tr\":\n return { type: \"tableRow\", content: children };\n case \"th\":\n case \"td\":\n return {\n type: name === \"th\" ? \"tableHeader\" : \"tableCell\",\n attrs: { colspan: Number(props.colSpan || 1), rowspan: Number(props.rowSpan || 1) },\n content: paragraphContent(children)\n };\n default:\n throw new ConversionError(`Unsupported HTML element: ${name}`, context.path);\n }\n }\n};\n/**\n * Create a reusable async HTML converter with application-specific defaults.\n * @param options - Default mappings and handlers; per-call maps merge by key and callbacks may be async.\n * @returns String and AST import/export methods. Defaults use an H1 title, unwrap fragments, and omit properties.\n * Custom elements use Andesine data attributes; frontmatter mappings are not supported.\n */\nconst createHTMLConverter = (options?: HTMLOptions) => createConverter(htmlAdapter, options);\nconst converter = createHTMLConverter();\n/**\n * Export ProseMirror JSON as HTML.\n * @param document - Entry or fragment document. Fragment wrappers are removed by default.\n * @param options - Title/property/fragment mappings and async handlers; imageURL resolves images.\n * @returns Serialized HTML. Omitted metadata and unwrapped fragment boundaries are not recoverable.\n * @throws ConversionError for unsupported content, unresolved images, or invalid mappings; handler errors pass through.\n */\nconst toHTML = converter.encode;\n/**\n * Import HTML as ProseMirror JSON without saving content or uploading assets.\n * @param source - Source text to parse. Custom elements use Andesine data attributes; frontmatter mappings are not supported.\n * @param options - Import mappings and async handlers. imageAssetID must resolve image URLs.\n * @returns An entry document; use document: \"fragment\" to omit the title and retain the first H1 as body content.\n * @throws ConversionError for unsupported content/mappings; parser and handler errors pass through.\n */\nconst fromHTML = converter.decode;\n/**\n * Export ProseMirror JSON as a HTML AST with separate frontmatter.\n * @param document - Source entry or fragment document.\n * @param options - Export mappings and async handlers, including imageURL for images.\n * @returns The format tree and metadata without string serialization.\n * @throws The same conversion errors as toHTML(), including unsupported frontmatter mappings.\n */\nconst toHTMLAST = converter.toAST;\n/**\n * Import a parsed HTML AST and its frontmatter as ProseMirror JSON.\n * @param input - Tree and frontmatter object; use an empty object when metadata is absent.\n * @param options - Import mappings and async handlers, including imageAssetID for images.\n * @returns An entry document by default, or a fragment document when requested.\n * @throws The same conversion errors as fromHTML(), excluding string-parser errors.\n */\nconst fromHTMLAST = converter.fromAST;\n\nexport { createHTMLConverter, htmlAdapter, toHTML, fromHTML, toHTMLAST, fromHTMLAST };\nexport type { HTMLNode, HTMLOptions };\n"],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import { _ as ImageReference, a as Converter, b as ImportFormatAdapter, c as DecodeHandlers, d as ExportConverter, f as ExportConverterOptions, g as HandlerResult, h as FragmentMapping, i as ConvertedAST, l as EncodeContext, m as FormatAdapter, n as ContentMark, o as ConverterOptions, p as ExportFormatAdapter, r as ContentNode, s as DecodeContext, t as Awaitable, u as EncodeHandlers, v as ImportConverter, y as ImportConverterOptions } from "./chunks/types-SDFWRP3z.js";
2
+ import { HeadingAnchor, getHeadingAnchors } from "./anchors.js";
3
+ //#region src/core.d.ts
4
+ /**
5
+ * Build an async export-only converter using the shared content mappings.
6
+ *
7
+ * @param adapter - Root builder, serializer, and export node/mark handlers. No import stubs are needed.
8
+ * @param defaults - Reusable options. Per-call handler maps and named fragment mappings merge by key.
9
+ * @returns Only encode() and toAST(), both async. Handlers and image callbacks may be async.
10
+ * Import methods are absent at runtime and in TypeScript. No content is saved.
11
+ * Unsupported nodes and marks are handled by the adapter, usually by throwing ConversionError.
12
+ * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and
13
+ * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.
14
+ */
15
+ declare const createExportConverter: <T>(adapter: ExportFormatAdapter<T>, defaults?: ExportConverterOptions<T>) => ExportConverter<T>;
16
+ /**
17
+ * Build an async import-only converter using the shared content mappings.
18
+ *
19
+ * @param adapter - Parser, decode handler, and node-type lookup. No export stubs are needed.
20
+ * @param defaults - Reusable import mappings and handlers, merged by key with per-call overrides.
21
+ * @returns Only decode() and fromAST(), both async. Parsers, handlers, and image callbacks may
22
+ * be async. Export methods are absent at runtime and in TypeScript. No content is saved.
23
+ * Imports create an entry with a title by default; document: "fragment" retains headings as body
24
+ * content. Unsupported input is handled by the adapter; parser and handler errors pass through.
25
+ */
26
+ declare const createImportConverter: <T>(adapter: ImportFormatAdapter<T>, defaults?: ImportConverterOptions<T>) => ImportConverter<T>;
27
+ /**
28
+ * Build an async converter for a custom format that supports both import and export.
29
+ *
30
+ * @param adapter - Full adapter with parser, serializer, and mappings for both directions.
31
+ * @param defaults - Shared defaults and direction-specific handlers. Per-call maps merge by key.
32
+ * @returns encode(), toAST(), decode(), and fromAST(), composed from the one-way factories.
33
+ * Each method accepts options for its own direction. No content is saved or uploaded.
34
+ * Defaults render titles as H1s, unwrap fragments, and omit properties. Removed boundaries and
35
+ * omitted data cannot be recovered on import; choose explicit mappings when preservation matters.
36
+ */
37
+ declare const createConverter: <T>(adapter: FormatAdapter<T>, defaults?: ConverterOptions<T>) => Converter<T>;
38
+ //#endregion
39
+ //#region src/utils.d.ts
40
+ /** A conversion failure, optionally located at a child-index path in the source tree. */
41
+ declare class ConversionError extends Error {
42
+ readonly path: readonly number[];
43
+ /**
44
+ * @param message - Description of the unsupported content or invalid mapping.
45
+ * @param path - Child indexes appended to the message; defaults to the document root.
46
+ */
47
+ constructor(message: string, path?: readonly number[]);
48
+ }
49
+ /**
50
+ * Concatenate a node's descendant text without changing the source.
51
+ * @param node - ProseMirror node to read.
52
+ * @returns Raw text with no added block separators, markup, or hard-break replacement.
53
+ */
54
+ declare const textContent: (node: ContentNode) => string;
55
+ /**
56
+ * Create text content suitable for a node handler.
57
+ * @param text - Literal text to include.
58
+ * @returns One text node, or an empty array for an empty string.
59
+ */
60
+ declare const textNode: (text: string) => ContentNode[];
61
+ /**
62
+ * Append a mark to all descendant text nodes without modifying the input nodes.
63
+ * @param nodes - Content to mark. Existing marks are retained, including duplicates.
64
+ * @param mark - Mark to append to each text node.
65
+ * @returns Mapped nodes; unchanged leaf nodes and existing marks may retain their references.
66
+ */
67
+ declare const withMark: (nodes: ContentNode[], mark: ContentMark) => ContentNode[];
68
+ /**
69
+ * Create an Andesine element node with static JSON properties and a source representation.
70
+ * @param name - Element name, starting with a letter and containing letters, digits, _, ., or -.
71
+ * @param props - Static JSON properties with valid attribute names; executable expressions are rejected.
72
+ * @param content - Child nodes. The supplied content array is retained.
73
+ * @param selfClosing - Whether the source uses a self-closing tag; defaults to true for empty content.
74
+ * @returns A ProseMirror element node for use in import handlers.
75
+ * @throws ConversionError for invalid names, property keys, or non-JSON property values.
76
+ */
77
+ declare const element: (name: string, props: Record<string, unknown>, content: ContentNode[], selfClosing?: boolean) => ContentNode;
78
+ //#endregion
79
+ //#region src/images.d.ts
80
+ interface ImageAsset {
81
+ assetID: string;
82
+ variant: string;
83
+ url: string;
84
+ }
85
+ interface ImageURLOptions {
86
+ /** Variant to resolve, or an async selector for each image. Defaults to "display". */
87
+ variant?: string | ((node: ContentNode) => Awaitable<string>);
88
+ }
89
+ interface PublishedImageContent {
90
+ assets: readonly ImageAsset[];
91
+ }
92
+ /**
93
+ * Create an async imageURL callback from published asset references.
94
+ * @param assets - Assets from the same entry and snapshot as the document being converted.
95
+ * @param options - Image variant or async variant selector. Defaults to "display".
96
+ * @returns A callback that looks up node.attrs.assetID and returns the supplied URL unchanged.
97
+ * It does not fetch images, refresh expiring URLs, or fall back to another variant.
98
+ * @throws ConversionError when the callback cannot find the requested asset and variant.
99
+ */
100
+ declare const createImageURLResolver: (assets: readonly ImageAsset[], options?: ImageURLOptions) => (node: ContentNode) => Promise<string>;
101
+ /**
102
+ * Supply converter options derived from a published-content response or full list item.
103
+ * @param page - An object with the document's published asset references; no SDK type is required.
104
+ * @param options - Image variant settings passed to createImageURLResolver().
105
+ * @returns An imageURL callback only. Title, fragment, and property defaults remain unchanged.
106
+ * Missing asset URLs throw ConversionError when an image is converted, not during this call.
107
+ * @example
108
+ * const html = await toHTML(page.content, { ...publishedContentOptions(page), title: "omit" });
109
+ */
110
+ declare const publishedContentOptions: (page: PublishedImageContent, options?: ImageURLOptions) => {
111
+ imageURL: (node: ContentNode) => Promise<string>;
112
+ };
113
+ //#endregion
114
+ export { type Awaitable, type ContentMark, type ContentNode, ConversionError, type ConvertedAST, type Converter, type ConverterOptions, type DecodeContext, type DecodeHandlers, type EncodeContext, type EncodeHandlers, type ExportConverter, type ExportConverterOptions, type ExportFormatAdapter, type FormatAdapter, type FragmentMapping, type HandlerResult, type HeadingAnchor, type ImageAsset, type ImageReference, type ImageURLOptions, type ImportConverter, type ImportConverterOptions, type ImportFormatAdapter, type PublishedImageContent, createConverter, createExportConverter, createImageURLResolver, createImportConverter, element, getHeadingAnchors, publishedContentOptions, textContent, textNode, withMark };
115
+ //# sourceMappingURL=index.d.ts.map