@quario/pdf 0.7.0 → 0.8.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/CHANGELOG.md +37 -61
- package/README.md +11 -0
- package/lib/painter.js +3 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,39 +1,51 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @quario/pdf
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 0.8.0
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
|
+
### Minor Changes
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
- **An image's box is now as wide as the container it sits in.** A
|
|
8
|
+
`background` or `border*` on an image item hugged the picture and now spans
|
|
9
|
+
the content width, or the slot's share inside a split; the picture itself
|
|
10
|
+
does not move. See the `@quario/layout` changelog for the rule and for what
|
|
11
|
+
it costs a report that relied on a border hugging a logo.
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
### Patch Changes
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
- **Every published README says where the documentation is.** Each package now
|
|
16
|
+
carries a Documentation section pointing at the reference, at the report schema
|
|
17
|
+
that normatively specifies what a report may declare, and at the package's own
|
|
18
|
+
API. The paragraphs that used to end on an unstated contract — the event
|
|
19
|
+
stream's field semantics, the style vocabulary, page columns, the Content
|
|
20
|
+
Security Policy a fragment with images needs, the formula mangling, and each
|
|
21
|
+
target's own contract — link the page that states it. Every link is an absolute
|
|
22
|
+
URL, so it resolves from the npm package page as readily as from an installed
|
|
23
|
+
copy.
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- @quario/layout@0.5.0
|
|
26
|
+
- quario@0.8.0
|
|
27
|
+
|
|
28
|
+
## 0.7.0
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
13
31
|
|
|
14
32
|
- **Styled runs reach the page.** A cell value written as a list of styled runs
|
|
15
33
|
draws each run in its own face, size and colour, underlines and strikes
|
|
16
34
|
through per run rather than across the line, and paints a run's `background`
|
|
17
35
|
as a highlight behind its text.
|
|
18
|
-
|
|
19
|
-
### Changed
|
|
20
|
-
|
|
21
36
|
- **A `format` inside a sentence now presents where the engine says it does.** A
|
|
22
37
|
cell mixing literal text and one interpolation under a `format` draws the
|
|
23
38
|
value plainly, as the spreadsheet and CSV targets already did; splitting the
|
|
24
39
|
value into styled runs is how a value inside a sentence is formatted.
|
|
25
40
|
|
|
26
|
-
##
|
|
41
|
+
## 0.6.0
|
|
27
42
|
|
|
28
|
-
###
|
|
43
|
+
### Minor Changes
|
|
29
44
|
|
|
30
45
|
- **A cell's own `currency` code is honoured**, ahead of the instance's
|
|
31
46
|
default, so a listing whose rows arrive in different currencies presents each
|
|
32
47
|
in its own. A code the engine could not accept leaves the cell as plain
|
|
33
48
|
display text rather than presenting it in the instance's currency.
|
|
34
|
-
|
|
35
|
-
### Changed
|
|
36
|
-
|
|
37
49
|
- **Numbers presented through `format` now show a fixed two fraction digits,
|
|
38
50
|
matching every other target.** `format: "number"` on `1000` renders
|
|
39
51
|
`1,000.00` where it rendered `1,000`, and `0.12345` renders `0.12` where it
|
|
@@ -42,9 +54,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
54
|
so a JPY amount loses the two decimals it never had. `date` is unchanged, as
|
|
43
55
|
are grouping separators and symbol placement. The digits come from the
|
|
44
56
|
engine, so a cell reads the same here as it does in a workbook.
|
|
45
|
-
|
|
46
|
-
### Fixed
|
|
47
|
-
|
|
48
57
|
- **An image these bytes cannot embed now fails with the item's name on it.**
|
|
49
58
|
A PNG whose pixel data is corrupt past the size in its header used to reject
|
|
50
59
|
the render with `Invalid typed array length: 0` — the PDF writer's own words,
|
|
@@ -54,9 +63,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
54
63
|
account after it and on `cause`. A JPEG is unchanged: its header is read but
|
|
55
64
|
its pixel data never is, so a corrupt one still embeds without complaint.
|
|
56
65
|
|
|
57
|
-
##
|
|
66
|
+
## 0.5.0
|
|
58
67
|
|
|
59
|
-
###
|
|
68
|
+
### Minor Changes
|
|
60
69
|
|
|
61
70
|
- **A spanning cell draws as one box** across the columns it covers, through
|
|
62
71
|
`@quario/layout`. It takes no part in measuring them, and a spanning row that
|
|
@@ -64,16 +73,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
64
73
|
each slice lands in.
|
|
65
74
|
- **`valign`** on table cells and split slots, through `@quario/layout`: middle
|
|
66
75
|
and bottom place the content in the height its row or split leaves over it.
|
|
67
|
-
|
|
68
|
-
### Changed
|
|
69
|
-
|
|
70
76
|
- **A row's box is drawn by the row's cells**, through `@quario/layout`. A box
|
|
71
77
|
declared on a table row used to be one rect across the columns; each covered
|
|
72
78
|
cell now draws its own. A row's `borderBottom` still reads as one continuous
|
|
73
79
|
edge, a row's `borderLeft` becomes an edge on every cell rather than one at
|
|
74
80
|
the row's outer left, and a bordered row is taller by its border's width,
|
|
75
81
|
since a border occupies height as a cell's always has.
|
|
76
|
-
|
|
77
82
|
- **Embedding TrueType fonts now needs `fontkit`, not `@pdf-lib/fontkit`.**
|
|
78
83
|
Install `fontkit` instead; nothing else about `options.fonts` changes. The
|
|
79
84
|
old package's bundle crashed with a bare `ReferenceError` on any OpenType
|
|
@@ -81,28 +86,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
81
86
|
Tamil, Khmer or Myanmar webfont in practice, and some fifty further scripts
|
|
82
87
|
besides. Those faces now measure, embed and draw. Which scripts a face
|
|
83
88
|
supports remains the font's and the parser's to answer, not this package's.
|
|
84
|
-
|
|
85
89
|
- **`pdf-lib` is now `@cantoo/pdf-lib`.** A maintained fork, and what
|
|
86
90
|
`fontkit`'s subsetting requires. Rendered documents are unchanged in what
|
|
87
91
|
they draw: every drawn string is identical and every filled area lands in
|
|
88
92
|
the same place, but the file's bytes differ, so a host comparing digests
|
|
89
93
|
against stored output will see them move once.
|
|
90
94
|
|
|
91
|
-
##
|
|
95
|
+
## 0.4.0
|
|
92
96
|
|
|
93
|
-
###
|
|
97
|
+
### Minor Changes
|
|
94
98
|
|
|
95
99
|
- **A split slot's box now fills the split's height.** A slot's background and
|
|
96
100
|
border stopped at that slot's own content and now take the split's height,
|
|
97
101
|
the way a table cell's take their row's. See the `@quario/layout` changelog
|
|
98
102
|
for the rule and for what it costs a report that relied on the short box.
|
|
99
|
-
|
|
100
103
|
- **A date string under `format: "date"` now presents as a date.** The
|
|
101
104
|
drawn text comes from the engine's `format()` helper, which revives the two
|
|
102
105
|
read forms. See the `quario` changelog for the forms and the timezone rule.
|
|
103
|
-
|
|
104
|
-
### Changed
|
|
105
|
-
|
|
106
106
|
- **The layout moved to `@quario/layout`; this target paints its list.**
|
|
107
107
|
Measurement, wrapping, pagination, page furniture, the marking's geometry
|
|
108
108
|
and the page-size table now live in the layout package, which this target
|
|
@@ -112,16 +112,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
112
112
|
options are the layout's own, so the same object configures `pdf()`, the
|
|
113
113
|
viewer and the editor. The font mapping's shape is now refused at the
|
|
114
114
|
factory call rather than at render.
|
|
115
|
-
|
|
116
|
-
### Fixed
|
|
117
|
-
|
|
118
115
|
- **A nested group's footer keeps the page columns.** Inside a page-column
|
|
119
116
|
region, the first footer of a group nested in it ended the region: the
|
|
120
117
|
strips collapsed and every band after it was laid out across the page, as
|
|
121
118
|
if `columns` were absent. Only the node that declared `columns` closes its
|
|
122
119
|
own region now — a nested group's header and footer are region content,
|
|
123
120
|
laid out in the strips.
|
|
124
|
-
|
|
125
121
|
- **A padded or bordered item or row that breaks across a page keeps its
|
|
126
122
|
box.** Content too tall for one page is drawn as slices, and a slice now
|
|
127
123
|
carries the box sides the break left it — the top on the first, the bottom
|
|
@@ -133,60 +129,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
133
129
|
the horizontal padding they were wrapped for, rather than flush to the
|
|
134
130
|
column. **This changes output** for reports where such content breaks.
|
|
135
131
|
|
|
136
|
-
##
|
|
132
|
+
## 0.3.0
|
|
137
133
|
|
|
138
|
-
###
|
|
134
|
+
### Minor Changes
|
|
139
135
|
|
|
140
136
|
- **`format` stringifies at the edge from the instance locale.** A PDF
|
|
141
137
|
without a host locale still uses `en-US` / UTC, so the bytes stay
|
|
142
138
|
reproducible.
|
|
143
|
-
|
|
144
139
|
- **A height-declared report header pins from the page top.** Leftover sits
|
|
145
140
|
under the items; the next band starts at the pin. The half-line group gap
|
|
146
141
|
drops after it. `page.margin` on the document is the inset when the host
|
|
147
142
|
omits it; both is a render error.
|
|
148
|
-
|
|
149
143
|
- **`spaceBefore` / `spaceAfter` skip the cursor.** Adjacent gaps add.
|
|
150
144
|
`spaceBefore` drops at a fresh body page or strip top; page-band items
|
|
151
145
|
keep it.
|
|
152
|
-
|
|
153
146
|
- **The box is honoured in layout.** Padding and border inset wrap width; a
|
|
154
147
|
named padding `0` beats the cell omakase (`PADX` 6 / `PADY` 2) on that
|
|
155
148
|
side. Incomplete sides draw nothing.
|
|
156
|
-
|
|
157
|
-
### Changed
|
|
158
|
-
|
|
159
149
|
- **The last data row keeps the whole emitted total block.** A stack taller
|
|
160
150
|
than a page degrades like a tall row.
|
|
161
|
-
|
|
162
151
|
- **An unstyled table has no rules.** This target used to draw two 0.5 pt
|
|
163
152
|
rules, under the header and above the total, that no declaration could
|
|
164
153
|
ask for or refuse. Those strokes are gone. The strokes an author wants
|
|
165
154
|
are the box they declared. Cell padding omakase stays on undeclared cell
|
|
166
155
|
sides.
|
|
167
|
-
|
|
168
156
|
- **A visible text item occupies a line at its own `size`, empty or not.** An
|
|
169
157
|
empty or whitespace-only value used to sit at the report's base leading
|
|
170
158
|
(~14 pt at the 10 pt baseline). It now occupies `1.4 ×` the item's size, the
|
|
171
159
|
same as a glyph line. A literal newline is a line break; the blank line
|
|
172
160
|
among `"a\n\nb"` is that size too. A table cell that is empty or only
|
|
173
161
|
horizontal whitespace still has no content height.
|
|
174
|
-
|
|
175
|
-
### Fixed
|
|
176
|
-
|
|
177
162
|
- **A missing TrueType glyph draws as `?`, not `.notdef`.** Characters
|
|
178
163
|
outside WinAnsi already substituted `?`; an embedded face's cmap holes
|
|
179
164
|
drew a box instead, and text extraction hid it. Same rule for every
|
|
180
165
|
face: a character the face cannot draw becomes `?`.
|
|
181
|
-
|
|
182
166
|
- **CR, LF, and CRLF are one hard line break.** Cell text already broke
|
|
183
167
|
on LF; a CRLF left a CR on the previous line, and a lone CR did not
|
|
184
168
|
break. All three are now one break, matching `SCHEMA.md` Cell values.
|
|
185
169
|
Wrapping still applies within each line.
|
|
186
170
|
|
|
187
|
-
##
|
|
171
|
+
## 0.2.0
|
|
188
172
|
|
|
189
|
-
###
|
|
173
|
+
### Minor Changes
|
|
190
174
|
|
|
191
175
|
- **The report default sets the document's face and base size.** A report's
|
|
192
176
|
top-level `style` replaces this target's own baseline, so its `size` scales
|
|
@@ -194,12 +178,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
194
178
|
nothing is set in. It is the layer _under_ the band-role defaults: a report
|
|
195
179
|
declaring `size: 12` still renders its report header at 14, and an item's own
|
|
196
180
|
style wins over both.
|
|
197
|
-
|
|
198
181
|
- **`uppercase` draws capitals.** With no text-transform to defer to, this
|
|
199
182
|
target capitalises the string before measuring it, so wrapping and column
|
|
200
183
|
widths are those of the text actually drawn. The mapping is Unicode default
|
|
201
184
|
case, never the host's locale, so output stays byte-reproducible.
|
|
202
|
-
|
|
203
185
|
- **Splits lay out across the content width.** Each slot is measured and
|
|
204
186
|
wrapped inside its own share, all slots draw from a common top, and the
|
|
205
187
|
split takes the height of its tallest slot so the band below clears them
|
|
@@ -208,27 +190,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
208
190
|
any page renders in full past the bottom margin. The split's own style is
|
|
209
191
|
the layer under each slot's, and its `background` fills the whole split
|
|
210
192
|
behind them.
|
|
211
|
-
|
|
212
|
-
### Changed
|
|
213
|
-
|
|
214
193
|
- **A bare `Date` draws as ISO 8601 UTC, the same on every machine.** Cell
|
|
215
194
|
text and outline bookmark titles for `Date` values used `String(date)`,
|
|
216
195
|
which bakes the host's timezone and locale into the document — at odds with
|
|
217
196
|
this target's byte-reproducibility guarantee. Both now render through the
|
|
218
197
|
engine's shared display rule, so a `Date` group key titles its bookmark
|
|
219
198
|
with the same ISO text its cells draw.
|
|
220
|
-
|
|
221
|
-
### Removed
|
|
222
|
-
|
|
223
199
|
- **`options.baseSize`.** A document's type size is the document's own, so it
|
|
224
200
|
is the report's `style.size` — portable, travelling with the definition to
|
|
225
201
|
every target — rather than a host option one target honoured. Text with
|
|
226
202
|
nothing declared still renders at 10 points. Replace `pdf({ baseSize: 11 })`
|
|
227
203
|
with `"style": { "size": 11 }` on the report.
|
|
228
204
|
|
|
229
|
-
##
|
|
205
|
+
## 0.1.0
|
|
230
206
|
|
|
231
|
-
###
|
|
207
|
+
### Minor Changes
|
|
232
208
|
|
|
233
209
|
- **Paginated PDFs from the same compiled report.** The band flow places
|
|
234
210
|
headers, groups, and tables; pdf-lib writes the file. Page furniture and an
|
package/README.md
CHANGED
|
@@ -198,6 +198,17 @@ per-page presence is normative; exact geometry is best-effort. A licensed render
|
|
|
198
198
|
Paper size and fonts are options, not schema; the margin is an option a document may declare in
|
|
199
199
|
its stead. Authored watermarks and finer break control stay out of scope. Keep-together and continuation headers are by construction, above.
|
|
200
200
|
|
|
201
|
+
The full contract is [The PDF target](https://getquario.com/docs/diving-deeper/pdf-target/),
|
|
202
|
+
with each declaration's fate in the
|
|
203
|
+
[support matrix](https://getquario.com/docs/reference/support-matrix/).
|
|
204
|
+
|
|
205
|
+
## Documentation
|
|
206
|
+
|
|
207
|
+
[The quario documentation](https://getquario.com/docs/) is the reference.
|
|
208
|
+
The [report schema](https://getquario.com/docs/reference/report-schema/) is the normative
|
|
209
|
+
specification of what a report may declare, and
|
|
210
|
+
[`@quario/pdf`](https://getquario.com/docs/reference/pdf/) is this package's own API.
|
|
211
|
+
|
|
201
212
|
## License
|
|
202
213
|
|
|
203
214
|
Commercial software with readable source. Free, unlimited, watermarked evaluation; per-developer
|
package/lib/painter.js
CHANGED
|
@@ -80,6 +80,7 @@ let paintLine = ({ page, height }, op) =>
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
/** @type {(painter: Painter, op: any) => void} */
|
|
83
|
+
// fallow-ignore-next-line code-duplication -- one operator path, so a face is embedded once per page; ink, baseline, rotation and opacity all differ, and the marking's draw stays its own
|
|
83
84
|
let paintText = ({ page, height, fonts, faceKey }, op) => {
|
|
84
85
|
let font = fontFor(fonts, op.font);
|
|
85
86
|
page.pushOperators(
|
|
@@ -100,6 +101,7 @@ let paintText = ({ page, height, fonts, faceKey }, op) => {
|
|
|
100
101
|
// face reuses the page's `faceKey` resource instead of growing the dictionary
|
|
101
102
|
// per draw.
|
|
102
103
|
/** @type {(painter: Painter, op: any) => void} */
|
|
104
|
+
// fallow-ignore-next-line code-duplication -- one operator path, so a face is embedded once per page; ink, baseline, rotation and opacity all differ, and the marking's draw stays its own
|
|
103
105
|
let paintMark = ({ page, height, fonts, faceKey }, op) => {
|
|
104
106
|
let font = fontFor(fonts, op.font);
|
|
105
107
|
page.pushOperators(
|
|
@@ -126,7 +128,7 @@ let paintMark = ({ page, height, fonts, faceKey }, op) => {
|
|
|
126
128
|
// The embedders parse the bytes, and what they throw when those bytes are bad
|
|
127
129
|
// says nothing an author could act on: a corrupt PNG used to reach a host as a
|
|
128
130
|
// bare `RangeError: Invalid typed array length: 0`, naming no image and no
|
|
129
|
-
// item (quario-e0bz). The engine vouched for the magic numbers and
|
|
131
|
+
// item (quario-e0bz). The engine vouched for the magic numbers and
|
|
130
132
|
// read the size out of the header, so a file corrupt past that point arrives
|
|
131
133
|
// here looking like any other and this is the first place that knows. The
|
|
132
134
|
// embedder's own class and words survive behind the path, which is the shape
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quario/pdf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "The browserless, paginated PDF render target for quario — in the makings, not yet released",
|
|
5
5
|
"homepage": "https://getquario.com",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -37,20 +37,20 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@cantoo/pdf-lib": "^2.9.1",
|
|
40
|
-
"@quario/layout": "^0.
|
|
40
|
+
"@quario/layout": "^0.5.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@arethetypeswrong/cli": "^0.18.3",
|
|
44
44
|
"@size-limit/preset-small-lib": "^13.0.3",
|
|
45
45
|
"@types/fontkit": "^2.0.9",
|
|
46
46
|
"fontkit": "^2.0.4",
|
|
47
|
-
"quario": "^0.
|
|
47
|
+
"quario": "^0.8.0",
|
|
48
48
|
"size-limit": "^13.0.3",
|
|
49
49
|
"typescript": "^7.0.2"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"fontkit": "^2.0.4",
|
|
53
|
-
"quario": "^0.
|
|
53
|
+
"quario": "^0.8.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"fontkit": {
|