Layouts

markdown-document uses layouts for pdf generation. This chapter shows how layouts are used, how they are working and how you can create your own layout.

Existing layouts

Currently there is only one built-in layout available:

How are documents generated?

During document generation, the following steps are being made:

  1. Options are preprocessed (fallbacks applied, checked)
  2. Markdown file is rendered as HTML using jonschlinkert/remarkable
  3. Every layout part is processed using wycats/handlebars.js
  4. PDF document is generated using wkhtmltopdf
  5. PDF metadata is written using ExifTool

Create a custom layout

The best way to create a new layout is when you copy an existing one. All built-in layouts can be found inside markdown-document/layouts.

Parts of the layout

The main configuration file of a layout is the options.json file. This file consists of general layout page settings like paper size, orientation, margins and the definition of each part of the layout.

With these two parts you can define how the header and footer should appear. The relevant data is passed through GET parameters.

The following parameters are available:

Configuration:

"header": {
    "html": "header.html",
    "spacing": 10,
    "data": { ... }
},
"footer": {
    "html": "footer.html",
    "spacing": 10,
    "data": { ... }
}

Part cover

The cover is the first part of the document. It is basically the same as every content part.

Configuration:

"parts": {
    "cover": {
        "type": "cover",
        "html": "cover.html",
        "data": { ... }
    },
    ...
}

Part toc

The toc part is for generating a table of contents. This is done using a xslt transformation.

Configuration:

"parts": {
    ...,
    "toc": {
        "type": "toc",
        "xslStyleSheet": "toc.xslt",
        "data": { ... }
    },
    ...
}

Part content

A content part is the only part you can define multiple times.

Configuration:

"parts": {
    ...,
    "info": {
        "type": "content",
        "html": "info.html",
        "data": { ... }
    },
    ...,
    "content": {
        "type": "content",
        "html": "content.html",
        "data": { ... }
    }
    ...
}

Templating engine

Every part of an template (all html and xslt files) is processed using wycats/handlebars.js.

The following data object is passed to every part:

{
    "layoutPath": "file:///path/to/layout/",
    // The markdown content as html. Use } inside the layout
    "markdown": "<h1>Title</h1>...",
    // The document information defined inside the document options
    "document": { ... },
    "env": {
        "inputFile": "document.md",
        "outputFile": "document.pdf"
    },
    // The data of the current part
    "data": { ... },
    // Metadata provided during markdown processing
    "meta": {
        // Caption data provided by CaptionHelper
        "captions": {
            "table": [
                { "index": 1, "link": "table-1", "title": "Table title" },
                ...
            ],
            ...
        }
    }
}

External files

External files like CSS / JavaScript / Images must be linked using absolute file:/// links. You can use the `` templating variable to link to these files.

If you want to use external files from other node packages, you should use the resolve helper.

Resolve helper

The resolve helper resolves the path to a file of other node packages.

The following snippet shows how the file styles/github.css of the node package highlight.js can be resolved:

<link rel="stylesheet" href="" media="all" />

Translations

Templates can be translated using i18next. This can be useful if you want to translate the text ‘Page x of y’ or ‘Table of contents’ into different languages.

Translation files

Translation files must be placed inside the i18n subfolder of the layout. The name pattern for these files are: $language$.json (eg. en.json for english translations) and the content looks like:

{
    "TOC": "Table of Contents",
    "Copyright": "Copyright",
    ...
}

Templating syntax

The following syntax can be used:

Additional features can be found on the i18next website.

Concat helper

This helper concats strings (constants or variables):


IsEmpty helper

Checks if a value is null or empty (including objects and arrays).

Usage:


    Data is null / empty array / empty object
`

LookupHelper

Returns the property of an object by passing it’s name (by literal or variable).

Example

Using the following data:

{
    "users": ["john", "david"],
    "data": {
        "john": [1, 2, 3],
        "david": [4, 5, 6]
    }
}

The helper can be used like this:


    :
    
        ,
    

The result will look something like this (whitespaces ignored):

john:1,2,3,
david:4,5,6,