diff --git a/cv/cv.typ b/cv/cv.typ index 5e99202..51a5950 100644 --- a/cv/cv.typ +++ b/cv/cv.typ @@ -62,7 +62,7 @@ } // address -#let addresstext(info, uservars) = { +#let addresstext(lang, info, uservars) = { if uservars.showAddress { block(width: 100%)[ #info.personal.location.city, #info.personal.location.region, #info.personal.location.country @@ -77,11 +77,11 @@ } -#let contacttext(info, uservars) = block(width: 100%)[ +#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.url != 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 @@ -100,25 +100,23 @@ ] ] -#let cvheading(info, uservars) = { +#let cvheading(lang, info, uservars) = { align(center)[ = #info.personal.name - #addresstext(info, uservars) - #contacttext(info, uservars) + #addresstext(lang, info, uservars) + #contacttext(lang, info, uservars) ] } #let cvwork(lang, info, isbreakable: true) = { if info.experience != none {block[ - == #utils.getWithLang(lang, info.experience.title) + == #info.experience.title #for w in info.experience.content { - let wwith = utils.getWithLang(lang, w.with) - let wwhere = utils.getWithLang(lang, w.where) block(width: 100%, breakable: isbreakable)[ #if w.url != none [ - *#link(utils.getWithLang(lang, w.url))[#wwith]* #h(1fr) *#wwhere* \ + *#link(w.url)[#w.with]* #h(1fr) *#w.where* \ ] else [ - *#wwith* #h(1fr) *#wwhere* \ + *#w.with* #h(1fr) *#w.where* \ ] ] // create a block layout for each work entry @@ -130,11 +128,11 @@ #let start = utils.strpdate(lang, p.startDate) #let end = utils.strpdate(lang, p.endDate) // line 2: position and date range - #text(style: "italic")[#utils.getWithLang(lang, p.what)] #h(1fr) + #text(style: "italic")[#p.what] #h(1fr) #start #sym.dash.en #end \ // highlights or description - #for hi in utils.getWithLang(lang, p.why) [ - - #eval(utils.getWithLang(lang, hi), mode: "markup") + #for hi in p.why [ + - #eval(hi, mode: "markup") ] ] index = index + 1 @@ -144,34 +142,29 @@ } #let cveducation(lang, info, isbreakable: true) = { - if info.education != none {block[ - == Education - #for edu in info.education { + 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 edu-items = "" - if edu.honors != none {edu-items = edu-items + "- *Honors*: " + edu.honors.join(", ") + "\n"} - if edu.why != none {edu-items = edu-items + "- *Courses*: " + edu.why.join(", ") + "\n"} - if edu.highlights != none { - for hi in edu.highlights { - edu-items = edu-items + "- " + hi + "\n" - } - edu-items = edu-items.trim("\n") - } + 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 edu.url != none [ - *#link(edu.url)[#edu.with]* #h(1fr) *#edu.what* \ + #if eduurl != none [ + *#link(eduurl)[#edu.with]* #h(1fr) *#edu.where* \ ] else [ - *#edu.with* #h(1fr) *#edu.what* \ + *#edu.with* #h(1fr) *#edu.where* \ ] // line 2: degree and date #text(style: "italic")[#edu.what] #h(1fr) #start #sym.dash.en #end \ - #eval(edu-items, mode: "markup") + + #for hi in edu.why [ + - #eval(hi, mode: "markup") + ] ] } ]} @@ -303,25 +296,14 @@ ]} } -#let cvskills(info, isbreakable: true) = { - if (info.languages != none) or (info.skills != none) or (info.interests != none) {block(breakable: isbreakable)[ - == Skills, Languages, Interests - #if (info.languages != none) [ - #let langs = () - #for lang in info.languages { - langs.push([#lang.language (#lang.fluency)]) - } - - *Languages*: #langs.join(", ") - ] - #if (info.skills != none) [ - #for group in info.skills [ - - *#group.category*: #group.skills.join(", ") - ] - ] - #if (info.interests != none) [ - - *Interests*: #info.interests.join(", ") - ] - ]} +#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) = { diff --git a/cv/utils.typ b/cv/utils.typ index 28e39f3..10b66b6 100644 --- a/cv/utils.typ +++ b/cv/utils.typ @@ -1,6 +1,5 @@ #let months = yaml("../data/months.yaml") - #let getWithLang(lang, data) = { if type(data) == dictionary { data.at(lang) @@ -9,34 +8,52 @@ } } -#let display = getWithLang("fr", months.at("short")).at(1) - // Helper Functions -#let monthname(lang, n, display: "short") = { - n = int(n) - let month = "" +#let monthname(lang, n, display: "short") = { + n = int(n) + let month = "" - let displayMonths = getWithLang(lang, months.at(display)) + let displayMonths = getWithLang(lang, months.at(display)) - if (n > 0 and n <= 12) { - month = displayMonths.at(n - 1) - } + if (n > 0 and n <= 12) { + month = displayMonths.at(n - 1) + } - month + month } #let strpdate(lang, isodate) = { - let date = "" - let isodate = getWithLang(lang, isodate) - if (regex("\d{4}-\d{2}-\d{2}") in isodate) { - date = datetime( - year: int(isodate.slice(0, 4)), - month: int(isodate.slice(5, 7)), - day: int(isodate.slice(8, 10)) - ) - date = monthname(lang, date.month()) + " " + date.display("[year repr:full]") + let date = "" + let isodate = getWithLang(lang, isodate) + if (regex("\d{4}-\d{2}-\d{2}") in isodate) { + date = datetime( + year: int(isodate.slice(0, 4)), + month: int(isodate.slice(5, 7)), + day: int(isodate.slice(8, 10)), + ) + date = monthname(lang, date.month()) + " " + date.display("[year repr:full]") + } else { + date = isodate + } + return date +} + +#let filterLanguage(lang, data) = { + if type(data) == dictionary { + if data.at(lang, default: none) == none { + data = data + .pairs() + .map(xs => (xs.first(), filterLanguage(lang, xs.last()))) + .fold((:), (acc, xs) => { + acc.insert(xs.first(), xs.last()) + acc + }) } else { - date = isodate + data = filterLanguage(lang, data.at(lang)) } - return date + } else if type(data) == array { + data = data.map(v => filterLanguage(lang, v)) + } + + data } \ No newline at end of file