#import "fontawesome.typ": github, fa // Reduce space between paragraphs. #let par_space = 0.75em // Reduce space between headings and descriptions. #let sep_space = par_space + 0.1em let subtitle_space = par_space - 0.2em // Format start and end dates. #let format_date(start_date: none, end_date: none) = { let date = { if end_date == none { start_date } else if start_date == none { end_date } else { [#start_date -- #end_date] } } [*#date*] } // Format locations. #let format_location(location) = { [_#block(above: par_space, location)_] } #let indent(content) = { block( inset: (left: 1em, right: 0.5em), content ) } // General entry that is split into a left and right half (for experience and education). #let cv_entry(left_content: none, right_content: none, details: none) = { stack( dir: ttb, spacing: 0.75em, grid( columns: (11fr, 6fr), column-gutter: 1cm, { set align(left) left_content }, { set align(right) right_content } ), { set align(left) details } ) } // Entry for education. #let education_entry(university, degree, start_date: none, end_date: none, location: none, details: none) = { let details_list = if details != none { let list = [] for detail in details { list += [- #detail] } list } else { none } cv_entry( left_content: { text(1.2em)[*#university*] + "\n" + emph[#degree] }, right_content: { format_date(start_date: start_date, end_date: end_date) if location != none { "\n" + format_location(location) } }, details: details_list ) } // Entry for work. #let work_entry(role, company, tasks: none, start_date: none, end_date: none, location: none) = { let task_list = if tasks != none { let list = [] for task in tasks { list += [- #task] } list } else { none } cv_entry( left_content: { text(1.1em)[*#role*] + "\n" + text[#emph[#company]] }, right_content: { format_date(start_date: start_date, end_date: end_date) if location != none { "\n" + format_location(location) } }, details: task_list ) } #let project(title, repo_link, tools) = { link(repo_link)[#text(1.1em)[*#title* #fa(github)]] + [ | _ #tools _] } // Set name and contact data and format headings #let template(name, contact_data, color, doc) = { set page(margin: (rest: 0.5in, top: 0.4in), paper: "us-letter") set list(indent: 1.25em, marker: [•]) set text(font: "Latin Modern Sans", 10pt) set par(justify: true, leading: 0.65em) align(center)[ #text(size: 2em)[*#name*] #block(above: 0em, below: 1em) #{ if contact_data != none and contact_data.len() > 0 { let elements = for el in contact_data { (link(el.link)[#{el.service + " " + el.display}],) } text(1.1em)[#elements.join(" | ")] } } ] show heading.where(level: 1): i => { set align(left) let title = smallcaps(i.body) set block(above: 1em) set text(weight: "light", size: 0.9em, fill: color, font: "New Computer Modern") stack( dir: ttb, spacing: 1.5mm, title, line(length: 100%, stroke: color + 0.4pt) ) } doc }