Created by [jonschlinkert]({%= author.url %}) and [doowb](https://github.com/doowb).

**Features**

- Bootstrap your own parser, get sourcemap support for free
- All parsing and compiling is handled by simple, reusable middleware functions
- Inspired by the parsers in [pug][] and [css][].

## Quickstart example

All of the examples in this document assume the following two lines of setup code exist first:

```js
var Snapdragon = require('{%= name %}');
var snapdragon = new Snapdragon();
```

**Parse a string**

```js
var ast = snapdragon.parser
  // parser handlers (essentially middleware)
  // used for parsing substrings to create tokens
  .set('foo', function () {})
  .set('bar', function () {})
  .parse('some string', options);
```

**Compile an AST returned from `.parse()`**

```js
var result = snapdragon.compiler
  // compiler handlers (essentially middleware), 
  // called on a node when the `node.type` matches
  // the name of the handler
  .set('foo', function () {})
  .set('bar', function () {})
  // pass the `ast` from the parse method
  .compile(ast)

// the compiled string
console.log(result.output);
```

See the [examples](./examples/).

## Parsing

**Parser handlers**

Parser handlers are middleware functions responsible for matching substrings to create tokens:

**Example handler**

```js
var ast = snapdragon.parser
  .set('dot', function() {
    var pos = this.position();
    var m = this.match(/^\./);
    if (!m) return;
    return pos({
      // the "type" will be used by the compiler later on,
      // we'll go over this in the compiler docs
      type: 'dot',
      // "val" is the string captured by ".match",
      // in this case that would be '.'
      val: m[0]
    });
  })
  .parse('.'[, options])
```

_As a side node, it's not scrictly required to set the `type` on the token, since the parser will add it to the token if it's undefined, based on the name of the handler. But it's good practice since tokens aren't always returned._

**Example token**

And the resulting tokens look something like this:

```js
{ 
  type: 'dot',
  val: '.' 
}
```

**Position**

Next, `pos()` is called on the token as it's returned, which patches the token with the `position` of the string that was captured:

```js
{ type: 'dot',
  val: '.',
  position:
   { start: { lineno: 1, column: 1 },
     end: { lineno: 1, column: 2 } }}
```

**Life as an AST node**

When the token is returned, the parser pushes it onto the `nodes` array of the "previous" node (since we're in a tree, the "previous" node might be literally the last node that was created, or it might be the "parent" node inside a nested context, like when parsing brackets or something with an open or close), at which point the token begins its life as an AST node.


**Wrapping up**

In the parser calls all handlers and cannot find a match for a substring, an error is thrown.

Assuming the parser finished parsing the entire string, an AST is returned.


## Compiling

The compiler's job is to take the AST created by the [parser](#parsing) and convert it to a new string. It does this by iterating over each node on the AST and calling a function on the node based on its `type`.

This function is called a "handler".

**Compiler handlers**

Handlers are _named_ middleware functions that are called on a node when `node.type` matches the name of a registered handler.

```js
var result = snapdragon.compiler
  .set('dot', function (node) {
    console.log(node.val)
    //=> '.'
    return this.emit(node.val);
  })
```

If `node.type` does not match a registered handler, an error is thrown.


**Source maps**

If you want source map support, make sure to emit the entire node as the second argument as well (this allows the compiler to get the `node.position`).

```js
var res = snapdragon.compiler
  .set('dot', function (node) {
    return this.emit(node.val, node);
  })
```

## All together

This is a very basic example, but it shows how to parse a dot, then compile it as an escaped dot.

```js
var Snapdragon = require('..');
var snapdragon = new Snapdragon();

var ast = snapdragon.parser
  .set('dot', function () {
    var pos = this.position();
    var m = this.match(/^\./);
    if (!m) return;
    return pos({
      type: 'dot',
      val: m[0]
    })
  })
  .parse('.')

var result = snapdragon.compiler
  .set('dot', function (node) {
    return this.emit('\\' + node.val);
  })
  .compile(ast)

console.log(result.output);
//=> '\.'
```

## API

### Parse
{%= apidocs("lib/parser.js") %}

### Compile
{%= apidocs("lib/compiler.js") %}


## Snapdragon in the wild
{%= verb.related.description %}
{%= related(verb.related.implementations) %}

## History

### v0.9.0

**Breaking changes!**

In an attempt to make snapdragon lighter, more versatile, and more pluggable, some major changes were made in this release. 

- `parser.capture` was externalized to [snapdragon-capture][]
- `parser.capturePair` was externalized to [snapdragon-capture-set][]
- Nodes are now an instance of [snapdragon-node][]

### v0.5.0

**Breaking changes!**

Substantial breaking changes were made in v0.5.0! Most of these changes are part of a larger refactor that will be finished in 0.6.0, including the introduction of a `Lexer` class. 

- Renderer was renamed to `Compiler`
- the `.render` method was renamed to `.compile`
