Tag: Resume

  • Automating Job Applications with Markdown: From 60 Minutes to 20 Minutes

    Automating Job Applications with Markdown: From 60 Minutes to 20 Minutes

    Who This Is For: This workflow is designed for developers and technical professionals who are comfortable with command-line tools, enjoy working in code editors like VSCode, and who prefer markdown for writing (or are willing to give it a try). If you’re already using git for version control and don’t mind a bit of setup for long-term efficiency gains, this approach could save you significant time during your job search.

    Introduction 💡

    Job applications are tedious. Between customizing resumes, writing cover letters, tweaking formatting, and tracking applications, I was spending hours on administrative work instead of finding and responding to great opportunities–or working on side projects which I find infinitely more interesting.

    A little while ago I wrote a blog post on writing with markdown, which has greatly sped up my writing process. I’ve been using it for several weeks now and have made a bunch of automation improvements which enable me to quickly create a job application, customize a resume, draft a new cover letter, and track each application’s progress.

    I also took this opportunity to give Claude Code a test drive and see how it could help me build out some new automation scripts. In the past I’ve found agents like Cursor to be too aggressive–cranking out code faster than I can wrap my head around it. If I’m trying to learn something I want to go slow, ask questions, and understand what’s being built. Agents can’t reason but they’re good at replicating patterns, so I want to make sure it stays on track. (I’ll write more on Claude Code later–but so far I really like it!)

    The result of this collaboration is my new workflow, which I wanted to share with others: Markdown Writer. It’s still a work in progress, but if you like working in an IDE and are comfortable with a CLI you might find this a good way to manage your job applications.

    Why not use existing job tracking tools? TBH, I didn’t even research what’s available–I just knew I wanted to stay in my IDE where I’m most comfortable and productive. As developers, we often build our own tools not because existing solutions don’t exist, but because we have specific workflows and preferences. I wanted something that felt like coding: version-controlled, scriptable, and integrated with my daily development environment. Plus I wanted a small project to experiment with AI.

    Get Set Up ⚙️

    I use VSCode because it has great integration of file/project navigation, editing, helpful extensions, terminal integration, key bindings, snippets, and custom command integration. However this will also work with your favorite code editor and either zsh or bash in your terminal.

    This project is available as a GitHub template repository, making it easy to create your own private copy with one click. Simply visit the Markdown Writer repository and click “Use this template” to create a new repository in your GitHub account.

    If you prefer to clone and experiment first, you can use the repository directly:

    git clone git@github.com:nickhart/markdown-writer.git

    However, for ongoing use, I recommend creating your own repository from the template so you can customize it and track your applications privately. When there are updates to the main Markdown Writer repository, you can use the included script (scripts/sync.sh) to copy updates from the upstream repository to your own, or manually copy specific files you want to update.

    Requirements 📋

    Installing ⬇️

    git clone git@github.com:nickhart/markdown-writer.git
    cd markdown-writer
    ./setup.sh

    NOTE PDF formatting is supported, but requires installation of a LaTeX package. Out of the box Markdown Writer works great for creating DOCX files.

    Configuring 🔧

    Edit .writing.yml with your information. You can see an example .writing.yml here.

    Edit your resume and cover letter templates:

    • templates/resume/default.md
    • templates/cover_letter/default.md

    If you wish to customize your document formatting you can edit the styles in the files located below. Be sure to modify the standard styles (Heading, Heading 2, Body, etc…), then save the changes to reference.docx. Pandoc will use these reference files and use the styles in them when generating your formatted resume or cover letter.

    • templates/resume/reference.docx
    • templates/cover_letter/reference.docx

    You should now be ready to go. The system supports multiple resume templates. For many people “default” might suffice, but I find myself applying to a few different kinds of roles and have one tailored more towards mobile, frontend or fullstack… so I have resume templates with each of those names.

    Workflow 🔄

    Applying To a New Job 📝

    When I want to apply to a new job from the terminal I run

    job-apply Acme "Engineering Manager" default "http://acme.com/jobs/engineering-manager/1234"

    Or if I want to use a specific resume template other than default:

    job-apply Acme "Engineering Manager" fullstack "http://acme.com/jobs/engineering-manager/1234"

    This creates a new job application in the applications/active/acme_engineering_manager_20250624 directory. It copies my “default” resume template and standard cover letter and performs the variable substitution using my .writing.yml. It downloads the job description at the provided URL and saves it as an html file (job_description.html). It creates a metadata file (application.yml) which contains the company name, role, job description URL, and date created.

    Then I go in and tweak the resume as needed (perhaps just the title, maybe the intro blurb), and then crank out a few brief paragraphs for the cover letter. Usually I want to customize the intro to the cover-letter, but often I’ve already got some good content from prior cover letters which addresses particular needs/requirements in the job description. The organization of the applications makes it super easy for me to find a prior cover letter, lift a few sentences and add them into my new cover letter.

    Then I run job-format acme_engineering_manager_20250624 and it automatically formats my markdown resume and cover letter into DOCX format, using reference template files with my preferred styles and page format. The formatted versions go into a formatted subdirectory of the application. The .gitignore automatically excludes the formatted docs from being committed–but if one wished they could tweak that and commit the formatted files too.

    From here it’s a matter of uploading the DOCX files to the job application and filling out the rest of the application information.

    Some applications require some essay-style questions, in which case I add another markdown file to the application folder (eg: application_questions.md) and use my same editing process. I don’t bother formatting these into DOCX but it’s nice to have a record of my responses and then it’s easy to copy/paste them into the application form.

    Submitting and Tracking the Application 📤

    When I’m satisfied with the application I have a helpful command to commit it to my repo:

    job-commit acme_engineering_manager_20250624

    Once I’ve submitted the application, and as it moves through the review process I have a command to update its status:

    job-status acme_engineering_manager_20250624 submitted
    job-status acme_engineering_manager_20250624 interview
    job-status acme_engineering_manager_20250624 offered
    job-status acme_engineering_manager_20250624 rejected

    Each of these statuses has its own sub-folder inside the applications folder in the project root. The job-status command moves the application from one folder to another and updates the status in the application.yml metadata file.

    If I get to the interview stage (w00t!) I take notes in a markdown file which I keep in the application’s folder, eg:

    applications/
      interview/
        acme_engineering_manager_20250624/
          recruiter_notes.md
          hiring_manager_notes.md
          interview_loop_notes.md

    I also have a job-log command which will show a summary of all my applications, or just ones in a certain status. Right now the summary is terse, but I intend to make it a bit fancier in case someone in the state unemployment office decides to challenge me. It will be trivial to take the metadata and generate a log of each job application in DOCX format to prove I’ve exceeded their “three job activities a week” requirement.

    VSCode Integration 🛠️

    I mentioned in my prior post about how I like to use VSCode for my markdown writing. For those who are also using VSCode it will recommend some extensions that I find handy:

    • Markdown All in One
    • Code Spell Checker
    • markdownlint
    • Word Count
    • YAML

    The VSCode configuration adds some helpful settings for Markdown and YAML editing, as well as allowlisting some common words that the spell checker might flag.

    It also adds some commands to the command palette. With a simple cmd-shift-p to open the command palette, select Run Tasks, and choose one of my commands like Create Job Application. It’ll prompt me for the company name, role, which resume template (or use default), and the URL for the job description. It’ll run the command in a terminal and show me the output!

    Wrapping Up and Next Steps 🚀

    In my last post on this topic it was taking me an hour to do what now takes me 20 minutes–and most of that time is me thinking about what I want to write and entering it into a markdown file. I still only apply to a few jobs a day, but I can focus on applying to the roles that really interest me, take the time to craft a thoughtful cover letter, and then have more time to work on my other projects or write a blog post.

    I will continue to use the Markdown Writer to craft my job applications. I also use it for blog posts and format the results into HTML which I can copy/paste into Wordpress. No doubt I will continue to refine this aspect of my writing workflow.

    And if you’re curious about some of the other features I’m planning for my job application workflow, take a look at the TODO!

  • Markdown Writing Workflow: How I Write 3x Faster

    Markdown Writing Workflow: How I Write 3x Faster

    The Power of Writing Everything in Markdown First

    I’ve been writing tons of resumes, cover letters, and blog posts lately. Word processors felt cumbersome—too much time formatting, too much repetitive work. Then I realized: why not approach writing like an engineering project?” Instead of jumping straight into WordPress, Google Docs, or Apple Pages, I now write everything in VSCode using markdown.

    Blog posts, resumes, cover letters, interview notes, writing assignments… they all go into markdown first. Then I use Pandoc to convert them to whatever format I need.

    The results? I’m faster, more focused, and my content is way more portable.

    Why Markdown Makes Sense 📝

    I find writing in a word processor to be distracting—there are so many formatting choices. I just want to focus on the content and have a standard format for the output. This is why markdown appeals to me. It’s simple and consistent.

    Perhaps it’s the engineer in me, but I feel like I have more power and control over the structure of my writing. It’s easier to “refactor” the structure of my prose and move ideas around for a better flow.

    Markdown gets all the formatting out of the way. You focus purely on content and structure. The syntax is dead simple: bold, italics, # headers, - lists, and links — but nothing more.

    Why VSCode? ⚡

    VSCode helps keep my files organized, easy to find, easy to search, and fast to switch context. It’s a fast, flexible text editor, and extension support for Markdown and other formats is a huge time saver.

    All of my files are organized into folders in a single project. When I’m done writing a resume I can quickly switch to my cover_letters folder, create a new markdown file, copy/paste my boilerplate contact info, salutation, and start writing.

    Also VSCode has a great built-in preview that lets you see how the markdown will render. The stroke of a few keys (Cmd + shift + V on macOS) and you can see the results instantly.

    The Secret Sauce: Pandoc 🔧

    I use Pandoc to do my conversion. It’s a simple command line tool that you can run from the terminal inside VSCode. I used to keep Terminal windows open all over the place to run command line tools, but using the terminal integrated into VSCode helps keep everything organized and in one place.

    Project Structure 📂

    I mentioned using VSCode to keep my files organized. Here’s a rough sketch of my project structure:

    writing/
    ├── blog/
    │   └── formatted/
    ├── assignments/
    │   └── company_x/
    │   └── company_y/
    ├── resumes/
    │   └── formatted/
    ├── cover_letters/
    │   └── formatted/
    └── interviews/
        └── company_x/
        └── company_y/

    I keep the markdown organized into top-level folders (blog posts, assignments, resumes, interviews, etc.) and for interviews and assignments I use sub-folders for each company. Any place I want to generate a formatted version from markdown I use a formatted sub-folder.

    On occasion if I feel the need to do some custom formatting in a wordprocessor I add some notation to the edited filename (eg: resume_company_x_edited.docx) as a reminder not to blow it away by re-generating from the markdown.

    Version Control with Git 📋

    Since I’m treating writing like an engineering project, I use Git to track all my markdown files. This gives me powerful revision history, the ability to see exactly what changed between drafts, and easy restoration if I mess something up.

    VSCode’s Git integration makes this even better—I can see at a glance which files have changes, view diffs right in the editor, and commit directly from the IDE without switching to the terminal.

    I keep a .gitignore file that excludes the generated content:

    # macOS
    .DS_Store
    ._*
    
    1. Ignore generated formatted files
    */formatted/
    *.pdf
    *.docx
    *.html
    
    1. But keep the reference template(s)
    !reference.docx

    This way my repository stays clean with just the source markdown files, but I can still track my reference templates. The formatted outputs are disposable since I can regenerate them anytime with pandoc.

    The Workflow 🚀

    Here’s what my typical workflow looks like now:

    1. Open VSCode and create a new .md file in the appropriate folder
    2. Write the entire piece without worrying about final formatting
    3. Preview the markdown in VSCode and make sure it looks good
    4. Convert to whatever format I need (HTML for WordPress, DOCX for resumes, etc.)
    5. Proofread the formatted version (check fonts, margins, spacing, etc.)
    6. Upload the formatted version to WordPress, a job application, or anywhere you need it

    I have a bunch of aliases for pandoc that make the conversion process a breeze. Add these to your ~/.bashrc or ~/.zshrc file to make them available in your terminal.

    # HTML for blog posts (clean, WordPress-friendly)
    md2html() {
        pandoc --no-highlight --wrap=none -t html -o "./formatted/$(basename "$1" .md).html" "$1"
    }
    
    1. DOCX with reference template
    md2docx() {
        pandoc --reference-doc=reference.docx -o "./formatted/$(basename "$1" .md).docx" "$1"
    }
    
    1. PDF via LaTeX
    md2pdf() {
        pandoc -o "./formatted/$(basename "$1" .md).pdf" "$1"
    }

    Each format serves a specific purpose: HTML works perfectly for pasting into WordPress or web platforms, DOCX is what most job applications expect for resumes and cover letters, and PDF is ideal for sharing finalized documents that need to look identical everywhere. You can use PDF for resumes and cover letters, but I have read that some ATS scanners can choke on it, which is why I stick to DOCX.

    Making a Reference DOCX Template ⚙️

    To create a reference DOCX template, start by generating a basic one from any markdown file: pandoc sample.md -o reference.docx. Then open this file in Microsoft Word (or your favorite word processor which can export to DOCX) and customize all the styles you care about: fonts, margins, headings, paragraph spacing, etc. The key is to modify the actual Word styles (like “Heading 1”, “Normal”, “Strong”) rather than just formatting individual text, since pandoc maps markdown elements to these named styles. Save the file, and now every time you use --reference-doc=reference.docx, your converted documents will inherit this formatting. You only need to set this up once, and it works great for making professional-looking resumes and cover letters that maintain consistent branding across all your materials.

    You can also put this file somewhere central like ~/.pandoc/reference.docx so you can easily access it from anywhere. However, for my workflow I like to keep a separate reference.docx in each project folder so I can easily customize the formatting depending on the type of content.

    The Portability Game-Changer 🎯

    The portability of using markdown and Pandoc is incredible. I usually generate my resumes into DOCX format because I think ATS scanners sometimes choke on PDF, but if you want it in PDF it’s just a one line command.

    The learning curve for Markdown is minimal too (although if you’re an engineer you’re already probably familiar with it). If you can remember that # makes headers and text makes things bold, you’re 90% there. GitHub has a great tutorial on using Markdown. It’s very handy if you need a quick reference or refresher.

    Future Automation Ideas 🔮

    I’m planning to automate this even further. Git hooks could automatically regenerate formatted versions whenever I commit changes. Imagine pushing a blog post update and having the HTML automatically ready for WordPress!

    I’m also thinking about a simple script that can create new WordPress posts directly from my markdown files and leveraging WP-CLI.

    The best workflows are the ones that get out of your way and let you focus on what matters: the actual work.


    Have you tried writing in markdown? I’d love to hear about your workflow experiments.