Full Code of coffeedoc/codo for AI

master a02771cbf23a cached
165 files
594.0 KB
168.1k tokens
77 symbols
1 requests
Download .txt
Showing preview only (641K chars total). Download the full file or copy to clipboard to get everything.
Repository: coffeedoc/codo
Branch: master
Commit: a02771cbf23a
Files: 165
Total size: 594.0 KB

Directory structure:
gitextract_nbr74owg/

├── .codoopts
├── .gitignore
├── .travis.yml
├── Gruntfile.coffee
├── LICENSE.md
├── README.md
├── bin/
│   └── codo
├── lib/
│   ├── _entities.coffee
│   ├── _meta.coffee
│   ├── _tools.coffee
│   ├── codo.coffee
│   ├── command.coffee
│   ├── documentation.coffee
│   ├── entities/
│   │   ├── class.coffee
│   │   ├── extra.coffee
│   │   ├── file.coffee
│   │   ├── method.coffee
│   │   ├── mixin.coffee
│   │   ├── property.coffee
│   │   └── variable.coffee
│   ├── entity.coffee
│   ├── environment.coffee
│   ├── meta/
│   │   ├── method.coffee
│   │   └── parameter.coffee
│   ├── tools/
│   │   ├── markdown.coffee
│   │   └── referencer.coffee
│   └── traverser.coffee
├── package.json
├── spec/
│   ├── _templates/
│   │   ├── angular/
│   │   │   ├── angular-with-new.coffee
│   │   │   ├── angular-with-new.json
│   │   │   ├── angular.coffee
│   │   │   └── angular.json
│   │   ├── classes/
│   │   │   ├── class_description_markdown.coffee
│   │   │   ├── class_description_markdown.json
│   │   │   ├── class_documentation.coffee
│   │   │   ├── class_documentation.json
│   │   │   ├── class_extends.coffee
│   │   │   ├── class_extends.json
│   │   │   ├── empty_class.coffee
│   │   │   ├── empty_class.json
│   │   │   ├── export_class.coffee
│   │   │   ├── export_class.json
│   │   │   ├── global_class.coffee
│   │   │   ├── global_class.json
│   │   │   ├── inner_class.coffee
│   │   │   ├── inner_class.json
│   │   │   ├── namespaced_class.coffee
│   │   │   ├── namespaced_class.json
│   │   │   ├── simple_class.coffee
│   │   │   └── simple_class.json
│   │   ├── complicateds/
│   │   │   ├── methods.coffee
│   │   │   └── variables.coffee
│   │   ├── environment/
│   │   │   ├── class.coffee
│   │   │   ├── mixin.coffee
│   │   │   └── result.json
│   │   ├── example/
│   │   │   ├── CHANGELOG
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── angry_animal.coffee
│   │   │       ├── animal.coffee
│   │   │       ├── lion.coffee
│   │   │       ├── over_documented_class.coffee
│   │   │       └── over_documented_mixin.coffee
│   │   ├── extras/
│   │   │   ├── README
│   │   │   └── README.md
│   │   ├── files/
│   │   │   ├── non_class_file.coffee
│   │   │   └── non_class_file.json
│   │   ├── methods/
│   │   │   ├── assigned_parameters.coffee
│   │   │   ├── assigned_parameters.json
│   │   │   ├── class_methods.coffee
│   │   │   ├── class_methods.json
│   │   │   ├── curly_method_documentation.coffee
│   │   │   ├── curly_method_documentation.json
│   │   │   ├── dynamic_methods.coffee
│   │   │   ├── dynamic_methods.json
│   │   │   ├── instance_methods.coffee
│   │   │   ├── instance_methods.json
│   │   │   ├── method_documentation.coffee
│   │   │   ├── method_documentation.json
│   │   │   ├── method_events.coffee
│   │   │   ├── method_events.json
│   │   │   ├── method_example.coffee
│   │   │   ├── method_example.json
│   │   │   ├── named_parameters.coffee
│   │   │   ├── named_parameters.json
│   │   │   ├── overload_method.coffee
│   │   │   └── overload_method.json
│   │   ├── mixins/
│   │   │   ├── concern.coffee
│   │   │   ├── concern.json
│   │   │   ├── extend_mixin.coffee
│   │   │   ├── extend_mixin.json
│   │   │   ├── include_mixin.coffee
│   │   │   ├── include_mixin.json
│   │   │   ├── missing_mixins.coffee
│   │   │   ├── missing_mixins.json
│   │   │   ├── mixin_documentation.coffee
│   │   │   ├── mixin_documentation.json
│   │   │   ├── mixin_methods.coffee
│   │   │   └── mixin_methods.json
│   │   ├── properties/
│   │   │   ├── properties.coffee
│   │   │   └── properties.json
│   │   └── variables/
│   │       ├── class_variables.coffee
│   │       ├── class_variables.json
│   │       ├── constant_variables.coffee
│   │       ├── constant_variables.json
│   │       ├── instance_variables.coffee
│   │       └── instance_variables.json
│   ├── lib/
│   │   ├── api_spec.coffee
│   │   ├── codo_spec.coffee
│   │   ├── entities/
│   │   │   ├── class_spec.coffee
│   │   │   └── mixin_spec.coffee
│   │   ├── environment_spec.coffee
│   │   ├── meta/
│   │   │   ├── method_spec.coffee
│   │   │   └── parameter_spec.coffee
│   │   └── tools/
│   │       └── markdown_spec.coffee
│   └── themes/
│       └── default/
│           └── lib/
│               ├── templater_spec.coffee
│               ├── theme_spec.coffee
│               └── tree_builder_spec.coffee
└── themes/
    └── default/
        ├── assets/
        │   ├── javascript/
        │   │   ├── application.js
        │   │   ├── codo.coffee
        │   │   ├── frames.coffee
        │   │   ├── fuzzy.coffee
        │   │   ├── keys.coffee
        │   │   ├── sidebar.coffee
        │   │   ├── toc.coffee
        │   │   └── vendor/
        │   │       ├── fuzzy.coffee
        │   │       ├── highlight.coffeescript.js
        │   │       ├── highlight.js
        │   │       ├── jquery.js
        │   │       ├── keymaster.js
        │   │       └── underscore.js
        │   └── stylesheets/
        │       ├── alphabetical_index.styl
        │       ├── application.styl
        │       ├── base.styl
        │       ├── class.styl
        │       ├── footer.styl
        │       ├── header.styl
        │       ├── lists.styl
        │       ├── toc.styl
        │       └── vendor/
        │           └── highlight.css
        ├── lib/
        │   ├── _theme.coffee
        │   ├── templater.coffee
        │   ├── theme.coffee
        │   └── tree_builder.coffee
        └── templates/
            ├── alphabetical_index.hamlc
            ├── class.hamlc
            ├── class_list.hamlc
            ├── extra.hamlc
            ├── extra_list.hamlc
            ├── file.hamlc
            ├── file_list.hamlc
            ├── frames.hamlc
            ├── layout/
            │   ├── footer.hamlc
            │   ├── header.hamlc
            │   └── intro.hamlc
            ├── method_list.hamlc
            ├── mixin.hamlc
            ├── mixin_list.hamlc
            └── partials/
                ├── documentation.hamlc
                ├── list_nav.hamlc
                ├── method_list.hamlc
                ├── method_signature.hamlc
                ├── method_summary.hamlc
                ├── type_link.hamlc
                └── variable_list.hamlc

================================================
FILE CONTENTS
================================================

================================================
FILE: .codoopts
================================================
--title "Codo Documentation"
lib/
themes/


================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
.bundle
.idea
doc
npm-debug.log


================================================
FILE: .travis.yml
================================================
language: node_js
branches:
  only:
    - master
    - 1.x
notifications:
  recipients:
    - michi@netzpiraten.ch
    - boris@staal.io


================================================
FILE: Gruntfile.coffee
================================================
module.exports = (grunt) ->

  grunt.loadNpmTasks 'grunt-release'

  grunt.initConfig
    release:
      options:
        bump: false
        add: false
        commit: false
        push: false

================================================
FILE: LICENSE.md
================================================
# MIT License

Copyright (c) 2012-2013 Michael Kessler, Boris Staal

Template components are derivative works of YARD (http://yardoc.org)  
Copyright (c) Loren Segal and licensed under the MIT license

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Codo [![Build Status](https://secure.travis-ci.org/coffeedoc/codo.png)](https://travis-ci.org/coffeedoc/codo)

Codo is a [CoffeeScript](http://coffeescript.org/) API documentation generator, similar to [YARD](http://yardoc.org/).
Its generated documentation is focused on CoffeeScript class syntax for classical inheritance.

## Features

* Detects classes, methods, constants, mixins & concerns.
* Many tags to add semantics to your code.
* Generates a nice site to browse your code documentation in various ways.
* Can be used to assure minimum documentation
* ~~Documentation generation and hosting as a service on [CoffeeDoc.info](http://coffeedoc.info)~~ (we no longer have the access to domain and the service is currently inaccessible)

## Codo in action

Annotate your source with Codo tags to add semantic information to your code. It looks like this:

```CoffeeScript
# Base class for all animals.
#
# @example How to subclass an animal
#   class Lion extends Animal
#     move: (direction, speed): ->
#
class Example.Animal

  # The Answer to the Ultimate Question of Life, the Universe, and Everything
  @ANSWER = 42

  # Construct a new animal.
  #
  # @param [String] name the name of the animal
  # @param [Date] birthDate when the animal was born
  #
  constructor: (@name, @birthDate = new Date()) ->

  # Move the animal.
  #
  # @example Move an animal
  #   new Lion('Simba').move(direction: 'south', speed: 12)
  #
  # @param [Object] options the moving options
  # @option options [String] direction the moving direction
  # @option options [Number] speed the speed in mph
  #
  move: (options = {}) ->
```

Then generate the documentation with the `codo` command line tool. You can browse some
generated Codo documentation on [CoffeeDoc.info](http://coffeedoc.info) to get a feeling how you can navigate in various ways through your code layers.

In the `Example` namespace you'll find some classes and mixins that makes absolutely no sense, its purpose is only to show the many features Codo offers.

## Installation

Codo is available in NPM and can be installed with:

```bash
$ npm install -g codo
```

Please have a look at the [CHANGELOG](https://github.com/coffeedoc/codo/releases) when upgrading to a newer Codo version with `npm update`.

## Tags

You have to annotate your code with Codo tags to give it some meaning to the parser that generates the documentation. Each tag starts with the `@` sign followed by the tag name. See the following overview for a minimal description of all available tags. Most tags are self-explaining and the one that aren't are described afterwards in more detail.

Tags can take multiple lines, just indent subsequent lines by two spaces.

### Overview

The following table shows the list of all available tags in alphabetical order with its expected options. An option in parenthesis is optional and the square brackets are part of the Codo tag format and must actually be written. Some tags can be defined multiple times and they can be applied to different contexts, either in the comment for a class, a comment for a mixin or in a method comment.

<table>
  <thead>
    <tr>
      <td><strong>Tag format</strong></td>
      <td><strong>Multiple occurrences</strong></td>
      <td><strong>Classes</strong></td>
      <td><strong>Mixins</strong></td>
      <td><strong>Methods</strong></td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>@namespace</strong> namespace</td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@abstract</strong> (message)</td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@author</strong> name</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@concern</strong> mixin</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@copyright</strong> name</td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@deprecated</strong></td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@example</strong> (title)<br/>&nbsp;&nbsp;Code</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@extend</strong> mixin</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@include</strong> mixin</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@note</strong> message</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@method</strong> signature<br/>&nbsp;&nbsp;Method tags</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@mixin</strong></td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
      <td></td>
    </tr>
    <tr>
      <td><strong>@option</strong> option [type] name description</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@event</strong> name [description]<br />&nbsp;&nbsp;Event tags</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@overload</strong> signature<br/>&nbsp;&nbsp;Method tags</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td>
        <strong>@param</strong> [type] name description<br/>
        <strong>@param</strong> name [type] description<br/>
      </td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@private</strong></td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@property</strong> [type] description</td>
      <td></td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@public</strong></td>
      <td></td>
      <td>&#10004;</td>
      <td></td>
      <td>&#10004;</td> 
    </tr> 
    <tr>
      <td><strong>@return</strong> [type] description</td>
      <td></td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@see</strong> link/reference</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@since</strong> version</td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@throw</strong> message</td>
      <td>&#10004;</td>
      <td></td>
      <td></td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@todo</strong> message</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@version</strong> version</td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td><strong>@nodoc</strong></td>
      <td></td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
  </tbody>
</table>

### Alternative syntax

You can also use curly braces instead of square brackets if you prefer:

```CoffeeScript
# Move the animal.
#
# @example Move an animal
#   new Lion('Simba').move('south', 12)
#
# @param {Object} options the moving options
# @option options {String} direction the moving direction
# @option options {Number} speed the speed in mph
#
move: (options = {}) ->
```

It's also possible to use [CoffeeScript block comments](http://coffeescript.org/#strings) instead of the normal
comments. If you solely use block comments, you may want to use the `--cautious` flag to disable the internal comment conversion.

```CoffeeScript
###
Move the animal.

@example Move an animal
  new Lion('Simba').move('south', 12)

@param [Object] options the moving options
@option options [String] direction the moving direction
@option options [Number] speed the speed in mph
###
move: (options = {}) ->
```

If you want to compile your JavaScript with Google Closure and make use of the special block comments with an asterisk, you want to use the `--closure` flag so that Codo ignores the asterisk.

### Parameters

There are two different format recognized for your parameters, so you can chose your favorite. This one is with the
parameter after the parameter type:

```CoffeeScript
# Feed the animal
#
# @param [World.Food] food the food to eat
# @param [Object] options the feeding options
# @option options [String] time the time to feed
#
feed: (food) ->
```

And this one with the name before the type:

```CoffeeScript
# Feed the animal
#
# @param food [World.Food] the food to eat
# @param options [Object] the feeding options
# @option options time [String] the time to feed
#
feed: (food) ->
```

The parameter type can contain multiple comma separated types:

```CoffeeScript
# Feed the animal
#
# @param [String, Char] input
# @return [Integer, Float] output
#
do: (input) ->
```

Each known type will be automatically linked. Also named parameters are recognized:

```CoffeeScript
class Classmate

  # @param {string} name Full name (first + last)
  # @param {string} phone Phone number
  # @param {obj} picture JPG of the person
  constructor: ( {@name, @phone, picture} ) ->

  # @param {string} reason Why I'm no longer friends
  # @param {Date} revisit_decision_on When to reconsider
  unfriend: ( {reason, revisit_decision_on} ) ->
```

### Options

If you have an object as parameter and you like to define the accepted properties as options to the method, you can use the `@options` tag:


```CoffeeScript
# Feed the animal
#
# @param [Object] options the calculation options
# @option options [Integer] age the age of the animal
# @option options [Integer] weight the weight of the animal
#
expectationOfLife: (options) ->
```

The first parameter to the option tag is the parameter name it describes, followed by the parameter type, name and
description.

### Types

The object types for the `@param`, `@option` and `@return` tags are parsed for known classes or mixins and linked. You can also define types for Arrays with:

```CoffeeScript
#
# @param [World.Region] region the region of the herd
# @return [Array<Animals>] the animals in the herd
#
getHerdMembers: (regions) ->
```

### Properties

You can mark an instance variable as property of the class by using the `@property` tag like:

```CoffeeScript
class Person

  # @property [Array<String>] the nicknames
  nicknames: []
```

In addition, the following properties pattern is detected:

```CoffeeScript
class Person

  get = (props) => @::__defineGetter__ name, getter for name, getter of props
  set = (props) => @::__defineSetter__ name, setter for name, setter of props

  # @property [String] The person name
  get name: -> @_name
  set name: (@_name) ->

  # The persons age
  get age: -> @_age
```

If you follow this convention, they will be shown in the generated documentation with its read/write status shown. To specify type of the property, use the `@property` tag.

### Method overloading

If you allow your method to take different parameters, you can describe the method overloading with the `@overload` tag:

```CoffeeScript
# This is a generic Store set method.
#
# @overload set(key, value)
#   Sets a value on key
#   @param [Symbol] key describe key param
#   @param [Object] value describe value param
#
# @overload set(value)
#   Sets a value on the default key `:foo`
#   @param [Object] value describe value param
#   @return [Boolean] true when success
#
set: (args...) ->
```

The `@overload` tag must be followed by the alternative method signature that will appear in the documentation, followed by any method tag indented by two spaces.

### Virtual methods

If you copy over functions from other objects without using mixins or concerns, you can add documentation for this
virtual (or dynamic) method with the `@method` tag:

```CoffeeScript
# This class has a virtual method, that doesn't
# exist in the source but appears in the documentation.
#
# @method #set(key, value)
#   Sets a value on key
#   @param [Symbol] key describe key param
#   @param [Object] value describe value param
#
class VirtualMethods
```

The `@method` tag must be followed by the method signature that will appear in the documentation, followed
by any method tag indented by two spaces. The difference to the `@overload` tag beside the different context is that the signature should contain either the instance prefix `#` or the class prefix `.`.

### Mixins

It's common practice to mix in objects to share common logic when inheritance is not suited. You can read
more about mixins in the [The Little Book on CoffeeScript](http://arcturo.github.io/library/coffeescript/03_classes.html).

Simply mark any plain CoffeeScript object with the `@mixin` tag to have a mixin page generated that supports many tags:

```CoffeeScript
# Speed calculation for animal.
#
# @mixin
# @author Rockstar Ninja
#
Example.Animal.Speed =

  # Get the distance the animal will put back in a certain time.
  #
  # @param [Integer] time Number of seconds
  # @return [Integer] The distance in miles
  #
  distance: (time) ->
```

Next mark the target object that includes one or multiple mixins:

```CoffeeScript
# @include Example.Animal.Speed
class Example.Animal.Lion
```

and you'll see the mixin methods appear as instance methods in the lion class documentation. You can also extend a mixin:

```CoffeeScript
# @extend Example.Animal.Speed
class Example.Animal.Lion
```

so its methods will show up as class methods.

#### Concerns

A concern is a combination of two mixins, one for instance methods and the other for class methods and it's automatically detected when a mixin has both a `ClassMethods` and an `InstanceMethods` property:

```CoffeeScript
# Speed calculations for animal.
#
# @mixin
# @author Rockstar Ninja
#
Example.Animal.Speed =

  InstanceMethods:

    # Get the distance the animal will put back in a certain time.
    #
    # @param [Integer] time Number of seconds
    # @return [Integer] The distance in miles
    #
    distance: (time) ->

  ClassMethods:

    # Get the common speed of the animal in MPH.
    #
    # @param [Integer] age The age of the animal
    # @return [Integer] The speed in MPH
    #
    speed: (age) ->
```

You can use `@concern` to include and extend the correspondent properties:

```CoffeeScript
# @concern Example.Animal.Speed
class Example.Animal.Lion
```

### Non-class methods and variables

You can also document your non-class, top level functions and constants within a file. As soon Codo detects these types within a file, it will be added to the file list and you can browse your file methods and constants.

## Text processing

### GitHub Flavored Markdown

Codo class, mixin and method documentation and extra files written in
[Markdown](http://daringfireball.net/projects/markdown/) syntax are rendered as full
[GitHub Flavored Markdown](https://github.github.com/github-flavored-markdown/).

The `@return`, `@param`, `@option`, `@see`, `@author`, `@copyright`, `@note`, `@todo`, `@since`, `@version` and
`@deprecated` tags rendered with a limited Markdown syntax, which means that only inline elements will be returned.

### Automatically link references

Codo comments and all tag texts will be parsed for references to other classes, methods and mixins, and are automatically linked. The reference searching will not take place within code blocks, thus you can avoid reference searching errors by surround your code block that contains curly braces with backticks.

There are several ways of link types supported and all can take an optional label after the link.

* Normal URL links: `{http://coffeescript.org/}` or `{http://coffeescript.org/ Try CoffeeScript}`
* Link to a class or mixin: `{Animal.Lion}` or `{Animal.Lion The mighty lion}`
* Direct link to an instance method: `{Animal.Lion#walk}` or `{Animal.Lion#walk The lion walks}`
* Direct link to a class method: `{Animal.Lion.constructor}` or `{Animal.Lion.constructor A new king was born}`
* Direct link to a module method: `{MyModule~method}` or `{MyModule~method ZOMG I can even refer modules!}`

The `@see` tag supports the same link types, just without the curly braces:

```CoffeeScript
@see https://en.wikipedia.org/wiki/Lion The wikipedia page about lions
```

## Generate

After the installation you will have a `codo` binary that can be used to generate the documentation recursively for all CoffeeScript files within a directory.

```bash
$ codo --help
Usage: codo [options] [source_files [- extra_files]]

Options:
  --help, -h          Show this help                          
  --version           Show version                            
  --extension, -x     Coffee files extension                                 [default: "coffee"]
  --output, -o        The output directory                                   [default: "./doc"]
  --min-coverage, -m  Require a minimum percentage to be documented or fail  [default: 0]
  --test, -t          Do not create any output files. Use with min-coverage  [default: 0]
  --theme             The theme to be used                                   [default: "default"]
  --name, -n          The project name used                   
  --readme, -r        The readme file used                    
  --quiet, -q         Supress warnings                                       [default: false]
  --verbose, -v       Show parsing errors                                    [default: false]
  --undocumented, -u  List undocumented objects                              [default: false]
  --closure           Try to parse closure-like block comments               [default: false]
  --private, -p       Show privates                                          [default: false]
  --analytics, -a     The Google analytics ID                                [default: false]
  --title, -t         HTML Title                                             [default: "Codo Documentation"]
```

Codo wants to be smart and tries to detect the best default settings for the sources, the readme, the extra files and the project name, so the above defaults may be different on your project.

### Project defaults

You can define your project defaults by writing your command line options to a `.codoopts` file:

```bash
--name       "Codo"
--readme     README.md
--title      "Codo Documentation"
--private
--quiet
--extension  coffee
--output     ./doc
./src
-
LICENSE
CHANGELOG.md
```

Put each option flag on a separate line, followed by the source directories or files, and optionally any extra file that should be included into the documentation separated by a dash (`-`). If your extra file has the extension `.md`, it'll be rendered as Markdown.

### API usage

If you want to use codo in your build tool, you can require `codo/lib/command.coffee`:

```coffeescript
CodoCLI = require 'codo/lib/command.coffee'
codoCLI = new CodoCLI()
codoCLI.generate "path/to/base/dir", options, (exitCode) -> process.exit exitCode
```

`option` is an object with options as above. Please note that they are *not* CamelCase (e.g. `min-coverage`
 instead of `minCoverage`). Furthermore only global defaults will be used, project defaults are ignored
 if Codo is used via API.

## Keyboard navigation

You can quickly search and jump through the documentation by using the fuzzy finder dialog:

* Open fuzzy finder dialog: `T`

In frame mode you can toggle the list naviation frame on the left side:

* Toggle list view: `L`

You can focus a list in frame mode or toggle a tab in frameless mode:

* Class list: `C`
* Mixin list: `I`
* File list: `F`
* Method list: `M`
* Extras list: `E`

You can focus and blur the search input:

* Focus search input: `S`
* Blur search input: `Esc`

In frameless mode you can close the list tab:

* Close list tab: `Esc`

## Report issues

Issues hosted at [GitHub Issues](https://github.com/coffeedoc/codo/issues).

The Codo specs are template based, so make sure you provide a code snippet that can be added as failing spec to the
project when reporting an issue with parsing your CoffeeScript code. The other thing that might be useful is the actual exception happening (run with `-d`).

## Development

Source hosted at [GitHub](https://github.com/coffeedoc/codo).

Pull requests are very welcome! Please try to follow these simple rules if applicable:

* Please create a topic branch for every separate change you make.
* Make sure your patches are well tested.
* Update the documentation.
* Update the README.
* Update the CHANGELOG for noteworthy changes.
* Please **do not change** the version number.

## Alternatives

* [Docco](http://jashkenas.github.io/docco/) is a quick-and-dirty, literate-programming-style documentation generator.
* [CoffeeDoc](https://github.com/omarkhan/coffeedoc) an alternative API documentation generator for CoffeeScript.
* [JsDoc](https://github.com/micmath/jsdoc) an automatic documentation generator for JavaScript.
* [Dox](https://github.com/tj/dox) JavaScript documentation generator for node using markdown and jsdoc.

## Core Team

* [Boris Staal](https://github.com/inossidabile) ([@_inossidabile](http://twitter.com/#!/_inossidabile))
* [Michael Kessler](https://github.com/netzpirat) ([@netzpirat](http://twitter.com/#!/netzpirat), [FlinkFinger](http://www.blackbeans.ch))

## Acknowledgment

- [Jeremy Ashkenas](https://github.com/jashkenas) for [CoffeeScript](http://coffeescript.org/), that mighty language
that compiles to JavaScript and makes me enjoy JavaScript development.
- [Loren Segal](https://github.com/lsegal) for creating YARD and giving me the perfect documentation syntax for
dynamic programming languages.
- [Stratus Editor](https://github.com/stratuseditor) for open sourcing their [fuzzy filter](https://github.com/stratuseditor/fuzzy-filter).

## License

(The MIT License)

Copyright (c) 2012-2016 Michael Kessler, Boris Staal

Template components are derivative works of YARD (http://yardoc.org)  
Copyright (c) Loren Segal and licensed under the MIT license

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/coffeedoc/codo/trend.png)](https://bitdeli.com/free "Bitdeli Badge")



================================================
FILE: bin/codo
================================================
#!/usr/bin/env node

'use strict';

var compiler = require('coffee-script');
var location = require('path').join(
  __dirname, '..', 'lib', 'command'
)

if (compiler.register) {
  compiler.register();
}

require(location).run();

================================================
FILE: lib/_entities.coffee
================================================
module.exports = Entities = {}

================================================
FILE: lib/_meta.coffee
================================================
module.exports = Meta = {}

================================================
FILE: lib/_tools.coffee
================================================
module.exports = Tools = {}

================================================
FILE: lib/codo.coffee
================================================
FS          = require 'fs'
Path        = require 'path'
walkdir     = require 'walkdir'
Winston     = require 'winston'

module.exports = Codo =

  Environment: require './environment'

  Tools:
    Markdown:   require './tools/markdown'
    Referencer: require './tools/referencer'

  Entities:
    File:      require './entities/file'
    Class:     require './entities/class'
    Method:    require './entities/method'
    Variable:  require './entities/variable'
    Property:  require './entities/property'
    Mixin:     require './entities/mixin'
    Extra:     require './entities/extra'

  Meta:
    Method:    require './meta/method'
    Parameter: require './meta/parameter'

  version: ->
    JSON.parse(
      FS.readFileSync(Path.join(__dirname, '..', 'package.json'), 'utf-8')
    )['version']

  parseProject: (path, options={}) ->
    options.name      ||= @detectName(path)
    options.readme    ||= @detectReadme(path)
    options.basedir   ||= path
    options.extension ||= 'coffee'

    environment = new @Environment(options)

    if environment.options.readme
      environment.readExtra(Path.join path, environment.options.readme)

    for extra in (options.extras || @detectExtras(path))
      environment.readExtra(Path.join path, extra)

    for input in (options.inputs || [path])
      if FS.existsSync(input)
        if FS.lstatSync(input).isDirectory()
          for filename in walkdir.sync(input) when filename.match("\\._?#{options.extension}$")
            environment.readCoffee(filename)
        else
          environment.readCoffee(Path.resolve input)
      else
        Winston.warn("#{input} (#{Path.join process.cwd(), input}) skipped – does not exist")

    environment.linkify()
    environment

  detectDefaults: (path) ->
    results =
      _: []

    try
      if FS.existsSync(Path.join path, '.codoopts')
        configs = FS.readFileSync Path.join(path, '.codoopts'), 'utf8'

        for config in configs.split('\n')
          # Key value configs
          if option = /^-{1,2}([\w-]+)\s+(['"])?(.*?)\2?$/.exec config
            results[option[1]] = option[3]

          # Boolean configs
          else if bool = /^-{1,2}([\w-]+)\s*$/.exec config
            results[bool[1]] = true

          # Argv configs
          else if config != ''
            results._.push(config)

      results

    catch error
      Winston.error("Cannot parse .codoopts file: #{error.message}") unless @quiet


  # Find the project name by either parse `package.json`
  # or get the current working directory name.
  #
  detectName: (path) ->
    if FS.existsSync(Path.join path, 'package.json')
      name = JSON.parse(FS.readFileSync Path.join(path, 'package.json'), 'utf-8')['name']

    if !name && FS.existsSync(Path.join path, '.git', 'config')
      config = FS.readFileSync(Path.join(path, '.git', 'config'), 'utf-8')
      name   = /github\.com[:/][^/]+\/(.*)\.git/.exec(config)?[1]

    if !name
      name = Path.basename(path)

    return name.charAt(0).toUpperCase() + name.slice(1)

  # Find the project README.
  #
  detectReadme: (path) ->
    attempts = [
      'README.markdown'
      'README.md'
      'README'
    ]

    return attempt for attempt in attempts when FS.existsSync(Path.join path, attempt)

  # Find extra project files.
  #
  detectExtras: (path) ->
    [
      'CHANGELOG'
      'CHANGELOG.markdown'
      'CHANGELOG.md'
      'AUTHORS'
      'AUTHORS.md'
      'AUTHORS.markdown'
      'LICENSE'
      'LICENSE.md'
      'LICENSE.markdown'
      'LICENSE.MIT'
      'LICENSE.GPL'
      'README.markdown'
      'README.md'
      'README'
    ].filter (attempt) -> FS.existsSync(Path.join path, attempt)


================================================
FILE: lib/command.coffee
================================================
Path     = require 'path'
Codo     = require './codo'
Optimist = require 'optimist'
Theme    = require '../themes/default/lib/theme'
Table    = require 'cli-table'
colors   = require 'colors/safe'

module.exports = class Command
  options: [
    {name: 'help', alias: 'h', describe: 'Show this help'}
    {name: 'version', describe: 'Show version'}
    {name: 'extension', alias: 'x', describe: 'Coffee files extension', default: 'coffee'}
    {name: 'output', alias: 'o', describe: 'The output directory', default: './doc'}
    {name: 'min-coverage', alias: 'm', describe: 'Require a minimum percentage to be documented or fail', default: '0'}
    {name: 'output-dir'}
    {name: 'theme', describe: 'The theme to be used', default: 'default'}
    {name: 'name', alias: 'n', describe: 'The project name used'}
    {name: 'readme', alias: 'r', describe: 'The readme file used'}
    {name: 'quiet', alias: 'q', describe: 'Supress warnings', boolean: true, default: false}
    {name: 'verbose', alias: 'v', describe: 'Show parsing errors', boolean: true, default: false}
    {name: 'undocumented', alias: 'u', describe: 'List undocumented objects', boolean: true, default: false}
    {name: 'closure', describe: 'Try to parse closure-like block comments', boolean: true, default: false}
    {name: 'debug', alias: 'd', boolean: true}
  ]

  @run: ->
    new @().run (code) ->
      process.exit code

  extendOptimist: (optimist, defaults={}, options={}) ->
    for option in options
      optimist.options option.name,
        alias: option.alias,
        describe: option.describe,
        boolean: option.boolean,
        default: defaults[option.name] || defaults[option.alias] || option.default

  lookupTheme: (name) ->
    if name == 'default'
      @theme = Theme
    else
      try
        @theme = require "codo-theme-#{name}"
      catch
        try
          @theme = require Path.resolve("node_modules/codo-theme-#{name}")
        catch
          console.log "Error loading theme #{name}: are you sure you have codo-theme-#{name} package installed?"
          process.exit()

  prepareOptions: (optimist, defaults) ->
    options = optimist.argv
    options._.push entry for entry in defaults._

    keyword = 'inputs'
    for entry in options._
      if entry == '-'
        keyword = 'extras'
      else
        options[keyword] ?= []
        options[keyword].push entry

    delete options._

    options

  run: (cb) ->
    defaults = Codo.detectDefaults(process.cwd())

    optimist = Optimist.usage('Usage: $0 [options] [source_files [- extra_files]]')
    @extendOptimist(optimist, defaults, @options)

    @theme = @lookupTheme(optimist.argv.theme)
    @extendOptimist(optimist, defaults, @theme::options)

    @options = @prepareOptions(optimist, defaults)

    if @options['output-dir']
      console.log "The usage of outdated `--output-dir` option detected. Please switch to `--output`."
      process.exit()

    if @options.help
      console.log optimist.help()
    else if @options.version
      console.log Codo.version()
    else
      @generate(process.cwd(), @options, cb)

  collectStats: (environment) ->
    sections =
      Classes:
        total: environment.allClasses().length
        undocumented: environment.allClasses().filter((e) -> !e.documentation?).map (x) ->
          [x.name, x.file.path]

      Mixins:
        total: environment.allMixins().length
        undocumented: environment.allMixins().filter((e) -> !e.documentation?).map (x) ->
          [x.name, x.file.path]

      Methods:
        total: environment.allMethods().length
        undocumented: environment.allMethods().filter((e) -> !e.entity.documentation?).map (x) ->
          ["#{x.entity.name} (#{x.owner.name})", x.owner.file.path]

    sections

  generate: (dir = process.cwd(), options = @options, cb) ->
    for option in @options
      if option.default?
        options[option.name] ?= option.default
    @theme ?= @lookupTheme(options.theme)

    for option in @theme::options
      if option.default?
        options[option.name] ?= option.default

    environment = Codo.parseProject(dir, options)
    sections    = @collectStats(environment)

    unless options.test
      @theme.compile(environment)

    overall      = 0
    undocumented = 0

    for section, data of sections
      overall      += data.total
      undocumented += data.undocumented.length

    if options.undocumented
      for section, data of sections when data.undocumented.length != 0
        table = new Table
          head: [section, 'Path']

        table.push(entry) for entry in data.undocumented
        unless options.test
          console.log table.toString()
          console.log ''
    else
      table = new Table
        head: ['', 'Total', 'Undocumented']

      undocumented_percent = 100/overall*undocumented || 0

      table.push(
        ['Files', environment.allFiles().length, ''],
        ['Extras', environment.allExtras().length, ''],
        ['Classes', sections['Classes'].total, sections['Classes'].undocumented.length],
        ['Mixins', sections['Mixins'].total, sections['Mixins'].undocumented.length],
        ['Methods', sections['Methods'].total, sections['Methods'].undocumented.length]
      )

      unless options.test
        console.log table.toString()
        console.log ''
        console.log "  Totally documented: #{(100 - undocumented_percent).toFixed(2)}%"
        console.log ''

    documentedRatio = 100 - (100*undocumented/overall).toFixed(2)
    if documentedRatio < options["min-coverage"]
      unless options.test
        console.error colors.red("  Expected " + options["min-coverage"] +
                       "% to be documented, but only " + documentedRatio + "% were.")
      cb 1 if cb
    else
      cb() if cb


================================================
FILE: lib/documentation.coffee
================================================
module.exports = class Documentation

  constructor: (comment) ->
    @parseTags(comment)
  
  # Parse the given lines and adds the result
  # to the result object.
  #
  # @param [Array<String>] lines the lines to parse
  #
  parseTags: (lines) ->
    comment = []

    while (line = lines.shift()) isnt undefined

      # Look ahead
      unless /^@example|@overload|@method|@event/.exec line
        while /^\s{2}\S+/.test(lines[0])
          line += lines.shift().substring(1)

      if property = /^@nodoc/i.exec line
        @nodoc = true

      if property = /^@property\s+[\[\{](.+?)[\]\}](?:\s+(.+))?/i.exec line
        @property = property[1]
        lines.unshift property[2] if property[2]?

      else if returns = /^@return\s+[\[\{](.+?)[\]\}](?:\s+(.+))?/i.exec line
        @returns =
          type: returns[1]
          description: returns[2]

      else if returns = /^@return\s+(.+)/i.exec line
        @returns =
          type: '?'
          description: returns[1]

      else if throws = /^@throw\s+[\[\{](.+?)[\]\}](?:\s+(.+))?/i.exec line
        @throws ?= []
        @throws.push
          type: throws[1]
          description: throws[2]

      else if throws = /^@throw\s+(.+)/i.exec line
        @throws ?= []
        @throws.push
          type: '?'
          description: throws[1]

      else if param = /^@param\s+[\[\{](.+?)[\]}]\s+\[([^\]]+)](?:\s+(.+))?/i.exec line
        @params ?= []
        if paramNameVal = /^([^ ]+)\s*=\s*([^ ]+)/.exec param[2]
          paramName = paramNameVal[1]
          defValue = paramNameVal[2]
        else
          defValue = null
          paramName = param[2]
        @params.push
          type: param[1]
          name: paramName
          description: param[3]
          defaultState: defValue
          optional: yes

      else if param = /^@param\s+([^ ]+)\s+[\[\{](.+?)[\]\}](?:\s+(.+))?/i.exec line
        @params ?= []
        @params.push
          type: param[2]
          name: param[1]
          description: param[3]

      else if param = /^@param\s+[\[\{](.+?)[\]\}]\s+([^ ]+)(?:\s+(.+))?/i.exec line
        @params ?= []
        @params.push
          type: param[1]
          name: param[2]
          description: param[3]

      else if option = /^@option\s+([^ ]+)\s+[\[\{](.+?)[\]\}]\s+([^ ]+)(?:\s+(.+))?/i.exec line
        @options ?= {}
        @options[option[1]] ?= []

        @options[option[1]].push
          type: option[2]
          name: option[3]
          description: option[4]

      else if option = /^@option\s+([^ ]+)\s+([^ ]+)\s+[\[\{](.+?)[\]\}](?:\s+(.+))?/i.exec line
        @options ?= {}
        @options[option[1]] ?= []

        @options[option[1]].push
          type: option[3]
          name: option[2]
          description: option[4]

      else if see = /^@see\s+([^\s]+)(?:\s+(.+))?/i.exec line
        @see ?= []
        @see.push
          reference: see[1]
          label: see[2]

      else if author = /^@author\s+(.+)/i.exec line
        @authors ?= []
        @authors.push author[1] || ''

      else if copyright = /^@copyright\s+(.+)/i.exec line
        @copyright = copyright[1] || ''

      else if note = /^@note\s+(.+)/i.exec line
        @notes ?= []
        @notes.push note[1] || ''

      else if todo = /^@todo\s+(.+)/i.exec line
        @todos ?= []
        @todos.push todo[1] || ''

      else if example = /^@example(?:\s+(.+))?/i.exec line
        title = example[1] || ''
        code = []

        while /^\s{2}.*/.test(lines[0]) or (/^$/.test(lines[0]) and /^\s{2}.*/.test(lines[1]))
          code.push lines.shift().substring(2)

        if code.length isnt 0
          @examples ?= []
          @examples.push
            title: title
            code: code.join '\n'

      else if namespace = /^@namespace\s+(.+)/i.exec line
        @namespace = namespace[1] || ''

      else if abstract = /^@abstract(?:\s+(.+))?/i.exec line
        @abstract = abstract[1] || ''

      else if /^@private/.exec line
        @private = true

      else if /^@public/.exec line
        @public = true
      
      else if since = /^@since\s+(.+)/i.exec line
        @since = since[1] || ''

      else if version = /^@version\s+(.+)/i.exec line
        @version = version[1] || ''

      else if deprecated = /^@deprecated(\s+)?(.*)/i.exec line
        @deprecated = deprecated[2] || ''

      else if mixin = /^@mixin/i.exec line
        @mixin = true

      else if concern = /^@concern\s+(.+)/i.exec line
        @concerns ?= []
        @concerns.push concern[1]

      else if include = /^@include\s+(.+)/i.exec line
        @includes ?= []
        @includes.push include[1]

      else if extend = /^@extend\s+(.+)/i.exec line
        @extends ?= []
        @extends.push extend[1]

      else if event = /^@event\s+(\S+)(\s+(.+))?/i.exec line
        @events ?= []

        innerComment = []
        innerComment.push(event[2]) if event[2]
        doc = {}

        while /^\s{2}.*/.test(lines[0]) || /^\s*$/.test(lines[0])
          innerComment.push lines.shift().substring(2)

        @parseTags.call(doc, innerComment) if innerComment

        @events.push
          name: event[1]
          documentation: doc

      else if overload = /^@overload\s+(.+)/i.exec line
        signature = overload[1]
        innerComment = []

        while /^\s{2}.*/.test(lines[0]) || /^\s*$/.test(lines[0])
          innerComment.push lines.shift().substring(2)

        if innerComment.length != 0
          @overloads ?= []

          doc = {}
          @parseTags.call doc, innerComment

          @overloads.push
            signature: signature
            documentation: doc

      else if method = /^@method\s+(.+)/i.exec line
        signature = method[1]
        innerComment = []

        while /^\s{2}.*/.test(lines[0]) or /^\s*$/.test(lines[0])
          innerComment.push lines.shift().substring(2)

        if innerComment.length isnt 0
          @methods ?= []

          doc = {}
          @parseTags.call doc, innerComment

          @methods.push
            signature: signature
            documentation: doc
      else
        comment.push line

    text = comment.join('\n')
    @comment = text.trim()

    sentence = /((?:.|\n)*?[.#][\s$])/.exec(text)
    sentence = sentence[1].replace(/\s*#\s*$/, '') if sentence
    @summary = (sentence || text || '').trim()

  inspect: ->
    {
      comment: @comment
      summary: @summary
      notes: @notes
      see: @see

      namespace: @namespace
      abstract: @abstract
      private: @private
      public: @public
      deprecated: @deprecated
      version: @version
      since: @since

      authors: @authors
      copyright: @copyright
      todos: @todos

      includes: @includes
      extends: @extends
      concerns: @concerns
      
      examples: @examples
      
      params: @params
      options: @options
      returns: @returns
      throws: @throws
      overloads: @overloads

      events: @events
      methods: @methods
      property: @property
    }


================================================
FILE: lib/entities/class.coffee
================================================
Entity     = require '../entity'
Method     = require './method'
Variable   = require './variable'
Property   = require './property'
Mixin      = require './mixin'
MetaMethod = require '../meta/method'
Entities   = require '../_entities'
Winston    = require 'winston'

module.exports = class Entities.Class extends Entity
  @name = "Class"

  @looksLike: (node) ->
    node.constructor.name is 'Class' && node.variable?.base?.value?

  constructor: (@environment, @file, @node) ->
    [@selfish, @container] = @determineContainment(@node.variable)

    @parent        = @fetchParent(@node.parent) if @node.parent
    @documentation = @node.documentation

    @name        = @fetchName(@node.variable, @selfish, @container)
    @methods     = []
    @variables   = []
    @properties  = []
    @includes    = []
    @extends     = []
    @concerns    = []
    @descendants = []

    name = @name.split('.')
    @basename  = name.pop()
    @namespace = @documentation?.namespace or name.join('.')

    if @environment.options.debug
      Winston.info "Creating new Class Entity"
      Winston.info " name: " + @name
      Winston.info " documentation: " + @documentation

    @

  # Determines if the class definition at given node is using @assignation
  # and if in such case this class is nested into another one
  determineContainment: (node) ->
    if node.base?.value == 'this'
      selfish   = true                   # class @Foo
      container = @lookup(Class, node)   # class Foo \n class @Bar

    [selfish, container]

  fetchParent: (source) ->
    [selfish, container] = @determineContainment(source)
    @fetchName(source, selfish, container)

  fetchName: (source, selfish, container) ->
    name = []

    # Nested class definition inherits 
    # the namespace from the containing class
    name.push container.name if container

    # Take the actual name of assignation unless
    # we are prefixed with `@`
    name.push source.base.value if !selfish && source.base?

    # Get the rest of actual assignation path
    if source.properties
      name.push prop.name.value for prop in source.properties when prop.name?

    # Here comes the magic!
    name.join('.')

  linkify: ->
    super

    for node in @node.body.expressions

      if node.constructor.name == 'Assign' && node.entities?
        @linkifyAssign(node)

      if node.constructor.name == 'Value'
        @linkifyValue(node)

      if node.constructor.name == 'Call' && node.entities?
        @linkifyCall(node)

    @linkifyParent()
    @linkifyMixins()

  linkifyAssign: (node) ->
    for entity in node.entities when entity.selfish
      # class Foo
      #   @foo = ->            
      if entity instanceof Method
        entity.kind = 'static'
        @methods.push entity

      # class Foo
      #   @foo = 'test'
      if entity instanceof Variable 
        entity.kind = 'static'
        @variables.push entity

  linkifyValue: (node) ->
    for property in node.base.properties when property.entities?
      for entity in property.entities
        # class Foo
        #   @foo: ->
        #   foo: ->
        if entity instanceof Method
          entity.kind = if entity.selfish then 'static' else 'dynamic'
          @methods.push entity

        # class Foo
        #   foo: 'test'
        if entity instanceof Variable 
          entity.kind = if entity.selfish then 'static' else 'dynamic'
          @variables.push entity

        if entity instanceof Property
          @properties.push entity

  linkifyCall: (node) ->
    for entity in node.entities
      if entity instanceof Property
        found = false

        for property in @properties
          if property.name == entity.name
            entity.unite(property)
            found = true

        @properties.push(entity) unless found

  linkifyParent: ->
    if @parent
      @parent = @environment.find(Class, @parent) || @parent
      @parent.descendants?.push(@)

  linkifyMixins: ->
    if @documentation?.includes?
      for entry in @documentation.includes
        mixin = @environment.find(Mixin, entry) || entry
        @includes.push(mixin)
        mixin.inclusions?.push(@)

    if @documentation?.extends?
      for entry in @documentation.extends
        mixin = @environment.find(Mixin, entry) || entry
        @extends.push(mixin)
        mixin.extensions?.push(@)

    if @documentation?.concerns?
      for entry in @documentation.concerns
        mixin = @environment.find(Mixin, entry) || entry
        @concerns.push(mixin)
        mixin.concerns?.push(@)

  effectiveMethods: ->
    return @_effectiveMethods if @_effectiveMethods?

    @_effectiveMethods = []

    for method in @methods
      @_effectiveMethods.push(MetaMethod.fromMethodEntity method)

    if @documentation?.methods
      for method in @documentation.methods
        @_effectiveMethods.push(MetaMethod.fromDocumentationMethod method)

    @_effectiveMethods

  allMethods: ->
    methods = @effectiveMethods().map (method) =>
      {
        entity: method
        owner: @
      }

    resolvers =
      includes: 'effectiveInclusionMethods'
      extends: 'effectiveExtensionMethods'
      concerns: 'effectiveConcernMethods'

    for storage, resolver of resolvers
      for mixin in @[storage]
        if mixin[resolver]
          for method in mixin[resolver]()
            methods.push
              entity: method
              owner: mixin

    methods

  inherited: (getter) ->
    return [] if !@parent || !@parent.name?

    found   = {}
    entries = getter()

    entries.filter (entry) ->
      found[entry.entity.name] = true unless found[entry.entity.name]

  inheritedMethods: ->
    @_inheritedMethods ||= @inherited =>
      @parent.allMethods().concat @parent.inheritedMethods()

  inheritedVariables: ->
    @_inheritedVariables ||= @inherited =>
      variables = @parent.variables.map (variable) =>
        {
          entity: variable
          owner: @parent
        }

      variables.concat @parent.inheritedVariables()

  inheritedProperties: ->
    @_inheritedProperties ||= @inherited =>
      properties = @parent.properties.map (property) =>
        {
          entity: property
          owner: @parent
        }

      properties.concat @parent.inheritedProperties()

  inspect: ->
    {
      file:          @file.path
      documentation: @documentation?.inspect()
      selfish:       @selfish
      name:          @name
      container:     @container?.inspect()
      parent:        @parent?.inspect?() || @parent
      methods:       @methods.map (x) -> x.inspect()
      variables:     @variables.map (x) -> x.inspect()
      properties:    @properties.map (x) -> x.inspect()
      includes:      @includes.map (x) -> x.inspect?() || x
      extends:       @extends.map (x) -> x.inspect?() || x
      concerns:      @concerns.map (x) -> x.inspect?() || x
    }

================================================
FILE: lib/entities/extra.coffee
================================================
FS       = require 'fs'
Path     = require 'path'
Entities = require '../_entities'
Markdown = require '../tools/markdown'

module.exports = class Entities.Extra
  @name: "Extra"

  constructor: (@environment, @path) ->
    @name    = Path.relative(@environment.options.basedir, @path)
    @content = FS.readFileSync @path, 'utf-8'

    if @environment.options.debug
      Winston.info "Creating new Extra Entity"
      Winston.info " name: " + @name
      Winston.info " content: " + @content

    @parsed = if /\.(markdown|md)$/.test @path
      Markdown.convert(@content)
    else
      "<p>"+@content.replace(/\n/g, '<br/>')+"</p>"

  linkify: ->

  inspect: ->
    {
      path: @path,
      parsed: @parsed
    }

================================================
FILE: lib/entities/file.coffee
================================================
Entity     = require '../entity'
Path       = require 'path'
Method     = require './method'
Variable   = require './variable'
Mixin      = require './mixin'
Class      = require './class'
MetaMethod = require '../meta/method'
Entities   = require '../_entities'
Winston    = require 'winston'

module.exports = class Entities.File extends Entity
  @Name: "File"

  constructor: (@environment, @path, @node) ->
    @file      = @
    @name      = Path.relative(@environment.options.basedir, @path)
    @basename  = Path.basename(@name)
    @dirname   = Path.dirname(@name)
    @methods   = []
    @variables = []
    @mixins    = []
    @classes   = []
    if @environment.options.debug
      Winston.info "Creating new File Entity"
      Winston.info " name: " + @name
      Winston.info " path: " + @path

  linkify: ->
    super

    for node in @node.expressions
      # Checking direct members
      unless entities = node.entities
        # And members prefixed with `module.exports =`
        if node.variable?.base?.value == 'module'
          if node.variable?.properties?[0]?.name?.value == 'exports'
            entities = node.value?.entities

      if entities
        for entity in entities
          if entity instanceof Method
            @methods.push(entity) if entity.name.length > 0
          if entity instanceof Variable
            @variables.push entity
          if entity instanceof Mixin
            @mixins.push entity
          if entity instanceof Class
            @classes.push entity

  effectiveMethods: ->
    @_effectiveMethods ||= @methods.map (method) -> MetaMethod.fromMethodEntity method

  inspect: ->
    {
      file:          @name
      methods:       @methods.map (x) -> x.inspect()
      variables:     @variables.map (x) -> x.inspect()
    }


================================================
FILE: lib/entities/method.coffee
================================================
Entity    = require '../entity'
Parameter = require '../meta/parameter'
Entities  = require '../_entities'
Winston = require 'winston'

module.exports = class Entities.Method extends Entity
  @name: "Method"

  @looksLike: (node) ->
    node.constructor.name == 'Assign' && node.value?.constructor.name == 'Code'

  constructor: (@environment, @file, @node) ->
    Winston.info "Creating new Method Entity" if @environment.options.debug

    @name = [@node.variable.base.value]
    @name.push prop.name.value for prop in @node.variable.properties when prop.name?

    if @name[0] == 'this'
      @selfish = true
      @name    = @name.slice(1)

    if @name[0] == 'module' && @name[1] == 'exports'
      @name = @name.slice(2)

    if @name[0] == 'exports'
      @name = @name.slice(1)

    @name  = @name.join('.')
    @bound = @node.value.bound

    @documentation = @node.documentation

    @parameters = @node.value.params.map (node) ->
      Parameter.fromNode(node)

    if @environment.options.debug
      Winston.info " name: " + @name
      Winston.info " documentation: " + @documentation

  inspect: ->
    {
      file:          @file.path
      name:          @name
      bound:         @bound
      documentation: @documentation?.inspect()
      selfish:       @selfish
      kind:          @kind
      parameters:    @parameters.map (x) -> x.inspect()
    }


================================================
FILE: lib/entities/mixin.coffee
================================================
Entity     = require '../entity'
Method     = require './method'
Variable   = require './variable'
MetaMethod = require '../meta/method'
Entities   = require '../_entities'
Winston    = require 'winston'

module.exports = class Entities.Mixin extends Entity
  @name: "Mixin"

  @looksLike: (node) ->
    node.constructor.name == 'Assign' && node.value?.base?.properties?

  @is: (node) ->
    node.documentation?.mixin && super(node)

  @isConcernSection: (node) ->
    node.constructor.name == 'Assign' &&
    node.value?.constructor.name == 'Value' &&
    (
      node.variable.base.value == 'ClassMethods' ||
      node.variable.base.value == 'InstanceMethods'
    )

  constructor: (@environment, @file, @node) ->
    [@name, @selfish] = @fetchName()

    @documentation = @node.documentation
    @methods       = []
    @variables     = []
    @inclusions    = []
    @extensions    = []
    @concerns      = []

    for property in @node.value.base.properties
      # Recognize assigned code on the mixin
      @concern = true if @constructor.isConcernSection(property)

    if @concern
      @classMethods = []
      @instanceMethods = []

    name = @name.split('.')
    @basename  = name.pop()
    @namespace = @documentation?.namespace or name.join('.')
    if @environment.options.debug
      Winston.info "Creating new Mixin Entity"
      Winston.info " name: " + @name
      Winston.info " documentation: " + @documentation


  linkify: ->
    super

    @grabMethods @methods, @node

    if @concern
      for property in @node.value.base.properties
        # Recognize concerns as inner mixins
        if property.value?.constructor.name is 'Value'
          switch property.variable.base.value
            when 'ClassMethods'
              @grabMethods @classMethods, property

            when 'InstanceMethods'
              @grabMethods @instanceMethods, property

  grabMethods: (container, node) ->
    for property in node.value.base.properties
      if property.entities?
        for entity in property.entities
          # Foo =
          #   foo: ->
          container.push entity if entity instanceof Method

  aggregateEffectiveMethods: (kind) ->
    methods   = []
    overrides = {}

    overrides.kind = kind if kind?

    for method in @methods
      methods.push(MetaMethod.fromMethodEntity method, overrides)

    if @documentation.methods
      for method in @documentation.methods
        methods.push(MetaMethod.fromDocumentationMethod method, overrides)

    methods

  effectiveMethods: ->
    return @effectiveConcernMethods() if @concern
    @_effectiveMethods ||= @aggregateEffectiveMethods()

  effectiveInclusionMethods: ->
    @_effectiveInclusionMethods ||= @aggregateEffectiveMethods('dynamic')

  effectiveExtensionMethods: ->
    @_effectiveExtensionMethods ||= @aggregateEffectiveMethods('static')

  effectiveConcernMethods: ->
    return @_effectiveConcernMethods if @_effectiveConcernMethods?

    @_effectiveConcernMethods = []

    for method in @classMethods
      @_effectiveConcernMethods.push(MetaMethod.fromMethodEntity method, kind: 'static')

    for method in @instanceMethods
      @_effectiveConcernMethods.push(MetaMethod.fromMethodEntity method, kind: 'dynamic')

    if @documentation.methods
      for method in @documentation.methods
        @_effectiveConcernMethods.push(MetaMethod.fromDocumentationMethod method)

    @_effectiveConcernMethods

  inspect: ->
    {
      file:            @file.path
      name:            @name
      concern:         @concern
      documentation:   @documentation?.inspect()
      selfish:         @selfish
      methods:         @methods.map (x) -> x.inspect()
      classMethods:    @classMethods?.map (x) -> x.inspect()
      instanceMethods: @instanceMethods?.map (x) -> x.inspect()
      variables:       @variables.map (x) -> x.inspect()
    }


================================================
FILE: lib/entities/property.coffee
================================================
Entity   = require '../entity'
Entities = require '../_entities'
Winston  = require 'winston'

#
# Supported formats:
#
#   foo: []
#
#   get foo: ->
#   set foo: (value) ->
#
#   @property 'foo'
#   @property 'foo', ->
#   @property 'foo',
#     get: ->
#     set: (value) ->
#
module.exports = class Entities.Property extends Entity
  @name: "Property"

  @looksLike: (node) ->
    (node.constructor.name == 'Assign' && node.value?.constructor.name == 'Value') ||
    (node.constructor.name == 'Call' && node.variable?.base?.value == 'this') ||
    (
      node.constructor.name == 'Call' &&
      node.args?[0]?.base?.properties?[0]?.variable?.base?.value &&
      (node.variable?.base?.value == 'set' || node.variable?.base?.value == 'get')
    )

  @is: (node) ->
    super(node) && (
      node.documentation?.property || 
      (node.constructor.name == 'Call' && node.variable?.base?.value != 'this')
    )

  constructor: (@environment, @file, @node) ->
    if @node.constructor.name == 'Call' && @node.variable?.base?.value != 'this'
      @name   = @node.args[0].base.properties[0].variable.base.value
      @setter = @node.variable.base.value == 'set'
      @getter = @node.variable.base.value == 'get'
    else if @node.constructor.name == 'Call' && @node.variable?.base?.value == 'this'
      @name = @node.args[0].base.value.replace(/["']/g, '')

      if @node.args.length > 1
        if @node.args[1].constructor.name == 'Value'
          # @property 'test', {set: ->, get: ->}
          @setter = false
          @getter = false
          for property in @node.args[1].base?.properties
            @setter = true if property.variable?.base.value == 'set'
            @getter = true if property.variable?.base.value == 'get'
        else
          # @property 'test', ->
          @setter = false
          @getter = true
      else
        # @property 'test'
        @setter = true
        @getter = true
    else
      [@name, @selfish] = @fetchVariableName()
      @setter = true
      @getter = true

    @documentation = @node.documentation
    if @environment.options.debug
      Winston.info "Creating new Property Entity"
      Winston.info " name: " + @name
      Winston.info " documentation: " + @documentation


  fetchVariableName: ->
    @fetchName()

  unite: (property) ->
    for attribute in ['documentation', 'getter', 'setter']
      property[attribute] = @[attribute] = property[attribute] || @[attribute]

  inspect: ->
    {
      file:          @file.path
      name:          @name
      getter:        @getter
      setter:        @setter
      documentation: @documentation?.inspect()
    }


================================================
FILE: lib/entities/variable.coffee
================================================
Entity   = require '../entity'
Entities = require '../_entities'
Winston  = require 'winston'

module.exports = class Entities.Variable extends Entity
  @name: "Variable"

  @looksLike: (node) ->
    node.constructor.name == 'Assign' && node.value?.constructor.name == 'Value' && node.variable?.base?.value? && node.value.base.constructor.name isnt 'Call'

  @is: (node) ->
    !node.documentation?.property && !node.documentation?.mixin && super(node)

  constructor: (@environment, @file, @node) ->
    [@name, @selfish] = @fetchName()

    @constant = /^[A-Z_-]*$/.test @name

    try
      @value = @node.value.base.compile
        indent: ''

      # Workaround to replace CoffeeScript internal
      # representations with something reasonable
      @value = 'undefined' if @value == 'void 0'

    @documentation = @node.documentation
    if @environment.options.debug
      Winston.info "Creating new Variable Entity"
      Winston.info " name: " + @name
      Winston.info " documentation: " + @documentation

  inspect: ->
    {
      file:          @file.path
      name:          @name
      constant:      @constant
      value:         @value
      documentation: @documentation?.inspect()
      selfish:       @selfish
      kind:          @kind
    }


================================================
FILE: lib/entity.coffee
================================================
# Base class for all entities.
#
module.exports = class Entity

  @is: (node) ->
    !node.documentation?.nodoc

  linkify: ->

  visible: ->
    @environment.options.private || !@node.documentation?.private

  fetchName: ->
    name = [@node.variable.base.value]
    name.push prop.name.value for prop in @node.variable.properties when prop.name?

    if name[0] == 'this'
      selfish = true
      name    = name.slice(1)

    [name.join('.'), selfish]

  lookup: (Entity, node) ->
    if node.ancestor
      if node.ancestor.entities?
        for entity in node.ancestor.entities
          return entity if entity instanceof Entity

      @lookup Entity, node.ancestor

================================================
FILE: lib/environment.coffee
================================================
FS        = require 'fs'
Path      = require 'path'
Traverser = require './traverser'

File      = require './entities/file'
Class     = require './entities/class'
Method    = require './entities/method'
Variable  = require './entities/variable'
Property  = require './entities/property'
Mixin     = require './entities/mixin'
Extra     = require './entities/extra'
walkdir   = require 'walkdir'
Winston   = require 'winston'

module.exports = class Environment

  @read: (files, options={}) ->
    files       = [files] unless Array.isArray(files)
    environment = new @(options)

    environment.readCoffee(file) for file in files
    environment.linkify()
    environment

  constructor: (@options={}) ->
    @version = JSON.parse(
      FS.readFileSync(Path.join(__dirname, '..', 'package.json'), 'utf-8')
    )['version']

    @options.name    ?= 'Unknown Project'
    @options.verbose ?= false
    @options.debug   ?= false
    @options.cautios ?= false
    @options.quiet   ?= false
    @options.closure ?= false
    @options.output  ?= 'doc'
    @options.basedir ?= process.cwd()

    @needles    = []
    @entities   = []
    @references = {}
    @parsed     = {}

    @needles.push Class
    @needles.push Method
    @needles.push Variable
    @needles.push Property
    @needles.push Mixin

  readCoffee: (file) ->
    return if @parsed[file]
    Winston.info("Parsing Codo file #{file}") if @options.verbose

    try
      Traverser.read(file, @)
    catch error
      throw error if @options.debug
      Winston.error("Cannot parse Coffee file #{file}: #{error.message}") unless @options.quiet
    finally
      @parsed[file] = true

  readExtra: (file) ->
    return if @parsed[file]
    Winston.info("Parsing Extra file #{file}") if @options.verbose

    try
      @registerEntity(new Extra @, file)
    catch error
      throw error if @options.debug
      Winston.error("Cannot parse Extra file #{file}: #{error.message}") unless @options.quiet
    finally
      @parsed[file] = true

  registerEntity: (entity) ->
    @entities.push entity

  all: (Entity, haystack = []) ->
    for entity in @entities
      haystack.push(entity) if entity instanceof Entity
    haystack

  visibleFiles:     -> @allFiles()
  visibleClasses:   -> @allClasses().filter((x) -> x.visible())
  visibleMixins:    -> @allMixins().filter((x) -> x.visible())
  visibleExtras:    -> @allExtras()
  visibleMethods:   -> @allMethods().filter((x) -> x.entity.visible && x.owner.visible())
  visibleVariables: -> @allVariables()

  allFiles:   -> @_allFiles   ||= @all(File)
  allClasses: -> @_allClasses ||= @all(Class)
  allMixins:  -> @_allMixins  ||= @all(Mixin)
  allExtras:  -> @_allExtras  ||= @all(Extra)
  allMethods: ->
    return @_allMethods if @_allMethods?

    @_allMethods = []

    for source in [@allFiles(), @allClasses(), @allMixins()]
      for entry in source
        for method in entry.effectiveMethods()
          @_allMethods.push {entity: method, owner: entry}

    @_allMethods.sort (a, b) ->
      return -1 if a.entity.name < b.entity.name
      return 1  if a.entity.name > b.entity.name
      return 0

  allVariables: ->
    return @_allVariables if @_allVariables?

    @_allVariables = []

    for source in [@allFiles(), @allClasses(), @allMixins()]
      for entry in source
        for variable in entry.variables
          @_allVariables.push {entity: variable, owner: entry}

    @_allVariables


  find: (Entity, name) ->
    for entity in @entities
      if entity instanceof Entity && entity.name == name
        return entity

  findReadme: ->
    @find Extra, Path.relative(@options.basedir, @options.readme)

  linkify: ->
    entity.linkify() for entity in @entities

    for basics in [@allFiles(), @allClasses(), @allMixins()]
      for basic in basics
        @references[basic.name] = basic

    for variable in @allVariables()
      keyword = variable.owner.name + '.' + variable.entity.name
      @references[keyword] = variable

    for method in @allMethods()
      keyword = method.owner.name + method.entity.shortSignature()
      @references[keyword] = method

  reference: (needle, context='') ->
    needle = needle.split(' ')[0]

    if @references[needle]
      @references[needle]
    else if @references[context+needle]
      @references[context+needle]
    else
      needle

  inspect: ->
    @entities.map (entity) -> entity.inspect()

================================================
FILE: lib/meta/method.coffee
================================================
Parameter = require './parameter'
Meta      = require '../_meta'

module.exports = class Meta.Method

  @override: (options, overrides) ->
    options[key] = value for key, value of overrides
    options

  @fromMethodEntity: (entity, overrides={}) ->
    options =
      name: entity.name.match(/[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*/)?[0]
      kind: entity.kind || ''
      bound: entity.bound
      parameters: entity.parameters.map (x) -> x.toString()
      visible: entity.visible()
      documentation: entity.documentation

    new @(@override options, overrides)

  @fromDocumentationMethod: (entry, overrides={}) ->
    kind = switch entry.signature[0]
      when '#'
        'dynamic'
      when '.'
        'static'

    options =
      name: entry.signature.replace /^[\#\.]?["']?([^\("']+)\(.+/, '$1'
      kind: kind || ''
      parameters: Parameter.fromSignature(entry.signature).map (x) -> x.toString()
      documentation: entry.documentation
      visible: true # force this to be always visible

    new @(@override options, overrides)

  constructor: (options={}) ->
    @constructor.override @, options

  effectiveOverloads: ->
    return @_effectiveOverloads if @_effectiveOverloads?

    @_effectiveOverloads = []

    if @documentation?.overloads
      for overload in @documentation.overloads
        @_effectiveOverloads.push(Method.fromDocumentationMethod overload)
    else
      @_effectiveOverloads.push(@)

    @_effectiveOverloads

  kindSignature: ->
    switch @kind
      when 'dynamic'
        '#'
      when 'static'
        '.'
      else
        '~'

  shortSignature: ->
    @kindSignature() + @name

  typeSignature: ->
    '('+(@documentation?.returns?.type || 'void')+')'

  paramsSignature: ->
    '('+@parameters.join(', ')+')'

  inspect: ->
    {
      name: @name,
      kind: @kind,
      bound: @bound,
      parameters: @parameters
    }


================================================
FILE: lib/meta/parameter.coffee
================================================
CoffeeScript = require 'coffee-script'
Meta         = require '../_meta'

module.exports = class Meta.Parameter

  @fromNode: (node) ->
    new @ @fetchName(node), !!node.splat, @fetchDefault(node)

  @fromSignature: (signature) ->
    signature = signature.replace /^.([^\(]+)/, "x="
    nodes = CoffeeScript.nodes("#{signature} ->").expressions[0].value.params
    nodes.map (node) => @fromNode(node)

  @fetchName: (node) ->
    # Normal attribute `do: (it) ->`
    name = node.name.value

    # Named parameters a la python:
    #  `make_fac : ({numerator, divisor}) ->`
    # Also works for class constructors:
    #  `constructor : ( { @name, @key, opts }) ->
    unless name
      if (o = node.name.objects)?
        vars = for v in o
          if v.base
            if v.base.value is 'this' then v.properties[0].name.value
            else v.base.value
          else if v.variable && v.value
            "#{v.variable.base.value}:#{v.value.base.value}"
          else throw new Error('Unhandled syntax')
        name = "{#{vars.join ', '}}"

    # Assigned attributes `do: (@it) ->`
    unless name
      if node.name.properties
        name = node.name.properties[0]?.name.value

    name

  @fetchDefault: (node) ->
    try
      node.value?.compile
        indent: ''

    catch error
      if node?.value?.base?.value is 'this'
        value = node.value.properties[0]?.name.compile
          indent: ''

        "@#{value}"

  constructor: (@name, @splat, @default) ->

  toString: ->
    splat = '...' if @splat
    defauld = " = #{@default}" if @default

    [@name, splat, defauld].join('')

  inspect: ->
    {
      name: @name
      splat: @splat
      default: @default
    }


================================================
FILE: lib/tools/markdown.coffee
================================================
marked = require 'marked'
Tools  = require '../_tools'

# It looks like all the markdown libraries for node doesn't get
# GitHub flavored markdown right. This helper class post-processes
# the best available output from the marked library to conform to
# GHM. In addition the allowed tags can be limited.
#
module.exports = class Tools.Markdown

  # Tags to keep when parsing is limited
  @limitedTags: 'a,abbr,acronym,b,big,cite,code,del,em,i,ins,sub,sup,span,small,strike,strong,q,tt,u'

  # Convert markdown to Html. If the param `limit`
  # is true, then all unwanted elements are stripped from the
  # result and also all existing newlines.
  #
  # @param [String] markdown the markdown markup
  # @param [Boolean] limit if elements should be limited
  #
  @convert: (markdown, limit = false, allowed = Markdown.limitedTags) ->
    return if markdown is undefined

    html = marked(markdown)

    if limit
      html = html.replace(/\n/, ' ')
      html = Markdown.limit(html, allowed)

    # Remove newlines around open and closing paragraph tags
    html = html.replace /(?:\n+)?<(\/?p)>(?:\n+)?/mg, '<$1>'

    # Add '.html' to relative markdown links
    html = html.replace /href="(?!https?:\/\/)(.*\.md)"/mg, 'href="$1.html"'

    html

  # Strips all unwanted tag from the html
  #
  # @param [String] html the Html to clean
  # @param [String] allowed the comma separated list of allowed tags
  # @return [String] the cleaned Html
  #
  @limit: (html, allowed) ->
    allowed = allowed.split ','

    replace = (html) ->
      result = html.replace /<([a-z0-9]+)\s*(?:\s[^>]+)?>([\s\S]+?)<\/\1>/g, (match, tag, text) ->
        if allowed.indexOf(tag) is -1 then text else match
      if result == html
        result
      else
        replace(result)
    replace(html)



================================================
FILE: lib/tools/referencer.coffee
================================================
Tools = require '../_tools'

module.exports = class Tools.Referencer

  constructor: (@environment) ->

  resolve: (text, replacer) ->
    # Make curly braces within code blocks undetectable
    text = text.replace /\`[^\`]*\`/mg, (match) -> match.replace(/\{/mg, "\u0091").replace(/\}/mg, "\u0092")

    # Search for references and replace them
    text = text.replace /\{([^\}]*)\}/gm, (match, link) =>
      link  = link.split(' ')
      href  = link.shift()
      label = link.join(' ')

      replacement = @environment.reference(href)

      if replacement != href || /\:\/\/\w+((\:\d+)?\/\S*)?/.test(href)
        replacer replacement, label || href
      else
        match

    # Restore curly braces within code blocks
    text = text.replace /\`[^\`]*\`/mg, (match) -> match.replace(/\u0091/mg, '{').replace(/\u0092/mg, '}')


================================================
FILE: lib/traverser.coffee
================================================
FS            = require 'fs'
_             = require 'underscore'
_.str         = require 'underscore.string'
CoffeeScript  = require 'coffee-script'
Environment   = require './environment'
Documentation = require './documentation'
File          = require './entities/file'
Winston       = require 'winston'

#
# The class takes CS nodes tree and recursively injects
# additional meta-data into it:
#
#   1. For each possible node it tries every registered
#      entity and pushes an instance of it into tree if it suites.
#   2. For every suitable node it finds the suitable comment block
#      respecting things like `this.` and `module.exports =` and
#      links it to the tree as well.
#
# Since the transformation is happening upside down, nested entities
# can interact with initialized parents (for instance a class can find
# parent class; method can find the class/mixin/file it belongs to).
#
module.exports = class Traverser

  @read: (file, environment) ->
    content = FS.readFileSync(file, 'utf8')
    content = @convertComments(content, environment.options.closure) unless environment.options.cautios

    new @(file, content, environment)

  # Attach each parent to its children, so we are able
  # to traverse the ancestor parse tree. Since the
  # parent attribute is already used in the class node,
  # the parent is stored as `ancestor`.
  #
  # @param [Base] nodes the CoffeeScript nodes
  #
  @linkAncestors: (node) ->
    node.eachChild (child) =>
      child.ancestor = node
      @linkAncestors child

    node

  # Convert the comments to block comments,
  # so they appear in the nodes.
  #
  # The methods replaces starting # symbols with invisible
  # unicode whitespace to keep empty lines formatted.
  #
  # @param [String] content the CoffeeScript file content
  #
  @convertComments: (content, closure=false) ->
    result         = []
    comment        = []
    inComment      = false
    inBlockComment = false
    indentComment  = 0

    for line in content.split('\n')

      blockComment = /^\s*#{3}/.exec(line) && !/^\s*#{3}.+#{3}/.exec(line)

      if blockComment || inBlockComment
        line = line.replace /#{3}\*/, "###" if closure
        inBlockComment = !inBlockComment if blockComment
        result.push line
      else
        commentLine = /^(\s*#)\s?(\s*.*)/.exec(line)
        if commentLine
          if inComment
            comment.push @whitespace(indentComment) + commentLine[2]?.replace /#/g, "\u0091#"
          else
            inComment = true
            indentComment =  commentLine[1].length - 1

            comment.push @whitespace(indentComment) + '###'
            comment.push @whitespace(indentComment) + commentLine[2]?.replace /#/g, "\u0091#"
        else
          if inComment
            inComment = false
            comment.push @whitespace(indentComment) + '###'

            # Push here comments only before certain lines
            if ///
                 ( # class Foo
                   class\s*@?[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*
                 | # variable =
                   ^\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff.]*\s+\=
                 | # method: ->
                   (?:[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*|["'].*["'])\s*:\s*(\(.*\)\s*)?[-=]>
                 | # @method = ->
                   @[A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*\s*=\s*(\(.*\)\s*)?[-=]>
                 | # CONSTANT
                   ^\s*@[$A-Z_][A-Z_]*
                 | # property:
                   ^\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*:
                 | # @property 'foo'
                   @[A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*\s+['"].+['"]
                 )
               ///.exec line

              result.push c for c in comment

            comment = []

          result.push line

    result.join('\n')

  # Whitespace helper function
  #
  # @param [Number] n the number of spaces
  # @return [String] the space string
  #
  @whitespace: (n) ->
    a = []
    while a.length < n
      a.push ' '
    a.join ''

  constructor: (@path, @content, @environment) ->
    @environment ?= new Environment
    @history      = []
    @root         = @constructor.linkAncestors(CoffeeScript.nodes @content)
    @file         = @prepare(@root, @path, File)

    @root.traverseChildren true, (node) =>
      for Entity in @environment.needles when Entity.looksLike(node)
        Winston.info "Adding entity " + Entity.name if @environment.options.debug
        @prepare(node, @file, Entity)

      @history.push node

  prepare: (node, file, Entity) ->
    node.entities ?= []

    unless node.documentation?
      # Find actual comment node
      previous = @history[@history.length-1]

      if @environment.options.debug
        Winston.info "Type of previous is " + previous?.constructor.name
        Winston.info "History is " + @history.map (entry) -> entry.constructor.name

      switch previous?.constructor.name
        # A comment is preceding the entity declaration
        when 'Comment'
          doc = previous

        when 'Literal', 'PropertyName'
          # The node is exported `module.exports = ...`, take the comment before `module`
          if previous.value is 'exports'
            previous = @history[@history.length-6]
            doc = previous if previous?.constructor.name is 'Comment'

        # An assign that is handled as an object by CoffeeScript
        when 'Obj'
          if @history[@history.length-2]?.constructor.name is 'Value'
            previous = @history[@history.length-3]
            doc = previous if previous?.constructor.name is 'Comment'

        # An operator precedes the definition, e.g. `new class ClassName`
        when 'Op'
          previous = @history[@history.length-2]
          doc = previous if previous?.constructor.name is 'Comment'

      Winston.info "Doc is " + doc?.comment if @environment.options.debug
      if doc?.comment?
        node.documentation = new Documentation(@leftTrimBlock doc.comment)

    if Entity.is(node)
      entity = new Entity @environment, file, node

      node.entities.push(entity)
      @environment.registerEntity(entity)

      entity

  # Detect whitespace on the left and removes
  # the minimum whitespace ammount.
  #
  # The method additionally drops invisible UTF
  # whitespace introduced by `convertComments`
  #
  # @example left trim all lines
  #   leftTrimBlock(['', '  Escape at maximum speed.', '', '  @param (see #move)', '  '])
  #   => ['', 'Escape at maximum speed.', '', '@param (see #move)', '']
  #
  # This will keep indention for examples intact.
  #
  # @param [Array<String>] lines the comment lines
  # @return [Array<String>] lines left trimmed lines
  #
  leftTrimBlock: (text) ->
    return unless text

    lines = text.replace(/\u0091/gm, '').split('\n')

    # Detect minimal left trim amount
    trimMap = lines.map (line) ->
      line.length - _.str.ltrim(line).length if line.length != 0

    minimalTrim = _.min _.without(trimMap, undefined)

    # If we have a common amount of left trim
    if minimalTrim > 0 && minimalTrim < Infinity

      # Trim same amount of left space on each line
      lines = for line in lines
        line = line.substring(minimalTrim, line.length)
        line

    # Strip empty prepending lines
    lines = lines.slice(1) while lines[0].length == 0

    # Strip empty postponing lines
    lines = lines.slice(0, -1) while lines[lines.length-1].length == 0

    lines

  inspect: ->
    @environment.inspect()


================================================
FILE: package.json
================================================
{
  "name": "codo",
  "description": "A CoffeeScript documentation generator.",
  "keywords": [
    "coffeescript",
    "doc"
  ],
  "author": "Michael Kessler <michi@netzpiraten.ch>",
  "maintainers": [
    {
      "name": "Michael Kessler"
    },
    {
      "name": "Boris Staal"
    }
  ],
  "version": "2.1.2",
  "license": "MIT",
  "engines": {
    "node": ">=0.9.0"
  },
  "directories": {
    "lib": "./src",
    "theme/default/assets": "./theme/default/assets",
    "theme/default/templates": "./theme/default/templates"
  },
  "main": "./lib/codo.coffee",
  "bin": {
    "codo": "./bin/codo"
  },
  "dependencies": {
    "coffee-script": ">= 1.6.0",
    "walkdir": ">= 0.0.2",
    "optimist": ">= 0.3.0",
    "marked": ">= 0.2.10",
    "underscore": ">= 0.1.0",
    "underscore.string": ">= 0.1.0",
    "haml-coffee": ">= 0.6.0",
    "mkdirp": ">= 0.1.0",
    "connect": ">= 0.1.0",
    "colors": ">= 1.1.2",
    "async": ">= 0.1.22",
    "mincer": "~0.5.11",
    "stylus": "~0.38.0",
    "nib": "~1.0.0",
    "winston": "~0.8.0",
    "cli-table": "~0.2.0",
    "strftime": "~0.6.2"
  },
  "devDependencies": {
    "diff": ">=2.1.1",
    "jasmine-node": ">= 1.13.1",
    "deep-eql": "*",
    "rimraf": "~2.2.2",
    "grunt": "~0.4.1",
    "grunt-release": "~0.6.0"
  },
  "homepage": "https://github.com/coffeedoc/codo",
  "repository": {
    "type": "git",
    "url": "git://github.com/coffeedoc/codo.git"
  },
  "bugs": {
    "url": "https://github.com/coffeedoc/codo/issues"
  },
  "scripts": {
    "test": "jasmine-node --coffee spec"
  }
}


================================================
FILE: spec/_templates/angular/angular-with-new.coffee
================================================
module.exports = require('angular').module 'module-name', ['some-dependency']
.factory 'a-factory', ['some-dependency', (someDependency) ->
  ###
   This is a testy test class with a documenty documentation
  ###
  new class MyTestClass
]
.name

================================================
FILE: spec/_templates/angular/angular-with-new.json
================================================
[
  {
    "file": "spec/_templates/angular/angular-with-new.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/angular/angular-with-new.coffee",
    "documentation": {
      "comment": "This is a testy test class with a documenty documentation",
      "summary": "This is a testy test class with a documenty documentation"
    },
    "name": "MyTestClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/angular/angular.coffee
================================================
module.exports = require('angular').module 'module-name', ['some-dependency']
.factory 'a-factory', ['some-dependency', (someDependency) ->
  ###
   This is a testy test class with a documenty documentation
  ###
  class MyTestClass
]
.name

================================================
FILE: spec/_templates/angular/angular.json
================================================
[
  {
    "file": "spec/_templates/angular/angular.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/angular/angular.coffee",
    "documentation": {
      "comment": "This is a testy test class with a documenty documentation",
      "summary": "This is a testy test class with a documenty documentation"
    },
    "name": "MyTestClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/class_description_markdown.coffee
================================================
# Codo - the CoffeeScript API documentation generator
#
# # Header 1
#
# This is a paragraph.
#
# ## Header 2
#
# This is a paragraph.
#
# ### Header 3
#
# This is a paragraph.
#
# #### Header 4
#
# This is a paragraph.
#
# ##### Header 5
#
# This is a paragraph.
#
# ###### Header 6
#
# This is a paragraph.
#
# @abstract _Template methods_ must be implemented
# @note Also notes have _now_ <del>Markdown</del>
# @todo Allow **markdown** in todos
#
# @author Mickey
# @author **Donald**
# @copyright _No Copyright_
# @since **1.0.0**
# @version _1.1.0_
# @deprecated **nobody** uses this
#
class TestMarkdownDocumentation


================================================
FILE: spec/_templates/classes/class_description_markdown.json
================================================
[
  {
    "file": "spec/_templates/classes/class_description_markdown.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/class_description_markdown.coffee",
    "documentation": {
      "comment": "Codo - the CoffeeScript API documentation generator\n\n# Header 1\n\nThis is a paragraph.\n\n## Header 2\n\nThis is a paragraph.\n\n### Header 3\n\nThis is a paragraph.\n\n#### Header 4\n\nThis is a paragraph.\n\n##### Header 5\n\nThis is a paragraph.\n\n###### Header 6\n\nThis is a paragraph.",
      "summary": "Codo - the CoffeeScript API documentation generator",
      "notes": [
        "Also notes have _now_ <del>Markdown</del>"
      ],
      "abstract": "_Template methods_ must be implemented",
      "deprecated": "**nobody** uses this",
      "version": "_1.1.0_",
      "since": "**1.0.0**",
      "authors": [
        "Mickey",
        "**Donald**"
      ],
      "copyright": "_No Copyright_",
      "todos": [
        "Allow **markdown** in todos"
      ]
    },
    "name": "TestMarkdownDocumentation",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/class_documentation.coffee
================================================
# This is a test class with `inline.dot`. Beware.
#
# @note Please use
#   this carefully
# @note For internal use only
#
# @example
#   Class.getType('cat')
#
# @example Use it in this way
#   new Class()
#
# @example Alternatively also this is possible
#   cl = Class.for(obj)
#   cl.execute()
#
# @todo Clean up socket handler
# @todo Refactor
#   property factory
# @author Netzpirat
# @author Plasticman
# @abstract Each listener implementation must inherit
# @private
# @public
# @deprecated Use other class
#   which is thread safe
# @since 1.0.0
# @version 1.0.2
#
class TestClassDocumentation


================================================
FILE: spec/_templates/classes/class_documentation.json
================================================
[
  {
    "file": "spec/_templates/classes/class_documentation.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/class_documentation.coffee",
    "documentation": {
      "comment": "This is a test class with `inline.dot`. Beware.",
      "summary": "This is a test class with `inline.dot`.",
      "notes": [
        "Please use this carefully",
        "For internal use only"
      ],
      "abstract": "Each listener implementation must inherit",
      "private": true,
      "public": true,
      "deprecated": "Use other class which is thread safe",
      "version": "1.0.2",
      "since": "1.0.0",
      "authors": [
        "Netzpirat",
        "Plasticman"
      ],
      "todos": [
        "Clean up socket handler",
        "Refactor property factory"
      ],
      "examples": [
        {
          "title": "",
          "code": "Class.getType('cat')"
        },
        {
          "title": "Use it in this way",
          "code": "new Class()"
        },
        {
          "title": "Alternatively also this is possible",
          "code": "cl = Class.for(obj)\ncl.execute()"
        }
      ]
    },
    "name": "TestClassDocumentation",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]


================================================
FILE: spec/_templates/classes/class_extends.coffee
================================================
class NS.Clazz extends Another.Clazz


================================================
FILE: spec/_templates/classes/class_extends.json
================================================
[
  {
    "file": "spec/_templates/classes/class_extends.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/class_extends.coffee",
    "name": "NS.Clazz",
    "parent": "Another.Clazz",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/empty_class.coffee
================================================
class A

class extends A

================================================
FILE: spec/_templates/classes/empty_class.json
================================================
[
  {
    "file": "spec/_templates/classes/empty_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/empty_class.coffee",
    "name": "A",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/export_class.coffee
================================================
# Yep, this should be assigned to the class
module.exports = class TestExportClass


================================================
FILE: spec/_templates/classes/export_class.json
================================================
[
  {
    "file": "spec/_templates/classes/export_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/export_class.coffee",
    "documentation": {
      "comment": "Yep, this should be assigned to the class",
      "summary": "Yep, this should be assigned to the class"
    },
    "name": "TestExportClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/global_class.coffee
================================================
# This is a test class
class @GlobalTestClass

================================================
FILE: spec/_templates/classes/global_class.json
================================================
[
  {
    "file": "spec/_templates/classes/global_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/global_class.coffee",
    "documentation": {
      "comment": "This is a test class",
      "summary": "This is a test class"
    },
    "selfish": true,
    "name": "GlobalTestClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/inner_class.coffee
================================================
class Tower.Model.Relation.HasMany extends Tower.Model.Relation
  class @Scope 
  class @Scope2 extends @Scope

================================================
FILE: spec/_templates/classes/inner_class.json
================================================
[
  {
    "file": "spec/_templates/classes/inner_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/inner_class.coffee",
    "name": "Tower.Model.Relation.HasMany",
    "parent": "Tower.Model.Relation",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/classes/inner_class.coffee",
    "selfish": true,
    "name": "Tower.Model.Relation.HasMany.Scope",
    "container": {
      "file": "spec/_templates/classes/inner_class.coffee",
      "name": "Tower.Model.Relation.HasMany",
      "parent": "Tower.Model.Relation",
      "methods": [],
      "variables": [],
      "properties": [],
      "includes": [],
      "extends": [],
      "concerns": []
    },
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/classes/inner_class.coffee",
    "selfish": true,
    "name": "Tower.Model.Relation.HasMany.Scope2",
    "container": {
      "file": "spec/_templates/classes/inner_class.coffee",
      "name": "Tower.Model.Relation.HasMany",
      "parent": "Tower.Model.Relation",
      "methods": [],
      "variables": [],
      "properties": [],
      "includes": [],
      "extends": [],
      "concerns": []
    },
    "parent": {
      "file": "spec/_templates/classes/inner_class.coffee",
      "selfish": true,
      "name": "Tower.Model.Relation.HasMany.Scope",
      "container": {
        "file": "spec/_templates/classes/inner_class.coffee",
        "name": "Tower.Model.Relation.HasMany",
        "parent": "Tower.Model.Relation",
        "methods": [],
        "variables": [],
        "properties": [],
        "includes": [],
        "extends": [],
        "concerns": []
      },
      "methods": [],
      "variables": [],
      "properties": [],
      "includes": [],
      "extends": [],
      "concerns": []
    },
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/namespaced_class.coffee
================================================
# Test description
class Some.Namespace.MyClass

# Test description
class @Another.Namespace.MyClass

# Test description
# @namespace Manual.Namespace
class MyClass

================================================
FILE: spec/_templates/classes/namespaced_class.json
================================================
[
  {
    "file": "spec/_templates/classes/namespaced_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/namespaced_class.coffee",
    "documentation": {
      "comment": "Test description",
      "summary": "Test description"
    },
    "name": "Some.Namespace.MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/classes/namespaced_class.coffee",
    "documentation": {
      "comment": "Test description",
      "summary": "Test description"
    },
    "selfish": true,
    "name": "Another.Namespace.MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/classes/namespaced_class.coffee",
    "documentation": {
      "comment": "Test description",
      "summary": "Test description",
      "namespace": "Manual.Namespace"
    },
    "name": "MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/classes/simple_class.coffee
================================================
class MyTestClass


================================================
FILE: spec/_templates/classes/simple_class.json
================================================
[
  {
    "file": "spec/_templates/classes/simple_class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/classes/simple_class.coffee",
    "name": "MyTestClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/complicateds/methods.coffee
================================================
# @include Mixin
# @extend Mixin
# @concern Concern
#
# @method #x(key, value)
#   Sets a value
#
class Class
  z: ->

# @mixin
Mixin =
  m: ->

# @mixin
Concern =
  ClassMethods:
    cs: ->

  InstanceMethods:
    cd: ->

class Subclass extends Class
  x: ->

class Subsubclass extends Subclass
  y: ->

================================================
FILE: spec/_templates/complicateds/variables.coffee
================================================
class Class
  z: '123'

class Subclass extends Class
  z: '456'

class Subsubclass extends Subclass
  y: '123'

================================================
FILE: spec/_templates/environment/class.coffee
================================================
#
# @include LookAndFeel
#
class Fluffy

================================================
FILE: spec/_templates/environment/mixin.coffee
================================================
#
# @mixin
#
LookAndFeel =
  look: ->
  feel: ->

================================================
FILE: spec/_templates/environment/result.json
================================================
[
  {
    "file": "spec/_templates/environment/class.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/environment/class.coffee",
    "documentation": {
      "comment": "",
      "summary": "",
      "includes": [
        "LookAndFeel"
      ]
    },
    "name": "Fluffy",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [
      {
        "file": "spec/_templates/environment/mixin.coffee",
        "name": "LookAndFeel",
        "documentation": {
          "comment": "",
          "summary": ""
        },
        "methods": [
          {
            "file": "spec/_templates/environment/mixin.coffee",
            "name": "look",
            "bound": false,
            "parameters": []
          },
          {
            "file": "spec/_templates/environment/mixin.coffee",
            "name": "feel",
            "bound": false,
            "parameters": []
          }
        ],
        "variables": []
      }
    ],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/environment/mixin.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/environment/mixin.coffee",
    "name": "LookAndFeel",
    "documentation": {
      "comment": "",
      "summary": ""
    },
    "methods": [
      {
        "file": "spec/_templates/environment/mixin.coffee",
        "name": "look",
        "bound": false,
        "parameters": []
      },
      {
        "file": "spec/_templates/environment/mixin.coffee",
        "name": "feel",
        "bound": false,
        "parameters": []
      }
    ],
    "variables": []
  },
  {
    "file": "spec/_templates/environment/mixin.coffee",
    "name": "look",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/environment/mixin.coffee",
    "name": "feel",
    "bound": false,
    "parameters": []
  }
]

================================================
FILE: spec/_templates/example/CHANGELOG
================================================
Changelog

This project is actually so incredible that it never changes.

Seriously!!!

================================================
FILE: spec/_templates/example/README.md
================================================
# Readme

That's how we do it, this is how we do it (c)

================================================
FILE: spec/_templates/example/package.json
================================================
{
  "name": "example",
  "description": "The best ever project about lines and wildness!",
  "keywords": [
    "coffeescript",
    "doc"
  ],
  "version": "0.1.0"
}

================================================
FILE: spec/_templates/example/src/angry_animal.coffee
================================================
# Ola-la
# @abstract
TROLOLO = 'test'

# @mixin
Example.AngryAnimal =
  roar: ->

# Ola-la once more
#
# @overload ?globalMethod(a, b)
#   Overload this animal for once!
#
# @deprecated Don't use it anymore!
globalMethod = ({a, b}) ->

================================================
FILE: spec/_templates/example/src/animal.coffee
================================================
# Base class for all animals.
#
# @note This is not used for codo, its purpose is to show
#   all possible tags within a class.
#
# @todo Provide more examples
#
# @example How to subclass an animal
#   class Lion extends Animal
#     move: (direction, speed): ->
#
# @abstract Each animal implementation must inherit from {Animal}
#
# @author Michael Kessler
# @deprecated This class is not used anymore
# @version 0.2.0
# @since 0.1.0
#
class Example.Animal

  # The Answer to the Ultimate Question of Life, the Universe, and Everything
  @ANSWER = 42

  # Construct a new animal.
  #
  # @todo Clean up
  # @param [String] name the name of the animal
  # @param [Date] birthDate when the animal was born
  #
  constructor: (@name, @birthDate = new Date()) ->

  # Move the animal.
  #
  # @example Move an animal
  #   new Lion('Simba').move('south', 12)
  #
  # @abstract
  # @param [Object] options the moving options
  # @option options [String] direction the moving direction
  # @option options [Number] speed the speed in mph
  #
  move: (options = {}) ->

  # Copulate another animal.
  #
  # @note Don't take it seriously
  #
  # @private
  # @author Michael Kessler
  # @param [Animal] animal the partner animal
  # @return [Boolean] true when success
  # @deprecated Do not copulate
  # @version 0.2.0
  # @since 0.1.0
  #
  copulate: (animal) =>

  # Moves all animal into the ark.
  #
  # @return [Boolean] true when all in Ark
  #
  @enterArk: ->


================================================
FILE: spec/_templates/example/src/lion.coffee
================================================
# A dangerous lion. Take care.
#
# @author Simba
# @see http://en.wikipedia.org/wiki/Lion
# @include Example.AngryAnimal
# @extend MissingMixin
#
class Example.Animal.Lion extends Example.Animal

  # Maximum speed in MPH
  @MAX_SPEED = 50

  # Move the lion fast
  #
  # @param [String] direction the moving direction
  # @param [Number] speed the moving speed
  #
  move: (direction, speed) ->
    super({ diection: direction, speed: speed })

  # Escape at maximum speed.
  #
  # @param (see #move)
  #
  escape: (direction) ->
    @move(direction, @MAX_SPEED)


================================================
FILE: spec/_templates/example/src/over_documented_class.coffee
================================================
#
# This class is SO DOCUMENTED! Seriously, Just look at that! This is so incredible!
#
# It even has some links: {http://www.google.com Google for instance} {OverDocumentedClass}
# {OverDocumentedClass itself} {http://www.github.com} {OverDocumentedMixin~mixed_method}
# {Casper The ghost!}
#
# @abstract It's so abstract! ^_^ {http://www.github.com}
# @author The great Yoda {http://www.github.com}
# @include OverDocumentedMixin
# @include Casper
# @extend OverDocumentedMixin
# @extend Casper
# @copyright The great Yoda {http://www.github.com}
# @deprecated Don't use this anymore!!11
# @example Foobar
#   foo = bar
# @note Never fortget this thing! {http://www.github.com}
# @method #virtual_method({a, b})
#   This is the virtual method ZOMG
# @private
# @see www.github.com
# @since 1.0
# @todo Run with the wolves {http://www.github.com}
# @version 1.1
class OverDocumentedClass

  # The constant that is SO DOCUMENTED as well (I feel sick about it)
  # @abstract It's so abstract! ^_^ {http://www.github.com}
  # @author The great Yoda {http://www.github.com}
  # @copyright The great Yoda {http://www.github.com}
  # @deprecated Don't use this anymore!!11
  # @example Foobar
  #   foo = bar
  # @note Never fortget this thing! {http://www.github.com}
  # @private
  # @see www.github.com
  # @since 1.0
  # @todo Run with the wolves {http://www.github.com}
  # @version 1.1
  CONSTANT:
    foo: 'bar'

  # @property [OverDocumentedClass] Returns the {OverDocumentedClass clone}.
  @property 'clone',
    get: -> new OverDocumentedClass

  # @abstract It's so abstract! ^_^ {http://www.github.com}
  # @author The great Yoda {http://www.github.com}
  # @copyright The great Yoda {http://www.github.com}
  # @deprecated Don't use this anymore!!11
  # @example Foobar
  #   foo = bar
  # @note Never fortget this thing! {http://www.github.com}
  # @private
  # @see www.github.com
  # @since 1.0
  # @todo Run with the wolves {http://www.github.com}
  # @version 1.1
  # @throw [OverDocumentedClass] EXCEPTION OMG
  # @return [OverDocumentedClass] RETVAL OMG
  # @param [String] foo                 The first parameter
  # @param [Integer] bar                The second parameter (all of a sudden)
  # @option options [String] option     The only option (wtf?)
  # @event simpleEvent
  # @event notSoSimpleEvent             Having description
  # @event complicatedEvent
  #   Having description and parameters
  #   @param [String]                   The string
  @class_method: (foo, bar, options={}) ->

  # @abstract It's so abstract! ^_^ {http://www.github.com}
  # @author The great Yoda {http://www.github.com}
  # @copyright The great Yoda {http://www.github.com}
  # @deprecated Don't use this anymore!!11
  # @example Foobar
  #   foo = bar
  # @note Never fortget this thing! {http://www.github.com}
  # @private
  # @see www.github.com
  # @since 1.0
  # @todo Run with the wolves {http://www.github.com}
  # @version 1.1
  # @throw [String] EXCEPTION OMG
  # @return [String] RETVAL OMG
  # @overload #instance_method(foo, bar)
  #   Obviously you can omit the last parameter
  # @overload #instance_method(foo, bar, options)
  #   Or you can set it!
  instance_method: (foo, bar, options={}) ->

================================================
FILE: spec/_templates/example/src/over_documented_mixin.coffee
================================================
#
# This mixin is SO DOCUMENTED! Seriously, Just look at that! This is so incredible!
#
# It even has some links: {http://www.google.com Google for instance} {OverDocumentedMixin}
# {OverDocumentedMixin itself} {http://www.github.com} {OverDocumentedClass.class_method}
# {Casper The ghost!}
#
# @mixin
# @abstract It's so abstract! ^_^ {http://www.github.com}
# @author The great Yoda {http://www.github.com}
# @copyright The great Yoda {http://www.github.com}
# @deprecated Don't use this anymore!!11
# @example Foobar
#   foo = bar
# @note Never fortget this thing! {http://www.github.com}
# @method #virtual_method({a, b})
#   This is the virtual method ZOMG
# @private
# @see www.github.com
# @since 1.0
# @todo Run with the wolves {http://www.github.com}
# @version 1.1
OverDocumentedMixin =

  mixed_method: ->

================================================
FILE: spec/_templates/extras/README
================================================
This is a test README

================================================
FILE: spec/_templates/extras/README.md
================================================
# This is a test README

We even have some content here. [With links!](http://github.com)

## And nested menus

And even more content

### Actually...

I feel terribly sick writing this. It's like talking to myself.

[With relative markdown links too](SomeOtherFile.md)


================================================
FILE: spec/_templates/files/non_class_file.coffee
================================================
# The greeting
GREETING = 'Hay'

# Hey, check this out!
module.exports = FOO = 'Foo constant!'

# Says hello to a person
#
# @param [String] name the name of the person
#
hello = (name) ->
  console.log GREETING, name

# Says bye to a person
#
# @param [String] name the name of the person
#
bye = (name) ->
  console.log "Bye, bye #{ name }"

# Say hi to a person
#
# @param [String] name the name of the person
#
module.exports.sayHi = (hi) -> console.log "Hi #{ hi}!"

# A fooer for fooing foos.
#
# @note Foo
module.exports = foo = (foos) ->
  logger.info 'Fooing...'

================================================
FILE: spec/_templates/files/non_class_file.json
================================================
[
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "methods": [
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "hello",
        "bound": false,
        "documentation": {
          "comment": "Says hello to a person",
          "summary": "Says hello to a person",
          "params": [
            {
              "type": "String",
              "name": "name",
              "description": "the name of the person"
            }
          ]
        },
        "parameters": [
          {
            "name": "name",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "bye",
        "bound": false,
        "documentation": {
          "comment": "Says bye to a person",
          "summary": "Says bye to a person",
          "params": [
            {
              "type": "String",
              "name": "name",
              "description": "the name of the person"
            }
          ]
        },
        "parameters": [
          {
            "name": "name",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "sayHi",
        "bound": false,
        "documentation": {
          "comment": "Say hi to a person",
          "summary": "Say hi to a person",
          "params": [
            {
              "type": "String",
              "name": "name",
              "description": "the name of the person"
            }
          ]
        },
        "parameters": [
          {
            "name": "hi",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "foo",
        "bound": false,
        "documentation": {
          "comment": "A fooer for fooing foos.",
          "summary": "A fooer for fooing foos.",
          "notes": [
            "Foo"
          ]
        },
        "parameters": [
          {
            "name": "foos",
            "splat": false
          }
        ]
      }
    ],
    "variables": [
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "GREETING",
        "constant": true,
        "value": "'Hay'",
        "documentation": {
          "comment": "The greeting",
          "summary": "The greeting"
        }
      },
      {
        "file": "spec/_templates/files/non_class_file.coffee",
        "name": "FOO",
        "constant": true,
        "value": "'Foo constant!'",
        "documentation": {
          "comment": "Hey, check this out!",
          "summary": "Hey, check this out!"
        }
      }
    ]
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "GREETING",
    "constant": true,
    "value": "'Hay'",
    "documentation": {
      "comment": "The greeting",
      "summary": "The greeting"
    }
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "FOO",
    "constant": true,
    "value": "'Foo constant!'",
    "documentation": {
      "comment": "Hey, check this out!",
      "summary": "Hey, check this out!"
    }
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "hello",
    "bound": false,
    "documentation": {
      "comment": "Says hello to a person",
      "summary": "Says hello to a person",
      "params": [
        {
          "type": "String",
          "name": "name",
          "description": "the name of the person"
        }
      ]
    },
    "parameters": [
      {
        "name": "name",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "bye",
    "bound": false,
    "documentation": {
      "comment": "Says bye to a person",
      "summary": "Says bye to a person",
      "params": [
        {
          "type": "String",
          "name": "name",
          "description": "the name of the person"
        }
      ]
    },
    "parameters": [
      {
        "name": "name",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "sayHi",
    "bound": false,
    "documentation": {
      "comment": "Say hi to a person",
      "summary": "Say hi to a person",
      "params": [
        {
          "type": "String",
          "name": "name",
          "description": "the name of the person"
        }
      ]
    },
    "parameters": [
      {
        "name": "hi",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/files/non_class_file.coffee",
    "name": "foo",
    "bound": false,
    "documentation": {
      "comment": "A fooer for fooing foos.",
      "summary": "A fooer for fooing foos.",
      "notes": [
        "Foo"
      ]
    },
    "parameters": [
      {
        "name": "foos",
        "splat": false
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/assigned_parameters.coffee
================================================
class TestAssignedParameters
  help: (@me) ->


================================================
FILE: spec/_templates/methods/assigned_parameters.json
================================================
[
  {
    "file": "spec/_templates/methods/assigned_parameters.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/assigned_parameters.coffee",
    "name": "TestAssignedParameters",
    "methods": [
      {
        "file": "spec/_templates/methods/assigned_parameters.coffee",
        "name": "help",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "me",
            "splat": false
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/assigned_parameters.coffee",
    "name": "help",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "me",
        "splat": false
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/class_methods.coffee
================================================
class TestClassMethods

  @helper: ->

  @another: (a, b) ->

  @withDefault: (a = 2, c, d = 'hi', d, e = { a: 2 }, f = new TestClassMethods()) ->

  @nowWithSpalt: (foo, bar...) ->

  @andSoDoesThis = (foo, bar) ->


================================================
FILE: spec/_templates/methods/class_methods.json
================================================
[
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "TestClassMethods",
    "methods": [
      {
        "file": "spec/_templates/methods/class_methods.coffee",
        "name": "helper",
        "bound": false,
        "selfish": true,
        "kind": "static",
        "parameters": []
      },
      {
        "file": "spec/_templates/methods/class_methods.coffee",
        "name": "another",
        "bound": false,
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "a",
            "splat": false
          },
          {
            "name": "b",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/class_methods.coffee",
        "name": "withDefault",
        "bound": false,
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "a",
            "splat": false,
            "default": "2"
          },
          {
            "name": "c",
            "splat": false
          },
          {
            "name": "d",
            "splat": false,
            "default": "'hi'"
          },
          {
            "name": "d",
            "splat": false
          },
          {
            "name": "e",
            "splat": false,
            "default": "{\n  a: 2\n}"
          },
          {
            "name": "f",
            "splat": false,
            "default": "new TestClassMethods()"
          }
        ]
      },
      {
        "file": "spec/_templates/methods/class_methods.coffee",
        "name": "nowWithSpalt",
        "bound": false,
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "foo",
            "splat": false
          },
          {
            "name": "bar",
            "splat": true
          }
        ]
      },
      {
        "file": "spec/_templates/methods/class_methods.coffee",
        "name": "andSoDoesThis",
        "bound": false,
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "foo",
            "splat": false
          },
          {
            "name": "bar",
            "splat": false
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "helper",
    "bound": false,
    "selfish": true,
    "kind": "static",
    "parameters": []
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "another",
    "bound": false,
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "a",
        "splat": false
      },
      {
        "name": "b",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "withDefault",
    "bound": false,
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "a",
        "splat": false,
        "default": "2"
      },
      {
        "name": "c",
        "splat": false
      },
      {
        "name": "d",
        "splat": false,
        "default": "'hi'"
      },
      {
        "name": "d",
        "splat": false
      },
      {
        "name": "e",
        "splat": false,
        "default": "{\n  a: 2\n}"
      },
      {
        "name": "f",
        "splat": false,
        "default": "new TestClassMethods()"
      }
    ]
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "a",
    "constant": false,
    "value": "2"
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "nowWithSpalt",
    "bound": false,
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "foo",
        "splat": false
      },
      {
        "name": "bar",
        "splat": true
      }
    ]
  },
  {
    "file": "spec/_templates/methods/class_methods.coffee",
    "name": "andSoDoesThis",
    "bound": false,
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "foo",
        "splat": false
      },
      {
        "name": "bar",
        "splat": false
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/curly_method_documentation.coffee
================================================
class App.TestMethodDocumentation extends App.Doc

  # Should be overloaded to change fetch limit.
  #
  # @return Number of items per fetch
  #
  fetchLimit: () -> 5

  # Do it!
  #
  # @see #undo for more information
  #
  # @private
  # @param {String} it The thing to do
  # @param again {Boolean} Do it again
  # @param {Object} options The do options
  # @option options {String} speed The speed
  # @option options {Number} repeat How wany time to repeat
  # @option options {Array<Tasks>} tasks The tasks to do
  # @return {Boolean} When successful executed
  #
  do: (it, again, options) ->

  # Do it!
  #
  # @see #undo for more information
  #
  # @private
  # @param {String} it The thing to do
  # @param again {Boolean} Do it again
  # @param {Object} options The do options
  # @option options {String} speed The speed
  # @option options {Number} repeat How wany time to repeat
  # @option options {Array<Tasks>} tasks The tasks to do
  # @return {Boolean} When successful executed
  #
  doWithoutSpace:(it, again, options)->

  # Do it!
  #
  # @see {#undo} for more information
  #
  # @private
  # @param {String} it The thing to do
  # @param {Object} options The do options
  # @option options {String} speed The speed
  # @option options {Number} repeat How wany time to repeat
  # @option options {Array<Tasks>} tasks The tasks to do
  # @return {Boolean} When successful executed
  #
  @lets_do_it = (it, options) ->


================================================
FILE: spec/_templates/methods/curly_method_documentation.json
================================================
[
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "name": "App.TestMethodDocumentation",
    "parent": "App.Doc",
    "methods": [
      {
        "file": "spec/_templates/methods/curly_method_documentation.coffee",
        "name": "fetchLimit",
        "bound": false,
        "documentation": {
          "comment": "Should be overloaded to change fetch limit.",
          "summary": "Should be overloaded to change fetch limit.",
          "returns": {
            "type": "?",
            "description": "Number of items per fetch"
          }
        },
        "kind": "dynamic",
        "parameters": []
      },
      {
        "file": "spec/_templates/methods/curly_method_documentation.coffee",
        "name": "do",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "#undo",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Boolean",
              "name": "again",
              "description": "Do it again"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          }
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "again",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/curly_method_documentation.coffee",
        "name": "doWithoutSpace",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "#undo",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Boolean",
              "name": "again",
              "description": "Do it again"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          }
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "again",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/curly_method_documentation.coffee",
        "name": "lets_do_it",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "{#undo}",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          }
        },
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "name": "fetchLimit",
    "bound": false,
    "documentation": {
      "comment": "Should be overloaded to change fetch limit.",
      "summary": "Should be overloaded to change fetch limit.",
      "returns": {
        "type": "?",
        "description": "Number of items per fetch"
      }
    },
    "kind": "dynamic",
    "parameters": []
  },
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "name": "do",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "#undo",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Boolean",
          "name": "again",
          "description": "Do it again"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      }
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "again",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "name": "doWithoutSpace",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "#undo",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Boolean",
          "name": "again",
          "description": "Do it again"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      }
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "again",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/curly_method_documentation.coffee",
    "name": "lets_do_it",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "{#undo}",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      }
    },
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/dynamic_methods.coffee
================================================
# This class has virtual methods, which doesn't
# exist in the source but appears in the documentation.
#
# @method #set(key, value)
#   Sets a value
#   @param [String] key describe key param
#   @param [Object] value describe value param
#   @option value [String] string
#   @option value [Integer] number
#   @option value [Object] whatever
#
# @method .get(key)
#   Gets a value
#   @param [String] key describe key param
#   @return [Object] describe value param
#
# @method #delete({key, passion}, foo='bar')
#   Deletes a key from the data.
#
#   Another line
#
#   @param [String] key describe key param
#
#   @example Delete a key.
#     emv = new Example.Methods.Virtual
#     emv.set 'foo', 'bar'
#     val = emv.get 'foo'
#
#     # now, proclaim you're done with foo.
#     emv.delete 'foo'
#
# This line should be part of the class description, and the method declaration
# shouldn't have messed it up.
#
class Example.Methods.Virtual


================================================
FILE: spec/_templates/methods/dynamic_methods.json
================================================
[
  {
    "file": "spec/_templates/methods/dynamic_methods.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/dynamic_methods.coffee",
    "documentation": {
      "comment": "This class has virtual methods, which doesn't\nexist in the source but appears in the documentation.\n\nThis line should be part of the class description, and the method declaration\nshouldn't have messed it up.",
      "summary": "This class has virtual methods, which doesn't\nexist in the source but appears in the documentation.",
      "methods": [
        {
          "signature": "#set(key, value)",
          "documentation": {
            "params": [
              {
                "type": "String",
                "name": "key",
                "description": "describe key param"
              },
              {
                "type": "Object",
                "name": "value",
                "description": "describe value param"
              }
            ],
            "options": {
              "value": [
                {
                  "type": "String",
                  "name": "string"
                },
                {
                  "type": "Integer",
                  "name": "number"
                },
                {
                  "type": "Object",
                  "name": "whatever"
                }
              ]
            },
            "comment": "Sets a value",
            "summary": "Sets a value"
          }
        },
        {
          "signature": ".get(key)",
          "documentation": {
            "params": [
              {
                "type": "String",
                "name": "key",
                "description": "describe key param"
              }
            ],
            "returns": {
              "type": "Object",
              "description": "describe value param"
            },
            "comment": "Gets a value",
            "summary": "Gets a value"
          }
        },
        {
          "signature": "#delete({key, passion}, foo='bar')",
          "documentation": {
            "params": [
              {
                "type": "String",
                "name": "key",
                "description": "describe key param"
              }
            ],
            "examples": [
              {
                "title": "Delete a key.",
                "code": "emv = new Example.Methods.Virtual\nemv.set 'foo', 'bar'\nval = emv.get 'foo'\n\n# now, proclaim you're done with foo.\nemv.delete 'foo'"
              }
            ],
            "comment": "Deletes a key from the data.\n\nAnother line",
            "summary": "Deletes a key from the data."
          }
        }
      ]
    },
    "name": "Example.Methods.Virtual",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/methods/instance_methods.coffee
================================================
class TestInstanceMethods

  helper: ->

  another: (param, obj) ->

  anotherWithValues: (param = 123, obj = { a: 1 }, yup, comp = new TestInstanceMethods()) ->

  nowWithSpalt: (foo, bar...) ->

  bound: =>

  # This is not exposed to the outside world.
  internalToClassClosure = -> alert 'internal!'


================================================
FILE: spec/_templates/methods/instance_methods.json
================================================
[
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "TestInstanceMethods",
    "methods": [
      {
        "file": "spec/_templates/methods/instance_methods.coffee",
        "name": "helper",
        "bound": false,
        "kind": "dynamic",
        "parameters": []
      },
      {
        "file": "spec/_templates/methods/instance_methods.coffee",
        "name": "another",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "param",
            "splat": false
          },
          {
            "name": "obj",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/instance_methods.coffee",
        "name": "anotherWithValues",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "param",
            "splat": false,
            "default": "123"
          },
          {
            "name": "obj",
            "splat": false,
            "default": "{\n  a: 1\n}"
          },
          {
            "name": "yup",
            "splat": false
          },
          {
            "name": "comp",
            "splat": false,
            "default": "new TestInstanceMethods()"
          }
        ]
      },
      {
        "file": "spec/_templates/methods/instance_methods.coffee",
        "name": "nowWithSpalt",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "foo",
            "splat": false
          },
          {
            "name": "bar",
            "splat": true
          }
        ]
      },
      {
        "file": "spec/_templates/methods/instance_methods.coffee",
        "name": "bound",
        "bound": true,
        "kind": "dynamic",
        "parameters": []
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "helper",
    "bound": false,
    "kind": "dynamic",
    "parameters": []
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "another",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "param",
        "splat": false
      },
      {
        "name": "obj",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "anotherWithValues",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "param",
        "splat": false,
        "default": "123"
      },
      {
        "name": "obj",
        "splat": false,
        "default": "{\n  a: 1\n}"
      },
      {
        "name": "yup",
        "splat": false
      },
      {
        "name": "comp",
        "splat": false,
        "default": "new TestInstanceMethods()"
      }
    ]
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "a",
    "constant": false,
    "value": "1"
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "nowWithSpalt",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "foo",
        "splat": false
      },
      {
        "name": "bar",
        "splat": true
      }
    ]
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "bound",
    "bound": true,
    "kind": "dynamic",
    "parameters": []
  },
  {
    "file": "spec/_templates/methods/instance_methods.coffee",
    "name": "internalToClassClosure",
    "bound": false,
    "documentation": {
      "comment": "This is not exposed to the outside world.",
      "summary": "This is not exposed to the outside world."
    },
    "parameters": []
  }
]

================================================
FILE: spec/_templates/methods/method_documentation.coffee
================================================
class App.TestMethodDocumentation extends App.Doc

  # Should be overloaded to change fetch limit.
  #
  # @public
  # @return Number of items per fetch
  #
  fetchLimit: () -> 5

  # Do it!
  #
  # @see #undo for more information
  #
  # @private
  # @param [String] it The thing to do
  # @param again [Boolean] Do it again
  # @param [Object] options The do options
  # @option options [String] speed The speed
  # @option options [Number] repeat How wany time to repeat
  # @option options [Array<Tasks>] tasks The tasks to do
  # @return [Boolean] When successful executed
  # @throw [TypeError] when it can't be done
  #
  do: (it, again, options) ->

  # Do it!
  #
  # @see #undo for more information
  #
  # @private
  # @param [String] it The thing to do
  # @param again [Boolean] Do it again
  # @param [Object] options The do options
  # @option options [String] speed The speed
  # @option options [Number] repeat How wany time to repeat
  # @option options [Array<Tasks>] tasks The tasks to do
  # @return [Boolean] When successful executed
  #
  doWithoutSpace:(it, again, options)->

  # Do it!
  #
  # @see {#undo} for more information
  #
  # @private
  # @param [String] it The thing to do
  # @param [Object] options The do options
  # @option options [String] speed The speed
  # @option options [Number] repeat How wany time to repeat
  # @option options [Array<Tasks>] tasks The tasks to do
  # @return [Boolean] When successful executed
  #
  @lets_do_it = (it, options) ->


================================================
FILE: spec/_templates/methods/method_documentation.json
================================================
[
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "name": "App.TestMethodDocumentation",
    "parent": "App.Doc",
    "methods": [
      {
        "file": "spec/_templates/methods/method_documentation.coffee",
        "name": "fetchLimit",
        "bound": false,
        "documentation": {
          "comment": "Should be overloaded to change fetch limit.",
          "summary": "Should be overloaded to change fetch limit.",
          "public": true,
          "returns": {
            "type": "?",
            "description": "Number of items per fetch"
          }
        },
        "kind": "dynamic",
        "parameters": []
      },
      {
        "file": "spec/_templates/methods/method_documentation.coffee",
        "name": "do",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "#undo",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Boolean",
              "name": "again",
              "description": "Do it again"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          },
          "throws": [
            {
              "type": "TypeError",
              "description": "when it can't be done"
            }
          ]
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "again",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/method_documentation.coffee",
        "name": "doWithoutSpace",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "#undo",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Boolean",
              "name": "again",
              "description": "Do it again"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          }
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "again",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/methods/method_documentation.coffee",
        "name": "lets_do_it",
        "bound": false,
        "documentation": {
          "comment": "Do it!",
          "summary": "Do it!",
          "see": [
            {
              "reference": "{#undo}",
              "label": "for more information"
            }
          ],
          "private": true,
          "params": [
            {
              "type": "String",
              "name": "it",
              "description": "The thing to do"
            },
            {
              "type": "Object",
              "name": "options",
              "description": "The do options"
            }
          ],
          "options": {
            "options": [
              {
                "type": "String",
                "name": "speed",
                "description": "The speed"
              },
              {
                "type": "Number",
                "name": "repeat",
                "description": "How wany time to repeat"
              },
              {
                "type": "Array<Tasks>",
                "name": "tasks",
                "description": "The tasks to do"
              }
            ]
          },
          "returns": {
            "type": "Boolean",
            "description": "When successful executed"
          }
        },
        "selfish": true,
        "kind": "static",
        "parameters": [
          {
            "name": "it",
            "splat": false
          },
          {
            "name": "options",
            "splat": false
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "name": "fetchLimit",
    "bound": false,
    "documentation": {
      "comment": "Should be overloaded to change fetch limit.",
      "summary": "Should be overloaded to change fetch limit.",
      "public": true,
      "returns": {
        "type": "?",
        "description": "Number of items per fetch"
      }
    },
    "kind": "dynamic",
    "parameters": []
  },
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "name": "do",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "#undo",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Boolean",
          "name": "again",
          "description": "Do it again"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      },
      "throws": [
        {
          "type": "TypeError",
          "description": "when it can't be done"
        }
      ]
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "again",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "name": "doWithoutSpace",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "#undo",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Boolean",
          "name": "again",
          "description": "Do it again"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      }
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "again",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/methods/method_documentation.coffee",
    "name": "lets_do_it",
    "bound": false,
    "documentation": {
      "comment": "Do it!",
      "summary": "Do it!",
      "see": [
        {
          "reference": "{#undo}",
          "label": "for more information"
        }
      ],
      "private": true,
      "params": [
        {
          "type": "String",
          "name": "it",
          "description": "The thing to do"
        },
        {
          "type": "Object",
          "name": "options",
          "description": "The do options"
        }
      ],
      "options": {
        "options": [
          {
            "type": "String",
            "name": "speed",
            "description": "The speed"
          },
          {
            "type": "Number",
            "name": "repeat",
            "description": "How wany time to repeat"
          },
          {
            "type": "Array<Tasks>",
            "name": "tasks",
            "description": "The tasks to do"
          }
        ]
      },
      "returns": {
        "type": "Boolean",
        "description": "When successful executed"
      }
    },
    "selfish": true,
    "kind": "static",
    "parameters": [
      {
        "name": "it",
        "splat": false
      },
      {
        "name": "options",
        "splat": false
      }
    ]
  }
]


================================================
FILE: spec/_templates/methods/method_events.coffee
================================================
class Example.Events

  # This is a generic Events emit method.
  #
  # @event theBasic.One
  # @event theWeirdOne Omg this event is so weird o_O
  # @event theComplicatedOne
  #   This is the complicated event yo
  #   @param [String] the incredible string
  #
  # This should be more description for the method itself, and events
  # shouldn't have messed it up.
  #
  emit: (args...) ->


================================================
FILE: spec/_templates/methods/method_events.json
================================================
[
  {
    "file": "spec/_templates/methods/method_events.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/method_events.coffee",
    "name": "Example.Events",
    "methods": [
      {
        "file": "spec/_templates/methods/method_events.coffee",
        "name": "emit",
        "bound": false,
        "documentation": {
          "comment": "This is a generic Events emit method.\n\nThis should be more description for the method itself, and events\nshouldn't have messed it up.",
          "summary": "This is a generic Events emit method.",
          "events": [
            {
              "name": "theBasic.One",
              "documentation": {
                "comment": "",
                "summary": ""
              }
            },
            {
              "name": "theWeirdOne",
              "documentation": {
                "comment": "Omg this event is so weird o_O",
                "summary": "Omg this event is so weird o_O"
              }
            },
            {
              "name": "theComplicatedOne",
              "documentation": {
                "params": [
                  {
                    "type": "String",
                    "name": "the",
                    "description": "incredible string"
                  }
                ],
                "comment": "This is the complicated event yo",
                "summary": "This is the complicated event yo"
              }
            }
          ]
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "args",
            "splat": true
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/method_events.coffee",
    "name": "emit",
    "bound": false,
    "documentation": {
      "comment": "This is a generic Events emit method.\n\nThis should be more description for the method itself, and events\nshouldn't have messed it up.",
      "summary": "This is a generic Events emit method.",
      "events": [
        {
          "name": "theBasic.One",
          "documentation": {
            "comment": "",
            "summary": ""
          }
        },
        {
          "name": "theWeirdOne",
          "documentation": {
            "comment": "Omg this event is so weird o_O",
            "summary": "Omg this event is so weird o_O"
          }
        },
        {
          "name": "theComplicatedOne",
          "documentation": {
            "params": [
              {
                "type": "String",
                "name": "the",
                "description": "incredible string"
              }
            ],
            "comment": "This is the complicated event yo",
            "summary": "This is the complicated event yo"
          }
        }
      ]
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "args",
        "splat": true
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/method_example.coffee
================================================
class TestExample

  # @example Run generation
  #   codo = require 'codo'
  #
  #   file = (filename, content) ->
  #     console.log "New file %s with content %s", filename, content
  #
  #   done = (err) ->
  #     if err
  #       console.log "Cannot generate documentation:", err
  #     else
  #       console.log "Documentation generated"
  #
  #   codo.run file, done
  run: ->


================================================
FILE: spec/_templates/methods/method_example.json
================================================
[
  {
    "file": "spec/_templates/methods/method_example.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/method_example.coffee",
    "name": "TestExample",
    "methods": [
      {
        "file": "spec/_templates/methods/method_example.coffee",
        "name": "run",
        "bound": false,
        "documentation": {
          "comment": "",
          "summary": "",
          "examples": [
            {
              "title": "Run generation",
              "code": "codo = require 'codo'\n\nfile = (filename, content) ->\n  console.log \"New file %s with content %s\", filename, content\n\ndone = (err) ->\n  if err\n    console.log \"Cannot generate documentation:\", err\n  else\n    console.log \"Documentation generated\"\n\ncodo.run file, done"
            }
          ]
        },
        "kind": "dynamic",
        "parameters": []
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/method_example.coffee",
    "name": "run",
    "bound": false,
    "documentation": {
      "comment": "",
      "summary": "",
      "examples": [
        {
          "title": "Run generation",
          "code": "codo = require 'codo'\n\nfile = (filename, content) ->\n  console.log \"New file %s with content %s\", filename, content\n\ndone = (err) ->\n  if err\n    console.log \"Cannot generate documentation:\", err\n  else\n    console.log \"Documentation generated\"\n\ncodo.run file, done"
        }
      ]
    },
    "kind": "dynamic",
    "parameters": []
  }
]

================================================
FILE: spec/_templates/methods/named_parameters.coffee
================================================
class TestNamedParameters
  constructor : ({@cat, @dog, eel}, @fish, gorilla = 400, hog...) ->

  burp : ({a, b, c}, e = 20, {f, g, h}, i = 10) ->


================================================
FILE: spec/_templates/methods/named_parameters.json
================================================
[
  {
    "file": "spec/_templates/methods/named_parameters.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/named_parameters.coffee",
    "name": "TestNamedParameters",
    "methods": [
      {
        "file": "spec/_templates/methods/named_parameters.coffee",
        "name": "constructor",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "{cat, dog, eel}",
            "splat": false
          },
          {
            "name": "fish",
            "splat": false
          },
          {
            "name": "gorilla",
            "splat": false,
            "default": "400"
          },
          {
            "name": "hog",
            "splat": true
          }
        ]
      },
      {
        "file": "spec/_templates/methods/named_parameters.coffee",
        "name": "burp",
        "bound": false,
        "kind": "dynamic",
        "parameters": [
          {
            "name": "{a, b, c}",
            "splat": false
          },
          {
            "name": "e",
            "splat": false,
            "default": "20"
          },
          {
            "name": "{f, g, h}",
            "splat": false
          },
          {
            "name": "i",
            "splat": false,
            "default": "10"
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/named_parameters.coffee",
    "name": "constructor",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "{cat, dog, eel}",
        "splat": false
      },
      {
        "name": "fish",
        "splat": false
      },
      {
        "name": "gorilla",
        "splat": false,
        "default": "400"
      },
      {
        "name": "hog",
        "splat": true
      }
    ]
  },
  {
    "file": "spec/_templates/methods/named_parameters.coffee",
    "name": "burp",
    "bound": false,
    "kind": "dynamic",
    "parameters": [
      {
        "name": "{a, b, c}",
        "splat": false
      },
      {
        "name": "e",
        "splat": false,
        "default": "20"
      },
      {
        "name": "{f, g, h}",
        "splat": false
      },
      {
        "name": "i",
        "splat": false,
        "default": "10"
      }
    ]
  }
]

================================================
FILE: spec/_templates/methods/overload_method.coffee
================================================
class Example.Overload

  # This is a generic Store set method.
  #
  # @overload set(key, value)
  #   Sets a value on key
  #   @param [Symbol] key describe key param
  #   @param [Object] value describe value param
  #   @param [Object] options the options
  #   @option options test [String] the test option
  #
  # @overload set(value)
  #
  #   Sets a value on the default key `:foo`
  #
  #   @param [Object] value describe value param
  #   @return [Boolean] true when success
  #
  # This should be more description for the method itself, and overload
  # shouldn't have messed it up.
  #
  set: (args...) ->


================================================
FILE: spec/_templates/methods/overload_method.json
================================================
[
  {
    "file": "spec/_templates/methods/overload_method.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/methods/overload_method.coffee",
    "name": "Example.Overload",
    "methods": [
      {
        "file": "spec/_templates/methods/overload_method.coffee",
        "name": "set",
        "bound": false,
        "documentation": {
          "comment": "This is a generic Store set method.\n\nThis should be more description for the method itself, and overload\nshouldn't have messed it up.",
          "summary": "This is a generic Store set method.",
          "overloads": [
            {
              "signature": "set(key, value)",
              "documentation": {
                "params": [
                  {
                    "type": "Symbol",
                    "name": "key",
                    "description": "describe key param"
                  },
                  {
                    "type": "Object",
                    "name": "value",
                    "description": "describe value param"
                  },
                  {
                    "type": "Object",
                    "name": "options",
                    "description": "the options"
                  }
                ],
                "options": {
                  "options": [
                    {
                      "type": "String",
                      "name": "test",
                      "description": "the test option"
                    }
                  ]
                },
                "comment": "Sets a value on key",
                "summary": "Sets a value on key"
              }
            },
            {
              "signature": "set(value)",
              "documentation": {
                "params": [
                  {
                    "type": "Object",
                    "name": "value",
                    "description": "describe value param"
                  }
                ],
                "returns": {
                  "type": "Boolean",
                  "description": "true when success"
                },
                "comment": "Sets a value on the default key `:foo`",
                "summary": "Sets a value on the default key `:foo`"
              }
            }
          ]
        },
        "kind": "dynamic",
        "parameters": [
          {
            "name": "args",
            "splat": true
          }
        ]
      }
    ],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": []
  },
  {
    "file": "spec/_templates/methods/overload_method.coffee",
    "name": "set",
    "bound": false,
    "documentation": {
      "comment": "This is a generic Store set method.\n\nThis should be more description for the method itself, and overload\nshouldn't have messed it up.",
      "summary": "This is a generic Store set method.",
      "overloads": [
        {
          "signature": "set(key, value)",
          "documentation": {
            "params": [
              {
                "type": "Symbol",
                "name": "key",
                "description": "describe key param"
              },
              {
                "type": "Object",
                "name": "value",
                "description": "describe value param"
              },
              {
                "type": "Object",
                "name": "options",
                "description": "the options"
              }
            ],
            "options": {
              "options": [
                {
                  "type": "String",
                  "name": "test",
                  "description": "the test option"
                }
              ]
            },
            "comment": "Sets a value on key",
            "summary": "Sets a value on key"
          }
        },
        {
          "signature": "set(value)",
          "documentation": {
            "params": [
              {
                "type": "Object",
                "name": "value",
                "description": "describe value param"
              }
            ],
            "returns": {
              "type": "Boolean",
              "description": "true when success"
            },
            "comment": "Sets a value on the default key `:foo`",
            "summary": "Sets a value on the default key `:foo`"
          }
        }
      ]
    },
    "kind": "dynamic",
    "parameters": [
      {
        "name": "args",
        "splat": true
      }
    ]
  }
]

================================================
FILE: spec/_templates/mixins/concern.coffee
================================================
# This is my concern
# @mixin
Example.Mixins.Concern =

  ClassMethods:
    # @param [String] a This is the a parameter
    # @param [String] b This is the a parameter
    # @param [String] c This is the a parameter
    a: (a, b, c) ->

    # @param [String] x This is the x parameter
    # @param [String] y This is the y parameter
    # @param [String] z This is the z parameter
    z: (x, y, z) ->

  InstanceMethods:
    # Say hi
    # @param [String] to the name
    hi: (to) ->
    # Say goodbye
    # @param [String] to the name
    goodbye: (to) ->

# @concern Example.Mixins.Concern
class Example.Concern


================================================
FILE: spec/_templates/mixins/concern.json
================================================
[
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "Example.Mixins.Concern",
    "concern": true,
    "documentation": {
      "comment": "This is my concern",
      "summary": "This is my concern"
    },
    "methods": [],
    "classMethods": [
      {
        "file": "spec/_templates/mixins/concern.coffee",
        "name": "a",
        "bound": false,
        "documentation": {
          "comment": "",
          "summary": "",
          "params": [
            {
              "type": "String",
              "name": "a",
              "description": "This is the a parameter"
            },
            {
              "type": "String",
              "name": "b",
              "description": "This is the a parameter"
            },
            {
              "type": "String",
              "name": "c",
              "description": "This is the a parameter"
            }
          ]
        },
        "parameters": [
          {
            "name": "a",
            "splat": false
          },
          {
            "name": "b",
            "splat": false
          },
          {
            "name": "c",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/mixins/concern.coffee",
        "name": "z",
        "bound": false,
        "documentation": {
          "comment": "",
          "summary": "",
          "params": [
            {
              "type": "String",
              "name": "x",
              "description": "This is the x parameter"
            },
            {
              "type": "String",
              "name": "y",
              "description": "This is the y parameter"
            },
            {
              "type": "String",
              "name": "z",
              "description": "This is the z parameter"
            }
          ]
        },
        "parameters": [
          {
            "name": "x",
            "splat": false
          },
          {
            "name": "y",
            "splat": false
          },
          {
            "name": "z",
            "splat": false
          }
        ]
      }
    ],
    "instanceMethods": [
      {
        "file": "spec/_templates/mixins/concern.coffee",
        "name": "hi",
        "bound": false,
        "documentation": {
          "comment": "Say hi",
          "summary": "Say hi",
          "params": [
            {
              "type": "String",
              "name": "to",
              "description": "the name"
            }
          ]
        },
        "parameters": [
          {
            "name": "to",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/mixins/concern.coffee",
        "name": "goodbye",
        "bound": false,
        "documentation": {
          "comment": "Say goodbye",
          "summary": "Say goodbye",
          "params": [
            {
              "type": "String",
              "name": "to",
              "description": "the name"
            }
          ]
        },
        "parameters": [
          {
            "name": "to",
            "splat": false
          }
        ]
      }
    ],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "ClassMethods",
    "constant": false,
    "value": "{\n\n  /*\n  @param [String] a This is the a parameter\n  @param [String] b This is the a parameter\n  @param [String] c This is the a parameter\n   */\n  a: function(a, b, c) {},\n\n  /*\n  @param [String] x This is the x parameter\n  @param [String] y This is the y parameter\n  @param [String] z This is the z parameter\n   */\n  z: function(x, y, z) {}\n}"
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "a",
    "bound": false,
    "documentation": {
      "comment": "",
      "summary": "",
      "params": [
        {
          "type": "String",
          "name": "a",
          "description": "This is the a parameter"
        },
        {
          "type": "String",
          "name": "b",
          "description": "This is the a parameter"
        },
        {
          "type": "String",
          "name": "c",
          "description": "This is the a parameter"
        }
      ]
    },
    "parameters": [
      {
        "name": "a",
        "splat": false
      },
      {
        "name": "b",
        "splat": false
      },
      {
        "name": "c",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "z",
    "bound": false,
    "documentation": {
      "comment": "",
      "summary": "",
      "params": [
        {
          "type": "String",
          "name": "x",
          "description": "This is the x parameter"
        },
        {
          "type": "String",
          "name": "y",
          "description": "This is the y parameter"
        },
        {
          "type": "String",
          "name": "z",
          "description": "This is the z parameter"
        }
      ]
    },
    "parameters": [
      {
        "name": "x",
        "splat": false
      },
      {
        "name": "y",
        "splat": false
      },
      {
        "name": "z",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "InstanceMethods",
    "constant": false,
    "value": "{\n\n  /*\n  Say hi\n  @param [String] to the name\n   */\n  hi: function(to) {},\n\n  /*\n  Say goodbye\n  @param [String] to the name\n   */\n  goodbye: function(to) {}\n}"
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "hi",
    "bound": false,
    "documentation": {
      "comment": "Say hi",
      "summary": "Say hi",
      "params": [
        {
          "type": "String",
          "name": "to",
          "description": "the name"
        }
      ]
    },
    "parameters": [
      {
        "name": "to",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "name": "goodbye",
    "bound": false,
    "documentation": {
      "comment": "Say goodbye",
      "summary": "Say goodbye",
      "params": [
        {
          "type": "String",
          "name": "to",
          "description": "the name"
        }
      ]
    },
    "parameters": [
      {
        "name": "to",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/concern.coffee",
    "documentation": {
      "comment": "",
      "summary": "",
      "concerns": [
        "Example.Mixins.Concern"
      ]
    },
    "name": "Example.Concern",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [],
    "concerns": [
      {
        "file": "spec/_templates/mixins/concern.coffee",
        "name": "Example.Mixins.Concern",
        "concern": true,
        "documentation": {
          "comment": "This is my concern",
          "summary": "This is my concern"
        },
        "methods": [],
        "classMethods": [
          {
            "file": "spec/_templates/mixins/concern.coffee",
            "name": "a",
            "bound": false,
            "documentation": {
              "comment": "",
              "summary": "",
              "params": [
                {
                  "type": "String",
                  "name": "a",
                  "description": "This is the a parameter"
                },
                {
                  "type": "String",
                  "name": "b",
                  "description": "This is the a parameter"
                },
                {
                  "type": "String",
                  "name": "c",
                  "description": "This is the a parameter"
                }
              ]
            },
            "parameters": [
              {
                "name": "a",
                "splat": false
              },
              {
                "name": "b",
                "splat": false
              },
              {
                "name": "c",
                "splat": false
              }
            ]
          },
          {
            "file": "spec/_templates/mixins/concern.coffee",
            "name": "z",
            "bound": false,
            "documentation": {
              "comment": "",
              "summary": "",
              "params": [
                {
                  "type": "String",
                  "name": "x",
                  "description": "This is the x parameter"
                },
                {
                  "type": "String",
                  "name": "y",
                  "description": "This is the y parameter"
                },
                {
                  "type": "String",
                  "name": "z",
                  "description": "This is the z parameter"
                }
              ]
            },
            "parameters": [
              {
                "name": "x",
                "splat": false
              },
              {
                "name": "y",
                "splat": false
              },
              {
                "name": "z",
                "splat": false
              }
            ]
          }
        ],
        "instanceMethods": [
          {
            "file": "spec/_templates/mixins/concern.coffee",
            "name": "hi",
            "bound": false,
            "documentation": {
              "comment": "Say hi",
              "summary": "Say hi",
              "params": [
                {
                  "type": "String",
                  "name": "to",
                  "description": "the name"
                }
              ]
            },
            "parameters": [
              {
                "name": "to",
                "splat": false
              }
            ]
          },
          {
            "file": "spec/_templates/mixins/concern.coffee",
            "name": "goodbye",
            "bound": false,
            "documentation": {
              "comment": "Say goodbye",
              "summary": "Say goodbye",
              "params": [
                {
                  "type": "String",
                  "name": "to",
                  "description": "the name"
                }
              ]
            },
            "parameters": [
              {
                "name": "to",
                "splat": false
              }
            ]
          }
        ],
        "variables": []
      }
    ]
  }
]

================================================
FILE: spec/_templates/mixins/extend_mixin.coffee
================================================
# @mixin
Name.Space.MyMixin =
  hello: ->
  goodbye: ->

# @extend Name.Space.MyMixin
class SomeNamespace.MyClass


================================================
FILE: spec/_templates/mixins/extend_mixin.json
================================================
[
  {
    "file": "spec/_templates/mixins/extend_mixin.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/extend_mixin.coffee",
    "name": "Name.Space.MyMixin",
    "documentation": {
      "comment": "",
      "summary": ""
    },
    "methods": [
      {
        "file": "spec/_templates/mixins/extend_mixin.coffee",
        "name": "hello",
        "bound": false,
        "parameters": []
      },
      {
        "file": "spec/_templates/mixins/extend_mixin.coffee",
        "name": "goodbye",
        "bound": false,
        "parameters": []
      }
    ],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/extend_mixin.coffee",
    "name": "hello",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/mixins/extend_mixin.coffee",
    "name": "goodbye",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/mixins/extend_mixin.coffee",
    "documentation": {
      "comment": "",
      "summary": "",
      "extends": [
        "Name.Space.MyMixin"
      ]
    },
    "name": "SomeNamespace.MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [],
    "extends": [
      {
        "file": "spec/_templates/mixins/extend_mixin.coffee",
        "name": "Name.Space.MyMixin",
        "documentation": {
          "comment": "",
          "summary": ""
        },
        "methods": [
          {
            "file": "spec/_templates/mixins/extend_mixin.coffee",
            "name": "hello",
            "bound": false,
            "parameters": []
          },
          {
            "file": "spec/_templates/mixins/extend_mixin.coffee",
            "name": "goodbye",
            "bound": false,
            "parameters": []
          }
        ],
        "variables": []
      }
    ],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/mixins/include_mixin.coffee
================================================
# @mixin
Name.Space.MyMixin =
  hello: ->
  goodbye: ->

# @include Name.Space.MyMixin
class SomeNamespace.MyClass


================================================
FILE: spec/_templates/mixins/include_mixin.json
================================================
[
  {
    "file": "spec/_templates/mixins/include_mixin.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/include_mixin.coffee",
    "name": "Name.Space.MyMixin",
    "documentation": {
      "comment": "",
      "summary": ""
    },
    "methods": [
      {
        "file": "spec/_templates/mixins/include_mixin.coffee",
        "name": "hello",
        "bound": false,
        "parameters": []
      },
      {
        "file": "spec/_templates/mixins/include_mixin.coffee",
        "name": "goodbye",
        "bound": false,
        "parameters": []
      }
    ],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/include_mixin.coffee",
    "name": "hello",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/mixins/include_mixin.coffee",
    "name": "goodbye",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/mixins/include_mixin.coffee",
    "documentation": {
      "comment": "",
      "summary": "",
      "includes": [
        "Name.Space.MyMixin"
      ]
    },
    "name": "SomeNamespace.MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [
      {
        "file": "spec/_templates/mixins/include_mixin.coffee",
        "name": "Name.Space.MyMixin",
        "documentation": {
          "comment": "",
          "summary": ""
        },
        "methods": [
          {
            "file": "spec/_templates/mixins/include_mixin.coffee",
            "name": "hello",
            "bound": false,
            "parameters": []
          },
          {
            "file": "spec/_templates/mixins/include_mixin.coffee",
            "name": "goodbye",
            "bound": false,
            "parameters": []
          }
        ],
        "variables": []
      }
    ],
    "extends": [],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/mixins/missing_mixins.coffee
================================================
# @include Name.Space.MyMixin
# @extend Name.Space.MyMixin
class SomeNamespace.MyClass


================================================
FILE: spec/_templates/mixins/missing_mixins.json
================================================
[
  {
    "file": "spec/_templates/mixins/missing_mixins.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/missing_mixins.coffee",
    "documentation": {
      "comment": "",
      "summary": "",
      "includes": [
        "Name.Space.MyMixin"
      ],
      "extends": [
        "Name.Space.MyMixin"
      ]
    },
    "name": "SomeNamespace.MyClass",
    "methods": [],
    "variables": [],
    "properties": [],
    "includes": [
      "Name.Space.MyMixin"
    ],
    "extends": [
      "Name.Space.MyMixin"
    ],
    "concerns": []
  }
]

================================================
FILE: spec/_templates/mixins/mixin_documentation.coffee
================================================
# This is a test module with `inline.dot`. Beware.
#
# @note Please use
#   this carefully
# @note For internal use only
#
# @example Use it in this way
#   class Rumba
#     @include Foo.Bar
#
# @todo Clean up socket handler
# @todo Refactor
#   property factory
# @author Netzpirat
# @author Supermakaka
# @abstract Each listener implementation must include
# @private
# @deprecated Use other module
#   which is thread safe
# @since 1.0.0
# @version 1.0.2
#
# @namespace Manual.Namespace
# @mixin
#
Foo.Bar = {}


================================================
FILE: spec/_templates/mixins/mixin_documentation.json
================================================
[
  {
    "file": "spec/_templates/mixins/mixin_documentation.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/mixin_documentation.coffee",
    "name": "Foo.Bar",
    "documentation": {
      "comment": "This is a test module with `inline.dot`. Beware.",
      "summary": "This is a test module with `inline.dot`.",
      "notes": [
        "Please use this carefully",
        "For internal use only"
      ],
      "abstract": "Each listener implementation must include",
      "private": true,
      "deprecated": "Use other module which is thread safe",
      "version": "1.0.2",
      "since": "1.0.0",
      "authors": [
        "Netzpirat",
        "Supermakaka"
      ],
      "todos": [
        "Clean up socket handler",
        "Refactor property factory"
      ],
      "examples": [
        {
          "title": "Use it in this way",
          "code": "class Rumba\n  @include Foo.Bar"
        }
      ],
      "namespace": "Manual.Namespace"
    },
    "methods": [],
    "variables": []
  }
]

================================================
FILE: spec/_templates/mixins/mixin_methods.coffee
================================================
#
# @method #set(key, value)
#   Sets a value
#   @param [String] key describe key param
#   @param [Object] value describe value param
#   @option value [String] string
#   @option value [Integer] number
#   @option value [Object] whatever
#
# @mixin
Foo =

  helper: ->

  another: (a, b) ->

  withDefault: (a = 2, c, d = 'hi', d, e = { a: 2 }, f = new TestClassMethods()) ->

  nowWithSpalt: (foo, bar...) ->


================================================
FILE: spec/_templates/mixins/mixin_methods.json
================================================
[
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "Foo",
    "documentation": {
      "comment": "",
      "summary": "",
      "methods": [
        {
          "signature": "#set(key, value)",
          "documentation": {
            "params": [
              {
                "type": "String",
                "name": "key",
                "description": "describe key param"
              },
              {
                "type": "Object",
                "name": "value",
                "description": "describe value param"
              }
            ],
            "options": {
              "value": [
                {
                  "type": "String",
                  "name": "string"
                },
                {
                  "type": "Integer",
                  "name": "number"
                },
                {
                  "type": "Object",
                  "name": "whatever"
                }
              ]
            },
            "comment": "Sets a value",
            "summary": "Sets a value"
          }
        }
      ]
    },
    "methods": [
      {
        "file": "spec/_templates/mixins/mixin_methods.coffee",
        "name": "helper",
        "bound": false,
        "parameters": []
      },
      {
        "file": "spec/_templates/mixins/mixin_methods.coffee",
        "name": "another",
        "bound": false,
        "parameters": [
          {
            "name": "a",
            "splat": false
          },
          {
            "name": "b",
            "splat": false
          }
        ]
      },
      {
        "file": "spec/_templates/mixins/mixin_methods.coffee",
        "name": "withDefault",
        "bound": false,
        "parameters": [
          {
            "name": "a",
            "splat": false,
            "default": "2"
          },
          {
            "name": "c",
            "splat": false
          },
          {
            "name": "d",
            "splat": false,
            "default": "'hi'"
          },
          {
            "name": "d",
            "splat": false
          },
          {
            "name": "e",
            "splat": false,
            "default": "{\n  a: 2\n}"
          },
          {
            "name": "f",
            "splat": false,
            "default": "new TestClassMethods()"
          }
        ]
      },
      {
        "file": "spec/_templates/mixins/mixin_methods.coffee",
        "name": "nowWithSpalt",
        "bound": false,
        "parameters": [
          {
            "name": "foo",
            "splat": false
          },
          {
            "name": "bar",
            "splat": true
          }
        ]
      }
    ],
    "variables": []
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "helper",
    "bound": false,
    "parameters": []
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "another",
    "bound": false,
    "parameters": [
      {
        "name": "a",
        "splat": false
      },
      {
        "name": "b",
        "splat": false
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "withDefault",
    "bound": false,
    "parameters": [
      {
        "name": "a",
        "splat": false,
        "default": "2"
      },
      {
        "name": "c",
        "splat": false
      },
      {
        "name": "d",
        "splat": false,
        "default": "'hi'"
      },
      {
        "name": "d",
        "splat": false
      },
      {
        "name": "e",
        "splat": false,
        "default": "{\n  a: 2\n}"
      },
      {
        "name": "f",
        "splat": false,
        "default": "new TestClassMethods()"
      }
    ]
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "a",
    "constant": false,
    "value": "2"
  },
  {
    "file": "spec/_templates/mixins/mixin_methods.coffee",
    "name": "nowWithSpalt",
    "bound": false,
    "parameters": [
      {
        "name": "foo",
        "splat": false
      },
      {
        "name": "bar",
        "splat": true
      }
    ]
  }
]

================================================
FILE: spec/_templates/properties/properties.coffee
================================================
# Property test class. It's almost the most difficult
# part to come up with stupid examples.
#
module.exports = class Person

  # @property [Array<String>] The nicknames
  #
  # All the nicknames the person is known by.
  nicknames: []

  # @property [Object]
  # The entity's position
  position:
    x: 0
    y: 0

  # Language helpers
  get = (props) => @::__defineGetter__ name, getter for name, getter of props
  set = (props) => @::__defineSetter__ name, setter for name, setter of props

  # @property [String] The first name
  get firstname: -> @_firstname
  set firstname: (@_firstname) ->

  # The last name
  get lastname: -> @_lastname
  set lastname: (@_lastname) ->

  # @property [Date] The day
  #   (of birth)
  get birth: -> @_birth

  # The twitter handle
  get twitter: -> @_twitter

  # @property [String] The confession
  set confession: (@_confession) ->

  # @property [String] Something different
  @property 'test', 
    get: -> 'test'
    set: (k,v) ->

  # @property [String] Something different 2
  @property 'test2', -> 'test'

  # @property [String] Something different 3
  @property 'test3', set: -> 'test'

  # The email address offer
  set email: (@_email) ->

  # This should not be swallowed
  test: ->

================================================
FILE: spec/_templates/properties/properties.json
================================================
[
  {
    "file": "spec/_templates/properties/properties.coffee",
    "methods": [],
    "variables": []
  },
  {
    "file": "spec/_templates/properties/properties.coffee",
    "documentation": {
      "comment": "Property test class. It's almost the most difficult\npart to come up with stupid examples.",
      "summary": "Property test class."
    },
    "name": "Person",
    "methods": [
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "test",
        "bound": false,
        "documentation": {
          "comment": "This should not be swallowed",
          "summary": "This should not be swallowed"
        },
        "kind": "dynamic",
        "parameters": []
      }
    ],
    "variables": [],
    "properties": [
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "nicknames",
        "getter": true,
        "setter": true,
        "documentation": {
          "comment": "The nicknames\n\nAll the nicknames the person is known by.",
          "summary": "The nicknames\n\nAll the nicknames the person is known by.",
          "property": "Array<String>"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "position",
        "getter": true,
        "setter": true,
        "documentation": {
          "comment": "The entity's position",
          "summary": "The entity's position",
          "property": "Object"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "firstname",
        "getter": true,
        "setter": true,
        "documentation": {
          "comment": "The first name",
          "summary": "The first name",
          "property": "String"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "lastname",
        "getter": true,
        "setter": true,
        "documentation": {
          "comment": "The last name",
          "summary": "The last name"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "birth",
        "getter": true,
        "setter": false,
        "documentation": {
          "comment": "The day (of birth)",
          "summary": "The day (of birth)",
          "property": "Date"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "twitter",
        "getter": true,
        "setter": false,
        "documentation": {
          "comment": "The twitter handle",
          "summary": "The twitter handle"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "confession",
        "getter": false,
        "setter": true,
        "documentation": {
          "comment": "The confession",
          "summary": "The confession",
          "property": "String"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "test",
        "getter": true,
        "setter": true,
        "documentation": {
          "comment": "Something different",
          "summary": "Something different",
          "property": "String"
        }
      },
      {
        "file": "spec/_templates/properties/properties.coffee",
        "name": "test2",
        "getter": true,
        "setter": false,
        "documentation": {
          "comment": "Something different 2",
          "summary": "Something different 2",
          "property": "String"
Download .txt
gitextract_nbr74owg/

├── .codoopts
├── .gitignore
├── .travis.yml
├── Gruntfile.coffee
├── LICENSE.md
├── README.md
├── bin/
│   └── codo
├── lib/
│   ├── _entities.coffee
│   ├── _meta.coffee
│   ├── _tools.coffee
│   ├── codo.coffee
│   ├── command.coffee
│   ├── documentation.coffee
│   ├── entities/
│   │   ├── class.coffee
│   │   ├── extra.coffee
│   │   ├── file.coffee
│   │   ├── method.coffee
│   │   ├── mixin.coffee
│   │   ├── property.coffee
│   │   └── variable.coffee
│   ├── entity.coffee
│   ├── environment.coffee
│   ├── meta/
│   │   ├── method.coffee
│   │   └── parameter.coffee
│   ├── tools/
│   │   ├── markdown.coffee
│   │   └── referencer.coffee
│   └── traverser.coffee
├── package.json
├── spec/
│   ├── _templates/
│   │   ├── angular/
│   │   │   ├── angular-with-new.coffee
│   │   │   ├── angular-with-new.json
│   │   │   ├── angular.coffee
│   │   │   └── angular.json
│   │   ├── classes/
│   │   │   ├── class_description_markdown.coffee
│   │   │   ├── class_description_markdown.json
│   │   │   ├── class_documentation.coffee
│   │   │   ├── class_documentation.json
│   │   │   ├── class_extends.coffee
│   │   │   ├── class_extends.json
│   │   │   ├── empty_class.coffee
│   │   │   ├── empty_class.json
│   │   │   ├── export_class.coffee
│   │   │   ├── export_class.json
│   │   │   ├── global_class.coffee
│   │   │   ├── global_class.json
│   │   │   ├── inner_class.coffee
│   │   │   ├── inner_class.json
│   │   │   ├── namespaced_class.coffee
│   │   │   ├── namespaced_class.json
│   │   │   ├── simple_class.coffee
│   │   │   └── simple_class.json
│   │   ├── complicateds/
│   │   │   ├── methods.coffee
│   │   │   └── variables.coffee
│   │   ├── environment/
│   │   │   ├── class.coffee
│   │   │   ├── mixin.coffee
│   │   │   └── result.json
│   │   ├── example/
│   │   │   ├── CHANGELOG
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── angry_animal.coffee
│   │   │       ├── animal.coffee
│   │   │       ├── lion.coffee
│   │   │       ├── over_documented_class.coffee
│   │   │       └── over_documented_mixin.coffee
│   │   ├── extras/
│   │   │   ├── README
│   │   │   └── README.md
│   │   ├── files/
│   │   │   ├── non_class_file.coffee
│   │   │   └── non_class_file.json
│   │   ├── methods/
│   │   │   ├── assigned_parameters.coffee
│   │   │   ├── assigned_parameters.json
│   │   │   ├── class_methods.coffee
│   │   │   ├── class_methods.json
│   │   │   ├── curly_method_documentation.coffee
│   │   │   ├── curly_method_documentation.json
│   │   │   ├── dynamic_methods.coffee
│   │   │   ├── dynamic_methods.json
│   │   │   ├── instance_methods.coffee
│   │   │   ├── instance_methods.json
│   │   │   ├── method_documentation.coffee
│   │   │   ├── method_documentation.json
│   │   │   ├── method_events.coffee
│   │   │   ├── method_events.json
│   │   │   ├── method_example.coffee
│   │   │   ├── method_example.json
│   │   │   ├── named_parameters.coffee
│   │   │   ├── named_parameters.json
│   │   │   ├── overload_method.coffee
│   │   │   └── overload_method.json
│   │   ├── mixins/
│   │   │   ├── concern.coffee
│   │   │   ├── concern.json
│   │   │   ├── extend_mixin.coffee
│   │   │   ├── extend_mixin.json
│   │   │   ├── include_mixin.coffee
│   │   │   ├── include_mixin.json
│   │   │   ├── missing_mixins.coffee
│   │   │   ├── missing_mixins.json
│   │   │   ├── mixin_documentation.coffee
│   │   │   ├── mixin_documentation.json
│   │   │   ├── mixin_methods.coffee
│   │   │   └── mixin_methods.json
│   │   ├── properties/
│   │   │   ├── properties.coffee
│   │   │   └── properties.json
│   │   └── variables/
│   │       ├── class_variables.coffee
│   │       ├── class_variables.json
│   │       ├── constant_variables.coffee
│   │       ├── constant_variables.json
│   │       ├── instance_variables.coffee
│   │       └── instance_variables.json
│   ├── lib/
│   │   ├── api_spec.coffee
│   │   ├── codo_spec.coffee
│   │   ├── entities/
│   │   │   ├── class_spec.coffee
│   │   │   └── mixin_spec.coffee
│   │   ├── environment_spec.coffee
│   │   ├── meta/
│   │   │   ├── method_spec.coffee
│   │   │   └── parameter_spec.coffee
│   │   └── tools/
│   │       └── markdown_spec.coffee
│   └── themes/
│       └── default/
│           └── lib/
│               ├── templater_spec.coffee
│               ├── theme_spec.coffee
│               └── tree_builder_spec.coffee
└── themes/
    └── default/
        ├── assets/
        │   ├── javascript/
        │   │   ├── application.js
        │   │   ├── codo.coffee
        │   │   ├── frames.coffee
        │   │   ├── fuzzy.coffee
        │   │   ├── keys.coffee
        │   │   ├── sidebar.coffee
        │   │   ├── toc.coffee
        │   │   └── vendor/
        │   │       ├── fuzzy.coffee
        │   │       ├── highlight.coffeescript.js
        │   │       ├── highlight.js
        │   │       ├── jquery.js
        │   │       ├── keymaster.js
        │   │       └── underscore.js
        │   └── stylesheets/
        │       ├── alphabetical_index.styl
        │       ├── application.styl
        │       ├── base.styl
        │       ├── class.styl
        │       ├── footer.styl
        │       ├── header.styl
        │       ├── lists.styl
        │       ├── toc.styl
        │       └── vendor/
        │           └── highlight.css
        ├── lib/
        │   ├── _theme.coffee
        │   ├── templater.coffee
        │   ├── theme.coffee
        │   └── tree_builder.coffee
        └── templates/
            ├── alphabetical_index.hamlc
            ├── class.hamlc
            ├── class_list.hamlc
            ├── extra.hamlc
            ├── extra_list.hamlc
            ├── file.hamlc
            ├── file_list.hamlc
            ├── frames.hamlc
            ├── layout/
            │   ├── footer.hamlc
            │   ├── header.hamlc
            │   └── intro.hamlc
            ├── method_list.hamlc
            ├── mixin.hamlc
            ├── mixin_list.hamlc
            └── partials/
                ├── documentation.hamlc
                ├── list_nav.hamlc
                ├── method_list.hamlc
                ├── method_signature.hamlc
                ├── method_summary.hamlc
                ├── type_link.hamlc
                └── variable_list.hamlc
Download .txt
SYMBOL INDEX (77 symbols across 4 files)

FILE: themes/default/assets/javascript/vendor/highlight.js
  function escape (line 10) | function escape(value) {
  function langRe (line 14) | function langRe(language, value, global) {
  function findCode (line 21) | function findCode(pre) {
  function blockText (line 31) | function blockText(block, ignoreNewLines) {
  function blockLanguage (line 49) | function blockLanguage(block) {
  function nodeStream (line 62) | function nodeStream(node) {
  function mergeStreams (line 89) | function mergeStreams(stream1, stream2, value) {
  function compileModes (line 159) | function compileModes() {
  function highlight (line 228) | function highlight(language_name, value) {
  function highlightAuto (line 439) | function highlightAuto(text) {
  function fixMarkup (line 472) | function fixMarkup(value, tabReplace, useBR) {
  function highlightBlock (line 488) | function highlightBlock(block, tabReplace, useBR) {
  function initHighlighting (line 542) | function initHighlighting() {
  function initHighlightingOnLoad (line 557) | function initHighlightingOnLoad() {

FILE: themes/default/assets/javascript/vendor/jquery.js
  function createOptions (line 911) | function createOptions( options ) {
  function dataAttr (line 1800) | function dataAttr( elem, key, data ) {
  function isEmptyDataObject (line 1832) | function isEmptyDataObject( obj ) {
  function returnFalse (line 3276) | function returnFalse() {
  function returnTrue (line 3279) | function returnTrue() {
  function Sizzle (line 3865) | function Sizzle( selector, context, results, seed ) {
  function createInputPseudo (line 3934) | function createInputPseudo( type ) {
  function createButtonPseudo (line 3942) | function createButtonPseudo( type ) {
  function siblingCheck (line 4527) | function siblingCheck( a, b, ret ) {
  function tokenize (line 4645) | function tokenize( selector, context, xml, parseOnly ) {
  function addCombinator (line 4733) | function addCombinator( matcher, combinator, context, xml ) {
  function addMatcher (line 4786) | function addMatcher( higher, deeper ) {
  function matcherFromTokens (line 4796) | function matcherFromTokens( tokens, context, xml ) {
  function matcherFromGroupMatchers (line 4811) | function matcherFromGroupMatchers( matchers ) {
  function multipleContexts (line 4846) | function multipleContexts( selector, contexts, results, seed ) {
  function handlePOSGroup (line 4854) | function handlePOSGroup( selector, posfilter, argument, contexts, seed, ...
  function handlePOS (line 4869) | function handlePOS( groups, context, results, seed ) {
  function select (line 4952) | function select( selector, context, results, seed, xml ) {
  function isDisconnected (line 5353) | function isDisconnected( node ) {
  function sibling (line 5357) | function sibling( cur, dir ) {
  function winnow (line 5465) | function winnow( elements, qualifier, keep ) {
  function createSafeFragment (line 5498) | function createSafeFragment( document ) {
  function findOrAppend (line 5882) | function findOrAppend( elem, tag ) {
  function cloneCopyEvent (line 5886) | function cloneCopyEvent( src, dest ) {
  function cloneFixAttributes (line 5914) | function cloneFixAttributes( src, dest ) {
  function getAll (line 6057) | function getAll( elem ) {
  function fixDefaultChecked (line 6070) | function fixDefaultChecked( elem ) {
  function jQuerySub (line 6366) | function jQuerySub( selector, context ) {
  function vendorPropName (line 6412) | function vendorPropName( style, name ) {
  function isHidden (line 6434) | function isHidden( elem, el ) {
  function showHide (line 6439) | function showHide( elements, show ) {
  function setPositiveNumber (line 6747) | function setPositiveNumber( elem, value, subtract ) {
  function augmentWidthOrHeight (line 6754) | function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
  function getWidthOrHeight (line 6796) | function getWidthOrHeight( elem, name, extra ) {
  function css_defaultDisplay (line 6839) | function css_defaultDisplay( nodeName ) {
  function buildParams (line 7093) | function buildParams( prefix, obj, traditional, add ) {
  function addToPrefiltersOrTransports (line 7182) | function addToPrefiltersOrTransports( structure ) {
  function inspectPrefiltersOrTransports (line 7216) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
  function ajaxExtend (line 7258) | function ajaxExtend( target, src ) {
  function done (line 7569) | function done( status, nativeStatusText, responses, headers ) {
  function ajaxHandleResponses (line 7862) | function ajaxHandleResponses( s, jqXHR, responses ) {
  function ajaxConvert (line 7924) | function ajaxConvert( s, response ) {
  function createStandardXHR (line 8191) | function createStandardXHR() {
  function createActiveXHR (line 8197) | function createActiveXHR() {
  function createFxNow (line 8452) | function createFxNow() {
  function createTweens (line 8459) | function createTweens( animation, props ) {
  function Animation (line 8474) | function Animation( elem, properties, options ) {
  function propFilter (line 8570) | function propFilter( props, specialEasing ) {
  function defaultPrefilter (line 8637) | function defaultPrefilter( elem, props, opts ) {
  function Tween (line 8752) | function Tween( elem, options, prop, end, easing ) {
  function genFx (line 8936) | function genFx( type, includeWidth ) {
  function getWindow (line 9234) | function getWindow( elem ) {

FILE: themes/default/assets/javascript/vendor/keymaster.js
  function index (line 36) | function index(array, item){
  function dispatch (line 43) | function dispatch(event, scope){
  function clearModifier (line 88) | function clearModifier(event){
  function resetModifiers (line 97) | function resetModifiers() {
  function assignKey (line 103) | function assignKey(key, scope, method){
  function filter (line 134) | function filter(event){
  function setScope (line 144) | function setScope(scope){ _scope = scope || 'all' }
  function getScope (line 145) | function getScope(){ return _scope || 'all' }
  function deleteScope (line 148) | function deleteScope(scope){
  function addEvent (line 161) | function addEvent(object, event, method) {

FILE: themes/default/assets/javascript/vendor/underscore.js
  function eq (line 682) | function eq(a, b, stack) {
Condensed preview — 165 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (675K chars).
[
  {
    "path": ".codoopts",
    "chars": 42,
    "preview": "--title \"Codo Documentation\"\nlib/\nthemes/\n"
  },
  {
    "path": ".gitignore",
    "chars": 55,
    "preview": ".DS_Store\nnode_modules\n.bundle\n.idea\ndoc\nnpm-debug.log\n"
  },
  {
    "path": ".travis.yml",
    "chars": 136,
    "preview": "language: node_js\nbranches:\n  only:\n    - master\n    - 1.x\nnotifications:\n  recipients:\n    - michi@netzpiraten.ch\n    -"
  },
  {
    "path": "Gruntfile.coffee",
    "chars": 194,
    "preview": "module.exports = (grunt) ->\n\n  grunt.loadNpmTasks 'grunt-release'\n\n  grunt.initConfig\n    release:\n      options:\n      "
  },
  {
    "path": "LICENSE.md",
    "chars": 1225,
    "preview": "# MIT License\n\nCopyright (c) 2012-2013 Michael Kessler, Boris Staal\n\nTemplate components are derivative works of YARD (h"
  },
  {
    "path": "README.md",
    "chars": 23736,
    "preview": "# Codo [![Build Status](https://secure.travis-ci.org/coffeedoc/codo.png)](https://travis-ci.org/coffeedoc/codo)\n\nCodo is"
  },
  {
    "path": "bin/codo",
    "chars": 228,
    "preview": "#!/usr/bin/env node\n\n'use strict';\n\nvar compiler = require('coffee-script');\nvar location = require('path').join(\n  __di"
  },
  {
    "path": "lib/_entities.coffee",
    "chars": 30,
    "preview": "module.exports = Entities = {}"
  },
  {
    "path": "lib/_meta.coffee",
    "chars": 26,
    "preview": "module.exports = Meta = {}"
  },
  {
    "path": "lib/_tools.coffee",
    "chars": 27,
    "preview": "module.exports = Tools = {}"
  },
  {
    "path": "lib/codo.coffee",
    "chars": 3675,
    "preview": "FS          = require 'fs'\nPath        = require 'path'\nwalkdir     = require 'walkdir'\nWinston     = require 'winston'\n"
  },
  {
    "path": "lib/command.coffee",
    "chars": 5777,
    "preview": "Path     = require 'path'\nCodo     = require './codo'\nOptimist = require 'optimist'\nTheme    = require '../themes/defaul"
  },
  {
    "path": "lib/documentation.coffee",
    "chars": 7004,
    "preview": "module.exports = class Documentation\n\n  constructor: (comment) ->\n    @parseTags(comment)\n  \n  # Parse the given lines a"
  },
  {
    "path": "lib/entities/class.coffee",
    "chars": 6859,
    "preview": "Entity     = require '../entity'\nMethod     = require './method'\nVariable   = require './variable'\nProperty   = require "
  },
  {
    "path": "lib/entities/extra.coffee",
    "chars": 718,
    "preview": "FS       = require 'fs'\nPath     = require 'path'\nEntities = require '../_entities'\nMarkdown = require '../tools/markdow"
  },
  {
    "path": "lib/entities/file.coffee",
    "chars": 1790,
    "preview": "Entity     = require '../entity'\nPath       = require 'path'\nMethod     = require './method'\nVariable   = require './var"
  },
  {
    "path": "lib/entities/method.coffee",
    "chars": 1373,
    "preview": "Entity    = require '../entity'\nParameter = require '../meta/parameter'\nEntities  = require '../_entities'\nWinston = req"
  },
  {
    "path": "lib/entities/mixin.coffee",
    "chars": 3857,
    "preview": "Entity     = require '../entity'\nMethod     = require './method'\nVariable   = require './variable'\nMetaMethod = require "
  },
  {
    "path": "lib/entities/property.coffee",
    "chars": 2635,
    "preview": "Entity   = require '../entity'\nEntities = require '../_entities'\nWinston  = require 'winston'\n\n#\n# Supported formats:\n#\n"
  },
  {
    "path": "lib/entities/variable.coffee",
    "chars": 1266,
    "preview": "Entity   = require '../entity'\nEntities = require '../_entities'\nWinston  = require 'winston'\n\nmodule.exports = class En"
  },
  {
    "path": "lib/entity.coffee",
    "chars": 672,
    "preview": "# Base class for all entities.\n#\nmodule.exports = class Entity\n\n  @is: (node) ->\n    !node.documentation?.nodoc\n\n  linki"
  },
  {
    "path": "lib/environment.coffee",
    "chars": 4391,
    "preview": "FS        = require 'fs'\nPath      = require 'path'\nTraverser = require './traverser'\n\nFile      = require './entities/f"
  },
  {
    "path": "lib/meta/method.coffee",
    "chars": 1893,
    "preview": "Parameter = require './parameter'\nMeta      = require '../_meta'\n\nmodule.exports = class Meta.Method\n\n  @override: (opti"
  },
  {
    "path": "lib/meta/parameter.coffee",
    "chars": 1698,
    "preview": "CoffeeScript = require 'coffee-script'\nMeta         = require '../_meta'\n\nmodule.exports = class Meta.Parameter\n\n  @from"
  },
  {
    "path": "lib/tools/markdown.coffee",
    "chars": 1786,
    "preview": "marked = require 'marked'\nTools  = require '../_tools'\n\n# It looks like all the markdown libraries for node doesn't get\n"
  },
  {
    "path": "lib/tools/referencer.coffee",
    "chars": 836,
    "preview": "Tools = require '../_tools'\n\nmodule.exports = class Tools.Referencer\n\n  constructor: (@environment) ->\n\n  resolve: (text"
  },
  {
    "path": "lib/traverser.coffee",
    "chars": 7485,
    "preview": "FS            = require 'fs'\n_             = require 'underscore'\n_.str         = require 'underscore.string'\nCoffeeScri"
  },
  {
    "path": "package.json",
    "chars": 1555,
    "preview": "{\n  \"name\": \"codo\",\n  \"description\": \"A CoffeeScript documentation generator.\",\n  \"keywords\": [\n    \"coffeescript\",\n    "
  },
  {
    "path": "spec/_templates/angular/angular-with-new.coffee",
    "chars": 244,
    "preview": "module.exports = require('angular').module 'module-name', ['some-dependency']\n.factory 'a-factory', ['some-dependency', "
  },
  {
    "path": "spec/_templates/angular/angular-with-new.json",
    "chars": 517,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/angular/angular-with-new.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n   "
  },
  {
    "path": "spec/_templates/angular/angular.coffee",
    "chars": 240,
    "preview": "module.exports = require('angular').module 'module-name', ['some-dependency']\n.factory 'a-factory', ['some-dependency', "
  },
  {
    "path": "spec/_templates/angular/angular.json",
    "chars": 499,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/angular/angular.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"file\": "
  },
  {
    "path": "spec/_templates/classes/class_description_markdown.coffee",
    "chars": 623,
    "preview": "# Codo - the CoffeeScript API documentation generator\n#\n# # Header 1\n#\n# This is a paragraph.\n#\n# ## Header 2\n#\n# This i"
  },
  {
    "path": "spec/_templates/classes/class_description_markdown.json",
    "chars": 1188,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/class_description_markdown.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  "
  },
  {
    "path": "spec/_templates/classes/class_documentation.coffee",
    "chars": 602,
    "preview": "# This is a test class with `inline.dot`. Beware.\n#\n# @note Please use\n#   this carefully\n# @note For internal use only\n"
  },
  {
    "path": "spec/_templates/classes/class_documentation.json",
    "chars": 1327,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/class_documentation.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n"
  },
  {
    "path": "spec/_templates/classes/class_extends.coffee",
    "chars": 37,
    "preview": "class NS.Clazz extends Another.Clazz\n"
  },
  {
    "path": "spec/_templates/classes/class_extends.json",
    "chars": 354,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/class_extends.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"f"
  },
  {
    "path": "spec/_templates/classes/empty_class.coffee",
    "chars": 24,
    "preview": "class A\n\nclass extends A"
  },
  {
    "path": "spec/_templates/classes/empty_class.json",
    "chars": 312,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/empty_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fil"
  },
  {
    "path": "spec/_templates/classes/export_class.coffee",
    "chars": 83,
    "preview": "# Yep, this should be assigned to the class\nmodule.exports = class TestExportClass\n"
  },
  {
    "path": "spec/_templates/classes/export_class.json",
    "chars": 481,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/export_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fi"
  },
  {
    "path": "spec/_templates/classes/global_class.coffee",
    "chars": 45,
    "preview": "# This is a test class\nclass @GlobalTestClass"
  },
  {
    "path": "spec/_templates/classes/global_class.json",
    "chars": 460,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/global_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fi"
  },
  {
    "path": "spec/_templates/classes/inner_class.coffee",
    "chars": 110,
    "preview": "class Tower.Model.Relation.HasMany extends Tower.Model.Relation\n  class @Scope \n  class @Scope2 extends @Scope"
  },
  {
    "path": "spec/_templates/classes/inner_class.json",
    "chars": 2118,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/inner_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fil"
  },
  {
    "path": "spec/_templates/classes/namespaced_class.coffee",
    "chars": 164,
    "preview": "# Test description\nclass Some.Namespace.MyClass\n\n# Test description\nclass @Another.Namespace.MyClass\n\n# Test description"
  },
  {
    "path": "spec/_templates/classes/namespaced_class.json",
    "chars": 1160,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/namespaced_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n   "
  },
  {
    "path": "spec/_templates/classes/simple_class.coffee",
    "chars": 18,
    "preview": "class MyTestClass\n"
  },
  {
    "path": "spec/_templates/classes/simple_class.json",
    "chars": 324,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/classes/simple_class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fi"
  },
  {
    "path": "spec/_templates/complicateds/methods.coffee",
    "chars": 303,
    "preview": "# @include Mixin\n# @extend Mixin\n# @concern Concern\n#\n# @method #x(key, value)\n#   Sets a value\n#\nclass Class\n  z: ->\n\n#"
  },
  {
    "path": "spec/_templates/complicateds/variables.coffee",
    "chars": 110,
    "preview": "class Class\n  z: '123'\n\nclass Subclass extends Class\n  z: '456'\n\nclass Subsubclass extends Subclass\n  y: '123'"
  },
  {
    "path": "spec/_templates/environment/class.coffee",
    "chars": 39,
    "preview": "#\n# @include LookAndFeel\n#\nclass Fluffy"
  },
  {
    "path": "spec/_templates/environment/mixin.coffee",
    "chars": 48,
    "preview": "#\n# @mixin\n#\nLookAndFeel =\n  look: ->\n  feel: ->"
  },
  {
    "path": "spec/_templates/environment/result.json",
    "chars": 1899,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/environment/class.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"file\""
  },
  {
    "path": "spec/_templates/example/CHANGELOG",
    "chars": 86,
    "preview": "Changelog\n\nThis project is actually so incredible that it never changes.\n\nSeriously!!!"
  },
  {
    "path": "spec/_templates/example/README.md",
    "chars": 55,
    "preview": "# Readme\n\nThat's how we do it, this is how we do it (c)"
  },
  {
    "path": "spec/_templates/example/package.json",
    "chars": 164,
    "preview": "{\n  \"name\": \"example\",\n  \"description\": \"The best ever project about lines and wildness!\",\n  \"keywords\": [\n    \"coffeesc"
  },
  {
    "path": "spec/_templates/example/src/angry_animal.coffee",
    "chars": 234,
    "preview": "# Ola-la\n# @abstract\nTROLOLO = 'test'\n\n# @mixin\nExample.AngryAnimal =\n  roar: ->\n\n# Ola-la once more\n#\n# @overload ?glob"
  },
  {
    "path": "spec/_templates/example/src/animal.coffee",
    "chars": 1463,
    "preview": "# Base class for all animals.\n#\n# @note This is not used for codo, its purpose is to show\n#   all possible tags within a"
  },
  {
    "path": "spec/_templates/example/src/lion.coffee",
    "chars": 563,
    "preview": "# A dangerous lion. Take care.\n#\n# @author Simba\n# @see http://en.wikipedia.org/wiki/Lion\n# @include Example.AngryAnimal"
  },
  {
    "path": "spec/_templates/example/src/over_documented_class.coffee",
    "chars": 3217,
    "preview": "#\n# This class is SO DOCUMENTED! Seriously, Just look at that! This is so incredible!\n#\n# It even has some links: {http:"
  },
  {
    "path": "spec/_templates/example/src/over_documented_mixin.coffee",
    "chars": 817,
    "preview": "#\n# This mixin is SO DOCUMENTED! Seriously, Just look at that! This is so incredible!\n#\n# It even has some links: {http:"
  },
  {
    "path": "spec/_templates/extras/README",
    "chars": 21,
    "preview": "This is a test README"
  },
  {
    "path": "spec/_templates/extras/README.md",
    "chars": 270,
    "preview": "# This is a test README\n\nWe even have some content here. [With links!](http://github.com)\n\n## And nested menus\n\nAnd even"
  },
  {
    "path": "spec/_templates/files/non_class_file.coffee",
    "chars": 571,
    "preview": "# The greeting\nGREETING = 'Hay'\n\n# Hey, check this out!\nmodule.exports = FOO = 'Foo constant!'\n\n# Says hello to a person"
  },
  {
    "path": "spec/_templates/files/non_class_file.json",
    "chars": 4957,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/files/non_class_file.coffee\",\n    \"methods\": [\n      {\n        \"file\": \"spec/_templat"
  },
  {
    "path": "spec/_templates/methods/assigned_parameters.coffee",
    "chars": 46,
    "preview": "class TestAssignedParameters\n  help: (@me) ->\n"
  },
  {
    "path": "spec/_templates/methods/assigned_parameters.json",
    "chars": 851,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/assigned_parameters.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n"
  },
  {
    "path": "spec/_templates/methods/class_methods.coffee",
    "chars": 216,
    "preview": "class TestClassMethods\n\n  @helper: ->\n\n  @another: (a, b) ->\n\n  @withDefault: (a = 2, c, d = 'hi', d, e = { a: 2 }, f = "
  },
  {
    "path": "spec/_templates/methods/class_methods.json",
    "chars": 4405,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/class_methods.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"f"
  },
  {
    "path": "spec/_templates/methods/curly_method_documentation.coffee",
    "chars": 1442,
    "preview": "class App.TestMethodDocumentation extends App.Doc\n\n  # Should be overloaded to change fetch limit.\n  #\n  # @return Numbe"
  },
  {
    "path": "spec/_templates/methods/curly_method_documentation.json",
    "chars": 10995,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/curly_method_documentation.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  "
  },
  {
    "path": "spec/_templates/methods/dynamic_methods.coffee",
    "chars": 949,
    "preview": "# This class has virtual methods, which doesn't\n# exist in the source but appears in the documentation.\n#\n# @method #set"
  },
  {
    "path": "spec/_templates/methods/dynamic_methods.json",
    "chars": 2882,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/dynamic_methods.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    "
  },
  {
    "path": "spec/_templates/methods/instance_methods.coffee",
    "chars": 304,
    "preview": "class TestInstanceMethods\n\n  helper: ->\n\n  another: (param, obj) ->\n\n  anotherWithValues: (param = 123, obj = { a: 1 }, "
  },
  {
    "path": "spec/_templates/methods/instance_methods.json",
    "chars": 3939,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/instance_methods.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n   "
  },
  {
    "path": "spec/_templates/methods/method_documentation.coffee",
    "chars": 1499,
    "preview": "class App.TestMethodDocumentation extends App.Doc\n\n  # Should be overloaded to change fetch limit.\n  #\n  # @public\n  # @"
  },
  {
    "path": "spec/_templates/methods/method_documentation.json",
    "chars": 11262,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/method_documentation.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {"
  },
  {
    "path": "spec/_templates/methods/method_events.coffee",
    "chars": 390,
    "preview": "class Example.Events\n\n  # This is a generic Events emit method.\n  #\n  # @event theBasic.One\n  # @event theWeirdOne Omg t"
  },
  {
    "path": "spec/_templates/methods/method_events.json",
    "chars": 3021,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/method_events.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"f"
  },
  {
    "path": "spec/_templates/methods/method_example.coffee",
    "chars": 386,
    "preview": "class TestExample\n\n  # @example Run generation\n  #   codo = require 'codo'\n  #\n  #   file = (filename, content) ->\n  #  "
  },
  {
    "path": "spec/_templates/methods/method_example.json",
    "chars": 1626,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/method_example.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \""
  },
  {
    "path": "spec/_templates/methods/named_parameters.coffee",
    "chars": 147,
    "preview": "class TestNamedParameters\n  constructor : ({@cat, @dog, eel}, @fish, gorilla = 400, hog...) ->\n\n  burp : ({a, b, c}, e ="
  },
  {
    "path": "spec/_templates/methods/named_parameters.json",
    "chars": 2410,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/named_parameters.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n   "
  },
  {
    "path": "spec/_templates/methods/overload_method.coffee",
    "chars": 618,
    "preview": "class Example.Overload\n\n  # This is a generic Store set method.\n  #\n  # @overload set(key, value)\n  #   Sets a value on "
  },
  {
    "path": "spec/_templates/methods/overload_method.json",
    "chars": 4531,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/methods/overload_method.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    "
  },
  {
    "path": "spec/_templates/mixins/concern.coffee",
    "chars": 614,
    "preview": "# This is my concern\n# @mixin\nExample.Mixins.Concern =\n\n  ClassMethods:\n    # @param [String] a This is the a parameter\n"
  },
  {
    "path": "spec/_templates/mixins/concern.json",
    "chars": 10559,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/concern.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"file\": \""
  },
  {
    "path": "spec/_templates/mixins/extend_mixin.coffee",
    "chars": 114,
    "preview": "# @mixin\nName.Space.MyMixin =\n  hello: ->\n  goodbye: ->\n\n# @extend Name.Space.MyMixin\nclass SomeNamespace.MyClass\n"
  },
  {
    "path": "spec/_templates/mixins/extend_mixin.json",
    "chars": 1862,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/extend_mixin.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fil"
  },
  {
    "path": "spec/_templates/mixins/include_mixin.coffee",
    "chars": 115,
    "preview": "# @mixin\nName.Space.MyMixin =\n  hello: ->\n  goodbye: ->\n\n# @include Name.Space.MyMixin\nclass SomeNamespace.MyClass\n"
  },
  {
    "path": "spec/_templates/mixins/include_mixin.json",
    "chars": 1873,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/include_mixin.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fi"
  },
  {
    "path": "spec/_templates/mixins/missing_mixins.coffee",
    "chars": 87,
    "preview": "# @include Name.Space.MyMixin\n# @extend Name.Space.MyMixin\nclass SomeNamespace.MyClass\n"
  },
  {
    "path": "spec/_templates/mixins/missing_mixins.json",
    "chars": 586,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/missing_mixins.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"f"
  },
  {
    "path": "spec/_templates/mixins/mixin_documentation.coffee",
    "chars": 515,
    "preview": "# This is a test module with `inline.dot`. Beware.\n#\n# @note Please use\n#   this carefully\n# @note For internal use only"
  },
  {
    "path": "spec/_templates/mixins/mixin_documentation.json",
    "chars": 1051,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/mixin_documentation.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n "
  },
  {
    "path": "spec/_templates/mixins/mixin_methods.coffee",
    "chars": 413,
    "preview": "#\n# @method #set(key, value)\n#   Sets a value\n#   @param [String] key describe key param\n#   @param [Object] value descr"
  },
  {
    "path": "spec/_templates/mixins/mixin_methods.json",
    "chars": 4261,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/mixins/mixin_methods.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"fi"
  },
  {
    "path": "spec/_templates/properties/properties.coffee",
    "chars": 1239,
    "preview": "# Property test class. It's almost the most difficult\n# part to come up with stupid examples.\n#\nmodule.exports = class P"
  },
  {
    "path": "spec/_templates/properties/properties.json",
    "chars": 10568,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/properties/properties.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n    \"f"
  },
  {
    "path": "spec/_templates/variables/class_variables.coffee",
    "chars": 117,
    "preview": "class TestClassVariables\n\n  @empty = undefined\n\n  @test = 'Hi'\n\n  @another = ['a', 'b']\n\n  @more =\n    a: 1\n    b: 2\n"
  },
  {
    "path": "spec/_templates/variables/class_variables.json",
    "chars": 2229,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/variables/class_variables.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {\n  "
  },
  {
    "path": "spec/_templates/variables/constant_variables.coffee",
    "chars": 94,
    "preview": "class TestContstantVariables\n\n  # Modify it here\n  @TEST = 'Hi'\n\n  @ANOTHER_CONST: ['a', 'b']\n"
  },
  {
    "path": "spec/_templates/variables/constant_variables.json",
    "chars": 1387,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/variables/constant_variables.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {"
  },
  {
    "path": "spec/_templates/variables/instance_variables.coffee",
    "chars": 112,
    "preview": "class TestInstanceVariables\n\n  empty: undefined\n\n  test: 'Hi'\n\n  another: ['a', 'b']\n\n  more:\n    a: 1\n    b: 2\n"
  },
  {
    "path": "spec/_templates/variables/instance_variables.json",
    "chars": 2092,
    "preview": "[\n  {\n    \"file\": \"spec/_templates/variables/instance_variables.coffee\",\n    \"methods\": [],\n    \"variables\": []\n  },\n  {"
  },
  {
    "path": "spec/lib/api_spec.coffee",
    "chars": 489,
    "preview": "API = require '../../lib/command.coffee'\nPath = require 'path'\n\ndescribe 'API', ->\n\n  it 'parses project', (done) ->\n   "
  },
  {
    "path": "spec/lib/codo_spec.coffee",
    "chars": 637,
    "preview": "Path = require 'path'\nCodo = require '../../lib/codo'\n\ndescribe 'Codo', ->\n\n  it 'parses project', ->\n    environment = "
  },
  {
    "path": "spec/lib/entities/class_spec.coffee",
    "chars": 1585,
    "preview": "Environment = require '../../../lib/environment'\nMethod = require '../../../lib/entities/mixin'\n\ndescribe 'Class', ->\n\n "
  },
  {
    "path": "spec/lib/entities/mixin_spec.coffee",
    "chars": 2732,
    "preview": "Environment = require '../../../lib/environment'\nMethod = require '../../../lib/entities/mixin'\n\ndescribe 'Mixin', ->\n\n "
  },
  {
    "path": "spec/lib/environment_spec.coffee",
    "chars": 5664,
    "preview": "FS          = require 'fs'\njsdiff      = require 'diff'\nPath        = require 'path'\nwalkdir     = require 'walkdir'\nEnv"
  },
  {
    "path": "spec/lib/meta/method_spec.coffee",
    "chars": 1782,
    "preview": "Environment = require '../../../lib/environment'\nMethod = require '../../../lib/meta/method'\n\ndescribe 'Method', ->\n\n  i"
  },
  {
    "path": "spec/lib/meta/parameter_spec.coffee",
    "chars": 777,
    "preview": "Parameter = require '../../../lib/meta/parameter'\n\ndescribe 'Parameter', ->\n\n  describe 'signature parsing', ->\n    it '"
  },
  {
    "path": "spec/lib/tools/markdown_spec.coffee",
    "chars": 495,
    "preview": "Markdown = require '../../../lib/tools/markdown'\njsdiff      = require 'diff'\n\ndescribe 'Markdown', ->\n  describe 'limit"
  },
  {
    "path": "spec/themes/default/lib/templater_spec.coffee",
    "chars": 825,
    "preview": "Environment = require '../../../../lib/environment'\nTemplater = require '../../../../themes/default/lib/templater'\n\ndesc"
  },
  {
    "path": "spec/themes/default/lib/theme_spec.coffee",
    "chars": 751,
    "preview": "OS          = require 'os'\nPath        = require 'path'\nEnvironment = require '../../../../lib/environment'\nTheme       "
  },
  {
    "path": "spec/themes/default/lib/tree_builder_spec.coffee",
    "chars": 1056,
    "preview": "TreeBuilder = require '../../../../themes/default/lib/tree_builder'\n\ndescribe 'Tree Builder', ->\n\n  it 'builds proper tr"
  },
  {
    "path": "themes/default/assets/javascript/application.js",
    "chars": 146,
    "preview": "//= require_tree './vendor'\n//= require ./codo\n//= require ./sidebar\n//= require ./toc\n//= require ./keys\n//= require ./"
  },
  {
    "path": "themes/default/assets/javascript/codo.coffee",
    "chars": 264,
    "preview": "$ ->\n\n  # Highlight code\n  $('pre code').each (i, e) -> hljs.highlightBlock e, '  '\n\n  # Show external links in the main"
  },
  {
    "path": "themes/default/assets/javascript/frames.coffee",
    "chars": 441,
    "preview": "$ ->\n  if $('frameset').length > 0\n    parser = document.createElement('a')\n    parser.href = location.href\n    starter "
  },
  {
    "path": "themes/default/assets/javascript/fuzzy.coffee",
    "chars": 1753,
    "preview": "$ ->\n\n  $('#search_frame').hide()\n  window.lastSearch = ''\n\n  # Global fuzzy search\n  #\n  $('#fuzzySearch input').keyup "
  },
  {
    "path": "themes/default/assets/javascript/keys.coffee",
    "chars": 1960,
    "preview": "$ ->\n\n  loadSearch = (url, link) ->\n    parent.frames.list.location.href = url unless /#{ url }$/.test parent.frames.lis"
  },
  {
    "path": "themes/default/assets/javascript/sidebar.coffee",
    "chars": 1761,
    "preview": "$ ->\n\n  # Create stripes\n  window.createStripes = ->\n    $('#content.list li:visible').each (i, el) ->\n      if i % 2 is"
  },
  {
    "path": "themes/default/assets/javascript/toc.coffee",
    "chars": 1169,
    "preview": "$ ->\n\n  #\n  # Create file TOC from the headings\n  #\n  $('#filecontents').each ->\n    nav = $('nav.toc')\n    target = nav"
  },
  {
    "path": "themes/default/assets/javascript/vendor/fuzzy.coffee",
    "chars": 5999,
    "preview": "# Taken from: https://github.com/stratuseditor/fuzzy-filter/blob/master/index.coffee\n\n# Public: Filter a list of items.\n"
  },
  {
    "path": "themes/default/assets/javascript/vendor/highlight.coffeescript.js",
    "chars": 3257,
    "preview": "//= require ./highlight\n\n/*\nLanguage: CoffeeScript\nAuthor: Dmytrii Nagirniak <dnagir@gmail.com>\nContributors: Oleg Efimo"
  },
  {
    "path": "themes/default/assets/javascript/vendor/highlight.js",
    "chars": 19356,
    "preview": "/*\nSyntax highlighting with language autodetection.\nhttp://softwaremaniacs.org/soft/highlight/\n*/\n\nvar hljs = new functi"
  },
  {
    "path": "themes/default/assets/javascript/vendor/jquery.js",
    "chars": 259994,
    "preview": "/*!\n * jQuery JavaScript Library v1.8.1\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Cop"
  },
  {
    "path": "themes/default/assets/javascript/vendor/keymaster.js",
    "chars": 5979,
    "preview": "//     keymaster.js\n//     (c) 2011 Thomas Fuchs\n//     keymaster.js may be freely distributed under the MIT license.\n\n;"
  },
  {
    "path": "themes/default/assets/javascript/vendor/underscore.js",
    "chars": 37390,
    "preview": "//     Underscore.js 1.3.3\n//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n//     Underscore is freely distribu"
  },
  {
    "path": "themes/default/assets/stylesheets/alphabetical_index.styl",
    "chars": 804,
    "preview": ".alphaindex {\n  margin-top: 0;\n  font-size: 22px;\n}\n\n.noborder {\n  border-top: 0px;\n  margin-top: 0;\n  padding-top: 4px;"
  },
  {
    "path": "themes/default/assets/stylesheets/application.styl",
    "chars": 172,
    "preview": "//= require_tree ./vendor\n\n@import 'nib';\n@import 'base';\n@import 'class';\n@import 'footer';\n@import 'header';\n@import '"
  },
  {
    "path": "themes/default/assets/stylesheets/base.styl",
    "chars": 2929,
    "preview": "body {\n  padding: 0 5px;\n  font-family: \"Lucida Sans\", \"Lucida Grande\", Verdana, Arial, sans-serif;\n  font-size: 13px;\n}"
  },
  {
    "path": "themes/default/assets/stylesheets/class.styl",
    "chars": 4366,
    "preview": "#content {\n\n  table.box {\n    font-size: 1em;\n    line-height: 2;\n\n    border-spacing: 0;\n    border-collapse: collapse;"
  },
  {
    "path": "themes/default/assets/stylesheets/footer.styl",
    "chars": 278,
    "preview": "#footer {\n  margin-top: 15px;\n  border-top: 1px solid #ccc;\n  text-align: center;\n  padding: 7px 0;\n\n  font-size: 12px;\n"
  },
  {
    "path": "themes/default/assets/stylesheets/header.styl",
    "chars": 1604,
    "preview": "#menu {\n  font-size: 1.3em;\n  color: #bbb;\n  top: -5px;\n  position: relative;\n\n  .title, a {\n    font-size: 0.7em;\n  }\n\n"
  },
  {
    "path": "themes/default/assets/stylesheets/lists.styl",
    "chars": 2937,
    "preview": "body.list {\n  padding: 0;\n  margin: 0;\n}\n\nbody {\n  #content.list {\n    #search {\n      position: relative;\n      margin-"
  },
  {
    "path": "themes/default/assets/stylesheets/toc.styl",
    "chars": 880,
    "preview": "nav.toc {\n  box-shadow: #bbb -2px 2px 6px;\n\n  overflow: hidden;\n  float: right;\n\n  z-index: 500;\n  right: 0px;\n  max-wid"
  },
  {
    "path": "themes/default/assets/stylesheets/vendor/highlight.css",
    "chars": 2180,
    "preview": "pre code{display:block;padding:.5em;background:#f0f0f0}pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure"
  },
  {
    "path": "themes/default/lib/_theme.coffee",
    "chars": 19,
    "preview": "module.exports = {}"
  },
  {
    "path": "themes/default/lib/templater.coffee",
    "chars": 1856,
    "preview": "FS      = require 'fs'\nPath    = require 'path'\nmkdirp  = require 'mkdirp'\n_       = require 'underscore'\nhamlc   = requ"
  },
  {
    "path": "themes/default/lib/theme.coffee",
    "chars": 7451,
    "preview": "strftime    = require 'strftime'\nFS          = require 'fs'\nPath        = require 'path'\nTemplater   = require './templa"
  },
  {
    "path": "themes/default/lib/tree_builder.coffee",
    "chars": 740,
    "preview": "Theme = require './_theme'\n\nmodule.exports = class Theme.TreeBuilder\n\n  @build: (collection, resolver) ->\n    (new @ col"
  },
  {
    "path": "themes/default/templates/alphabetical_index.hamlc",
    "chars": 2073,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body\n    != @render 'layout/intro'\n\n    #content\n      %h1.noborder.title= @ti"
  },
  {
    "path": "themes/default/templates/class.hamlc",
    "chars": 7339,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body\n    != @render 'layout/intro', breadcrumbs: @breadcrumbs\n\n    #content\n  "
  },
  {
    "path": "themes/default/templates/class_list.hamlc",
    "chars": 873,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body.list\n    #content.tree.list\n      %h1.full_list_header Class List\n\n      "
  },
  {
    "path": "themes/default/templates/extra.hamlc",
    "chars": 397,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body\n    != @render 'layout/intro', breadcrumbs: @breadcrumbs\n\n    #content\n  "
  },
  {
    "path": "themes/default/templates/extra_list.hamlc",
    "chars": 619,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body.list\n    #content.tree.list\n      %h1.full_list_header File List\n\n      !"
  },
  {
    "path": "themes/default/templates/file.hamlc",
    "chars": 1182,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body\n    != @render 'layout/intro', breadcrumbs: @breadcrumbs\n\n    #content\n  "
  },
  {
    "path": "themes/default/templates/file_list.hamlc",
    "chars": 703,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body.list\n    #content.tree.list\n      %h1.full_list_header File List\n\n      !"
  },
  {
    "path": "themes/default/templates/frames.hamlc",
    "chars": 164,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %frameset{ cols: '25%, *' }\n    %frame{ name: 'list', src: \"#{@list}\" }\n    %fr"
  },
  {
    "path": "themes/default/templates/layout/footer.hamlc",
    "chars": 1035,
    "preview": "#footer\n\n  By\n  %a{href: 'https://github.com/coffeedoc/codo', title: 'CoffeeScript API documentation generator'}\n    Cod"
  },
  {
    "path": "themes/default/templates/layout/header.hamlc",
    "chars": 777,
    "preview": "%head\n  %meta{charset: 'UTF-8'}\n  %title= @environment.options.title\n\n  %script{src: \"#{@path}javascript/application.js\""
  },
  {
    "path": "themes/default/templates/layout/intro.hamlc",
    "chars": 390,
    "preview": "#base{data: {path: @path}}\n#header\n  #menu\n    - if @breadcrumbs?.length > 0\n      - current = @breadcrumbs.pop()\n      "
  },
  {
    "path": "themes/default/templates/method_list.hamlc",
    "chars": 576,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body.list\n    #content.list\n      %h1.full_list_header Method List\n\n      != @"
  },
  {
    "path": "themes/default/templates/mixin.hamlc",
    "chars": 2759,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body\n    != @render 'layout/intro', breadcrumbs: @breadcrumbs\n\n    #content\n  "
  },
  {
    "path": "themes/default/templates/mixin_list.hamlc",
    "chars": 850,
    "preview": "!!!\n%html\n  != @render 'layout/header'\n  %body.list\n    #content.tree.list\n      %h1.full_list_header Mixin List\n\n      "
  },
  {
    "path": "themes/default/templates/partials/documentation.hamlc",
    "chars": 4887,
    "preview": "- if @documentation\n\n  - show_description = false\n  - show_description ||= @documentation[field] for field in ['deprecat"
  },
  {
    "path": "themes/default/templates/partials/list_nav.hamlc",
    "chars": 556,
    "preview": "%nav\n  - if @environment.visibleClasses().length > 0\n    %a{target: '_self', href: 'class_list.html'}\n      Classes\n\n  -"
  },
  {
    "path": "themes/default/templates/partials/method_list.hamlc",
    "chars": 510,
    "preview": ".methods\n  - for method in @methods\n    .method_details\n      %p.signature{id: \"#{method.name}-#{method.kind}\"}\n        "
  },
  {
    "path": "themes/default/templates/partials/method_signature.hamlc",
    "chars": 102,
    "preview": "= @method.kindSignature()\n= @method.typeSignature()\n%b= @method.name\n%span>= @method.paramsSignature()"
  },
  {
    "path": "themes/default/templates/partials/method_summary.hamlc",
    "chars": 965,
    "preview": "%ul.summary\n  - for method in @methods\n    %li{deprecated: if method.documentation?.deprecated? then true else false}\n\n "
  },
  {
    "path": "themes/default/templates/partials/type_link.hamlc",
    "chars": 110,
    "preview": "- if @awareOf(@type)\n  %tt<>\n    %a{href: @reference(@type, @path)}<>\n      = @type\n- else\n  %tt<>\n    = @type"
  },
  {
    "path": "themes/default/templates/partials/variable_list.hamlc",
    "chars": 339,
    "preview": "- if @variables? && @variables.length > 0\n  %dl.constants\n    - for variable in @variables\n      %dt{ id: \"#{variable.na"
  }
]

About this extraction

This page contains the full source code of the coffeedoc/codo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 165 files (594.0 KB), approximately 168.1k tokens, and a symbol index with 77 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!