packages feed

pdf-slave-1.0.0.0: README.md

pdf-slave
=========

Tool that compiles `haskintex` (TeX with embedded Haskell) files into PDF documents.
Templates are described in YAML format and can define dependencies.

Features:

* Input JSON file for `htex` file that holds template varying data.

* Option for packing a template in all-in YAML bundle.

* Support for template dependencies that include:
  - Bibtex files
  - Images, listings, other static files.
  - Other `.htex` templates that compiles into TeX and includes into parent template.
  - Other `.htex` templates that compiles into PDF and includes into parent template.

Template reference
==================

Common template consists of several files:

* `template_input.json` - Input data for template in JSON format.

``` JSON
{
  "line-width": 2,
  "spiral-precision": 0.01,
  "spiral-interval": [0,4],
  "spiral-a": 0.1,
  "spiral-b": 4
}
```

* `template.htex` - TeX/LaTeX with embedded Haskell that reads input data from
file `template.json`. You have to provide code at the beginning of file that reads
the inputs, like that:

``` Haskell
\begin{document}

\begin{haskellpragmas}
{-# LANGUAGE OverloadedStrings #-}
\end{haskellpragmas}
\begin{writehaskell}
import Data.Aeson
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.ByteString.Lazy as BS

data Input = Input {
  lineWidth       :: Double
, spiralPrecision :: Double
, spiralInterval  :: (Double, Double)
, spiralA         :: Double
, spiralB         :: Double
}

instance FromJSON Input where
  parseJSON (Object o) = Input
    <$> o .: "line-width"
    <*> o .: "spiral-precision"
    <*> o .: "spiral-interval"
    <*> o .: "spiral-a"
    <*> o .: "spiral-b"

inpt :: Input
inpt = case unsafePerformIO $ fmap eitherDecode' $ BS.readFile "template_input.json" of
  Left e -> error (show e)
  Right a -> a

\end{writehaskell}
```

* `template.yaml` - description of template and its dependencies.

``` YAML
name:  template01             # name of template
input: template01_input.json  # name of input file
body:  template01.htex        # name of .htex file
dependencies: {}              # dependency tree (see below)
haskintex-opts: []            # additional flags to haskintex
```

## Dependencies

There are 4 different types of dependencies:

* `other` - static files that don't require any processing. They could be images,
listings etc. Example of YAML configuration:

  ``` YAML
  dependencies:
    lambda.png: # name of dependency is equal to filename relative to parent template
      type: other # marks type of dependency
    code/demo.hs:
      type: other
  ```

  See [examples/example02](https://github.com/NCrashed/pdf-slave/tree/master/examples/template02) for full example.

* `bibtex` - bibliography files that require additional passes with `bibtex`. Example of YAML configuration:

  ``` YAML
  dependencies:
    biblio.bib: # name of dependency is equal to filename relative to parent template
      type: bibtex # marks type of dependency
  ```

  See [examples/example03](https://github.com/NCrashed/pdf-slave/tree/master/examples/template03) for full example.

* `template` - other `.htex` templates that are included in parent via `\\input{...}` or `\\include{..}`. Example of YAML configuration:

  ``` YAML
  dependencies:
    dep1: # name of dependency defines subfolder where the output tex file is located
      type:  template # marks type of dependency
      name:  dep1
      input: dep1_input.json
      body:  dep1.htex
    dep2:
      type:  template
      name:  dep2
      body:  dep2.htex
      dependencies:
        lambda.png:
          type: other
        code/demo.hs:
          type: other
  ```

  See [examples/example04](https://github.com/NCrashed/pdf-slave/tree/master/examples/template04) for full example.

  **Note that `code/demo.hs` subdependency should be included as `dep2/code/demo.hs` in `dep2.htex` as `dep2.tex` is inlined into parent.**

* `template_pdf` - other `.htex` templates that are included as PDFs into parent template. Example of YAML configuration:

  ``` YAML
  dependencies:
    template01: # name of dependency defines subfolder where the output tex file is located
      type:  template_pdf # marks type of dependency
      name:  template01
      input: template01_input.json
      body:  template01.htex
    template02:
      type:  template_pdf
      name:  template02
      body:  template02.htex
      dependencies:
        lambda.png:
          type: other
        code/demo.hs:
          type: other
  ```

  See [examples/example05](https://github.com/NCrashed/pdf-slave/tree/master/examples/template05) for full example.

### Input propagation

When you work with dependencies you have two options how to handle inputs:

* Define dependency inputs in its own file:

  ``` YAML
  dependencies:
    dep1:
      type:  template
      name:  dep1
      input: dep1_input.json # private input file
      body:  dep1.htex
  ```

* Define dependency inputs in parent file:

  ``` YAML
  name:  template06
  input: template06_input.json # contains inputs for dep1
  body:  template06.htex
  dependencies:
    dep1:
      type:  template
      name:  dep1
      body:  dep1.htex
  ```

  Contents of `template06_input.json`:

  ``` JSON
  {
    "dep1": {
      "line-width": 2,
      "spiral-precision": 0.01,
      "spiral-interval": [0,4],
      "spiral-a": 0.1,
      "spiral-b": 4
    }
  }
  ```

  Note that key of subsection must be equal to name of dependency.

  See [examples/example06](https://github.com/NCrashed/pdf-slave/tree/master/examples/template06) for full example.

## Making bundles

One can pack all `.htex`, `.json`, `.yaml` and all dependencies in single YAML
bundle that can be easily distributed, transmitted between services and stored:

``` bash
cd examples/template01
pdf-slave --template template01.yaml --output template01_bundle.yaml pack
```

As modification of such bundles isn't handy, one can unpack bundle:

``` bash
pdf-slave --template template01_bundle.yaml --output template01_directory unpack
```

Rendering of bundles is handled with the same command that is used for ordinary
templates.

Compilation
===========

You need:

* LaTeX distribution (for instance, texlive or miktex)

* [stack](https://docs.haskellstack.org/en/stable/README/) or system wide GHC 8.0.1 + Cabal 1.24.0.

Compilation with stack:
``` bash
git clone https://github.com/NCrashed/pdf-slave.git
cd pdf-slave
stack install
```

Compilation with cabal:
``` bash
git clone https://github.com/NCrashed/pdf-slave.git
cd pdf-slave
cabal sandbox init
cabal install --dependencies-only
cabal install
```

Running examples
================

You need:

* LaTeX distribution (for instance, texlive or miktex)

* stack or GHC+Cabal (yes, you need GHC to evaluate templates at runtime)

* `pdf-slave` and `haskintex` executables in PATH

Stack users:
``` bash
cd examples/template01
stack install aeson HaTeX
stack exec -- pdf-slave --template template01.yaml --output output.pdf pdf && xdg-open output.pdf
```

Cabal users:
``` bash
cd examples/template01
cabal sandbox init
cabal install aeson HaTeX
pdf-slave --template template01.yaml --output output.pdf pdf && xdg-open output.pdf
```

Docker build
============

1. Run `cook_doocker.sh` script. This will build two images, one `pdf-slave-build` for compilation of binaries and the second one `pdf-slave` for production usage.

2. Usage:

  ``` bash
  docker run -it --rm -v $(pwd)/examples/template01:/data/examples pdf-slave pdf --template examples/template01.yaml --output examples/output.pdf
  xdg-open examples/template01/output.pdf
  ```

3. Or download [precompiled container](https://hub.docker.com/r/ncrashed/pdf-slave/) from Docker Hub.