cvMangle isn’t as technically impressive as some of my other projects, like handWavey. But it has made such a huge difference that I’m just as excited about it.
This is actually my second time writing this post. In the first version, I wove a long, beautiful tale about how my CV got to 11 densely packed pages, and why I stuck with it for so long. But the TL;DR was that it had actually become a liability, and was pretty hypocritical given my stance on verbosity in documentation. Yet every time I tried to re-write it, I came back to basically the same thing.
I needed to cut ties with everything that already existed, and the ability to quickly experiment with different variants without destroying any data. This way I could quickly see if any given idea would work without the mental inertia that comes with 11 densely packed pages.
Table of contents
- The requirements
- A couple of other possible solutions
- The solution
- Other stuff that cvMangle makes easy
- The result
- Useful links
- More details for those who are curious
I need to be able to
- have multiple variants at once.
- Editing original data in one place, should affect all places.
- The solution should cope with exceptions without becoming cumbersome.
- It should keep a history of changes that I can browse back through easily.
- Drastically different layouts shouldn’t compromise existing layouts. Yet data duplication should be minimised.
- use the same data in very different ways.
- still read old versions of the CV in 20 years from now.
- back it up confidently.
- easily move to a completely different solution if the current one is no longer the best one.
- not have to keep paying a service that I’m not using most of the time.
- make changes confidently, and trust that those changes will be applied sensibly. (Eg one job entry should not be split over two pages.)
- have the filenames and footers generated for me in a sensible way, and match each other.
- Specifically I want to instantly know which version the person at the other end of a zoom call is looking at. (This becomes relevant when the CV has been revised to address something that they wanted to see and they therefore have multiple CVs.)
- I have been doing this manually, and it’s very prone to human error.
- be independent of 3rd party services.
- It’s becoming more and more common that companies try new products quickly, and then exit the market when there’s no competition left. Additionally companies simply go out of business from time to time.
- 3rd parties have a habit of changing things from one day to the next, so you can’t rely on something working at the moment when you actually need it.
On top of explicitly mentioning 3rd party services in the last bullet point, they fail pretty much all of the bullet points. So let’s move on…
A couple of other possible solutions
There are at least a couple of command line CV tools that ticked some of my requirements. They weren’t quite what I was after, but are really cool, and might be for you. The ones I’ve found are:
Note that they are actually different projects.
Markdown + git + a little special sauce:
It takes standard Markdown, and adds a couple of commands to help with organisation and data re-use, track changes in git, and then use cvMangle to build the different variants concurrently.
The output files are versioned:
$ ls -1 *pdf 2023-11-11.2-cv-kevinSandom-2page.pdf 2023-11-11.2-cv-kevinSandom-3page.pdf 2023-11-11.2-cv-kevinSandom-fullDynamic.pdf 2023-11-11.2-cv-kevinSandom-shortDynamic.pdf
And old versions are moved to the
$ ls -1 old/ | wc -l 544
… I’ve done a bit of experimentation to see what I like ;)
Other stuff that cvMangle makes easy
Sometimes you want to do a one-off customisation for one specific job that you want to apply for. You can do that with custom CVs. A custom CV is exactly the same as a variant, except that it only gets built when you specifically ask for it.
Meanwhile a variant will get built every time you do a normal build.
Stuff that’s hard in markdown
There are some things that, to the best of my knowledge, are not easy to achieve in markdown to PDF conversion:
I’ve automated both into easily include-able files. Specific-width columns via hk-pandoc-filters, and blocks via a hack using columns.
I keep thinking of things that I want to try. I still have a long way to go to achieve what I’m after. But have made a lot of process so far. Here’s a quick visualisation to give you an idea:
Here I’ve gone from a wad of text where you have to dig to find anything, to a few bullet points that say way more than the original text, in a whole lot less space.
There are several things to observe in this screenshot:
More details for those who are curious
How to use it
There is documentation specifically for using cvMangle. But the gist of it is that you create variants of your CV, which you then build using the
cv command, which creates PDF files for you.
includeis the building block for abstracting out things like an introduction, your education, or key skills.
- Includes can be nested. There will be a technical limit to how many levels deep you can nest things. But for legitimate uses, I can’t imagine that we’ll ever get anywhere near that limit.
forEachis for iterating over a directory of things.
- I use this for iterating over jobs.
- I split recent, and older jobs into two separate directories so that I can create short CVs that only include the recent jobs, and long CVs that include all of my experience.
- When a job needs to move from recent jobs to old jobs, simply move it and re-generate the CVs.
- I use this for iterating over jobs.
2023-11-17: I generated this CV on the 17th of November, 2023.
.0: This is the first version I generated that day.
cv: This is a CV, as opposed to a something like a cover letter, which I name in the same format.
kevinSandom: That’s me! If a recruiter has a folder full of CVs, this will hopefully help them identify mine/yours more quickly.
3page: This is the variant named “
3page”. My other current variants (listed above) are
Why these tools
- Markdown being an easily readable text format:
- works incredibly well with git. So history is very efficient, and easy to manage.
- is light weight.
- is easy to read and get the data out of if any tooling breaks in the future.
- Git is well supported, and well known. It:
- is likely to be around for a long time.
- has lots of tooling available.
- can be run locally and/or on a third party service.
- We get the advantage of being immune to 3rd party changes.
- And the security of having it locally.
- Pandoc is heavily used and available at the moment.
- If this changes, the compiled markdown is still usable for other converters.
- Bash is excellent at this type of task. But there is not much code there, so it’s easy to migrate to something else later on if that is deemed to be the better option.
cvMangle does not create, or manage, a git repo for you. But it does have some tooling to help you track automated state changes such as turning every occurrence of a keyword into a link.
Basically, it’s up to you if you want to use it. For me, there is some piece of mind in being able to roll back changes if I do something stupid. If you don’t like git, but like the idea, you could use a completely different code versioning tool.
There are linux-specific assumptions in place at the moment. It is highly likely to work on MacOS, and WSL, but will not work on Windows natively.
If you’re interested in Windows support. Check the Work on Windows? issue to register your interest and see where things are at.
I think that I’ve got everything up-to-date. But if there’s something that isn’t clear, and you haven’t been able to figure it out and create a pull-reqeust, please create an issue so that we can figure it out together.