rspace-online/modules/pubs/typst/templates/pocket-book.typ

152 lines
3.7 KiB
Plaintext

// rPubs Book Template — main entry point
// Reads structured content from JSON and renders a complete pocket book.
// Works with any format file (A6, A7, digest, etc.)
#import "../lib/series-style.typ": apply-series-style, series-colors, series-fonts, series-rule, series-separator
#let data = json(sys.inputs.at("data-path"))
// Apply series typography
#show: apply-series-style
// --- Cover Page ---
#page(
numbering: none,
margin: (x: 15mm, y: 20mm),
fill: series-colors.cover-bg,
)[
#set text(fill: series-colors.cover-fg)
#v(1fr)
#align(center)[
#block(width: 100%)[
#set text(font: series-fonts.heading)
// Title
#text(size: 18pt, weight: "bold")[
#data.title
]
#if data.at("subtitle", default: none) != none {
v(0.3em)
text(size: 11pt, fill: series-colors.cover-fg.lighten(20%))[
#data.subtitle
]
}
#v(1em)
#line(length: 40%, stroke: 0.5pt + series-colors.cover-fg.darken(40%))
#v(1em)
// Author
#if data.at("author", default: none) != none {
text(size: 10pt)[
#data.author
]
}
]
]
#v(1fr)
#align(center)[
#text(size: 7pt, fill: series-colors.cover-fg.darken(40%))[
rpubs
]
]
]
// --- Table of Contents (if there are headings) ---
#let has-headings = data.sections.any(s => s.at("heading", default: none) != none)
#if has-headings {
page(numbering: none)[
#v(2em)
#text(font: series-fonts.heading, size: 12pt, weight: "bold", fill: series-colors.accent)[Contents]
#v(1em)
#series-rule()
#v(0.5em)
#for (i, section) in data.sections.enumerate() {
if section.at("heading", default: none) != none {
let level = section.at("level", default: 1)
let indent = (level - 1) * 1em
pad(left: indent)[
#text(size: 9pt)[#section.heading]
]
v(0.2em)
}
}
]
}
// --- Body Content ---
#for section in data.sections {
// Section heading
if section.at("heading", default: none) != none {
let level = section.at("level", default: 1)
if level == 1 {
heading(level: 1)[#section.heading]
} else if level == 2 {
heading(level: 2)[#section.heading]
} else {
heading(level: 3)[#section.heading]
}
}
// Content blocks
for item in section.at("blocks", default: ()) {
if item.type == "paragraph" {
par[#item.text]
} else if item.type == "quote" {
pad(left: 1em)[
#block(
inset: (left: 8pt, y: 4pt),
stroke: (left: 2pt + series-colors.accent),
)[
#set text(style: "italic", size: 8.5pt)
#item.text
#if item.at("attribution", default: none) != none {
v(0.2em)
align(right)[
#text(size: 7.5pt, fill: series-colors.muted)[— #item.attribution]
]
}
]
]
} else if item.type == "list" {
if item.at("ordered", default: false) {
enum(..item.items.map(entry => [#entry]))
} else {
list(..item.items.map(entry => [#entry]))
}
} else if item.type == "code" {
raw(block: true, lang: item.at("language", default: none), item.code)
} else if item.type == "separator" {
series-separator()
}
}
}
// --- Colophon (back page) ---
#pagebreak()
#v(1fr)
#series-rule()
#v(0.5em)
#set text(size: 7pt, fill: series-colors.muted)
#if data.at("title", default: none) != none [
*#data.title*
#if data.at("author", default: none) != none [ by #data.author]
#v(0.3em)
]
#[
Typeset with rPubs. \
Formatted for standardized pocket-book printing.
]
#v(0.5em)
#align(center)[
#text(size: 6pt)[rpubs · drop in a document · get a book]
]