Organize docs by category. [closes #84]

Former-commit-id: f4ebda7c32a0ce9c5a86cdb0fd1e689f76557e42
This commit is contained in:
John-David Dalton
2012-10-07 02:19:16 -07:00
parent 8f7d5dcb4d
commit 839e52ba30
7 changed files with 2547 additions and 2392 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,10 @@
// generate Markdown // generate Markdown
$markdown = docdown(array( $markdown = docdown(array(
'path' => '../' . $file, 'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.8.1</sup>', 'title' => 'Lo-Dash <sup>v0.8.1</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js' 'toc' => 'categories',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
)); ));
// save to a .md file // save to a .md file

View File

@@ -235,6 +235,7 @@
* *
* @name _ * @name _
* @constructor * @constructor
* @category Chaining
* @param {Mixed} value The value to wrap in a `lodash` instance. * @param {Mixed} value The value to wrap in a `lodash` instance.
* @returns {Object} Returns a `lodash` instance. * @returns {Object} Returns a `lodash` instance.
*/ */

View File

@@ -22,7 +22,7 @@ class Alias {
* @param {String} $name The alias name. * @param {String} $name The alias name.
* @param {Object} $owner The alias owner. * @param {Object} $owner The alias owner.
*/ */
public function __construct($name, $owner) { public function __construct( $name, $owner ) {
$this->owner = $owner; $this->owner = $owner;
$this->_name = $name; $this->_name = $name;
$this->_call = $owner->getCall(); $this->_call = $owner->getCall();

View File

@@ -166,6 +166,8 @@ class Entry {
preg_match('#\* *@category\s+([^\n]+)#', $this->entry, $result); preg_match('#\* *@category\s+([^\n]+)#', $this->entry, $result);
if (count($result)) { if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1])); $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = $this->getType() == 'Function' ? 'Methods' : 'Properties';
} }
$this->_category = $result; $this->_category = $result;
return $result; return $result;

View File

@@ -7,6 +7,15 @@ require(dirname(__FILE__) . "/Entry.php");
*/ */
class Generator { class Generator {
/**
* The HTML for the close tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $closeTag = "\n<!-- /div -->\n";
/** /**
* An array of JSDoc entries. * An array of JSDoc entries.
* *
@@ -15,6 +24,15 @@ class Generator {
*/ */
public $entries = array(); public $entries = array();
/**
* The HTML for the open tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $openTag = "\n<!-- div -->\n";
/** /**
* An options array used to configure the generator. * An options array used to configure the generator.
* *
@@ -24,7 +42,7 @@ class Generator {
public $options = array(); public $options = array();
/** /**
* The entire file's source code. * The file's source code.
* *
* @memberOf Generator * @memberOf Generator
* @type String * @type String
@@ -86,7 +104,7 @@ class Generator {
* @param {String} $string The string to format. * @param {String} $string The string to format.
* @returns {String} The formatted string. * @returns {String} The formatted string.
*/ */
private static function format($string) { private static function format( $string ) {
$counter = 0; $counter = 0;
// tokenize inline code snippets // tokenize inline code snippets
@@ -121,7 +139,7 @@ class Generator {
* @param {Array|Object} $object The template object. * @param {Array|Object} $object The template object.
* @returns {String} The modified string. * @returns {String} The modified string.
*/ */
private static function interpolate($string, $object) { private static function interpolate( $string, $object ) {
preg_match_all('/#\{([^}]+)\}/', $string, $tokens); preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
$tokens = array_unique(array_pop($tokens)); $tokens = array_unique(array_pop($tokens));
@@ -149,6 +167,63 @@ class Generator {
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/**
* Adds the given `$entries` to the `$result` array.
*
* @private
* @memberOf Generator
* @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,
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [&#x24C8;](#{href} \"View in source\") [&#x24C9;][1]\n\n#{desc}", $entry)
);
// @alias
if (count($aliases = $entry->getAliases())) {
array_push($result, '', '#### Aliases');
foreach ($aliases as $index => $alias) {
$aliases[$index] = $alias->getName();
}
$result[] = '*' . implode(', ', $aliases) . '*';
}
// @param
if (count($params = $entry->getParams())) {
array_push($result, '', '#### Arguments');
foreach ($params as $index => $param) {
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
'desc' => $param[2],
'name' => $param[1],
'num' => $index + 1,
'type' => $param[0]
));
}
}
// @returns
if (count($returns = $entry->getReturns())) {
array_push(
$result, '',
'#### Returns',
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
);
}
// @example
if ($example = $entry->getExample()) {
array_push($result, '', '#### Example', $example);
}
array_push($result, "\n* * *", $this->closeTag);
}
}
/** /**
* Resolves the entry's hash used to navigate the documentation. * Resolves the entry's hash used to navigate the documentation.
* *
@@ -204,10 +279,11 @@ class Generator {
*/ */
public function generate() { public function generate() {
$api = array(); $api = array();
$byCategory = @$this->options['toc'] == 'categories';
$categories = array(); $categories = array();
$closeTag = $this->closeTag;
$compiling = false; $compiling = false;
$openTag = "\n<!-- div -->\n"; $openTag = $this->openTag;
$closeTag = "\n<!-- /div -->\n";
$result = array('# ' . $this->options['title']); $result = array('# ' . $this->options['title']);
$toc = 'toc'; $toc = 'toc';
@@ -231,18 +307,6 @@ class Generator {
$api[$member]->plugin = array(); $api[$member]->plugin = array();
} }
// track categories
$category = $entry->getCategory();
if ($category) {
if (!isset($categories[$category])) {
$categories[$category] = array();
}
$categories[$category][] = $entry;
foreach ($entry->getAliases() as $alias) {
$categories[$category][] = $alias;
}
}
// append entry to api member // append entry to api member
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' && if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
!preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) { !preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) {
@@ -274,6 +338,26 @@ class Generator {
} }
} }
// add properties to each entry
foreach ($api as $key => $entry) {
$entry->hash = $this->getHash($entry);
$entry->href = $this->getLineUrl($entry);
$member = $entry->getMembers(0);
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $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 // custom sort for root level entries
@@ -323,48 +407,89 @@ class Generator {
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
// add categories
foreach ($api as $key => $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 // compile TOC
$result[] = $openTag; $result[] = $openTag;
foreach ($api as $key => $entry) { // compile TOC by categories
$entry->hash = $this->getHash($entry); if ($byCategory) {
$entry->href = $this->getLineUrl($entry); foreach ($categories as $key => $entries) {
if ($compiling) {
$member = $entry->getMembers(0); $result[] = $closeTag;
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName(); } else {
$compiling = true;
$entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
$compiling = $compiling ? ($result[] = $closeTag) : true;
// assign TOC hash
if (count($result) == 2) {
$toc = $member;
}
// add root entry
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
Generator::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) { // assign TOC hash
$subentry->hash = $this->getHash($subentry); if (count($result) == 2) {
$subentry->href = $this->getLineUrl($subentry); $toc = $key;
$subentry->member = $member; }
$subentry->separator = $this->getSeparator($subentry); // add category
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry); array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $key . '`'
);
// add entries
foreach ($entries as $entry) {
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $entry);
}
}
}
// compile TOC by namespace
else {
foreach ($api as $key => $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 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
Generator::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) {
$result[] = Generator::interpolate('* [`' . $member . '#{separator}#{name}`](##{hash})', $subentry);
}
} }
} }
} }
@@ -377,81 +502,51 @@ class Generator {
$compiling = false; $compiling = false;
$result[] = $openTag; $result[] = $openTag;
foreach ($api as $entry) { if ($byCategory) {
// skip aliases foreach ($categories as $key => $entries) {
if ($entry->isAlias()) { if ($compiling) {
continue; $result[] = $closeTag;
} } else {
$compiling = true;
// add root entry
$member = $entry->member . $entry->getName();
$compiling = $compiling ? ($result[] = $closeTag) : true;
array_push($result, $openTag, '## `' . $member . '`');
foreach (array($entry, 'static', 'plugin') as $kind) {
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
// title
if ($kind != 'static' && $entry->getType() != 'Object' &&
count($subentries) && $subentries[0] != $kind) {
if ($kind == 'plugin') {
$result[] = $closeTag;
}
array_push(
$result,
$openTag,
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
);
} }
if ($key != 'Methods' && $key != 'Properties') {
$key = '“' . $key . '” Methods';
}
array_push($result, $openTag, '## `' . $key . '`');
$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 . '`');
// body foreach (array($entry, 'static', 'plugin') as $kind) {
foreach ($subentries as $subentry) { $subentries = is_string($kind) ? $entry->{$kind} : array($kind);
// skip aliases
if ($subentry->isAlias()) {
continue;
}
// description // add sub-entry name
array_push( if ($kind != 'static' && $entry->getType() != 'Object' &&
$result, count($subentries) && $subentries[0] != $kind) {
$openTag, if ($kind == 'plugin') {
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [&#x24C8;](#{href} \"View in source\") [&#x24C9;][1]\n\n#{desc}", $subentry) $result[] = $closeTag;
);
// @alias
if (count($aliases = $subentry->getAliases())) {
array_push($result, '', '#### Aliases');
foreach ($aliases as $index => $alias) {
$aliases[$index] = $alias->getName();
} }
$result[] = '*' . implode(', ', $aliases) . '*';
}
// @param
if (count($params = $subentry->getParams())) {
array_push($result, '', '#### Arguments');
foreach ($params as $index => $param) {
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
'desc' => $param[2],
'name' => $param[1],
'num' => $index + 1,
'type' => $param[0]
));
}
}
// @returns
if (count($returns = $subentry->getReturns())) {
array_push( array_push(
$result, '', $result,
'#### Returns', $openTag,
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0])) '## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
); );
} }
// @example $this->addEntries($result, $subentries);
if ($example = $subentry->getExample()) {
array_push($result, '', '#### Example', $example);
}
array_push($result, "\n* * *", $closeTag);
} }
} }
} }