diff options
| author | Urban Prah <urban@urbanprah.xyz> | 2025-09-15 21:40:19 +0200 |
|---|---|---|
| committer | Urban Prah <urban@urbanprah.xyz> | 2025-09-15 21:40:19 +0200 |
| commit | ed230903fd17e3518ae307a2e87926cb63822e28 (patch) | |
| tree | 4bd3b998d1e800a56c18c8216ecc339cdf03b13a /template.typ | |
| parent | 8cb4b48300001dc3b4831dc3f1d2d2bb17533c75 (diff) | |
| download | CV-ed230903fd17e3518ae307a2e87926cb63822e28.tar.gz CV-ed230903fd17e3518ae307a2e87926cb63822e28.zip | |
Typst rewrite
Diffstat (limited to '')
| -rw-r--r-- | template.typ | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/template.typ b/template.typ new file mode 100644 index 0000000..8bc210d --- /dev/null +++ b/template.typ @@ -0,0 +1,211 @@ +#let default_font = "Raleway" +#let icon_font = "Font Awesome 7 Free Solid" +#let icon_size = 10pt + +#let fa(txt, size: 7pt) = text( + font: icon_font, + size: size, + txt, +) + +#let smartlink(url, content) = if url != none { + link(url, underline(offset: 1.5pt, content)) +} else { + content +} + +#let inv_box(content, size: 10pt, bold: true, capital: true) = box( + fill: black, + inset: 3pt, + text( + fill: white, + weight: if bold { "bold" } else { "regular" }, + size: size, + if capital { upper(content) } else { content }, + ), +) + +#let job(title, location) = stack( + dir: ttb, + spacing: 0.5em, + strong(title), + location, +) + +#let iconlink(icon, label) = grid( + columns: (auto, auto), + column-gutter: 0.5em, + align: (horizon, horizon), + /* Icon */ + square( + size: icon_size * 1.8, + fill: black, + align( + horizon + center, + move( + dy: -icon_size / 10, + text(white, fa(icon, size: icon_size)), + ), + ), + ), + /* Text */ + text(size: 9pt, label) +) + +#let skillbar(title, percent) = ( + // Use array so alignment can be determined in parrent + inv_box(title, size: 9pt, bold: false, capital: false), + line(length: percent, stroke: 10pt), +) + +#let skillbubble(title, percent) = ( + circle(fill: black, radius: percent * 2.5em), + text(title), +) + +#let field(name, bubbles: (), experiences: (), education: (), other: ()) = { + /* Title */ + heading(name) + line(length: 100%, stroke: 0.05em) + + /* Bubbles */ + if bubbles.len() > 0 { + set align(center) + box( + grid( + columns: bubbles.len(), + rows: 2, + row-gutter: 2em, + column-gutter: 2em, + align: (horizon), + ..bubbles.map(pair => pair.at(0)).flatten(), + ..bubbles.map(pair => pair.at(1)).flatten(), + ), + ) + } + + /* Experinces */ + if experiences.len() > 0 { inv_box("Experience") } + stack(dir: ttb, spacing: 1.0em, ..experiences) + + /* Education */ + if education.len() > 0 { inv_box("Education") } + stack(dir: ttb, spacing: 1.0em, ..education) + + /* Other */ + grid( + columns: (auto, auto, auto), + gutter: 3em, + ..other, + ) +} + +#let date_tag(tag) = if tag != "" { + v(-0.2em) + text(size: 8pt, tag) +} + +#let experience(date, title, location, description, skills: (), tag: "") = block( + breakable: false, + grid( + columns: (8em, auto), + rows: (auto, auto), + row-gutter: 0.7em, + column-gutter: 1em, + date, + stack( + dir: ltr, + spacing: 1fr, + strong(title), + text(size: 8pt, weight: "bold", location), + ), + date_tag(tag), // + par(justify: true, description), + none, + skills + .map(raw) + .join({ + h(1em) + raw("/") + h(1em) + }), + ), +) + +#let info(title, content) = { + inv_box(title, size: 8pt) + set par(justify: true) + set text(size: 8pt) + content +} + +#let CV( + author: "Janez Novak", + active_jobs: (), + links: (), + about: lorem(150), + skills: (), + fields: (), +) = { + set document( + title: "CV", + author: author, + description: author + "'s CV", + ) + set page( + paper: "a4", + margin: (top: 2.0cm, bottom: 3.0cm, left: 1.75cm, right: 1.75cm), + ) + set underline(stroke: (dash: "dotted")) + set text(size: 9pt, spacing: 1.3pt, font: default_font) + + /* Content */ + grid( + columns: (1fr, 1fr), + rows: (auto, auto), + gutter: 2em, + + /* Name, jobs */ + stack( + dir: ttb, + author.split(" ").map(a => { inv_box(a, size: 30pt) }).join(v(-1em)), + v(0.7em), + stack(spacing: 0.7em, ..active_jobs), + ), + + /* Icon links */ + box( + height: 12%, + columns( + 2, + gutter: 1em, + links + .map(l => { + l + v(-1em) + }) + .join(), + ), + ), + + /* About */ + box[ + #inv_box("About me") + #par(justify: true)[ #context about ] + ], + + /* Skill bar */ + grid.cell( + align: left + horizon, + grid( + columns: (1fr, 3fr), + column-gutter: 1em, + row-gutter: 0.2em, + align: (right, horizon, left, horizon), + ..skills.flatten(), + ), + ), + ) + set underline(stroke: (dash: "solid")) + fields.join(pagebreak()) +} |
