Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/owickstrom/pandoc-include-code

A Pandoc filter for including code from source files
https://github.com/owickstrom/pandoc-include-code

Last synced: about 19 hours ago
JSON representation

A Pandoc filter for including code from source files

Awesome Lists containing this project

README

        

# pandoc-include-code

_A Pandoc filter for including code from source files._

You get to:

* Keep your examples and documentation compiled and in sync
* Include small snippets from larger source files without needing to keep
track of line numbers
* Dedent included snippets

## Usage

The filter recognizes code blocks with the `include` attribute present. It
swaps the content of the code block with contents from a file.

### Including Files

The simplest way to use this filter is to include an entire file:

```{include=docs/MyFile.hs}
```

You can still use other attributes, and classes, to control the code blocks:

```{.purescript include=docs/MyFile.purs}
```

### Snippets

There is support for delimited _snippets_. Use a line comment of
whatever kind you want, and enclose the snippet between `start snippet
` and `end snippet `.

-- start snippet cool-thingy
main =
putStrLn "I explain some cool concept in Haskell code."
-- end snippet cool-thingy

Or why not some C code:

// start snippet wow
int main() {
printf("such performance");
}
// end snippet wow

**NOTE:** There can only be whitespace and a newline _after_ the
snippet name. This means that multi-line comments in C, Java, etc,
will not work. Only single-line comments will.

Then, in your code block, specify the snippet name:

```{include=docs/MyFile.hs snippet=cool-thingy}
```

### Ranges

If you want to include a specific range of lines, use `startLine` and `endLine`:

```{include=docs/MyFile.hs startLine=35 endLine=80}
```

### Dedent

Using the `dedent` attribute, you can have whitespaces removed on each line,
where possible (non-whitespace character will not be removed even if they occur
in the dedent area).

```{include=docs/MyFile.hs dedent=4}
```

### Conflicting Modes

"Snippet mode" and "range mode" cannot be used together.

### Line Numbers

If you include the `numberLines` class in your code block, and use `include`,
the `startFrom` attribute will be added with respect to the included code's
location in the source file.

```{include=docs/MyFile.hs startLine=35 endLine=80 .numberLines}
```

### Adding Direct Links

It is possible to add hyperlinks to the original source code file specified in the `include` attribute by adding the `.includeLink` class in your code block.

```{include=docs/MyFile.hs .includeLink}
```
## Adding Base url for all CodeBlock links
A base url will be appended to all relative paths specified in the
`include` attribute of each `CodeBlock` . It does not affect paths beginning with `file:` , `C:`, `\`, `/`,.... This can be done
two option:

#### Option 1: YAML

Specify a base key along with the base url as the attribute in
the YAML header:

```
---
title: All About Wonderland
author: Alice
date: November 2020
base: http://localhost:8000/
---
```

#### Option 2: Command Line

Add the base as a metavalue ` -M base=` or
` --metavalue base=` in the command line when
calling pandoc.

```
pandoc --filter pandoc-include-code -M base=http://localhost:8000/ in.md -o out.html
```

NOTE: If the base url is specified in the metadata block, then
by specifying a different base in the command line, it will override
the original base.

Both of these options will add a hyperlink to the filepath defined
in the `include` attribute linking to
`http://localhost:8000/source/sample.hs`:

#### Overriding a specified base url

Adding a base attribute in the metadata block or the command line
will affect all relative links in the `CodeBlocks`. To add an alternative base for a
specific link, add the base as an attribute `base=https....` to
the`CodeBlock`:

````
```{.haskell .includeLink include=source/sample.hs snippet=animals base=}
```
````

This adds a hyperlink to the filepath specified in the
`include` attribute linking to `../source/sample.hs` :

### More Usage Examples

* The blog post [Automating the Build of Your Technical Presentation](https://wickstrom.tech/programming/2017/09/24/automating-the-build-of-your-technical-presentation.html)
shows practical examples of how to use this filter.

## Install

Executables for Linux and macOS are available in the [Releases
page](https://github.com/owickstrom/pandoc-include-code/releases).

### From Homebrew

You can use [Homebrew](https://brew.sh) to install this filter:

```bash
brew install pandoc-include-code
```

### From Hackage

If you'd rather install using `cabal` or `stack`, you can use the following
command:

```bash
cabal install pandoc-include-code
```

The package is [available at Hackage](https://hackage.haskell.org/package/pandoc-include-code).

## Build

Requirements:

* [Cabal](https://www.haskell.org/cabal/) or
[Stack](https://docs.haskellstack.org/en/stable/README/), either works.

To install from sources, run:

```bash
git clone [email protected]:owickstrom/pandoc-include-code.git
cd pandoc-include-code
cabal configure
cabal install
```

## Run

If you have installed from sources, and you have `~/.local/bin` on your
`PATH`, you can use the filter with Pandoc like so:

```bash
pandoc --filter pandoc-include-code input.md output.html
```

## Usage with Hakyll

If you are using the [Hakyll](https://jaspervdj.be/hakyll/) static site generator, you can use the filter by importing it as a library and using the snippet below.

Add `pandoc`, `pandoc-types`, and `pandoc-include-code` to your project dependencies, then define a custom Hakyll compiler using a Pandoc transform:

```haskell
import Text.Pandoc (Format (..), Pandoc)
import Text.Pandoc.Walk (walkM)
import Text.Pandoc.Filter.IncludeCode (includeCode)

includeCodeTransform :: Pandoc -> IO Pandoc
includeCodeTransform = walkM (includeCode (Just (Format "html5")))

includeCodePandocCompiler :: Compiler (Item String)
includeCodePandocCompiler =
pandocCompilerWithTransformM
defaultHakyllReaderOptions
defaultHakyllWriterOptions
(unsafeCompiler . includeCodeTransform)
```

You can now use `includeCodePandocCompiler` instead of the default `pandocCompiler` in your Hakyll rules:

```haskell
match "*.md" $ do
route $ setExtension "html"
compile $ includeCodePandocCompiler
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
```

## Changelog

[CHANGELOG.md](CHANGELOG.md)

## License

[Mozilla Public License Version 2.0](LICENSE)