Kishore Vancheeshwaran
Resume in yaml and orgmode
100DaystoOffload resume orgmode plaintext

In my previous post we created the resume using orgmode. Although it was very versatile and friendly with version control, I noticed that I had trouble with blocks of text having tables like below where I had to mix in the latex and html settings along with the content which wasn’t very pretty with git diff.

* FirstName LastName
#+attr_html: :class mytable meta :rules all :border nil :cellspacing nil :cellpadding nil :frame nil
#+attr_latex: :align c|c|c|c
| [[][]] | [[][]] | +91-9876543210 | City, Country |
** Experience
*** Company 1
#+attr_html: :class mytable exp :rules nil :border nil :cellspacing nil :cellpadding nil :frame nil
#+attr_latex: :align L{0.27\textwidth}C{0.40\textwidth}R{0.25\textwidth}
| *Software Engineer* | *Company Inc.* | *Feb 2015 -- Present* |
| Software Team       | City           |                       |

In addition to that, to get anonymized resume reviews, I had to manually copy paste parts of the content into another org file and anonymize the relevant info before publishing it. I don’t find this to be that efficient use of my time. I ended up doing what the programmer stereotype does - automate this task of generating my resume which plays well with version control.

Yaml seemed to be the popular format which is (al)most human readable and easy to parse.

The gist of this automation is as follows.

  • Write resume in yaml
  • Parse yaml with python. Python code will have string snippets for org mode. Write this to an org file
  • Run emacs from the command line with a custom init set up and export to both html and pdf
  • Have a Makefile to automate all of this.

Seems straightforward enough.

Yaml structure


name: Kishore Vancheeshwaran
  phone: +91-0000000000
  location: Bangalore, IN
  - company: Company 2
    position: Software Engineer
    team: Awesome
    start_date: Jan 2015
    location: Bangalore
      - 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
      - I did something awesome
      - I automated some work
  languages: Python
  frameworks: Django
  databases: PostgreSQL
  dev_tools: Git
  - degree: Fancy degree
    university: University of freedom
    from: Jul 2000
    to: Jun 2004

The yaml file is pretty self explanatory. You can have multiple experience/companies, multiple education entries, etc.

Here’s a a not so pretty but works python script which takes care of parsing the yaml and writing it to org file.

Now we have the Makefile which automates the entire process. The recent option is so that you can have your most recent work experience listed in your yaml but not the actual pdf/html. It will be prepopulated with I currently work here as the entry. This way you don’t have to worry about having two separate entries with one having a noexport in the org file or even having two separate org files for the same. I wanted this feature to avoid disclosing what I am currently working on in the current company unless it was necessary.

.PHONY: clean pdf anon recent html

all: clean pdf anon html

	emacs --batch -f org-latex-export-to-pdf

	emacs --batch -l custominit.el -f org-html-export-to-html

	python -t anon
	emacs --batch -f org-latex-export-to-pdf

	python -t recent
	emacs --batch -f org-latex-export-to-pdf
	emacs --batch -l custominit.el -f org-html-export-to-html

	find . -maxdepth 1 ! -iname '' ! -iname 'resume.yaml' ! -iname 'Makefile' ! -iname 'latexTemplate.tex' ! -iname 'style.css' ! -iname 'custominit.el' -and -type f -exec rm "{}" \;

The custominit file is below. The file is necessary because -batch mode runs emacs with -q option which means without the default init file. Since we require only parts of the init file, we can have a custom file with the bare necessity to run the command.

;; This function is to run the eval without confirmation, at the top of the org
;; file to generate a link for the pdf file from the html file.
(defun org-confirm-babel-evaluate (lang body)
  (not (or (string= lang "python") )))
(setq org-confirm-babel-evaluate 'org-confirm-babel-evaluate)

(org-babel-do-load-languages 'org-babel-load-languages '((python . t)))

(defun my-org-inline-css-hook (exporter)
  "Insert custom inline css"
  (when (eq exporter 'html)
    (let* ((dir (ignore-errors (file-name-directory (buffer-file-name))))
           (path (concat dir "style.css"))
           (homestyle (or (null dir) (null (file-exists-p path))))
           (final (if homestyle "~/.emacs.d/org-style.css" path)))
      (setq org-html-head-include-default-style nil)
      (setq org-html-head (concat
                           "<style type=\"text/css\">\n"
                             (insert-file-contents final)

(add-hook 'org-export-before-processing-hook 'my-org-inline-css-hook)

The style.css and latexTemplate.tex remain the same as in the previous post.

Phew, now we can run make and it automates the entire build. And we have perfect diffs.

If you would like to leave a comment, contact me via email.
Post 7/99 - part of 100DaystoOffload