[![NPM Version](https://img.shields.io/npm/v/transfigure.svg?style=flat)](https://npmjs.org/package/transfigure)
[![Build Status](https://img.shields.io/travis/popeindustries/transfigure.svg?style=flat)](https://travis-ci.org/popeindustries/transfigure)

# Transfigure

**Transfigure** is a plug-in based transformer/transpiler for higher order languages that need to be converted to js|css|html. It provides the compile functionality for the [Buddy](https://github.com/popeindustries/buddy) build tool.

## Plug-in transpilers

In order to add transpilation support to Buddy projects, separate **transfigure-** modules need to be installed alongside Buddy:

```bash
$ npm install transfigure-coffeescript transfigure-less
```

The following plug-ins are currently available (with version numbers tracking their underlying language versions):

**js**
- [transfigure-babel](https://github.com/popeindustries/transfigure-babel)
- [transfigure-coffeescript](https://github.com/popeindustries/transfigure-coffeescript)
- [transfigure-react](https://github.com/popeindustries/transfigure-react) [deprecated - JSX now compiled with *transfigure-babel*]

**css**
- [transfigure-less](https://github.com/popeindustries/transfigure-less)
- [transfigure-stylus](https://github.com/popeindustries/transfigure-stylus)

**html**
- [transfigure-dust](https://github.com/popeindustries/transfigure-dust)
- [transfigure-handlebars](https://github.com/popeindustries/transfigure-handlebars)
- [transfigure-jade](https://github.com/popeindustries/transfigure-jade)
- [transfigure-nunjucks](https://github.com/popeindustries/transfigure-nunjucks)
- [transfigure-twig](https://github.com/popeindustries/transfigure-twig)

### Writing your own plug-in

Writing a plug-in for *Transfigure* is relatively simple. Each plun-in should conform to the following requirements:

1. Must have a package name starting with *transfigure-*
2. Must implement the correct `registration` and `compile` behaviour
3. Must be installed in the current project's *node_modules* directory (or a reachable parent)

#### API

Modules must export a `registration` object with `name` and `extensions` properties (Note that a plug-in can register multiple extensions):
```js
exports.registration = {
  name: 'myPlugin',
  extensions: {
    js: [
      'foo',
      'bar'
    ]
  }
};
```

Modules must export an async `compile` function with the following signature and behaviour:
```js
exports.compile = function (content, options, fn) {
  try {
    content = myPlugin.api(content, options);
    fn(null, content);
  } catch (err) {
    // Attach current filepath for helpful console output
    err.filepath = options.filepath;
    fn(err);
  }
};
```
The passed `options` object has the following properties:
- `filepath`: the fully resolved file path (ex: `/users/alex/projects/foo/src/js/foo.js`)
- `extension`: the file extension (ex: `js`)
- `name`: the file name without extension (ex: `foo`)
- `type`: the build target type (`js`, `css`, or `html`)
- `includes`: an array of html include/partials objects that can be precompiled/loaded before compilation
  - `id`: a unique dependency id
  - `content`: the file content
- `cache`: an html template cache instance that may be used to store precompiled html templates (see [transfigure-dust](https://github.com/popeindustries/transfigure-dust/blob/master/index.js) and [transfigure-nunjucks](https://github.com/popeindustries/transfigure-nunjucks/blob/master/index.js) for usage)
