1
0
Fork
You've already forked beats
0
Simple CLI program to print a custom beat sheet based on the provided length for a work of art
  • C 78.8%
  • Shell 10.8%
  • Forth 10.4%
2026年05月25日 16:05:08 -07:00
.gitignore Add bin folder to gitignore 2025年11月03日 09:55:36 -07:00
beats.c Add and document program code 2025年10月26日 01:36:50 -07:00
beats.fth Add and document program code 2025年10月26日 01:36:50 -07:00
beats.scr Add and document program code 2025年10月26日 01:36:50 -07:00
beats.sh Add executable script version 2026年05月25日 16:02:23 -07:00
LICENSE Initial commit 2025年10月26日 08:12:36 +01:00
README.md Add instructions for script version 2026年05月25日 16:05:08 -07:00

beats

beats is a simple CLI program to print a custom beat sheet based on a user-provided integer representing the length of an artwork

Preamble

My understanding of the "beat sheet" comes from the classic screenwriting text Save the Cat! by Blake Snyder. While reading the book, I started considering how the 15 standard beats manifested in various artworks beyond film, and realized that the beats could be a meaningful tool to make sense of narrative patterns embedded in other contexts as well.

This is a program I use to quickly check and test my hunches about these patterns. The user argument is a simple integer that can represent any unit of length: pages, minutes, days, years, etc. The output is a formatted text table scaling the beats across the range from 1 to the provided integer argument (inclusive). Each line of the table contains the name of the beat, its start range, and its end range.

Example

> beats
Usage: beats <integer>
> beats 110
 Start End
 Opening Image 1 1
 Set-up 1 10
 Theme Stated 5 5
 Catalyst 12 12
 Debate 12 25
 Break into 2 25 25
 B Story 30 30
 Fun and Games 30 55
 Midpoint 55 55
 Bad Guys Close In 55 75
 All is Lost 75 75
 Dark Night of the Soul 75 85
 Break into 3 85 85
 Finale 85 110
 Final Image 110 110

The instructions below use 110 as an example argument but it can be basically any integer you choose.

Usage

The program is brief and written in Forth. Aside from installing through a package manager (see below), there are 5 avenues provided for interacting with beats: executing a released binary, executing as a shell script, building from generated C, using a Forth interpreter, or using the 4th compiler. The first is available for x86_64 Linux, while the remaining 3 are accessible on most platforms.

Installing via a package manager

beats is packaged with the kiss package manager for the following distributions:

Refer to the documentation provided in or linked by the above repositories.

Executing a released binary

Currently there are executables released for 2 platforms:

  • x86_64 Linux (glib)
  • x86_64 Linux (musl)

Download the one matching your system (typically the glib version), extract it, then execute with ./beats 110

Executing as a shell script

Ensure gforth is installed on your system then execute with ./beats.sh

Building from generated C

To build an executable yourself from the included C code:

  • Install the 4th library from its source (make libinstall from within the "sources" subdirectory)
  • Copy 4th.h provided with the 4th source into the directory where you've cloned this repo.
  • Make sure you have a C compiler installed on your system.
  • Run one of the following (or something similar for another C compiler of your choice).
    • gcc -s -Wall -fsigned-char beats.c -o beats -l4th
    • cc beats.c -o beats -l4th
    • tcc beats.c -o beats -l4th

Then you can execute natively with ./beats 110

Using a Forth interpreter

Your Forth interpreter needs to be able to compile Forth source files. There are many options, but here is an example with gforth:

gforth -e "110" beats.fth

If you'd prefer to have your user value near the end of the command, remove the last 2 lines of the beats.fth file and do:

gforth beats.fth -e "110 beats bye"

For bonus ergonomics based on the second example, suppose you're using the Fish shell. You can create a function in ~/.config/fish/functions/beats.fish:

function beats
 gforth beats.fth -e $argv -e beats -e bye
end

Add an abbreviation line in ~/.config/fish/config.fish: abbr --add beats --set-cursor=! beats '"!"'

After running exec fish, you can now use beats "110", with the cursor automatically jumping between the quotes after you finish typing beats.

Using the 4th compiler

  • Install 4th
  • In the directory where you cloned this repo, run 4th csv beats.scr beats.hx
  • Run 4th lxq beats.hx 110