@lpdfio/lpdf 0.6.0 → 0.7.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 +32 -39
- package/dist/_shared.d.ts +3 -6
- package/dist/browser.js +21 -62
- package/dist/canvas.d.ts +8 -6
- package/dist/canvas.js +13 -13
- package/dist/engine.d.ts +16 -13
- package/dist/engine.js +23 -23
- package/dist/index.d.ts +9 -45
- package/dist/index.js +12 -32
- package/dist/kit-to-xml.d.ts +2 -2
- package/dist/kit.d.ts +7 -16
- package/dist/kit.js +12 -12
- package/dist/layout.d.ts +35 -34
- package/dist/layout.js +43 -43
- package/dist/pdf.d.ts +61 -0
- package/dist/pdf.js +70 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# @lpdfio/lpdf
|
|
4
4
|
|
|
5
|
-
Node.js
|
|
5
|
+
**Node.js SDK for [Lpdf](https://lpdf.io) — PDF as Code on every platform**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
You describe a document as code or XML. Lpdf renders a compact, pixel-perfect PDF — identical across platforms.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -15,48 +15,41 @@ npm install @lpdfio/lpdf
|
|
|
15
15
|
## Usage — Node.js
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
import { L, NoAttr } from 'lpdf'
|
|
19
|
+
|
|
20
|
+
const engine = L.engine()
|
|
21
|
+
|
|
22
|
+
const doc = L.document({ size: 'letter', margin: '48pt' }, [
|
|
23
|
+
L.section(NoAttr, [
|
|
24
|
+
L.layout(NoAttr, [
|
|
25
|
+
L.stack({ gap: '24pt' }, [
|
|
26
|
+
L.split(NoAttr, [
|
|
27
|
+
L.text({ fontSize: '8pt', color: '#888888' }, ['ACME CORP']),
|
|
28
|
+
L.text({ fontSize: '22pt', bold: 'true' }, ['Project Proposal']),
|
|
29
|
+
]),
|
|
30
|
+
L.divider({ thickness: 'xs' }),
|
|
31
|
+
L.text({ fontSize: '13pt', bold: 'true' }, ['Scope of Work']),
|
|
32
|
+
L.flank({ gap: '12pt', align: 'start' }, [
|
|
33
|
+
L.text({ color: '#888888', width: '24pt' }, ['01']),
|
|
34
|
+
L.text(NoAttr, ['Discovery & Research']),
|
|
35
|
+
]),
|
|
36
|
+
]),
|
|
37
|
+
]),
|
|
38
|
+
]),
|
|
39
|
+
])
|
|
40
|
+
|
|
41
|
+
const pdf = await engine.render(doc)
|
|
30
42
|
```
|
|
31
43
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
import { LpdfEngine } from '@lpdfio/lpdf/browser';
|
|
44
|
+
## Requirements
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
- Node.js 16+
|
|
47
|
+
- No external runtime dependencies — the WASM engine is embedded in the package.
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
const pdf = await engine.renderPdf(xml);
|
|
49
|
+
## Docs
|
|
41
50
|
|
|
42
|
-
|
|
43
|
-
window.open(URL.createObjectURL(blob));
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## XML format
|
|
47
|
-
|
|
48
|
-
Documents are defined in a layout XML format. See the [Lpdf documentation](https://lpdf.io/docs) and [examples](https://github.com/lpdfio/lpdf/tree/main/docs/examples) for the full schema.
|
|
49
|
-
|
|
50
|
-
```xml
|
|
51
|
-
<stack spacing="m" padding="l">
|
|
52
|
-
<text font-size="xl" font="Montserrat-Bold">Invoice #1001</text>
|
|
53
|
-
<grid columns="2">
|
|
54
|
-
<text>Date</text> <text>2026-04-25</text>
|
|
55
|
-
<text>Due</text> <text>2026-05-25</text>
|
|
56
|
-
</grid>
|
|
57
|
-
</stack>
|
|
58
|
-
```
|
|
51
|
+
[lpdf.io/docs/js](https://lpdf.io/docs/js)
|
|
59
52
|
|
|
60
|
-
|
|
53
|
+
--
|
|
61
54
|
|
|
62
55
|
Dual-licensed: Community License (free) and Commercial License (paid). See [LICENSE](LICENSE) for full terms.
|
package/dist/_shared.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared types used by both the Node.js and browser entry points.
|
|
3
3
|
*/
|
|
4
|
+
/** Construction-time configuration for {@link PdfEngine}. Node has no infra options. */
|
|
5
|
+
export interface EngineOptions {
|
|
6
|
+
}
|
|
4
7
|
export interface RenderOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Pre-loaded font bytes for custom fonts referenced via <fonts src="…">.
|
|
7
|
-
* Keys are the font names used in the document; values are raw TTF/OTF bytes.
|
|
8
|
-
* @deprecated Pass font bytes via `LpdfEngine.loadFont()` instead.
|
|
9
|
-
*/
|
|
10
|
-
fontBytes?: Record<string, Uint8Array>;
|
|
11
8
|
/**
|
|
12
9
|
* Optional ISO 8601 creation timestamp (e.g. `"2024-06-01T12:00:00"`).
|
|
13
10
|
* When provided, written as `/CreationDate` in the PDF info dictionary.
|
package/dist/browser.js
CHANGED
|
@@ -378,63 +378,12 @@ async function __wbg_init(module_or_path) {
|
|
|
378
378
|
return __wbg_finalize_init(instance, module);
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
// src/kit.ts
|
|
382
|
-
function attrKey(camel) {
|
|
383
|
-
return camel.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());
|
|
384
|
-
}
|
|
385
|
-
function buildAttrs(options) {
|
|
386
|
-
const result = {};
|
|
387
|
-
for (const [key, val] of Object.entries(options)) {
|
|
388
|
-
if (val !== void 0) {
|
|
389
|
-
result[attrKey(key)] = val;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
return result;
|
|
393
|
-
}
|
|
394
|
-
function layout(nodes = []) {
|
|
395
|
-
return { type: "layout", nodes };
|
|
396
|
-
}
|
|
397
|
-
function canvas(layers = []) {
|
|
398
|
-
return { type: "canvas", nodes: layers };
|
|
399
|
-
}
|
|
400
|
-
function section(input = {}) {
|
|
401
|
-
return {
|
|
402
|
-
type: "section",
|
|
403
|
-
attrs: buildAttrs(input.options ?? {}),
|
|
404
|
-
nodes: input.nodes ?? []
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
function document(input = {}) {
|
|
408
|
-
const { tokens, meta, ...restOpts } = input.options ?? {};
|
|
409
|
-
const attrs = {
|
|
410
|
-
...buildAttrs(restOpts)
|
|
411
|
-
};
|
|
412
|
-
if (tokens !== void 0) attrs["tokens"] = tokens;
|
|
413
|
-
if (meta !== void 0) attrs["meta"] = meta;
|
|
414
|
-
return {
|
|
415
|
-
version: 1,
|
|
416
|
-
type: "document",
|
|
417
|
-
attrs,
|
|
418
|
-
nodes: input.sections ?? []
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
var LpdfKit = Object.freeze({
|
|
422
|
-
layout,
|
|
423
|
-
canvas,
|
|
424
|
-
section,
|
|
425
|
-
document
|
|
426
|
-
});
|
|
427
|
-
|
|
428
381
|
// src/browser.ts
|
|
429
|
-
|
|
382
|
+
var NoAttr = null;
|
|
383
|
+
async function initLpdf(wasmSource, licenseKey = "") {
|
|
430
384
|
await __wbg_init(wasmSource);
|
|
431
385
|
const fontMap = /* @__PURE__ */ new Map();
|
|
432
386
|
const imageMap = /* @__PURE__ */ new Map();
|
|
433
|
-
if (initOptions.fontBytes) {
|
|
434
|
-
for (const [name, bytes] of Object.entries(initOptions.fontBytes)) {
|
|
435
|
-
fontMap.set(name, bytes);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
387
|
return {
|
|
439
388
|
loadFont(name, bytes) {
|
|
440
389
|
fontMap.set(name, bytes);
|
|
@@ -442,27 +391,37 @@ async function initLpdf(wasmSource, licenseKey = "", initOptions = {}) {
|
|
|
442
391
|
loadImage(name, bytes) {
|
|
443
392
|
imageMap.set(name, bytes);
|
|
444
393
|
},
|
|
445
|
-
async
|
|
394
|
+
async render(input, callOptions = {}) {
|
|
446
395
|
const engine = new LpdfEngine(licenseKey);
|
|
447
396
|
for (const [name, bytes] of fontMap) {
|
|
448
397
|
engine.load_font(name, bytes);
|
|
449
398
|
}
|
|
450
|
-
if (callOptions.fontBytes) {
|
|
451
|
-
for (const [name, bytes] of Object.entries(callOptions.fontBytes)) {
|
|
452
|
-
if (!fontMap.has(name)) engine.load_font(name, bytes);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
399
|
for (const [name, bytes] of imageMap) {
|
|
456
400
|
engine.load_image(name, bytes);
|
|
457
401
|
}
|
|
458
|
-
|
|
459
|
-
|
|
402
|
+
if (callOptions.createdOn) {
|
|
403
|
+
engine.set_created_on(callOptions.createdOn);
|
|
404
|
+
}
|
|
405
|
+
let pdf;
|
|
406
|
+
if (typeof input === "string") {
|
|
407
|
+
const dataJson = callOptions.data != null ? JSON.stringify(callOptions.data) : null;
|
|
408
|
+
pdf = engine.render_pdf(input, dataJson);
|
|
409
|
+
} else {
|
|
410
|
+
const wasmExt = engine;
|
|
411
|
+
if (typeof wasmExt.render_tree_pdf === "function") {
|
|
412
|
+
pdf = wasmExt.render_tree_pdf(JSON.stringify(input));
|
|
413
|
+
} else {
|
|
414
|
+
const mod = engine;
|
|
415
|
+
const xml = mod.constructor.kit_to_xml?.(JSON.stringify(input)) ?? "";
|
|
416
|
+
pdf = engine.render_pdf(xml, null);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
460
419
|
engine.free();
|
|
461
420
|
return pdf;
|
|
462
421
|
}
|
|
463
422
|
};
|
|
464
423
|
}
|
|
465
424
|
export {
|
|
466
|
-
|
|
425
|
+
NoAttr,
|
|
467
426
|
initLpdf
|
|
468
427
|
};
|
package/dist/canvas.d.ts
CHANGED
|
@@ -100,7 +100,9 @@ export interface LpdfCanvasImgNode {
|
|
|
100
100
|
attrs: Record<string, string>;
|
|
101
101
|
}
|
|
102
102
|
export type LpdfCanvasPrimitiveNode = LpdfCanvasRectNode | LpdfCanvasLineNode | LpdfCanvasEllipseNode | LpdfCanvasCircleNode | LpdfCanvasPathNode | LpdfCanvasTextNode | LpdfCanvasImgNode;
|
|
103
|
-
|
|
103
|
+
/** @deprecated Use {@link LayerAttr} */
|
|
104
|
+
export type CanvasLayerOptions = LayerAttr;
|
|
105
|
+
export interface LayerAttr {
|
|
104
106
|
page?: PageScope | string;
|
|
105
107
|
opacity?: number;
|
|
106
108
|
transform?: CanvasTransform;
|
|
@@ -115,17 +117,17 @@ declare function line(x1: number, y1: number, x2: number, y2: number, style?: Ca
|
|
|
115
117
|
declare function ellipse(cx: number, cy: number, rx: number, ry: number, style?: CanvasEllipseStyle): LpdfCanvasEllipseNode;
|
|
116
118
|
declare function circle(cx: number, cy: number, r: number, style?: CanvasEllipseStyle): LpdfCanvasCircleNode;
|
|
117
119
|
declare function path(d: string, style?: CanvasPathStyle): LpdfCanvasPathNode;
|
|
118
|
-
declare function
|
|
119
|
-
declare function
|
|
120
|
-
declare function layer(nodes: LpdfCanvasPrimitiveNode[]
|
|
120
|
+
declare function textAt(x: number, y: number, content: string, style?: CanvasTextStyle, runs?: CanvasRun[]): LpdfCanvasTextNode;
|
|
121
|
+
declare function imgAt(x: number, y: number, w: number, h: number, name: string): LpdfCanvasImgNode;
|
|
122
|
+
declare function layer(attrs: LayerAttr | null, nodes: LpdfCanvasPrimitiveNode[]): LpdfCanvasLayerNode;
|
|
121
123
|
export declare const LpdfCanvas: Readonly<{
|
|
122
124
|
rect: typeof rect;
|
|
123
125
|
line: typeof line;
|
|
124
126
|
ellipse: typeof ellipse;
|
|
125
127
|
circle: typeof circle;
|
|
126
128
|
path: typeof path;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
textAt: typeof textAt;
|
|
130
|
+
imgAt: typeof imgAt;
|
|
129
131
|
layer: typeof layer;
|
|
130
132
|
}>;
|
|
131
133
|
export {};
|
package/dist/canvas.js
CHANGED
|
@@ -124,7 +124,7 @@ function path(d, style) {
|
|
|
124
124
|
attrs['line-join'] = style.lineJoin;
|
|
125
125
|
return { type: 'canvas-path', attrs };
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function textAt(x, y, content, style, runs) {
|
|
128
128
|
const attrs = { x: String(x), y: String(y) };
|
|
129
129
|
if (style?.font !== undefined)
|
|
130
130
|
attrs['font'] = style.font;
|
|
@@ -153,21 +153,21 @@ function canvasText(x, y, content, style, runs) {
|
|
|
153
153
|
}
|
|
154
154
|
return node;
|
|
155
155
|
}
|
|
156
|
-
function
|
|
156
|
+
function imgAt(x, y, w, h, name) {
|
|
157
157
|
return {
|
|
158
158
|
type: 'canvas-img',
|
|
159
159
|
attrs: { x: String(x), y: String(y), w: String(w), h: String(h), name },
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
|
-
function layer(
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
return { type: 'canvas-layer', attrs, nodes };
|
|
162
|
+
function layer(attrs, nodes) {
|
|
163
|
+
const a = {};
|
|
164
|
+
if (attrs?.page !== undefined)
|
|
165
|
+
a['page'] = attrs.page;
|
|
166
|
+
if (attrs?.opacity !== undefined)
|
|
167
|
+
a['opacity'] = String(attrs.opacity);
|
|
168
|
+
if (attrs?.transform !== undefined)
|
|
169
|
+
a['transform'] = attrs.transform.toString();
|
|
170
|
+
return { type: 'canvas-layer', attrs: a, nodes };
|
|
171
171
|
}
|
|
172
172
|
exports.LpdfCanvas = Object.freeze({
|
|
173
173
|
rect,
|
|
@@ -175,7 +175,7 @@ exports.LpdfCanvas = Object.freeze({
|
|
|
175
175
|
ellipse,
|
|
176
176
|
circle,
|
|
177
177
|
path,
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
textAt,
|
|
179
|
+
imgAt,
|
|
180
180
|
layer,
|
|
181
181
|
});
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RenderOptions } from './_shared';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PdfDocument } from './kit';
|
|
3
3
|
/** Thrown when the lpdf engine returns a layout or parse error. */
|
|
4
4
|
export declare class LpdfRenderError extends Error {
|
|
5
5
|
constructor(message: string);
|
|
@@ -15,7 +15,7 @@ export interface EncryptPermissions {
|
|
|
15
15
|
assemble?: boolean;
|
|
16
16
|
print_hq?: boolean;
|
|
17
17
|
}
|
|
18
|
-
/** RC4-128 encryption options passed to {@link
|
|
18
|
+
/** RC4-128 encryption options passed to {@link PdfEngine.setEncryption}. */
|
|
19
19
|
export interface EncryptOptions {
|
|
20
20
|
/** Open password shown to readers. Empty string = no open password required. */
|
|
21
21
|
userPassword: string;
|
|
@@ -24,26 +24,29 @@ export interface EncryptOptions {
|
|
|
24
24
|
/** Permission flags applied to the document. Omitted flags default to `true`. */
|
|
25
25
|
permissions?: EncryptPermissions;
|
|
26
26
|
}
|
|
27
|
-
export declare class
|
|
28
|
-
private
|
|
29
|
-
private readonly _opts;
|
|
27
|
+
export declare class PdfEngine {
|
|
28
|
+
private _licenseKey;
|
|
30
29
|
private readonly _fonts;
|
|
31
30
|
private readonly _images;
|
|
32
31
|
private _disposed;
|
|
33
32
|
private _encrypt;
|
|
34
|
-
constructor(
|
|
33
|
+
constructor();
|
|
34
|
+
/**
|
|
35
|
+
* Set the license key. Returns `this` for chaining.
|
|
36
|
+
*/
|
|
37
|
+
setLicenseKey(key: string): this;
|
|
35
38
|
/**
|
|
36
39
|
* Register raw TTF/OTF bytes for a custom font name used in `<font src="…">`.
|
|
37
|
-
* Call before `
|
|
40
|
+
* Call before `render`. Returns `this` for chaining.
|
|
38
41
|
*/
|
|
39
42
|
loadFont(name: string, bytes: Uint8Array): this;
|
|
40
43
|
/**
|
|
41
44
|
* Register raw image bytes (PNG or JPEG) for an image name used in `<img name="…">`.
|
|
42
|
-
* Call before `
|
|
45
|
+
* Call before `render`. Returns `this` for chaining.
|
|
43
46
|
*/
|
|
44
47
|
loadImage(name: string, bytes: Uint8Array): this;
|
|
45
48
|
/**
|
|
46
|
-
* Configure RC4-128 encryption for all subsequent `
|
|
49
|
+
* Configure RC4-128 encryption for all subsequent `render` calls.
|
|
47
50
|
* Returns `this` for chaining.
|
|
48
51
|
*/
|
|
49
52
|
setEncryption(options: EncryptOptions): this;
|
|
@@ -53,7 +56,7 @@ export declare class LpdfEngine {
|
|
|
53
56
|
*/
|
|
54
57
|
clearEncryption(): this;
|
|
55
58
|
/**
|
|
56
|
-
* Release held resources. Idempotent. Subsequent `
|
|
59
|
+
* Release held resources. Idempotent. Subsequent `render` / `loadFont`
|
|
57
60
|
* calls after disposal will throw.
|
|
58
61
|
*/
|
|
59
62
|
dispose(): void;
|
|
@@ -62,9 +65,9 @@ export declare class LpdfEngine {
|
|
|
62
65
|
/**
|
|
63
66
|
* Render an lpdf XML string to PDF bytes (Node.js).
|
|
64
67
|
*/
|
|
65
|
-
|
|
68
|
+
render(input: string, callOptions?: RenderOptions): Promise<Uint8Array>;
|
|
66
69
|
/**
|
|
67
|
-
* Render
|
|
70
|
+
* Render a `PdfDocument` tree (built with `Pdf.document`) to PDF bytes (Node.js).
|
|
68
71
|
*/
|
|
69
|
-
|
|
72
|
+
render(input: PdfDocument, callOptions?: RenderOptions): Promise<Uint8Array>;
|
|
70
73
|
}
|
package/dist/engine.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PdfEngine = exports.LpdfRenderError = void 0;
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
5
|
// require() path is relative to the compiled output at dist/engine.js.
|
|
6
6
|
// In the published package, wasm-pack artifacts live in dist/wasm/.
|
|
@@ -16,18 +16,25 @@ class LpdfRenderError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
exports.LpdfRenderError = LpdfRenderError;
|
|
19
|
-
class
|
|
20
|
-
constructor(
|
|
19
|
+
class PdfEngine {
|
|
20
|
+
constructor() {
|
|
21
|
+
this._licenseKey = '';
|
|
21
22
|
this._fonts = new Map();
|
|
22
23
|
this._images = new Map();
|
|
23
24
|
this._disposed = false;
|
|
24
25
|
this._encrypt = null;
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Set the license key. Returns `this` for chaining.
|
|
29
|
+
*/
|
|
30
|
+
setLicenseKey(key) {
|
|
31
|
+
this._throwIfDisposed();
|
|
32
|
+
this._licenseKey = key;
|
|
33
|
+
return this;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Register raw TTF/OTF bytes for a custom font name used in `<font src="…">`.
|
|
30
|
-
* Call before `
|
|
37
|
+
* Call before `render`. Returns `this` for chaining.
|
|
31
38
|
*/
|
|
32
39
|
loadFont(name, bytes) {
|
|
33
40
|
this._throwIfDisposed();
|
|
@@ -36,7 +43,7 @@ class LpdfEngine {
|
|
|
36
43
|
}
|
|
37
44
|
/**
|
|
38
45
|
* Register raw image bytes (PNG or JPEG) for an image name used in `<img name="…">`.
|
|
39
|
-
* Call before `
|
|
46
|
+
* Call before `render`. Returns `this` for chaining.
|
|
40
47
|
*/
|
|
41
48
|
loadImage(name, bytes) {
|
|
42
49
|
this._throwIfDisposed();
|
|
@@ -44,7 +51,7 @@ class LpdfEngine {
|
|
|
44
51
|
return this;
|
|
45
52
|
}
|
|
46
53
|
/**
|
|
47
|
-
* Configure RC4-128 encryption for all subsequent `
|
|
54
|
+
* Configure RC4-128 encryption for all subsequent `render` calls.
|
|
48
55
|
* Returns `this` for chaining.
|
|
49
56
|
*/
|
|
50
57
|
setEncryption(options) {
|
|
@@ -62,7 +69,7 @@ class LpdfEngine {
|
|
|
62
69
|
return this;
|
|
63
70
|
}
|
|
64
71
|
/**
|
|
65
|
-
* Release held resources. Idempotent. Subsequent `
|
|
72
|
+
* Release held resources. Idempotent. Subsequent `render` / `loadFont`
|
|
66
73
|
* calls after disposal will throw.
|
|
67
74
|
*/
|
|
68
75
|
dispose() {
|
|
@@ -71,28 +78,20 @@ class LpdfEngine {
|
|
|
71
78
|
[Symbol.dispose]() { this.dispose(); }
|
|
72
79
|
_throwIfDisposed() {
|
|
73
80
|
if (this._disposed)
|
|
74
|
-
throw new Error('
|
|
81
|
+
throw new Error('PdfEngine has been disposed.');
|
|
75
82
|
}
|
|
76
|
-
async
|
|
83
|
+
async render(input, callOptions = {}) {
|
|
77
84
|
this._throwIfDisposed();
|
|
78
|
-
// Merge fonts: instance-level loadFont() calls take precedence over the
|
|
79
|
-
// deprecated fontBytes option, which is kept for one-version compat.
|
|
80
|
-
const allFonts = new Map(this._fonts);
|
|
81
|
-
const extraBytes = { ...this._opts.fontBytes, ...callOptions.fontBytes };
|
|
82
|
-
for (const [name, bytes] of Object.entries(extraBytes)) {
|
|
83
|
-
if (!allFonts.has(name))
|
|
84
|
-
allFonts.set(name, bytes);
|
|
85
|
-
}
|
|
86
85
|
const engine = new WasmEngine(this._licenseKey);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
engine.set_created_on(createdOn);
|
|
86
|
+
if (callOptions.createdOn) {
|
|
87
|
+
engine.set_created_on(callOptions.createdOn);
|
|
90
88
|
}
|
|
91
89
|
let pdf;
|
|
92
90
|
try {
|
|
93
91
|
if (typeof input === 'string') {
|
|
94
92
|
// XML path — auto-load fonts and images declared via src="…".
|
|
95
93
|
const xml = input;
|
|
94
|
+
const allFonts = new Map(this._fonts);
|
|
96
95
|
for (const [key, src] of extractAssetSrcs(xml, 'font')) {
|
|
97
96
|
if (!allFonts.has(key)) {
|
|
98
97
|
try {
|
|
@@ -126,6 +125,7 @@ class LpdfEngine {
|
|
|
126
125
|
else {
|
|
127
126
|
// JSON (Kit tree) path — pass JSON directly to render_tree_pdf.
|
|
128
127
|
const json = JSON.stringify(input);
|
|
128
|
+
const allFonts = new Map(this._fonts);
|
|
129
129
|
for (const [key, src] of extractFontSrcsFromJson(json)) {
|
|
130
130
|
if (!allFonts.has(key)) {
|
|
131
131
|
try {
|
|
@@ -156,7 +156,7 @@ class LpdfEngine {
|
|
|
156
156
|
return pdf;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
exports.
|
|
159
|
+
exports.PdfEngine = PdfEngine;
|
|
160
160
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
161
161
|
/** Extract `ref??name → src` pairs from `<font>` or `<image>` tags in XML. */
|
|
162
162
|
function extractAssetSrcs(xml, tag) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,45 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export {
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
Kit: Readonly<{
|
|
11
|
-
layout: (nodes?: import("./layout").LpdfNode[]) => import("./kit").LpdfLayoutBlock;
|
|
12
|
-
canvas: (layers?: import("./canvas").LpdfCanvasLayerNode[]) => import("./kit").LpdfCanvasBlock;
|
|
13
|
-
section: (input?: import("./kit").SectionInput) => import("./kit").LpdfSectionNode;
|
|
14
|
-
document: (input?: import("./kit").DocumentInput) => import("./kit").LpdfDocument;
|
|
15
|
-
}>;
|
|
16
|
-
Layout: Readonly<{
|
|
17
|
-
stack: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").StackOptions) => import("./layout").LpdfContainerNode;
|
|
18
|
-
flank: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").FlankOptions) => import("./layout").LpdfContainerNode;
|
|
19
|
-
split: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").SplitOptions) => import("./layout").LpdfContainerNode;
|
|
20
|
-
cluster: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").ClusterOptions) => import("./layout").LpdfContainerNode;
|
|
21
|
-
grid: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").GridOptions) => import("./layout").LpdfContainerNode;
|
|
22
|
-
frame: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").FrameOptions) => import("./layout").LpdfContainerNode;
|
|
23
|
-
link: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").LinkOptions) => import("./layout").LpdfContainerNode;
|
|
24
|
-
text: (nodes?: (string | import("./layout").LpdfSpanNode)[], options?: import("./layout").TextOptions) => import("./layout").LpdfTextNode;
|
|
25
|
-
span: (nodes?: string[], options?: import("./layout").SpanOptions) => import("./layout").LpdfSpanNode;
|
|
26
|
-
divider: (options?: import("./layout").DividerOptions) => import("./layout").LpdfDividerNode;
|
|
27
|
-
img: (options: import("./layout").ImgOptions) => import("./layout").LpdfImgNode;
|
|
28
|
-
barcode: (options: import("./layout").BarcodeOptions) => import("./layout").LpdfBarcodeNode;
|
|
29
|
-
table: (options: import("./layout").TableOptions, nodes?: (import("./layout").LpdfTheadNode | import("./layout").LpdfTrNode)[]) => import("./layout").LpdfTableNode;
|
|
30
|
-
thead: (nodes?: import("./layout").LpdfTdNode[], options?: import("./layout").TheadOptions) => import("./layout").LpdfTheadNode;
|
|
31
|
-
tr: (nodes?: import("./layout").LpdfTdNode[], options?: import("./layout").TrOptions) => import("./layout").LpdfTrNode;
|
|
32
|
-
td: (nodes?: import("./layout").LpdfNode[], options?: import("./layout").TdOptions) => import("./layout").LpdfTdNode;
|
|
33
|
-
region: (pin: string, nodes?: import("./layout").LpdfNode[], options?: import("./layout").RegionOptions) => import("./layout").LpdfRegionNode;
|
|
34
|
-
}>;
|
|
35
|
-
Canvas: Readonly<{
|
|
36
|
-
rect: (x: number, y: number, w: number, h: number, style?: import("./canvas").CanvasRectStyle) => import("./canvas").LpdfCanvasRectNode;
|
|
37
|
-
line: (x1: number, y1: number, x2: number, y2: number, style?: import("./canvas").CanvasLineStyle) => import("./canvas").LpdfCanvasLineNode;
|
|
38
|
-
ellipse: (cx: number, cy: number, rx: number, ry: number, style?: import("./canvas").CanvasEllipseStyle) => import("./canvas").LpdfCanvasEllipseNode;
|
|
39
|
-
circle: (cx: number, cy: number, r: number, style?: import("./canvas").CanvasEllipseStyle) => import("./canvas").LpdfCanvasCircleNode;
|
|
40
|
-
path: (d: string, style?: import("./canvas").CanvasPathStyle) => import("./canvas").LpdfCanvasPathNode;
|
|
41
|
-
text: (x: number, y: number, content: string, style?: import("./canvas").CanvasTextStyle, runs?: import("./canvas").CanvasRun[]) => import("./canvas").LpdfCanvasTextNode;
|
|
42
|
-
img: (x: number, y: number, w: number, h: number, name: string) => import("./canvas").LpdfCanvasImgNode;
|
|
43
|
-
layer: (nodes: import("./canvas").LpdfCanvasPrimitiveNode[], options?: import("./canvas").CanvasLayerOptions) => import("./canvas").LpdfCanvasLayerNode;
|
|
44
|
-
}>;
|
|
45
|
-
}>;
|
|
1
|
+
export { PdfEngine, LpdfRenderError } from './engine';
|
|
2
|
+
export type { EncryptPermissions, EncryptOptions } from './engine';
|
|
3
|
+
export type { RenderOptions, EngineOptions, PageScope } from './_shared';
|
|
4
|
+
export type { PdfDocument, LpdfSectionNode, LpdfLayoutBlock, LpdfCanvasBlock, LpdfTokens, LpdfFontDef, LpdfMeta, SectionAttr, DocumentAttr, } from './kit';
|
|
5
|
+
export type { StackAttr, FlankAttr, SplitAttr, ClusterAttr, GridAttr, FrameAttr, LinkAttr, TableAttr, TheadAttr, TrAttr, TdAttr, TextAttr, SpanAttr, DividerAttr, ImgAttr, BarcodeAttr, RegionAttr, } from './layout';
|
|
6
|
+
export type { LpdfNode, LpdfContainerNode, LpdfTextNode, LpdfSpanNode, LpdfDividerNode, LpdfImgNode, LpdfBarcodeNode, LpdfTableNode, LpdfTheadNode, LpdfTrNode, LpdfTdNode, LpdfRegionNode, } from './layout';
|
|
7
|
+
export { CanvasTransform } from './canvas';
|
|
8
|
+
export type { LineCap, LineJoin, TextAlign, LayerAttr, CanvasRun, CanvasRectStyle, CanvasLineStyle, CanvasEllipseStyle, CanvasPathStyle, CanvasTextStyle, LpdfCanvasLayerNode, LpdfCanvasPrimitiveNode, LpdfCanvasRectNode, LpdfCanvasLineNode, LpdfCanvasEllipseNode, LpdfCanvasCircleNode, LpdfCanvasPathNode, LpdfCanvasTextNode, LpdfCanvasImgNode, } from './canvas';
|
|
9
|
+
export { L, NoAttr } from './pdf';
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
Object.defineProperty(exports, "
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
exports.Lpdf = Object.freeze({
|
|
30
|
-
Engine: engine_1.LpdfEngine,
|
|
31
|
-
Kit: kit_1.LpdfKit,
|
|
32
|
-
Layout: layout_1.LpdfLayout,
|
|
33
|
-
Canvas: canvas_1.LpdfCanvas,
|
|
34
|
-
});
|
|
3
|
+
exports.NoAttr = exports.L = exports.CanvasTransform = exports.LpdfRenderError = exports.PdfEngine = void 0;
|
|
4
|
+
// ── Engine ────────────────────────────────────────────────────────────────────
|
|
5
|
+
var engine_1 = require("./engine");
|
|
6
|
+
Object.defineProperty(exports, "PdfEngine", { enumerable: true, get: function () { return engine_1.PdfEngine; } });
|
|
7
|
+
Object.defineProperty(exports, "LpdfRenderError", { enumerable: true, get: function () { return engine_1.LpdfRenderError; } });
|
|
8
|
+
// ── Canvas types ──────────────────────────────────────────────────────────────
|
|
9
|
+
var canvas_1 = require("./canvas");
|
|
10
|
+
Object.defineProperty(exports, "CanvasTransform", { enumerable: true, get: function () { return canvas_1.CanvasTransform; } });
|
|
11
|
+
// ── Facade ────────────────────────────────────────────────────────────────────
|
|
12
|
+
var pdf_1 = require("./pdf");
|
|
13
|
+
Object.defineProperty(exports, "L", { enumerable: true, get: function () { return pdf_1.L; } });
|
|
14
|
+
Object.defineProperty(exports, "NoAttr", { enumerable: true, get: function () { return pdf_1.NoAttr; } });
|
package/dist/kit-to-xml.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* console.log(xml);
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
import type {
|
|
19
|
+
import type { PdfDocument } from './kit';
|
|
20
20
|
/**
|
|
21
21
|
* Convert an `LpdfDocument` tree (built with `LpdfKit`) into an lpdf XML
|
|
22
22
|
* string.
|
|
@@ -27,4 +27,4 @@ import type { LpdfDocument } from './kit';
|
|
|
27
27
|
* @param doc - The document tree returned by `LpdfKit.document(...)`.
|
|
28
28
|
* @returns A well-formed XML string with an `<?xml ...?>` declaration.
|
|
29
29
|
*/
|
|
30
|
-
export declare function kitToXml(doc:
|
|
30
|
+
export declare function kitToXml(doc: PdfDocument): string;
|
package/dist/kit.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface LpdfMeta {
|
|
|
49
49
|
keywords?: string;
|
|
50
50
|
creator?: string;
|
|
51
51
|
}
|
|
52
|
-
export interface
|
|
52
|
+
export interface SectionAttr {
|
|
53
53
|
size?: string;
|
|
54
54
|
orientation?: string;
|
|
55
55
|
margin?: string;
|
|
@@ -57,7 +57,7 @@ export interface SectionOptions {
|
|
|
57
57
|
title?: string;
|
|
58
58
|
debug?: string;
|
|
59
59
|
}
|
|
60
|
-
export interface
|
|
60
|
+
export interface DocumentAttr {
|
|
61
61
|
size?: string;
|
|
62
62
|
orientation?: string;
|
|
63
63
|
margin?: string;
|
|
@@ -81,25 +81,16 @@ export interface LpdfSectionNode {
|
|
|
81
81
|
attrs: Record<string, string>;
|
|
82
82
|
nodes: (LpdfLayoutBlock | LpdfCanvasBlock)[];
|
|
83
83
|
}
|
|
84
|
-
export interface
|
|
84
|
+
export interface PdfDocument {
|
|
85
85
|
version: 1;
|
|
86
86
|
type: 'document';
|
|
87
87
|
attrs: Record<string, unknown>;
|
|
88
88
|
nodes: LpdfSectionNode[];
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
export interface DocumentInput {
|
|
95
|
-
/** Sections — serialised as `nodes` on the wire (matching kit_to_xml and parse_tree). */
|
|
96
|
-
sections?: LpdfSectionNode[];
|
|
97
|
-
options?: DocumentOptions;
|
|
98
|
-
}
|
|
99
|
-
declare function layout(nodes?: LpdfNode[]): LpdfLayoutBlock;
|
|
100
|
-
declare function canvas(layers?: LpdfCanvasLayerNode[]): LpdfCanvasBlock;
|
|
101
|
-
declare function section(input?: SectionInput): LpdfSectionNode;
|
|
102
|
-
declare function document(input?: DocumentInput): LpdfDocument;
|
|
90
|
+
declare function layout(_attrs: null, nodes: LpdfNode[]): LpdfLayoutBlock;
|
|
91
|
+
declare function canvas(_attrs: null, layers: LpdfCanvasLayerNode[]): LpdfCanvasBlock;
|
|
92
|
+
declare function section(attrs: SectionAttr | null, nodes: (LpdfLayoutBlock | LpdfCanvasBlock)[]): LpdfSectionNode;
|
|
93
|
+
declare function document(attrs: DocumentAttr | null, nodes: LpdfSectionNode[]): PdfDocument;
|
|
103
94
|
export declare const LpdfKit: Readonly<{
|
|
104
95
|
layout: typeof layout;
|
|
105
96
|
canvas: typeof canvas;
|
package/dist/kit.js
CHANGED
|
@@ -40,33 +40,33 @@ function buildAttrs(options) {
|
|
|
40
40
|
return result;
|
|
41
41
|
}
|
|
42
42
|
// ── Factory functions ─────────────────────────────────────────────────────────
|
|
43
|
-
function layout(nodes
|
|
43
|
+
function layout(_attrs, nodes) {
|
|
44
44
|
return { type: 'layout', nodes };
|
|
45
45
|
}
|
|
46
|
-
function canvas(layers
|
|
46
|
+
function canvas(_attrs, layers) {
|
|
47
47
|
return { type: 'canvas', nodes: layers };
|
|
48
48
|
}
|
|
49
|
-
function section(
|
|
49
|
+
function section(attrs, nodes) {
|
|
50
50
|
return {
|
|
51
51
|
type: 'section',
|
|
52
|
-
attrs: buildAttrs((
|
|
53
|
-
nodes
|
|
52
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
53
|
+
nodes,
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
function document(
|
|
57
|
-
const { tokens, meta, ...restOpts } =
|
|
58
|
-
const
|
|
56
|
+
function document(attrs, nodes) {
|
|
57
|
+
const { tokens, meta, ...restOpts } = attrs ?? {};
|
|
58
|
+
const attrsObj = {
|
|
59
59
|
...buildAttrs(restOpts),
|
|
60
60
|
};
|
|
61
61
|
if (tokens !== undefined)
|
|
62
|
-
|
|
62
|
+
attrsObj['tokens'] = tokens;
|
|
63
63
|
if (meta !== undefined)
|
|
64
|
-
|
|
64
|
+
attrsObj['meta'] = meta;
|
|
65
65
|
return {
|
|
66
66
|
version: 1,
|
|
67
67
|
type: 'document',
|
|
68
|
-
attrs,
|
|
69
|
-
nodes
|
|
68
|
+
attrs: attrsObj,
|
|
69
|
+
nodes,
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
// ── LpdfKit export ────────────────────────────────────────────────────────────
|
package/dist/layout.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PageScope } from './_shared';
|
|
2
|
-
export interface
|
|
2
|
+
export interface StackAttr {
|
|
3
3
|
gap?: string;
|
|
4
4
|
padding?: string;
|
|
5
5
|
background?: string;
|
|
@@ -11,7 +11,7 @@ export interface StackOptions {
|
|
|
11
11
|
radius?: string;
|
|
12
12
|
debug?: string;
|
|
13
13
|
}
|
|
14
|
-
export interface
|
|
14
|
+
export interface FlankAttr {
|
|
15
15
|
gap?: string;
|
|
16
16
|
padding?: string;
|
|
17
17
|
background?: string;
|
|
@@ -24,7 +24,7 @@ export interface FlankOptions {
|
|
|
24
24
|
radius?: string;
|
|
25
25
|
debug?: string;
|
|
26
26
|
}
|
|
27
|
-
export interface
|
|
27
|
+
export interface SplitAttr {
|
|
28
28
|
gap?: string;
|
|
29
29
|
padding?: string;
|
|
30
30
|
background?: string;
|
|
@@ -36,7 +36,7 @@ export interface SplitOptions {
|
|
|
36
36
|
radius?: string;
|
|
37
37
|
debug?: string;
|
|
38
38
|
}
|
|
39
|
-
export interface
|
|
39
|
+
export interface ClusterAttr {
|
|
40
40
|
gap?: string;
|
|
41
41
|
padding?: string;
|
|
42
42
|
background?: string;
|
|
@@ -48,7 +48,7 @@ export interface ClusterOptions {
|
|
|
48
48
|
radius?: string;
|
|
49
49
|
debug?: string;
|
|
50
50
|
}
|
|
51
|
-
export interface
|
|
51
|
+
export interface GridAttr {
|
|
52
52
|
cols?: string;
|
|
53
53
|
colWidth?: string;
|
|
54
54
|
gap?: string;
|
|
@@ -61,7 +61,7 @@ export interface GridOptions {
|
|
|
61
61
|
radius?: string;
|
|
62
62
|
debug?: string;
|
|
63
63
|
}
|
|
64
|
-
export interface
|
|
64
|
+
export interface FrameAttr {
|
|
65
65
|
width?: string;
|
|
66
66
|
height?: string;
|
|
67
67
|
padding?: string;
|
|
@@ -71,13 +71,13 @@ export interface FrameOptions {
|
|
|
71
71
|
align?: string;
|
|
72
72
|
debug?: string;
|
|
73
73
|
}
|
|
74
|
-
export interface
|
|
74
|
+
export interface LinkAttr {
|
|
75
75
|
url?: string;
|
|
76
76
|
width?: string;
|
|
77
77
|
height?: string;
|
|
78
78
|
debug?: string;
|
|
79
79
|
}
|
|
80
|
-
export interface
|
|
80
|
+
export interface TableAttr {
|
|
81
81
|
cols: string;
|
|
82
82
|
border?: string;
|
|
83
83
|
stripe?: string;
|
|
@@ -89,13 +89,13 @@ export interface TableOptions {
|
|
|
89
89
|
repeat?: string;
|
|
90
90
|
debug?: string;
|
|
91
91
|
}
|
|
92
|
-
export interface
|
|
92
|
+
export interface TheadAttr {
|
|
93
93
|
background?: string;
|
|
94
94
|
}
|
|
95
|
-
export interface
|
|
95
|
+
export interface TrAttr {
|
|
96
96
|
background?: string;
|
|
97
97
|
}
|
|
98
|
-
export interface
|
|
98
|
+
export interface TdAttr {
|
|
99
99
|
padding?: string;
|
|
100
100
|
background?: string;
|
|
101
101
|
align?: string;
|
|
@@ -105,7 +105,7 @@ export interface TdOptions {
|
|
|
105
105
|
gap?: string;
|
|
106
106
|
debug?: string;
|
|
107
107
|
}
|
|
108
|
-
export interface
|
|
108
|
+
export interface TextAttr {
|
|
109
109
|
font?: string;
|
|
110
110
|
fontSize?: string;
|
|
111
111
|
textAlign?: string;
|
|
@@ -121,7 +121,7 @@ export interface TextOptions {
|
|
|
121
121
|
repeat?: string;
|
|
122
122
|
debug?: string;
|
|
123
123
|
}
|
|
124
|
-
export interface
|
|
124
|
+
export interface SpanAttr {
|
|
125
125
|
font?: string;
|
|
126
126
|
fontSize?: string;
|
|
127
127
|
color?: string;
|
|
@@ -130,13 +130,13 @@ export interface SpanOptions {
|
|
|
130
130
|
underline?: string;
|
|
131
131
|
strike?: string;
|
|
132
132
|
}
|
|
133
|
-
export interface
|
|
133
|
+
export interface DividerAttr {
|
|
134
134
|
color?: string;
|
|
135
135
|
thickness?: string;
|
|
136
136
|
direction?: string;
|
|
137
137
|
debug?: string;
|
|
138
138
|
}
|
|
139
|
-
export interface
|
|
139
|
+
export interface ImgAttr {
|
|
140
140
|
name: string;
|
|
141
141
|
height?: string;
|
|
142
142
|
width?: string;
|
|
@@ -150,7 +150,7 @@ export interface ImgOptions {
|
|
|
150
150
|
repeat?: string;
|
|
151
151
|
debug?: string;
|
|
152
152
|
}
|
|
153
|
-
export interface
|
|
153
|
+
export interface BarcodeAttr {
|
|
154
154
|
type: string;
|
|
155
155
|
data: string;
|
|
156
156
|
size?: string;
|
|
@@ -163,7 +163,8 @@ export interface BarcodeOptions {
|
|
|
163
163
|
repeat?: string;
|
|
164
164
|
debug?: string;
|
|
165
165
|
}
|
|
166
|
-
export interface
|
|
166
|
+
export interface RegionAttr {
|
|
167
|
+
pin: string;
|
|
167
168
|
page?: PageScope | string;
|
|
168
169
|
w?: string;
|
|
169
170
|
debug?: string;
|
|
@@ -221,23 +222,23 @@ export interface LpdfRegionNode {
|
|
|
221
222
|
nodes: LpdfNode[];
|
|
222
223
|
}
|
|
223
224
|
export type LpdfNode = LpdfContainerNode | LpdfTextNode | LpdfDividerNode | LpdfTableNode | LpdfImgNode | LpdfBarcodeNode | LpdfRegionNode;
|
|
224
|
-
declare function stack(nodes
|
|
225
|
-
declare function flank(nodes
|
|
226
|
-
declare function split(nodes
|
|
227
|
-
declare function cluster(nodes
|
|
228
|
-
declare function grid(nodes
|
|
229
|
-
declare function frame(nodes
|
|
230
|
-
declare function link(nodes
|
|
231
|
-
declare function table(
|
|
232
|
-
declare function thead(nodes
|
|
233
|
-
declare function tr(nodes
|
|
234
|
-
declare function td(nodes
|
|
235
|
-
declare function text(nodes
|
|
236
|
-
declare function span(nodes
|
|
237
|
-
declare function divider(
|
|
238
|
-
declare function img(
|
|
239
|
-
declare function barcode(
|
|
240
|
-
declare function region(
|
|
225
|
+
declare function stack(attrs: StackAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
226
|
+
declare function flank(attrs: FlankAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
227
|
+
declare function split(attrs: SplitAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
228
|
+
declare function cluster(attrs: ClusterAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
229
|
+
declare function grid(attrs: GridAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
230
|
+
declare function frame(attrs: FrameAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
231
|
+
declare function link(attrs: LinkAttr | null, nodes: LpdfNode[]): LpdfContainerNode;
|
|
232
|
+
declare function table(attrs: TableAttr, nodes: (LpdfTheadNode | LpdfTrNode)[]): LpdfTableNode;
|
|
233
|
+
declare function thead(attrs: TheadAttr | null, nodes: LpdfTdNode[]): LpdfTheadNode;
|
|
234
|
+
declare function tr(attrs: TrAttr | null, nodes: LpdfTdNode[]): LpdfTrNode;
|
|
235
|
+
declare function td(attrs: TdAttr | null, nodes: LpdfNode[]): LpdfTdNode;
|
|
236
|
+
declare function text(attrs: TextAttr | null, nodes: (string | LpdfSpanNode)[]): LpdfTextNode;
|
|
237
|
+
declare function span(attrs: SpanAttr | null, nodes: string[]): LpdfSpanNode;
|
|
238
|
+
declare function divider(attrs: DividerAttr | null): LpdfDividerNode;
|
|
239
|
+
declare function img(attrs: ImgAttr): LpdfImgNode;
|
|
240
|
+
declare function barcode(attrs: BarcodeAttr): LpdfBarcodeNode;
|
|
241
|
+
declare function region(attrs: RegionAttr, nodes: LpdfNode[]): LpdfRegionNode;
|
|
241
242
|
export declare const LpdfLayout: Readonly<{
|
|
242
243
|
stack: typeof stack;
|
|
243
244
|
flank: typeof flank;
|
package/dist/layout.js
CHANGED
|
@@ -15,100 +15,100 @@ function buildAttrs(options) {
|
|
|
15
15
|
return result;
|
|
16
16
|
}
|
|
17
17
|
// ── Helper ────────────────────────────────────────────────────────────────────
|
|
18
|
-
function makeContainer(type,
|
|
19
|
-
return { type, attrs: buildAttrs(
|
|
18
|
+
function makeContainer(type, attrs, nodes) {
|
|
19
|
+
return { type, attrs: buildAttrs(attrs ?? {}), nodes };
|
|
20
20
|
}
|
|
21
21
|
// ── LpdfLayout factory ────────────────────────────────────────────────────────
|
|
22
|
-
function stack(
|
|
23
|
-
return makeContainer('stack',
|
|
22
|
+
function stack(attrs, nodes) {
|
|
23
|
+
return makeContainer('stack', attrs, nodes);
|
|
24
24
|
}
|
|
25
|
-
function flank(
|
|
26
|
-
return makeContainer('flank',
|
|
25
|
+
function flank(attrs, nodes) {
|
|
26
|
+
return makeContainer('flank', attrs, nodes);
|
|
27
27
|
}
|
|
28
|
-
function split(
|
|
29
|
-
return makeContainer('split',
|
|
28
|
+
function split(attrs, nodes) {
|
|
29
|
+
return makeContainer('split', attrs, nodes);
|
|
30
30
|
}
|
|
31
|
-
function cluster(
|
|
32
|
-
return makeContainer('cluster',
|
|
31
|
+
function cluster(attrs, nodes) {
|
|
32
|
+
return makeContainer('cluster', attrs, nodes);
|
|
33
33
|
}
|
|
34
|
-
function grid(
|
|
35
|
-
return makeContainer('grid',
|
|
34
|
+
function grid(attrs, nodes) {
|
|
35
|
+
return makeContainer('grid', attrs, nodes);
|
|
36
36
|
}
|
|
37
|
-
function frame(
|
|
38
|
-
return makeContainer('frame',
|
|
37
|
+
function frame(attrs, nodes) {
|
|
38
|
+
return makeContainer('frame', attrs, nodes);
|
|
39
39
|
}
|
|
40
|
-
function link(
|
|
41
|
-
return makeContainer('link',
|
|
40
|
+
function link(attrs, nodes) {
|
|
41
|
+
return makeContainer('link', attrs, nodes);
|
|
42
42
|
}
|
|
43
|
-
function table(
|
|
43
|
+
function table(attrs, nodes) {
|
|
44
44
|
return {
|
|
45
45
|
type: 'table',
|
|
46
|
-
attrs: buildAttrs(
|
|
46
|
+
attrs: buildAttrs(attrs),
|
|
47
47
|
nodes,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
function thead(
|
|
50
|
+
function thead(attrs, nodes) {
|
|
51
51
|
return {
|
|
52
52
|
type: 'thead',
|
|
53
|
-
attrs: buildAttrs((
|
|
53
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
54
54
|
nodes,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
function tr(
|
|
57
|
+
function tr(attrs, nodes) {
|
|
58
58
|
return {
|
|
59
59
|
type: 'tr',
|
|
60
|
-
attrs: buildAttrs((
|
|
60
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
61
61
|
nodes,
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
-
function td(
|
|
64
|
+
function td(attrs, nodes) {
|
|
65
65
|
return {
|
|
66
66
|
type: 'td',
|
|
67
|
-
attrs: buildAttrs((
|
|
67
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
68
68
|
nodes,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
function text(
|
|
71
|
+
function text(attrs, nodes) {
|
|
72
72
|
return {
|
|
73
73
|
type: 'text',
|
|
74
|
-
attrs: buildAttrs((
|
|
74
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
75
75
|
nodes,
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
-
function span(
|
|
78
|
+
function span(attrs, nodes) {
|
|
79
79
|
return {
|
|
80
80
|
type: 'span',
|
|
81
|
-
attrs: buildAttrs((
|
|
81
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
82
82
|
nodes,
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
function divider(
|
|
85
|
+
function divider(attrs) {
|
|
86
86
|
return {
|
|
87
87
|
type: 'divider',
|
|
88
|
-
attrs: buildAttrs((
|
|
88
|
+
attrs: buildAttrs((attrs ?? {})),
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
-
function img(
|
|
91
|
+
function img(attrs) {
|
|
92
92
|
return {
|
|
93
93
|
type: 'img',
|
|
94
|
-
attrs: buildAttrs(
|
|
94
|
+
attrs: buildAttrs(attrs),
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
function barcode(
|
|
97
|
+
function barcode(attrs) {
|
|
98
98
|
return {
|
|
99
99
|
type: 'barcode',
|
|
100
|
-
attrs: buildAttrs(
|
|
100
|
+
attrs: buildAttrs(attrs),
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
function region(
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
return { type: 'layout-region', attrs, nodes };
|
|
103
|
+
function region(attrs, nodes) {
|
|
104
|
+
const a = { pin: attrs.pin };
|
|
105
|
+
if (attrs.page !== undefined)
|
|
106
|
+
a['page'] = attrs.page;
|
|
107
|
+
if (attrs.w !== undefined)
|
|
108
|
+
a['w'] = attrs.w;
|
|
109
|
+
if (attrs.debug !== undefined)
|
|
110
|
+
a['debug'] = attrs.debug;
|
|
111
|
+
return { type: 'layout-region', attrs: a, nodes };
|
|
112
112
|
}
|
|
113
113
|
exports.LpdfLayout = Object.freeze({
|
|
114
114
|
stack,
|
package/dist/pdf.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { PdfDocument } from './kit';
|
|
2
|
+
import { PdfEngine } from './engine';
|
|
3
|
+
/** Pass as `attrs` when a node has no attributes. Equivalent to `null`. */
|
|
4
|
+
export declare const NoAttr: null;
|
|
5
|
+
/**
|
|
6
|
+
* Unified lpdf facade.
|
|
7
|
+
*
|
|
8
|
+
* All document, layout, and canvas factory methods are available as flat
|
|
9
|
+
* properties on this object. Construction-time configuration is handled via
|
|
10
|
+
* `L.engine()`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { L, NoAttr } from 'lpdf';
|
|
15
|
+
*
|
|
16
|
+
* const engine = L.engine().setLicenseKey(process.env.LPDF_KEY);
|
|
17
|
+
*
|
|
18
|
+
* const doc = L.document(NoAttr, [
|
|
19
|
+
* L.section(NoAttr, [
|
|
20
|
+
* L.layout(null, [ L.text(NoAttr, ['Hello']) ]),
|
|
21
|
+
* ]),
|
|
22
|
+
* ]);
|
|
23
|
+
*
|
|
24
|
+
* const pdf = await engine.render(doc);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const L: Readonly<{
|
|
28
|
+
/** Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure. */
|
|
29
|
+
engine: () => PdfEngine;
|
|
30
|
+
/** Convert a `PdfDocument` tree to an lpdf XML string. */
|
|
31
|
+
toXml: (doc: PdfDocument) => string;
|
|
32
|
+
document: (attrs: import("./kit").DocumentAttr | null, nodes: import("./kit").LpdfSectionNode[]) => PdfDocument;
|
|
33
|
+
section: (attrs: import("./kit").SectionAttr | null, nodes: (import("./kit").LpdfLayoutBlock | import("./kit").LpdfCanvasBlock)[]) => import("./kit").LpdfSectionNode;
|
|
34
|
+
layout: (_attrs: null, nodes: import("./layout").LpdfNode[]) => import("./kit").LpdfLayoutBlock;
|
|
35
|
+
canvas: (_attrs: null, layers: import("./canvas").LpdfCanvasLayerNode[]) => import("./kit").LpdfCanvasBlock;
|
|
36
|
+
stack: (attrs: import("./layout").StackAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
37
|
+
flank: (attrs: import("./layout").FlankAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
38
|
+
split: (attrs: import("./layout").SplitAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
39
|
+
cluster: (attrs: import("./layout").ClusterAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
40
|
+
grid: (attrs: import("./layout").GridAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
41
|
+
frame: (attrs: import("./layout").FrameAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
42
|
+
link: (attrs: import("./layout").LinkAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfContainerNode;
|
|
43
|
+
table: (attrs: import("./layout").TableAttr, nodes: (import("./layout").LpdfTheadNode | import("./layout").LpdfTrNode)[]) => import("./layout").LpdfTableNode;
|
|
44
|
+
thead: (attrs: import("./layout").TheadAttr | null, nodes: import("./layout").LpdfTdNode[]) => import("./layout").LpdfTheadNode;
|
|
45
|
+
tr: (attrs: import("./layout").TrAttr | null, nodes: import("./layout").LpdfTdNode[]) => import("./layout").LpdfTrNode;
|
|
46
|
+
td: (attrs: import("./layout").TdAttr | null, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfTdNode;
|
|
47
|
+
text: (attrs: import("./layout").TextAttr | null, nodes: (string | import("./layout").LpdfSpanNode)[]) => import("./layout").LpdfTextNode;
|
|
48
|
+
span: (attrs: import("./layout").SpanAttr | null, nodes: string[]) => import("./layout").LpdfSpanNode;
|
|
49
|
+
divider: (attrs: import("./layout").DividerAttr | null) => import("./layout").LpdfDividerNode;
|
|
50
|
+
img: (attrs: import("./layout").ImgAttr) => import("./layout").LpdfImgNode;
|
|
51
|
+
barcode: (attrs: import("./layout").BarcodeAttr) => import("./layout").LpdfBarcodeNode;
|
|
52
|
+
region: (attrs: import("./layout").RegionAttr, nodes: import("./layout").LpdfNode[]) => import("./layout").LpdfRegionNode;
|
|
53
|
+
layer: (attrs: import("./canvas").LayerAttr | null, nodes: import("./canvas").LpdfCanvasPrimitiveNode[]) => import("./canvas").LpdfCanvasLayerNode;
|
|
54
|
+
rect: (x: number, y: number, w: number, h: number, style?: import("./canvas").CanvasRectStyle) => import("./canvas").LpdfCanvasRectNode;
|
|
55
|
+
line: (x1: number, y1: number, x2: number, y2: number, style?: import("./canvas").CanvasLineStyle) => import("./canvas").LpdfCanvasLineNode;
|
|
56
|
+
ellipse: (cx: number, cy: number, rx: number, ry: number, style?: import("./canvas").CanvasEllipseStyle) => import("./canvas").LpdfCanvasEllipseNode;
|
|
57
|
+
circle: (cx: number, cy: number, r: number, style?: import("./canvas").CanvasEllipseStyle) => import("./canvas").LpdfCanvasCircleNode;
|
|
58
|
+
path: (d: string, style?: import("./canvas").CanvasPathStyle) => import("./canvas").LpdfCanvasPathNode;
|
|
59
|
+
textAt: (x: number, y: number, content: string, style?: import("./canvas").CanvasTextStyle, runs?: import("./canvas").CanvasRun[]) => import("./canvas").LpdfCanvasTextNode;
|
|
60
|
+
imgAt: (x: number, y: number, w: number, h: number, name: string) => import("./canvas").LpdfCanvasImgNode;
|
|
61
|
+
}>;
|
package/dist/pdf.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.L = exports.NoAttr = void 0;
|
|
4
|
+
const kit_1 = require("./kit");
|
|
5
|
+
const layout_1 = require("./layout");
|
|
6
|
+
const canvas_1 = require("./canvas");
|
|
7
|
+
const engine_1 = require("./engine");
|
|
8
|
+
const kit_to_xml_1 = require("./kit-to-xml");
|
|
9
|
+
/** Pass as `attrs` when a node has no attributes. Equivalent to `null`. */
|
|
10
|
+
exports.NoAttr = null;
|
|
11
|
+
/**
|
|
12
|
+
* Unified lpdf facade.
|
|
13
|
+
*
|
|
14
|
+
* All document, layout, and canvas factory methods are available as flat
|
|
15
|
+
* properties on this object. Construction-time configuration is handled via
|
|
16
|
+
* `L.engine()`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { L, NoAttr } from 'lpdf';
|
|
21
|
+
*
|
|
22
|
+
* const engine = L.engine().setLicenseKey(process.env.LPDF_KEY);
|
|
23
|
+
*
|
|
24
|
+
* const doc = L.document(NoAttr, [
|
|
25
|
+
* L.section(NoAttr, [
|
|
26
|
+
* L.layout(null, [ L.text(NoAttr, ['Hello']) ]),
|
|
27
|
+
* ]),
|
|
28
|
+
* ]);
|
|
29
|
+
*
|
|
30
|
+
* const pdf = await engine.render(doc);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
exports.L = Object.freeze({
|
|
34
|
+
/** Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure. */
|
|
35
|
+
engine: () => new engine_1.PdfEngine(),
|
|
36
|
+
/** Convert a `PdfDocument` tree to an lpdf XML string. */
|
|
37
|
+
toXml: (doc) => (0, kit_to_xml_1.kitToXml)(doc),
|
|
38
|
+
// ── Kit ───────────────────────────────────────────────────────────────────
|
|
39
|
+
document: kit_1.LpdfKit.document,
|
|
40
|
+
section: kit_1.LpdfKit.section,
|
|
41
|
+
layout: kit_1.LpdfKit.layout,
|
|
42
|
+
canvas: kit_1.LpdfKit.canvas,
|
|
43
|
+
// ── Layout ────────────────────────────────────────────────────────────────
|
|
44
|
+
stack: layout_1.LpdfLayout.stack,
|
|
45
|
+
flank: layout_1.LpdfLayout.flank,
|
|
46
|
+
split: layout_1.LpdfLayout.split,
|
|
47
|
+
cluster: layout_1.LpdfLayout.cluster,
|
|
48
|
+
grid: layout_1.LpdfLayout.grid,
|
|
49
|
+
frame: layout_1.LpdfLayout.frame,
|
|
50
|
+
link: layout_1.LpdfLayout.link,
|
|
51
|
+
table: layout_1.LpdfLayout.table,
|
|
52
|
+
thead: layout_1.LpdfLayout.thead,
|
|
53
|
+
tr: layout_1.LpdfLayout.tr,
|
|
54
|
+
td: layout_1.LpdfLayout.td,
|
|
55
|
+
text: layout_1.LpdfLayout.text,
|
|
56
|
+
span: layout_1.LpdfLayout.span,
|
|
57
|
+
divider: layout_1.LpdfLayout.divider,
|
|
58
|
+
img: layout_1.LpdfLayout.img,
|
|
59
|
+
barcode: layout_1.LpdfLayout.barcode,
|
|
60
|
+
region: layout_1.LpdfLayout.region,
|
|
61
|
+
// ── Canvas ────────────────────────────────────────────────────────────────
|
|
62
|
+
layer: canvas_1.LpdfCanvas.layer,
|
|
63
|
+
rect: canvas_1.LpdfCanvas.rect,
|
|
64
|
+
line: canvas_1.LpdfCanvas.line,
|
|
65
|
+
ellipse: canvas_1.LpdfCanvas.ellipse,
|
|
66
|
+
circle: canvas_1.LpdfCanvas.circle,
|
|
67
|
+
path: canvas_1.LpdfCanvas.path,
|
|
68
|
+
textAt: canvas_1.LpdfCanvas.textAt,
|
|
69
|
+
imgAt: canvas_1.LpdfCanvas.imgAt,
|
|
70
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lpdfio/lpdf",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Node.js
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Node.js SDK for Lpdf — PDF as Code on every platform. You describe a document as code or XML. Lpdf renders a compact, pixel-perfect PDF — identical across platforms.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|