-
-
Notifications
You must be signed in to change notification settings - Fork 1
Custom Methods
Custom method titles can be implemented by providing a method
JSX component. The component can be placed in the project's directory e.g.,
-
package/.documentary/index.jsx
, or package/.documentary.jsx
The JSX file read by documentary must export the named method
export:
/**
* A method title for Documentary.
* @param {Object} opts
* @param {import('typal/types').Method} opts.method
*/
export const method = ({ method, level }) => {
const hash = '#'.repeat(level)
const args = method.args.map(({ name, optional }) => {
return optional ? `[${name}]` : name
}).join(', ')
return `${hash} ${method.name} (${args})`
} |
The component itself, like other Documentary Components can return a string, a JSX element, or an array of those.
The method title rule allows to define a method in Markdown using JSON notation using an array of arguments and their types, for example:
```### async runSoftware => string
[
["path", "string"],
["config", {
"View": ["Container"],
"actions": ["object"],
"static=": ["boolean", true],
"render=": ["function"]
}, "Config"]
]
```
The method title above would be rendered in the following way:
async runSoftware(
path: string,
config: {
View: Container,
actions: object,
static?: boolean = true,
render?: function,
},
): string
However, it is understandable that developers would want to implement their own designs of method titles, yet use the simplicity and standardisation of notation to their advantage.
In a more advanced use case, methods are defined in a separate file, and can also be embedded into documentation. This page shows how to render the headings of methods and their titles, regardless of where the information about the method comes from.
A method is a special case of a Typal's type and includes the following properties that can be used when rendering the title:
- name: The name of the method.
- async: Whether the method is async.
- return: The return type.
- args: And the array of arguments.
Each argument is a record of the following type:
- name: The name of the argument.
- type: The argument's type. Either a string, or an object as discussed on the Method Titles page.
-
optional: Whether the argument is optional. This is deduced from arguments' name ending with the
=
symbol. - shortType: When an argument is defined as an object as in the example above, this can be used as a shorted title, for example for the table of contents.
When the correct JSDoc specifying import('typal/types').Method as the method param is written for the custom component, all this information will be available in the IDE (VSCode):
|
|
Finally, the component will receive the level
property indicating the level at which the heading should be placed.
Therefore, by following the custom implementation provided at the top of the page, the following result will be achieved:
## Table Of Contents
- [Table Of Contents](#table-of-contents)
- [runSoftware (path, [config])](#runsoftware-path-config)
## runSoftware (path, [config])
Show Source
## Table Of Contents
%TOC%
```## async runSoftware => string
[
["path", "string"],
["config=", {
"View": ["Container"],
"actions": ["object"],
"static?": ["boolean", true],
"render?": ["function"]
}, "Config"]
]
```
After the method title is placed, another pass will generate tables of contents at the end by looking for #{...}
and <h{1-6}>
headings. To supply a custom link for the table of contents, it's possible to call the documentary.addDToc
method:
/**
* A method title for Documentary.
* @param {Object} opts
* @param {import('typal/types').Method} opts.method
* @param {import('documentary')} opts.documentary
*/
export const method = ({ method, level, documentary }) => {
const hash = '#'.repeat(level)
const args = method.args.map(({ name, optional }) => {
return optional ? `[${name}]` : name
}).join(', ')
const sig = `${hash} ${method.name} (${args})`
/* can use Documentary engine to generate TOC entry
const dtoc = documentary.addDtoc('MT', {
args: method.args.map(({ name, type, shortType, optional }) => {
const N = `${name}${optional ? '=' : ''}`
return [N, type, shortType]
}),
hash,
isAsync: method.async,
name: method.name,
returnType: method.return,
replacedTitle: sig,
noArgTypesInToc,
}) */
const dtoc = documentary.addDtoc('MT', {
string: `${method.name}()`,
replacedTitle: sig,
level,
})
return `${dtoc}${sig}`
}
There are two possibilities to use the addDToc
method: either to use Documentary's engine to render the heading for the link, using information about the method, or to give the string that should appear in TOC. When giving a string, 3 options are expected:
- string: The string to display in TOC.
- replacedTitle: The title that will serve as heading. It will be used to generate a link in the same format that GitHub uses, so that's basically the return of the component.
- level: Controls the level of TOC where to place the link.
The updated generated documentation looks the following:
## Table Of Contents
- [Table Of Contents](#table-of-contents)
- [runSoftware()](#runsoftware-path-config)
## runSoftware (path, [config])
Notice how this time, because the string
was passed with the title without arguments, they don't appear in the table of contents, yet are present in the heading and participate in the formation of the link.
To debug a method title, the following configuration can be created for VS Code:
{
"type": "node",
"request": "launch",
"name": "Launch Doc",
"program": "${workspaceFolder}/node_modules/.bin/doc",
"env": { "NODE_DEBUG": "doc" },
"skipFiles": [
"<node_internals>/**/*.js"
]
}
Then either a breakpoint should be set in the component's file, or the debugger
statement added somewhere in the code. Without any arguments, Documentary will read the documentary
source directory and produce output to STDOUT. No JSX setup is required since Documentary uses ÀLaMode internally for transpilation.