grelin_templates/resume-career/data/layout.typ
MORRO 769decd445 Add resume-career template and migrate resume to resume-bp.
Introduce one-page career resume alongside the full BP resume, unify brand color across templates, and update monorepo docs and gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 23:19:37 +08:00

146 lines
4.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#import "theme.typ": *
#import "config.typ": *
// =====================================================================
// GreLin 求职简历 · LayoutTailwind 灰稿)
// 双栏共用 grid右栏联系方式与下方模块左对齐
// =====================================================================
#let sidebar-photo() = {
let path = profile.at("photo-path", default: "")
if path != "" {
block(width: 100%, below: space-photo-below)[
#box(width: 100%, clip: true, radius: rounded)[
#image(path, width: 100%, fit: "cover")
]
]
}
}
#let profile-block() = block(width: 100%)[
#text(font: heading-font, size: size-name, weight: weight-semibold, fill: color-accent)[#profile.name]
#v(space-name-summary)
#box(width: summary-max-width)[
#set text(fill: color-text-light, size: size-prose, weight: weight-normal)
#set par(leading: leading-prose, spacing: space-none, justify: false)
#profile.summary
]
]
#let sidebar-body(content) = {
set text(fill: color-text-light, size: size-prose, weight: weight-normal)
set par(leading: leading-prose, spacing: space-none, justify: false)
content
}
#let sidebar-body-en(content) = sidebar-body(content)
#let sidebar-body-zh(content) = sidebar-body(content)
#let contact-block() = block(width: 100%)[
#let github = contact.at("github", default: "")
#let github-label = contact.at("github-label", default: github)
#set text(font: mono-font, size: size-prose, fill: color-meta, weight: weight-normal)
#set par(leading: leading-prose, spacing: space-contact-line)
#link("mailto:" + contact.email, contact.email)
#linebreak()
#link("tel:" + contact.phone, contact.phone)
#if github != "" [
#linebreak()
#link(github, github-label)
]
#if contact.website != "" [
#linebreak()
#link(contact.website, contact.website-label)
]
]
#let section-title(title, above: auto, below: auto, accent: true) = {
let gap-above = if above != auto { above } else { space-section }
let gap-below = if below != auto { below } else { space-title-below }
let title-color = if accent { color-accent } else { color-heading }
block(width: 100%, above: gap-above, below: gap-below)[
#text(font: heading-font, size: size-section, weight: weight-semibold, fill: title-color)[#title]
]
}
#let sidebar-subtitle(title, above: auto, below: auto) = {
let gap-above = if above != auto { above } else { space-skill-group }
let gap-below = if below != auto { below } else { space-subtitle-below }
block(above: gap-above, below: gap-below)[
#text(font: heading-font, size: size-body, weight: weight-semibold, fill: color-heading)[#title]
]
}
#let sidebar-entry-title(title) = block(below: space-subtitle-below)[
#text(font: heading-font, size: size-body, weight: weight-semibold, fill: color-heading)[#title]
]
#let experience-entry(entry) = block[
#text(font: heading-font, size: size-body, fill: color-heading)[
#entry.role
#text(fill: color-text-light, weight: weight-normal)[ · ]
#text(weight: weight-semibold)[#entry.company]
#h(space-entry-date-gap)
#text(font: mono-font, fill: color-meta, size: size-body, weight: weight-normal)[
#entry.start#if entry.end != "" [ — #entry.end]
]
]
#v(space-entry-title-below)
#set text(fill: color-text-light, size: size-prose, weight: weight-normal)
#set par(leading: leading-prose, spacing: space-none, justify: false)
#set list(tight: true, indent: list-indent, body-indent: list-body-indent)
#for line in entry.bullets [
- #line
]
]
#let experiences-block() = {
for (i, entry) in experiences.enumerate() {
if i > 0 { v(space-entry) }
experience-entry(entry)
}
}
#let skills-block() = {
for (i, cat) in skills.categories.enumerate() {
sidebar-subtitle(cat.title, above: if i == 0 { space-none } else { space-subtitle-group })
block(below: space-none)[
#sidebar-body-en[#cat.items]
]
}
}
#let sidebar-project-entry(entry) = block[
#sidebar-entry-title(entry.name)
#sidebar-body-zh[#entry.intro]
]
#let sidebar-projects-block() = {
for (i, entry) in projects.enumerate() {
if i > 0 { v(space-sidebar-item) }
sidebar-project-entry(entry)
}
}
#let sidebar-edu-entry(item) = block[
#sidebar-entry-title(item.school)
#sidebar-body-zh[
#item.degree#if item.period != "" [ · #item.period]
]
]
#let sidebar-education-block() = {
for (i, item) in education.enumerate() {
if i > 0 { v(space-sidebar-item) }
sidebar-edu-entry(item)
}
}
#let interests-block() = {
if interests != "" {
block(above: space-none)[
#sidebar-body-zh[#interests]
]
}
}