Compare commits
2 Commits
b8eed931ac
...
ed33425ee9
| Author | SHA1 | Date | |
|---|---|---|---|
| ed33425ee9 | |||
| ab0f73cbd6 |
3
.gitignore
vendored
@ -3,6 +3,9 @@
|
|||||||
!resume/sample.pdf
|
!resume/sample.pdf
|
||||||
!feasibility/sample.pdf
|
!feasibility/sample.pdf
|
||||||
|
|
||||||
|
# 本地定制简历(个人内容、照片、PDF,不提交)
|
||||||
|
resume/local/
|
||||||
|
|
||||||
# IDE / 编辑器本地配置
|
# IDE / 编辑器本地配置
|
||||||
.cursor/
|
.cursor/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# Resume · 团队简历模板
|
# Resume · 团队简历模板
|
||||||
|
|
||||||
GreLin 双栏中文简历 Typst 模板(HyperLabel 配色),用于融资 BP data room 附录。
|
GreLin 双栏中文简历 Typst 模板,用于融资 BP data room 附录。
|
||||||
|
|
||||||
## 照片
|
## 照片
|
||||||
|
|
||||||
@ -25,16 +25,17 @@ GreLin 双栏中文简历 Typst 模板(HyperLabel 配色),用于融资 BP
|
|||||||
)
|
)
|
||||||
|
|
||||||
#let skills = (
|
#let skills = (
|
||||||
abilities: (
|
|
||||||
(name: "全栈开发", level: 0.9),
|
|
||||||
),
|
|
||||||
language: (
|
|
||||||
name: "英语",
|
|
||||||
level: 0.75,
|
|
||||||
label: "读写",
|
|
||||||
),
|
|
||||||
tags: ("Rust", "Python"),
|
tags: ("Rust", "Python"),
|
||||||
notes: (), // 可选:侧栏技能补充列表
|
notes: (), // 可选:侧栏技能补充列表
|
||||||
|
// 可选:能力进度条(有数据时自动显示「能力」子区块)
|
||||||
|
// abilities: (
|
||||||
|
// (name: "全栈开发", level: 0.9),
|
||||||
|
// ),
|
||||||
|
// language: (
|
||||||
|
// name: "英语",
|
||||||
|
// level: 0.75,
|
||||||
|
// label: "读写",
|
||||||
|
// ),
|
||||||
)
|
)
|
||||||
|
|
||||||
#let education = (
|
#let education = (
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#C4D94A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#434950" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 294 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#C4D94A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#434950" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#C4D94A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#434950" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#C4D94A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#434950" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 480 B |
@ -33,12 +33,22 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
#let main-content = [
|
#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()
|
#experiences-block()
|
||||||
|
|
||||||
#section-title("项目经历")
|
#section-title("项目经历")
|
||||||
#projects-block()
|
#projects-block()
|
||||||
|
|
||||||
|
#if publications.len() > 0 [
|
||||||
|
#section-title("代表性成果")
|
||||||
|
#publications-block()
|
||||||
|
]
|
||||||
|
|
||||||
#if awards.len() > 0 [
|
#if awards.len() > 0 [
|
||||||
#section-title("获奖经历")
|
#section-title("获奖经历")
|
||||||
#awards-block()
|
#awards-block()
|
||||||
|
|||||||
@ -22,15 +22,6 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
#let skills = (
|
#let skills = (
|
||||||
abilities: (
|
|
||||||
(name: "全栈开发", level: 0.9),
|
|
||||||
(name: "系统架构", level: 0.75),
|
|
||||||
),
|
|
||||||
language: (
|
|
||||||
name: "英语",
|
|
||||||
level: 0.75,
|
|
||||||
label: "读写",
|
|
||||||
),
|
|
||||||
tags: (
|
tags: (
|
||||||
"Rust", "Python", "Java", "React", "Tauri", "RAG", "Linux", "MySQL", "Redis",
|
"Rust", "Python", "Java", "React", "Tauri", "RAG", "Linux", "MySQL", "Redis",
|
||||||
"LLM Agent",
|
"LLM Agent",
|
||||||
@ -108,3 +99,7 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
#let awards = ()
|
#let awards = ()
|
||||||
|
|
||||||
|
// 可选:研究经历、代表性成果(留空则不渲染)
|
||||||
|
#let research = ""
|
||||||
|
#let publications = ()
|
||||||
|
|||||||
@ -82,9 +82,15 @@
|
|||||||
} else if sidebar {
|
} else if sidebar {
|
||||||
space-none
|
space-none
|
||||||
} else {
|
} else {
|
||||||
space-block
|
space-main-section
|
||||||
|
}
|
||||||
|
let title-below = if below != auto {
|
||||||
|
below
|
||||||
|
} else if sidebar {
|
||||||
|
space-title-gap
|
||||||
|
} else {
|
||||||
|
space-main-title-below
|
||||||
}
|
}
|
||||||
let title-below = if below != auto { below } else { space-title-gap }
|
|
||||||
block(width: 100%, above: title-above, below: title-below)[
|
block(width: 100%, above: title-above, below: title-below)[
|
||||||
#text(font: heading-font, size: size-heading, weight: "bold", fill: color-ink)[#title]
|
#text(font: heading-font, size: size-heading, weight: "bold", fill: color-ink)[#title]
|
||||||
#if divider [
|
#if divider [
|
||||||
@ -121,7 +127,7 @@
|
|||||||
/// 教育背景条目(notes 可选,一段普通正文)
|
/// 教育背景条目(notes 可选,一段普通正文)
|
||||||
#let edu-entry(degree, school, period, location, notes: "") = block(above: space-none, below: space-none)[
|
#let edu-entry(degree, school, period, location, notes: "") = block(above: space-none, below: space-none)[
|
||||||
#text(fill: color-body, size: size-body)[#degree]
|
#text(fill: color-body, size: size-body)[#degree]
|
||||||
#v(space-inline)
|
#v(space-edu-meta-gap)
|
||||||
#text(fill: color-text-light, size: size-secondary)[
|
#text(fill: color-text-light, size: size-secondary)[
|
||||||
#school#if period != "" [ · #period]#if location != "" [ · #location]
|
#school#if period != "" [ · #period]#if location != "" [ · #location]
|
||||||
]
|
]
|
||||||
@ -174,7 +180,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 技能进度条(level: 0–1);条与条之间仅用 above 控制间距
|
/// 技能进度条(level: 0–1);config 提供 abilities / language 时由 abilities-block 渲染
|
||||||
#let skill-bar(name, level, subtitle: none, above: space-none) = block(above: above, below: space-none)[
|
#let skill-bar(name, level, subtitle: none, above: space-none) = block(above: above, below: space-none)[
|
||||||
#if subtitle != none [
|
#if subtitle != none [
|
||||||
#grid(
|
#grid(
|
||||||
@ -193,6 +199,56 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#let has-abilities-section() = {
|
||||||
|
let ability-list = skills.at("abilities", default: ())
|
||||||
|
let has-lang = skills.at("language", default: none) != none
|
||||||
|
ability-list.len() > 0 or has-lang
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 「能力」进度条区块(skills.abilities / skills.language 有数据时才显示)
|
||||||
|
#let abilities-block() = {
|
||||||
|
if has-abilities-section() {
|
||||||
|
sidebar-subtitle("能力", above: space-none)
|
||||||
|
block(below: space-none)[
|
||||||
|
#for (i, item) in skills.at("abilities", default: ()).enumerate() {
|
||||||
|
skill-bar(
|
||||||
|
item.name,
|
||||||
|
item.level,
|
||||||
|
above: if i == 0 { space-none } else { space-skill-gap },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#let lang = skills.at("language", default: none)
|
||||||
|
#if lang != none {
|
||||||
|
skill-bar(
|
||||||
|
lang.name,
|
||||||
|
lang.level,
|
||||||
|
subtitle: lang.at("label", default: none),
|
||||||
|
above: if skills.at("abilities", default: ()).len() == 0 {
|
||||||
|
space-none
|
||||||
|
} else {
|
||||||
|
space-skill-gap
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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(
|
#let tech-pill(label) = box(
|
||||||
fill: color-page,
|
fill: color-page,
|
||||||
stroke: stroke-pill,
|
stroke: stroke-pill,
|
||||||
@ -213,24 +269,16 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
#let skills-section-block() = {
|
#let skills-section-block() = {
|
||||||
sidebar-subtitle("能力", above: space-none)
|
abilities-block()
|
||||||
block(below: space-none)[
|
if has-skill-groups() {
|
||||||
#for (i, item) in skills.abilities.enumerate() {
|
skill-groups-block()
|
||||||
skill-bar(
|
} else {
|
||||||
item.name,
|
sidebar-subtitle(
|
||||||
item.level,
|
"技术栈",
|
||||||
above: if i == 0 { space-none } else { space-skill-gap },
|
above: if has-abilities-section() { space-subsection-gap } else { space-none },
|
||||||
)
|
)
|
||||||
}
|
|
||||||
#skill-bar(
|
|
||||||
skills.language.name,
|
|
||||||
skills.language.level,
|
|
||||||
subtitle: skills.language.label,
|
|
||||||
above: space-skill-gap,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
sidebar-subtitle("技术栈", above: space-subsection-gap)
|
|
||||||
tech-stack-block()
|
tech-stack-block()
|
||||||
|
}
|
||||||
if skills.notes.len() > 0 {
|
if skills.notes.len() > 0 {
|
||||||
sidebar-subtitle("补充", above: space-subsection-gap)
|
sidebar-subtitle("补充", above: space-subsection-gap)
|
||||||
skill-notes-block()
|
skill-notes-block()
|
||||||
@ -239,6 +287,7 @@
|
|||||||
|
|
||||||
/// 主栏经历 / 项目条目
|
/// 主栏经历 / 项目条目
|
||||||
#let timeline-entry(entry, title-key: "company", subtitle-key: "role") = block[
|
#let timeline-entry(entry, title-key: "company", subtitle-key: "role") = block[
|
||||||
|
#block(above: space-entry-title-above, below: space-entry-title-below)[
|
||||||
#text(fill: color-body, size: size-body, weight: "bold")[
|
#text(fill: color-body, size: size-body, weight: "bold")[
|
||||||
#if subtitle-key != none [
|
#if subtitle-key != none [
|
||||||
#entry.at(title-key) / #entry.at(subtitle-key)
|
#entry.at(title-key) / #entry.at(subtitle-key)
|
||||||
@ -246,10 +295,16 @@
|
|||||||
#entry.at(title-key)
|
#entry.at(title-key)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
#v(space-body)
|
]
|
||||||
#text(fill: color-text-light, size: size-body)[
|
#text(fill: color-text-light, size: size-body)[
|
||||||
#entry.location#if entry.location != "" [,]#entry.start - #entry.end
|
#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)
|
#v(space-body)
|
||||||
#set text(weight: "regular", fill: color-text-light, size: size-body)
|
#set text(weight: "regular", fill: color-text-light, size: size-body)
|
||||||
#set par(leading: list-item-leading, spacing: space-none, justify: true)
|
#set par(leading: list-item-leading, spacing: space-none, justify: true)
|
||||||
@ -282,8 +337,9 @@
|
|||||||
|
|
||||||
/// 获奖经历条目(bullets 可留空)
|
/// 获奖经历条目(bullets 可留空)
|
||||||
#let award-entry(entry) = block[
|
#let award-entry(entry) = block[
|
||||||
|
#block(above: space-entry-title-above, below: space-entry-title-below)[
|
||||||
#text(fill: color-body, size: size-body, weight: "bold")[#entry.title]
|
#text(fill: color-body, size: size-body, weight: "bold")[#entry.title]
|
||||||
#v(space-body)
|
]
|
||||||
#text(fill: color-text-light, size: size-body)[#entry.meta]
|
#text(fill: color-text-light, size: size-body)[#entry.meta]
|
||||||
#if entry.bullets.len() > 0 [
|
#if entry.bullets.len() > 0 [
|
||||||
#v(space-body)
|
#v(space-body)
|
||||||
@ -306,3 +362,29 @@
|
|||||||
award-entry(entry)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
#import "../../brand/colors.typ": *
|
#import "../../brand/colors.typ": *
|
||||||
|
|
||||||
#let color-accent-bright = color-lime-deep
|
#let color-icon = color-muted
|
||||||
|
#let color-accent-bright = color-body
|
||||||
#let color-accent = color-muted
|
#let color-accent = color-muted
|
||||||
#let color-skill-bar = color-lime-mid
|
#let color-skill-bar = color-muted
|
||||||
#let color-divider = color-muted.lighten(68%)
|
#let color-divider = color-muted.lighten(68%)
|
||||||
#let color-text-light = color-muted.lighten(32%)
|
#let color-text-light = color-muted.lighten(32%)
|
||||||
|
|
||||||
@ -35,9 +36,14 @@
|
|||||||
#let space-body = size-body
|
#let space-body = size-body
|
||||||
#let space-title-gap = 12pt
|
#let space-title-gap = 12pt
|
||||||
#let space-edu-notes-before = space-title-gap
|
#let space-edu-notes-before = space-title-gap
|
||||||
|
#let space-edu-meta-gap = 10pt
|
||||||
#let leading-edu-notes = size-secondary
|
#let leading-edu-notes = size-secondary
|
||||||
#let space-between-entries = 12pt
|
#let space-between-entries = 20pt
|
||||||
|
#let space-entry-title-above = 6pt
|
||||||
|
#let space-entry-title-below = 14pt
|
||||||
#let space-block = 18pt
|
#let space-block = 18pt
|
||||||
|
#let space-main-section = 26pt
|
||||||
|
#let space-main-title-below = 14pt
|
||||||
#let space-hero-to-photo = space-block
|
#let space-hero-to-photo = space-block
|
||||||
#let space-column-gap = space-title-gap
|
#let space-column-gap = space-title-gap
|
||||||
|
|
||||||
@ -86,6 +92,6 @@
|
|||||||
#let page-margin = (
|
#let page-margin = (
|
||||||
top: 2cm,
|
top: 2cm,
|
||||||
bottom: 2cm,
|
bottom: 2cm,
|
||||||
left: 2cm,
|
left: 1.5cm,
|
||||||
right: 2cm,
|
right: 1.5cm,
|
||||||
)
|
)
|
||||||
|
|||||||