@inshapardaz/likhari-converters 0.1.45-dev.337 → 0.1.45-dev.340
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/convert/index.d.ts +26 -0
- package/dist/convert/index.d.ts.map +1 -0
- package/dist/convert/index.js +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/markdown/parse.d.ts.map +1 -1
- package/dist/markdown/parse.js +3 -1
- package/dist/markdown/serialize.d.ts.map +1 -1
- package/dist/markdown/serialize.js +9 -2
- package/dist/merge/continuation.d.ts +4 -6
- package/dist/merge/continuation.d.ts.map +1 -1
- package/dist/merge/continuation.js +8 -12
- package/dist/merge/index.js +2 -2
- package/dist/shared/serialized.d.ts +2 -0
- package/dist/shared/serialized.d.ts.map +1 -1
- package/dist/shared/serialized.js +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SerializedEditorState } from 'lexical';
|
|
2
|
+
import { type FormatRegistry } from '../registry.js';
|
|
3
|
+
import type { ConverterContext, FormatId } from '../types.js';
|
|
4
|
+
export interface ConvertContentOptions {
|
|
5
|
+
/** The format `content` is in. */
|
|
6
|
+
inputFormat: FormatId;
|
|
7
|
+
/** The format to write. */
|
|
8
|
+
outputFormat: FormatId;
|
|
9
|
+
/** Passed to the parse and the serialize (image URL resolver and the like). */
|
|
10
|
+
context?: ConverterContext;
|
|
11
|
+
/** Defaults to the registry with all four built-in formats. */
|
|
12
|
+
registry?: FormatRegistry;
|
|
13
|
+
}
|
|
14
|
+
/** Reads `content` and returns it as Lexical state. */
|
|
15
|
+
export declare function convertContentToState(content: string, options: Omit<ConvertContentOptions, 'outputFormat'>): SerializedEditorState;
|
|
16
|
+
/**
|
|
17
|
+
* Converts a document from one format to another through the editor's own parsers and
|
|
18
|
+
* serializers, so the result is exactly what the editor would save in that format. Needs no
|
|
19
|
+
* editor or DOM for Markdown, Lexical JSON and plain text (HTML input uses `DOMParser`).
|
|
20
|
+
*
|
|
21
|
+
* Going to a format that holds less than the input (rich text to plain text, a table to
|
|
22
|
+
* Markdown, ...) degrades the way the format's fidelity matrix says; see
|
|
23
|
+
* `docs/lexical-editor-spec.md` and `docs/markdown-dialect.md`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function convertContent(content: string, options: ConvertContentOptions): string;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/convert/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,WAAW,EAAE,QAAQ,CAAC;IACtB,2BAA2B;IAC3B,YAAY,EAAE,QAAQ,CAAC;IACvB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,GAAG,qBAAqB,CAQlI;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAGtF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defaultFormatRegistry } from '../registry.js';
|
|
2
|
+
/** Reads `content` and returns it as Lexical state. */
|
|
3
|
+
export function convertContentToState(content, options) {
|
|
4
|
+
const { inputFormat, context, registry = defaultFormatRegistry } = options;
|
|
5
|
+
try {
|
|
6
|
+
return registry.parse(inputFormat, content, context);
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
10
|
+
throw new Error(`convertContent: the input is not valid ${inputFormat}: ${reason}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Converts a document from one format to another through the editor's own parsers and
|
|
15
|
+
* serializers, so the result is exactly what the editor would save in that format. Needs no
|
|
16
|
+
* editor or DOM for Markdown, Lexical JSON and plain text (HTML input uses `DOMParser`).
|
|
17
|
+
*
|
|
18
|
+
* Going to a format that holds less than the input (rich text to plain text, a table to
|
|
19
|
+
* Markdown, ...) degrades the way the format's fidelity matrix says; see
|
|
20
|
+
* `docs/lexical-editor-spec.md` and `docs/markdown-dialect.md`.
|
|
21
|
+
*/
|
|
22
|
+
export function convertContent(content, options) {
|
|
23
|
+
const registry = options.registry ?? defaultFormatRegistry;
|
|
24
|
+
return registry.serialize(options.outputFormat, convertContentToState(content, options), options.context);
|
|
25
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { lexicalJsonConverter } from './lexical-json/index.js';
|
|
|
5
5
|
export { markdownConverter } from './markdown/index.js';
|
|
6
6
|
export { htmlConverter } from './html/index.js';
|
|
7
7
|
export { mergePages, mergePagesToState, type MergePagesOptions, type PageInput } from './merge/index.js';
|
|
8
|
+
export { convertContent, convertContentToState, type ConvertContentOptions } from './convert/index.js';
|
|
8
9
|
//# 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,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,3 +5,4 @@ export { lexicalJsonConverter } from './lexical-json/index.js';
|
|
|
5
5
|
export { markdownConverter } from './markdown/index.js';
|
|
6
6
|
export { htmlConverter } from './html/index.js';
|
|
7
7
|
export { mergePages, mergePagesToState } from './merge/index.js';
|
|
8
|
+
export { convertContent, convertContentToState } from './convert/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/markdown/parse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/markdown/parse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAoUjD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,qBAAqB,CAO3F"}
|
package/dist/markdown/parse.js
CHANGED
|
@@ -264,6 +264,8 @@ function blocks(nodes, extra = {}) {
|
|
|
264
264
|
case 'leafDirective': {
|
|
265
265
|
if (node.name === 'pagebreak')
|
|
266
266
|
out.push({ type: 'page-break', version: 1 });
|
|
267
|
+
else if (node.name === 'blank')
|
|
268
|
+
out.push(paragraph());
|
|
267
269
|
else if (node.name === 'figure') {
|
|
268
270
|
const attrs = node.attributes ?? {};
|
|
269
271
|
const src = safeImageSrc(attrs.src ?? '');
|
|
@@ -302,7 +304,7 @@ function restoreUnknownDirectives(node, source) {
|
|
|
302
304
|
node.children = node.children.map((child) => {
|
|
303
305
|
const c = child;
|
|
304
306
|
const unknownText = c.type === 'textDirective' && !KNOWN_TEXT_DIRECTIVES.has(c.name ?? '');
|
|
305
|
-
const unknownLeaf = c.type === 'leafDirective' && c.name !== 'pagebreak' && c.name !== 'figure';
|
|
307
|
+
const unknownLeaf = c.type === 'leafDirective' && c.name !== 'pagebreak' && c.name !== 'blank' && c.name !== 'figure';
|
|
306
308
|
if ((unknownText || unknownLeaf) && c.position?.start.offset !== undefined && c.position.end.offset !== undefined) {
|
|
307
309
|
const raw = source.slice(c.position.start.offset, c.position.end.offset);
|
|
308
310
|
return unknownLeaf ? { type: 'paragraph', children: [{ type: 'text', value: raw }] } : { type: 'text', value: raw };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/markdown/serialize.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAKjD,OAAO,EAAa,KAAK,KAAK,EAAe,MAAM,SAAS,CAAC;AA6C7D,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAWjD;AAqHD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAMhE;AAuJD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/markdown/serialize.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAKjD,OAAO,EAAa,KAAK,KAAK,EAAe,MAAM,SAAS,CAAC;AA6C7D,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAWjD;AAqHD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAMhE;AAuJD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAc9F"}
|
|
@@ -2,7 +2,7 @@ import { unified } from 'unified';
|
|
|
2
2
|
import remarkStringify from 'remark-stringify';
|
|
3
3
|
import remarkGfm from 'remark-gfm';
|
|
4
4
|
import remarkDirective from 'remark-directive';
|
|
5
|
-
import { FORMAT_BOLD, FORMAT_CODE, FORMAT_HIGHLIGHT, FORMAT_ITALIC, FORMAT_STRIKETHROUGH, FORMAT_SUBSCRIPT, FORMAT_SUPERSCRIPT, FORMAT_UNDERLINE, rootChildren, } from '../shared/serialized.js';
|
|
5
|
+
import { FORMAT_BOLD, FORMAT_CODE, FORMAT_HIGHLIGHT, FORMAT_ITALIC, FORMAT_STRIKETHROUGH, FORMAT_SUBSCRIPT, FORMAT_SUPERSCRIPT, FORMAT_UNDERLINE, isEmptyParagraph, rootChildren, } from '../shared/serialized.js';
|
|
6
6
|
import { directive } from './mdast.js';
|
|
7
7
|
import { layoutOrDefault, scaleOrDefault } from '../shared/poetry.js';
|
|
8
8
|
import { nodeToHtml, setFootnoteOrder } from '../html/serialize.js';
|
|
@@ -333,7 +333,14 @@ function blockToMd(node, ctx) {
|
|
|
333
333
|
export function serializeMarkdown(state, ctx) {
|
|
334
334
|
const blocks = rootChildren(state);
|
|
335
335
|
setFootnoteOrder(blocks);
|
|
336
|
-
|
|
336
|
+
// Markdown has no empty paragraph, so a run of them at the end of the document (which marks where a
|
|
337
|
+
// page's last paragraph ends, see mergePages) is written as `::blank` lines to survive a save.
|
|
338
|
+
let end = blocks.length;
|
|
339
|
+
while (end > 0 && (isEmptyParagraph(blocks[end - 1]) || blocks[end - 1].type === 'footnote-list'))
|
|
340
|
+
end -= 1;
|
|
341
|
+
// A document that is nothing but empty paragraphs is still just empty (end === 0).
|
|
342
|
+
const children = blocks.flatMap((n, i) => end > 0 && i >= end && isEmptyParagraph(n) ? [directive('leafDirective', 'blank', {})] : blockToMd(n, ctx));
|
|
343
|
+
const tree = { type: 'root', children };
|
|
337
344
|
// remark-stringify consumes mdast; our MdNode is a structural subset of it.
|
|
338
345
|
return String(processor.stringify(tree)).replace(/\n+$/, '\n').replace(/^\n+$/, '');
|
|
339
346
|
}
|
|
@@ -11,13 +11,11 @@ export declare function endsMidSentence(block: SNode): boolean;
|
|
|
11
11
|
* and alignment. A direction left unset on either side is compatible with anything.
|
|
12
12
|
*/
|
|
13
13
|
export declare function canJoinParagraphs(previous: SNode | undefined, next: SNode | undefined): boolean;
|
|
14
|
-
/** A paragraph with nothing in it: only whitespace and line breaks. */
|
|
15
|
-
export declare function isEmptyParagraph(block: SNode | undefined): boolean;
|
|
16
14
|
/**
|
|
17
|
-
* Whether a page's text ends with an empty line, which marks the end of a paragraph
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* Whether a page's text ends with an empty line, which marks the end of a paragraph: a trailing
|
|
16
|
+
* empty paragraph in the parsed page (Markdown writes one as `::blank`). Markdown written by hand
|
|
17
|
+
* may instead just end with a blank line (`\n\n`, not only a final newline), which the parser
|
|
18
|
+
* would drop, so for Markdown the raw text is checked too.
|
|
21
19
|
*/
|
|
22
20
|
export declare function endsWithBlankLine(rawFormat: string, rawText: string, blocks: SNode[]): boolean;
|
|
23
21
|
/** Appends `next`'s content to `previous` (which is changed), separated by one space unless one is already there. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuation.d.ts","sourceRoot":"","sources":["../../src/merge/continuation.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"continuation.d.ts","sourceRoot":"","sources":["../../src/merge/continuation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAc9E;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGrD;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAM/F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAG9F;AAKD,qHAAqH;AACrH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,CAOjE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { textNode } from '../shared/serialized.js';
|
|
1
|
+
import { isEmptyParagraph, textNode } from '../shared/serialized.js';
|
|
2
2
|
/** Marks that end a sentence, in Urdu and Latin script: ۔ ؟ ! ? . … and the CJK full stop. */
|
|
3
3
|
const SENTENCE_END = /[۔؟!?.…。]/;
|
|
4
4
|
/** Closing quotes and brackets that may follow the mark and still end the sentence: ” ’ " ' ) ] » */
|
|
@@ -38,20 +38,16 @@ export function canJoinParagraphs(previous, next) {
|
|
|
38
38
|
return false;
|
|
39
39
|
return alignment(previous) === alignment(next);
|
|
40
40
|
}
|
|
41
|
-
/** A paragraph with nothing in it: only whitespace and line breaks. */
|
|
42
|
-
export function isEmptyParagraph(block) {
|
|
43
|
-
return !!block && block.type === 'paragraph' && plainText(block).trim() === '';
|
|
44
|
-
}
|
|
45
41
|
/**
|
|
46
|
-
* Whether a page's text ends with an empty line, which marks the end of a paragraph
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
42
|
+
* Whether a page's text ends with an empty line, which marks the end of a paragraph: a trailing
|
|
43
|
+
* empty paragraph in the parsed page (Markdown writes one as `::blank`). Markdown written by hand
|
|
44
|
+
* may instead just end with a blank line (`\n\n`, not only a final newline), which the parser
|
|
45
|
+
* would drop, so for Markdown the raw text is checked too.
|
|
50
46
|
*/
|
|
51
47
|
export function endsWithBlankLine(rawFormat, rawText, blocks) {
|
|
52
|
-
if (
|
|
53
|
-
return
|
|
54
|
-
return
|
|
48
|
+
if (isEmptyParagraph(blocks[blocks.length - 1]))
|
|
49
|
+
return true;
|
|
50
|
+
return rawFormat === 'markdown' && /(\r?\n[ \t]*){2,}$/.test(rawText);
|
|
55
51
|
}
|
|
56
52
|
const startsWithSpace = (children) => /^\s/.test(plainText({ type: 'x', children: children.slice(0, 1) }));
|
|
57
53
|
const endsWithSpace = (children) => /\s$/.test(plainText({ type: 'x', children: children.slice(-1) }));
|
package/dist/merge/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defaultFormatRegistry } from '../registry.js';
|
|
2
|
-
import { elementBase, makeState, rootChildren } from '../shared/serialized.js';
|
|
3
|
-
import { canJoinParagraphs, endsMidSentence, endsWithBlankLine,
|
|
2
|
+
import { elementBase, isEmptyParagraph, makeState, rootChildren } from '../shared/serialized.js';
|
|
3
|
+
import { canJoinParagraphs, endsMidSentence, endsWithBlankLine, joinParagraphs } from './continuation.js';
|
|
4
4
|
/** Parses each page and returns the combined document as Lexical state, without serializing it. */
|
|
5
5
|
export function mergePagesToState(pages, options = {}) {
|
|
6
6
|
const { inputFormat = 'markdown', skipBlankPages = false, joinParagraphs: joinMode, context, registry = defaultFormatRegistry } = options;
|
|
@@ -33,4 +33,6 @@ export declare function isInlineNode(node: SNode): boolean;
|
|
|
33
33
|
* order, among all such nodes. Walks the whole tree once so every converter
|
|
34
34
|
* numbers references and their matching footnote-list entries identically. */
|
|
35
35
|
export declare function collectFootnoteOrder(blocks: SNode[]): Map<string, number>;
|
|
36
|
+
/** A paragraph with nothing in it: no children, or only whitespace and line breaks. */
|
|
37
|
+
export declare function isEmptyParagraph(node: SNode | undefined): boolean;
|
|
36
38
|
//# sourceMappingURL=serialized.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialized.d.ts","sourceRoot":"","sources":["../../src/shared/serialized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,6DAA6D;AAC7D,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;AAE7C,wBAAgB,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,KAAK,EAAE,CAElE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,KAAK,SAAK,GAAG,KAAK,CAEpE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,KAAK,CAEvG;AAED,wBAAgB,SAAS,CAAC,QAAQ,GAAE,KAAK,EAAO,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,KAAK,CAE5F;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAKhE;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAEjD;AAED;;;8EAG8E;AAC9E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzE"}
|
|
1
|
+
{"version":3,"file":"serialized.d.ts","sourceRoot":"","sources":["../../src/shared/serialized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,6DAA6D;AAC7D,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;AAE7C,wBAAgB,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,KAAK,EAAE,CAElE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,KAAK,SAAK,GAAG,KAAK,CAEpE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,KAAK,CAEvG;AAED,wBAAgB,SAAS,CAAC,QAAQ,GAAE,KAAK,EAAO,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,KAAK,CAE5F;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAKhE;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAEjD;AAED;;;8EAG8E;AAC9E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzE;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAMjE"}
|
|
@@ -45,3 +45,9 @@ export function collectFootnoteOrder(blocks) {
|
|
|
45
45
|
blocks.forEach(visit);
|
|
46
46
|
return order;
|
|
47
47
|
}
|
|
48
|
+
/** A paragraph with nothing in it: no children, or only whitespace and line breaks. */
|
|
49
|
+
export function isEmptyParagraph(node) {
|
|
50
|
+
return (!!node &&
|
|
51
|
+
node.type === 'paragraph' &&
|
|
52
|
+
(node.children ?? []).every((child) => (child.type === 'text' ? String(child.text ?? '').trim() === '' : child.type === 'linebreak')));
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inshapardaz/likhari-converters",
|
|
3
|
-
"version": "0.1.45-dev.
|
|
3
|
+
"version": "0.1.45-dev.340",
|
|
4
4
|
"description": "Format transformers (Markdown/HTML/plain-text/Lexical JSON) against the canonical Lexical EditorState, isolated from UI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|