typstcard/common.typ

200 lines
4.2 KiB
Plaintext
Raw Normal View History

2023-09-24 02:55:24 +00:00
#let address_text(card) = {
text(font: ("OCR-B", "Noto Emoji"), size: 8pt, card.address)
}
#let place_avatar(text_height, card) = {
style(styles => {
let text_offset = (text_height - measure(address_text(card), styles).height) / 2
place(
top + left,
dx: 0.1in,
2023-09-24 05:06:59 +00:00
dy: calc.max(text_offset + 4pt - 0.15in, 0pt),
2023-09-24 02:55:24 +00:00
image(card.avatar, width: 0.3in)
)
})
}
2023-09-24 00:28:46 +00:00
#let address_content(width, height, card) = {
set par(leading: 0.5em)
let text_height = if card.imb == "" {
height
} else {
height - 1in/8
}
2023-09-24 02:55:24 +00:00
2023-09-24 00:28:46 +00:00
place(
top + left,
dx: 0.5in,
block(
width: width - 0.5in,
height: text_height,
align(
start + horizon,
2023-09-24 02:55:24 +00:00
address_text(card)
2023-09-24 00:28:46 +00:00
)
)
)
if card.imb != "" {
place(
top + left,
dy: height - 1in/8,
2023-10-31 18:36:36 +00:00
dx: 0.05in,
2023-09-24 00:28:46 +00:00
block(
width: 100%,
height: 1in/8,
align(
2023-10-31 18:36:36 +00:00
top + left,
2023-09-24 00:28:46 +00:00
text(font: "USPSIMBCompact", size: 12pt, card.imb)
)
)
)
}
2023-11-30 18:23:40 +00:00
if card.avatar != none {
2023-09-24 02:55:24 +00:00
place_avatar(text_height, card)
2023-09-24 00:28:46 +00:00
}
}
#let address_block(width, height, card) = {
block(
width: width,
height: height,
breakable: false,
address_content(width, height, card)
)
}
2023-09-25 20:58:24 +00:00
#let postcard_content(width, height, content_fn, args, card) = {
2023-09-25 20:58:24 +00:00
// Content block
place(
top + left,
dx: 1in/8,
dy: 1in/8,
block(
width: width - 2in - 7in/8,
height: height - 0.25in,
2023-09-25 20:58:24 +00:00
breakable: false,
content_fn(card)
)
)
// Stamp placement guide
if(not args.no_nixowos) {
place(
top + right,
dx: -0.25in,
dy: 0.25in,
image("nixowos.svg", width: 0.5in)
)
}
2023-09-25 20:58:24 +00:00
// Address block
place(
horizon + right,
dx: -1in/8,
2023-09-25 20:58:24 +00:00
address_block(2.5in, 1in, card)
)
}
#let postcard_block(width, height, content_fn, args, card) = {
2023-09-25 20:58:24 +00:00
block(
width: width,
height: height,
breakable: false,
postcard_content(width, height, content_fn, args, card)
2023-09-25 20:58:24 +00:00
)
}
#let postcard_square(width, height, margin, content_fn, args, card) = {
rect(
width: width + margin * 2,
height: height + margin * 2,
inset: margin,
postcard_block(width, height, content_fn, args, card)
)
}
2024-01-20 08:43:53 +00:00
#let get_content_fn(args) = {
if args.no_content {
_ => []
} else {
import "cache/content/content.typ"
content.content
}
2024-01-20 08:43:53 +00:00
}
#let card_sheets(width, height, margin, args, cards) = {
let content_fn = get_content_fn()
for (idx, card) in cards.enumerate() {
let row = calc.rem(idx + args.skip, 2)
if idx != 0 and row == 0 {
pagebreak()
}
place(
top + left,
dx: 50% - width / 2 - margin,
dy: 25% - height / 2 - margin + 50% * row,
postcard_square(width, height, margin, content_fn, args, card)
)
}
}
2024-01-20 08:43:53 +00:00
// It would be nice to calculate this but the rounding makes no sense,
// hardcode it.
#let iso216_lengths = (
1189mm,
841mm,
594mm,
420mm,
297mm,
210mm,
148mm,
105mm,
74mm,
52mm,
37mm,
26mm
)
#let iso216_a_size(format) = {
(iso216_lengths.at(format), iso216_lengths.at(format + 1))
}
// Pack together smaller ISO 216 A-series cards to make a full-size card.
// Useful to print on a large printer or plotter then use a paper cutter
#let iso216_a_card_sheets(page_format, card_format, args, cards) = {
let is_landscape = calc.even(card_format - page_format)
let (num_rows, num_cols) = if is_landscape {
let num = calc.pow(2, (card_format - page_format) / 2)
(num, num)
} else {
let cols = calc.pow(2, (card_format - 1 - page_format) / 2)
(cols * 2, cols)
}
let (page_long, page_short) = iso216_a_size(page_format)
set page(margin: 0mm, width: page_short, height: page_long, flipped: is_landscape)
let (card_long, card_short) = iso216_a_size(card_format)
let content_fn = get_content_fn(args)
for (idx, card) in cards.enumerate() {
if idx != 0 and calc.rem(idx + args.skip, num_rows * num_cols) == 0 {
pagebreak()
}
let offset_idx = idx + args.skip
let col = calc.rem(offset_idx, num_cols)
let row = calc.rem(calc.floor(offset_idx / num_cols), num_rows)
place(
top + left,
dx: col * card_long,
dy: row * card_short,
postcard_block(card_long, card_short, content_fn, args, card)
)
}
}