-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlib.typ
81 lines (73 loc) · 2.18 KB
/
lib.typ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#let muchpdf = {
let muchpdf-plugin = plugin("muchpdf.wasm")
let encode-pages(pages) = {
// Convert to array if necessary.
let pages = pages
if type(pages) == int {
pages = ((start: pages, end: pages),)
} else if type(pages) == dictionary {
pages = (pages,)
} else if type(pages) != array {
panic("expected pages to be `int`, `dictionary`, or `array`, but got " + type(pages))
}
// Convert to array of ranges.
let ranges = ()
for page in pages {
if type(page) == int {
ranges.push((start: page, end: page, step: 1))
} else if type(page) == dictionary {
ranges.push((
start: page.remove("start", default: 0),
end: page.remove("end", default: none),
step: page.remove("step", default: 1),
))
if page.len() != 0 {
panic("page contains attributes other than `start`, `end`, and `step`")
}
} else {
panic("pages array contained value of type that is neither `int` nor `dictionary`, got " + type(page))
}
}
// Encode ranges to flat byte array.
let encoded = bytes(())
for range in ranges {
if range.start < 0 or (range.end != none and range.end < 0) {
panic("pages must not be negative")
}
if range.step < 1 {
panic("step must be positive")
}
let encode-int = int.to-bytes.with(endian: "little", size: 4)
encoded += encode-int(range.start)
encoded += encode-int(if range.end == none { -1 } else { range.end })
encoded += encode-int(range.step)
}
encoded
}
let muchpdf(
data,
scale: 2.0,
pages: (:),
..args,
) = {
assert.eq(type(data), bytes)
let rendered-pages = muchpdf-plugin.render(
data,
float.to-bytes(scale),
encode-pages(pages),
)
let cursor = 0
while cursor < rendered-pages.len() {
let page-len = int.from-bytes(
endian: "little",
signed: false,
rendered-pages.slice(cursor, count: 8),
)
cursor += 8
let page = rendered-pages.slice(cursor, count: page-len)
cursor += page-len
image.decode(page, format: "svg", ..args)
}
}
muchpdf
}