packages feed

pandoc-markdown-ghci-filter-0.1.0.0: README.md

pandoc-markdown-ghci-filter
===========================

A `Pandoc` filter that identifies code blocks(`Haskell`) in Pandoc
supported formats, executes the code in GHCI and embeds the results in
the returned output by updating the AST provided by `Pandoc`.

Quick Overview
==============

Often a markdown(or any `pandoc` supported document) for any `Haskell`
related documentation or a technical blog post involves `code` blocks.
The `code` block could include `definitions` and also a demonstration of
output with an `interactive` prompt. For, example, take this `code`
block:

``` {.haskell code-filter="Off"}
-- README.md

-- definition
increment:: Integer -> Integer
increment x = x + 1

-- interactive prompt to demonstrate the working of definitions so far

>> increment 41
```

It would be nice if this `code` block was automatically evaluated and
`output` of `increment 41` is automatically recorded below
`>> increment 41`, as follows:

``` {.haskell}
-- README.md

-- definition
increment:: Integer -> Integer
increment x = x + 1

-- interactive prompt to demonstrate the working of definitions so far

>> increment 41
42

```

Notice, that the `42` is automatically populated by this filter while
transforming the original document.

To transform the document, we need to run the document through the
`pandoc` filter, as follows:

``` {.shell}

-- set up pandoc_filter to the executable of this program (see Installation)

pandoc -s -t json README.md | pandoc_filter | pandoc -f json -t markdown
```

To read more about how `filter` work, visit the
[this](https://pandoc.org/filters.html) page.

Installation
============

Requirements
------------

    - [Stack](https://docs.haskellstack.org/en/stable/README/)

### From Source

``` {.shell}

git clone https://github.com/gdevanla/pandoc-markdown-ghci-filter.git
cd pandoc-markdown-ghci-filter

stack build
```

### From Stackage/Hackage

``` {.shell}
stack build pandoc-markdown-ghci-filter # executable only available to local stack environment

or

stack install pandoc-markdown-ghci-filter # if you want to across all stack environments
```

Running the filter
==================

``` {.shell}
pandoc -s -t json test.md | pandoc-markdown-ghci-filter-exe | pandoc -f json -t markdown
```

Usage Notes/Caveats
===================

1.  All interactive statements (prefixed with `>>`) need to be preceded
    by `\n` to let the filter respect original new line spacing. If this
    is not followed, `\n` may be truncated.
2.  The program internally wraps all commands inside the GHCi multi-line
    construct `:{..:}`. Therefore, the code segments should not have
    multi-line constructs as part of code blocks.
3.  If you want the filter to ignore a certain `code` block, you can
    turn-off the filter by setting the `code` block attribute as follows

``` {.markdown}

{.haskell code_filter="Off"}

-- do not run this code through GHCi

>> putStrLn "This line will not be expanded by the filter"
```

Note, the default value is "On"

Limitations/Open Issues
=======================

1.  Attaching different formattting properties to `output`.
2.  As explained in `Usage Notes`, all `interactive` statements should
    be preceded by an empty line, for the filter to maintain the `\n`
    characters as given by the input.

More examples
=============

Sample Markdown Before Transformation
-------------------------------------

Sample markdown as fed into filter through `pandoc`.

Example 1
---------

``` {.haskell code-filter="Off"}
import Data.Text

>> putStrLn "This string should show up in the output"
```

Example 2
---------

``` {.haskell code-filter="Off"}
addOne:: Integer -> Integer
addOne x = x + 1

>> addOne 13

multBy2:: Integer -> Integer
multBy2 x = x * 2

>> (addOne 10) + (multBy2 20)
```

Example 3
---------

Any errors that occur while executing statements in the `code` block are
also rendered.

``` {.haskell code-filter="Off"}

wrongFuncDefinition:: Integer -> Integer
wrongFuncDefintion = x + 1

>> functionNotInScope 10
```

Markdown after transformation
-----------------------------

Example 1
---------

``` {.haskell code-filter="On"}
import Data.Text

>> putStrLn "This string should show up in the output"
This string should show up in the output

```

Example 2
---------

``` {.haskell code-filter="On"}
addOne:: Integer -> Integer
addOne x = x + 1

>> addOne 13
14

multBy2:: Integer -> Integer
multBy2 x = x * 2

>> (addOne 10) + (multBy2 20)
51

```

Example 3
---------

Any errors that occur while executing statements in the `code` block are
also rendered.

``` {.haskell code-filter="On"}

wrongFuncDefinition:: Integer -> Integer
wrongFuncDefintion = x + 1

<interactive>:16:1: error:
    The type signature for ‘wrongFuncDefinition’
      lacks an accompanying binding

>> functionNotInScope 10
<interactive>:29:2: error:
    Variable not in scope: functionNotInScope :: Integer -> t

```

*Fun Fact:* This document was generated using this same tool it
describes. This
[README-pre-process.md](https://github.com/gdevanla/pandoc-markdown-ghci-filter/blob/master/README-pre-process.md)
was used to generate this document. Here is the command that was used:

``` {.shell}
pandoc -s -t json README-pre-process.md | stack runhaskell app/Main.hs | pandoc -f json -t markdown > README.md
```