This template for an academic CV serves the peculiarities of academic CVs. If you are not an academic, this template is not useful. Most of the times in academics, applicants need to show everything they have done. This makes it a bit cumbersome doing it by single entries. In addition, academics might apply to institutions around the globe, making it necessary to send translated CVs or at least translations of some parts (i.e., title of papers in different languages).
This template serves these special needs in introducting automated sections based on indicated yaml
-files. Furthermore, it has a simplified multilingual support by setting different headers, title etc. for different languages (by the user in the yaml
-fields). With this template, it might be more handy to keep your CV easier on track, especially when you need in different languages, since managing a yaml
-file is easier than checking typesetting files against each other.
This template is influenced by LaTeX’s moderncv and its typst translation moderner-cv.
Fonts
In this template, the use of FontAwesome icons via the fontawesome typst package is possible, as well as the icons from Academicons use-academicons typst package. To use these icons properly, you need to install each fonts on your system. You can download fontawesome here and academicons here. Both typst packages will be load by the template itself.
Furthermore, I included my favorite font Fira Sans. You can download it here here, or just change the font argument in modern-acad-cv()
.
Usage
The main function to load the construct of the academic CV is modern-acad-cv()
. After importing the template, you can call it right away. If you don’t have Fira Sans installed, choose a different font. Examples are given below.
#import "@preview/modern-acad-cv:0.1.0": *
#show: modern-acad-cv.with(
metadata,
multilingual,
lang: "en",
font: ("Fira Sans", "Andale Mono", "Roboto"),
show-date: true,
body
)
// ...
In the remainder, I show basic settings and how to use the automated functions with the corresponding yaml
-file.
Setting up the main file and the access to the yaml
-files
A first step in your document is to invoke the template. Second, since this template works with yaml
-files in the background you need to specify paths to each yaml
-file you want to use throughout the document.
The template comes along with the metadata.yaml
. In the beginning of this yaml-file you set colors. Feel free to change it to your preferred color scheme.
colors:
main_color: "#579D90"
lightgray_color: "#d5d5d5"
gray_color: "#737373"
...
At the beginning of your document, you just set then set the metadata-object:
#import "@preview/modern-acad-cv:0.1.0": *
#let metadata = yaml("metadata.yaml")
Initially, the metadata.yaml
is located on the same level as the example.typ
. All other yaml
-files are saved in the folder dbs
. Since typ
-documents search for paths from the root of the document in that the function is called, you have to give the databases for the entry along the metadata.yaml
within each function call.
socials
Contact details are important. In this CV template, you have the possibility to use fontawesome icons and academicons. To use socials, you just need to specify in metadata.yaml
, the wanted entries.
As you can see below, you set a category, i.e. email or lattes and then you have to define four arguments: username
, prefix
, icon
, and set
. The username
will be used for constructing the link and will be shown next to the logo. The prefix
is needed to build the valid link. The icon
is the name of the icon in the respective set, which is chosen in set
.
personal:
name: ["Mustermensch, Momo"]
socials:
email:
username: momo@mustermensch.com
prefix: "mailto:"
icon: paper-plane
set: fa
homepage:
username: momo.github.io
prefix: https://
icon: globe
set: fa
orcid:
username: 0000-0000-0000-0000
prefix: https://orcid.org
icon: orcid
set: ai
lattes:
username: "1234567891234567"
prefix: http://lattes.cnpq.br/
icon: lattes
set: ai
...
Language setting & headers
In order to support changing headers, you need to specify the language and the different content for each header in each language in the i18n.yaml
in the folder dbs
.
The structure of the yaml is simple:
lang:
de:
subtitle: Short CV
education: Hochschulbildung
work: Akademische Berufserfahrung (Auswahl)
grants: Fördermittel, Stipendien & Preise
...
en:
subtitle: Short CV
education: Higher education
work: Academic work experience (selection)
grants: Scholarships & awards
...
pt:
subtitle: Currículo
education: Formação acadêmica
work: Atuação profissional (seleção)
grants: Bolsas de estudo e prémios
...
For each language, you want to use later, you have to define all the entries. Reminder, don’t change the entry names, since the functions won’t find it under different names without changing the functions.
First you have to set up a variable that inherits the ISO-language code, save the database into an object (here multilingual
) and then give the object multilingual
and language
to the function create-headers
:
// set the language of the document
#let language = "pt"
// loading multilingual database
#let multilingual = yaml("dbs/i18n.yaml")
// defining variables
#let headerLabs = create-headers(multilingual, lang: language)
You create an object headerLabs
that uses the function create-headers()
which will define the headers as you provided in the yaml
. Then by switching the language object, all headers (if used accordingly to the naming in the yaml
) will change directly.
Throughout the document you then reference the created headerLabs
object. If you change language, and values are provided, these automatically change.
= #headerLabs.at("work")
...
= #headerLabs.at("education")
...
= #headerLabs.at("grants")
Automated functions
All of the following functions share common arguments: what
, multilingual
, and lang
. In what
, you always declare the database you want to use with the function.
For example, to get work entries, you choose work
, which you defined beforehand as input from work.yaml
. In the multilingual
argument, you just pass the multilingual
object. In lang
you pass your language
object.
#let multilingual = yaml("dbs/multilingual.yaml")
#let work = yaml("dbs/work.yaml")
#let language = "pt"
// Function call with objects
#cv-auto-stc(work, multilingual, lang: language)
Sorting publications and referencing your own name or correpsonding
Since typst
so far does not support multiple bibliographies or subsetting these, this function let you choose specific entries via the entries
argument or group of entries by the tag
argument. Furthermore, you can indicate a string in me
that can be highlighted in every output entry (i.e., your formatted name). So far, this function leads to another function that create APA-style format, if you want to use any other citation style, you need to download the template on github, introduce your own styling and then add it in the cv-refs()
function.
#let multilingual = yaml("dbs/multilingual.yaml")
#let refs = yaml("dbs/refs/yaml")
// function call of group of peer-reviewed with tag `peer`
#cv-refs(refs, multilingual, tag: "peer", me: [Mustermensch, M.], lang: language)
You see in the example pictures that I used this function to built five different subheaders, i.e. for peer reviewed articles (tag: "peer"
) and chapters in edited books (tag: "edited"
). You can define the tags how you want, however, they need to put them into tag: <str>
.
Sometimes, it is not only necessary to highlight your own name, you might also want to indicate yourself as corresponding author. This can be done through the refs.yaml
which adhere to Hayagriva. By adding an argument corresponding
in the yaml and setting the value to true
, a small C
will appear next to your name.
Mustermensch2023:
type: "article"
date: 2023
page-range: 55-78
title: "Populism and Social Media: A Comparative Study of Political Mobilization"
tags: "peer"
author: [ "Mustermensch, Momo", "Rivera, Casey" ]
corresponding: true
parent:
title: "Journal of Political Communication"
volume: 41
issue: 3
serial-number:
doi: "10.1016/j.jpolcom.2023.102865"
For applications abroad, it might be worth to translate at least title of the publications so that other persons easily can see what the paper is about. In every title
argument, you can therefore provide a dictionary with the language codes and the titles. Keep the original title in main
and the translations with the corresponding language shortcut (i.e., "en"
or "pt"
). The function prints the main and translated title, depending on the provided translation in the refs.yaml
. Be aware, here you find not de
in the dictionary, instead you find main
. The original title needs to be wrapped in main
.
Mustermensch2023:
type: "article"
date: 2023
page-range: 55-78
title:
main: "Populismus und soziale Medien: Eine vergleichende Studie zur politischen Mobilisierung"
en: "Populism and Social Media: A Comparative Study of Political Mobilization"
pt: "Populismo e redes sociais: Um Estudo Comparativo de Mobilização Política"
tags: "peer"
author: [ "Mustermensch, Momo", "Rivera, Casey" ]
corresponding: true
parent:
title: "Journal of Political Communication"
volume: 41
issue: 3
serial-number:
doi: "10.1016/j.jpolcom.2023.102865"
cv-auto-skills()
Instead of just enumerating your skills or your knowledge of specific software, you can build a skill-matrix with this function. In this skill-matrix, you can have sections, i.e. Computer Languages, Programs and Languages. These sections are the highest level in the corresponding skills.yaml
:
computer:
...
programs:
...
languages:
...
You can then define in each categories specific skills, i.e. German and Portuguese in languages
:
computer:
...
programs:
...
languages:
german:
...
portugues:
...
For each entry, you have to define name
, level
and description
.
languages:
...
pt:
name:
de: Portugiesisch
en: Portuguese
pt: Português
level: 3
description:
de: fortgeschritten
en: advanced
pt: avançado
As you can see, you can again define language-dependent names in name
and descriptions in description
. level
is a numeric value and indicates how many of the four boxes are filled to indicate you level of proficiency. If you don’t have the need for a CV of different languages, you can directly define name
or description
.
You have to call the function with three objects skills
, multilingual
, and metadata
and the corresponding language
of the document:
#let skills = yaml("dbs/skills.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let metadata = yaml("dbs/metadata.yaml")
#let language = "pt"
#cv-auto-skills(skills, multilingual, metadata, lang: language)
Print your info without any formatting
The function cv-auto
is the base function for printing the provided infos in the specified yaml
file with no further formatting. The functions cv-auto-stc
and cv-auto-stp
do only differ in the point that cv-auto-stc
both give the title in bold, cv-auto-stp
puts the subtitle in parentheses and cv-auto-stc
puts the subtitle after a comma.
The structure of the corresponding yaml
files is simple: in each entry you can have the following entries: title
, subtitle
, location
, description
and left
. title
is mandatory, subtitle
, location
, and description
are voluntary. In all functions you need to specify left
, which indicates period of time, or year. For title
, subtitle
, location
, and description
, you can provide a dictionary for different languages (see below).
master:
title:
de: Master of Arts
en: Master of Arts
pt: Pós-Graduação
subtitle:
de: Sozialwissenschaften
en: Social Sciences
pt: Ciências Sociais
location:
de: Exzellenz-Universität
en: University of Excellence
pt: Universidade de Excelência
description:
de: mit Auszeichnung
en: with distinction
pt: com distinção
left: "2014"
In your main document, you then easily call the function and transfer the standard arguments what
, metadata
, and lang
.
// section of education
#let education = yaml("dbs/education.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#cv-auto-stp(education, multilingual, lang: language)
// section of work positions
#let work = yaml("dbs/work.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#cv-auto-stc(work, multilingual, lang: language)
// section of given talks
#let talks = yaml("dbs/talks.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#cv-auto(talks, multilingual, lang: language)
Creating a list instead of single entrie
Sometimes, instead of giving every entry, you want to group by year. Another example for this case could be that you want to summarize your memberships or reviewer duties.
The function cv-auto-list
uses just the standard input:
#let conferences = yaml("dbs/conferences.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#cv-auto-list(conferences, multilingual, lang: language)
The corresponding yaml
file is differently organized: The entry point in the file is the corresponding year. In every year, you organize your entries (i.e. conference participations). In each entry in a year, you have the name
and action
entry. You can provide a dictionary for the name
. For action
, I used P
and C
, for paper/presentation and chair. You can then manually define this upfront the function call for the reader, or you use the i18n.yaml
, indicate the explanations for each language in exp-confs
and then it automatically changes with the specific language code.
"2024":
conference2:
name: European Conference on Gender and Politics
action: P
conference1:
name: ECPR General Conference
action: P, C
The action will be added after each conference name in superscripts.
Creating a table
This case is mostly used for listing your prior teaching experience. The corresponding teaching.yaml
for this description, is organized as followed:
"2024":
course1:
summer: T
name:
de: "Statistik+: Einstieg in R leicht gemacht"
en: "Statistics+: Starting with R (de)"
pt: "Estatística+: Começando com R (de)"
study:
de: Bachelor
en: Bachelor
pt: Graduação
...
First you indicate the year "2024"
and then you organize all courses you gave within that year (i.e. here course1
). Mandatory are name
and study
. For both you can indicate a single value or a dictionary corresponding to your chosen languages. You can provide summer
if you want to indicate differences for terms. This is boolean
, the specific word is then given in the i18n.yaml
under table-winter
resp. table-summer
.
The function then uses again just the standard arguments and plots a table with the indicated year, name, and study area.
#let teaching = yaml("dbs/teaching.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#cv-table-teaching(teaching, multilingual, lang: language)
cv-auto-cats()
In case you want to directly print entries from categories that belong to one yaml
-file, you can use cv-auto-cats
. This will print the header for each subcategory and then the belonging entries.
An example is given in training.yaml
. In this file, further training is given by categories (i.e., methods and didactics). Within the categories you have here courses and then title
, location
, and left
. location
and title
can be dictionaries if you want to translate between different languages.
methods:
course2:
title: Bayesian modelling in the Social Sciences
location: An expensive Spring Seminar
left: "2024"
...
didactics:
course2:
title:
de: Konfliktkompetenz I + II
en: Conflict competence I + II
pt: Competência de conflitos I + II
location:
de: Universitätsallianz
en: University Alliance
pt: Aliança Universitária
left: "2019"
Call the function as usal:
#let training = yaml("dbs/training.yaml")
#let multilingual = yaml("dbs/multilingual.yaml")
#let language = "pt"
#let headerLabs = create-headers(multilingual, lang: language)
#cv-auto-cats(training, multilingual, headerLabs, lang: language)
Special cases: long names
If you have a long name that crosses the social media side, just set the argument split
to true
within metadata.yaml
:
...
personal:
name: ["Mustermensch, Momo"]
split: true
...
Examples