# grunt-panda

Convert documents (often to/from markdown) using pandoc while extracting YAML metadata

npm install grunt-panda

# grunt-panda

Convert documents (often to/from markdown) using pandoc

## Getting Started

This plugin requires Grunt ~0.4.1 and Pandoc.

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

Since this plugin uses LiveScript, run grunt livescript before other tasks. Alternatively, run grunt twice. The first time you run it you will probably get an error that certain javascripts do not yet exist.

npm install grunt-panda --save-dev


Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of coffeescript:

grunt.loadNpmTasks 'grunt-panda'


### Overview

In your project's Gruntfile, add a section named panda to the data object passed into grunt.initConfig().

grunt.initConfig
panda:
options:
# see below
files:
# Specify src and dest files in the usual grunt manner.
# Multiple input files (i.e. src files in an array) will be
# concatenated with a blank line between each file before
# offering them as a single stream to pandoc.


### Options

#### infile

Type: String

Default: "tmp/inputs.md"

The path of the temporary file used to accumulate multiple input files that are being concatenated before sending them to pandoc. Relative paths are relative to the GruntFile location.

#### metaReplace

Type: String

Default: null

If the string matches the root of the file path (which usually starts with whatever is specified in the files cwd option), then this root will be replaced in the output metadata. The file foo/bar/bat.md normally generates metadata in foo.bar.bat.meta, but if metaReplace were "foo/", the metadata would appear in bar.bat.meta.

#### metaReplacement

Type: String

Default: null

If a valid metaReplace string is given (which can be ""), then that string will be replaced with the given replacement in the output metadata. e.g. The file foo/bar/bat.md normally generates metadata in foo.bar.bat.meta, but if metaReplace were "foo/bar", and metaReplace were "baz", the metadata would appear in baz.bat.meta.

#### pandocOptions

Type: String or Array

Default:

• for HTML: "-t html5 --smart --section-divs --mathjax"
• else: "-f markdown --smart"

Can be used to pass any command line options along to pandoc.

If a string, it will be split into arguments on space characters. If an array the arguments will be used as is.

#### separator

Type: String

Default: set to two OS independent line feeds.

The separator to be inserted between input files that are concatenated before processing by pandoc.

#### spawnLimit

Type: Integer > 0

Default: 1

Limits the number of pandoc child processes that can be spawned at any one time. Increase the number if you find this helps with performance and if you are not concatenating files into one destination. If you are concatenating markdown, the order is likely to matter and can only be guaranteed when the spawnLimit is 1.

#### stripMeta

Type: String

Default: ""

If the input files contain metadata in the header, this can be removed by setting here the separator string. This separates the meatadata from the markdown content. The metadata and the separator will be ignored. The separator must start at the beginning of the line. If no separator is seen at all, the whole content will be processed.

Type: String a pathname relative to the Gruntfile

Default: none

If metaDataPath is defined, any Yaml metadata stripped from file headers is merged and written to that path.

Type: String a variable name

#### metaOnly

Type: Boolean

Default: false

Don't run pandoc - only generate metadata.

#### pipeToModule (deprecated)

Type: String a node module path

Default: none

If a pipeToModule node module path is given, the task will require the module. It should return a function of one parameter. The task will call that function passing the metadata object as a parameter. If the module if given as a javascript file name, then the path must be absolute or relative to grunt-panda's Gruntfile.

#### postProcess (deprecated)

Type: Function (grunt, metadata) -> metadata

• If a postProcess function is given, panda passes any generated metadata object to it. The function acts as a filter, returning the metadata object transformed in some way. Typically useful for making future searches faster.

#### process

Type: Boolean Object

Default: false

Process source files as templates before concatenating.

• false - No processing will occur.
• true - Process source files using grunt.template.process defaults.
• options object - Process source files using grunt.template.process, using the specified options.
• function(src, filepath) - Process source files using the given function, called once for each file. The returned value will be used as source code.

(Default processing options are explained in the grunt.template.process documentation)

### Usage Examples

      test1:
options:
process: true
files:
"test/actual/test1.html": "test/fixtures/test1.md"

test2:
files:
"test/actual/test2.html": [
"test/fixtures/input1.md"
"test/fixtures/input2.md"
"test/fixtures/input3.md"
]

test3:
files:

"test/actual/test3.pdf": [
"test/fixtures/input1.md"
"test/fixtures/input2.md"
"test/fixtures/input3.md"
]
"test/actual/test3.html": [
"test/fixtures/input1.md"
"test/fixtures/input2.md"
"test/fixtures/input3.md"
]
"test/actual/test3.docx": [
"test/fixtures/input1.md"
"test/fixtures/input2.md"
"test/fixtures/input3.md"
]


Whole directories of markdown files may be processed using grunt's multi-file capability.

    panda
test4:
options:
spawnLimit: 3
files: [
expand: true
cwd: "test/fixtures/test4"
src: "**/*.md"
dest: "test/actual/test4"
ext: ".html"
]


If metaDataPath is defined, any Yaml metadata stripped from file headers is merged and written to that path.

In addition, or alternatively, you can pipe the metadata to a function returned by a node module specified in pipeToModule.

    panda
test6:
options:
stripMeta: ''
pipeToModule: '../test/fixtures/test6/nodeModuleToRun.js'

files: [
expand: true
cwd: "test/fixtures"
src: ["**/test5.md","**/test4/*.md"]
dest: "test/actual"
ext: ".html"
]


File foo/bar/baz metadata will be found in the output yaml as

  foo:
bar:
baz:
meta:


### Error handling

The task should fail reporting any errors encountered in pandoc. Use grunt -v for more detailed reporting.

If you do not have Pandoc installed, test1 will fail with:

Running "panda:test1" (panda) task
Processing test/fixtures/input.md
format = -t html5


You will need TeX to be installed to generate pdfs. See the Pandoc notes on this.

If you do not have a recent unicode aware TeX or LaTeX installed you may need to update. Older installations are likely to generate when running test3:

Fatal error: Command failed: pandoc: Error producing PDF from TeX source.
! LaTeX Error: File ifluatex.sty' not found.
`

### Code Style

NB. Source is in LiveScript.

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

## Release History

version-0.2.6

• Allows an array of pandocOptions.

version-0.2.5

• removed debugger leftovers. Yaml detection should now work on windows file too.

version-0.2.4

• added metaOnly option which creates only the metadata and does not run pandoc. Useful for 2 pass processing.

version-0.2.3

• Metadata is now written to the grunt configuraion variable defined in the metaDataVar option.

version-0.2.2

• Added metaReplace and metaReplacement options. These are useful in order to adjust the paths inside metadata to convenient values no matter where your source markdown lives.

version-0.2.1

• Revised behaviour so panda now always generates an aggregate yaml file, optionally passing the file through a filter before writing it. The filter is typically used by an application to expand the data to speed up future searches - e.g. by making references bidirectional, or preparing contexts for page generation.

version-0.1.13

• Removed some debug logging. Revised Getting Started advice.

version-0.1.12

• Fixed bug that meant a write to yaml metadata file had to be configured even though pipeToModule option was used instead.

version-0.1.11

• Added pipeToModule option to facilitate further processing without the need to write and then read in a metadata file.

version-0.1.10

• Removed --section-divs option as it does not play well with raw html. The html nesting ends up broken.

version-0.1.9

• Default pandoc options now include -S for typographically correct output.

version-0.1.8

version-0.1.7

• Changed test1 so it tests lodash template processing
• Improved test4 to catch issue 2
• Fixed silly asynchronous bug by piping data direct to pandoc rather than by using a temporary file.
• Added spawnLimit option to control number of pandoc child processes.
• Changed default options for markdown to html
• Changed stripMeta default to 4 backticks. Backticks play better than dashes when source markdown is previewed without stripping. They are interpreted as a code block in both Github and Pandoc flavour markdown.
• Moved async dependency from developer to user dependencies in package.json

version-0.1.6

• Tests use normalised pathnmames for Windows compatibility

version-0.1.5

• Now works with file globbing

version-0.1.4

• Revised process option description

version-0.1.3

• Documented missing Pandoc and TeX errors

version-0.1.2

• Corrected option docs and usage examples

version-0.1.1

• Clarify purpose in docs

version-0.1.0

• First release
npm loves you