Automating LaTeX to PDF Conversion with GitHub Actions

Feb 21
·
views
·
likes

Changelog:


Ive tweaked the workflow to include a timestamp in the PDF file, Also changed the action trigger to pushes made only to the resume latex file.

Hello there! Today, I'm excited to share a neat little trick I've been using to automate the conversion of my LaTeX manuscripts into PDF and PNG formats using GitHub Actions. This has been a game-changer for me, especially when working on my resume and academic papers. Let's dive in!

The Problem

Ever since a friend introduced me to LaTeX for creating resumes, I've become an avid user. Frequently, I find myself needing to convert these documents into PDF and PNG formats. This need became particularly evident when I began updating my resume.

Initially, I used Overleaf for this task, which was straightforward. However, as I transitioned to using Visual Studio Code and compiling locally, the process became more complex. I remembered that Overleaf offered an automatic push feature for manuscripts to a GitHub repository. Unfortunately, this was a paid feature and I no longer used the platform.

Recognizing the value of this feature, I was determined to find a way to replicate it. In the interim, I resorted to manually updating my GitHub repository with the latest versions of my manuscripts in both PDF and PNG formats. This manual process was not only time-consuming but also prone to errors. I yearned for a solution that could automate this process, ensuring that my GitHub repository was always up-to-date with the latest versions of my manuscripts.

GitHub Actions to the Rescue

GitHub Actions is a powerful tool that allows you to automate, customize, and execute your software development workflows right in your repository. I realized that I could leverage GitHub Actions to automate the conversion of my LaTeX manuscripts into PDF and PNG formats and push the updated files to my GitHub repository on every push event. This would ensure that my repository was always up-to-date with the latest versions of my manuscripts, without any manual intervention from me.

Using GitHub Actions

GitHub Actions allows you to create custom workflows that can be triggered by various events, such as push, pull request, issue, and more. Each workflow is defined in a YAML file within the .github/workflows directory of your repository. The workflow file contains a series of jobs, each of which can contain multiple steps. Each step can run commands, execute a script, or use an action, which is a reusable unit of code that can be used in a workflow. In my case, I created a workflow that runs on every push event and consists of several steps to build my LaTeX documents, convert them to PDF and PNG formats, and push the updated files to my repository.

The Workflow

Here's the GitHub Actions workflow I've created, which I've named LaTex2PDF:

name: LaTex2PDF
on:
  push:
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      MANUSCRIPT_PATH: latexResume/main
      LATEX: pdflatex
    steps:
      - uses: actions/checkout@v4.1.1

This workflow is triggered every time I push to my repository. It runs on the latest version of Ubuntu and uses the pdflatex engine to build my LaTeX documents.

Building the Manuscript

The first few steps of the workflow involve checking out the latest code from my repository and installing the necessary TeX Live packages to build LaTeX documents:

- uses: actions/checkout@v4.1.1
- name: Install texlive
  run: |
    sudo apt-get install texlive-publishers \
    texlive-latex-recommended \
    texlive-latex-extra \
    texlive-fonts-recommended \
    texlive-fonts-extra
- name: Build resume
  run: |
    cd ${MANUSCRIPT_PATH%/*}
    ${LATEX} ${MANUSCRIPT_PATH##*/}.tex

Once the environment is set up, the workflow navigates to the directory containing my LaTeX file and builds the PDF.

Pushing the PDF

After the PDF is built, the workflow adds it to my repository and pushes the changes back to GitHub:

- name: Push resume
  run: |
    cd ${MANUSCRIPT_PATH%/*}
    git add -f ${MANUSCRIPT_PATH##*/}.pdf
    git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update pdf"
    git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}

This ensures that the latest version of my resume is always available in PDF format in my repository.

Converting PDF to PNG

The next few steps involve installing Ghostscript, modifying the security policy of ImageMagick, and converting the PDF into a PNG image:

- name: Install ghostscript
  run: sudo apt-get update --fix-missing && sudo apt install ghostscript
...
- name: Convert PDF to PNG
  run: |
    cd ${MANUSCRIPT_PATH%/*}
    convert -density 900 -background white -alpha off ${MANUSCRIPT_PATH##*/}.pdf -resize 25% -quality 90 -colorspace RGB ${MANUSCRIPT_PATH##*/}.png

And voila! The latest versions of my resume in both PDF and PNG formats are always available in my repository, without any manual intervention from me. Plus, I can link the PNG in the GitHub readme like so ![](latexResume/main.png) and have the PNG displayed on GitHub.

Full .yml code

Select a file
replace previous PDF and PNG
name: LaTex2PDF
# description: build LaTex manuscripts and push the latest PDF and PNG back to GitHub
 
on:
  push:
    paths: 
      - 'latexResume/resume.tex'
 
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      MANUSCRIPT_PATH: latexResume/main
      LATEX: pdflatex
    steps: 
    - uses: actions/checkout@v1 
    
    - name: Install texlive
      run: |
            sudo apt-get install texlive-publishers \
                                 texlive-latex-recommended \
                                 texlive-latex-extra \
                                 texlive-fonts-recommended \
                                 texlive-fonts-extra 
    - name: Build resume
      run: |
            cd ${MANUSCRIPT_PATH%/*}
            ${LATEX} ${MANUSCRIPT*PATH##*/}.tex
 
    - name: Push resume
      run: |
            git checkout --orphan ${GITHUB_REF##*/}
            cd ${MANUSCRIPT_PATH%/*}
            git add -f ${MANUSCRIPT_PATH##*/}.pdf
            git -c user.name='resume-maker' -c user.email='resume-maker' commit -m "update pdf"
            git push -q -f https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
    
    - name: Install ghostscript
      run: sudo apt-get update --fix-missing && sudo apt install ghostscript
    
    - name: Change ImageMagick security policy
      run: |
              DQT='"'
              SRC="rights=${DQT}none${DQT} pattern=${DQT}PDF${DQT}"
              RPL="rights=${DQT}read\|write${DQT} pattern=${DQT}PDF${DQT}"
 
              HGT="name=${DQT}height${DQT} value=${DQT}10KP${DQT}"
              HGTR="name=${DQT}height${DQT} value=${DQT}128Kp${DQT}"
 
              WDT="name=${DQT}width${DQT} value=${DQT}10KP${DQT}"
              WDTR="name=${DQT}width${DQT} value=${DQT}128Kp${DQT}"
 
              MAP="name=${DQT}map${DQT} value=${DQT}512MiB${DQT}"
              MAPR="name=${DQT}map${DQT} value=${DQT}4GiB${DQT}"
 
              MEM="name=${DQT}memory${DQT} value=${DQT}256MiB${DQT}"
              MEMR="name=${DQT}memory${DQT} value=${DQT}2GiB${DQT}"
 
              sudo sed -i "s/$SRC/$RPL/" /etc/ImageMagick-6/policy.xml
              sudo sed -i "s/$HGT/$HGTR/" /etc/ImageMagick-6/policy.xml
              sudo sed -i "s/$WDT/$WDTR/" /etc/ImageMagick-6/policy.xml
              sudo sed -i "s/$MAP/$MAPR/" /etc/ImageMagick-6/policy.xml
              sudo sed -i "s/$MEM/$MEMR/" /etc/ImageMagick-6/policy.xml
 
    - name: Convert PDF to PNG
      run: |
              cd ${MANUSCRIPT_PATH%/*}
              convert -density 900 -background white -alpha off ${MANUSCRIPT_PATH##*/}.pdf -resize 25% -quality 90 -colorspace RGB ${MANUSCRIPT_PATH##*/}.png
    - name: Commit PNG
      id: commit
      run: |
              cd ${MANUSCRIPT_PATH%/*}
              git config --local user.email "action[bot]@github.com"
              git config --local user.name "github-actions[bot]"
              git add ${MANUSCRIPT_PATH##*/}.png
              git commit -m "[bot] updated ${MANUSCRIPT_PATH##*/}.png"
    - name: Push changes
      uses: ad-m/github-push-action@master
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
 

Wrapping Up

Lastly, the finishing touch, in order to add a download link to my resume on this very site, I utilized the GitHub raw link. By using the raw link of the PDF file in my GitHub repository, I was able to generate a download link for the resume on my website. Allowing visitors to easily access and download the latest version of my resume.

I hope you found this post helpful! Automating this process has saved me a lot of time and effort, and I hope it can do the same for you. Happy coding!

Series
Tiny Tools

  • Automating LaTeX to PDF Conversion with GitHub Actions
  • Test Blog