diff --git a/src/base/page.typ b/src/base/page.typ new file mode 100644 index 0000000..7238148 --- /dev/null +++ b/src/base/page.typ @@ -0,0 +1,8 @@ +#let base_page(body) = page( + paper: "us-letter", + margin: ( + x: 0.5in, + y: 0.3in, + ), + body +) diff --git a/src/base/text.typ b/src/base/text.typ new file mode 100644 index 0000000..153ced3 --- /dev/null +++ b/src/base/text.typ @@ -0,0 +1,6 @@ +#let base_text(body) = text( + font: "Inter", + size: 10pt, + weight: "regular", + body +) diff --git a/src/main.typ b/src/main.typ index dcb8008..fb45414 100644 --- a/src/main.typ +++ b/src/main.typ @@ -1,5 +1,5 @@ #{ - import "resume_page.typ": resume_page + import "page_resume.typ": page_resume let config = ( identity: ( @@ -149,5 +149,5 @@ date: none, ) - resume_page(..config) + page_resume(..config) } diff --git a/src/page_resume.typ b/src/page_resume.typ new file mode 100644 index 0000000..da9a508 --- /dev/null +++ b/src/page_resume.typ @@ -0,0 +1,111 @@ +#let page_resume( + identity: ( + name: "", + email: "", + phone: "", + location: "", + website: "", + ), + skills: ( + ( + title: "", + items: (""), + ), + ), + education: ( + ( + title: "", + degree: "", + graduation: "", + gpa: "", + coursework: (""), + highlights: (""), + ), + ), + work_experience: ( + ( + title: "", + location: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), + professional_development: ( + ( + title: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), +) = { + import "base/text.typ": base_text + import "base/page.typ": base_page + import "section/identity.typ": section_identity + import "section/skills.typ": section_skills + import "section/education.typ": section_education + import "section/work_experience.typ": section_work_experience + import "section/professional_development.typ": section_professional_development + + let resume_content( + skills: ( + ( + title: "", + items: (""), + ), + ), + education: ( + ( + title: "", + degree: "", + graduation: "", + gpa: "", + coursework: (""), + highlights: (""), + ), + ), + work_experience: ( + ( + title: "", + location: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), + professional_development: ( + ( + title: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), + ) = grid( + gutter: 2.4em, + section_skills(skills: skills), + section_education(education: education), + section_work_experience(work_experience: work_experience), + section_professional_development(professional_development: professional_development), + ) + + base_page( + base_text( + grid( + gutter: 2.75em, + section_identity(identity: identity), + resume_content( + skills: skills, + education: education, + work_experience: work_experience, + professional_development: professional_development, + ) + ) + ) + ) +} diff --git a/src/resume_page.typ b/src/resume_page.typ deleted file mode 100644 index ca43e3b..0000000 --- a/src/resume_page.typ +++ /dev/null @@ -1,402 +0,0 @@ -#let resume_page( - identity: ( - name: "", - email: "", - phone: "", - location: "", - website: "", - ), - skills: ( - ( - title: "", - items: (""), - ), - ), - education: ( - ( - title: "", - degree: "", - graduation: "", - gpa: "", - coursework: (""), - highlights: (""), - ), - ), - work_experience: ( - ( - title: "", - location: "", - timeframe: "", - role: "", - skills: (""), - highlights: (""), - ), - ), - professional_development: ( - ( - title: "", - timeframe: "", - role: "", - skills: (""), - highlights: (""), - ), - ), -) = { - let _block( - below: 0em, - width: 100%, - padding: ( - top: 0em, - right: 0em, - bottom: 0em, - left: 0em, - ), - body - ) = block( - below: below, - width: width, - align( - top + left, - pad( - ..padding, - body - ) - ) - ) - - let _text( - font: "Inter", - size: 10pt, - weight: "regular", - block: ( - below: 0em, - width: 100%, - padding: ( - top: 0em, - right: 0em, - bottom: 0em, - left: 0em, - ), - ), - body - ) = text( - font: font, - size: size, - weight: weight, - _block( - ..block, - body - ) - ) - - let section_base( - title: "", - body - ) = _text( - block: (below: 2.5em), - { - _text( - size: 13pt, - block: (below: .95em), - heading( - _text( - size: 13pt, - weight: "bold", - title - ) - ) - ) - _text( - block: ( - padding: (left: 1em), - ), - body - ) - } - ) - - let section_item( - title: "", - subtitle: "", - role: "", - timeframe: "", - skills: (""), - highlights: (""), - ) = _text( - block: (below: 1.5em), - { - _text( - block: (below: 0.95em), - grid( - columns: (40%, 60%), - rows: 2, - gutter: 0.75em, - align: ( - left, - right, - ), - grid( - columns: 2, - gutter: 1.5em, - align: bottom, - heading( - level: 2, - _text( - weight: "semibold", - block: (width: auto), - title - ), - ), - text( - size: 9pt, - weight: "extralight", - subtitle - ) - ), - text( - weight: "regular", - timeframe - ), - text( - weight: "light", - size: 9.5pt, - role - ), - text( - weight: "light", - size: 9.5pt, - skills.join(", "), - ), - ) - ) - _text( - block: ( - padding: (left: 2em), - ), - for highlight in highlights { - _text( - block: (below: 1em), - par( - justify: true, - highlight - ) - ) - } - ) - } - ) - - let section( - title: "", - items: ( - ( - title: "", - subtitle: "", - role: "", - timeframe: "", - skills: (""), - highlights: (""), - ), - ), - ) = section_base( - title: title, - for item in items { - section_item(..item) - } - ) - - let title_block(title: "") = _text( - size: 28pt, - block: (below: 0.60em), - weight: "extrabold", - align( - center, - title - ) - ) - - let contact_info_block( - email: "", - phone: "", - location: "", - website: "", - ) = _text( - size: 10.5pt, - block: (below: 2.75em), - weight: "medium", - align( - center, - grid( - columns: 4, - rows: 1, - gutter: 4em, - email, - phone, - location, - website, - ) - ) - ) - - let skills_block( - skills: ( - ( - title: "", - items: (""), - ), - ), - ) = section_base( - title: "Skills", - _text( - grid( - columns: 2, - gutter: 1em, - ..for skill in skills { - ( - heading( - level: 2, - _text( - weight: "semibold", - block: (width: auto), - skill.title - ) - ), - skill.items.join(", "), - ) - } - ) - ) - ) - - let education_block( - education: ( - ( - title: "", - degree: "", - graduation: "", - gpa: "", - coursework: ( - completed: (""), - current: (""), - ), - highlights: (""), - ), - ), - ) = section( - title: "Education", - items: education.map(school => ( - title: school.title, - role: school.degree, - timeframe: school.graduation, - skills: ( - school.gpa, - ), - highlights: ( - ..school.highlights, - { - _text( - weight: "medium", - block: ( - below: .95em, - ), - "Relevant Coursework" - ) - _text( - size: 9.5pt, - block: ( - padding: ( - left: 1.5em, - ), - ), - grid( - columns: 2, - rows: 2, - gutter: 1em, - text( - weight: "regular", - "Completed", - ), - text( - weight: "light", - school.coursework.completed.join(", "), - ), - text( - weight: "regular", - "Current", - ), - text( - weight: "light", - school.coursework.current.join(", "), - ), - ) - ) - } - ), - )) - ) - - let work_experience_block( - work_experience: ( - ( - title: "", - location: "", - timeframe: "", - role: "", - skills: (""), - highlights: (""), - ), - ), - ) = section( - title: "Work Experience", - items: work_experience.map(company => ( - title: company.title, - subtitle: company.location, - timeframe: company.timeframe, - role: company.role, - skills: company.skills, - highlights: company.highlights, - )), - ) - - let professional_development_block( - professional_development: ( - ( - title: "", - timeframe: "", - role: "", - skills: (""), - highlights: (""), - ), - ), - ) = section( - title: "Professional Development", - items: professional_development.map(item => ( - title: item.title, - timeframe: item.timeframe, - role: item.role, - skills: item.skills, - highlights: item.highlights, - )), - ) - - page( - paper: "us-letter", - margin: ( - x: 0.5in, - y: 0.3in, - ), - { - title_block(title: identity.name) - contact_info_block( - email: identity.email, - phone: identity.phone, - location: identity.location, - website: identity.website, - ) - skills_block(skills: skills) - education_block(education: education) - work_experience_block(work_experience: work_experience) - professional_development_block(professional_development: professional_development) - } - ) -} diff --git a/src/section/base/full.typ b/src/section/base/full.typ new file mode 100644 index 0000000..314f96f --- /dev/null +++ b/src/section/base/full.typ @@ -0,0 +1,26 @@ +#let section_base_full( + title: "", + items: ( + ( + title: "", + subtitle: "", + role: "", + timeframe: "", + skills: (""), + highlights: (""), + ), + ), +) = { + import "small.typ": section_base_small + import "item.typ": section_base_item + + section_base_small( + title: title, + grid( + gutter: 1.5em, + for item in items { + section_base_item(..item) + } + ) + ) +} diff --git a/src/section/base/item.typ b/src/section/base/item.typ new file mode 100644 index 0000000..9ba2de0 --- /dev/null +++ b/src/section/base/item.typ @@ -0,0 +1,36 @@ +#let section_base_item( + title: "", + subtitle: "", + role: "", + timeframe: "", + skills: (""), + highlights: (""), +) = { + import "../../base/text.typ": base_text + import "item/header.typ": section_base_item_header + + let item_highlights(highlights: highlights) = for highlight in highlights { + block( + below: 1em, + par( + justify: true, + highlight + ) + ) + } + + grid( + gutter: 0.95em, + section_base_item_header( + title: title, + subtitle: subtitle, + role: role, + timeframe: timeframe, + skills: skills, + ), + pad( + left: 2em, + item_highlights(highlights: highlights) + ) + ) +} diff --git a/src/section/base/item/header.typ b/src/section/base/item/header.typ new file mode 100644 index 0000000..ea65915 --- /dev/null +++ b/src/section/base/item/header.typ @@ -0,0 +1,66 @@ +#let section_base_item_header( + title: "", + subtitle: "", + role: "", + timeframe: "", + skills: (""), + ) = { + import "../../../base/text.typ": base_text + + let header_title( + title: "", + subtitle: "", + ) = grid( + columns: 2, + gutter: 1.5em, + align: bottom, + heading( + level: 2, + base_text( + text( + weight: "semibold", + title + ) + ) + ), + text( + size: .9em, + weight: "extralight", + subtitle + ), + ) + + grid( + columns: 2, + rows: 2, + gutter: 0.75em, + align: ( + left, + right, + ), + header_title( + title: title, + subtitle: subtitle, + ), + block( + width: 100%, + text( + weight: "regular", + timeframe + ) + ), + text( + weight: "light", + size: .95em, + role + ), + block( + width: 100%, + text( + weight: "light", + size: .95em, + skills.join(", ") + ) + ), + ) +} diff --git a/src/section/base/small.typ b/src/section/base/small.typ new file mode 100644 index 0000000..69fa4fa --- /dev/null +++ b/src/section/base/small.typ @@ -0,0 +1,23 @@ +#let section_base_small( + title: "", + body +) = { + import "../../base/text.typ": base_text + + grid( + gutter: 1.1em, + heading( + base_text( + text( + size: 1.3em, + weight: "bold", + title + ) + ) + ), + pad( + left: 1em, + body + ) + ) +} diff --git a/src/section/education.typ b/src/section/education.typ new file mode 100644 index 0000000..6fa73cb --- /dev/null +++ b/src/section/education.typ @@ -0,0 +1,34 @@ +#let section_education( + education: ( + ( + title: "", + degree: "", + graduation: "", + gpa: "", + coursework: ( + completed: (""), + current: (""), + ), + highlights: (""), + ), + ), +) = { + import "base/full.typ": section_base_full + import "education/coursework.typ": section_education_coursework + + section_base_full( + title: "Education", + items: education.map(school => ( + title: school.title, + role: school.degree, + timeframe: school.graduation, + skills: ( + school.gpa, + ), + highlights: ( + ..school.highlights, + section_education_coursework(..school.coursework), + ), + )) + ) +} diff --git a/src/section/education/coursework.typ b/src/section/education/coursework.typ new file mode 100644 index 0000000..ac9d96d --- /dev/null +++ b/src/section/education/coursework.typ @@ -0,0 +1,47 @@ +#let section_education_coursework( + completed: (""), + current: (""), +) = { + let coursework_content( + completed: (""), + current: (""), + ) = grid( + columns: 2, + rows: 2, + gutter: 1em, + text( + weight: "regular", + "Completed", + ), + text( + weight: "light", + completed.join(", "), + ), + text( + weight: "regular", + "Current", + ), + text( + weight: "light", + current.join(", "), + ), + ) + + grid( + gutter: .95em, + text( + weight: "medium", + "Relevant Coursework" + ), + pad( + left: 1.5em, + text( + size: .95em, + coursework_content( + completed: completed, + current: current, + ) + ) + ) + ) +} diff --git a/src/section/identity.typ b/src/section/identity.typ new file mode 100644 index 0000000..d6d3a40 --- /dev/null +++ b/src/section/identity.typ @@ -0,0 +1,46 @@ +#let section_identity( + identity: ( + name: "", + email: "", + phone: "", + location: "", + website: "", + ), +) = { + let title(title: "") = text( + size: 2.8em, + weight: "extrabold", + title + ) + + let contact_info( + email: "", + phone: "", + location: "", + website: "", + ) = text( + size: 1.05em, + weight: "medium", + grid( + columns: 4, + rows: 1, + gutter: 4em, + email, + phone, + location, + website, + ) + ) + + grid( + gutter: 1.5em, + align: center, + title(title: identity.name), + contact_info( + email: identity.email, + phone: identity.phone, + location: identity.location, + website: identity.website, + ), + ) +} diff --git a/src/section/professional_development.typ b/src/section/professional_development.typ new file mode 100644 index 0000000..a3db63b --- /dev/null +++ b/src/section/professional_development.typ @@ -0,0 +1,24 @@ +#let section_professional_development( + professional_development: ( + ( + title: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), +) = { + import "base/full.typ": section_base_full + + section_base_full( + title: "Professional Development", + items: professional_development.map(item => ( + title: item.title, + timeframe: item.timeframe, + role: item.role, + skills: item.skills, + highlights: item.highlights, + )), + ) +} diff --git a/src/section/skills.typ b/src/section/skills.typ new file mode 100644 index 0000000..1ebafe2 --- /dev/null +++ b/src/section/skills.typ @@ -0,0 +1,33 @@ +#let section_skills( + skills: ( + ( + title: "", + items: (""), + ), + ), +) = { + import "../base/text.typ": base_text + import "base/small.typ": section_base_small + + section_base_small( + title: "Skills", + grid( + columns: 2, + gutter: 1em, + ..for skill in skills { + ( + heading( + level: 2, + base_text( + text( + weight: "semibold", + skill.title + ) + ) + ), + skill.items.join(", "), + ) + } + ) + ) +} diff --git a/src/section/work_experience.typ b/src/section/work_experience.typ new file mode 100644 index 0000000..16c6971 --- /dev/null +++ b/src/section/work_experience.typ @@ -0,0 +1,26 @@ +#let section_work_experience( + work_experience: ( + ( + title: "", + location: "", + timeframe: "", + role: "", + skills: (""), + highlights: (""), + ), + ), +) = { + import "base/full.typ": section_base_full + + section_base_full( + title: "Work Experience", + items: work_experience.map(company => ( + title: company.title, + subtitle: company.location, + timeframe: company.timeframe, + role: company.role, + skills: company.skills, + highlights: company.highlights, + )), + ) +}