Dynamic resume generation using YAML, HAML, and Ruby
The problem
Resumes are hard. Format, content, and structure can differ significantly depending on personal style, industry expectations, or local culture. And worst of all, everyone has a subjective view on what makes a good resume, with little agreement.
If you’re anything like me, you have countless resume versions on the filesystems of multiple devices, in the cloud, and in email. These are in a variety of formats, mostly Microsoft Word and PDF. Some of these resumes have had minor deviations in formatting, structure, and data. Depending on the roles I was targeting, I would change the resume significantly to highlight different roles and different skills.
After my most recent job search was over, I didn’t want to continue with the status quo. The process was too inefficient. The duplication of data and effort was staggering. There had to be a better way.
My requirements
The solution should satisfy the following:
- Allow separation between data, formatting, and structure
- Data to be stored in as close to plaintext as possible
- Use boring technology that is established and will be used well into the future
- Be easy to maintain
- Allow for an easy development workflow
- Not require a lot of dependencies
- Allow for easy templating or themes
- Allow significant control over document formatting and display
The solution
If you want to read about the journey I took to this solution, please see the section Looking for a solution.
The solution is very simple. It’s not innovative. It allows me to think of the basics, and not learn yet another framework or language.
All it does is read YAML files, use that data in a HAML template, and output a HTML document, using a stylesheet to style it. It allows me to configure which YAML files to use, what template to use, and what stylesheet to use. Simple. I can generate different resumes very easily just by providing a different config.yml file with different options.
Let’s see how it stacks up against my requirements.
-
Allow separation between data, formatting, and structure
Yes. My data resides in a separate, private repository. The data is completely separate from the document structure and style. I can structure my data however I want, and not worry about how it will be displayed. I can store loads of data/metadata about my job history, experience and skills, and only display what I decide.
-
Data to be stored in as close to plaintext as possible
Yes. Data is stored in YAML documents, which is a very low-syntax structured language. It’s easy to write and easy to read.
-
Use boring technology that is established and will be used well into the future
Yes. Ruby was released in 1996, and HAML in 2006. Both are well established, mature and widely used.
-
Be easy to maintain
Yes. My code doesn’t do much, and isn’t that complex. My code does the simple things like read configuration and YAML, while HAML does the heavy lifting.
-
Allow for an easy development workflow
Yes. I use
vimandgitfor development. I use a browser to check how the resulting file looks. The tools are not unusual or special. -
Not require a lot of dependencies
Yes. It requires the
hamlgem, and that’s about it. It uses paper-css stylesheet linked in the default HAML template to display the resume as an A4 paper on the screen. -
Allow for easy templating or themes
Yes. Just add another HAML file in the
templatesdirectory, reference it in theconfig.ymlfile, and that’s it! I can add a new stylesheet in thestylesheetsdirectory too, and reference it i theconfig.ymlfile. -
Allow significant control over document formatting and display
Yes. Basically whatever HTML, CSS, and Javascript allow for.
Looking for a solution
First iteration
My first working solution was using LaTeX to generate a PDF of my resume. Let’s see how it stacked up against my requirements. These are my opinions and experiences.
-
Allow separation between data, formatting, and structure
Yes. It allowed me to use a separate project to host my data. To reduce the amount of packages used, I decided to store the data in
.texfiles. I was (and still am) a LaTeX noob, so this was probably not the best way to store the data. -
Data to be stored in as close to plaintext as possible
Yes. However, I used
.texfiles with variables for fields, so the data format was not interchangeable. -
Use boring technology that is established and will be used well into the future
Yes. LaTeX is the textbook definition of boring. It’s been used for decades. It will be used decades after I’m dead.
-
Be easy to maintain
No. To someone who is an expert in *TeX, maintaining your classs and style files, formatting documents, and debugging compilation errors, would be a piece of cake. However, I was never able to properly understand what the compilation errors and warnings were telling me. Simple formatting and document structure would take me a very long time to accomplish. Minor changes caused compilation to fail.
-
Allow for an easy development workflow
Not really. To do any type of development, you need a TeX distribution. This can be gigabytes in size. For convenience, I was using vscode with the LaTeX Workshop extension to dynamically compile and preview the document side-by-side to the LaTeX. This was a pretty good setup, and I enjoyed the experience (unless I was fighting with compilation errors).
However, this became much worse when I started using CI/CD jobs to generate the PDF files. Downloading the TeX distribution was a massive overhead. I noticed there were differences between my locally-compiled PDF and the PDF compiled in my pipeline jobs, despite using the same TeX distribution and version.
-
Not require a lot of dependencies
No. To do anything useful in LaTeX, you need to use a lot of packages, or write a lot of code yourself.
-
Allow for easy templating or themes
Yes. I was able to implement this functionality. I was even able to dynamically make changes to existing templates via configuration options. This gave a lot of flexibility.
-
Allow significant control over document formatting and display
Yes. However, this has a huge cost. The learning curve was significant, and required compromising some of my other requirements.
Other options
Why didn’t I just use a static site generator, or find another existing tool that did what I was looking for?
I was fatigued looking at existing alternatives. Other options involved learning curves, frameworks, different languages. They might have done sort of what I wanted, but had a lot of features I didn’t need, which also added complexity. I just wanted to focus on my YAML data, the HAML template, and my stylesheets.