@inshapardaz/likhari-converters 0.1.44 → 0.1.45-dev.334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/merge/index.d.ts +31 -0
- package/dist/merge/index.d.ts.map +1 -0
- package/dist/merge/index.js +65 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export { plainTextConverter } from './plain-text/index.js';
|
|
|
4
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
|
+
export { mergePages, mergePagesToState, type MergePagesOptions, type PageInput } from './merge/index.js';
|
|
7
8
|
//# 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"}
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -4,3 +4,4 @@ export { plainTextConverter } from './plain-text/index.js';
|
|
|
4
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
|
+
export { mergePages, mergePagesToState } from './merge/index.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SerializedEditorState } from 'lexical';
|
|
2
|
+
import { type FormatRegistry } from '../registry.js';
|
|
3
|
+
import type { ConverterContext, FormatId } from '../types.js';
|
|
4
|
+
/** One page: its text, plus its format when that differs from `MergePagesOptions.inputFormat`. */
|
|
5
|
+
export type PageInput = string | {
|
|
6
|
+
content: string;
|
|
7
|
+
format?: FormatId;
|
|
8
|
+
};
|
|
9
|
+
export interface MergePagesOptions {
|
|
10
|
+
/** The format of every page given as a bare string. Defaults to 'markdown'. */
|
|
11
|
+
inputFormat?: FormatId;
|
|
12
|
+
/** The format of the combined document. */
|
|
13
|
+
outputFormat: FormatId;
|
|
14
|
+
/** Passed to every parse and to the final serialize (image URL resolver and the like). */
|
|
15
|
+
context?: ConverterContext;
|
|
16
|
+
/** Defaults to the registry with all four built-in formats. */
|
|
17
|
+
registry?: FormatRegistry;
|
|
18
|
+
}
|
|
19
|
+
/** Parses each page and returns the combined document as Lexical state, without serializing it. */
|
|
20
|
+
export declare function mergePagesToState(pages: PageInput[], options?: Omit<MergePagesOptions, 'outputFormat'>): SerializedEditorState;
|
|
21
|
+
/**
|
|
22
|
+
* Merges pages (Markdown, Lexical JSON, or any other supported format) into one document,
|
|
23
|
+
* with a page break between each pair of pages, in the requested output format. Needs no
|
|
24
|
+
* editor or DOM, so it can run in a server, a worker or a build script.
|
|
25
|
+
*
|
|
26
|
+
* Footnote ids are only unique within a page, so a page whose footnote ids clash with an
|
|
27
|
+
* earlier page's gets them renamed (`1` becomes `1-2`), in references and notes alike; the
|
|
28
|
+
* notes of all pages end up in one list at the end of the document.
|
|
29
|
+
*/
|
|
30
|
+
export declare function mergePages(pages: PageInput[], options: MergePagesOptions): string;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/merge/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;AAG3D,kGAAkG;AAClG,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC;AAExE,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,2CAA2C;IAC3C,YAAY,EAAE,QAAQ,CAAC;IACvB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,mGAAmG;AACnG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAM,GAAG,qBAAqB,CA4BlI;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAGjF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { defaultFormatRegistry } from '../registry.js';
|
|
2
|
+
import { elementBase, makeState, rootChildren } from '../shared/serialized.js';
|
|
3
|
+
/** Parses each page and returns the combined document as Lexical state, without serializing it. */
|
|
4
|
+
export function mergePagesToState(pages, options = {}) {
|
|
5
|
+
const { inputFormat = 'markdown', context, registry = defaultFormatRegistry } = options;
|
|
6
|
+
const body = [];
|
|
7
|
+
const footnotes = [];
|
|
8
|
+
const takenFootnoteIds = new Set();
|
|
9
|
+
pages.forEach((page, index) => {
|
|
10
|
+
const { content, format = inputFormat } = typeof page === 'string' ? { content: page } : page;
|
|
11
|
+
let blocks;
|
|
12
|
+
try {
|
|
13
|
+
blocks = structuredClone(rootChildren(registry.parse(format, content, context)));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
17
|
+
throw new Error(`mergePages: page ${index + 1} is not valid ${format}: ${reason}`);
|
|
18
|
+
}
|
|
19
|
+
// Each page brings its own footnote list; they are combined into one at the end.
|
|
20
|
+
const pageLists = blocks.filter((block) => block.type === 'footnote-list');
|
|
21
|
+
const pageBody = blocks.filter((block) => block.type !== 'footnote-list');
|
|
22
|
+
uniquifyFootnoteIds([...pageBody, ...pageLists], takenFootnoteIds);
|
|
23
|
+
for (const list of pageLists)
|
|
24
|
+
footnotes.push(...(list.children ?? []));
|
|
25
|
+
if (index > 0)
|
|
26
|
+
body.push({ type: 'page-break', version: 1 });
|
|
27
|
+
body.push(...pageBody);
|
|
28
|
+
});
|
|
29
|
+
return makeState(footnotes.length > 0 ? [...body, elementBase('footnote-list', footnotes)] : body);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Merges pages (Markdown, Lexical JSON, or any other supported format) into one document,
|
|
33
|
+
* with a page break between each pair of pages, in the requested output format. Needs no
|
|
34
|
+
* editor or DOM, so it can run in a server, a worker or a build script.
|
|
35
|
+
*
|
|
36
|
+
* Footnote ids are only unique within a page, so a page whose footnote ids clash with an
|
|
37
|
+
* earlier page's gets them renamed (`1` becomes `1-2`), in references and notes alike; the
|
|
38
|
+
* notes of all pages end up in one list at the end of the document.
|
|
39
|
+
*/
|
|
40
|
+
export function mergePages(pages, options) {
|
|
41
|
+
const registry = options.registry ?? defaultFormatRegistry;
|
|
42
|
+
return registry.serialize(options.outputFormat, mergePagesToState(pages, options), options.context);
|
|
43
|
+
}
|
|
44
|
+
/** Renames this page's footnote ids that an earlier page already uses, then claims all its ids. */
|
|
45
|
+
function uniquifyFootnoteIds(blocks, taken) {
|
|
46
|
+
const nodes = [];
|
|
47
|
+
const collect = (node) => {
|
|
48
|
+
if (typeof node.footnoteId === 'string')
|
|
49
|
+
nodes.push(node);
|
|
50
|
+
(node.children ?? []).forEach(collect);
|
|
51
|
+
};
|
|
52
|
+
blocks.forEach(collect);
|
|
53
|
+
const renamed = new Map();
|
|
54
|
+
for (const node of nodes) {
|
|
55
|
+
const id = node.footnoteId;
|
|
56
|
+
if (!renamed.has(id)) {
|
|
57
|
+
let next = id;
|
|
58
|
+
for (let n = 2; taken.has(next); n += 1)
|
|
59
|
+
next = `${id}-${n}`;
|
|
60
|
+
renamed.set(id, next);
|
|
61
|
+
}
|
|
62
|
+
node.footnoteId = renamed.get(id);
|
|
63
|
+
}
|
|
64
|
+
renamed.forEach((id) => taken.add(id));
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inshapardaz/likhari-converters",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45-dev.334",
|
|
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": {
|