Kishore Vancheeshwaran
Resume in yaml and jinja templates

In my previous post I created my resume using yaml and orgmode. Even though I was satisfied to an extent with this solution, I still felt there was a limitation in using orgmode as a middleware to export my yaml into pdf and html. I realised that this challenge was partially due to my obsession to using emacs and orgmode. The main thing I was unhappy with was I could not edit the templates being exported easily without modifying emacs’s backend exporter. I needed a way to translate yaml to latex and html directly. Initially I started writing python scripts with a custom formatter but realised I was still trying to solve the wrong problem.

When I googled, I realised there is Jinja. Quoting from the documentation,

Jinja is a fast, expressive, extensible templating engine. Special placeholders in the template allow writing code similar to Python syntax. Then the template is passed data to render the final document.

This was wonderful and suited my needs. Searching further I could see other repositories here and here implementing this workflow. This workflow was much more straightforward.

A simple example is as below which can be expanded/modified for your use case.

resume.yaml

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24  name: Kishore Vancheeshwaran contact: email: personal.email@gmail.com linkedin: linkedin.com/in/kishvanchee phone: +91-0000000000 location: Bangalore, IN experience: - company: Company 2 position: Software Engineer team: Awesome start_date: Jan 2015 location: Bangalore summary: - I did something awesome - I automated some work - company: Company 1 position: Software Engineer team: Awesome start_date: Jan 2005 to_date: Dec 2014 location: Bangalore summary: - I did something awesome - I automated some work 

generate.py

  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 32 33 34 35 36 37 38  import yaml from jinja2 import Environment, FileSystemLoader import argparse parser = argparse.ArgumentParser() parser.add_argument("-t", "--type", required=False, help="type of resume") parser.add_argument("-o", "--outfile", required=True, help="output file name") parser.add_argument("-j", "--template", required=True, help="jinja template") args = parser.parse_args() with open("resume.yaml", "r") as fin: resume = yaml.safe_load(fin) # style.css which we will embed in the html directly # to avoid requiring the stylesheet separately with open("style.css") as fin: style = fin.read() resume["style"] = style # This modification is to make sure the syntax # plays well with latex templates env = Environment( block_start_string="\BLOCK{", block_end_string="}", variable_start_string="\VAR{", variable_end_string="}", comment_start_string="\#{", comment_end_string="}", line_statement_prefix="%%", line_comment_prefix="%#", trim_blocks=True, autoescape=False, loader=FileSystemLoader("./templates"), ) template = env.get_template(args.template) with open(args.outfile, "w") as fout: fout.write(template.render(resume=resume)) 

html.template

  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   \VAR{resume['name']}
\VAR{resume['contact']['phone']} | \VAR{resume['contact']['email']} | \VAR{resume['contact']['linkedin']} \BLOCK{for exp in resume['experience']} \VAR{exp['position']} \VAR{exp['start_date']} \VAR{exp['to_date']} \VAR{exp['company']} \VAR{exp['location']} \BLOCK{for item in exp['summary']}
• \VAR{item}
\BLOCK{endfor} 

latex.template

  1 2 3 4 5 6 7 8 9 10 11 12 13  \documentclass[letterpaper,11pt]{article} \begin{document} \begin{center} \textbf{\Huge \scshape \color{TextColor} \VAR{resume['name']}} \\ \vspace{1pt} \small \VAR{resume['contact']['phone']} $|$ \href{mailto:\VAR{resume['contact']['email']}}{\VAR{resume['contact']['email']}} $|$ \href{https://\VAR{resume['contact']['linkedin']}}{\VAR{resume['contact']['linkedin']}} \end{center} \begin{itemize} \BLOCK{for item in exp['summary']} \item {\VAR{item}} \BLOCK{endfor} \end{itemize} \end{document} 

Makefile

  1 2 3 4 5 6 7 8 9 10  .PHONY: jake anon html image all: pdf html pdf: python generate.py -t pdf -j latex.template -o resume_kishore.tex pdflatex resume_kishore.tex html: python generate.py -t html -j html.template -o resume_kishore.html 

The benefits I can see in this approach is the use of python like syntax directly in the templating. Additionally the tempaltes are separated from the content.

Now I can make sure that I maintain my resume in plaintext and at the same time export it to different formats with a templating engine without worrying about a middle layer with customised exports. My process is finally(?) simplified.