Skip to content

Commit

Permalink
feat: support multi files in manual.
Browse files Browse the repository at this point in the history
  • Loading branch information
h13i32maru committed Oct 18, 2015
1 parent a6e12d4 commit a887a78
Show file tree
Hide file tree
Showing 26 changed files with 423 additions and 115 deletions.
16 changes: 8 additions & 8 deletions esdoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
],
"manual": {
"asset": "./manual/asset",
"overview": "./manual/overview.md",
"installation": "./manual/installation.md",
"usage": "./manual/usage.md",
"tutorial": "./manual/tutorial.md",
"configuration": "./manual/configuration.md",
"example": "./manual/example.md",
"faq": "./manual/faq.md",
"changelog": "./CHANGELOG.md"
"overview": ["./manual/overview.md", "./manual/feature.md"],
"installation": ["./manual/installation.md"],
"usage": ["./manual/usage.md", "./manual/api.md"],
"tutorial": ["./manual/tutorial.md"],
"configuration": ["./manual/configuration.md"],
"example": ["./manual/example.md"],
"faq": ["./manual/faq.md"],
"changelog": ["./CHANGELOG.md"]
}
}
95 changes: 95 additions & 0 deletions manual/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# API
If you want to customize output, you can choose following way.

- [Style sheets and scripts](#style-sheets-and-scripts)
- [Plugin feature](#plugin-feature)
- [Publisher](#publisher)

## Style Sheets and Scripts
You can includes your style sheets and scripts into output documentation.
To see ``styles`` and ``scripts`` in [Config](config.html)

## Plugin Feature
You can modify data(config, code, parser, AST, tag and HTML) at hook points with plugins.

First, you set ``plugins`` property in config.

<p class="file-path">esdoc.json</p>
```json
{
"source": "./src",
"destination": "./doc",
"plugins": [
{"name": "./my-plugin.js"},
{"name": "awesome-plugin-in-npm", "option": {"foo": 123}}
]
}
```

Second, you write plugin code.

<p class="file-path">my-plugin.js</p>
```javascript
exports.onStart = function(ev) {
// take option
ev.data.option;
};

exports.onHandleConfig = function(ev) {
// modify config
ev.data.config.title = ...;
};

exports.onHandleCode = function(ev) {
// modify code
ev.data.code = ...;
};

exports.onHandleCodeParser = function(ev) {
// modify parser
ev.data.parser = function(code){ ... };
};

exports.onHandleAST = function(ev) {
// modify AST
ev.data.ast = ...;
};

exports.onHandleTag = function(ev) {
// modify tag
ev.data.tag = ...;
};

exports.onHandleHTML = function(ev) {
// modify HTML
ev.data.html = ...;
};

exports.onComplete = function(ev) {
// complete
};
```

FYI: [esdoc-es7-plugin](https://github.com/esdoc/esdoc-es7-plugin) and [esdoc-importpath-plugin](https://github.com/esdoc/esdoc-importpath-plugin)

## Publisher
This is useful for programmable operation ESDoc(e.g. making grunt plugin of ESDoc)

```javascript
import ESDoc from 'esdoc/out/src/ESDoc.js';
import publisher from 'esdoc/out/src/Publisher/publish.js';

const config = {source: './src', destination: './doc'};

ESDoc.generate(config, publisher);

# if you want to use own publisher
# function publisher(results, config) {
# console.log(results);
# }
# ESDoc.generate(config, publisher);
```

## Internal Data
TODO: describe internal data.

Binary file added manual/asset/image/feature/class1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/class2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/coverage1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/hosting1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/lint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/manual1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/manual2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/module1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/search1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/test1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/asset/image/feature/test2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
156 changes: 156 additions & 0 deletions manual/feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Features
ESDoc has some features.
I will introduce part of the features.
If you want to see all features, you visit [Demo](./#demo) page.

- [ES6 Class](#es6-class)
- [ES6 Module](#es6-module)
- [Documentation Coverage](#documentation-coverage)
- [Integration Test Codes](#integration-test-codes)
- [Integration Manual](#integration-manual)
- [Search Documentation](#search-documentation)
- [Guess Type](#guess-type)
- [Documentation Lint](#documentation-lint)
- [Customize](#customize)
- [ESDoc Hosting Service](#esdoc-hosting-service)


## ES6 Class
ESDoc supports ES6 Class syntax and targets a code that is written by it.
ES6 Class syntax makes the clear relation of class, method, member, constructor and inheritance.
This means that ESDoc can generate a document without using a tag for these.

ESDoc automatically generates the under contents by Class syntax.

- Super classes of self
- Direct Subclasses and Indirect Subclasses of self.
- Inherited methods and members from super class.
- Override methods and members from super class.

<img src="./asset/image/feature/class1.png" class="screen-shot" width="500px">

<img src="./asset/image/feature/class2.png" class="screen-shot" width="500px">

## ES6 Module
ESDoc supports ES6 Module syntax and targets a code that is written by it.
ES6 Modules syntax is file base. So ESDoc treats as one file = one module.

ESDoc displays the import style in accordance with the export style.
- If ``export default class Foo{}``, displays ``import Foo from './Foo.js'``
- If ``export class Foo{}``, displays ``import {Foo} from './Foo.js'``

This is useful because you not need to see export style in source code.

<img src="./asset/image/feature/module1.png" class="screen-shot" width="500px">

## Documentation Coverage
ESDoc measures a documentation coverage. This is useful information for following.
- This leads the motivation of documentation.
- This inspects a missing of documentation.

ESDoc processes only top-level class, function and variable.
This is based on, ESDoc measures coverage by how much the document is being written out of all the processing target.
And, ESDoc is also to measure coverage of each module, you will have become easier to also find a missing of the document.
For example, [this](./esdoc/source.html) is coverage of ESDoc itself.

<img src="./asset/image/feature/coverage1.png" class="screen-shot" width="500px">

## Integration Test Codes
Test codes are important information.
So, ESDoc generates a cross reference of test codes and document.
You need to use @test tag for this function.

```javascript
/** @test {MyClass} */
describe('MyClass is super useful class.', ()=>{

/** @test {MyClass#sayMyName} */
it('say my name', ()=>{
let foo = new MyClass('Alice');
assert.equal(foo.sayMyName(), 'My name is Alice');
})
});
```

<img src="./asset/image/feature/test1.png" class="screen-shot" width="500px">

<img src="./asset/image/feature/test2.png" class="screen-shot" width="500px">

However, for now, ESDoc supports only Mocha.

## Integration Manual
You can integrate manual into documentation. The manual is:
- Overview
- Installation
- Usage
- Tutorial
- Configuration
- Example
- FAQ
- Changelog

You write manual as markdown and add ``manual`` config.

```json
{
"source": "./src",
"destination": "./doc",
"manual": {
"overview": "./manual/overview.md",
"installation": "./manual/installation.md",
"usage": "./manual/usage.md",
"tutorial": "./manual/tutorial.md",
"configuration": "./manual/configuration.md",
"example": "./manual/example.md",
"faq": "./manual/faq.md",
"changelog": "./CHANGELOG.md"
}
}
```

You can specify a only part of these manuals (e.g. only overview and installation).

<img src="./asset/image/feature/manual1.png" class="screen-shot" width="500px">

<img src="./asset/image/feature/manual2.png" class="screen-shot" width="500px">

## Search Documentation
ESDoc supports searching in document with only JavaScript(without server implementation).
The implementation of searching:
- ESDoc made the index(JSON) at the time of document generation.
- The user search from the index.

However, this implementation is very naive. There might be a problem in search performance. For now, no problem in 500 indexes.

<img src="./asset/image/feature/search1.png" class="screen-shot" width="500px">

## Guess Type
ESDoc guesses type of function arguments by ES6 default argument syntax if there is not ``@param`` at the function.
This implementation is very simply. If Arguments has a primitive(number, boolean, string, etc) default value, ESDoc guesses that the function arguments type is the primitive value.
ESDoc guesses type of function return in the same way if there is not ``@return`` at the function.

## Documentation Lint
If documentation is invalid, show warning log.

```javascript
export default class Foo {
/**
* @param {number} x
*/
method(p){}
}
```

<img src="./asset/image/feature/lint.png" class="screen-shot" width="500px">

For now, only validate method|function signature.

## Customize
If you want to customize a document, you can includes your stylesheets and scripts to the document.
And, ESDoc support to plugin feature. But, ESDoc has goal that generates the useful document without user plugins.
Please read [API](/api.html) for more information.

## ESDoc Hosting Service
[ESDoc Hosting Service](https://doc.esdoc.org) generates your documentation via GitHub and hosts it.

<img src="./asset/image/feature/hosting1.png" class="screen-shot" width="500px">
11 changes: 0 additions & 11 deletions manual/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,3 @@
```
esdoc -c esdoc.json
```

## API
```javascript
import ESDoc from 'esdoc/out/src/ESDoc.js';
import publisher from 'esdoc/out/src/Publisher/publish.js';

const config = {source: './src', destination: './doc'};

ESDoc.generate(config, publisher);
```

42 changes: 20 additions & 22 deletions src/Publisher/Builder/ManualDocBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class ManualDocBuilder extends DocBuilder {
const manualConfig = this._getManualConfig();
const ice = this._buildLayoutDoc();
ice.autoDrop = false;
ice.attr('rootContainer', 'class', ' manual-root');

{
const fileName = 'manual/index.html';
Expand All @@ -32,7 +33,7 @@ export default class ManualDocBuilder extends DocBuilder {
}

for (let item of manualConfig) {
if (!item.path) continue;
if (!item.paths) continue;
const fileName = this._getManualOutputFileName(item);
const baseUrl = this._getBaseUrl(fileName);
ice.load('content', this._buildManual(item), IceCap.MODE_WRITE);
Expand All @@ -55,15 +56,15 @@ export default class ManualDocBuilder extends DocBuilder {
_getManualConfig() {
const m = this._config.manual;
const manualConfig = [];
if (m.overview) manualConfig.push({label: 'Overview', path: m.overview});
if (m.installation) manualConfig.push({label: 'Installation', path: m.installation});
if (m.usage) manualConfig.push({label: 'Usage', path: m.usage});
if (m.tutorial) manualConfig.push({label: 'Tutorial', path: m.tutorial});
if (m.configuration) manualConfig.push({label: 'Configuration', path: m.configuration});
if (m.example) manualConfig.push({label: 'Example', path: m.example});
if (m.overview) manualConfig.push({label: 'Overview', paths: m.overview});
if (m.installation) manualConfig.push({label: 'Installation', paths: m.installation});
if (m.tutorial) manualConfig.push({label: 'Tutorial', paths: m.tutorial});
if (m.usage) manualConfig.push({label: 'Usage', paths: m.usage});
if (m.configuration) manualConfig.push({label: 'Configuration', paths: m.configuration});
if (m.example) manualConfig.push({label: 'Example', paths: m.example});
manualConfig.push({label: 'Reference', fileName: 'identifiers.html', references: true});
if (m.faq) manualConfig.push({label: 'FAQ', path: m.faq});
if (m.changelog) manualConfig.push({label: 'Changelog', path: m.changelog});
if (m.faq) manualConfig.push({label: 'FAQ', paths: m.faq});
if (m.changelog) manualConfig.push({label: 'Changelog', paths: m.changelog});
return manualConfig;
}

Expand All @@ -74,12 +75,10 @@ export default class ManualDocBuilder extends DocBuilder {
* @private
*/
_buildManualNav(manualConfig) {
const ice = new IceCap(this._readTemplate('manualNav.html'));
ice.loop('navItem', manualConfig, (i, item, ice)=>{
ice.text('link', item.label);
ice.attr('link', 'href', this._getManualOutputFileName(item));
});
return ice;
const ice = this._buildManualIndex(manualConfig);
const $root = cheerio.load(ice.html).root();
$root.find('.github-markdown').removeClass('github-markdown');
return $root.html();
}

/**
Expand All @@ -92,7 +91,6 @@ export default class ManualDocBuilder extends DocBuilder {
const html = this._convertMDToHTML(item);
const ice = new IceCap(this._readTemplate('manual.html'));
ice.text('title', item.label);
ice.attr('title', 'id', item.label.toLowerCase());
ice.load('content', html);

// convert relative src to base url relative src.
Expand Down Expand Up @@ -157,6 +155,7 @@ export default class ManualDocBuilder extends DocBuilder {
});
}

ice.attr('manual', 'data-toc-name', item.label.toLowerCase());
ice.text('title', item.label);
ice.attr('title', 'href', this._getManualOutputFileName(item));
ice.loop('manualNav', toc, (i, item, ice)=>{
Expand Down Expand Up @@ -189,14 +188,13 @@ export default class ManualDocBuilder extends DocBuilder {
* @private
*/
_convertMDToHTML(item) {
const content = fs.readFileSync(item.path).toString();
const contents = [];
for (let path of item.paths) {
contents.push(fs.readFileSync(path).toString());
}
const content = contents.join('\n\n');
const html = markdown(content);
const $root = cheerio.load(html).root();
const $h1 = $root.find('h1');
const synonyms = this._getLabelSynonyms(item.label);
if ($h1.length === 1 && synonyms.includes($h1.text().toLowerCase())) {
$h1.remove();
}
return $root.html();
}

Expand Down
Loading

0 comments on commit a887a78

Please sign in to comment.