turbo-html2pdf-react 0.1.3 → 0.1.7
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.cjs +273 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +169 -0
- package/package.json +5 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
Anchor: () => Anchor,
|
|
24
|
+
Case: () => Case,
|
|
25
|
+
Counter: () => Counter,
|
|
26
|
+
Default: () => Default,
|
|
27
|
+
Each: () => Each,
|
|
28
|
+
Else: () => Else,
|
|
29
|
+
ElseIf: () => ElseIf,
|
|
30
|
+
Endnote: () => Endnote,
|
|
31
|
+
Endnotes: () => Endnotes,
|
|
32
|
+
Expr: () => Expr,
|
|
33
|
+
Footnote: () => Footnote,
|
|
34
|
+
FootnoteSeparator: () => FootnoteSeparator,
|
|
35
|
+
If: () => If,
|
|
36
|
+
Include: () => Include,
|
|
37
|
+
Leader: () => Leader,
|
|
38
|
+
Page: () => Page,
|
|
39
|
+
PageMaster: () => PageMaster,
|
|
40
|
+
Pages: () => Pages,
|
|
41
|
+
Raw: () => Raw,
|
|
42
|
+
Region: () => Region,
|
|
43
|
+
Running: () => Running,
|
|
44
|
+
RunningFooter: () => RunningFooter,
|
|
45
|
+
RunningHeader: () => RunningHeader,
|
|
46
|
+
Switch: () => Switch,
|
|
47
|
+
UseMaster: () => UseMaster,
|
|
48
|
+
Variant: () => Variant,
|
|
49
|
+
compileTemplate: () => compileTemplate
|
|
50
|
+
});
|
|
51
|
+
module.exports = __toCommonJS(index_exports);
|
|
52
|
+
|
|
53
|
+
// src/compile.ts
|
|
54
|
+
var import_server = require("react-dom/server");
|
|
55
|
+
|
|
56
|
+
// src/sentinel.ts
|
|
57
|
+
var OPEN = "\uE000";
|
|
58
|
+
var CLOSE = "\uE001";
|
|
59
|
+
function toBase64Url(text) {
|
|
60
|
+
const bytes = new TextEncoder().encode(text);
|
|
61
|
+
let binary = "";
|
|
62
|
+
for (const byte of bytes) {
|
|
63
|
+
binary += String.fromCharCode(byte);
|
|
64
|
+
}
|
|
65
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
66
|
+
}
|
|
67
|
+
function fromBase64Url(encoded) {
|
|
68
|
+
const padded = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
69
|
+
const binary = atob(padded);
|
|
70
|
+
const bytes = new Uint8Array(binary.length);
|
|
71
|
+
for (let i = 0; i < binary.length; i++) {
|
|
72
|
+
bytes[i] = binary.charCodeAt(i);
|
|
73
|
+
}
|
|
74
|
+
return new TextDecoder().decode(bytes);
|
|
75
|
+
}
|
|
76
|
+
function sentinel(literal) {
|
|
77
|
+
return `${OPEN}${toBase64Url(literal)}${CLOSE}`;
|
|
78
|
+
}
|
|
79
|
+
function expandSentinels(markup) {
|
|
80
|
+
const pattern = new RegExp(`${OPEN}([A-Za-z0-9_-]*)${CLOSE}`, "g");
|
|
81
|
+
return markup.replace(pattern, (_match, payload) => fromBase64Url(payload));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/compile.ts
|
|
85
|
+
function compileTemplate(element, options = {}) {
|
|
86
|
+
const markup = (0, import_server.renderToStaticMarkup)(element);
|
|
87
|
+
const expanded = expandSentinels(markup);
|
|
88
|
+
return options.trim === false ? expanded : expanded.trim();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/control-flow.tsx
|
|
92
|
+
var import_react = require("react");
|
|
93
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
94
|
+
function statement(body) {
|
|
95
|
+
return sentinel(`{% ${body} %}`);
|
|
96
|
+
}
|
|
97
|
+
function If(props) {
|
|
98
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
99
|
+
statement(`if ${props.cond}`),
|
|
100
|
+
props.children,
|
|
101
|
+
statement("endif")
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
function ElseIf(props) {
|
|
105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
106
|
+
statement(`elif ${props.cond}`),
|
|
107
|
+
props.children
|
|
108
|
+
] });
|
|
109
|
+
}
|
|
110
|
+
function Else(props) {
|
|
111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
112
|
+
statement("else"),
|
|
113
|
+
props.children
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
function Each(props) {
|
|
117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
118
|
+
statement(`for ${props.as} in ${props.of}`),
|
|
119
|
+
props.index ? statement(`set ${props.index} = loop.index0`) : null,
|
|
120
|
+
props.children,
|
|
121
|
+
statement("endfor")
|
|
122
|
+
] });
|
|
123
|
+
}
|
|
124
|
+
function Switch(props) {
|
|
125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
126
|
+
statement(`switch ${props.on}`),
|
|
127
|
+
props.children,
|
|
128
|
+
statement("endswitch")
|
|
129
|
+
] });
|
|
130
|
+
}
|
|
131
|
+
function Case(props) {
|
|
132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
133
|
+
statement(`case ${props.value}`),
|
|
134
|
+
props.children
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
function Default(props) {
|
|
138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
|
|
139
|
+
statement("default"),
|
|
140
|
+
props.children
|
|
141
|
+
] });
|
|
142
|
+
}
|
|
143
|
+
function includeStatement(src, withCtx) {
|
|
144
|
+
return withCtx ? `include ${src} with ${withCtx}` : `include ${src}`;
|
|
145
|
+
}
|
|
146
|
+
function Include(props) {
|
|
147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: statement(includeStatement(props.src, props.with)) });
|
|
148
|
+
}
|
|
149
|
+
function Expr(props) {
|
|
150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: sentinel(`{{ ${props.value} }}`) });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/raw.ts
|
|
154
|
+
var import_react2 = require("react");
|
|
155
|
+
function Raw(props) {
|
|
156
|
+
return (0, import_react2.createElement)(import_react2.Fragment, null, sentinel(props.html));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/paged-media.ts
|
|
160
|
+
var import_react3 = require("react");
|
|
161
|
+
function defined(attrs) {
|
|
162
|
+
const out = {};
|
|
163
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
164
|
+
if (value !== void 0) {
|
|
165
|
+
out[key] = value;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
170
|
+
function directive(name, attrs, children) {
|
|
171
|
+
return (0, import_react3.createElement)(`t:${name}`, defined(attrs), children);
|
|
172
|
+
}
|
|
173
|
+
function RunningHeader(props) {
|
|
174
|
+
return directive("running-header", { extent: props.extent }, props.children);
|
|
175
|
+
}
|
|
176
|
+
function RunningFooter(props) {
|
|
177
|
+
return directive("running-footer", { extent: props.extent }, props.children);
|
|
178
|
+
}
|
|
179
|
+
function PageMaster(props) {
|
|
180
|
+
return directive(
|
|
181
|
+
"page-master",
|
|
182
|
+
{
|
|
183
|
+
name: props.name,
|
|
184
|
+
size: props.size,
|
|
185
|
+
orientation: props.orientation,
|
|
186
|
+
margin: props.margin
|
|
187
|
+
},
|
|
188
|
+
props.children
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
function Region(props) {
|
|
192
|
+
return directive("region", { slot: props.slot, extent: props.extent }, props.children);
|
|
193
|
+
}
|
|
194
|
+
function Variant(props) {
|
|
195
|
+
return directive("variant", { kind: props.kind }, props.children);
|
|
196
|
+
}
|
|
197
|
+
function UseMaster(props) {
|
|
198
|
+
return directive("use-master", { name: props.name });
|
|
199
|
+
}
|
|
200
|
+
function Footnote(props) {
|
|
201
|
+
return directive(
|
|
202
|
+
"footnote",
|
|
203
|
+
{ mark: props.mark, "t:footnote-reset": props.reset },
|
|
204
|
+
props.children
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
function FootnoteSeparator(props) {
|
|
208
|
+
return directive("footnote-separator", {}, props.children);
|
|
209
|
+
}
|
|
210
|
+
function Counter(props) {
|
|
211
|
+
return directive("counter", {
|
|
212
|
+
name: props.name,
|
|
213
|
+
action: props.action,
|
|
214
|
+
step: props.step,
|
|
215
|
+
start: props.start
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function Leader(props) {
|
|
219
|
+
return directive("leader", {}, props.children);
|
|
220
|
+
}
|
|
221
|
+
function Anchor(props) {
|
|
222
|
+
return directive("anchor", { id: props.id });
|
|
223
|
+
}
|
|
224
|
+
function Endnote(props) {
|
|
225
|
+
return directive("endnote", {}, props.children);
|
|
226
|
+
}
|
|
227
|
+
function Endnotes() {
|
|
228
|
+
return directive("endnotes", {});
|
|
229
|
+
}
|
|
230
|
+
function Running(props) {
|
|
231
|
+
return (0, import_react3.createElement)(
|
|
232
|
+
props.as ?? "span",
|
|
233
|
+
defined({ "t:running": props.name, "t:running-policy": props.policy }),
|
|
234
|
+
props.children
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
function Page() {
|
|
238
|
+
return directive("page", {});
|
|
239
|
+
}
|
|
240
|
+
function Pages() {
|
|
241
|
+
return directive("pages", {});
|
|
242
|
+
}
|
|
243
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
244
|
+
0 && (module.exports = {
|
|
245
|
+
Anchor,
|
|
246
|
+
Case,
|
|
247
|
+
Counter,
|
|
248
|
+
Default,
|
|
249
|
+
Each,
|
|
250
|
+
Else,
|
|
251
|
+
ElseIf,
|
|
252
|
+
Endnote,
|
|
253
|
+
Endnotes,
|
|
254
|
+
Expr,
|
|
255
|
+
Footnote,
|
|
256
|
+
FootnoteSeparator,
|
|
257
|
+
If,
|
|
258
|
+
Include,
|
|
259
|
+
Leader,
|
|
260
|
+
Page,
|
|
261
|
+
PageMaster,
|
|
262
|
+
Pages,
|
|
263
|
+
Raw,
|
|
264
|
+
Region,
|
|
265
|
+
Running,
|
|
266
|
+
RunningFooter,
|
|
267
|
+
RunningHeader,
|
|
268
|
+
Switch,
|
|
269
|
+
UseMaster,
|
|
270
|
+
Variant,
|
|
271
|
+
compileTemplate
|
|
272
|
+
});
|
|
273
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/compile.ts","../src/sentinel.ts","../src/control-flow.tsx","../src/raw.ts","../src/paged-media.ts"],"sourcesContent":["// `turbo-html2pdf-react` — the first authoring frontend for turbo-pdf.\n//\n// React components that render *once at authoring time* to a turbo-pdf template\n// source string (Jinja control flow + `t:` paged-media directives + plain HTML).\n// React is never on the render hot path; expressions are strings resolved in Rust\n// at render. See ./compile for the entry point and ./sentinel for how literal Jinja\n// survives React's HTML-escaping.\n\nexport { compileTemplate, type CompileOptions } from \"./compile.js\";\nexport {\n Case,\n Default,\n Each,\n Else,\n ElseIf,\n Expr,\n If,\n Include,\n Switch,\n} from \"./control-flow.js\";\nexport { Raw } from \"./raw.js\";\nexport {\n Anchor,\n Counter,\n Endnote,\n Endnotes,\n Footnote,\n FootnoteSeparator,\n Leader,\n Page,\n PageMaster,\n Pages,\n Region,\n Running,\n RunningFooter,\n RunningHeader,\n UseMaster,\n Variant,\n} from \"./paged-media.js\";\n","// The public authoring entry point: turn a React element tree into a turbo-pdf\n// template *source string* (Jinja control flow + `t:` paged-media directives +\n// plain HTML). React runs **once at authoring time** here via `renderToStaticMarkup`;\n// it is never on the render hot path and has no access to render data (§8.4).\n\nimport type { ReactElement } from \"react\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { expandSentinels } from \"./sentinel.js\";\n\n/** Options for {@link compileTemplate}. */\nexport interface CompileOptions {\n /**\n * Trim insignificant leading/trailing whitespace from the final string. On by\n * default; this is the only normalization applied (the interior is verbatim).\n */\n trim?: boolean;\n}\n\n/**\n * Render `element` to a turbo-pdf template source string.\n *\n * Pipeline: `renderToStaticMarkup` produces HTML where plain elements and `t:`\n * directives are emitted (and legitimately HTML-escaped) as-is, while control-flow\n * components emitted sentinel tokens carrying their literal Jinja. `expandSentinels`\n * then decodes those tokens into real `{% … %}` / `{{ … }}` text — the one\n * post-process pass that undoes nothing else, so the result is byte-stable.\n */\nexport function compileTemplate(element: ReactElement, options: CompileOptions = {}): string {\n const markup = renderToStaticMarkup(element);\n const expanded = expandSentinels(markup);\n return options.trim === false ? expanded : expanded.trim();\n}\n","// The Jinja-escaping problem, solved.\n//\n// React's `renderToStaticMarkup` HTML-escapes text children (`<` -> `<`,\n// `&` -> `&`, …) and attribute values (`\"` -> `"`, …). Our control-flow\n// components must emit *literal* Jinja statements like `{% if total > 0 %}` whose\n// expression strings contain `<`, `>`, `&`, `\"` that React would mangle.\n//\n// Approach: control-flow components do NOT render Jinja text directly. They render\n// a *sentinel token* — a base64url payload wrapped in two Unicode Private-Use-Area\n// characters (`` … ``). Those characters are not HTML-special, so React\n// passes them through `renderToStaticMarkup` byte-for-byte, no escaping. A single\n// post-process pass (`expandSentinels`) decodes each payload back into the literal\n// Jinja string. Plain HTML and `t:` elements are emitted by React normally and kept\n// verbatim — they legitimately *want* HTML escaping.\n//\n// Base64url keeps the encoded payload free of `<`, `>`, `&`, `\"`, `'`, `=` and the\n// sentinel chars themselves, so a payload can never be confused with markup or with\n// another sentinel.\n\nconst OPEN = \"\";\nconst CLOSE = \"\";\n\n/** Encode arbitrary text to a base64url string (no padding, HTML-safe alphabet). */\nfunction toBase64Url(text: string): string {\n const bytes = new TextEncoder().encode(text);\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** Decode a base64url string produced by {@link toBase64Url}. */\nfunction fromBase64Url(encoded: string): string {\n const padded = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/** Wrap literal Jinja text in a sentinel token so React emits it un-escaped. */\nexport function sentinel(literal: string): string {\n return `${OPEN}${toBase64Url(literal)}${CLOSE}`;\n}\n\n/** Replace every sentinel token in `markup` with its decoded literal Jinja text. */\nexport function expandSentinels(markup: string): string {\n const pattern = new RegExp(`${OPEN}([A-Za-z0-9_-]*)${CLOSE}`, \"g\");\n return markup.replace(pattern, (_match, payload: string) => fromBase64Url(payload));\n}\n","// Control-flow components. These map to **Jinja statements**, never to `t:`\n// elements (a Jinja block tag is gone by the time html5ever sees the markup,\n// whereas structure that must survive into the DOM uses `t:` elements — §2).\n//\n// Each component emits literal Jinja via sentinel tokens (see ./sentinel) so the\n// expression strings survive React's HTML-escaping untouched. Attributes carry\n// **expression strings**, not evaluated JS: `cond=\"total > 0\"` stays the literal\n// `total > 0`.\n\nimport { Fragment, type ReactNode } from \"react\";\nimport { sentinel } from \"./sentinel.js\";\n\n/** A bare Jinja statement, e.g. `wrap(\"if total > 0\")` -> `{% if total > 0 %}`. */\nfunction statement(body: string): string {\n return sentinel(`{% ${body} %}`);\n}\n\n/** `{% if COND %} … {% endif %}` (§2.5). Chain with `<ElseIf>` / `<Else>`. */\nexport function If(props: { cond: string; children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(`if ${props.cond}`)}\n {props.children}\n {statement(\"endif\")}\n </Fragment>\n );\n}\n\n/** `{% elif COND %}` — a sibling inside the same `<If>` body (§2.5). */\nexport function ElseIf(props: { cond: string; children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(`elif ${props.cond}`)}\n {props.children}\n </Fragment>\n );\n}\n\n/** `{% else %}` — a sibling inside the same `<If>` (or `<Each>`) body (§2.5/2.7). */\nexport function Else(props: { children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(\"else\")}\n {props.children}\n </Fragment>\n );\n}\n\n/**\n * `{% for AS in OF %} … {% endfor %}` (§2.7). When `index` is supplied, the body\n * is prefixed with `{% set <index> = loop.index0 %}` so authors get a named\n * 0-based index.\n *\n * TODO(phase11): stock Jinja has no per-name index binding in the `for` header —\n * the built-in `loop.index`/`loop.index0` are always available. We model the\n * optional `index` prop as a `{% set %}` of `loop.index0` at body top, which is\n * the closest portable equivalent.\n */\nexport function Each(props: {\n of: string;\n as: string;\n index?: string;\n children?: ReactNode;\n}): ReactNode {\n return (\n <Fragment>\n {statement(`for ${props.as} in ${props.of}`)}\n {props.index ? statement(`set ${props.index} = loop.index0`) : null}\n {props.children}\n {statement(\"endfor\")}\n </Fragment>\n );\n}\n\n/** `{% switch ON %} … {% endswitch %}` (§2.6). Children are `<Case>` / `<Default>`. */\nexport function Switch(props: { on: string; children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(`switch ${props.on}`)}\n {props.children}\n {statement(\"endswitch\")}\n </Fragment>\n );\n}\n\n/** `{% case V1, V2, … %}` — comma means membership; first match wins (§2.6). */\nexport function Case(props: { value: string; children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(`case ${props.value}`)}\n {props.children}\n </Fragment>\n );\n}\n\n/** `{% default %}` — must be the last child of `<Switch>` (§2.6). */\nexport function Default(props: { children?: ReactNode }): ReactNode {\n return (\n <Fragment>\n {statement(\"default\")}\n {props.children}\n </Fragment>\n );\n}\n\n/** Build the `include` statement, appending `with { … }` context when given. */\nfunction includeStatement(src: string, withCtx?: string): string {\n return withCtx ? `include ${src} with ${withCtx}` : `include ${src}`;\n}\n\n/**\n * `{% include SRC %}` / `{% include SRC with CTX %}` (§2.8). `src` is an\n * expression string (usually a quoted partial name, e.g. `\"remittance\"`).\n */\nexport function Include(props: { src: string; with?: string }): ReactNode {\n return <Fragment>{statement(includeStatement(props.src, props.with))}</Fragment>;\n}\n\n/** `{{ EXPR }}` interpolation (§2.4). The expression is resolved in Rust at render. */\nexport function Expr(props: { value: string }): ReactNode {\n return <Fragment>{sentinel(`{{ ${props.value} }}`)}</Fragment>;\n}\n","// Raw passthrough escape hatch.\n//\n// React's JSX intrinsics impose their own attribute model: `class`/`colspan` warn\n// (they want `className`/`colSpan`, though they still render), and `style` MUST be\n// an object — a `style=\"color:#111\"` *string* is a hard error. turbo-pdf templates,\n// by contrast, are plain HTML where `class`, `style=\"…\"`, and `t:style` are ordinary\n// string attributes (spec §8.4). `<Raw html=\"…\" />` lets an author drop a literal\n// markup fragment that bypasses React's attribute model entirely: the string is\n// emitted verbatim (un-escaped) via the same sentinel channel the control-flow\n// components use, so whatever you write is exactly what lands in the template.\n//\n// The author owns well-formedness here (just like hand-authored HTML); the markup is\n// re-parsed by html5ever in the core.\n\nimport { createElement, Fragment, type ReactElement } from \"react\";\nimport { sentinel } from \"./sentinel.js\";\n\n/** Emit `props.html` verbatim into the template (no HTML-escaping, no React model). */\nexport function Raw(props: { html: string }): ReactElement {\n return createElement(Fragment, null, sentinel(props.html));\n}\n","// Paged-media components. These map to the `t:` directive elements that must\n// survive into the parsed DOM as typed layout nodes (§3). The element names match\n// `turbo-pdf-core`'s authoritative `t_kind()` table exactly (node.rs).\n//\n// We build these with `createElement(string, …)` rather than JSX, because a JSX\n// tag like `<t:running-header>` parses as the member expression `t.running` — the\n// `t:` namespace prefix is only valid as a *string* tag name. React DOM renders an\n// arbitrary string tag verbatim, and `renderToStaticMarkup` HTML-escapes the\n// attribute values and text children exactly as a hand-written template would, so\n// the `t:` output is byte-identical to hand-authored markup.\n\nimport { createElement, type ReactElement, type ReactNode } from \"react\";\n\n/** Drop `undefined`-valued attributes so they don't render as `attr=\"undefined\"`. */\nfunction defined(attrs: Record<string, string | undefined>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/** Create a `t:`-prefixed directive element with the given attrs and children. */\nfunction directive(\n name: string,\n attrs: Record<string, string | undefined>,\n children?: ReactNode,\n): ReactElement {\n return createElement(`t:${name}`, defined(attrs), children);\n}\n\n/** `<t:running-header>` — attaches header content to every page's top band (§3.0). */\nexport function RunningHeader(props: { extent?: string; children?: ReactNode }): ReactElement {\n return directive(\"running-header\", { extent: props.extent }, props.children);\n}\n\n/** `<t:running-footer>` — attaches footer content to every page's bottom band (§3.0). */\nexport function RunningFooter(props: { extent?: string; children?: ReactNode }): ReactElement {\n return directive(\"running-footer\", { extent: props.extent }, props.children);\n}\n\n/** `<t:page-master>` — named geometry + region bundle (§3.1). */\nexport function PageMaster(props: {\n name: string;\n size?: string;\n orientation?: string;\n margin?: string;\n children?: ReactNode;\n}): ReactElement {\n return directive(\n \"page-master\",\n {\n name: props.name,\n size: props.size,\n orientation: props.orientation,\n margin: props.margin,\n },\n props.children,\n );\n}\n\n/** `<t:region slot extent>` — a margin-box region inside a master (§3.1). */\nexport function Region(props: {\n slot: string;\n extent?: string;\n children?: ReactNode;\n}): ReactElement {\n return directive(\"region\", { slot: props.slot, extent: props.extent }, props.children);\n}\n\n/** `<t:variant kind>` — first/left/right/blank override inside a master (§3.2). */\nexport function Variant(props: { kind: string; children?: ReactNode }): ReactElement {\n return directive(\"variant\", { kind: props.kind }, props.children);\n}\n\n/** `<t:use-master name>` — switches the active master from flow position (§3.4). */\nexport function UseMaster(props: { name: string }): ReactElement {\n return directive(\"use-master\", { name: props.name });\n}\n\n/** `<t:footnote>` — inline footnote reference + body (§3.6). */\nexport function Footnote(props: {\n mark?: string;\n reset?: string;\n children?: ReactNode;\n}): ReactElement {\n return directive(\n \"footnote\",\n { mark: props.mark, \"t:footnote-reset\": props.reset },\n props.children,\n );\n}\n\n/** `<t:footnote-separator>` — the rule between body and footnote area (§3.6). */\nexport function FootnoteSeparator(props: { children?: ReactNode }): ReactElement {\n return directive(\"footnote-separator\", {}, props.children);\n}\n\n/** `<t:counter name action step start>` — a general named counter (§3.8). */\nexport function Counter(props: {\n name: string;\n action?: string;\n step?: string;\n start?: string;\n}): ReactElement {\n return directive(\"counter\", {\n name: props.name,\n action: props.action,\n step: props.step,\n start: props.start,\n });\n}\n\n/** `<t:leader>` — dot-fill between two inline boxes, for TOCs/footers (§3.10). */\nexport function Leader(props: { children?: ReactNode }): ReactElement {\n return directive(\"leader\", {}, props.children);\n}\n\n/** `<t:anchor id>` — a cross-reference target (§3.9, feature-gated in core). */\nexport function Anchor(props: { id: string }): ReactElement {\n return directive(\"anchor\", { id: props.id });\n}\n\n/** `<t:endnote>` — collects to a `<t:endnotes/>` sink (§3.7, feature-gated). */\nexport function Endnote(props: { children?: ReactNode }): ReactElement {\n return directive(\"endnote\", {}, props.children);\n}\n\n/** `<t:endnotes/>` — the endnote sink (§3.7, feature-gated). */\nexport function Endnotes(): ReactElement {\n return directive(\"endnotes\", {});\n}\n\n/**\n * Named running element (§3.5). There is **no** `t:running` element in the core's\n * authoritative `t_kind()` table — running content is marked with the\n * `t:running=\"name\"` *attribute* on a normal element (`<h1 t:running=\"section\">`).\n * So `<Running name=\"section\">` renders that attribute on a host element (default\n * `<span>`, override via `as`), optionally with `t:running-policy`.\n *\n * TODO(phase11): the handoff sketched `<Running>` -> `<t:running>`, but node.rs\n * has no such directive; spec §3.5 defines it as an attribute, which is what we emit.\n */\nexport function Running(props: {\n name: string;\n as?: string;\n policy?: string;\n children?: ReactNode;\n}): ReactElement {\n return createElement(\n props.as ?? \"span\",\n defined({ \"t:running\": props.name, \"t:running-policy\": props.policy }),\n props.children,\n );\n}\n\n/** `<t:page/>` — current 1-based page number convenience element (§3.3). */\nexport function Page(): ReactElement {\n return directive(\"page\", {});\n}\n\n/** `<t:pages/>` — total page count convenience element (§3.3). */\nexport function Pages(): ReactElement {\n return directive(\"pages\", {});\n}\n"],"mappings":"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","names":["import_react","import_react"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/** Options for {@link compileTemplate}. */
|
|
4
|
+
interface CompileOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Trim insignificant leading/trailing whitespace from the final string. On by
|
|
7
|
+
* default; this is the only normalization applied (the interior is verbatim).
|
|
8
|
+
*/
|
|
9
|
+
trim?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Render `element` to a turbo-pdf template source string.
|
|
13
|
+
*
|
|
14
|
+
* Pipeline: `renderToStaticMarkup` produces HTML where plain elements and `t:`
|
|
15
|
+
* directives are emitted (and legitimately HTML-escaped) as-is, while control-flow
|
|
16
|
+
* components emitted sentinel tokens carrying their literal Jinja. `expandSentinels`
|
|
17
|
+
* then decodes those tokens into real `{% … %}` / `{{ … }}` text — the one
|
|
18
|
+
* post-process pass that undoes nothing else, so the result is byte-stable.
|
|
19
|
+
*/
|
|
20
|
+
declare function compileTemplate(element: ReactElement, options?: CompileOptions): string;
|
|
21
|
+
|
|
22
|
+
/** `{% if COND %} … {% endif %}` (§2.5). Chain with `<ElseIf>` / `<Else>`. */
|
|
23
|
+
declare function If(props: {
|
|
24
|
+
cond: string;
|
|
25
|
+
children?: ReactNode;
|
|
26
|
+
}): ReactNode;
|
|
27
|
+
/** `{% elif COND %}` — a sibling inside the same `<If>` body (§2.5). */
|
|
28
|
+
declare function ElseIf(props: {
|
|
29
|
+
cond: string;
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
}): ReactNode;
|
|
32
|
+
/** `{% else %}` — a sibling inside the same `<If>` (or `<Each>`) body (§2.5/2.7). */
|
|
33
|
+
declare function Else(props: {
|
|
34
|
+
children?: ReactNode;
|
|
35
|
+
}): ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* `{% for AS in OF %} … {% endfor %}` (§2.7). When `index` is supplied, the body
|
|
38
|
+
* is prefixed with `{% set <index> = loop.index0 %}` so authors get a named
|
|
39
|
+
* 0-based index.
|
|
40
|
+
*
|
|
41
|
+
* TODO(phase11): stock Jinja has no per-name index binding in the `for` header —
|
|
42
|
+
* the built-in `loop.index`/`loop.index0` are always available. We model the
|
|
43
|
+
* optional `index` prop as a `{% set %}` of `loop.index0` at body top, which is
|
|
44
|
+
* the closest portable equivalent.
|
|
45
|
+
*/
|
|
46
|
+
declare function Each(props: {
|
|
47
|
+
of: string;
|
|
48
|
+
as: string;
|
|
49
|
+
index?: string;
|
|
50
|
+
children?: ReactNode;
|
|
51
|
+
}): ReactNode;
|
|
52
|
+
/** `{% switch ON %} … {% endswitch %}` (§2.6). Children are `<Case>` / `<Default>`. */
|
|
53
|
+
declare function Switch(props: {
|
|
54
|
+
on: string;
|
|
55
|
+
children?: ReactNode;
|
|
56
|
+
}): ReactNode;
|
|
57
|
+
/** `{% case V1, V2, … %}` — comma means membership; first match wins (§2.6). */
|
|
58
|
+
declare function Case(props: {
|
|
59
|
+
value: string;
|
|
60
|
+
children?: ReactNode;
|
|
61
|
+
}): ReactNode;
|
|
62
|
+
/** `{% default %}` — must be the last child of `<Switch>` (§2.6). */
|
|
63
|
+
declare function Default(props: {
|
|
64
|
+
children?: ReactNode;
|
|
65
|
+
}): ReactNode;
|
|
66
|
+
/**
|
|
67
|
+
* `{% include SRC %}` / `{% include SRC with CTX %}` (§2.8). `src` is an
|
|
68
|
+
* expression string (usually a quoted partial name, e.g. `"remittance"`).
|
|
69
|
+
*/
|
|
70
|
+
declare function Include(props: {
|
|
71
|
+
src: string;
|
|
72
|
+
with?: string;
|
|
73
|
+
}): ReactNode;
|
|
74
|
+
/** `{{ EXPR }}` interpolation (§2.4). The expression is resolved in Rust at render. */
|
|
75
|
+
declare function Expr(props: {
|
|
76
|
+
value: string;
|
|
77
|
+
}): ReactNode;
|
|
78
|
+
|
|
79
|
+
/** Emit `props.html` verbatim into the template (no HTML-escaping, no React model). */
|
|
80
|
+
declare function Raw(props: {
|
|
81
|
+
html: string;
|
|
82
|
+
}): ReactElement;
|
|
83
|
+
|
|
84
|
+
/** `<t:running-header>` — attaches header content to every page's top band (§3.0). */
|
|
85
|
+
declare function RunningHeader(props: {
|
|
86
|
+
extent?: string;
|
|
87
|
+
children?: ReactNode;
|
|
88
|
+
}): ReactElement;
|
|
89
|
+
/** `<t:running-footer>` — attaches footer content to every page's bottom band (§3.0). */
|
|
90
|
+
declare function RunningFooter(props: {
|
|
91
|
+
extent?: string;
|
|
92
|
+
children?: ReactNode;
|
|
93
|
+
}): ReactElement;
|
|
94
|
+
/** `<t:page-master>` — named geometry + region bundle (§3.1). */
|
|
95
|
+
declare function PageMaster(props: {
|
|
96
|
+
name: string;
|
|
97
|
+
size?: string;
|
|
98
|
+
orientation?: string;
|
|
99
|
+
margin?: string;
|
|
100
|
+
children?: ReactNode;
|
|
101
|
+
}): ReactElement;
|
|
102
|
+
/** `<t:region slot extent>` — a margin-box region inside a master (§3.1). */
|
|
103
|
+
declare function Region(props: {
|
|
104
|
+
slot: string;
|
|
105
|
+
extent?: string;
|
|
106
|
+
children?: ReactNode;
|
|
107
|
+
}): ReactElement;
|
|
108
|
+
/** `<t:variant kind>` — first/left/right/blank override inside a master (§3.2). */
|
|
109
|
+
declare function Variant(props: {
|
|
110
|
+
kind: string;
|
|
111
|
+
children?: ReactNode;
|
|
112
|
+
}): ReactElement;
|
|
113
|
+
/** `<t:use-master name>` — switches the active master from flow position (§3.4). */
|
|
114
|
+
declare function UseMaster(props: {
|
|
115
|
+
name: string;
|
|
116
|
+
}): ReactElement;
|
|
117
|
+
/** `<t:footnote>` — inline footnote reference + body (§3.6). */
|
|
118
|
+
declare function Footnote(props: {
|
|
119
|
+
mark?: string;
|
|
120
|
+
reset?: string;
|
|
121
|
+
children?: ReactNode;
|
|
122
|
+
}): ReactElement;
|
|
123
|
+
/** `<t:footnote-separator>` — the rule between body and footnote area (§3.6). */
|
|
124
|
+
declare function FootnoteSeparator(props: {
|
|
125
|
+
children?: ReactNode;
|
|
126
|
+
}): ReactElement;
|
|
127
|
+
/** `<t:counter name action step start>` — a general named counter (§3.8). */
|
|
128
|
+
declare function Counter(props: {
|
|
129
|
+
name: string;
|
|
130
|
+
action?: string;
|
|
131
|
+
step?: string;
|
|
132
|
+
start?: string;
|
|
133
|
+
}): ReactElement;
|
|
134
|
+
/** `<t:leader>` — dot-fill between two inline boxes, for TOCs/footers (§3.10). */
|
|
135
|
+
declare function Leader(props: {
|
|
136
|
+
children?: ReactNode;
|
|
137
|
+
}): ReactElement;
|
|
138
|
+
/** `<t:anchor id>` — a cross-reference target (§3.9, feature-gated in core). */
|
|
139
|
+
declare function Anchor(props: {
|
|
140
|
+
id: string;
|
|
141
|
+
}): ReactElement;
|
|
142
|
+
/** `<t:endnote>` — collects to a `<t:endnotes/>` sink (§3.7, feature-gated). */
|
|
143
|
+
declare function Endnote(props: {
|
|
144
|
+
children?: ReactNode;
|
|
145
|
+
}): ReactElement;
|
|
146
|
+
/** `<t:endnotes/>` — the endnote sink (§3.7, feature-gated). */
|
|
147
|
+
declare function Endnotes(): ReactElement;
|
|
148
|
+
/**
|
|
149
|
+
* Named running element (§3.5). There is **no** `t:running` element in the core's
|
|
150
|
+
* authoritative `t_kind()` table — running content is marked with the
|
|
151
|
+
* `t:running="name"` *attribute* on a normal element (`<h1 t:running="section">`).
|
|
152
|
+
* So `<Running name="section">` renders that attribute on a host element (default
|
|
153
|
+
* `<span>`, override via `as`), optionally with `t:running-policy`.
|
|
154
|
+
*
|
|
155
|
+
* TODO(phase11): the handoff sketched `<Running>` -> `<t:running>`, but node.rs
|
|
156
|
+
* has no such directive; spec §3.5 defines it as an attribute, which is what we emit.
|
|
157
|
+
*/
|
|
158
|
+
declare function Running(props: {
|
|
159
|
+
name: string;
|
|
160
|
+
as?: string;
|
|
161
|
+
policy?: string;
|
|
162
|
+
children?: ReactNode;
|
|
163
|
+
}): ReactElement;
|
|
164
|
+
/** `<t:page/>` — current 1-based page number convenience element (§3.3). */
|
|
165
|
+
declare function Page(): ReactElement;
|
|
166
|
+
/** `<t:pages/>` — total page count convenience element (§3.3). */
|
|
167
|
+
declare function Pages(): ReactElement;
|
|
168
|
+
|
|
169
|
+
export { Anchor, Case, type CompileOptions, Counter, Default, Each, Else, ElseIf, Endnote, Endnotes, Expr, Footnote, FootnoteSeparator, If, Include, Leader, Page, PageMaster, Pages, Raw, Region, Running, RunningFooter, RunningHeader, Switch, UseMaster, Variant, compileTemplate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "turbo-html2pdf-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Author turbo-html2pdf PDF templates as React components — HTML/CSS + Jinja to PDF.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
|
-
"import": "./dist/index.js"
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
17
18
|
}
|
|
18
19
|
},
|
|
19
|
-
"main": "./dist/index.
|
|
20
|
+
"main": "./dist/index.cjs",
|
|
21
|
+
"module": "./dist/index.js",
|
|
20
22
|
"types": "./dist/index.d.ts",
|
|
21
23
|
"peerDependencies": {
|
|
22
24
|
"react": ">=18",
|