diff --git a/doc/parse.php b/doc/parse.php
deleted file mode 100644
index e1c952068..000000000
--- a/doc/parse.php
+++ /dev/null
@@ -1,38 +0,0 @@
-version;
-
- // generate Markdown
- $markdown = docdown(array(
- 'path' => '../' . $filePath,
- 'title' => 'Lo-Dash v' . $version . '',
- 'toc' => 'categories',
- 'url' => 'https://github.com/lodash/lodash/blob/master/lodash.js'
- ));
-
- // save to a `.md` file
- file_put_contents($outputName . '.md', $markdown);
-
- // print
- header('Content-Type: text/plain;charset=utf-8');
- echo $markdown . PHP_EOL;
-?>
\ No newline at end of file
diff --git a/vendor/docdown/LICENSE.txt b/vendor/docdown/LICENSE.txt
deleted file mode 100644
index 6cc7b220b..000000000
--- a/vendor/docdown/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright 2011-2014 John-David Dalton
-
-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.
\ No newline at end of file
diff --git a/vendor/docdown/docdown.php b/vendor/docdown/docdown.php
deleted file mode 100644
index f031470d3..000000000
--- a/vendor/docdown/docdown.php
+++ /dev/null
@@ -1,38 +0,0 @@
-
- * Available under MIT license
- */
-require(dirname(__FILE__) . '/src/DocDown/MarkdownGenerator.php');
-
-/**
- * Generates Markdown from JSDoc entries in a given file.
- *
- * @param {Array} [$options=array()] The options array.
- * @returns {string} The generated Markdown.
- * @example
- *
- * // specify a file path
- * $markdown = docdown(array(
- * // path to js file
- * 'path' => $filepath,
- * // url used to reference line numbers in code
- * 'url' => 'https://github.com/username/project/blob/master/my.js'
- * ));
- *
- * // or pass raw js
- * $markdown = docdown(array(
- * // raw JavaScript source
- * 'source' => $rawJS,
- * // documentation title
- * 'title' => 'My API Documentation',
- * // url used to reference line numbers in code
- * 'url' => 'https://github.com/username/project/blob/master/my.js'
- * ));
- */
-function docdown( $options = array() ) {
- $gen = new MarkdownGenerator($options);
- return $gen->generate();
-}
-?>
\ No newline at end of file
diff --git a/vendor/docdown/src/DocDown/Alias.php b/vendor/docdown/src/DocDown/Alias.php
deleted file mode 100644
index c04e55cbf..000000000
--- a/vendor/docdown/src/DocDown/Alias.php
+++ /dev/null
@@ -1,226 +0,0 @@
-owner = $owner;
- $this->_name = $name;
- $this->_call = $owner->getCall();
- $this->_category = $owner->getCategory();
- $this->_desc = $owner->getDesc();
- $this->_example = $owner->getExample();
- $this->_isCtor = $owner->isCtor();
- $this->_isLicense = $owner->isLicense();
- $this->_isPlugin = $owner->isPlugin();
- $this->_isPrivate = $owner->isPrivate();
- $this->_isStatic = $owner->isStatic();
- $this->_lineNumber = $owner->getLineNumber();
- $this->_members = $owner->getMembers();
- $this->_params = $owner->getParams();
- $this->_returns = $owner->getReturns();
- $this->_type = $owner->getType();
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Extracts the entry's `alias` objects.
- *
- * @memberOf Alias
- * @param {number} $index The index of the array value to return.
- * @returns {Array|string} The entry's `alias` objects.
- */
- public function getAliases( $index = null ) {
- $result = array();
- return $index !== null
- ? @$result[$index]
- : $result;
- }
-
- /**
- * Extracts the function call from the owner entry.
- *
- * @memberOf Alias
- * @returns {string} The function call.
- */
- public function getCall() {
- return $this->_call;
- }
-
- /**
- * Extracts the owner entry's `category` data.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's `category` data.
- */
- public function getCategory() {
- return $this->_category;
- }
-
- /**
- * Extracts the owner entry's description.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's description.
- */
- public function getDesc() {
- return $this->_desc;
- }
-
- /**
- * Extracts the owner entry's `example` data.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's `example` data.
- */
- public function getExample() {
- return $this->_example;
- }
-
- /**
- * Checks if the entry is an alias.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true`.
- */
- public function isAlias() {
- return true;
- }
-
- /**
- * Checks if the owner entry is a constructor.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true` if a constructor, else `false`.
- */
- public function isCtor() {
- return $this->_isCtor;
- }
-
- /**
- * Checks if the owner entry is a license.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true` if a license, else `false`.
- */
- public function isLicense() {
- return $this->_isLicense;
- }
-
- /**
- * Checks if the owner entry *is* assigned to a prototype.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true` if assigned to a prototype, else `false`.
- */
- public function isPlugin() {
- return $this->_isPlugin;
- }
-
- /**
- * Checks if the owner entry is private.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true` if private, else `false`.
- */
- public function isPrivate() {
- return $this->_isPrivate;
- }
-
- /**
- * Checks if the owner entry is *not* assigned to a prototype.
- *
- * @memberOf Alias
- * @returns {boolean} Returns `true` if not assigned to a prototype, else `false`.
- */
- public function isStatic() {
- return $this->_isStatic;
- }
-
- /**
- * Resolves the owner entry's line number.
- *
- * @memberOf Alias
- * @returns {number} The owner entry's line number.
- */
- public function getLineNumber() {
- return $this->_lineNumber;
- }
-
- /**
- * Extracts the owner entry's `member` data.
- *
- * @memberOf Alias
- * @param {number} $index The index of the array value to return.
- * @returns {Array|string} The owner entry's `member` data.
- */
- public function getMembers( $index = null ) {
- return $index !== null
- ? @$this->_members[$index]
- : $this->_members;
- }
-
- /**
- * Extracts the owner entry's `name` data.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's `name` data.
- */
- public function getName() {
- return $this->_name;
- }
-
- /**
- * Extracts the owner entry's `param` data.
- *
- * @memberOf Alias
- * @param {number} $index The index of the array value to return.
- * @returns {Array} The owner entry's `param` data.
- */
- public function getParams( $index = null ) {
- return $index !== null
- ? @$this->_params[$index]
- : $this->_params;
- }
-
- /**
- * Extracts the owner entry's `returns` data.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's `returns` data.
- */
- public function getReturns() {
- return $this->_returns;
- }
-
- /**
- * Extracts the owner entry's `type` data.
- *
- * @memberOf Alias
- * @returns {string} The owner entry's `type` data.
- */
- public function getType() {
- return $this->_type;
- }
-}
-?>
\ No newline at end of file
diff --git a/vendor/docdown/src/DocDown/Entry.php b/vendor/docdown/src/DocDown/Entry.php
deleted file mode 100644
index 62d419e5d..000000000
--- a/vendor/docdown/src/DocDown/Entry.php
+++ /dev/null
@@ -1,456 +0,0 @@
-entry = $entry;
- $this->lang = $lang;
- $this->source = str_replace(PHP_EOL, "\n", $source);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Extracts the documentation entries from source code.
- *
- * @static
- * @memberOf Entry
- * @param {string} $source The source code.
- * @returns {Array} The array of entries.
- */
- public static function getEntries( $source ) {
- preg_match_all('#/\*\*(?![-!])[\s\S]*?\*/\s*.+#', $source, $result);
- return array_pop($result);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Checks if the entry is a function reference.
- *
- * @private
- * @memberOf Entry
- * @returns {boolean} Returns `true` if the entry is a function reference, else `false`.
- */
- private function isFunction() {
- if (!isset($this->_isFunction)) {
- $this->_isFunction = !!(
- $this->isCtor() ||
- count($this->getParams()) ||
- count($this->getReturns()) ||
- preg_match('/\*[\t ]*@function\b/', $this->entry) ||
- preg_match('#\*/\s*function #', $this->entry)
- );
- }
- return $this->_isFunction;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Extracts the entry's `alias` objects.
- *
- * @memberOf Entry
- * @param {number} $index The index of the array value to return.
- * @returns {Array|string} The entry's `alias` objects.
- */
- public function getAliases( $index = null ) {
- if (!isset($this->_aliases)) {
- preg_match('#\*[\t ]*@alias\s+(.+)#', $this->entry, $result);
-
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result[1]));
- $result = preg_split('/,\s*/', $result);
- natsort($result);
-
- foreach ($result as $resultIndex => $value) {
- $result[$resultIndex] = new Alias($value, $this);
- }
- }
- $this->_aliases = $result;
- }
- return $index !== null
- ? @$this->_aliases[$index]
- : $this->_aliases;
- }
-
- /**
- * Extracts the function call from the entry.
- *
- * @memberOf Entry
- * @returns {string} The function call.
- */
- public function getCall() {
- if (isset($this->_call)) {
- return $this->_call;
- }
-
- preg_match('#\*/\s*(?:function ([^(]*)|(.*?)(?=[:=,]|return\b))#', $this->entry, $result);
- if ($result = array_pop($result)) {
- $result = array_pop(explode('var ', trim(trim(array_pop(explode('.', $result))), "'")));
- }
- // resolve name
- // avoid $this->getName() because it calls $this->getCall()
- preg_match('#\*[\t ]*@name\s+(.+)#', $this->entry, $name);
- if (count($name)) {
- $name = trim($name[1]);
- } else {
- $name = $result;
- }
- // compile function call syntax
- if ($this->isFunction()) {
- // compose parts
- $result = array($result);
- $params = $this->getParams();
- $paramNames = array();
-
- foreach ($params as $param) {
- // skip params that are properties of other params (e.g. `options.leading`)
- preg_match('/\w+(?=\.[\w.]+)/', $param[1], $parentParam);
- $parentParam = $parentParam[0];
- if (!in_array($parentParam, $paramNames)) {
- $result[] = $param[1];
- }
- $paramNames[] = preg_replace('/^\[|\]$/', '', $param[1]);
- }
- // format
- $result = $name .'('. implode(array_slice($result, 1), ', ') .')';
- }
-
- $this->_call = $result ? $result : $name;
- return $this->_call;
- }
-
- /**
- * Extracts the entry's `category` data.
- *
- * @memberOf Entry
- * @returns {string} The entry's `category` data.
- */
- public function getCategory() {
- if (isset($this->_category)) {
- return $this->_category;
- }
-
- preg_match('#\*[\t ]*@category\s+(.+)#', $this->entry, $result);
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result[1]));
- } else {
- $result = $this->getType() == 'Function' ? 'Methods' : 'Properties';
- }
- $this->_category = $result;
- return $result;
- }
-
- /**
- * Extracts the entry's description.
- *
- * @memberOf Entry
- * @returns {string} The entry's description.
- */
- public function getDesc() {
- if (isset($this->_desc)) {
- return $this->_desc;
- }
-
- preg_match('#/\*\*(?:\s*\*)?([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
- if (count($result)) {
- $type = $this->getType();
- $result = preg_replace('/:\n[\t ]*\*[\t ]*/', ":
\n", $result[1]);
- $result = preg_replace('/(?:^|\n)[\t ]*\*\n[\t ]*\*[\t ]*/', "\n\n", $result);
- $result = preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result);
- $result = trim($result);
- $result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result;
- }
- $this->_desc = $result;
- return $result;
- }
-
- /**
- * Extracts the entry's `example` data.
- *
- * @memberOf Entry
- * @returns {string} The entry's `example` data.
- */
- public function getExample() {
- if (isset($this->_example)) {
- return $this->_example;
- }
-
- preg_match('#\*[\t ]*@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', "\n", $result[1]));
- $result = '```' . $this->lang . "\n" . $result . "\n```";
- }
- $this->_example = $result;
- return $result;
- }
-
- /**
- * Checks if the entry is an alias.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `false`.
- */
- public function isAlias() {
- return false;
- }
-
- /**
- * Checks if the entry is a constructor.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `true` if a constructor, else `false`.
- */
- public function isCtor() {
- if (!isset($this->_isCtor)) {
- $this->_isCtor = !!preg_match('/\*[\t ]*@constructor\b/', $this->entry);
- }
- return $this->_isCtor;
- }
-
- /**
- * Checks if the entry is a license.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `true` if a license, else `false`.
- */
- public function isLicense() {
- if (!isset($this->_isLicense)) {
- $this->_isLicense = !!preg_match('/\*[\t ]*@license\b/', $this->entry);
- }
- return $this->_isLicense;
- }
-
- /**
- * Checks if the entry *is* assigned to a prototype.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `true` if assigned to a prototype, else `false`.
- */
- public function isPlugin() {
- if (!isset($this->_isPlugin)) {
- $this->_isPlugin = !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
- }
- return $this->_isPlugin;
- }
-
- /**
- * Checks if the entry is private.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `true` if private, else `false`.
- */
- public function isPrivate() {
- if (!isset($this->_isPrivate)) {
- $this->_isPrivate = $this->isLicense() || !!preg_match('/\*[\t ]*@private\b/', $this->entry) || !preg_match('/\*[\t ]*@[a-z]+\b/', $this->entry);
- }
- return $this->_isPrivate;
- }
-
- /**
- * Checks if the entry is *not* assigned to a prototype.
- *
- * @memberOf Entry
- * @returns {boolean} Returns `true` if not assigned to a prototype, else `false`.
- */
- public function isStatic() {
- if (isset($this->_isStatic)) {
- return $this->_isStatic;
- }
-
- $public = !$this->isPrivate();
- $result = $public && !!preg_match('/\*[\t ]*@static\b/', $this->entry);
-
- // set in cases where it isn't explicitly stated
- if ($public && !$result) {
- if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) {
- foreach (Entry::getEntries($this->source) as $entry) {
- $entry = new Entry($entry, $this->source);
- if ($entry->getName() == $parent) {
- $result = !$entry->isCtor();
- break;
- }
- }
- } else {
- $result = true;
- }
- }
- $this->_isStatic = $result;
- return $result;
- }
-
- /**
- * Resolves the entry's line number.
- *
- * @memberOf Entry
- * @returns {number} The entry's line number.
- */
- public function getLineNumber() {
- if (!isset($this->_lineNumber)) {
- preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines);
- $this->_lineNumber = count(array_pop($lines)) + 1;
- }
- return $this->_lineNumber;
- }
-
- /**
- * Extracts the entry's `member` data.
- *
- * @memberOf Entry
- * @param {number} $index The index of the array value to return.
- * @returns {Array|string} The entry's `member` data.
- */
- public function getMembers( $index = null ) {
- if (!isset($this->_members)) {
- preg_match('#\*[\t ]*@member(?:Of)?\s+(.+)#', $this->entry, $result);
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result[1]));
- $result = preg_split('/,\s*/', $result);
- natsort($result);
- }
- $this->_members = $result;
- }
- return $index !== null
- ? @$this->_members[$index]
- : $this->_members;
- }
-
- /**
- * Extracts the entry's `name` data.
- *
- * @memberOf Entry
- * @returns {string} The entry's `name` data.
- */
- public function getName() {
- if (isset($this->_name)) {
- return $this->_name;
- }
-
- preg_match('#\*[\t ]*@name\s+(.+)#', $this->entry, $result);
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result[1]));
- } else {
- $result = array_shift(explode('(', $this->getCall()));
- }
- $this->_name = $result;
- return $result;
- }
-
- /**
- * Extracts the entry's `param` data.
- *
- * @memberOf Entry
- * @param {number} $index The index of the array value to return.
- * @returns {Array} The entry's `param` data.
- */
- public function getParams( $index = null ) {
- if (!isset($this->_params)) {
- preg_match_all('#\*[\t ]*@param\s+\{\(?([^})]+)\)?\}\s+(\[.+\]|[$\w|]+(?:\[.+\])?)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $matchTuples);
- $matchTuples = array_filter(array_slice($matchTuples, 1));
- $result = array();
-
- if (count($matchTuples)) {
- foreach ($matchTuples as $tupleKey => $tuple) {
- foreach ($tuple as $key => $value) {
- if (!isset($result[$key])) {
- $result[$key] = array();
- }
- $result[$key][] = $tupleKey
- ? trim(preg_replace('/(?:^|\n)[\t ]*\*[\t ]*/', ' ', $value))
- : trim($value);
- }
- }
- }
- $this->_params = $result;
- }
- return $index !== null
- ? @$this->_params[$index]
- : $this->_params;
- }
-
- /**
- * Extracts the entry's `returns` data.
- *
- * @memberOf Entry
- * @returns {string} The entry's `returns` data.
- */
- public function getReturns() {
- if (isset($this->_returns)) {
- return $this->_returns;
- }
-
- preg_match('#\*[\t ]*@returns\s+\{([^}]+)\}\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
- if (count($result)) {
- $result = array_map('trim', array_slice($result, 1));
- $result[0] = str_replace('|', ', ', $result[0]);
- $result[1] = preg_replace('/(?:^|\n)[\t ]*\*[\t ]?/', ' ', $result[1]);
- }
- $this->_returns = $result;
- return $result;
- }
-
- /**
- * Extracts the entry's `type` data.
- *
- * @memberOf Entry
- * @returns {string} The entry's `type` data.
- */
- public function getType() {
- if (isset($this->_type)) {
- return $this->_type;
- }
-
- preg_match('#\*[\t ]*@type\s(?:\{\(?)?([^)}\n]+)#', $this->entry, $result);
- if (count($result)) {
- $result = trim($result[1]);
- if (preg_match('/^(?:array|function|object|regexp)$/', $result)) {
- $result = ucfirst($result);
- }
- } else {
- $result = $this->isFunction() ? 'Function' : 'unknown';
- }
- $this->_type = $result;
- return $result;
- }
-}
-?>
\ No newline at end of file
diff --git a/vendor/docdown/src/DocDown/MarkdownGenerator.php b/vendor/docdown/src/DocDown/MarkdownGenerator.php
deleted file mode 100644
index fd7fc15c0..000000000
--- a/vendor/docdown/src/DocDown/MarkdownGenerator.php
+++ /dev/null
@@ -1,648 +0,0 @@
-\n";
-
- /**
- * An array of JSDoc entries.
- *
- * @memberOf MarkdownGenerator
- * @type Array
- */
- public $entries = array();
-
- /**
- * The HTML for the open tag.
- *
- * @memberOf MarkdownGenerator
- * @type string
- */
- public $openTag = "\n\n";
-
- /**
- * An options array used to configure the generator.
- *
- * @memberOf MarkdownGenerator
- * @type Array
- */
- public $options = array();
-
- /**
- * The file's source code.
- *
- * @memberOf MarkdownGenerator
- * @type string
- */
- public $source = '';
-
- /**
- * The array of code snippets that are tokenized by `escape`.
- *
- * @private
- * @memberOf MarkdownGenerator
- * @type Array
- */
- private $snippets = array();
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The MarkdownGenerator constructor.
- *
- * @constructor
- * @param {string} $source The source code to parse.
- * @param {Array} $options The options array.
- */
- public function __construct( $source, $options = array() ) {
- // juggle arguments
- if (is_array($source)) {
- $options = $source;
- } else {
- $options['source'] = $source;
- }
- if (isset($options['source']) && realpath($options['source'])) {
- $options['path'] = $options['source'];
- }
- if (isset($options['path'])) {
- preg_match('/(?<=\.)[a-z]+$/', $options['path'], $ext);
- $options['source'] = file_get_contents($options['path']);
- $ext = array_pop($ext);
-
- if (!isset($options['lang']) && $ext) {
- $options['lang'] = $ext;
- }
- if (!isset($options['title'])) {
- $options['title'] = ucfirst(basename($options['path'])) . ' API documentation';
- }
- }
- if (!isset($options['lang'])) {
- $options['lang'] = 'js';
- }
- if (!isset($options['toc'])) {
- $options['toc'] = 'properties';
- }
-
- $this->options = $options;
- $this->source = str_replace(PHP_EOL, "\n", $options['source']);
- $this->entries = Entry::getEntries($this->source);
-
- foreach ($this->entries as $index => $value) {
- $this->entries[$index] = new Entry($value, $this->source, $options['lang']);
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Performs common string formatting operations.
- *
- * @private
- * @static
- * @memberOf MarkdownGenerator
- * @param {string} $string The string to format.
- * @returns {string} The formatted string.
- */
- private static function format( $string ) {
- $counter = 0;
-
- // tokenize inline code snippets
- preg_match_all('/`[^`]+`/', $string, $tokenized);
- $tokenized = $tokenized[0];
- foreach ($tokenized as $snippet) {
- $string = str_replace($snippet, '__token' . ($counter++) .'__', $string);
- }
-
- // italicize parentheses
- $string = preg_replace('/(^|\s)(\([^)]+\))/', '$1*$2*', $string);
-
- // mark numbers as inline code
- $string = preg_replace('/[\t ](-?\d+(?:.\d+)?)(?!\.[^\n])/', ' `$1`', $string);
-
- // detokenize inline code snippets
- $counter = 0;
- foreach ($tokenized as $snippet) {
- $string = str_replace('__token' . ($counter++) . '__', $snippet, $string);
- }
-
- return trim($string);
- }
-
- /**
- * Modify a string by replacing named tokens with matching assoc. array values.
- *
- * @private
- * @static
- * @memberOf MarkdownGenerator
- * @param {string} $string The string to modify.
- * @param {Array|Object} $object The template object.
- * @returns {string} The modified string.
- */
- private static function interpolate( $string, $object ) {
- preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
- $tokens = array_unique(array_pop($tokens));
-
- foreach ($tokens as $token) {
- $pattern = '/#\{' . preg_replace('/([.*+?^${}()|[\]\\\])/', '\\\$1', $token) . '\}/';
- $replacement = '';
-
- if (is_object($object)) {
- preg_match('/\(([^)]+?)\)$/', $token, $args);
- $args = preg_split('/,\s*/', array_pop($args));
- $method = 'get' . ucfirst(preg_replace('/\([^)]+?\)$/', '', $token));
-
- if (method_exists($object, $method)) {
- $replacement = (string) call_user_func_array(array($object, $method), $args);
- } else if (isset($object->{$token})) {
- $replacement = (string) $object->{$token};
- }
- } else if (isset($object[$token])) {
- $replacement = (string) $object[$token];
- }
- $string = preg_replace($pattern, trim($replacement), $string);
- }
- return MarkdownGenerator::format($string);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Adds the given `$entries` to the `$result` array.
- *
- * @private
- * @memberOf MarkdownGenerator
- * @param {Array} $result The result array to modify.
- * @param {Array} $entries The entries to add to the `$result`.
- */
- private function addEntries( &$result, $entries ) {
- foreach ($entries as $entry) {
- // skip aliases
- if ($entry->isAlias()) {
- continue;
- }
- // name and description
- array_push(
- $result,
- $this->openTag,
- MarkdownGenerator::interpolate("### `#{member}#{separator}#{call}`\n# [Ⓢ](#{href} \"View in source\") [Ⓣ][1]\n\n#{desc}", array(
- 'call' => $entry->getCall(),
- 'desc' => $this->escape($entry->getDesc()),
- 'hash' => $entry->hash,
- 'href' => $entry->href,
- 'member' => $entry->member,
- 'separator' => $entry->separator
- ))
- );
-
- // @alias
- if (count($aliases = $entry->getAliases())) {
- array_push($result, '', '#### Aliases');
- foreach ($aliases as $index => $alias) {
- $aliases[$index] = MarkdownGenerator::interpolate('#{member}#{separator}#{name}', $alias);
- }
- $result[] = '*' . implode(', ', $aliases) . '*';
- }
- // @param
- if (count($params = $entry->getParams())) {
- array_push($result, '', '#### Arguments');
- foreach ($params as $index => $param) {
- $result[] = MarkdownGenerator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
- 'desc' => $this->escape($param[2]),
- 'name' => $param[1],
- 'num' => $index + 1,
- 'type' => $this->escape($param[0])
- ));
- }
- }
- // @returns
- if (count($returns = $entry->getReturns())) {
- array_push(
- $result, '',
- '#### Returns',
- MarkdownGenerator::interpolate('(#{type}): #{desc}', array(
- 'desc' => $this->escape($returns[1]),
- 'type' => $this->escape($returns[0])
- ))
- );
- }
- // @example
- if ($example = $entry->getExample()) {
- array_push($result, '', '#### Example', $example);
- }
- array_push($result, "\n* * *", $this->closeTag);
- }
- }
-
- /**
- * Escapes special Markdown characters.
- *
- * @private
- * @memberOf Entry
- * @param {string} $string The string to escape.
- * @returns {string} Returns the escaped string.
- */
- private function escape( $string ) {
- $string = preg_replace_callback('/`.*?\`/', array($this, 'swapSnippetsToTokens'), $string);
- $string = preg_replace('/(?entries[$entry] : $entry;
- $member = !$member ? $entry->getMembers(0) : $member;
-
- $result = ($member ? $member . ($entry->isPlugin() ? 'prototype' : '') : '') . $entry->getCall();
- $result = preg_replace('/\(\[|\[\]/', '', $result);
- $result = preg_replace('/[\t =|\'"{}.()\]]/', '', $result);
- $result = preg_replace('/[\[#,]+/', '-', $result);
- return strtolower($result);
- }
-
- /**
- * Resolves the entry's url for the specific line number.
- *
- * @private
- * @memberOf MarkdownGenerator
- * @param {number|Object} $entry The entry object.
- * @returns {string} The url.
- */
- private function getLineUrl( $entry ) {
- $entry = is_numeric($entry) ? $this->entries($entry) : $entry;
- return $this->options['url'] . '#L' . $entry->getLineNumber();
- }
-
- /**
- * Extracts the character used to separate the entry's name from its member.
- *
- * @private
- * @memberOf MarkdownGenerator
- * @param {number|Object} $entry The entry object.
- * @returns {string} The separator.
- */
- private function getSeparator( $entry ) {
- $entry = is_numeric($entry) ? $this->entries($entry) : $entry;
- return $entry->isPlugin() ? '.prototype.' : '.';
- }
-
- /**
- * Swaps code snippets with tokens as a `preg_replace_callback` callback
- * used by `escape`.
- *
- * @private
- * @memberOf Entry
- * @param {Array} $matches The array of regexp matches.
- * @returns {string} Returns the token.
- */
- private function swapSnippetsToTokens( $matches ) {
- $this->snippets[] = $matches[0];
- return '@@token@@';
- }
-
- /**
- * Swaps tokens with code snippets as a `preg_replace_callback` callback
- * used by `escape`.
- *
- * @private
- * @memberOf Entry
- * @returns {string} Returns the code snippet.
- */
- private function swapTokensToSnippets() {
- return array_shift($this->snippets);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Generates Markdown from JSDoc entries.
- *
- * @memberOf MarkdownGenerator
- * @returns {string} The rendered Markdown.
- */
- public function generate() {
- $api = array();
- $byCategory = $this->options['toc'] == 'categories';
- $categories = array();
- $closeTag = $this->closeTag;
- $compiling = false;
- $openTag = $this->openTag;
- $result = array('# ' . $this->options['title']);
- $toc = 'toc';
-
- // initialize $api array
- foreach ($this->entries as $entry) {
- // skip invalid or private entries
- $name = $entry->getName();
- if (!$name || $entry->isPrivate()) {
- continue;
- }
-
- $members = $entry->getMembers();
- $members = count($members) ? $members : array('');
-
- foreach ($members as $member) {
- // create api category arrays
- if ($member && !isset($api[$member])) {
- // create temporary entry to be replaced later
- $api[$member] = new stdClass;
- $api[$member]->static = array();
- $api[$member]->plugin = array();
- }
-
- // append entry to api member
- if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
- !preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) {
-
- // assign the real entry, replacing the temporary entry if it exist
- $member = ($member ? $member . ($entry->isPlugin() ? '#' : '.') : '') . $name;
- $entry->static = @$api[$member] ? $api[$member]->static : array();
- $entry->plugin = @$api[$member] ? $api[$member]->plugin : array();
-
- $api[$member] = $entry;
- foreach ($entry->getAliases() as $alias) {
- $api[$member]->static[] = $alias;
- }
- }
- else if ($entry->isStatic()) {
- $api[$member]->static[] = $entry;
- foreach ($entry->getAliases() as $alias) {
- $api[$member]->static[] = $alias;
- }
- }
- else if (!$entry->isCtor()) {
- $api[$member]->plugin[] = $entry;
- foreach ($entry->getAliases() as $alias) {
- $api[$member]->plugin[] = $alias;
- }
- }
- }
- }
-
- // add properties to each entry
- foreach ($api as $entry) {
- $entry->hash = $this->getHash($entry);
- $entry->href = $this->getLineUrl($entry);
- $entry->separator = '';
-
- $member = $entry->getMembers(0);
- $member = ($member ? $member . $this->getSeparator($entry) : '') . $entry->getName();
- $entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
-
- // add properties to static and plugin sub-entries
- foreach (array('static', 'plugin') as $kind) {
- foreach ($entry->{$kind} as $subentry) {
- $subentry->hash = $this->getHash($subentry);
- $subentry->href = $this->getLineUrl($subentry);
- $subentry->member = $member;
- $subentry->separator = $this->getSeparator($subentry);
- }
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- // custom sort for root level entries
- // TODO: see how well it handles deeper namespace traversal
- function sortCompare($a, $b) {
- $score = array( 'a' => 0, 'b' => 0);
- foreach (array( 'a' => $a, 'b' => $b) as $key => $value) {
- // capitalized properties are last
- if (preg_match('/[#.][A-Z]/', $value)) {
- $score[$key] = 0;
- }
- // lowercase prototype properties are next to last
- else if (preg_match('/#[a-z]/', $value)) {
- $score[$key] = 1;
- }
- // lowercase static properties next to first
- else if (preg_match('/\.[a-z]/', $value)) {
- $score[$key] = 2;
- }
- // root properties are first
- else if (preg_match('/^[^#.]+$/', $value)) {
- $score[$key] = 3;
- }
- }
- $score = $score['b'] - $score['a'];
- return $score ? $score : strcasecmp($a, $b);
- }
-
- uksort($api, 'sortCompare');
-
- // sort static and plugin sub-entries
- foreach ($api as $entry) {
- foreach (array('static', 'plugin') as $kind) {
- $sortBy = array( 'a' => array(), 'b' => array(), 'c' => array() );
- foreach ($entry->{$kind} as $subentry) {
- $name = $subentry->getName();
- // functions w/o ALL-CAPs names are last
- $sortBy['a'][] = $subentry->getType() == 'Function' && !preg_match('/^[A-Z_]+$/', $name);
- // ALL-CAPs properties first
- $sortBy['b'][] = preg_match('/^[A-Z_]+$/', $name);
- // lowercase alphanumeric sort
- $sortBy['c'][] = strtolower($name);
- }
- array_multisort($sortBy['a'], SORT_ASC, $sortBy['b'], SORT_DESC, $sortBy['c'], SORT_ASC, $entry->{$kind});
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- // add categories
- foreach ($api as $entry) {
- $categories[$entry->getCategory()][] = $entry;
- foreach (array('static', 'plugin') as $kind) {
- foreach ($entry->{$kind} as $subentry) {
- $categories[$subentry->getCategory()][] = $subentry;
- }
- }
- }
-
- // sort categories
- ksort($categories);
-
- foreach(array('Methods', 'Properties') as $category) {
- if (isset($categories[$category])) {
- $entries = $categories[$category];
- unset($categories[$category]);
- $categories[$category] = $entries;
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- // compile TOC
- $result[] = $openTag;
-
- // compile TOC by categories
- if ($byCategory) {
- foreach ($categories as $category => $entries) {
- if ($compiling) {
- $result[] = $closeTag;
- } else {
- $compiling = true;
- }
- // assign TOC hash
- if (count($result) == 2) {
- $toc = strtolower($category);
- }
- // add category
- array_push(
- $result,
- $openTag, '## ' . (count($result) == 2 ? '' : '') . '`' . $category . '`'
- );
- // add entries
- foreach ($entries as $entry) {
- if ($entry->isAlias()) {
- $result[] = MarkdownGenerator::interpolate('* `#{member}#{separator}#{name}` -> `#{realName}`', array(
- 'hash' => $entry->hash,
- 'member' => $entry->member,
- 'name' => $entry->getName(),
- 'realName' => $entry->owner->getName(),
- 'separator' => $entry->separator
- ));
- }
- else {
- $result[] = MarkdownGenerator::interpolate('* `#{member}#{separator}#{name}`', $entry);
- }
- }
- }
- }
- // compile TOC by namespace
- else {
- foreach ($api as $entry) {
- if ($compiling) {
- $result[] = $closeTag;
- } else {
- $compiling = true;
- }
- $member = $entry->member . $entry->getName();
-
- // assign TOC hash
- if (count($result) == 2) {
- $toc = $member;
- }
- // add root entry
- array_push(
- $result,
- $openTag, '## ' . (count($result) == 2 ? '' : '') . '`' . $member . '`',
- MarkdownGenerator::interpolate('* [`' . $member . '`](##{hash})', $entry)
- );
-
- // add static and plugin sub-entries
- foreach (array('static', 'plugin') as $kind) {
- if ($kind == 'plugin' && count($entry->plugin)) {
- array_push(
- $result,
- $closeTag,
- $openTag,
- '## `' . $member . ($entry->isCtor() ? '.prototype`' : '`')
- );
- }
- foreach ($entry->{$kind} as $subentry) {
- $subentry->member = $member;
- if ($subentry->isAlias()) {
- $result[] = MarkdownGenerator::interpolate('* `#{member}#{separator}#{name}` -> `#{realName}`', array(
- 'hash' => $subentry->hash,
- 'member' => $subentry->member,
- 'name' => $subentry->getName(),
- 'realName' => $subentry->owner->getName(),
- 'separator' => $subentry->separator
- ));
- }
- else {
- $result[] = MarkdownGenerator::interpolate('* `#{member}#{separator}#{name}`', $subentry);
- }
- }
- }
- }
- }
-
- array_push($result, $closeTag, $closeTag);
-
- /*------------------------------------------------------------------------*/
-
- // compile content
- $compiling = false;
- $result[] = $openTag;
-
- if ($byCategory) {
- foreach ($categories as $category => $entries) {
- if ($compiling) {
- $result[] = $closeTag;
- } else {
- $compiling = true;
- }
- if ($category != 'Methods' && $category != 'Properties') {
- $category = '“' . $category . '” Methods';
- }
- array_push($result, $openTag, '## `' . $category . '`');
- $this->addEntries($result, $entries);
- }
- }
- else {
- foreach ($api as $entry) {
- // skip aliases
- if ($entry->isAlias()) {
- continue;
- }
- if ($compiling) {
- $result[] = $closeTag;
- } else {
- $compiling = true;
- }
- // add root entry name
- $member = $entry->member . $entry->getName();
- array_push($result, $openTag, '## `' . $member . '`');
-
- foreach (array($entry, 'static', 'plugin') as $kind) {
- $subentries = is_string($kind) ? $entry->{$kind} : array($kind);
-
- // add sub-entry name
- if ($kind != 'static' && $entry->getType() != 'Object' &&
- count($subentries) && $subentries[0] != $kind) {
- if ($kind == 'plugin') {
- $result[] = $closeTag;
- }
- array_push(
- $result,
- $openTag,
- '## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
- );
- }
- $this->addEntries($result, $subentries);
- }
- }
- }
-
- // close tags add TOC link reference
- array_push($result, $closeTag, $closeTag, '', ' [1]: #' . $toc . ' "Jump back to the TOC."');
-
- // cleanup whitespace
- return trim(preg_replace('/[\t ]+\n/', "\n", join($result, "\n")));
- }
-}
-?>
\ No newline at end of file