Featured image of post Creating a Maintainable Resume with Markdown and Pandoc

Creating a Maintainable Resume with Markdown and Pandoc

Learn how to create and maintain your resume in multiple formats using Markdown and Pandoc

Introduction Link to this section

Keeping a professional resume updated and adaptable for various applications can be a challenging. This post demonstrates how leveraging Markdown for content and Pandoc for conversion simplifies the process, enabling you to maintain a single, clean source file that effortlessly transforms into polished PDF, DOCX, or HTML outputs.

Why Markdown and Pandoc? Link to this section

When it comes to resume management, using Markdown and Pandoc offers several advantages:

  • Version Control: Your resume becomes easily trackable in Git and you can use tags or branches to preserve the versions that were sent to a job posting;
  • Simple Syntax: Markdown is simple, human-readable syntax makes editing and maintaining your resume straightforward;
  • Multiple Formats: Update your resume in one central Markdown file and generate multiple formats (PDF, DOCX, HTML, etc.). The source can even be rendered directly in platforms like GitHub;
  • Separation of Concerns: Keep your resume content clean in Markdown while managing formatting externally through templates. This ensures consistent styling across all generated formats, unlike manually formatted documents where styles can drift over time;
  • Multi-language Support: Facilitate multi-language resumes by managing different language versions of your content more easily;
  • Automation with Filters: Extend functionality with Pandoc filters (written in Lua or Python) to automate tasks like citations, custom formatting, or conditional content inclusion.

Setting Up the Environment Link to this section

To get started, you’ll need Pandoc and a PDF rendering engine like LaTeX, wkhtmltopdf, or WeasyPrint. Note that each engine has specific dependencies; for instance, using LaTeX necessitates installing numerous packages (e.g., amsfonts, amsmath, graphicx, hyperref, babel, etc.).

To avoid cluttering your system with numerous dependencies, consider running Pandoc within a Docker container. This approach isolates the environment while still allowing easy access to local templates, fonts, and assets via Docker volumes.

That said, in this post, I won’t cover installing Pandoc and will focus on using it in a container.

Pandoc has several container image variations (here is the official list), but I use pandoc/extra, that comes with LaTeX and dependencies installed.

Pull the image:

docker pull pandoc/extra

And every time you run Pandoc, use a docker run --rm to start a container and remove it afterwards:

docker run --rm -v "$(pwd):/data" -u $(id -u):$(id -g) pandoc/extra {pandoc-params}

Example:

docker run --rm -v "$(pwd):/data" -u $(id -u):$(id -g) pandoc/extra Resume.md -o Resume.pdf

â„č For simplicity’s sake, for the rest of the post I’ll use just the pandoc {params} command.

Creating Your Resume in Markdown Link to this section

Begin by creating a resume.md file. Here’s a fundamental structure to get you started:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# John Doe
## Software Engineer

> [john@doe.com](mailto:john@doe.com) | 
> [LinkedIn](https://linkedin.com/in/johndoe) |
> [GitHub](https://github.com/johndoe)

## Summary

Experienced software engineer with 8+ years of experience in full-stack development...

## Experience

### Senior Software Engineer | Tech Corp
*2020 - Present*

- Led development of microservices architecture serving 1M+ users
- Mentored junior developers and conducted code reviews
- Implemented CI/CD pipelines reducing deployment time by 40%

### Software Engineer | Start Up Inc
*2017 - 2020*

- Developed and maintained customer-facing web applications
- Improved application performance by 60%

## Skills

- **Languages**: Python, JavaScript, C#, SQL
- **Frameworks**: Django, React, .NET Core
- **Tools**: Docker, Kubernetes, AWS

Generating Your Resume Link to this section

Use the following Pandoc commands to convert your Markdown resume into various formats:

To PDF Link to this section

pandoc resume.md -o resume.pdf

To DOCX Link to this section

pandoc resume.md -o resume.docx

To HTML Link to this section

pandoc resume.md -o resume.html -s

Templates Link to this section

Pandoc templates offer diverse styles and functionalities. Select one that matches your desired aesthetic and customization needs. Popular choices include Eisvogel for LaTeX/PDF and various options for HTML/CSS.

If you intend to generate in more than one format, you need to chose a template that support all of them or use one template for each format.

Using a built-in or installed template (e.g., Eisvogel for PDF) Link to this section

To use a built-in template pass its name in the template parameter:

pandoc resume.md -o resume.pdf --template eisvogel

Using a custom template file within a container Link to this section

To use a custom template within a container, create a volume mapping a folder with the container and pass the relative path in the template parameter:

docker run --rm \
  --volume "$(pwd):/data" \
  --volume "$(pwd)/custom-templates:/templates" \
  --user "$(id -u):$(id -g)" \
  pandoc/extra \
  resume.md \
  -o resume.pdf \
  --template /templates/my-custom-template.latex

Frontmatter parameters Link to this section

Pandoc utilizes variables defined in a YAML metadata block (frontmatter) at the beginning of your Markdown file. Templates often define custom variables for controlling layout, styling, or adding header/footer information – consult the specific template’s documentation for details.

Here is an example of variables used by Pandoc:

1
2
3
4
5
6
7
8
9
---
title: "The Document Title"
author: [Example Author, Another Author]
date: "2017-02-20"
keywords: [Markdown, Example]
---
...

Here is the actual document text...

Custom Styling (with LaTeX) Link to this section

For fine-grained control PDF output via LaTeX, you can include custom LaTeX code snippets. Create a file (e.g., styling.tex) with your customizations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
% Adjust line spacing
\usepackage{setspace}
\setstretch{1.1}

% Customize hyperlink color
\usepackage{xcolor}
\usepackage{hyperref}
\hypersetup{
    colorlinks=true,
    linkcolor=blue,
    urlcolor=blue
}

Then, include this file during conversion using the --include-in-header flag:

pandoc resume.md -o resume.pdf --template eisvogel --include-in-header=styling.tex

Similarly, for HTML output, you can provide a custom CSS file using the --css flag.

Tips and Best Practices Link to this section

  1. Keep it Simple: Markdown is meant to be readable. Focus on content structure;
  2. Version Control: Use Git to track changes, experiment with branches, and tag versions sent to employers;
  3. Separate Content and Style: Manage styling externally using LaTeX includes/templates for PDF or CSS for HTML to keep your Markdown focused on content;
  4. Verify Output: Always check how your resume looks in each format (PDF, DOCX, HTML) to ensure correctness and the desired appearance;
  5. Use Templates and Variables: Leverage different templates and use metadata variables and Pandoc filters to easily generate tailored resume versions for specific job applications without duplicating the core content.

Exploring More Templates Link to this section

Beyond the popular Eisvogel template, many other options exist on GitHub, offering different styles and features. Some uses YAML instead of Markdown for content.

Here are a few examples:

When choosing a template, consider its output formats, customization options, dependencies, and documentation.

References Link to this section

💬 Like or have something to add? Leave a comment below.
Ko-fi
GitHub Sponsor
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy