Programmatically generating my CV with Typst
It’s the time of year to start sending some summer job applications again. And is there a better way to procrastinate improve the job searching experience than to generate the CV from simple markup with Typst?
Typst is new1 a typesetting system similar to LaTeX, but has much nicer syntax, and also it’s written in Rust!🤷
In this post I’ll show some basic features of Typst to build a simple CV file that looks like this.
To get started, you can either install the
typstCLI or use their online editor, typst.app (both are excellent). If you have thetypstCLI installed, you can create a file likecv.typand compile it withtypst compile cv.typ. I highly recommend using the VS Code extension Tinymist Typst as it provides autocomplete, error reporting, formatting and instant previews.
Here’s everything required to make the page header with contact information:
#set page(
paper: "a4"
)
#set text(
font: "Inter"
)
#set par(
spacing: 2em
)
#grid(
columns: (1fr, 1fr),
align(left)[
= John Smith
],
align(right)[
Phone +123 45678910 \
#link("mailto:[email protected]") \
#link("https://my-own.website")
]
)
#line(length: 100%, stroke: 1pt + gray)
There are a few rules in the file first, which set the paper size, font family and paragraph spacing. After that there is a “grid” element which allows displaying elements side-by-side. I define two columns that are 1 fraction each. = in front of a line makes it a h1 header, == becomes h2 and so on..
I’m using the Inter font here, you probably need to install the it from here to your system, or use a different font.
Here’s what that looks like:
Not much content in there yet, but notice how simple the markup really is. And you don’t even need to look up the documentation very often since the VS Code extension has such great autocomplete.
For the sections, it’s possible to define custom elements like this:
#let section(content, title: str) = {
grid(columns: (1fr, 2.5fr),
[= #title],
content
)
}
#let subheader(content) = text(content, weight: "semibold", size: 1.2em)
They can be used to create sections without duplicating any markup:
#section(title: "Profile")[
#lorem(50) // 50 words of lorem ipsum
]
#section(title: "Experience")[
#subheader("Computer programmer") \
#lorem(60)
]
Very neat!
Some sections of a CV may not be required for all applications. Another useful thing to remember is that whole sections of the file can be commented out:
// #section(title: "Hobbies")[
// Frolicking, doodling, lollygagging, horsing around
// ]
This means that they will be omitted from the output, but aren’t completely gone from the file. The .typ file can also be checked into a git repository, so that all changes are tracked.
Here’s what the final product looks like, again: