Literate Haskell support for Markdown
markdown-unlit
is a custom unlit
program. It can be used to extract
Haskell code from Markdown files.
To use it with GHC, add
ghc-options: -pgmL markdown-unlit
to your cabal file.
Extended example
tl;dr
markdown-unlit
allows you to have aREADME.md
, that at the same time is a literate Haskell program.
The following steps show you how to set things up, so that:
- the Haskell code in your
README.md
gets syntax highlighted on GitHub - you can run your literate Haskell within GHCi
- you can create a Cabal
test-suite
from yourREADME.md
(no broken code examples anymore, yay!)
The complete code of this example is provided in the example
subdirectory.
markdown-unlit
1. Install $ cabal update && cabal install markdown-unlit
README.md
2. Create a # nifty-library: Do nifty things (effortlessly!)
Here is a basic example:
```haskell
main :: IO ()
main = putStrLn "That was easy!"
```
Code blocks with class haskell
are syntax highlighted on GitHub (like
so).
README.lhs -> README.md
3. Create a symbolic link $ ln -s README.md README.lhs
4. Run your code
At this point we can load the code into GHCi:
$ ghci -pgmL markdown-unlit README.lhs
*Main> main
That was easy!
Or better yet, pipe the required flag into a .ghci
file, and forget about it:
$ echo ':set -pgmL markdown-unlit' >> .ghci
$ ghci README.lhs
*Main> main
That was easy!
test-suite
5. Create a Cabal name: nifty-library
version: 0.0.0
build-type: Simple
cabal-version: >= 1.8
library
-- nothing here yet
test-suite readme
type: exitcode-stdio-1.0
main-is: README.lhs
build-depends: base, markdown-unlit
ghc-options: -pgmL markdown-unlit
build-tool-depends: markdown-unlit:markdown-unlit
Run it like so:
$ cabal configure --enable-tests && cabal build && cabal test
Customizing
By default, markdown-unlit
extracts all code that is marked with haskell
,
unless it is marked with ignore
as well. You can customize this by passing
-optL <pattern>
to GHC.
A simple pattern is just a class name, e.g.:
-optL foo
extracts all code that is marked with foo
.
A class name can be negated by prepending it with a !
, e.g.
-optL !foo
extracts all code, unless it is marked with foo
.
You can use +
to combine two patterns with AND, e.g.
-optL foo+bar
extracts all code that is marked with both foo
and bar
.
If -optL
is given multiple times, the patterns are combined with OR, e.g.
-optL foo -optL bar
extracts all code that is either marked with foo
or bar
.
Development
Limitations
- indented code blocks are not yet supported
If you want to get any limitation lifted, open a ticket or send a pull request.
Contributing
Add tests for new code, and make sure that the test suite passes with your modifications.
cabal configure --enable-tests && cabal build && cabal test
Real world examples
That's it, have fun!