An MyST template for CV
MyST CV Template
A reusable template for building academic CV websites with MyST Markdown, automatic CV PDF generation via Typst, blog support with RSS feeds, and automated deployment via GitHub Actions.
Features
- MyST Markdown source format with Jupyter notebook integration
- Automatic CV PDF generation from website content using Typst and modern-cv
- Blog with RSS and Atom feed generation
- Giscus comments (GitHub-backed) for blog posts
- GitHub Pages deployment on push to
main - Netlify PR previews for pull request review
- Pre-commit hooks: Black, codespell, nbstripout for code quality
Quick Start
- Click Use this template on GitHub to create a new repository
- Update
myst.ymlwith your site title, description, and table of contents - Replace placeholder content in
pages/with your own - Update
generate_cv.pypreamble with your author information - Update
generate_rss.pywith your site URL and metadata - Push to GitHub to trigger automated builds
Project Structure
.
โโโ myst.yml # MyST configuration
โโโ index.md # Landing page (bio, highlights, news)
โโโ custom.css # Custom CSS styling
โโโ requirements.txt # Python dependencies
โโโ generate_cv.py # CV PDF generation script
โโโ generate_rss.py # RSS/Atom feed generation script
โโโ inject_comments.py # Giscus comment injection script
โโโ Dockerfile # Docker build for full site
โโโ logo.png # Site logo
โโโ fav.ico # Favicon
โโโ CNAME # Custom domain (optional)
โโโ pages/ # Site content
โ โโโ about.md # Biography, education, appointments
โ โโโ research.md # Publications, grants, patents
โ โโโ software.md # Open-source software projects
โ โโโ teaching.md # Courses, mentoring
โ โโโ talks.md # Workshops, invited talks, presentations
โ โโโ awards.md # Awards & honors
โ โโโ services.md # Professional & institutional services
โ โโโ contact.md # Contact information
โ โโโ news.md # News log by year
โ โโโ blog.md # Blog landing page
โ โโโ images/ # Shared images
โโโ blog/ # Blog posts
โ โโโ sample-post.md # Sample blog post
โโโ .pre-commit-config.yaml # Pre-commit hook configuration
โโโ CONTRIBUTING.md # Contribution guidelines
โโโ CONDUCT.md # Code of conduct
โโโ .github/workflows/
โโโ build.yml # PR preview builds (Netlify)
โโโ deploy.yml # Production deployment (GitHub Pages)
Customization
Site Metadata
Edit myst.yml:
project.title: your nameproject.description: site descriptionproject.keywords: your research keywordssite.parts.footer: footer links (CV PDF, social profiles)
Author Information for CV
Edit the genpreamble() function in generatecv.py:
firstname,lastname: your nameemail,phone,homepage: contact detailsgithub: GitHub usernameaddress: office addresspositions: job titlescustom: social media and academic profile links
Adding Pages
- Create a new
.mdfile inpages/ - Add the file to
project.tocinmyst.yml
Adding Blog Posts
- Create a new
.mdfile inblog/with frontmatter (title, date, authors, description, tags) - Add a card entry in
pages/blog.mdlinking to the new post
Building Locally
Build HTML
pip install -r requirements.txt
npm install -g mystmd
myst build --html
The built site will be in _build/html/.
Build CV PDF
Prerequisites: Python 3.10+, Typst CLI, Font Awesome 6 desktop fonts (OTF) in a fonts/ directory.
# Generate Typst source from website markdown files
python generate_cv.py
Compile to PDF (with custom fonts and icons)
typst compile cv.typ cv.pdf --font-path ./fonts --ignore-system-fonts
The script reads content from pages/about.md, pages/research.md, pages/software.md, pages/teaching.md, pages/talks.md, pages/awards.md, and pages/services.md, then generates a cv.typ file with all CV sections.
Font Setup (for CV)
The CV requires Source Sans Pro (body font) and Font Awesome 6 (icons). Download both into a fonts/ directory:
mkdir -p fonts
Source Sans Pro (body font - ensures consistent spacing)
curl -sL "https://github.com/adobe-fonts/source-sans-pro/releases/download/3.006R/source-sans-pro-3.006R.zip" -o source-sans-pro.zip
unzip -o source-sans-pro.zip -d /tmp/ssp
cp /tmp/ssp/source-sans-pro-3.006R/OTF/*.otf fonts/
Font Awesome 6 (icons)
curl -sL "https://use.fontawesome.com/releases/v6.7.2/fontawesome-free-6.7.2-desktop.zip" -o fa.zip
unzip -o fa.zip -d /tmp/fa
cp /tmp/fa/fontawesome-free-6.7.2-desktop/otfs/*.otf fonts/
The --ignore-system-fonts flag in the compile command ensures Typst uses only these fonts, which gives consistent icon spacing across environments.
Generate RSS/Atom Feeds
pip install feedgen pyyaml
python generate_rss.py
Reads frontmatter from blog/*.md and writes rss.xml and atom.xml.
Building with Docker
Build and serve the site without installing any dependencies locally:
docker build -t myst-cv-template .
docker run --rm -p 3000:3000 -p 3100:3100 myst-cv-template
Then open http://localhost:3000 in your browser. If port 3000 is already in use, map to different ports (e.g., -p 3001:3000 -p 3101:3100 and open http://localhost:3001). The Docker image includes Node.js, Python, Typst, and all required fonts.
Deployment
GitHub Pages (production)
Pushes to main trigger the deploy.yml workflow, which:
- Builds the HTML site with MyST
- Generates
rss.xmlandatom.xmlfrom blog posts - Generates
cv.typfrom markdown content - Compiles
cv.pdfwith Typst - Injects Giscus comments into blog posts
- Deploys everything to GitHub Pages
https://your-site.com/cv.pdf.
Netlify (PR previews)
Pull requests trigger the build.yml workflow for preview deployments. Requires NETLIFYAUTHTOKEN and NETLIFYSITEID secrets.
GitHub Secrets
| Secret | Purpose | |--------|---------| | NETLIFYAUTHTOKEN | Netlify authentication for PR previews | | NETLIFYSITEID | Netlify site ID for PR previews |