postext 0.1.3 → 0.1.4

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.
Files changed (45) hide show
  1. package/dist/__tests__/exports.test.js +25 -0
  2. package/dist/__tests__/exports.test.js.map +1 -1
  3. package/dist/canvas-backend.d.ts +5 -0
  4. package/dist/canvas-backend.d.ts.map +1 -0
  5. package/dist/canvas-backend.js +156 -0
  6. package/dist/canvas-backend.js.map +1 -0
  7. package/dist/createLayout.d.ts +2 -2
  8. package/dist/createLayout.d.ts.map +1 -1
  9. package/dist/createLayout.js +25 -2
  10. package/dist/createLayout.js.map +1 -1
  11. package/dist/defaults.d.ts +15 -3
  12. package/dist/defaults.d.ts.map +1 -1
  13. package/dist/defaults.js +276 -8
  14. package/dist/defaults.js.map +1 -1
  15. package/dist/hyphenate.d.ts +11 -0
  16. package/dist/hyphenate.d.ts.map +1 -0
  17. package/dist/hyphenate.js +140 -0
  18. package/dist/hyphenate.js.map +1 -0
  19. package/dist/index.d.ts +11 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +7 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/measure.d.ts +40 -0
  24. package/dist/measure.d.ts.map +1 -0
  25. package/dist/measure.js +267 -0
  26. package/dist/measure.js.map +1 -0
  27. package/dist/parse.d.ts +17 -0
  28. package/dist/parse.d.ts.map +1 -0
  29. package/dist/parse.js +152 -0
  30. package/dist/parse.js.map +1 -0
  31. package/dist/pipeline.d.ts +4 -0
  32. package/dist/pipeline.d.ts.map +1 -0
  33. package/dist/pipeline.js +324 -0
  34. package/dist/pipeline.js.map +1 -0
  35. package/dist/types.d.ts +111 -7
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/units.d.ts +9 -0
  38. package/dist/units.d.ts.map +1 -0
  39. package/dist/units.js +27 -0
  40. package/dist/units.js.map +1 -0
  41. package/dist/vdt.d.ts +83 -0
  42. package/dist/vdt.d.ts.map +1 -0
  43. package/dist/vdt.js +50 -0
  44. package/dist/vdt.js.map +1 -0
  45. package/package.json +4 -1
@@ -9,10 +9,35 @@ describe("package exports", () => {
9
9
  const exportedKeys = Object.keys(postext);
10
10
  expect(exportedKeys).toEqual([
11
11
  "createLayout",
12
+ "buildDocument",
13
+ "renderToCanvas",
14
+ "renderPage",
15
+ "renderPageToCanvas",
16
+ "dimensionToPx",
17
+ "buildFontString",
18
+ "measureBlock",
19
+ "measureRichBlock",
20
+ "initHyphenator",
21
+ "clearMeasurementCache",
22
+ "hyphenateText",
23
+ "setHyphenationLocale",
24
+ "parseMarkdown",
12
25
  "DEFAULT_PAGE_CONFIG",
13
26
  "PAGE_SIZE_PRESETS",
14
27
  "resolvePageConfig",
28
+ "DEFAULT_LAYOUT_CONFIG",
29
+ "resolveLayoutConfig",
30
+ "stripLayoutDefaults",
31
+ "DEFAULT_BODY_TEXT_CONFIG",
32
+ "DEFAULT_HYPHENATION_CONFIG",
33
+ "resolveBodyTextConfig",
34
+ "stripBodyTextDefaults",
35
+ "hyphenationEqual",
36
+ "DEFAULT_HEADINGS_CONFIG",
37
+ "resolveHeadingsConfig",
38
+ "stripHeadingsDefaults",
15
39
  "dimensionsEqual",
40
+ "colorsEqual",
16
41
  "stripPageDefaults",
17
42
  "stripConfigDefaults",
18
43
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"exports.test.js","sourceRoot":"","sources":["../../src/__tests__/exports.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,UAAU,CAAC;AAEpC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;YAC3B,cAAc;YACd,qBAAqB;YACrB,mBAAmB;YACnB,mBAAmB;YACnB,iBAAiB;YACjB,mBAAmB;YACnB,qBAAqB;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"exports.test.js","sourceRoot":"","sources":["../../src/__tests__/exports.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,UAAU,CAAC;AAEpC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;YAC3B,cAAc;YACd,eAAe;YACf,gBAAgB;YAChB,YAAY;YACZ,oBAAoB;YACpB,eAAe;YACf,iBAAiB;YACjB,cAAc;YACd,kBAAkB;YAClB,gBAAgB;YAChB,uBAAuB;YACvB,eAAe;YACf,sBAAsB;YACtB,eAAe;YACf,qBAAqB;YACrB,mBAAmB;YACnB,mBAAmB;YACnB,uBAAuB;YACvB,qBAAqB;YACrB,qBAAqB;YACrB,0BAA0B;YAC1B,4BAA4B;YAC5B,uBAAuB;YACvB,uBAAuB;YACvB,kBAAkB;YAClB,yBAAyB;YACzB,uBAAuB;YACvB,uBAAuB;YACvB,iBAAiB;YACjB,aAAa;YACb,mBAAmB;YACnB,qBAAqB;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { VDTDocument, VDTPage } from './vdt';
2
+ export declare function renderPageToCanvas(page: VDTPage, doc: VDTDocument, canvas: HTMLCanvasElement): void;
3
+ export declare function renderPage(page: VDTPage, doc: VDTDocument): HTMLCanvasElement;
4
+ export declare function renderToCanvas(doc: VDTDocument): HTMLCanvasElement[];
5
+ //# sourceMappingURL=canvas-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-backend.d.ts","sourceRoot":"","sources":["../src/canvas-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAkC,MAAM,OAAO,CAAC;AAwIlF,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CAqDN;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,iBAAiB,CAInB;AAMD,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,EAAE,CAEpE"}
@@ -0,0 +1,156 @@
1
+ import { dimensionToPx } from './units';
2
+ // ---------------------------------------------------------------------------
3
+ // Baseline grid overlay
4
+ // ---------------------------------------------------------------------------
5
+ function renderBaselineGrid(ctx, contentArea, baselineIncrement, color, lineWidth) {
6
+ ctx.save();
7
+ ctx.strokeStyle = color;
8
+ ctx.lineWidth = lineWidth;
9
+ // Draw one baseline per line that actually fits in the content area.
10
+ // Must match the placement logic: Math.floor(height / lineHeight) lines.
11
+ const maxLines = Math.floor(contentArea.height / baselineIncrement);
12
+ let y = contentArea.y + baselineIncrement * 0.8;
13
+ const right = contentArea.x + contentArea.width;
14
+ for (let i = 0; i < maxLines; i++) {
15
+ ctx.beginPath();
16
+ ctx.moveTo(contentArea.x, y);
17
+ ctx.lineTo(right, y);
18
+ ctx.stroke();
19
+ y += baselineIncrement;
20
+ }
21
+ ctx.restore();
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // Text rendering
25
+ // ---------------------------------------------------------------------------
26
+ function renderLine(ctx, line, font, boldFont, color, textAlign, columnWidth) {
27
+ ctx.fillStyle = color;
28
+ ctx.textBaseline = 'alphabetic';
29
+ const hasBoldSegments = boldFont && line.segments && line.segments.some((s) => s.bold);
30
+ // Justified rendering with per-segment spacing
31
+ if (textAlign === 'justify' && !line.isLastLine && line.segments && line.segments.length > 0) {
32
+ let wordWidth = 0;
33
+ let spaceCount = 0;
34
+ for (const seg of line.segments) {
35
+ if (seg.kind === 'space')
36
+ spaceCount++;
37
+ else
38
+ wordWidth += seg.width;
39
+ }
40
+ if (spaceCount > 0) {
41
+ const justifiedSpaceWidth = (columnWidth - wordWidth) / spaceCount;
42
+ let x = line.bbox.x;
43
+ for (const seg of line.segments) {
44
+ if (seg.kind === 'space') {
45
+ x += justifiedSpaceWidth;
46
+ }
47
+ else {
48
+ ctx.font = seg.bold && boldFont ? boldFont : font;
49
+ ctx.fillText(seg.text, x, line.baseline);
50
+ x += seg.width;
51
+ }
52
+ }
53
+ return;
54
+ }
55
+ }
56
+ // Ragged (left-aligned) rendering — also used for last lines of justified blocks
57
+ // If there are bold segments, render per-segment to apply correct fonts
58
+ if (hasBoldSegments && line.segments) {
59
+ let x = line.bbox.x;
60
+ for (const seg of line.segments) {
61
+ if (seg.kind === 'space') {
62
+ x += seg.width;
63
+ }
64
+ else {
65
+ ctx.font = seg.bold && boldFont ? boldFont : font;
66
+ ctx.fillText(seg.text, x, line.baseline);
67
+ x += seg.width;
68
+ }
69
+ }
70
+ return;
71
+ }
72
+ ctx.font = font;
73
+ ctx.fillText(line.text, line.bbox.x, line.baseline);
74
+ }
75
+ function renderBlock(ctx, block, columnWidth) {
76
+ for (const line of block.lines) {
77
+ renderLine(ctx, line, block.fontString, block.boldFontString, block.color, block.textAlign, columnWidth);
78
+ }
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Page rendering
82
+ // ---------------------------------------------------------------------------
83
+ function computeContentArea(page, doc) {
84
+ const { dpi, margins } = doc.config.page;
85
+ // We can derive content area from page dimensions and margins
86
+ // (same logic as pipeline, but we recalculate from resolved config)
87
+ const pxPerCm = dpi / 2.54;
88
+ const marginTop = margins.top.unit === 'cm' ? margins.top.value * pxPerCm : margins.top.value;
89
+ const marginLeft = margins.left.unit === 'cm' ? margins.left.value * pxPerCm : margins.left.value;
90
+ // Use the first column's bbox to infer content area bounds
91
+ if (page.columns.length > 0) {
92
+ const firstCol = page.columns[0];
93
+ const lastCol = page.columns[page.columns.length - 1];
94
+ return {
95
+ x: firstCol.bbox.x,
96
+ y: firstCol.bbox.y,
97
+ width: (lastCol.bbox.x + lastCol.bbox.width) - firstCol.bbox.x,
98
+ height: firstCol.bbox.height,
99
+ };
100
+ }
101
+ return { x: marginLeft, y: marginTop, width: 0, height: 0 };
102
+ }
103
+ export function renderPageToCanvas(page, doc, canvas) {
104
+ canvas.width = Math.round(page.width);
105
+ canvas.height = Math.round(page.height);
106
+ const ctx = canvas.getContext('2d');
107
+ if (!ctx)
108
+ return;
109
+ // Background
110
+ const bgColor = doc.config.page.backgroundColor.hex;
111
+ if (bgColor && bgColor !== 'transparent') {
112
+ ctx.fillStyle = bgColor;
113
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
114
+ }
115
+ else {
116
+ ctx.fillStyle = '#ffffff';
117
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
118
+ }
119
+ // Baseline grid overlay
120
+ if (doc.config.page.baselineGrid.enabled) {
121
+ const contentArea = computeContentArea(page, doc);
122
+ const isLastPage = page.index === doc.pages.length - 1;
123
+ // On non-last pages, limit the grid to the height actually used by
124
+ // placed blocks so that no "phantom" baselines appear at the bottom
125
+ // when the split / orphan-control algorithm leaves unused space.
126
+ if (!isLastPage && page.columns.length > 0) {
127
+ const maxUsed = Math.max(...page.columns.map((col) => col.bbox.height - col.availableHeight));
128
+ contentArea.height = maxUsed;
129
+ }
130
+ const gridLineWidthPx = dimensionToPx(doc.config.page.baselineGrid.lineWidth, doc.config.page.dpi);
131
+ renderBaselineGrid(ctx, contentArea, doc.baselineGrid, doc.config.page.baselineGrid.color.hex, gridLineWidthPx);
132
+ }
133
+ // Render all blocks (clip to column bounds to prevent overflow)
134
+ for (const col of page.columns) {
135
+ ctx.save();
136
+ ctx.beginPath();
137
+ ctx.rect(col.bbox.x, col.bbox.y, col.bbox.width, col.bbox.height);
138
+ ctx.clip();
139
+ for (const block of col.blocks) {
140
+ renderBlock(ctx, block, col.bbox.width);
141
+ }
142
+ ctx.restore();
143
+ }
144
+ }
145
+ export function renderPage(page, doc) {
146
+ const canvas = document.createElement('canvas');
147
+ renderPageToCanvas(page, doc, canvas);
148
+ return canvas;
149
+ }
150
+ // ---------------------------------------------------------------------------
151
+ // Public API
152
+ // ---------------------------------------------------------------------------
153
+ export function renderToCanvas(doc) {
154
+ return doc.pages.map((page) => renderPage(page, doc));
155
+ }
156
+ //# sourceMappingURL=canvas-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-backend.js","sourceRoot":"","sources":["../src/canvas-backend.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,SAAS,kBAAkB,CACzB,GAA6B,EAC7B,WAAwB,EACxB,iBAAyB,EACzB,KAAa,EACb,SAAiB;IAEjB,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;IACxB,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAE1B,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;IACpE,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,iBAAiB,GAAG,GAAG,CAAC;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;IAEhD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACrB,GAAG,CAAC,MAAM,EAAE,CAAC;QACb,CAAC,IAAI,iBAAiB,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,OAAO,EAAE,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,UAAU,CACjB,GAA6B,EAC7B,IAAa,EACb,IAAY,EACZ,QAA4B,EAC5B,KAAa,EACb,SAA6B,EAC7B,WAAmB;IAEnB,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC;IACtB,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;IAEhC,MAAM,eAAe,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEvF,+CAA+C;IAC/C,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7F,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,UAAU,EAAE,CAAC;;gBAClC,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC;QAC9B,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,mBAAmB,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,UAAU,CAAC;YACnE,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACzB,CAAC,IAAI,mBAAmB,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;oBAClD,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACzC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;gBACjB,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,wEAAwE;IACxE,IAAI,eAAe,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAClD,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAChB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAClB,GAA6B,EAC7B,KAAe,EACf,WAAmB;IAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC3G,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,kBAAkB,CAAC,IAAa,EAAE,GAAgB;IACzD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAEzC,8DAA8D;IAC9D,oEAAoE;IACpE,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC;IAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;IAC9F,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IAElG,2DAA2D;IAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QACvD,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;SAC7B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAa,EACb,GAAgB,EAChB,MAAyB;IAEzB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,aAAa;IACb,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC;IACpD,IAAI,OAAO,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;QACzC,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;QACxB,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;QAC1B,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,wBAAwB;IACxB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEvD,mEAAmE;QACnE,oEAAoE;QACpE,iEAAiE;QACjE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,CACpE,CAAC;YACF,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC;QAC/B,CAAC;QAED,MAAM,eAAe,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnG,kBAAkB,CAChB,GAAG,EACH,WAAW,EACX,GAAG,CAAC,YAAY,EAChB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EACtC,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,gEAAgE;IAChE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClE,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC/B,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,IAAa,EACb,GAAgB;IAEhB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,UAAU,cAAc,CAAC,GAAgB;IAC7C,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { FC } from 'react';
1
+ import { type FC } from 'react';
2
2
  import type { PostextContent, PostextConfig } from './types';
3
- export declare function createLayout(_content: PostextContent, _config?: PostextConfig): FC;
3
+ export declare function createLayout(content: PostextContent, config?: PostextConfig): FC;
4
4
  //# sourceMappingURL=createLayout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createLayout.d.ts","sourceRoot":"","sources":["../src/createLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7D,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,EAAE,CAIJ"}
1
+ {"version":3,"file":"createLayout.d.ts","sourceRoot":"","sources":["../src/createLayout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAqB,MAAM,OAAO,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7D,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,GACrB,EAAE,CA6BJ"}
@@ -1,5 +1,28 @@
1
- export function createLayout(_content, _config) {
2
- const Layout = () => null;
1
+ import { useEffect, useRef } from 'react';
2
+ import { buildDocument } from './pipeline';
3
+ import { renderToCanvas } from './canvas-backend';
4
+ export function createLayout(content, config) {
5
+ const Layout = () => {
6
+ const containerRef = useRef(null);
7
+ useEffect(() => {
8
+ const container = containerRef.current;
9
+ if (!container)
10
+ return;
11
+ const doc = buildDocument(content, config);
12
+ const pages = renderToCanvas(doc);
13
+ // Clear previous content
14
+ container.innerHTML = '';
15
+ // Display all pages
16
+ for (const canvas of pages) {
17
+ canvas.style.width = '100%';
18
+ canvas.style.height = 'auto';
19
+ canvas.style.display = 'block';
20
+ canvas.style.marginBottom = '16px';
21
+ container.appendChild(canvas);
22
+ }
23
+ }, []);
24
+ return null;
25
+ };
3
26
  Layout.displayName = 'PostextLayout';
4
27
  return Layout;
5
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createLayout.js","sourceRoot":"","sources":["../src/createLayout.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,YAAY,CAC1B,QAAwB,EACxB,OAAuB;IAEvB,MAAM,MAAM,GAAO,GAAG,EAAE,CAAC,IAAI,CAAC;IAC9B,MAAM,CAAC,WAAW,GAAG,eAAe,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"createLayout.js","sourceRoot":"","sources":["../src/createLayout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,YAAY,CAC1B,OAAuB,EACvB,MAAsB;IAEtB,MAAM,MAAM,GAAO,GAAG,EAAE;QACtB,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;QAElD,SAAS,CAAC,GAAG,EAAE;YACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;YACvC,IAAI,CAAC,SAAS;gBAAE,OAAO;YAEvB,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YAElC,yBAAyB;YACzB,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;YAEzB,oBAAoB;YACpB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;gBAC5B,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;gBAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC/B,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;gBACnC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,CAAC,WAAW,GAAG,eAAe,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,11 +1,23 @@
1
- import type { PageConfig, PageSizePreset, Dimension, PostextConfig } from './types';
1
+ import type { PageConfig, ResolvedPageConfig, PageSizePreset, Dimension, PostextConfig, LayoutConfig, ResolvedLayoutConfig, BodyTextConfig, ResolvedBodyTextConfig, HeadingsConfig, ResolvedHeadingsConfig, ColorValue, HyphenationConfig } from './types';
2
2
  export declare const PAGE_SIZE_PRESETS: Record<Exclude<PageSizePreset, 'custom'>, {
3
3
  width: Dimension;
4
4
  height: Dimension;
5
5
  }>;
6
- export declare const DEFAULT_PAGE_CONFIG: Required<PageConfig>;
6
+ export declare const DEFAULT_PAGE_CONFIG: ResolvedPageConfig;
7
7
  export declare function dimensionsEqual(a: Dimension, b: Dimension): boolean;
8
+ export declare function colorsEqual(a: ColorValue, b: ColorValue): boolean;
8
9
  export declare function stripPageDefaults(page?: PageConfig): PageConfig | undefined;
10
+ export declare const DEFAULT_LAYOUT_CONFIG: ResolvedLayoutConfig;
11
+ export declare function stripLayoutDefaults(layout?: LayoutConfig): LayoutConfig | undefined;
12
+ export declare const DEFAULT_HYPHENATION_CONFIG: ResolvedBodyTextConfig['hyphenation'];
13
+ export declare const DEFAULT_BODY_TEXT_CONFIG: ResolvedBodyTextConfig;
14
+ export declare function hyphenationEqual(a: HyphenationConfig | undefined, b: HyphenationConfig | undefined): boolean;
15
+ export declare function stripBodyTextDefaults(bodyText?: BodyTextConfig): BodyTextConfig | undefined;
16
+ export declare const DEFAULT_HEADINGS_CONFIG: ResolvedHeadingsConfig;
17
+ export declare function stripHeadingsDefaults(headings?: HeadingsConfig): HeadingsConfig | undefined;
9
18
  export declare function stripConfigDefaults(config: PostextConfig): PostextConfig;
10
- export declare function resolvePageConfig(partial?: PageConfig): Required<PageConfig>;
19
+ export declare function resolvePageConfig(partial?: PageConfig): ResolvedPageConfig;
20
+ export declare function resolveLayoutConfig(partial?: LayoutConfig): ResolvedLayoutConfig;
21
+ export declare function resolveBodyTextConfig(partial?: BodyTextConfig): ResolvedBodyTextConfig;
22
+ export declare function resolveHeadingsConfig(partial?: HeadingsConfig): ResolvedHeadingsConfig;
11
23
  //# sourceMappingURL=defaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAe,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEjG,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,EACjC;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAMxC,CAAC;AASF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,UAAU,CASpD,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAEnE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAyD3E;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CASxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,CAyB5E"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAe,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,sBAAsB,EAAE,cAAc,EAAsB,sBAAsB,EAA8B,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAExT,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,EACjC;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAMxC,CAAC;AASF,eAAO,MAAM,mBAAmB,EAAE,kBASjC,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAEnE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CA2D3E;AAED,eAAO,MAAM,qBAAqB,EAAE,oBAInC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,SAAS,CAoBnF;AAED,eAAO,MAAM,0BAA0B,EAAE,sBAAsB,CAAC,aAAa,CAG5E,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,sBAStC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,iBAAiB,GAAG,SAAS,EAAE,CAAC,EAAE,iBAAiB,GAAG,SAAS,GAAG,OAAO,CAK5G;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,CAwC3F;AAkBD,eAAO,MAAM,uBAAuB,EAAE,sBASrC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,CA8E3F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CA2BxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,kBAAkB,CA0B1E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,oBAAoB,CAQhF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,sBAAsB,CAgBtF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,sBAAsB,CA0BtF"}
package/dist/defaults.js CHANGED
@@ -7,28 +7,31 @@ export const PAGE_SIZE_PRESETS = {
7
7
  const DEFAULT_PAGE_MARGINS = {
8
8
  top: { value: 2, unit: 'cm' },
9
9
  bottom: { value: 2, unit: 'cm' },
10
- left: { value: 2, unit: 'cm' },
11
- right: { value: 2, unit: 'cm' },
10
+ left: { value: 1.5, unit: 'cm' },
11
+ right: { value: 1.5, unit: 'cm' },
12
12
  };
13
13
  export const DEFAULT_PAGE_CONFIG = {
14
- backgroundColor: '#ffffff',
14
+ backgroundColor: { hex: 'transparent', model: 'hex' },
15
15
  sizePreset: '17x24',
16
16
  width: { value: 17, unit: 'cm' },
17
17
  height: { value: 24, unit: 'cm' },
18
18
  margins: DEFAULT_PAGE_MARGINS,
19
19
  dpi: 300,
20
20
  cutLines: false,
21
- baselineGrid: { enabled: false, color: '#cccccc' },
21
+ baselineGrid: { enabled: false, color: { hex: '#cccccc', model: 'hex' }, lineWidth: { value: 0.5, unit: 'pt' } },
22
22
  };
23
23
  export function dimensionsEqual(a, b) {
24
24
  return a.value === b.value && a.unit === b.unit;
25
25
  }
26
+ export function colorsEqual(a, b) {
27
+ return a.hex === b.hex && a.model === b.model;
28
+ }
26
29
  export function stripPageDefaults(page) {
27
30
  if (!page)
28
31
  return undefined;
29
32
  const result = {};
30
33
  let hasOverride = false;
31
- if (page.backgroundColor !== undefined && page.backgroundColor !== DEFAULT_PAGE_CONFIG.backgroundColor) {
34
+ if (page.backgroundColor !== undefined && !colorsEqual(page.backgroundColor, DEFAULT_PAGE_CONFIG.backgroundColor)) {
32
35
  result.backgroundColor = page.backgroundColor;
33
36
  hasOverride = true;
34
37
  }
@@ -54,7 +57,7 @@ export function stripPageDefaults(page) {
54
57
  }
55
58
  }
56
59
  if (hasMarginOverride) {
57
- result.margins = { ...DEFAULT_PAGE_MARGINS, ...m };
60
+ result.margins = m;
58
61
  hasOverride = true;
59
62
  }
60
63
  }
@@ -68,17 +71,209 @@ export function stripPageDefaults(page) {
68
71
  }
69
72
  if (page.baselineGrid) {
70
73
  const enabledOverride = page.baselineGrid.enabled !== undefined && page.baselineGrid.enabled !== DEFAULT_PAGE_CONFIG.baselineGrid.enabled;
71
- const colorOverride = page.baselineGrid.color !== undefined && page.baselineGrid.color !== DEFAULT_PAGE_CONFIG.baselineGrid.color;
72
- if (enabledOverride || colorOverride) {
74
+ const colorOverride = page.baselineGrid.color !== undefined && !colorsEqual(page.baselineGrid.color, DEFAULT_PAGE_CONFIG.baselineGrid.color);
75
+ const lineWidthOverride = page.baselineGrid.lineWidth !== undefined && !dimensionsEqual(page.baselineGrid.lineWidth, DEFAULT_PAGE_CONFIG.baselineGrid.lineWidth);
76
+ if (enabledOverride || colorOverride || lineWidthOverride) {
73
77
  result.baselineGrid = {
74
78
  enabled: page.baselineGrid.enabled ?? DEFAULT_PAGE_CONFIG.baselineGrid.enabled,
75
79
  ...(colorOverride ? { color: page.baselineGrid.color } : {}),
80
+ ...(lineWidthOverride ? { lineWidth: page.baselineGrid.lineWidth } : {}),
76
81
  };
77
82
  hasOverride = true;
78
83
  }
79
84
  }
80
85
  return hasOverride ? result : undefined;
81
86
  }
87
+ export const DEFAULT_LAYOUT_CONFIG = {
88
+ layoutType: 'double',
89
+ gutterWidth: { value: 0.75, unit: 'cm' },
90
+ sideColumnPercent: 33,
91
+ };
92
+ export function stripLayoutDefaults(layout) {
93
+ if (!layout)
94
+ return undefined;
95
+ const result = {};
96
+ let hasOverride = false;
97
+ if (layout.layoutType !== undefined && layout.layoutType !== DEFAULT_LAYOUT_CONFIG.layoutType) {
98
+ result.layoutType = layout.layoutType;
99
+ hasOverride = true;
100
+ }
101
+ if (layout.gutterWidth !== undefined && !dimensionsEqual(layout.gutterWidth, DEFAULT_LAYOUT_CONFIG.gutterWidth)) {
102
+ result.gutterWidth = layout.gutterWidth;
103
+ hasOverride = true;
104
+ }
105
+ if (layout.sideColumnPercent !== undefined && layout.sideColumnPercent !== DEFAULT_LAYOUT_CONFIG.sideColumnPercent) {
106
+ result.sideColumnPercent = layout.sideColumnPercent;
107
+ hasOverride = true;
108
+ }
109
+ return hasOverride ? result : undefined;
110
+ }
111
+ export const DEFAULT_HYPHENATION_CONFIG = {
112
+ enabled: true,
113
+ locale: 'en-us',
114
+ };
115
+ export const DEFAULT_BODY_TEXT_CONFIG = {
116
+ fontFamily: 'EB Garamond',
117
+ fontSize: { value: 9, unit: 'pt' },
118
+ lineHeight: { value: 1.5, unit: 'em' },
119
+ color: { hex: '#000000', model: 'cmyk' },
120
+ textAlign: 'justify',
121
+ fontWeight: 400,
122
+ boldFontWeight: 700,
123
+ hyphenation: { ...DEFAULT_HYPHENATION_CONFIG },
124
+ };
125
+ export function hyphenationEqual(a, b) {
126
+ if (!a && !b)
127
+ return true;
128
+ if (!a || !b)
129
+ return false;
130
+ return (a.enabled ?? DEFAULT_HYPHENATION_CONFIG.enabled) === (b.enabled ?? DEFAULT_HYPHENATION_CONFIG.enabled)
131
+ && (a.locale ?? DEFAULT_HYPHENATION_CONFIG.locale) === (b.locale ?? DEFAULT_HYPHENATION_CONFIG.locale);
132
+ }
133
+ export function stripBodyTextDefaults(bodyText) {
134
+ if (!bodyText)
135
+ return undefined;
136
+ const result = {};
137
+ let hasOverride = false;
138
+ if (bodyText.fontFamily !== undefined && bodyText.fontFamily !== DEFAULT_BODY_TEXT_CONFIG.fontFamily) {
139
+ result.fontFamily = bodyText.fontFamily;
140
+ hasOverride = true;
141
+ }
142
+ if (bodyText.fontSize !== undefined && !dimensionsEqual(bodyText.fontSize, DEFAULT_BODY_TEXT_CONFIG.fontSize)) {
143
+ result.fontSize = bodyText.fontSize;
144
+ hasOverride = true;
145
+ }
146
+ if (bodyText.lineHeight !== undefined && !dimensionsEqual(bodyText.lineHeight, DEFAULT_BODY_TEXT_CONFIG.lineHeight)) {
147
+ result.lineHeight = bodyText.lineHeight;
148
+ hasOverride = true;
149
+ }
150
+ if (bodyText.color !== undefined && !colorsEqual(bodyText.color, DEFAULT_BODY_TEXT_CONFIG.color)) {
151
+ result.color = bodyText.color;
152
+ hasOverride = true;
153
+ }
154
+ if (bodyText.textAlign !== undefined && bodyText.textAlign !== DEFAULT_BODY_TEXT_CONFIG.textAlign) {
155
+ result.textAlign = bodyText.textAlign;
156
+ hasOverride = true;
157
+ }
158
+ if (bodyText.fontWeight !== undefined && bodyText.fontWeight !== DEFAULT_BODY_TEXT_CONFIG.fontWeight) {
159
+ result.fontWeight = bodyText.fontWeight;
160
+ hasOverride = true;
161
+ }
162
+ if (bodyText.boldFontWeight !== undefined && bodyText.boldFontWeight !== DEFAULT_BODY_TEXT_CONFIG.boldFontWeight) {
163
+ result.boldFontWeight = bodyText.boldFontWeight;
164
+ hasOverride = true;
165
+ }
166
+ if (bodyText.hyphenation && !hyphenationEqual(bodyText.hyphenation, DEFAULT_BODY_TEXT_CONFIG.hyphenation)) {
167
+ result.hyphenation = bodyText.hyphenation;
168
+ hasOverride = true;
169
+ }
170
+ return hasOverride ? result : undefined;
171
+ }
172
+ const DEFAULT_HEADING_FONT = 'Open Sans';
173
+ const DEFAULT_HEADING_LINE_HEIGHT = { value: 1.2, unit: 'em' };
174
+ const DEFAULT_HEADING_COLOR = { hex: '#000000', model: 'cmyk' };
175
+ const DEFAULT_HEADING_FONT_WEIGHT = 700;
176
+ const DEFAULT_HEADING_MARGIN_TOP = { value: 1.5, unit: 'em' };
177
+ const DEFAULT_HEADING_MARGIN_BOTTOM = { value: 0.5, unit: 'em' };
178
+ const DEFAULT_HEADING_LEVELS = [
179
+ { level: 1, fontSize: { value: 18, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
180
+ { level: 2, fontSize: { value: 15, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
181
+ { level: 3, fontSize: { value: 12, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
182
+ { level: 4, fontSize: { value: 10, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
183
+ { level: 5, fontSize: { value: 9, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
184
+ { level: 6, fontSize: { value: 8, unit: 'pt' }, lineHeight: DEFAULT_HEADING_LINE_HEIGHT, fontFamily: DEFAULT_HEADING_FONT, color: DEFAULT_HEADING_COLOR, fontWeight: DEFAULT_HEADING_FONT_WEIGHT, marginTop: DEFAULT_HEADING_MARGIN_TOP, marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM },
185
+ ];
186
+ export const DEFAULT_HEADINGS_CONFIG = {
187
+ fontFamily: DEFAULT_HEADING_FONT,
188
+ lineHeight: DEFAULT_HEADING_LINE_HEIGHT,
189
+ color: DEFAULT_HEADING_COLOR,
190
+ textAlign: 'left',
191
+ fontWeight: DEFAULT_HEADING_FONT_WEIGHT,
192
+ marginTop: DEFAULT_HEADING_MARGIN_TOP,
193
+ marginBottom: DEFAULT_HEADING_MARGIN_BOTTOM,
194
+ levels: DEFAULT_HEADING_LEVELS,
195
+ };
196
+ export function stripHeadingsDefaults(headings) {
197
+ if (!headings)
198
+ return undefined;
199
+ const result = {};
200
+ let hasOverride = false;
201
+ if (headings.fontFamily !== undefined && headings.fontFamily !== DEFAULT_HEADINGS_CONFIG.fontFamily) {
202
+ result.fontFamily = headings.fontFamily;
203
+ hasOverride = true;
204
+ }
205
+ if (headings.lineHeight !== undefined && !dimensionsEqual(headings.lineHeight, DEFAULT_HEADINGS_CONFIG.lineHeight)) {
206
+ result.lineHeight = headings.lineHeight;
207
+ hasOverride = true;
208
+ }
209
+ if (headings.color !== undefined && !colorsEqual(headings.color, DEFAULT_HEADINGS_CONFIG.color)) {
210
+ result.color = headings.color;
211
+ hasOverride = true;
212
+ }
213
+ if (headings.textAlign !== undefined && headings.textAlign !== DEFAULT_HEADINGS_CONFIG.textAlign) {
214
+ result.textAlign = headings.textAlign;
215
+ hasOverride = true;
216
+ }
217
+ if (headings.fontWeight !== undefined && headings.fontWeight !== DEFAULT_HEADINGS_CONFIG.fontWeight) {
218
+ result.fontWeight = headings.fontWeight;
219
+ hasOverride = true;
220
+ }
221
+ if (headings.marginTop !== undefined && !dimensionsEqual(headings.marginTop, DEFAULT_HEADINGS_CONFIG.marginTop)) {
222
+ result.marginTop = headings.marginTop;
223
+ hasOverride = true;
224
+ }
225
+ if (headings.marginBottom !== undefined && !dimensionsEqual(headings.marginBottom, DEFAULT_HEADINGS_CONFIG.marginBottom)) {
226
+ result.marginBottom = headings.marginBottom;
227
+ hasOverride = true;
228
+ }
229
+ if (headings.levels && headings.levels.length > 0) {
230
+ const strippedLevels = [];
231
+ for (const level of headings.levels) {
232
+ const def = DEFAULT_HEADING_LEVELS.find((d) => d.level === level.level);
233
+ if (!def) {
234
+ strippedLevels.push(level);
235
+ continue;
236
+ }
237
+ const entry = { level: level.level };
238
+ let levelHasOverride = false;
239
+ if (level.fontSize !== undefined && !dimensionsEqual(level.fontSize, def.fontSize)) {
240
+ entry.fontSize = level.fontSize;
241
+ levelHasOverride = true;
242
+ }
243
+ if (level.lineHeight !== undefined && !dimensionsEqual(level.lineHeight, def.lineHeight)) {
244
+ entry.lineHeight = level.lineHeight;
245
+ levelHasOverride = true;
246
+ }
247
+ if (level.fontFamily !== undefined && level.fontFamily !== def.fontFamily) {
248
+ entry.fontFamily = level.fontFamily;
249
+ levelHasOverride = true;
250
+ }
251
+ if (level.color !== undefined && !colorsEqual(level.color, def.color)) {
252
+ entry.color = level.color;
253
+ levelHasOverride = true;
254
+ }
255
+ if (level.fontWeight !== undefined && level.fontWeight !== def.fontWeight) {
256
+ entry.fontWeight = level.fontWeight;
257
+ levelHasOverride = true;
258
+ }
259
+ if (level.marginTop !== undefined && !dimensionsEqual(level.marginTop, def.marginTop)) {
260
+ entry.marginTop = level.marginTop;
261
+ levelHasOverride = true;
262
+ }
263
+ if (level.marginBottom !== undefined && !dimensionsEqual(level.marginBottom, def.marginBottom)) {
264
+ entry.marginBottom = level.marginBottom;
265
+ levelHasOverride = true;
266
+ }
267
+ if (levelHasOverride)
268
+ strippedLevels.push(entry);
269
+ }
270
+ if (strippedLevels.length > 0) {
271
+ result.levels = strippedLevels;
272
+ hasOverride = true;
273
+ }
274
+ }
275
+ return hasOverride ? result : undefined;
276
+ }
82
277
  export function stripConfigDefaults(config) {
83
278
  const result = { ...config };
84
279
  const strippedPage = stripPageDefaults(config.page);
@@ -88,6 +283,27 @@ export function stripConfigDefaults(config) {
88
283
  else {
89
284
  delete result.page;
90
285
  }
286
+ const strippedLayout = stripLayoutDefaults(config.layout);
287
+ if (strippedLayout) {
288
+ result.layout = strippedLayout;
289
+ }
290
+ else {
291
+ delete result.layout;
292
+ }
293
+ const strippedBodyText = stripBodyTextDefaults(config.bodyText);
294
+ if (strippedBodyText) {
295
+ result.bodyText = strippedBodyText;
296
+ }
297
+ else {
298
+ delete result.bodyText;
299
+ }
300
+ const strippedHeadings = stripHeadingsDefaults(config.headings);
301
+ if (strippedHeadings) {
302
+ result.headings = strippedHeadings;
303
+ }
304
+ else {
305
+ delete result.headings;
306
+ }
91
307
  return result;
92
308
  }
93
309
  export function resolvePageConfig(partial) {
@@ -112,8 +328,60 @@ export function resolvePageConfig(partial) {
112
328
  ? {
113
329
  enabled: partial.baselineGrid.enabled ?? DEFAULT_PAGE_CONFIG.baselineGrid.enabled,
114
330
  color: partial.baselineGrid.color ?? DEFAULT_PAGE_CONFIG.baselineGrid.color,
331
+ lineWidth: partial.baselineGrid.lineWidth ?? DEFAULT_PAGE_CONFIG.baselineGrid.lineWidth,
115
332
  }
116
333
  : { ...DEFAULT_PAGE_CONFIG.baselineGrid },
117
334
  };
118
335
  }
336
+ export function resolveLayoutConfig(partial) {
337
+ if (!partial)
338
+ return { ...DEFAULT_LAYOUT_CONFIG };
339
+ return {
340
+ layoutType: partial.layoutType ?? DEFAULT_LAYOUT_CONFIG.layoutType,
341
+ gutterWidth: partial.gutterWidth ?? DEFAULT_LAYOUT_CONFIG.gutterWidth,
342
+ sideColumnPercent: partial.sideColumnPercent ?? DEFAULT_LAYOUT_CONFIG.sideColumnPercent,
343
+ };
344
+ }
345
+ export function resolveBodyTextConfig(partial) {
346
+ if (!partial)
347
+ return { ...DEFAULT_BODY_TEXT_CONFIG, hyphenation: { ...DEFAULT_HYPHENATION_CONFIG } };
348
+ return {
349
+ fontFamily: partial.fontFamily ?? DEFAULT_BODY_TEXT_CONFIG.fontFamily,
350
+ fontSize: partial.fontSize ?? DEFAULT_BODY_TEXT_CONFIG.fontSize,
351
+ lineHeight: partial.lineHeight ?? DEFAULT_BODY_TEXT_CONFIG.lineHeight,
352
+ color: partial.color ?? DEFAULT_BODY_TEXT_CONFIG.color,
353
+ textAlign: partial.textAlign ?? DEFAULT_BODY_TEXT_CONFIG.textAlign,
354
+ fontWeight: partial.fontWeight ?? DEFAULT_BODY_TEXT_CONFIG.fontWeight,
355
+ boldFontWeight: partial.boldFontWeight ?? DEFAULT_BODY_TEXT_CONFIG.boldFontWeight,
356
+ hyphenation: {
357
+ enabled: partial.hyphenation?.enabled ?? DEFAULT_HYPHENATION_CONFIG.enabled,
358
+ locale: partial.hyphenation?.locale ?? DEFAULT_HYPHENATION_CONFIG.locale,
359
+ },
360
+ };
361
+ }
362
+ export function resolveHeadingsConfig(partial) {
363
+ if (!partial)
364
+ return { ...DEFAULT_HEADINGS_CONFIG, levels: DEFAULT_HEADING_LEVELS.map((l) => ({ ...l })) };
365
+ const generalFont = partial.fontFamily ?? DEFAULT_HEADINGS_CONFIG.fontFamily;
366
+ const generalLineHeight = partial.lineHeight ?? DEFAULT_HEADINGS_CONFIG.lineHeight;
367
+ const generalColor = partial.color ?? DEFAULT_HEADINGS_CONFIG.color;
368
+ const generalTextAlign = partial.textAlign ?? DEFAULT_HEADINGS_CONFIG.textAlign;
369
+ const generalFontWeight = partial.fontWeight ?? DEFAULT_HEADINGS_CONFIG.fontWeight;
370
+ const generalMarginTop = partial.marginTop ?? DEFAULT_HEADINGS_CONFIG.marginTop;
371
+ const generalMarginBottom = partial.marginBottom ?? DEFAULT_HEADINGS_CONFIG.marginBottom;
372
+ const levels = DEFAULT_HEADING_LEVELS.map((def) => {
373
+ const override = partial.levels?.find((l) => l.level === def.level);
374
+ return {
375
+ level: def.level,
376
+ fontSize: override?.fontSize ?? def.fontSize,
377
+ lineHeight: override?.lineHeight ?? generalLineHeight,
378
+ fontFamily: override?.fontFamily ?? generalFont,
379
+ color: override?.color ?? generalColor,
380
+ fontWeight: override?.fontWeight ?? generalFontWeight,
381
+ marginTop: override?.marginTop ?? generalMarginTop,
382
+ marginBottom: override?.marginBottom ?? generalMarginBottom,
383
+ };
384
+ });
385
+ return { fontFamily: generalFont, lineHeight: generalLineHeight, color: generalColor, textAlign: generalTextAlign, fontWeight: generalFontWeight, marginTop: generalMarginTop, marginBottom: generalMarginBottom, levels };
386
+ }
119
387
  //# sourceMappingURL=defaults.js.map