From ed33425ee908a186cd3ab00a6033830e9c29118d Mon Sep 17 00:00:00 2001 From: MORRO <3506897731@qq.com> Date: Thu, 25 Jun 2026 17:12:20 +0800 Subject: [PATCH] Extend resume template with optional research, publications, and skill groups. Ignore resume/local for personal configs and keep sample PDF in sync with template defaults. Co-authored-by: Cursor --- .gitignore | 3 +++ resume/cv.typ | 12 ++++++++- resume/data/config.typ | 4 +++ resume/data/layout.typ | 61 ++++++++++++++++++++++++++++++++++++++---- resume/sample.pdf | 6 ++--- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index afaf5c6..28e6dda 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ !resume/sample.pdf !feasibility/sample.pdf +# 本地定制简历(个人内容、照片、PDF,不提交) +resume/local/ + # IDE / 编辑器本地配置 .cursor/ .vscode/ diff --git a/resume/cv.typ b/resume/cv.typ index 449485c..2fa9205 100644 --- a/resume/cv.typ +++ b/resume/cv.typ @@ -33,12 +33,22 @@ ] #let main-content = [ - #section-title("工作经历", above: space-none) + #if research != "" [ + #section-title("研究经历", above: space-none) + #research-block() + ] + + #section-title("工作经历", above: if research != "" { auto } else { space-none }) #experiences-block() #section-title("项目经历") #projects-block() + #if publications.len() > 0 [ + #section-title("代表性成果") + #publications-block() + ] + #if awards.len() > 0 [ #section-title("获奖经历") #awards-block() diff --git a/resume/data/config.typ b/resume/data/config.typ index 0bab1fe..4a6928d 100644 --- a/resume/data/config.typ +++ b/resume/data/config.typ @@ -99,3 +99,7 @@ ) #let awards = () + +// 可选:研究经历、代表性成果(留空则不渲染) +#let research = "" +#let publications = () diff --git a/resume/data/layout.typ b/resume/data/layout.typ index 856a0aa..f314aa2 100644 --- a/resume/data/layout.typ +++ b/resume/data/layout.typ @@ -234,6 +234,21 @@ } } +#let has-skill-groups() = skills.at("groups", default: ()).len() > 0 + +#let skill-groups-block() = { + for (i, group) in skills.at("groups", default: ()).enumerate() { + sidebar-subtitle( + group.title, + above: if i == 0 and not has-abilities-section() { space-none } else { space-subsection-gap }, + ) + block(below: space-none)[ + #set par(leading: list-item-leading, spacing: space-none, justify: true) + #text(fill: color-text-light, size: size-secondary)[#group.items] + ] + } +} + #let tech-pill(label) = box( fill: color-page, stroke: stroke-pill, @@ -255,11 +270,15 @@ #let skills-section-block() = { abilities-block() - sidebar-subtitle( - "技术栈", - above: if has-abilities-section() { space-subsection-gap } else { space-none }, - ) - tech-stack-block() + if has-skill-groups() { + skill-groups-block() + } else { + sidebar-subtitle( + "技术栈", + above: if has-abilities-section() { space-subsection-gap } else { space-none }, + ) + tech-stack-block() + } if skills.notes.len() > 0 { sidebar-subtitle("补充", above: space-subsection-gap) skill-notes-block() @@ -280,6 +299,12 @@ #text(fill: color-text-light, size: size-body)[ #entry.location#if entry.location != "" [,]#entry.start - #entry.end ] + #let intro = entry.at("intro", default: "") + #if intro != "" [ + #v(space-body) + #set par(leading: list-item-leading, spacing: space-none, justify: true) + #text(weight: "regular", fill: color-text-light, size: size-body)[#intro] + ] #v(space-body) #set text(weight: "regular", fill: color-text-light, size: size-body) #set par(leading: list-item-leading, spacing: space-none, justify: true) @@ -337,3 +362,29 @@ award-entry(entry) } } + +#let research-block() = { + if research != "" { + block(above: space-none)[ + #set par(leading: leading-body, spacing: space-none, justify: true) + #text(fill: color-text-light, size: size-body)[#research] + ] + } +} + +#let publication-entry(entry, index) = block(above: space-none, below: space-none)[ + #if index > 1 { v(space-between-entries) } + #text(fill: color-body, size: size-secondary, weight: "bold")[ + \[#index\] #entry.title + ] + #v(space-inline) + #text(fill: color-text-light, size: size-secondary)[#entry.authors] + #v(space-micro) + #text(fill: color-text-light, size: size-secondary)[#entry.venue] +] + +#let publications-block() = { + for (i, entry) in publications.enumerate() { + publication-entry(entry, i + 1) + } +} diff --git a/resume/sample.pdf b/resume/sample.pdf index b31f402..546f839 100644 --- a/resume/sample.pdf +++ b/resume/sample.pdf @@ -4733,12 +4733,12 @@ T endstream endobj 119 0 obj -<> +<> endobj 120 0 obj <> stream -Typst 0.15.0zh2026-06-25T16:22:02+08:002026-06-25T16:22:02+08:001application/pdfwFnMDS1jMz01jF6pKGYgXA==wFnMDS1jMz01jF6pKGYgXA==proof1.7 +Typst 0.15.0zh2026-06-25T17:10:58+08:002026-06-25T17:10:58+08:001application/pdfYG9afPnvozvA+8c8Oh87JQ==YG9afPnvozvA+8c8Oh87JQ==proof1.7 endstream endobj 121 0 obj @@ -4869,7 +4869,7 @@ xref 0001005638 00000 n 0001006711 00000 n trailer -<> +<> startxref 1006881 %%EOF \ No newline at end of file