# Typst-Unlit
*[tangled.org/@oppi.li/typst-unlit](https://tangled.org/@oppi.li/typst-unlit)*
*Serves: 1 Prep Time: 10min Compile Time: 10ms*
A literate program is one where comments are first-class citizens, and
code is explicitly demarcated, as opposed to a regular program, where
comments are explicitly marked, and code is a first-class entity.
GHC supports literate programming out of the box, by using a
preprocessor to extract code from documents. This preprocessor is known
as *unlit*[^1]. GHC also supports *custom* preprocessors, which can be
passed in via the `-pgmL` flag. This very document you are reading, is
one such preprocessor that allows embedding Haskell code inside typst
files[^2].
This recipe not only gives you a fish (the typst-unlit preprocessor),
but also, teaches you how to fish (write your own preprocessors).
## Ingredients
To write your own preprocessor:
GHC: the Glorious Haskell Compiler
Typst: to generate PDFs
And thats it! No stacking, shaking or caballing here.
To compile this very document:
The bootstrap program
GHC: to produce an executable program
Typst: to produce a readable PDF
**Pro Tip:** If you’re missing any ingredients, your local nixpkgs
should stock them!
## Instructions
The idea behind the unlit program is super simple: iterate over the
lines in the supplied input file and replace lines that aren’t Haskell
with an empty line! To detect lines that are Haskell, we look for the
```` ```haskell ```` directive and stop at the end of the code fence.
Simple enough! Annoyingly, Haskell requires that imports be declared at
the top of the file. This results in literate haskell programs always
starting with a giant block of imports:
> -- So first we need to get some boilerplate and imports out of the way.
— Every literate programmer
Oh gee, if only we had a tool to put the important stuff first. Our
preprocessor will remedy this wart, with the `haskell-top` directive to
move blocks to the top. With that out of the way, lets move onto the
program itself!
### Step 1: The maincourse
I prefer starting with `main` but you do you. Any program that is passed
to `ghc -pgmL` has to accept exactly 4 arguments:
- `-h`: ignore this for now
- `