···11# Typst-Unlit
2233+Write literate Haskell programs in Typst
44+35*[tangled.org/@oppi.li/typst-unlit](https://tangled.org/@oppi.li/typst-unlit)*
4655-*Serves: 1 Prep Time: 10min Compile Time: 10ms*
77+**Serves: 1 Prep Time: 10min Compile Time: 10ms**
6879A literate program is one where comments are first-class citizens, and
810code is explicitly demarcated, as opposed to a regular program, where
···1214preprocessor to extract code from documents. This preprocessor is known
1315as *unlit*[^1]. GHC also supports *custom* preprocessors, which can be
1416passed in via the `-pgmL` flag. This very document you are reading, is
1515-one such preprocessor that allows embedding Haskell code inside typst
1616-files[^2].
1717+one such preprocessor program that allows extracting Haskell from Typst
1818+code (although it has been rendered to HTML, PDF or markdown depending
1919+on where you are reading it)[^2]!
17201821This recipe not only gives you a fish (the typst-unlit preprocessor),
1922but also, teaches you how to fish (write your own preprocessors).
···5356with an empty line! To detect lines that are Haskell, we look for the
5457```` ```haskell ```` directive and stop at the end of the code fence.
5558Simple enough! Annoyingly, Haskell requires that imports be declared at
5656-the top of the file. This results in literate haskell programs always
5959+the top of the file. This results in literate Haskell programs always
5760starting with a giant block of imports:
58615962> -- So first we need to get some boilerplate and imports out of the way.
···7376- `-h`: ignore this for now
7477- `<label>`: ignore this for now
7578- `<infile>`: the input lhaskell source code
7676-- `<outfile>`: the output haskell source code
7979+- `<outfile>`: the output Haskell source code
77807881Invoke the runes to handle CLI arguments:
7982···210213ghc -o typst-unlit typst-unlit.hs
211214```
212215213213-And now, we can execute our preprocessor on literate haskell files!
216216+And now, we can execute our preprocessor on literate Haskell files!
214217215218## Serving
216219217217-To test our preprocessor, first, write a literate haskell file
220220+To test our preprocessor, first, write a literate Haskell file
218221containing your typst code:
219222220223````
···265268```
266269#!/usr/bin/env bash
267270268268-# this does the same thing as typst-unlit.lhs, but depends on `typst` and `jq`
271271+# this does the same thing as typst-unlit.lhs, but depends on typst and jq
272272+# this script does clobber the line numbers, so users beware
269273270274typst query "$3" 'raw.where(lang: "haskell-top")' | jq -r '.[].text' > "$4"
271275typst query "$3" 'raw.where(lang: "haskell")' | jq -r '.[].text' >> "$4"
272276```
277277+278278+This document mentions the word “Haskell” 60 times.
273279274280[^1]: <https://gitlab.haskell.org/ghc/ghc/-/tree/master/utils/unlit>
275281