resume/resume.typ
Marty Oehme 1afc51a857
feat(resume): Add wrapit library to dynamically add sidebar
Removes issue that grid will be static throughout all pages and thus
empty space where the sidebar is on page 1. Now, the sidebar aligns
nicely along the first page but then we can use the full width for the
next few pages.
2025-03-19 12:53:41 +01:00

163 lines
4.3 KiB
Typst

#import "lib.typ": *
#import "wrapit.typ": *
#let create_body(main: (), contents: (:)) = {
for item in main {
if item == "summary" and "summary" in contents {
section(
title: "",
{
contents.summary.at(lang)
},
)
}
if item == "experience_by_type" and "experience" in contents {
let title = (en: "Professional Experience", de: "Berufserfahrung").at(lang)
section(title: title)[]
by_experience_type(experience: contents.experience, type: contents.experience_types)
}
if item == "experience_by_client" and "experience" in contents {
let title = (en: "Professional Experience", de: "Berufserfahrung").at(lang)
section(title: title)[]
by_client(experience: contents.experience)
}
if item == "experience" and "experience" in contents {
let title = (en: "Professional Experience", de: "Berufserfahrung").at(lang)
section(title: title, entries: contents.experience)[]
}
if item == "education" and "education" in contents {
let title = (en: "Education", de: "Ausbildung").at(lang)
section(title: title, entries: contents.thesis + contents.education)[]
}
if item == "volunteering" and "volunteering" in contents {
let title = (en: "Volunteer Work", de: "Ehrenamt").at(lang)
section(title: title, entries: contents.volunteering)[]
}
if item == "skills" and "skills" in contents {
let title = (en: "Qualifications", de: "Qualifikationen").at(lang)
section(
title: title,
{
sidebar_entry(item: contents.skills)
},
)
}
if item == "languages" and "languages" in contents {
let title = (en: "Languages", de: "Sprachen").at(lang)
section(
title: title,
{
sidebar_entry(item: contents.languages)
},
)
}
}
}
#let create_sidebar(sidebar: (), contents: (:)) = {
for item in sidebar {
if item == "volunteering" and "volunteering" in contents {
let title = (en: "Volunteer Work", de: "Ehrenamt").at(lang)
[== #title]
for e in contents.at("volunteering") {
[
- *#e.title.at(lang)* (#e.date.at(lang))
#par(e.bullets.at(0).at(lang)) \
]
}
}
if item == "languages" and "languages" in contents {
let title = (en: "Languages", de: "Sprachen").at(lang)
[== #title]
sidebar_entry(item: contents.languages, is_sidebar: true)
[\ ]
}
if item == "skills" and "skills" in contents {
let title = (en: "Qualifications", de: "Kenntnisse").at(lang)
[== #title]
sidebar_entry(item: contents.skills, is_sidebar: true)
}
}
}
#let resume(contents, main: ("experience", "education"), sidebar: ("volunteering", "languages", "skills")) = {
show: style
set text(lang: lang)
let date_formatting = {
if lang == "de" {
"[day]. [month repr:long] [year]"
} else {
"[month repr:long] [day], [year]"
}
}
set page(
paper: "a4",
margin: (x: 0.9cm, y: 1.3cm),
footer: [
#set text(
fill: luma(200),
size: 8pt,
)
#_columns_3[
#smallcaps[#datetime.today().display(date_formatting)]
][
#smallcaps[#contents.about.fullname]
][
#context counter(page).display()
]
],
)
set par(justify: true)
header(contents.about)
set block(above: 10pt)
show heading.where(level: 1): it => style(s => {
let h = text(size: 18pt, upper(it))
let dim = measure(h, s)
stack(
dir: ltr,
h,
place(
dy: 7pt,
dx: 10pt,
horizon + left,
line(stroke: accent-color, length: 100% - dim.width - 10pt),
),
)
})
let margin = 1pt
let sb = if sidebar.len() > 0 {
block(
fill: luma(230),
inset: (top: 15 * margin, left: 10 * margin, right: 15 * margin, bottom: 15 * margin),
{
show heading: it => align(right, upper(it))
set list(marker: "")
show list: it => {
set par(justify: false)
align(right, block(it))
}
create_sidebar(sidebar: sidebar, contents: contents)
},
)
} else { [] }
wrap-content(
sb,
create_body(main: main, contents: contents),
align: top + right,
columns: (auto, 30%),
)
}
#resume(yaml("content.yml"))