Fix Wikipedia link by escaping parens

Fix Wikipedia link by escaping parens

Docco
=====

**Docco** is a quick-and-dirty documentation generator, written in
[Literate CoffeeScript](http://coffeescript.org/#literate).
It produces an HTML document that displays your comments intermingled with your
code. All prose is passed through
[Markdown](http://daringfireball.net/projects/markdown/syntax), and code is
passed through [Highlight.js](http://highlightjs.org/) syntax highlighting.
This page is the result of running Docco against its own
[source file](https://github.com/jashkenas/docco/blob/master/docco.litcoffee).

1. Install Docco with **npm**: `sudo npm install -g docco`

2. Run it against your code: `docco src/*.coffee`

There is no "Step 3". This will generate an HTML page for each of the named
source files, with a menu linking to the other pages, saving the whole mess
into a `docs` folder (configurable).

The [Docco source](http://github.com/jashkenas/docco) is available on GitHub,
and is released under the [MIT license](http://opensource.org/licenses/MIT).

Docco can be used to process code written in any programming language. If it
doesn't handle your favorite yet, feel free to
[add it to the list](https://github.com/jashkenas/docco/blob/master/resources/languages.json).
Finally, the ["literate" style](http://coffeescript.org/#literate) of *any*
language is also supported — just tack an `.md` extension on the end:
`.coffee.md`, `.py.md`, and so on.

Partners in Crime:
------------------

* If Node.js doesn't run on your platform, or you'd prefer a more
convenient package, get [Ryan Tomayko](http://github.com/rtomayko)'s
[Rocco](http://rtomayko.github.com/rocco/rocco.html), the **Ruby** port that's
available as a gem.

* If you're writing shell scripts, try
[Shocco](http://rtomayko.github.com/shocco/), a port for the **POSIX shell**,
also by Mr. Tomayko.

* If **Python** is more your speed, take a look at
[Nick Fitzgerald](http://github.com/fitzgen)'s [Pycco](http://fitzgen.github.com/pycco/).

* For **Clojure** fans, [Fogus](http://blog.fogus.me/)'s
[Marginalia](http://fogus.me/fun/marginalia/) is a bit of a departure from
"quick-and-dirty", but it'll get the job done.

* There's a **Go** port called [Gocco](http://nikhilm.github.com/gocco/),
written by [Nikhil Marathe](https://github.com/nikhilm).

* Your all you **PHP** buffs out there, Fredi Bach's
[sourceMakeup](http://jquery-jkit.com/sourcemakeup/) (we'll let the faux pas
with respect to our naming scheme slide), should do the trick nicely.

* **Lua** enthusiasts can get their fix with
[Robert Gieseke](https://github.com/rgieseke)'s [Locco](http://rgieseke.github.com/locco/).

* And if you happen to be a **.NET**
aficionado, check out [Don Wilson](https://github.com/dontangg)'s
[Nocco](http://dontangg.github.com/nocco/).

* Going further afield from the quick-and-dirty, [Groc](http://nevir.github.com/groc/)
is a **CoffeeScript** fork of Docco that adds a searchable table of contents,
and aims to gracefully handle large projects with complex hierarchies of code.

Note that not all ports will support all Docco features ... yet.

Main Documentation Generation Functions
---------------------------------------

Generate the documentation for our configured source file by copying over static
assets, reading all the source files in, splitting them up into prose+code
sections, highlighting each file in the appropriate language, and printing them
out in an HTML template.

    document = (options = {}, callback) ->
      config = configure options

      fs.mkdirs config.output, ->

        callback or= (error) -> throw error if error
        copyAsset  = (file, callback) ->
          fs.copy file, path.join(config.output, path.basename(file)), callback
        complete   = ->
          copyAsset config.css, (error) ->
            if error then callback error
            else if fs.existsSync config.public then copyAsset config.public, callback
            else callback()

        files = config.sources.slice()

        nextFile = ->
          source = files.shift()
          fs.readFile source, (error, buffer) ->
            return callback error if error

            code = buffer.toString()
            sections = parse source, code, config
            format source, sections, config
            write source, sections, config
            if files.length then nextFile() else complete()

        nextFile()

Given a string of source code, **parse** out each block of prose and the code that
follows it — by detecting which is which, line by line — and then create an
individual **section** for it. Each section is an object with `docsText` and
`codeText` properties, and eventually `docsHtml` and `codeHtml` as well.

    parse = (source, code, config = {}) ->
      lines    = code.split '\n'
      sections = []
      lang     = getLanguage source, config
      hasCode  = docsText = codeText = ''

      save = ->
        sections.push {docsText, codeText}
        hasCode = docsText = codeText = ''

Our quick-and-dirty implementation of the literate programming style. Simply
invert the prose and code relationship on a per-line basis, and then continue as
normal below.

      if lang.literate
        for line, i in lines
          lines[i] = if /^\s*$/.test line
            ''
          else if match = (/^([ ]{4}|\t)/).exec line
            line[match[0].length..]
          else
            lang.symbol + ' ' + line

      for line in lines
        if line.match(lang.commentMatcher) and not line.match(lang.commentFilter)
          save() if hasCode
          docsText += (line = line.replace(lang.commentMatcher, '')) + '\n'
          save() if /^(---+|===+)$/.test line
          prev = 'text'
        else
          hasCode = yes
          codeText += line + '\n'
          prev = 'code'
      save()

      sections

To **format** and highlight the now-parsed sections of code, we use **Highlight.js**
over stdio, and run the text of their corresponding comments through
**Markdown**, using [Marked](https://github.com/chjj/marked).

    format = (source, sections, config) ->
      language = getLanguage source, config
      for section, i in sections
        code = highlight(language.name, section.codeText).value
        code = code.replace(/\s+$/, '')
        section.codeHtml = "

#{code}

"
        section.docsHtml = marked(section.docsText)

Once all of the code has finished highlighting, we can **write** the resulting
documentation file by passing the completed HTML sections into the template,
and rendering it to the specified output path.

    write = (source, sections, config) ->

      destination = (file) ->
        path.join(config.output, path.basename(file, path.extname(file)) + '.html')

The **title** of the file is either the first heading in the prose, or the
name of the source file.

      first = marked.lexer(sections[0].docsText)[0]
      hasTitle = first and first.type is 'heading' and first.depth is 1
      title = if hasTitle then first.text else path.basename source

      html = config.template {sources: config.sources, css: path.basename(config.css),
        title, hasTitle, sections, path, destination,}

      console.log "docco: #{source} -> #{destination source}"
      fs.writeFileSync destination(source), html

Configuration
-------------

Default configuration **options**. All of these may be extended by
user-specified options.

    defaults =
      layout:     'parallel'
      output:     'docs'
      template:   null
      css:        null
      extension:  null

**Configure** this particular run of Docco. We might use a passed-in external
template, or one of the built-in **layouts**. We only attempt to process
source files for languages for which we have definitions.

    configure = (options) ->
      config = _.extend {}, defaults, _.pick(options, _.keys(defaults)...)

      if options.template
        config.layout = null
      else
        dir = config.layout = path.join __dirname, 'resources', config.layout
        config.public       = path.join dir, 'public' if fs.existsSync path.join dir, 'public'
        config.template     = path.join dir, 'docco.jst'
        config.css          = options.css or path.join dir, 'docco.css'
      config.template = _.template fs.readFileSync(config.template).toString()

      config.sources = options.args.filter((source) ->
        lang = getLanguage source, config
        console.warn "docco: skipped unknown type (#{path.basename source})" unless lang
        lang
      ).sort()

      config

Helpers & Initial Setup
-----------------------

Require our external dependencies.

    _           = require 'underscore'
    fs          = require 'fs-extra'
    path        = require 'path'
    marked      = require 'marked'
    commander   = require 'commander'
    {highlight} = require 'highlight.js'

Languages are stored in JSON in the file `resources/languages.json`.
Each item maps the file extension to the name of the language and the
`symbol` that indicates a line comment. To add support for a new programming
language to Docco, just add it to the file.

    languages = JSON.parse fs.readFileSync(path.join(__dirname, 'resources', 'languages.json'))

Build out the appropriate matchers and delimiters for each language.

    for ext, l of languages

Does the line begin with a comment?

      l.commentMatcher = ///^\s*#{l.symbol}\s?///

Ignore [hashbangs](http://en.wikipedia.org/wiki/Shebang_%28Unix%29) and interpolations...

      l.commentFilter = /(^#![/]|^\s*#\{)/

A function to get the current language we're documenting, based on the
file extension. Detect and tag "literate" `.ext.md` variants.

    getLanguage = (source, config) ->
      ext  = config.extension or path.extname(source) or path.basename(source)
      lang = languages[ext]
      if lang and lang.name is 'markdown'
        codeExt = path.extname(path.basename(source, ext))
        if codeExt and codeLang = languages[codeExt]
          lang = _.extend {}, codeLang, {literate: yes}
      lang

Keep it DRY. Extract the docco **version** from `package.json`

    version = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'))).version

Command Line Interface
----------------------

Finally, let's define the interface to run Docco from the command line.
Parse options using [Commander](https://github.com/visionmedia/commander.js).

    run = (args = process.argv) ->
      c = defaults
      commander.version(version)
        .usage('[options] files')
        .option('-l, --layout [name]',    'choose a layout (parallel, linear or classic)', c.layout)
        .option('-o, --output [path]',    'output to a given folder', c.output)
        .option('-c, --css [file]',       'use a custom css file', c.css)
        .option('-t, --template [file]',  'use a custom .jst template', c.template)
        .option('-e, --extension [ext]',  'assume a file extension for all inputs', c.extension)
        .parse(args)
        .name = "docco"
      if commander.args.length
        document commander
      else
        console.log commander.helpInformation()

Public API
----------

    Docco = module.exports = {run, document, parse, version}

Docco
=====

**Docco** is a quick-and-dirty documentation generator, written in
[Literate CoffeeScript](http://coffeescript.org/#literate).
It produces an HTML document that displays your comments intermingled with your
code. All prose is passed through
[Markdown](http://daringfireball.net/projects/markdown/syntax), and code is
passed through [Highlight.js](http://highlightjs.org/) syntax highlighting.
This page is the result of running Docco against its own
[source file](https://github.com/jashkenas/docco/blob/master/docco.litcoffee).

1. Install Docco with **npm**: `sudo npm install -g docco`

2. Run it against your code: `docco src/*.coffee`

There is no "Step 3". This will generate an HTML page for each of the named
source files, with a menu linking to the other pages, saving the whole mess
into a `docs` folder (configurable).

The [Docco source](http://github.com/jashkenas/docco) is available on GitHub,
and is released under the [MIT license](http://opensource.org/licenses/MIT).

Docco can be used to process code written in any programming language. If it
doesn't handle your favorite yet, feel free to
[add it to the list](https://github.com/jashkenas/docco/blob/master/resources/languages.json).
Finally, the ["literate" style](http://coffeescript.org/#literate) of *any*
language is also supported — just tack an `.md` extension on the end:
`.coffee.md`, `.py.md`, and so on.

Partners in Crime:
------------------

* If Node.js doesn't run on your platform, or you'd prefer a more
convenient package, get [Ryan Tomayko](http://github.com/rtomayko)'s
[Rocco](http://rtomayko.github.com/rocco/rocco.html), the **Ruby** port that's
available as a gem.

* If you're writing shell scripts, try
[Shocco](http://rtomayko.github.com/shocco/), a port for the **POSIX shell**,
also by Mr. Tomayko.

* If **Python** is more your speed, take a look at
[Nick Fitzgerald](http://github.com/fitzgen)'s [Pycco](http://fitzgen.github.com/pycco/).

* For **Clojure** fans, [Fogus](http://blog.fogus.me/)'s
[Marginalia](http://fogus.me/fun/marginalia/) is a bit of a departure from
"quick-and-dirty", but it'll get the job done.

* There's a **Go** port called [Gocco](http://nikhilm.github.com/gocco/),
written by [Nikhil Marathe](https://github.com/nikhilm).

* Your all you **PHP** buffs out there, Fredi Bach's
[sourceMakeup](http://jquery-jkit.com/sourcemakeup/) (we'll let the faux pas
with respect to our naming scheme slide), should do the trick nicely.

* **Lua** enthusiasts can get their fix with
[Robert Gieseke](https://github.com/rgieseke)'s [Locco](http://rgieseke.github.com/locco/).

* And if you happen to be a **.NET**
aficionado, check out [Don Wilson](https://github.com/dontangg)'s
[Nocco](http://dontangg.github.com/nocco/).

* Going further afield from the quick-and-dirty, [Groc](http://nevir.github.com/groc/)
is a **CoffeeScript** fork of Docco that adds a searchable table of contents,
and aims to gracefully handle large projects with complex hierarchies of code.

Note that not all ports will support all Docco features ... yet.

Main Documentation Generation Functions
---------------------------------------

Generate the documentation for our configured source file by copying over static
assets, reading all the source files in, splitting them up into prose+code
sections, highlighting each file in the appropriate language, and printing them
out in an HTML template.

    document = (options = {}, callback) ->
      config = configure options

      fs.mkdirs config.output, ->

        callback or= (error) -> throw error if error
        copyAsset  = (file, callback) ->
          fs.copy file, path.join(config.output, path.basename(file)), callback
        complete   = ->
          copyAsset config.css, (error) ->
            if error then callback error
            else if fs.existsSync config.public then copyAsset config.public, callback
            else callback()

        files = config.sources.slice()

        nextFile = ->
          source = files.shift()
          fs.readFile source, (error, buffer) ->
            return callback error if error

            code = buffer.toString()
            sections = parse source, code, config
            format source, sections, config
            write source, sections, config
            if files.length then nextFile() else complete()

        nextFile()

Given a string of source code, **parse** out each block of prose and the code that
follows it — by detecting which is which, line by line — and then create an
individual **section** for it. Each section is an object with `docsText` and
`codeText` properties, and eventually `docsHtml` and `codeHtml` as well.

    parse = (source, code, config = {}) ->
      lines    = code.split '\n'
      sections = []
      lang     = getLanguage source, config
      hasCode  = docsText = codeText = ''

      save = ->
        sections.push {docsText, codeText}
        hasCode = docsText = codeText = ''

Our quick-and-dirty implementation of the literate programming style. Simply
invert the prose and code relationship on a per-line basis, and then continue as
normal below.

      if lang.literate
        for line, i in lines
          lines[i] = if /^\s*$/.test line
            ''
          else if match = (/^([ ]{4}|\t)/).exec line
            line[match[0].length..]
          else
            lang.symbol + ' ' + line

      for line in lines
        if line.match(lang.commentMatcher) and not line.match(lang.commentFilter)
          save() if hasCode
          docsText += (line = line.replace(lang.commentMatcher, '')) + '\n'
          save() if /^(---+|===+)$/.test line
          prev = 'text'
        else
          hasCode = yes
          codeText += line + '\n'
          prev = 'code'
      save()

      sections

To **format** and highlight the now-parsed sections of code, we use **Highlight.js**
over stdio, and run the text of their corresponding comments through
**Markdown**, using [Marked](https://github.com/chjj/marked).

    format = (source, sections, config) ->
      language = getLanguage source, config
      for section, i in sections
        code = highlight(language.name, section.codeText).value
        code = code.replace(/\s+$/, '')
        section.codeHtml = "

#{code}

"
        section.docsHtml = marked(section.docsText)

Once all of the code has finished highlighting, we can **write** the resulting
documentation file by passing the completed HTML sections into the template,
and rendering it to the specified output path.

    write = (source, sections, config) ->

      destination = (file) ->
        path.join(config.output, path.basename(file, path.extname(file)) + '.html')

The **title** of the file is either the first heading in the prose, or the
name of the source file.

      first = marked.lexer(sections[0].docsText)[0]
      hasTitle = first and first.type is 'heading' and first.depth is 1
      title = if hasTitle then first.text else path.basename source

      html = config.template {sources: config.sources, css: path.basename(config.css),
        title, hasTitle, sections, path, destination,}

      console.log "docco: #{source} -> #{destination source}"
      fs.writeFileSync destination(source), html

Configuration
-------------

Default configuration **options**. All of these may be extended by
user-specified options.

    defaults =
      layout:     'parallel'
      output:     'docs'
      template:   null
      css:        null
      extension:  null

**Configure** this particular run of Docco. We might use a passed-in external
template, or one of the built-in **layouts**. We only attempt to process
source files for languages for which we have definitions.

    configure = (options) ->
      config = _.extend {}, defaults, _.pick(options, _.keys(defaults)...)

      if options.template
        config.layout = null
      else
        dir = config.layout = path.join __dirname, 'resources', config.layout
        config.public       = path.join dir, 'public' if fs.existsSync path.join dir, 'public'
        config.template     = path.join dir, 'docco.jst'
        config.css          = options.css or path.join dir, 'docco.css'
      config.template = _.template fs.readFileSync(config.template).toString()

      config.sources = options.args.filter((source) ->
        lang = getLanguage source, config
        console.warn "docco: skipped unknown type (#{path.basename source})" unless lang
        lang
      ).sort()

      config

Helpers & Initial Setup
-----------------------

Require our external dependencies.

    _           = require 'underscore'
    fs          = require 'fs-extra'
    path        = require 'path'
    marked      = require 'marked'
    commander   = require 'commander'
    {highlight} = require 'highlight.js'

Languages are stored in JSON in the file `resources/languages.json`.
Each item maps the file extension to the name of the language and the
`symbol` that indicates a line comment. To add support for a new programming
language to Docco, just add it to the file.

    languages = JSON.parse fs.readFileSync(path.join(__dirname, 'resources', 'languages.json'))

Build out the appropriate matchers and delimiters for each language.

    for ext, l of languages

Does the line begin with a comment?

      l.commentMatcher = ///^\s*#{l.symbol}\s?///

Ignore [hashbangs](http://en.wikipedia.org/wiki/Shebang_(Unix\)) and interpolations...

      l.commentFilter = /(^#![/]|^\s*#\{)/

A function to get the current language we're documenting, based on the
file extension. Detect and tag "literate" `.ext.md` variants.

    getLanguage = (source, config) ->
      ext  = config.extension or path.extname(source) or path.basename(source)
      lang = languages[ext]
      if lang and lang.name is 'markdown'
        codeExt = path.extname(path.basename(source, ext))
        if codeExt and codeLang = languages[codeExt]
          lang = _.extend {}, codeLang, {literate: yes}
      lang

Keep it DRY. Extract the docco **version** from `package.json`

    version = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'))).version

Command Line Interface
----------------------

Finally, let's define the interface to run Docco from the command line.
Parse options using [Commander](https://github.com/visionmedia/commander.js).

    run = (args = process.argv) ->
      c = defaults
      commander.version(version)
        .usage('[options] files')
        .option('-l, --layout [name]',    'choose a layout (parallel, linear or classic)', c.layout)
        .option('-o, --output [path]',    'output to a given folder', c.output)
        .option('-c, --css [file]',       'use a custom css file', c.css)
        .option('-t, --template [file]',  'use a custom .jst template', c.template)
        .option('-e, --extension [ext]',  'assume a file extension for all inputs', c.extension)
        .parse(args)
        .name = "docco"
      if commander.args.length
        document commander
      else
        console.log commander.helpInformation()

Public API
----------

    Docco = module.exports = {run, document, parse, version}


Disable cache by default.

Disable cache by default.

# Configuration

GLP is configured using a specific grammar for explaining how to build a gulp
project. This grammar allows you to easily explain both simple and complicated
build processes in a single configuration file.

The file should be named **glp.yml** and can be placed in your project's root
directory, or it can be placed in an `etc` directory if preferred. You can
also include the configuration in your standard user-level or system-wide
configuration directories.

This document aims to provide a descriptive explanation of all configuration
and best practices for configuration options available to users of GLP.

GLP configuration options can be split up into the following high level
categories:

- **root** tells GLP where to place it's output files.
- **files** with *named groups* and where to find them
- **filters** for introducing new ways to transform files in *file group*
- **plugins** options for changing the way that glp uses them for each *file group*
- **concatenators** for defining which plugins are used for joining files in a *file group*
- **minifiers** for changing how a *file group* is minified
- **extensions** for defining the suffix of output files for each *file group*.
- **liveReload** options for defining changes affect your browser after compiling.
- **static** options for defining routing of built files to a local web server
- **tasks** to overlay different groupings of options based on command-line arguments

The following document will walk you step-by-step through GLP's default
configuration. It should help increase familiarity with all features, and how
to get started with building your own software using GLP and your favorite
programming languages.

## How GLP configuration works

This is a `.litcoffee` file, so we will be using the default configuration as a
practical example of what you can do when writing a configuration file. The
documented values are exactly what is exported to the compiler in GLP.

    module.exports =

These defaults are always overridden with any user-specific settings. When a
configuration file is loaded, GLP will run [lodash.merge][lodashmerge] in order
to merge the user's configuration data over the defaults. Once this is done,
the current *task* is merged in order to define commands which change behavior.

The one exception to this rule is the *files* option, which will be completely
overriden if provided by a user instead of being merged into the default
configuration. The *files* option will still be merged (instead of replaced) if
modified by *tasks*.

Don't  feel discouraged if this seems confusing. It will make more sense as you
read through this document and develop a better understanding of GLP's options.

# Options

## root

This should be a string that contains the name of the directory where you would
like GLP to put build output files.

      root: 'public'

## watch

This should be a boolean. When true, GLP will continue watching for changes to
files after tasks finish. Otherwise, it will not watch for any changes to files.

      watch: no

## debug

If this is set to true, then GLP will provide you with an exhaustive amount of
information describing the build process.

      debug: no

## globOptions

This can be an object which describes the options that should be passed to the
`gulp,watch` and `gulp.src` functions. The keys of the object should be the
name of the task that the options are used with. The value for each task should
be the options as [documented here][gulpsrcopts]. If no options are defined for
the currently active task, then the 'default' options will be used.

      globOptions:
        default:
          options: {}

## cache

Options for controlling how GLP caches files for faster compiling while watching
files for changes.

      cache:

The `cache.enabled` option is false by default, but can be made true if caching
happens to be working as expected with your project. This feature is disabled
by default because it is still experimental.

        enabled: no

## minify

Options for controlling how GLP minifies files.

      minify:

The `minify.enabled` option is false by default. You can set it to true
if you would like to minify built files.

        enabled: no

The `minify.extension` option  can be changed if you'd like to use a custom
prefix extension. For instance, files with the extension **.js** will be
converted to **.min.js** when minification is turned on. If you set
`minify.extension` to an empty string, it will then be converted into.

        extension: '.min'

## ordering

Ordering is disabled by default, but if ordering looks wrong (this shouldn't
ever happen) then you can use this in order to map specific file types to the
ordering you'd want the files to be in. This supports the globbing same format
which is supported by `gulp.src` and `gulp.watch` which is more thoroughly
[documented here][gulpsrcopts].

      ordering: {}

## plugins

The plugins option allows users to define options for gulp all plugins which
are used in the build process. In order to do this, you provide an object
where plugin names are *keys* and the options object is what will be passed
to the related gulp plugin.

Whenever referring to gulp plugins in GLP, you can optionally omit the `gulp-`
prefix. For instance, telling GLP to use a plugin called *cached* is the same
as telling it to use *gulp-cached*. The plugins are standard gulp plugins, so
any standard gulp plugin should work with GLP.

GLP has verify flexible support for easily configuring plugins to be used
through gulp, and tries to be as transparent as possible without sacrificing
usability in the process.

      plugins:

By default, we ask the [gulp-cached][gulpcached] plugin to optimize memory by
storing the files as MD5 instead of the entire file contents.

        cached:
          optimizeMemory: yes

We also want [gulp-uglify][gulpuglify] to output source maps.

        uglify:
          outSourceMap: yes

And while we're developing, we want our templates to be readable. So, we tell
jade to render pretty files instead of spitting them out in a single line.

        jade:
          pretty: yes

The options provided here can also be overridden per-file-type with the
*filters* option as described in the next section. Every setting can be
overriden on a per-task basis as well. This means that we can tell GLP to not
output source maps, pretty templates, or any other option via the *tasks*
option as will also be defined later.

## filters

It's important to remember that you can use any gulp plugin with GLP by
installing it into your project with [npm][npm]. In order to let users define
arbitrary ways of transforming files, we have filters.

The *filters* option provide a way to transform file contents for different
types of files. Each type of file can be given a number of filters which can
be passed through by defining them with this option.

      filters:

For instance, scripts can be compiled as *coffee*. This example is the least
verbose way to define a new filter. Since an empty settings object is being
mapped to the *coffee* type, GLP will automatically transform using a plugin
called [gulp-coffee][gulpcoffee] and match this plugin against a glob which
will automatically be generated with the filter name. In this case, the glob
pattern would be `\*\*/\*.coffee`.

It's worth noting here that you can install **any** gulp plugin into your
project, and GLP will support it when you just add a new filter option for it.

It is possible that the most powerful feature of GLP is it's ability to let you
configure it for any type of file without needing to touch any source code in
the process. This configuration file is all that you will need.

        scripts:
          coffee: {}

Scripts can also be compiled from jade templates. Since we have grouped
filters with the *scripts* file group, we also know that we want the compiled
files to become scripts in the end. So, we can use the `options` key to
forward options to [gulp-jade][gulpjade] in this case.

          jade:
            options:
              client: true

For the stylesheets group, we set up *sass* and *less* so that they will be
bound to files with matching extensions. We have no special options in these
cases, so we can just assign an empty object to them and let GLP assign
defaults as described before.

        stylesheets:
          sass: {}
          less: {}

There are more specific cases for stylus, though. We want to use the
[gulp-stylus][gulpstylus] module and match it against both *.styl* and
*.stylus* file extensions. A more specific case is that we also want to use the
'nib' module by default, but still allow users to override that choice with the
global *plugins* option. That's what the *hints* option is for.

By default, the *options* in a filter override global *plugins* options. The
*hints* option provides the opposite, where the *plugins* options act as an
override. This isn't an extremely useful feature, but it's helpful here for
users that might not want to use *nib* with their stylus files. They could just
set `use` to an empty array in the *plugins* option to prevent it.

          stylus:
            transforms: 'stylus'

            hints:
              use: ['nib']

            matches: [
              '**/*.styl'
              '**/*.stylus'
            ]

Here we redefine jade, but this time we are defining it as a template. The
reason that we have to define this twice is because we want to give different
options to [gulp-jade][gulpjade] for templates instead of scripts. This allows
us to render *templates* as *HTML* files, but jade files in *scripts* will be
rendered as *js* files as  described previously.

        templates:
          jade:
            options:
              client: false

## concatenators

If you need to use custom concatenation rules, you can define them here. This
can be set to an object which maps types of files to a plugin name. It can also
be set to an array if you need to use multiple concatenators. They will be
streamed through plugins in the order that they are provided.

When a plugin isn't defined in the *concatenators* option for a specific type,
GLP will set it to 'concat' as the default value. GLP will automatically prefix
plugin names with *gulp-*, so you don't need to do that. So, the default
concatenator could be found in [NPM][npm] as [gulp-concat][gulpconcat]

As an example use case, some users might want to compile all of their scripts
to [gulp-commonjs][gulpcommonjs] files and then pass the commonjs output to
[gulp-concat][gulpconcat] afterward. That could be done simply by adding a new
key to *concatenators*, such as: `scripts: ['commonjs', 'concat']` followed by
installing the necessary NPM plugins in your project directory.

      concatenators: {}

## extensions

      extensions:
        scripts: 'js'
        stylesheets: 'css'
        templates: 'html'

## minifiers

The minifiers option tells GLP how to minify files with different file
extensions. As an example, the default would use the [gulp-uglify][gulpuglify]
plugin for *js* files, and the [gulp-minify-css][gulpminifycss] plugin for css
files.

      minifiers:
        js: 'uglify'
        css: 'minify-css'

## files

Options for defining what types of files exist, where they are located, and
where they are placed after they have finished being built. The default
configuration will build many types of files from a directory called `src`,
and place them into the **root** directory (the default root is *public* as
described above) after they have been built.

      files:

Each type of file that needs built is given a name. The names can be whatever
you like, and any number of named types can be created. For instance, the
following files are called *scripts*:

        scripts:

Each type is an object which maps a path to a list of files. If a path ends
with a slash, then the files will be copied into a **directory** containing
an output file for every source file that was built. If the path does not
end with a slash, then the  *concatenators* for this type will be used.

In this case, we are building all files ending with `.js` or `.coffee`. After
they are built, the resulting files will be placed in the directory specified
by the **root** function as separate files. If the output file was not a
**directory** (as denoted by the ending slash) then the files would also be
concatenated and the resulting file would be given the *extension* which
corresponds to this type of file.

          '/': [
            'src/**/*.js'
            'src/**/*.coffee'
          ]

Here, we are doing the same thing for *html* and *jade* files, but we are
outputting them with the `templates` file type.

        templates:
          '/': [
            'src/**/*.html'
            'src/**/*.jade'
          ]

We are doing the same thing here but using different files and associating
them to the *stylesheets* file type.

        stylesheets:
          '/': [
            'src/**/*.css'
            'src/**/*.less'
            'src/**/*.sass'
            'src/**/*.stylus'
          ]

## static

GLP can optionally run a static server. If this is enabled, then the path
specified by the *root* option will be server on the provided static server
port.

      static:

The `static.enabled` function can be true or false. If it is true, then glp
will run it's static server. If false, then the server will not be run.

        enabled: no

The `static.directories` option can be set to true if you want to server
directory indexes, but defaults to false in order to prevent accidental
exposure of file listenings.

        directories: no

The `static.catchAll` option can be set to a string containing a filename. If
set, then all URLs that don't have a static file ready on the server will be
redirected to the given filename. This allows HTML5-style routing without
needing to define every possible route through GLP.

        catchAll: null

The `static.port` option tells GLP what port to serve it's static server on. By
default, the [local server][localserver] will be on port `3333`.

        port: 3333

**NOTE:** Remember that the *watch* option is separated from the *static*
option, so that glp's static server isn't limited to only development
environments.  If *watch* is set to false, then the server will not reflect
your changes until the next time you rebuild the files being served.

## liveReload

The `liveReload` options allow you to change the way that your browser responds
when files are changed.

      liveReload:

You can enable or disable liveReload by setting the `liveReload.enabled` option
to true, or disable it with a value of false.

        enabled: no

You can set the `liveReload.port` to whichever port you want the `liveReload`
server to be listening on if the default value of 35729 is not sufficient.

        port: 35729

If you have `liveReload.enabled` set to a truthy value, you're using the GLP
static server, and you set `liveReload.inject` to a truthy value, then GLP will
automatically inject *livereload.js* into the app from within the static
server. This means that you don't need to change your templates or install any
browser addons in order to get instant feedback of changes in your browser.

        inject: yes

## tasks

Every action in GLP is ran via a *task*. For instance, when you run `glp` you
are actually running the *default* task. This can also be ran with the `glp
default` command if you feel like typing extra. GLP allows you to define any
arbitrary task that you would like.

All tasks can optionally be set to a configuration object. When a configuration
option is provided for a task *it will override* the previously defined
options. Some examples:

      tasks:

You could define a task that is exactly the same as the default task by
providing no option overrides, for instance. This is how the default task
is defined:

        default: {}

You could also request GLP to watch all of your files by overriding the *watch*
option and setting it to yes. This is how the `glp watch` command works:

        watch:
          watch: yes

You could extend this even further by watching files *and* running a static
server with liveReload enabled. Under the hood, this is how the `glp server`
command works:

        server:
          watch: yes

          static:
            enabled: yes

          liveReload:
            enabled: yes

Maybe you don't want to run any servers or watch any files, but you may still
like to make sure that a specific build process outputs it's files in a
different way. This is exactly how `glp release` works:

        release:
          minify:
            enabled: yes

          plugins:
            uglify:
              outSourceMap: no

            jade:
              pretty: no

[npm]: https://www.npmjs.org/
[gulpsrcopts]: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpsrcglobs-options
[gulpcoffee]: https://www.npmjs.org/package/gulp-coffee
[gulpjade]: https://www.npmjs.org/package/gulp-jade
[gulpstylus]: https://www.npmjs.org/package/gulp-stylus
[gulpconcat]: https://github.com/wearefractal/gulp-concat
[gulpuglify]: https://www.npmjs.org/package/gulp-uglify
[gulpminifycss]: https://www.npmjs.org/package/gulp-minify-css
[gulpcached]: https://www.npmjs.org/package/gulp-cached
[localserver]: http://localhost:3333/
[lodashmerge]: http://lodash.com/docs#merge

# Configuration

GLP is configured using a specific grammar for explaining how to build a gulp
project. This grammar allows you to easily explain both simple and complicated
build processes in a single configuration file.

The file should be named **glp.yml** and can be placed in your project's root
directory, or it can be placed in an `etc` directory if preferred. You can
also include the configuration in your standard user-level or system-wide
configuration directories.

This document aims to provide a descriptive explanation of all configuration
and best practices for configuration options available to users of GLP.

GLP configuration options can be split up into the following high level
categories:

- **root** tells GLP where to place it's output files.
- **files** with *named groups* and where to find them
- **filters** for introducing new ways to transform files in *file group*
- **plugins** options for changing the way that glp uses them for each *file group*
- **concatenators** for defining which plugins are used for joining files in a *file group*
- **minifiers** for changing how a *file group* is minified
- **extensions** for defining the suffix of output files for each *file group*.
- **liveReload** options for defining changes affect your browser after compiling.
- **static** options for defining routing of built files to a local web server
- **tasks** to overlay different groupings of options based on command-line arguments

The following document will walk you step-by-step through GLP's default
configuration. It should help increase familiarity with all features, and how
to get started with building your own software using GLP and your favorite
programming languages.

## How GLP configuration works

This is a `.litcoffee` file, so we will be using the default configuration as a
practical example of what you can do when writing a configuration file. The
documented values are exactly what is exported to the compiler in GLP.

    module.exports =

These defaults are always overridden with any user-specific settings. When a
configuration file is loaded, GLP will run [lodash.merge][lodashmerge] in order
to merge the user's configuration data over the defaults. Once this is done,
the current *task* is merged in order to define commands which change behavior.

The one exception to this rule is the *files* option, which will be completely
overriden if provided by a user instead of being merged into the default
configuration. The *files* option will still be merged (instead of replaced) if
modified by *tasks*.

Don't  feel discouraged if this seems confusing. It will make more sense as you
read through this document and develop a better understanding of GLP's options.

# Options

## root

This should be a string that contains the name of the directory where you would
like GLP to put build output files.

      root: 'public'

## watch

This should be a boolean. When true, GLP will continue watching for changes to
files after tasks finish. Otherwise, it will not watch for any changes to files.

      watch: no

## debug

If this is set to true, then GLP will provide you with an exhaustive amount of
information describing the build process.

      debug: no

## globOptions

This can be an object which describes the options that should be passed to the
`gulp,watch` and `gulp.src` functions. The keys of the object should be the
name of the task that the options are used with. The value for each task should
be the options as [documented here][gulpsrcopts]. If no options are defined for
the currently active task, then the 'default' options will be used.

      globOptions:
        default:
          options: {}

## cache

Options for controlling how GLP caches files for faster compiling while watching
files for changes.

      cache:

The `cache.enabled` option is true by default, but can be made false if
caching isn't working as expected with your project.

        enabled: yes

## minify

Options for controlling how GLP minifies files.

      minify:

The `minify.enabled` option is false by default. You can set it to true
if you would like to minify built files.

        enabled: no

The `minify.extension` option  can be changed if you'd like to use a custom
prefix extension. For instance, files with the extension **.js** will be
converted to **.min.js** when minification is turned on. If you set
`minify.extension` to an empty string, it will then be converted into.

        extension: '.min'

## ordering

Ordering is disabled by default, but if ordering looks wrong (this shouldn't
ever happen) then you can use this in order to map specific file types to the
ordering you'd want the files to be in. This supports the globbing same format
which is supported by `gulp.src` and `gulp.watch` which is more thoroughly
[documented here][gulpsrcopts].

      ordering: {}

## plugins

The plugins option allows users to define options for gulp all plugins which
are used in the build process. In order to do this, you provide an object
where plugin names are *keys* and the options object is what will be passed
to the related gulp plugin.

Whenever referring to gulp plugins in GLP, you can optionally omit the `gulp-`
prefix. For instance, telling GLP to use a plugin called *cached* is the same
as telling it to use *gulp-cached*. The plugins are standard gulp plugins, so
any standard gulp plugin should work with GLP.

GLP has verify flexible support for easily configuring plugins to be used
through gulp, and tries to be as transparent as possible without sacrificing
usability in the process.

      plugins:

By default, we ask the [gulp-cached][gulpcached] plugin to optimize memory by
storing the files as MD5 instead of the entire file contents.

        cached:
          optimizeMemory: yes

We also want [gulp-uglify][gulpuglify] to output source maps.

        uglify:
          outSourceMap: yes

And while we're developing, we want our templates to be readable. So, we tell
jade to render pretty files instead of spitting them out in a single line.

        jade:
          pretty: yes

The options provided here can also be overridden per-file-type with the
*filters* option as described in the next section. Every setting can be
overriden on a per-task basis as well. This means that we can tell GLP to not
output source maps, pretty templates, or any other option via the *tasks*
option as will also be defined later.

## filters

It's important to remember that you can use any gulp plugin with GLP by
installing it into your project with [npm][npm]. In order to let users define
arbitrary ways of transforming files, we have filters.

The *filters* option provide a way to transform file contents for different
types of files. Each type of file can be given a number of filters which can
be passed through by defining them with this option.

      filters:

For instance, scripts can be compiled as *coffee*. This example is the least
verbose way to define a new filter. Since an empty settings object is being
mapped to the *coffee* type, GLP will automatically transform using a plugin
called [gulp-coffee][gulpcoffee] and match this plugin against a glob which
will automatically be generated with the filter name. In this case, the glob
pattern would be `\*\*/\*.coffee`.

It's worth noting here that you can install **any** gulp plugin into your
project, and GLP will support it when you just add a new filter option for it.

It is possible that the most powerful feature of GLP is it's ability to let you
configure it for any type of file without needing to touch any source code in
the process. This configuration file is all that you will need.

        scripts:
          coffee: {}

Scripts can also be compiled from jade templates. Since we have grouped
filters with the *scripts* file group, we also know that we want the compiled
files to become scripts in the end. So, we can use the `options` key to
forward options to [gulp-jade][gulpjade] in this case.

          jade:
            options:
              client: true

For the stylesheets group, we set up *sass* and *less* so that they will be
bound to files with matching extensions. We have no special options in these
cases, so we can just assign an empty object to them and let GLP assign
defaults as described before.

        stylesheets:
          sass: {}
          less: {}

There are more specific cases for stylus, though. We want to use the
[gulp-stylus][gulpstylus] module and match it against both *.styl* and
*.stylus* file extensions. A more specific case is that we also want to use the
'nib' module by default, but still allow users to override that choice with the
global *plugins* option. That's what the *hints* option is for.

By default, the *options* in a filter override global *plugins* options. The
*hints* option provides the opposite, where the *plugins* options act as an
override. This isn't an extremely useful feature, but it's helpful here for
users that might not want to use *nib* with their stylus files. They could just
set `use` to an empty array in the *plugins* option to prevent it.

          stylus:
            transforms: 'stylus'

            hints:
              use: ['nib']

            matches: [
              '**/*.styl'
              '**/*.stylus'
            ]

Here we redefine jade, but this time we are defining it as a template. The
reason that we have to define this twice is because we want to give different
options to [gulp-jade][gulpjade] for templates instead of scripts. This allows
us to render *templates* as *HTML* files, but jade files in *scripts* will be
rendered as *js* files as  described previously.

        templates:
          jade:
            options:
              client: false

## concatenators

If you need to use custom concatenation rules, you can define them here. This
can be set to an object which maps types of files to a plugin name. It can also
be set to an array if you need to use multiple concatenators. They will be
streamed through plugins in the order that they are provided.

When a plugin isn't defined in the *concatenators* option for a specific type,
GLP will set it to 'concat' as the default value. GLP will automatically prefix
plugin names with *gulp-*, so you don't need to do that. So, the default
concatenator could be found in [NPM][npm] as [gulp-concat][gulpconcat]

As an example use case, some users might want to compile all of their scripts
to [gulp-commonjs][gulpcommonjs] files and then pass the commonjs output to
[gulp-concat][gulpconcat] afterward. That could be done simply by adding a new
key to *concatenators*, such as: `scripts: ['commonjs', 'concat']` followed by
installing the necessary NPM plugins in your project directory.

      concatenators: {}

## extensions

      extensions:
        scripts: 'js'
        stylesheets: 'css'
        templates: 'html'

## minifiers

The minifiers option tells GLP how to minify files with different file
extensions. As an example, the default would use the [gulp-uglify][gulpuglify]
plugin for *js* files, and the [gulp-minify-css][gulpminifycss] plugin for css
files.

      minifiers:
        js: 'uglify'
        css: 'minify-css'

## files

Options for defining what types of files exist, where they are located, and
where they are placed after they have finished being built. The default
configuration will build many types of files from a directory called `src`,
and place them into the **root** directory (the default root is *public* as
described above) after they have been built.

      files:

Each type of file that needs built is given a name. The names can be whatever
you like, and any number of named types can be created. For instance, the
following files are called *scripts*:

        scripts:

Each type is an object which maps a path to a list of files. If a path ends
with a slash, then the files will be copied into a **directory** containing
an output file for every source file that was built. If the path does not
end with a slash, then the  *concatenators* for this type will be used.

In this case, we are building all files ending with `.js` or `.coffee`. After
they are built, the resulting files will be placed in the directory specified
by the **root** function as separate files. If the output file was not a
**directory** (as denoted by the ending slash) then the files would also be
concatenated and the resulting file would be given the *extension* which
corresponds to this type of file.

          '/': [
            'src/**/*.js'
            'src/**/*.coffee'
          ]

Here, we are doing the same thing for *html* and *jade* files, but we are
outputting them with the `templates` file type.

        templates:
          '/': [
            'src/**/*.html'
            'src/**/*.jade'
          ]

We are doing the same thing here but using different files and associating
them to the *stylesheets* file type.

        stylesheets:
          '/': [
            'src/**/*.css'
            'src/**/*.less'
            'src/**/*.sass'
            'src/**/*.stylus'
          ]

## static

GLP can optionally run a static server. If this is enabled, then the path
specified by the *root* option will be server on the provided static server
port.

      static:

The `static.enabled` function can be true or false. If it is true, then glp
will run it's static server. If false, then the server will not be run.

        enabled: no

The `static.directories` option can be set to true if you want to server
directory indexes, but defaults to false in order to prevent accidental
exposure of file listenings.

        directories: no

The `static.catchAll` option can be set to a string containing a filename. If
set, then all URLs that don't have a static file ready on the server will be
redirected to the given filename. This allows HTML5-style routing without
needing to define every possible route through GLP.

        catchAll: null

The `static.port` option tells GLP what port to serve it's static server on. By
default, the [local server][localserver] will be on port `3333`.

        port: 3333

**NOTE:** Remember that the *watch* option is separated from the *static*
option, so that glp's static server isn't limited to only development
environments.  If *watch* is set to false, then the server will not reflect
your changes until the next time you rebuild the files being served.

## liveReload

The `liveReload` options allow you to change the way that your browser responds
when files are changed.

      liveReload:

You can enable or disable liveReload by setting the `liveReload.enabled` option
to true, or disable it with a value of false.

        enabled: no

You can set the `liveReload.port` to whichever port you want the `liveReload`
server to be listening on if the default value of 35729 is not sufficient.

        port: 35729

If you have `liveReload.enabled` set to a truthy value, you're using the GLP
static server, and you set `liveReload.inject` to a truthy value, then GLP will
automatically inject *livereload.js* into the app from within the static
server. This means that you don't need to change your templates or install any
browser addons in order to get instant feedback of changes in your browser.

        inject: yes

## tasks

Every action in GLP is ran via a *task*. For instance, when you run `glp` you
are actually running the *default* task. This can also be ran with the `glp
default` command if you feel like typing extra. GLP allows you to define any
arbitrary task that you would like.

All tasks can optionally be set to a configuration object. When a configuration
option is provided for a task *it will override* the previously defined
options. Some examples:

      tasks:

You could define a task that is exactly the same as the default task by
providing no option overrides, for instance. This is how the default task
is defined:

        default: {}

You could also request GLP to watch all of your files by overriding the *watch*
option and setting it to yes. This is how the `glp watch` command works:

        watch:
          watch: yes

You could extend this even further by watching files *and* running a static
server with liveReload enabled. Under the hood, this is how the `glp server`
command works:

        server:
          watch: yes

          static:
            enabled: yes

          liveReload:
            enabled: yes

Maybe you don't want to run any servers or watch any files, but you may still
like to make sure that a specific build process outputs it's files in a
different way. This is exactly how `glp release` works:

        release:
          minify:
            enabled: yes

          plugins:
            uglify:
              outSourceMap: no

            jade:
              pretty: no

[npm]: https://www.npmjs.org/
[gulpsrcopts]: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpsrcglobs-options
[gulpcoffee]: https://www.npmjs.org/package/gulp-coffee
[gulpjade]: https://www.npmjs.org/package/gulp-jade
[gulpstylus]: https://www.npmjs.org/package/gulp-stylus
[gulpconcat]: https://github.com/wearefractal/gulp-concat
[gulpuglify]: https://www.npmjs.org/package/gulp-uglify
[gulpminifycss]: https://www.npmjs.org/package/gulp-minify-css
[gulpcached]: https://www.npmjs.org/package/gulp-cached
[localserver]: http://localhost:3333/
[lodashmerge]: http://lodash.com/docs#merge


Move redis require to code

Move redis require to code

    "use strict"

    mongo    = require './db/mongo'
    ObjectID = require('mongodb').ObjectID

## getFilter()

Get data filter for object type.

### Params

* `String` type - object type to get filter for.
* `boolean` preventDefault - prevent default filter switch.

### Return

Returns a `String` key - `boolean` value `Object` where each key represent a
document field. The value determines if they field should be included or not.

Returns an empty `Object` if the `preventDefault` parameter is set to `true` and
no filter was found for the given `type`.

    getFilter = (type, preventDefault) ->

      dataFields =
        default:
          _id       : false
          tilbyder  : true
          endret    : true
          checksum  : true
          status    : true
          navn      : true
          bilder    : true
          grupper   : true

        bilder:
          _id       : false
          tilbyder  : true
          endret    : true
          checksum  : true
          status    : true
          navn      : true

      return dataFields[type] if dataFields[type]
      return {} if preventDefault
      return dataFields.default

## filterData()

Filter data for given type.

### ToDo

* Handle undefined values.

### Params

* `String` type - object type to filter data for.
* `Object` data - data to filter on.

### Return

Returns an `Object` with a subset of the original object containing only the
accepted object properties for the given object type.

    filterData = (type, data) ->
      res = {}
      res[key] = data[key] for key,val of getFilter(type) when val is true and data[key]
      return res

## getDoc()

Get a document from MongoDB for given object type and object id.

This function will automaticly filter object keys according to type in order to
prevent fetching of uncesserary data.

### Params

* `String` type - object type to get document for.
* `String` id - object id for document.
* `function` cb - callback function (`Error` err, `Object` doc).

### Return

No return value or `undefined`.

    getDoc = (type, id, cb) ->
      require('./db/mongo')[type].findOne {_id: new ObjectID(id)}, getFilter(type), cb

## set()

Store data object in Redis for a given cache key.

### Params

* `String` key - cache key to store data for.
* `Object` data - data to store for cache key.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    set = (key, data, cb) ->
      require('./db/redis').hmset key, data, (err) -> cb(err, data)

## get()

Retrive data from cache for given a cache key.

### Params

* `String` key - cache key to get data for.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    get = (key, cb) ->
      require('./db/redis').hgetall key, cb

## setForType()

Store data in Redis for given object type and object id.

This function will automaticly remove object properties from input data in order
to match the object type cache preferences as defined in [#getFilter()](#getFilter).

### Params

* `String` type - object type to set cache data for.
* `String` id - object id to set cache data for.
* `Object` data - data store in cache for type and id.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    setForType = (type, id, data, cb) ->
      set "#{type}:#{id}", filterData(type, data), cb

## getForType()

Get data from Redis for object type and object id.

`NB` This function will return `Arrays` if the document is retrived directly
from MongoDB. `Arrays` stored in Redis will be returned as comma seperated
strings.

### Params

* `String` type - object type to get cache data for.
* `String` id - object id to get cache data for.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    getForType = (type, id, cb) ->
      get "#{type}:#{id}", (err, data) ->
        return cb null, data, true if data

        getDoc type, id, (err, data) ->
          return cb err, null, false if err

          data = status: 'Slettet' if not data

          # We don't need to use setForType() here since data is already formated
          # when using getDoc()

          set "#{type}:#{id}", data, (err, data) ->
            cb err, data, false

## Export

Expose the functions we want to be public by exporting them.

    module.exports =
      set       : set
      get       : get
      getDoc    : getDoc
      setForType: setForType
      getFilter : getFilter
      filterData: filterData
      getForType: getForType

    "use strict"

    redis    = require './db/redis'
    mongo    = require './db/mongo'
    ObjectID = require('mongodb').ObjectID

## getFilter()

Get data filter for object type.

### Params

* `String` type - object type to get filter for.
* `boolean` preventDefault - prevent default filter switch.

### Return

Returns a `String` key - `boolean` value `Object` where each key represent a
document field. The value determines if they field should be included or not.

Returns an empty `Object` if the `preventDefault` parameter is set to `true` and
no filter was found for the given `type`.

    getFilter = (type, preventDefault) ->

      dataFields =
        default:
          _id       : false
          tilbyder  : true
          endret    : true
          checksum  : true
          status    : true
          navn      : true
          bilder    : true
          grupper   : true

        bilder:
          _id       : false
          tilbyder  : true
          endret    : true
          checksum  : true
          status    : true
          navn      : true

      return dataFields[type] if dataFields[type]
      return {} if preventDefault
      return dataFields.default

## filterData()

Filter data for given type.

### ToDo

* Handle undefined values.

### Params

* `String` type - object type to filter data for.
* `Object` data - data to filter on.

### Return

Returns an `Object` with a subset of the original object containing only the
accepted object properties for the given object type.

    filterData = (type, data) ->
      res = {}
      res[key] = data[key] for key,val of getFilter(type) when val is true and data[key]
      return res

## getDoc()

Get a document from MongoDB for given object type and object id.

This function will automaticly filter object keys according to type in order to
prevent fetching of uncesserary data.

### Params

* `String` type - object type to get document for.
* `String` id - object id for document.
* `function` cb - callback function (`Error` err, `Object` doc).

### Return

No return value or `undefined`.

    getDoc = (type, id, cb) ->
      mongo[type].findOne {_id: new ObjectID(id)}, getFilter(type), cb

## set()

Store data object in Redis for a given cache key.

### Params

* `String` key - cache key to store data for.
* `Object` data - data to store for cache key.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    set = (key, data, cb) ->
      redis.hmset key, data, (err) -> cb(err, data)

## get()

Retrive data from cache for given a cache key.

### Params

* `String` key - cache key to get data for.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    get = (key, cb) ->
      redis.hgetall key, cb

## setForType()

Store data in Redis for given object type and object id.

This function will automaticly remove object properties from input data in order
to match the object type cache preferences as defined in [#getFilter()](#getFilter).

### Params

* `String` type - object type to set cache data for.
* `String` id - object id to set cache data for.
* `Object` data - data store in cache for type and id.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    setForType = (type, id, data, cb) ->
      set "#{type}:#{id}", filterData(type, data), cb

## getForType()

Get data from Redis for object type and object id.

`NB` This function will return `Arrays` if the document is retrived directly
from MongoDB. `Arrays` stored in Redis will be returned as comma seperated
strings.

### Params

* `String` type - object type to get cache data for.
* `String` id - object id to get cache data for.
* `function` cb - callback function (`Error` err, `Object` data).

### Return

No return value or `undefined`.

    getForType = (type, id, cb) ->
      get "#{type}:#{id}", (err, data) ->
        return cb null, data, true if data

        getDoc type, id, (err, data) ->
          return cb err, null, false if err

          data = status: 'Slettet' if not data

          # We don't need to use setForType() here since data is already formated
          # when using getDoc()

          set "#{type}:#{id}", data, (err, data) ->
            cb err, data, false

## Export

Expose the functions we want to be public by exporting them.

    module.exports =
      set       : set
      get       : get
      getDoc    : getDoc
      setForType: setForType
      getFilter : getFilter
      filterData: filterData
      getForType: getForType


[Sheet] well that was a really bad typo

[Sheet] well that was a really bad typo

Jelli Game Engine

#  Sheet  #

The `Sheet` constructor generates sprite-sheets and manages their rendering on a `CanvasRenderingContext2D`.
It is packaged with `Sprite`, which describes a single sprite on the sheet.

##  General functions  ##

The function `drawSprite()` is called by `Sprite`s and `Sheet`s in order to draw their images.
It is not exposed to the window.

    drawSprite = (sheet, start_index, context, x, y, frame = 1) ->

…That's a lot of arguments. Let's go through them:

- `sheet` is the `Sheet` from which to draw the sprite
- `start_index` gives us the index of the sprite within the sheet
- `context` is the `CanvasRenderingContext2D` on which to draw the sprite
- `x` is the x-coordinate of the top-left corner of the sprite
- `y` is the y-coordinate of the top-left corner of the sprite
- `frame` is merely there as a convenience: It increments `start_index` by its value

The first thing we do is make sure everything is typed correctly.
The `sheet` and `context`, clearly, need to be of a certain type in order for this to work.
If any of the other provided arguments aren't numbers, however, we can go ahead and reset them to zero.

        unless sheet instanceof Sheet and start_index < sheet.size and context instanceof CanvasRenderingContext2D then return
        if isNaN(start_index = Number(start_index)) then start_index = 0
        if isNaN(x = Number(x)) then x = 0
        if isNaN(y = Number(y)) then y = 0
        if isNaN(frame = Number(frame)) then frame = 0

Now we can increment `start_index` by `frame`'s value:

        start_index += frame

Next, we need to find the horizontal (`i`) and vertical (`j`) position of the sprite on the sheet.
We can get this information from `start_index` with a little math:

        i = start_index % sheet.width
        j = Math.floor start_index / sheet.width

These two lines just make the image a little easier to access:

        source = sheet.source
        image = sheet.image

Now we have all we need to draw the sprite!
There is a HUGE `if`-statement that precedes the draw function, because we want to make sure that what we're drawing is actually there.
If it isn't, then obviously we can't draw anything.

        if (source instanceof HTMLImageElement and source.complete or source instanceof SVGImageElement or source instanceof HTMLCanvasElement or createImageBitmap? and (image instanceof ImageBitmap or source instanceof ImageBitmap)) and not isNaN(i) and not isNaN(j) and Number(width = sheet.sprite_width) and Number(height = sheet.sprite_height) then context.drawImage (if createImageBitmap? and image instanceof ImageBitmap then image else source), i * width, j * height, width, height, x, y, width, height

Let's go through what those did.
First, we make sure that the `Sheet` actually has an image associated with it:

-   `source instanceof HTMLImageElement and source.complete`—
    If the image source is an `<img>` element, then it needs to have finished loading.

-   `source instanceof SVGImageElement or source instanceof HTMLCanvasElement`—
    The source doesn't have to be an `<img>` element though! It can also be an `<svg>` or a `<canvas>`.

-   `createImageBitmap? and (image instanceof ImageBitmap or source instanceof ImageBitmap)`—
    Finally, the source can be an `ImageBitmap`.
    This isn't supported in all browsers, so we check to make sure `createImageBitmap` exists first.
    However, if `createImageBitmap` *is* supported, then `Sheet`s have a special property, `Sheet.image`, which might contain one, and this should be given preference.

We also need to make sure that the sprite exists on the sheet:

-   `not isNaN(i) and not isNaN(j)`—
    This makes sure that our indices are actually, y'know, numbers.

-   `Number(width = sheet.sprite_width) and Number(height = sheet.sprite_height)`—
    This makes sure that the sprites in the sheet have a non-zero width and height.
    It also sets the variables `width` and `height` to those values, for convenient access later.

Finally, we can draw the sprite.
Again, we preference `image` if it is defined.

##  Sprite  ##

The `Sprite` constructor creates a reference to a sprite on a sheet.
For efficiency's sake, it does *not* actually contain any of the image data associated with that sprite.
The constructor takes three arguments: `sheet`, which gives the sheet; `index`, which is the index of the sprite on the sheet; and `length`, which for animated sprites gives the length of the animation.

    Sprite = (sheet, index, length = 1) ->

If `index` or `length` aren't numbers, then we go ahead and set them to `0` and `1`, respectively.

        if isNaN(index = Number(index)) then index = 0
        if isNaN(length = Number(length)) then length = 1

Now we can set the properties.
Note that `draw` simply binds `drawSprite` to the given `Sheet` and `index`.

        @draw = drawSprite.bind(null, sheet, index)
        @height = if sheet instanceof Sheet then sheet.sprite_height else 0
        @index = index
        @frames = length
        @sheet = if sheet instanceof Sheet then sheet else null
        @width = if sheet instanceof Sheet then sheet.sprite_width else 0

Since `Sprite`s are just static references, they should be immutable:

        Object.freeze this

And we're done!

`Sprite`s are very simple, and because the `draw` function is bound above, they don't have a prototype.
For purposes of inheritance, however, I've thrown this minimal one together:

    Sprite.prototype = {draw: ->}
    Object.freeze Sprite.prototype

##  Sheet  ##

`Sheet`s associate images with data and methods to make them easily referencable as sprite-sheets.

###  The constructor  ###

The `Sheet` constructor only takes three arguments: `source`, which gives the source image for the sheet, `sprite_width`, which gives the width of the sprites, and `sprite_height`, which gives their height.
In doing so, it makes the assumption that sprites and sprite-sheets do not have any borders or padding.
(Because borders and padding result in larger download times for users, this restriction is considered acceptable, but it may be lifted at some time in the future.)

    Sheet = (source, sprite_width, sprite_height) ->

First, we need to handle the arguments.
If `source` isn't an image type that we recognize, we go ahead and set it to `null`.
And if the `sprite_width` or `sprite_height` aren't recognizable as numbers, we set them to 0.
(Note from the above that a `Sheet` with zero `sprite_width` or `sprite_height` cannot be drawn.)

        unless source instanceof HTMLImageElement or source instanceof SVGImageElement or source instanceof HTMLCanvasElement or createImageBitmap? and source instanceof ImageBitmap then source = null
        if isNaN(sprite_width = Number(sprite_width)) then sprite_width = 0
        if isNaN(sprite_height = Number(sprite_height)) then sprite_height = 0

Recall that we need to check for `createImageBitmap` before checking to see if the source is an `ImageBitmap`.

We can get the width and height of the image from one of two sources, depending on the source type.
All of the accepted types have `width` and `height` properties, which specify their dimensions.
However, `HTMLImageElement`s also have `naturalWidth` and `naturalHeight` properties, and these should be preferred for pixel-perfect rendering.

If for some reason we can't get *either* of these properties, then the `source_width` and `source_height` are set to zero.

        unless source? and not isNaN(source_width = Number(if source.naturalWidth? then source.naturalWidth else source.width)) then source_width = 0
        unless source? and not isNaN(source_height = Number(if source.naturalHeight? then source.naturalHeight else source.height)) then source_height = 0

We now have everything we need to define the properties.
Note that `width` and `height` are provided in sprite-units, not pixels.
If `sprite_width` or `sprite_height` are `0`, then the corresponding `width` and `height` are obviously `NaN`.

        @height = Math.floor source_height / sprite_height
        @source = source
        @sprite_height = sprite_height
        @sprite_width = sprite_width
        @width = Math.floor source_width / sprite_width

The `size` property is just `width` times `height`.

        @size = @width * @height

`ImageBitmap`s are optimized for drawing to the canvas.
If they are supported, we can pre-render the sprite-sheet and store this in the `image` property.

        if createImageBitmap? then (createImageBitmap source).then (image) => @image = image

Because `Sheet`s contain static images, it doesn't make sense for them to change after creation.
We freeze them:

        Object.freeze this

For convenience's sake, two static methods have been defined for `Sheet` to let you draw arbitrary sprites.
These are largely intended for use with callbacks.

The first is called `draw`, and takes five arguments:

- `context`: A `CanvasRenderingContext2D`
- `sprite`: A `Sprite`
- `x`: The x-coordinate at which to draw the sprite
- `y`: The y-coordinate at which to draw the sprite
- `frame`: The frame of the animation which to draw

It maps onto `sprite.draw`:

    Sheet.draw = (context, sprite, x, y, frame = 0) -> if sprite instanceof Sprite then sprite.draw context, x, y, frame

The second is called `drawSheetAtIndex`, and also takes five arguments:

- `context`: A `CanvasRenderingContext2D`
- `sheet`: A `Sheet`
- `index`: The index of the sprite
- `x`: The x-coordinate at which to draw the sprite
- `y`: The y-coordinate at which to draw the sprite

It maps onto `sheet.drawIndex`:

    Sheet.drawSheetAtIndex = (context, sheet, index, x, y) -> if sheet instanceof Sheet then sheet.drawIndex context, index, x, y

Finally, the `Sprite` constructor is added to `Sheet` for later access:

    Sheet.Sprite = Sprite

And now we can make `Sheet` available to the window:

    window.Sheet = Sheet

##  The prototype  ##

The `Sheet` prototype is fairly minimal, consisting of only two functions.

    Sheet.prototype = {

The first, `drawIndex`, draws the sprite located at the given `index`.
It is little more than a repackaging of `drawSprite`.

        drawIndex: (context, index, x, y) -> drawSprite this, index, context, x, y

The second, `getSprite`, creates a new `Sprite` pointing to the given `index`.
It is the most convenient way of creating `Sprite` objects.
It takes two arguments, the `index` of the sprite, and the `length` of the animation.

        getSprite: (index, length = 1) -> new Sprite this, index, length

We can now freeze the prototype:

    }

    Object.freeze Sheet.prototype

…And that's the end!

Jelli Game Engine

#  Sheet  #

The `Sheet` constructor generates sprite-sheets and manages their rendering on a `CanvasRenderingContext2D`.
It is packaged with `Sprite`, which describes a single sprite on the sheet.

##  General functions  ##

The function `drawSprite()` is called by `Sprite`s and `Sheet`s in order to draw their images.
It is not exposed to the window.

    drawSprite = (sheet, start_index, context, x, y, frame = 1) ->

…That's a lot of arguments. Let's go through them:

- `sheet` is the `Sheet` from which to draw the sprite
- `start_index` gives us the index of the sprite within the sheet
- `context` is the `CanvasRenderingContext2D` on which to draw the sprite
- `x` is the x-coordinate of the top-left corner of the sprite
- `y` is the y-coordinate of the top-left corner of the sprite
- `frame` is merely there as a convenience: It increments `start_index` by its value

The first thing we do is make sure everything is typed correctly.
The `sheet` and `context`, clearly, need to be of a certain type in order for this to work.
If any of the other provided arguments aren't numbers, however, we can go ahead and reset them to zero.

        unless sheet instanceof Sheet and start_index < sheet.size and context instanceof CanvasRenderingContext2D then return
        if isNaN(start_index = Number(start_index)) then start_index = 0
        if isNaN(x = Number(x)) then x = 0
        if isNaN(y = Number(y)) then y = 0
        if isNaN(frame = Number(frame)) then frame = 0

Now we can increment `start_index` by `frame`'s value:

        `start_index` += frame

Next, we need to find the horizontal (`i`) and vertical (`j`) position of the sprite on the sheet.
We can get this information from `start_index` with a little math:

        i = start_index % sheet.width
        j = Math.floor start_index / sheet.width

These two lines just make the image a little easier to access:

        source = sheet.source
        image = sheet.image

Now we have all we need to draw the sprite!
There is a HUGE `if`-statement that precedes the draw function, because we want to make sure that what we're drawing is actually there.
If it isn't, then obviously we can't draw anything.

        if (source instanceof HTMLImageElement and source.complete or source instanceof SVGImageElement or source instanceof HTMLCanvasElement or createImageBitmap? and (image instanceof ImageBitmap or source instanceof ImageBitmap)) and not isNaN(i) and not isNaN(j) and Number(width = sheet.sprite_width) and Number(height = sheet.sprite_height) then context.drawImage (if createImageBitmap? and image instanceof ImageBitmap then image else source), i * width, j * height, width, height, x, y, width, height

Let's go through what those did.
First, we make sure that the `Sheet` actually has an image associated with it:

-   `source instanceof HTMLImageElement and source.complete`—
    If the image source is an `<img>` element, then it needs to have finished loading.

-   `source instanceof SVGImageElement or source instanceof HTMLCanvasElement`—
    The source doesn't have to be an `<img>` element though! It can also be an `<svg>` or a `<canvas>`.

-   `createImageBitmap? and (image instanceof ImageBitmap or source instanceof ImageBitmap)`—
    Finally, the source can be an `ImageBitmap`.
    This isn't supported in all browsers, so we check to make sure `createImageBitmap` exists first.
    However, if `createImageBitmap` *is* supported, then `Sheet`s have a special property, `Sheet.image`, which might contain one, and this should be given preference.

We also need to make sure that the sprite exists on the sheet:

-   `not isNaN(i) and not isNaN(j)`—
    This makes sure that our indices are actually, y'know, numbers.

-   `Number(width = sheet.sprite_width) and Number(height = sheet.sprite_height)`—
    This makes sure that the sprites in the sheet have a non-zero width and height.
    It also sets the variables `width` and `height` to those values, for convenient access later.

Finally, we can draw the sprite.
Again, we preference `image` if it is defined.

##  Sprite  ##

The `Sprite` constructor creates a reference to a sprite on a sheet.
For efficiency's sake, it does *not* actually contain any of the image data associated with that sprite.
The constructor takes three arguments: `sheet`, which gives the sheet; `index`, which is the index of the sprite on the sheet; and `length`, which for animated sprites gives the length of the animation.

    Sprite = (sheet, index, length = 1) ->

If `index` or `length` aren't numbers, then we go ahead and set them to `0` and `1`, respectively.

        if isNaN(index = Number(index)) then index = 0
        if isNaN(length = Number(length)) then length = 1

Now we can set the properties.
Note that `draw` simply binds `drawSprite` to the given `Sheet` and `index`.

        @draw = drawSprite.bind(null, sheet, index)
        @height = if sheet instanceof Sheet then sheet.sprite_height else 0
        @index = index
        @frames = length
        @sheet = if sheet instanceof Sheet then sheet else null
        @width = if sheet instanceof Sheet then sheet.sprite_width else 0

Since `Sprite`s are just static references, they should be immutable:

        Object.freeze this

And we're done!

`Sprite`s are very simple, and because the `draw` function is bound above, they don't have a prototype.
For purposes of inheritance, however, I've thrown this minimal one together:

    Sprite.prototype = {draw: ->}
    Object.freeze Sprite.prototype

##  Sheet  ##

`Sheet`s associate images with data and methods to make them easily referencable as sprite-sheets.

###  The constructor  ###

The `Sheet` constructor only takes three arguments: `source`, which gives the source image for the sheet, `sprite_width`, which gives the width of the sprites, and `sprite_height`, which gives their height.
In doing so, it makes the assumption that sprites and sprite-sheets do not have any borders or padding.
(Because borders and padding result in larger download times for users, this restriction is considered acceptable, but it may be lifted at some time in the future.)

    Sheet = (source, sprite_width, sprite_height) ->

First, we need to handle the arguments.
If `source` isn't an image type that we recognize, we go ahead and set it to `null`.
And if the `sprite_width` or `sprite_height` aren't recognizable as numbers, we set them to 0.
(Note from the above that a `Sheet` with zero `sprite_width` or `sprite_height` cannot be drawn.)

        unless source instanceof HTMLImageElement or source instanceof SVGImageElement or source instanceof HTMLCanvasElement or createImageBitmap? and source instanceof ImageBitmap then source = null
        if isNaN(sprite_width = Number(sprite_width)) then sprite_width = 0
        if isNaN(sprite_height = Number(sprite_height)) then sprite_height = 0

Recall that we need to check for `createImageBitmap` before checking to see if the source is an `ImageBitmap`.

We can get the width and height of the image from one of two sources, depending on the source type.
All of the accepted types have `width` and `height` properties, which specify their dimensions.
However, `HTMLImageElement`s also have `naturalWidth` and `naturalHeight` properties, and these should be preferred for pixel-perfect rendering.

If for some reason we can't get *either* of these properties, then the `source_width` and `source_height` are set to zero.

        unless source? and not isNaN(source_width = Number(if source.naturalWidth? then source.naturalWidth else source.width)) then source_width = 0
        unless source? and not isNaN(source_height = Number(if source.naturalHeight? then source.naturalHeight else source.height)) then source_height = 0

We now have everything we need to define the properties.
Note that `width` and `height` are provided in sprite-units, not pixels.
If `sprite_width` or `sprite_height` are `0`, then the corresponding `width` and `height` are obviously `NaN`.

        @height = Math.floor source_height / sprite_height
        @source = source
        @sprite_height = sprite_height
        @sprite_width = sprite_width
        @width = Math.floor source_width / sprite_width

The `size` property is just `width` times `height`.

        @size = @width * @height

`ImageBitmap`s are optimized for drawing to the canvas.
If they are supported, we can pre-render the sprite-sheet and store this in the `image` property.

        if createImageBitmap? then (createImageBitmap source).then (image) => @image = image

Because `Sheet`s contain static images, it doesn't make sense for them to change after creation.
We freeze them:

        Object.freeze this

For convenience's sake, two static methods have been defined for `Sheet` to let you draw arbitrary sprites.
These are largely intended for use with callbacks.

The first is called `draw`, and takes five arguments:

- `context`: A `CanvasRenderingContext2D`
- `sprite`: A `Sprite`
- `x`: The x-coordinate at which to draw the sprite
- `y`: The y-coordinate at which to draw the sprite
- `frame`: The frame of the animation which to draw

It maps onto `sprite.draw`:

    Sheet.draw = (context, sprite, x, y, frame = 0) -> if sprite instanceof Sprite then sprite.draw context, x, y, frame

The second is called `drawSheetAtIndex`, and also takes five arguments:

- `context`: A `CanvasRenderingContext2D`
- `sheet`: A `Sheet`
- `index`: The index of the sprite
- `x`: The x-coordinate at which to draw the sprite
- `y`: The y-coordinate at which to draw the sprite

It maps onto `sheet.drawIndex`:

    Sheet.drawSheetAtIndex = (context, sheet, index, x, y) -> if sheet instanceof Sheet then sheet.drawIndex context, index, x, y

Finally, the `Sprite` constructor is added to `Sheet` for later access:

    Sheet.Sprite = Sprite

And now we can make `Sheet` available to the window:

    window.Sheet = Sheet

##  The prototype  ##

The `Sheet` prototype is fairly minimal, consisting of only two functions.

    Sheet.prototype = {

The first, `drawIndex`, draws the sprite located at the given `index`.
It is little more than a repackaging of `drawSprite`.

        drawIndex: (context, index, x, y) -> drawSprite this, index, context, x, y

The second, `getSprite`, creates a new `Sprite` pointing to the given `index`.
It is the most convenient way of creating `Sprite` objects.
It takes two arguments, the `index` of the sprite, and the `length` of the animation.

        getSprite: (index, length = 1) -> new Sprite this, index, length

We can now freeze the prototype:

    }

    Object.freeze Sheet.prototype

…And that's the end!


custom nbsp parsing in markdown

custom nbsp parsing in markdown

# Builder

### Load modules

    {readFileSync, writeFileSync} = require 'fs'
    {renderFile} = require 'jade'
    {safeLoad} = require 'js-yaml'
    marked = require 'marked'

### Add custom `nbsp` support

Extend the default `renderer.paragraph` method
by first replacing all `~` characters
(which I don't use in paragraphs) with ` `.
If I want to add a `~` character, I can write `~`.

    renderer = new marked.Renderer()
    {paragraph} = renderer
    renderer.paragraph = (text) ->
        return paragraph text.replace /~/g, ' '

Override the `marked` function by a new one with the custom renderer.

    marked = do (marked) ->
        return (text) ->
            return marked text,
                renderer: renderer

### Render html

    options = safeLoad readFileSync process.argv[3], 'utf8'
    options.markdown = marked
    html = renderFile process.argv[2], options

### Write the output

    if process.argv[4]?
        writeFileSync process.argv[4], html
    else
        console.log html

# Builder

load modules

    {readFileSync, writeFileSync} = require 'fs'
    {renderFile} = require 'jade'
    {safeLoad} = require 'js-yaml'
    marked = require 'marked'

render html

    options = safeLoad readFileSync process.argv[3], 'utf8'
    options.markdown = marked
    html = renderFile process.argv[2], options

write the output

    if process.argv[4]?
        writeFileSync process.argv[4], html
    else
        console.log html


fix maxage for static caching, one more 0

# Application Startup

This code starts up the application.

## Configure

First, include required modules.

    express = require 'express'
    exp3hbs = require 'express3-handlebars'
    redis_store = require('connect-redis')(express)
    config = require './config/config.js'
    secrets = require './config/private.js'

Next, initialize the application.

    app = express()

Configure HBS to glue Express and Handlebars together with HTML file extensions
for templates.

    app.set 'view engine', 'html'
    exp3hbs_config =
      defaultLayout: 'default',
      extname: '.html'
    app.engine 'html', exp3hbs(exp3hbs_config)

Configure Express to serve static files.

    app.use express.static('public', { maxAge: 86400000 })

Initialize a session for later use.  Associate session data with
`res.locals.session`.

    app.use express.cookieParser(secrets.session_key)
    app.use express.session({
      store: new redis_store({host: config.redis_host, port: config.redis_port, prefix: config.redis_prefix}),
      secret: secrets.session_key,
      maxAge: 86400000
    })
    app.use (req, res, next) ->
      res.locals.session = req.session
      next()

Place directory URL in a place where we can find it later.

    app.directory_url = secrets.directory_url

## Cross-Site Request Forgeries

Add the CSRF submission protection middleware.  This generates
`req.session.\_csrf` and maps it to `res.locals.token` so it will be available
in all templates as {{{token}}}.

Anything other than a GET, HEAD, or OPTIONS will require a valid `\_CSRF` field
or else it will be rejected with a 403.

Must be after sessions and before routers.

    app.use express.bodyParser()
    app.use express.csrf()
    app.use (req, res, next) ->
      res.locals.token = req.csrfToken()
      next()

## Database

Connect to MongoDB through Mongoose and initialize models.

    app.models = require('./lib/models')(config)

## Routes

Execute routes module.

    app.use (req, res, next) ->
      if req.session.securityLevel
        res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0')
      next()

    require('./lib/routes')(app)

## Errors

Execute error handling module.

    require('./lib/error')(app)

    # This must be the very last middleware added to the app
    require('./lib/error/404')(app)

## Startup

Finally, start the server.

    app.listen config.port, config.ip

## Copying

This software is released under the ISC License.

Copyright (c) 2013, Cameron King <cking@ecc12.com>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

<!-- vim: ts=2 sts=2 sw=2 expandtab
     CoffeeScript-friendly tabstops in vim. -->

# Application Startup

This code starts up the application.

## Configure

First, include required modules.

    express = require 'express'
    exp3hbs = require 'express3-handlebars'
    redis_store = require('connect-redis')(express)
    config = require './config/config.js'
    secrets = require './config/private.js'

Next, initialize the application.

    app = express()

Configure HBS to glue Express and Handlebars together with HTML file extensions
for templates.

    app.set 'view engine', 'html'
    exp3hbs_config =
      defaultLayout: 'default',
      extname: '.html'
    app.engine 'html', exp3hbs(exp3hbs_config)

Configure Express to serve static files.

    app.use express.static('public', { maxAge: 8640000 })

Initialize a session for later use.  Associate session data with
`res.locals.session`.

    app.use express.cookieParser(secrets.session_key)
    app.use express.session({
      store: new redis_store({host: config.redis_host, port: config.redis_port, prefix: config.redis_prefix}),
      secret: secrets.session_key,
      maxAge: 86400000
    })
    app.use (req, res, next) ->
      res.locals.session = req.session
      next()

Place directory URL in a place where we can find it later.

    app.directory_url = secrets.directory_url

## Cross-Site Request Forgeries

Add the CSRF submission protection middleware.  This generates
`req.session.\_csrf` and maps it to `res.locals.token` so it will be available
in all templates as {{{token}}}.

Anything other than a GET, HEAD, or OPTIONS will require a valid `\_CSRF` field
or else it will be rejected with a 403.

Must be after sessions and before routers.

    app.use express.bodyParser()
    app.use express.csrf()
    app.use (req, res, next) ->
      res.locals.token = req.csrfToken()
      next()

## Database

Connect to MongoDB through Mongoose and initialize models.

    app.models = require('./lib/models')(config)

## Routes

Execute routes module.

    app.use (req, res, next) ->
      if req.session.securityLevel
        res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0')
      next()

    require('./lib/routes')(app)

## Errors

Execute error handling module.

    require('./lib/error')(app)

    # This must be the very last middleware added to the app
    require('./lib/error/404')(app)

## Startup

Finally, start the server.

    app.listen config.port, config.ip

## Copying

This software is released under the ISC License.

Copyright (c) 2013, Cameron King <cking@ecc12.com>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

<!-- vim: ts=2 sts=2 sw=2 expandtab
     CoffeeScript-friendly tabstops in vim. -->


added exports

added exports

# cnl

## CLASSES
* [Engine][Engine] - rendering engine
* [Element][Element] - visual element
* [Shape][Shape] - drawable shape
* [Component][Component] - interactive component
* [Style][Style] - loadable style
* [Pen][Pen] - drawing pen

---

### EXPORTS

    module.exports =
      Engine    : require './base'
      Element   : require './element'
      Shape     : require './shape'
      Style     : require './style'
      Pen       : require './pen'
      Component : require './component'

[Engine]: ./engine.litcoffee
[Element]: ./element.litcoffee
[Component]: ./component.litcoffee
[Shape]: ./shape.litcoffee
[Style]: ./style.litcoffee
[Pen]: ./pen.litcoffee

# ecl

## CLASSES
* [Engine][Engine] - rendering engine

---

### EXPORTS

    module.exports =
      Engine    : require './base'

[Engine]: ./base.litcoffee