CV_Typst/cv/cv.typ

332 lines
10 KiB
Plaintext

#import "utils.typ"
// set rules
#let setrules(uservars, doc) = {
set text(
font: uservars.bodyfont,
size: uservars.fontsize,
hyphenate: false,
)
set list(
spacing: uservars.linespacing
)
set par(
leading: uservars.linespacing,
justify: true,
)
doc
}
// show rules
#let showrules(uservars, doc) = {
// uppercase section headings
show heading.where(
level: 2,
): it => block(width: 100%)[
#set align(left)
#set text(font: uservars.headingfont, size: 1em, weight: "bold")
#if (uservars.at("headingsmallcaps", default:false)) {
smallcaps(it.body)
} else {
it.body
}
#v(-0.75em) #line(length: 100%, stroke: 1pt + black) // draw a line
]
// name title
show heading.where(
level: 1,
): it => block(width: 100%)[
#set text(font: uservars.headingfont, size: 2em, weight: "bold")
#if (uservars.at("headingsmallcaps", default:false)) {
smallcaps(it.body)
} else {
// upper(it.body)
it.body
}
#v(2pt)
]
doc
}
// set page layout
#let cvinit(doc) = {
doc = setrules(doc)
doc = showrules(doc)
doc
}
// address
#let addresstext(lang, info, uservars) = {
if uservars.showAddress {
block(width: 100%)[
#info.personal.location.city, #info.personal.location.region, #info.personal.location.country
#v(-4pt)
]
} else {none}
}
#let fa(body) = {
set text(font:"FontAwesome")
[#body]
}
#let contacttext(lang, info, uservars) = block(width: 100%)[
#let profiles = (
box(link("mailto:" + info.personal.email)[#fa(" ") #info.personal.email]),
if uservars.showNumber {box(link("tel:" + info.personal.phone)[#fa("") #info.personal.phone])} else {none},
if info.personal.at("url", default: none) != none {
box(link(info.personal.url)[#fa(" ") #info.personal.url.split("//").at(1)])
}
).filter(it => it != none) // filter out none elements from the profile array
#if info.personal.profiles.len() > 0 {
for profile in info.personal.profiles {
profiles.push(
box(link(profile.url)[#profile.username])
)
}
}
#set text(font: uservars.bodyfont, weight: "light", size: uservars.fontsize * 1)
#pad(x: 0em)[
#profiles.join([#sym.space.en|#sym.space.en])
]
]
#let cvheading(lang, info, uservars) = {
align(center)[
= #info.personal.name
#addresstext(lang, info, uservars)
#contacttext(lang, info, uservars)
]
}
#let cvwork(lang, info, isbreakable: true) = {
if info.experience != none {block[
== #info.experience.title
#for w in info.experience.content {
block(width: 100%, breakable: isbreakable)[
#if w.url != none [
*#link(w.url)[#w.with]* #h(1fr) *#w.where* \
] else [
*#w.with* #h(1fr) *#w.where* \
]
]
// create a block layout for each work entry
let index = 0
for p in w.what {
if index != 0 {v(0.6em)}
block(width: 100%, breakable: isbreakable, above: 0.6em)[
// parse ISO date strings into datetime objects
#let start = utils.strpdate(lang, p.startDate)
#let end = utils.strpdate(lang, p.endDate)
// line 2: position and date range
#text(style: "italic")[#p.what] #h(1fr)
#start #sym.dash.en #end \
// highlights or description
#for hi in p.why [
- #eval(hi, mode: "markup")
]
]
index = index + 1
}
}
]}
}
#let cveducation(lang, info, isbreakable: true) = {
let education = info.education
if education != none {block[
== #education.title
#for edu in education.content {
let start = utils.strpdate(lang, edu.startDate)
let end = utils.strpdate(lang, edu.endDate)
let eduurl = edu.at("url", default: none)
// create a block layout for each education entry
block(width: 100%, breakable: isbreakable)[
// line 1: institution and location
#if eduurl != none [
*#link(eduurl)[#edu.with]* #h(1fr) *#edu.where* \
] else [
*#edu.with* #h(1fr) *#edu.where* \
]
// line 2: degree and date
#text(style: "italic")[#edu.what] #h(1fr)
#start #sym.dash.en #end \
#for hi in edu.why [
- #eval(hi, mode: "markup")
]
]
}
]}
}
#let cvaffiliations(lang, info, isbreakable: true) = {
if info.affiliations != none {block[
== Leadership & Activities
#for org in info.affiliations {
// parse ISO date strings into datetime objects
let start = utils.strpdate(lang, org.startDate)
let end = utils.strpdate(lang, org.endDate)
// create a block layout for each affiliation entry
block(width: 100%, breakable: isbreakable)[
// line 1: organization and location
#if org.url != none [
*#link(org.url)[#org.with]* #h(1fr) *#org.where* \
] else [
*#org.with* #h(1fr) *#org.where* \
]
// line 2: position and date
#text(style: "italic")[#org.position] #h(1fr)
#start #sym.dash.en #end \
// highlights or description
#if org.highlights != none {
for hi in org.highlights [
- #eval(hi, mode: "markup")
]
} else {}
]
}
]}
}
#let cvprojects(lang, info, isbreakable: true) = {
if info.projects != none {block[
== Projects
#for project in info.projects {
// parse ISO date strings into datetime objects
let start = utils.strpdate(lang, project.startDate)
let end = utils.strpdate(lang, project.endDate)
// create a block layout for each project entry
block(width: 100%, breakable: isbreakable)[
// line 1: project name
#if project.url != none [
*#link(project.url)[#project.name]* \
] else [
*#project.name* \
]
// line 2: organization and date
#text(style: "italic")[#project.affiliation] #h(1fr) #start #sym.dash.en #end \
// summary or description
#for hi in project.highlights [
- #eval(hi, mode: "markup")
]
]
}
]}
}
#let cvawards(lang, info, isbreakable: true) = {
if info.awards != none {block[
== Honors & Awards
#for award in info.awards {
// parse ISO date strings into datetime objects
let date = utils.strpdate(lang, award.date)
// create a block layout for each award entry
block(width: 100%, breakable: isbreakable)[
// line 1: award title and location
#if award.url != none [
*#link(award.url)[#award.title]* #h(1fr) *#award.location* \
] else [
*#award.title* #h(1fr) *#award.location* \
]
// line 2: issuer and date
Issued by #text(style: "italic")[#award.issuer] #h(1fr) #date \
// summary or description
#if award.highlights != none {
for hi in award.highlights [
- #eval(hi, mode: "markup")
]
} else {}
]
}
]}
}
#let cvcertificates(lang, info, isbreakable: true) = {
if info.certificates != none {block[
== Licenses & Certifications
#for cert in info.certificates {
// parse ISO date strings into datetime objects
let date = utils.strpdate(lang, cert.date)
// create a block layout for each certificate entry
block(width: 100%, breakable: isbreakable)[
// line 1: certificate name
#if cert.url != none [
*#link(cert.url)[#cert.name]* \
] else [
*#cert.name* \
]
// line 2: issuer and date
Issued by #text(style: "italic")[#cert.issuer] #h(1fr) #date \
]
}
]}
}
#let cvpublications(lang, info, isbreakable: true) = {
if info.publications != none {block[
== Research & Publications
#for pub in info.publications {
// parse ISO date strings into datetime objects
let date = utils.strpdate(lang, pub.releaseDate)
// create a block layout for each publication entry
block(width: 100%, breakable: isbreakable)[
// line 1: publication title
#if pub.url != none [
*#link(pub.url)[#pub.name]* \
] else [
*#pub.name* \
]
// line 2: publisher and date
Published on #text(style: "italic")[#pub.publisher] #h(1fr) #date \
]
}
]}
}
#let cvskills(lang, info, isbreakable: true) = {
block(breakable: isbreakable)[
== #info.skills.title
#for skill in info.skills.content {
[- *#skill.title*]
}
]
}
#let cvreferences(info, isbreakable: true) = {
if info.references != none {block[
== References
#for ref in info.references {
block(width: 100%, breakable: isbreakable)[
#if ref.url != none [
- *#link(ref.url)[#ref.name]*: "#ref.reference"
] else [
- *#ref.name*: "#ref.reference"
]
]
}
]} else {}
}
#let endnote() = {
place(
bottom + right,
block[
#set text(size: 5pt, font: "Consolas", fill: silver)
Félix Desmaretz #datetime.today().display("[year]-[month]-[day]")
]
)
}