Is there an easy way to convert a literate Haskell file (.lhs
) to a regular Haskell (.hs
) source file?
I thought there might be a GHC option, but the GHC manual doesn't seem to have much information on literate programs or the .lhs
format. The word "literate" doesn't even appear in the index!
The Literate programming link on the Wiki includes links to scripts that convert between "bird" and "\begin{code}
..\end{code}
" styles or convert .lhs
to TeX format, but that's it.
GHC itself uses a standalone C program called unlit
to process .lhs
files. You can probably find it installed somewhere in your GHC installation. If you run it, it shows a few command line options without explanation:
$ cd ~/.stack/programs/x86_64-linux/ghc-8.6.4/lib/ghc-8.6.4/bin
$ ./unlit
usage: unlit [-q] [-n] [-c] [-#] [-P] [-h label] file1 file2
Digging into the source code, it looks like the options are:
-q "quiet": ignore certain errors, so permit missing empty lines before and after
"bird" style and accept completely empty programs
-n (default) "noisy": opposite of -q, so be noisy about errors
-c "crunch": don't leave blank lines where literate comments are removed
-# delete lines that start with "#!"
-P suppress CPP line number pragma, but only matters if `-h` is supplied
-h File name for an initial `#line` pragma
So, the command line:
$ /path/to/unlit -c myfile.lhs myfile.hs
will probably do a good job converting myfile.lhs
:
This is a literate program
> main :: IO ()
using both code styles
\begin{code}
main = putStrLn "hello"
\end{code}
to an "illiterate" program myfile.hs
:
main :: IO ()
main = putStrLn "hello"
For "bird" style, it actually replaces the '>' character with a space and leaves the rest of the indentation in place, so for my example above, both lines in myfile.hs
are indented with two spaces, which could be a drawback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With