A flowchart. Fountain, working file format. Right directed arrow. A grey box entitled github. Inside the box, after writing, automated file conversion. Right directed arrow. Adobe PDF, output file format.

I’m sold on this workflow, jump to the tutorial!


Why this workflow?

I write comic scripts in Fountain, an open-format filetype for scripts and screenplays, and export them to PDF to send to my collaborators (artists, coauthors, publishers).

Previously, each new draft would result in a sheepish email to everyone involved, asking them to please ignore the previous draft and see bullet points below for the summary of changes. This was untenable.

I wanted a workflow that enables my collaborators to:

  1. inspect the exact, line-by-line edits between any two drafts; and
  2. access the latest version of the script in PDF,

while I write and overwrite the same single file all throughout (i.e., none of this).

In short, I wanted to implement version control.

The workflow I settled on is straightforward: I push my .fountain script files to a GitHub repository, then use ’afterwriting, an open-source Fountain converter, to automatically keep the PDF versions up-to-date.

Requirement (1) is satisfied because Fountain files are plaintext, and thus compatible with GitHub’s compare (diff) feature. Requirement (2) is satisfied because ’afterwriting has a command line interface that can be automated with GitHub Actions.

When all is said and done, the repo looks something like this:

Screenshot of a GitHub repository with two folders and seven files. There are three columns. Column one shows the names of the contents. The two folders are dot github slash workflows, and pdf. The seven files are dot gitignore, readme dot markdown, config dot json, and four dot fountain files labeled K1 through K4. Column two lists the commit messages. Column three shows the commit dates. The header reads, scottleechua and github actions bot, apply automatic changes, twenty hours ago, forty nine commits.

Why use Fountain?

Fountain is a formatting convention for writing scriptlike documents. Here is a comic script written in Fountain:

# Page 1

.Panel 1

It's dark. A coffee cup in the foreground. In midground, ALYSSA on the phone.

ALYSSA
*Uh-huh...*

Fountain is free. Like Markdown, Fountain files are nothing more than plaintext files saved with a .fountain extension. Unlike Final Draft, Word, or Google Doc files, which require costly 1 and proprietary software to view and edit, .fountain files can be read and edited on literally any computer.2

Fountain is futureproof. Proprietary software may force strongly encourage you to upgrade to the latest version or change your file formats, but your computer will always have a text editor. This makes Fountain ideal for storing scripts without worrying about software obsolescence or incompatibilities.

Fountain exports to the usual file formats. While plaintext Fountain already looks rather “script-like,” free converter software can parse the special formatting rules3 into a nicely-rendered PDF:

Screenshot containing the formatted version of the comic script above.

(If you must, Fountain also exports nicely to Final Draft.)

Setup

  1. Make a GitHub account, create a new private repository, and clone it to your local computer. Let’s call this folder my-script-repo.
  2. Open a text editor.4 Create a text file called .gitignore in my-script-repo containing:
     .DS_Store
     desktop.ini
    
  3. Move your Fountain script file into my-script-repo. Let’s call it script.fountain.
  4. Create a text file called config.json in my-script-repo containing:
     {
         "embolden_scene_headers": true,
         "show_page_numbers": true,
         "split_dialogue": true,
         "print_title_page": true,
         "print_profile": "a4",
         "double_space_between_scenes": false,
         "print_sections": true,
         "print_synopsis": true,
         "print_actions": true,
         "print_headers": true,
         "print_dialogues": true,
         "number_sections": false,
         "use_dual_dialogue": true,
         "print_notes": true,
         "print_header": "",
         "print_footer": "",
         "print_watermark": "",
         "scenes_numbers": "none",
         "each_scene_on_new_page": false
     }
    

    This config file customizes the PDF output generated by ’afterwriting. Customize these settings as you like; refer to the documentation for a complete list of available settings.

  5. Create a subfolder my-script-repo/pdf. Inside it, create an empty text file called .gitkeep.
  6. Add, commit, then push this first set of changes to GitHub. (For help, see here.) At this stage, your folder structure should look like:
     .
     └── my-script-repo/
         ├── .gitignore
         ├── script.fountain
         ├── config.json
         ├── pdf/
         │   └── .gitkeep
         └── .git/
             └── << ignore these files >>
    
  7. Go to my-script-repo on GitHub. Click on Actions > New Workflow.
  8. Click on Simple Workflow > Configure.
  9. Rename the file from blank.yml to fountain_to_pdf.yml. Replace the contents of the text box with:

     name: fountain_to_pdf
    
     on:
       push:
         branches:
           - main
       workflow_dispatch:
    
     jobs:
       convert_files:
         name: Convert Fountain to PDF
         runs-on: ubuntu-latest
         permissions:
           contents: write
         steps:
           # Check out your repository
           - uses: actions/[email protected]
              
           # Install 'afterwriting
           - name: Install 'afterwriting
             run: npm install afterwriting -g
    
           # Invoke 'afterwriting to export script.fountain to script.pdf
           - name: Generate PDF
             run: afterwriting --source script.fountain --pdf pdf/script.pdf --overwrite --config config.json
    
           # Commits changes
           - uses: stefanzweifel/[email protected]
    

    If you have multiple .fountain files, the afterwiting --source ... command must be invoked separately per file. For example, if you have three chapters C1.fountain, C2.fountain, and C3.fountain, replace the appropriate lines above with:

     # Invoke 'afterwriting to export script.fountain to script.pdf
           - name: Generate PDF
             run: |
               afterwriting --source C1.fountain --pdf pdf/C1.pdf --overwrite --config config.json
               afterwriting --source C2.fountain --pdf pdf/C2.pdf --overwrite --config config.json
               afterwriting --source C3.fountain --pdf pdf/C3.pdf --overwrite --config config.json
    

    where the vertical delimiter | indicates that GitHub should run multiple commands instead of just one.

  10. To the upper right of the text box, click Start commit > Commit new file.

  11. Pull the changes to your local machine. Your folder structure should now look like:
    .
    └── my-script-repo/
        ├── .gitignore
        ├── script.fountain
        ├── config.json
        ├── pdf/
        │   └── .gitkeep
        ├── .git/
        │   └── << ignore these files >>
        └── .github/
            └── workflows/
                └── fountain_to_pdf.yml    
    

    Setup is complete!

Update your script

At this point, your pdf/ subfolder is still empty, as you haven’t pushed any new commits yet. Let’s do that now.

  1. Make some edits to script.fountain.
  2. Add, commit, and push the edits to GitHub.
  3. Allow the workflow to run. You can track its progress on GitHub, under Actions.
  4. Once the workflow has completed, go back to your local and pull changes from GitHub. A new file script.pdf should now appear under the pdf/ subfolder.

If you don’t want merge conflicts (and you don’t), always pull the newly-updated PDF after every push!


Congratulations!

At this point, the workflow has been set up and you know how to update your scripts. Now your collaborators can see the latest edits for a given file by clicking on its latest commit:5

Screenshot of the same github repository as above, with two folders and seven files. There are three columns. Column one shows the names of the contents. The two folders are dot github slash workflows, and pdf. The seven files are dot gitignore, readme dot markdown, config dot json, and four dot fountain files labeled K1 through K4. Column two lists the commit messages. Column three shows the commit dates. The commit message of file K1 dot fountain is highlighted. It reads, major draft K4, minor drafts K1, K2, K3.

which leads them to a page with line-by-line comparisons:

Screenshot of the diff file for K1 dot fountain. The commit message reads major draft K4, minor updates K1, K2, K3. Below the commit message, it says, showing 4 changed files, with 218 additions and 205 deletions. Below that, it shows the details of the changes in the file.

Your collaborators can also view the latest PDFs by going to the GitHub website or by pulling the latest changes to their local repo.

Contribute

This walkthrough last worked for me in May 2022. If you spot errors, vulnerabilities, or potential improvements, please do open a pull request on this blog post!

Acknowledgements

This tutorial owes a deep debt of gratitude to Piotr Jamróz and the rest of the ’afterwriting team. (So do I!)


Footnotes

  1. While Google Docs is technically free, a stable internet connection is not. ↩

  2. Free Fountain-specific scriptwriting apps with syntax highlighting and other quality-of-life features are also available, such as Beat (Mac) or Trelby (Windows, Linux). ↩

  3. For instance, section headings begin with #; scene headings begin with .; character names are in all caps. Read the full syntax guide here. ↩

  4. Every operating system has one by default, e.g., Notepad on Windows, TextEdit on Mac. ↩

  5. Read the GitHub documentation for more ways to compare commits. ↩