Embedding a build script in .typ

I recently built a little tool called Hanzi Shader that renders any videos in Chinese characters, and I used Typst to build the HTML and organize the files. However, I wanted to keep a minimal amount of files and avoid Justfiles or Makefiles (please ignore the flake files in the repo), so I came up with this polyglot that embeds a little bash header inside a Typst file:

(using bash syntax highlighting)

#!/usr/bin/env bash
#let _ = ```sh
case "$1" in
  compile) typst compile --features bundle,html --format bundle $0 ;;
  watch)   typst watch   --features bundle,html --format bundle --pretty $0 ;;
  *)       echo "Unknown option: $1. Enter 'compile' or 'watch'"; exit 1 ;;
esac
exit 0
```

#title[I am the title] <random-label>

Put your Typst content here! See #link(<random-label>)[this link].

(using Typst syntax highlighting)

#!/usr/bin/env bash
#let _ = ```sh
case "$1" in
  compile) typst compile --features bundle,html --format bundle $0 ;;
  watch)   typst watch   --features bundle,html --format bundle --pretty $0 ;;
  *)       echo "Unknown option: $1. Enter 'compile' or 'watch'"; exit 1 ;;
esac
exit 0
```

#title[I am the title] <random-label>

Put your Typst content here! See #link(<random-label>)[this link].

The reason why it works is because bash interprets # as comments, while in Typst they are used to switch from markup mode to code mode. From Typst’s perspective, this creates a code block that gets discarded. The bash script ends at exit 0, so anything following that line won’t run at all.

Because the bash header is wrapped in backticks, the bash part is also highlighted correctly in my editor.

I took inspiration from this post:

1 Like