-
-
Notifications
You must be signed in to change notification settings - Fork 1
Forks
When placing examples, it is important to show the output that they produce. This can be achieved using the FORK
marker.
%[/!_]FORK(-lang)? module ...args%
Listing examples and forking source code in documentation, gives another layer of Quality Assurance of the program, since after the compilation of the README file, any errors due to introduced changes to the source code will appear there. In fact, in some cases, documentation-driven development can even substitute tests.
- On This Page
- Stderr
- Caching
- Import/Exports Support
- Replace Absolute Paths
<fork>
- Env Variables
- Both Channels
- CLI Answers
The %FORK%
marker will make Documentary fork a Node.JS module using the child_process.fork
function. The output is printed in a code block, with optionally given language. If the process cleared lines with \r
, the output will be adjusted to account for that to be displayed like it would be in the terminal. The environment variables will be inherited from the parent doc
process.
Markdown | JavaScript |
---|---|
The program will output:
%FORK-fs example/fork/fork% |
process.stdout.write('...\r')
process.stdout.write('!!\r')
process.stdout.write('?\r\n')
// Display a welcome message.
console.log('HELLO world') |
Output | |
|
By default, the FORK
marker will print the stdout
output. To print the stderr
output, there is the FORKERR
marker.
%FORKERR(-lang)? module ...args%
It works exactly the same as %FORK%
but will print the output of the process's stderr
stream.
Markdown | JavaScript |
---|---|
In case of an error,
the program will print:
%FORKERR-fs example/fork/fork-stderr% |
// Notify of an error.
console.error('Runtime error!') |
Output | |
In case of an error,
the program will print:
```fs
Runtime error!
``` |
The output of forks will be cached in the .documentary/cache
directory. When compiling documentation, Documentary will check for the presence of cache, check the mtime of the module and if it is the same as cached, analyse module's dependencies to see if any of them had changes (updates to package dependencies' versions, changes to source files).
When the cache is matched, no forking will take place and the value will be taken from the saved outputs. To explicitly prevent caching on a particular FORK marker, it should be prefixed with !
: %!FORK module arg1 arg2%
. To disable caching across all forks, the -c
option can be passed to the CLI. In this case, even though caching was disabled, the new output will still be written to cache so that when Documentary is run next time, the latest known output is placed instantly.
Documentary is able to fork modules that use import
and export
without the developer having to write a proxy file that would otherwise require @babel/register
or other runtime transpilers. It was made possible with a simple ÀLaMode regex-based transpiler that will update the import/export
statements on-the-fly. If there are any problems while using this feature, it can be disabled with the plain _
symbol: %_FORK module arg1 arg2%
.
With the / prefix in the FORK command, all absolute paths that contain the current working directory, will be replaced with relative paths.
%/FORKERR-table example/print-table%
This can help with documenting errors or other code that prints absolute paths in a nimble way.
example/fork/absolute.js:2
throw err
^
Error: test
at Object.<anonymous> (example/fork/absolute.js:1:75)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3
The <fork>
component is the same as the %FORK%
marker, but it offers extended functionality. The optional properties described above on this page are specified in the arguments, and the location of the fork module is passed as a child.
<fork nocache plain relative stderr lang="js"
env="ENV_VAR=testing SECRET_KEY=hello-world">
module/location/run.js
</fork>
All environment variables will be inherited from the Documentary process. Additional variables can be passed in the env
argument, which is only available for the <fork>
component and not the %FORK%
marker. The variables will be split by whitespace, and the key-value pairs will be split by =
. It's not possible to specify values with =
in them at the moment.
Same forks but with different env variables are cached separately.
Whenever there are two forks of the same module with the same arguments and env variables, but one prints stdout
and another one stderr
, only one fork will be spawn, and its result reused. That saves time when trying to document the total output of the program, possibly in different sections, for example in a 2-column table:
<table>
<tr><th>STDOUT</th><th>STDERR</th></tr>
<!-- block-start -->
<tr><td>
<fork>example</fork>
</td>
<td>
<fork>example</fork>
</td></tr>
</table>
If the fork interacts with the CLI via the stdin
interface, it is possible to write answers which will be entered when the fork's output (either stdout
or stderr
) is matched against the regular expression given in the answer.
For example, the following README can be written:
<h2>Running the program</h2>
When you run the program, it will ask for your confirmation.
<fork lang="js">
<answer regex="Are you sure">yes</answer>
<answer regex="Please confirm">no</answer>
<answer stderr regex="STDERR">documentary 123</answer>
test/fixture/fork-comp.js
</fork>
And this is the source code of the fork:
import askQuestions from 'reloquent'
import { createInterface } from 'readline'
(async () => {
const res = await askQuestions({
'a': 'Are you sure?',
'b': 'Please confirm',
})
console.log(res)
const i = createInterface({
input: process.stdin,
output: process.stderr,
})
i.question('STDERR question: ', (answer) => {
console.log(answer)
i.close()
process.exit()
})
})()
The output:
Are you sure? yes
Please confirm: no
{ a: 'yes', b: 'no' }
documentary 123
Above, both answers to stdout are printed, and the answer to stderr, however because it is the fork of STDOUT only, stderr questions and user-supplied answer to it is not shown.
At the moment, the answers are not cached, so if they change, documentation must be compiled again with
-c
(ornocache
argument). Also, if there are two same forks which use different answers that wouldn't work.