documentary
Advanced tools
Comparing version 1.14.0 to 1.15.0
const { createReadStream, lstatSync } = require('fs'); | ||
let spawn = require('spawncommand'); if (spawn && spawn.__esModule) spawn = spawn.default; | ||
let Catchment = require('catchment'); if (Catchment && Catchment.__esModule) Catchment = Catchment.default; | ||
const { collect } = require('catchment'); | ||
let Pedantry = require('pedantry'); if (Pedantry && Pedantry.__esModule) Pedantry = Pedantry.default; | ||
@@ -30,8 +30,3 @@ let tableRule = require('./rules/table'); if (tableRule && tableRule.__esModule) tableRule = tableRule.default; | ||
const rs = createReadStream(source) | ||
const data = await new Promise(async (r, j) => { | ||
const { promise } = new Catchment({ rs }) | ||
rs.on('error', j) | ||
const res = await promise | ||
r(res) | ||
}) | ||
const data = await collect(rs) | ||
return data | ||
@@ -68,3 +63,9 @@ } | ||
const codeSurround = (content, lang = '') => { | ||
const hasBackticks = /```/.test(content) | ||
const t = hasBackticks ? '````' : '```' | ||
return `${t}${lang}\n${content}\n${t}` | ||
} | ||
module.exports.getLink = getLink | ||
@@ -78,2 +79,3 @@ module.exports.makeARegexFromRule = makeARegexFromRule | ||
module.exports.git = git | ||
module.exports.codeSurround = codeSurround | ||
//# sourceMappingURL=index.js.map |
@@ -1,119 +0,5 @@ | ||
const { Replaceable, makeMarkers, makeCutRule, makePasteRule } = require('restream'); | ||
const { | ||
createTocRule, commentRule: stripComments, codeRe, innerCodeRe, linkTitleRe, linkRe, | ||
} = require('./rules'); | ||
let tableRule = require('./rules/table'); if (tableRule && tableRule.__esModule) tableRule = tableRule.default; const { tableRe } = tableRule | ||
let methodTitleRule = require('./rules/method-title'); if (methodTitleRule && methodTitleRule.__esModule) methodTitleRule = methodTitleRule.default; const { methodTitleRe } = methodTitleRule | ||
let treeRule = require('./rules/tree'); if (treeRule && treeRule.__esModule) treeRule = treeRule.default; | ||
let exampleRule = require('./rules/example'); if (exampleRule && exampleRule.__esModule) exampleRule = exampleRule.default; | ||
let forkRule = require('./rules/fork'); if (forkRule && forkRule.__esModule) forkRule = forkRule.default; | ||
const { getLink } = require('.'); | ||
let gifRule = require('./rules/gif'); if (gifRule && gifRule.__esModule) gifRule = gifRule.default; | ||
let typeRule = require('./rules/type'); if (typeRule && typeRule.__esModule) typeRule = typeRule.default; | ||
let badgeRule = require('./rules/badge'); if (badgeRule && badgeRule.__esModule) badgeRule = badgeRule.default; | ||
let typedefMdRule = require('./rules/typedef-md'); if (typedefMdRule && typedefMdRule.__esModule) typedefMdRule = typedefMdRule.default; | ||
let Documentary = require('./Documentary'); if (Documentary && Documentary.__esModule) Documentary = Documentary.default; | ||
class DocumentationStream extends Replaceable { | ||
constructor({ toc }) { | ||
const tocRule = createTocRule(toc) | ||
const { | ||
table, methodTitle, code, innerCode, linkTitle, | ||
} = makeMarkers({ | ||
table: tableRe, | ||
methodTitle: methodTitleRe, | ||
code: codeRe, | ||
innerCode: innerCodeRe, | ||
linkTitle: linkTitleRe, | ||
}) | ||
/* below have ``` in them, therefore we want more control over handling them | ||
* so that Replaceable does not confuse them with the code blocks. | ||
*/ | ||
const [cutCode, cutTable, cutMethodTitle, cutInnerCode] = | ||
[code, table, methodTitle, innerCode, linkTitle].map((marker) => { | ||
const rule = makeCutRule(marker) | ||
return rule | ||
}) | ||
const [insertCode, insertTable, insertMethodTitle, insertInnerCode] = | ||
[code, table, methodTitle, innerCode, linkTitle].map((marker) => { | ||
const rule = makePasteRule(marker) | ||
return rule | ||
}) | ||
super([ | ||
cutInnerCode, | ||
cutTable, | ||
cutMethodTitle, | ||
cutCode, | ||
stripComments, | ||
badgeRule, | ||
treeRule, | ||
exampleRule, | ||
forkRule, | ||
tocRule, | ||
gifRule, | ||
typeRule, | ||
insertTable, | ||
typedefMdRule, // places a table hence just before table | ||
tableRule, | ||
{ // a hackish way to update types property tables to include links to seen types. | ||
re: /\| _(\w+)_ \|/g, | ||
replacement(match, name) { | ||
if (!(name in this.types)) return match | ||
return `| _[${name}](#${getLink(name)})_ |` | ||
}, | ||
}, | ||
{ | ||
re: linkTitleRe, | ||
replacement(match, title) { | ||
const ic = new RegExp(innerCode.regExp.source).exec(title) // test please | ||
let link | ||
if (!ic) { | ||
link = getLink(title) | ||
} else { | ||
const [, i] = ic | ||
const val = innerCode.map[i] | ||
link = getLink(val) | ||
} | ||
return `<a name="${link}">${title}</a>` | ||
}, | ||
}, | ||
{ | ||
re: linkRe, // make links | ||
replacement(match, title) { | ||
// check why is needed to use innerCode re above | ||
const link = getLink(title) | ||
return `<a name="${link}">${title}</a>` | ||
}, | ||
}, | ||
insertMethodTitle, | ||
methodTitleRule, | ||
insertCode, | ||
insertInnerCode, | ||
// those found inside of code blocks | ||
insertTable, | ||
insertMethodTitle, | ||
]) | ||
this._types = {} | ||
this.on('types', types => { | ||
types.forEach(this.addType.bind(this)) | ||
}) | ||
} | ||
addType(name) { | ||
this.types[name] = true | ||
} | ||
get types() { | ||
return this._types | ||
} | ||
} | ||
function createReplaceStream(toc) { | ||
const s = new DocumentationStream({ | ||
const s = new Documentary({ | ||
toc, | ||
@@ -135,3 +21,2 @@ }) | ||
module.exports = createReplaceStream | ||
module.exports.DocumentationStream = DocumentationStream | ||
//# sourceMappingURL=replace-stream.js.map |
const { debuglog } = require('util'); | ||
const { parse } = require('path'); | ||
const { read } = require('..'); | ||
const { read, codeSurround } = require('..'); | ||
@@ -55,7 +55,8 @@ const LOG = debuglog('doc') | ||
return `\`\`\`${getExt(type, source)} | ||
${ff.trim()} | ||
\`\`\`` | ||
} catch (err) { | ||
LOG(err) | ||
const lang = getExt(type, source) | ||
const res = codeSurround(ff.trim(), lang) | ||
return res | ||
} catch ({ stack }) { | ||
LOG('Could not read an example from %s.', source) | ||
LOG(stack) | ||
return match | ||
@@ -62,0 +63,0 @@ } |
const { fork } = require('spawncommand'); | ||
const { codeSurround } = require('..');; | ||
// import { debuglog } from 'util' | ||
@@ -16,11 +17,6 @@ | ||
const res = err ? stderr : stdout | ||
const hasBackticks = /```/.test(res) | ||
return codeSurround(res, lang, hasBackticks) | ||
return codeSurround(res.trim(), lang) | ||
}, | ||
} | ||
const codeSurround = (m, lang = '', hasBackticks = false) => { | ||
const t = hasBackticks ? '````' : '```' | ||
return `${t}${lang}\n${m.trim()}\n${t}` | ||
} | ||
@@ -27,0 +23,0 @@ module.exports=forkRule |
@@ -5,13 +5,20 @@ const { debuglog } = require('util'); | ||
const replacer = (match, table) => { | ||
const t = table.trim() | ||
function replacer(match, macro, table) { | ||
const { tableMacros = {} } = this | ||
const macroFn = tableMacros[macro] | ||
try { | ||
const res = JSON.parse(t) | ||
const res = JSON.parse(table) | ||
const [header, ...rows] = res | ||
const realRows = macroFn ? rows.map(macroFn) : rows | ||
const replacedData = this.replaceInnerCode | ||
? [header, ...realRows].map(c => c.map(cc => this.replaceInnerCode(cc))) | ||
: [header, ...realRows] | ||
const lengths = findLengths(replacedData) | ||
const sep = lengths.map(l => '-'.repeat(l)) | ||
const h = getRow(header, lengths, true) | ||
const a = [ | ||
getRow(header), | ||
getRow(header.map(({ length }) => '-'.repeat(length))), | ||
...rows.map(getRow), | ||
] | ||
return a.join('\n') | ||
sep, | ||
...realRows, | ||
].map(r => getRow(r, lengths)) | ||
return [h, ...a].join('\n') | ||
} catch (err) { | ||
@@ -23,8 +30,47 @@ LOG('Could not parse the table.') | ||
const getRow = (row) => { | ||
const s = `| ${row.join(' | ')} |` | ||
const findLengths = (array) => { | ||
const [header] = array | ||
const lengths = array.reduce((acc, columns) => { | ||
const columnLengths = columns.map(({ length }) => length) | ||
const newAcc = columnLengths.map((l, i) => { | ||
const prevLength = acc[i] | ||
if (l > prevLength) return l | ||
return prevLength | ||
}) | ||
return newAcc | ||
}, [...header].fill(0)) | ||
return lengths | ||
} | ||
const padRight = (val, length) => { | ||
// if there was an INNER CODE it can be negative | ||
// but we're not gonna adjust for a toc-title. | ||
// TODO make %TABLE marker | ||
const extra = Math.max(length - val.length, 0) | ||
const r = ' '.repeat(extra) | ||
const res = `${val}${r}` | ||
return res | ||
} | ||
const padMiddle = (val, length) => { | ||
const extra = length - val.length | ||
const left = Math.floor(extra / 2) | ||
const right = extra - left | ||
const l = ' '.repeat(left) | ||
const r = ' '.repeat(right) | ||
const res = `${l}${val}${r}` | ||
return res | ||
} | ||
const getRow = (row, lengths, center = false) => { | ||
const cols = row.map((col, i) => { | ||
const l = lengths[i] | ||
const r = center ? padMiddle(col, l) : padRight(col, l) | ||
return r | ||
}) | ||
const s = `| ${cols.join(' | ')} |` | ||
return s | ||
} | ||
const re = /```table([\s\S]+?)```/mg | ||
const re = /```table(?: +(.+) *)?\n([\s\S]+?)\n```$/mg | ||
@@ -31,0 +77,0 @@ const tableRule = { |
@@ -0,1 +1,17 @@ | ||
## 13 September 2018 | ||
### 1.15.0 | ||
- [feature] Implement table macros for templating in tables. | ||
- [fix] Make sure toc-titles work with partial inner code in them, e.g., | ||
``` | ||
[hello `world`](t) | ||
``` | ||
- [feature] Make example escape content with 4 backticks, and make sure code from the example does not get replaced further down (e.g., if example inserts a table). | ||
- [feature] Align content inside tables (does not work properly with a toc title.) | ||
- [deps] Update `zoroaster@3.0.4`. | ||
- [refactor] Create separate `Documentary` file to eventually only use it as a stream instead of `createReplaceStream`. | ||
- [tests] Rewrite some tests as masks; remove unhandled rejection. | ||
## 5 September 2018 | ||
@@ -2,0 +18,0 @@ |
{ | ||
"name": "documentary", | ||
"version": "1.14.0", | ||
"version": "1.15.0", | ||
"description": "A library to manage documentation, such as README, usage, man pages and changelog.", | ||
@@ -66,3 +66,3 @@ "main": "build", | ||
"yarn-s": "1.1.0", | ||
"zoroaster": "3.0.0" | ||
"zoroaster": "3.0.4" | ||
}, | ||
@@ -69,0 +69,0 @@ "dependencies": { |
@@ -20,2 +20,3 @@ # documentary | ||
* [Tables Display](#tables-display) | ||
* [Table Macro](#table-macro) | ||
* [Method Title](#method-title) | ||
@@ -134,2 +135,34 @@ * [`async runSoftware(path: string, config: Config): string`](#async-runsoftwarepath-stringconfig-view-containeractions-objectstatic-boolean--truerender-function-string) | ||
| -z | A list of zones to check | | ||
#### Table Macro | ||
Whenever there's a pattern for presenting data in the table, so that the input fields can be mapped to output ones, a table macro can be defined. The example below defines a macro to print a row containing a link, logo and description of a company. It is then used in a table, where only the actual values are entered, relying `documentary` to place them in the template. | ||
````markdown | ||
%TABLE-MACRO Company | ||
<a href="$2">![$1 Logo](images/logos/$3)</a>, $4, $5\, $6 | ||
% | ||
```table Company | ||
[ | ||
["Company", "Tag Line", "Evaluation & Exit"], | ||
[ | ||
"VWO", "https://vwo.com", "vwo.png", "A/B Testing and Conversion Optimization Platform™", "$10m", "2018" | ||
] | ||
] | ||
``` | ||
```` | ||
```markdown | ||
| Company | Tag Line | Evaluation & Exit | | ||
| --------------------------------------------------------------- | ------------------------------------------------- | ----------------- | | ||
| <a href="https://vwo.com">![VWO Logo](images/logos/vwo.png)</a> | A/B Testing and Conversion Optimization Platform™ | $10m, 2018 | | ||
``` | ||
The values in the macro need to be separated with `,` which allows to substitute them into the correct column of the table row. When a `,` needs to be used as part of the column in the macro, it can be escaped with `\` such as `\,` as shown in the last column of the example. | ||
| Company | Tag Line | Evaluation & Exit | | ||
| ------- | -------- | ----------------- | | ||
| <a href="https://vwo.com">![VWO Logo](images/logos/vwo.png)</a> | A/B Testing and Conversion Optimization Platform™ | $10m, 2018 | | ||
### Method Title | ||
@@ -220,8 +253,8 @@ | ||
| Rule | Description | | ||
| ---- | ----------- | | ||
| <a name="npm-package-name">`%NPM: package-name%`</a> | Adds an NPM badge, e.g., `[![npm version] (https://badge.fury.io/js/documentary.svg)] (https://npmjs.org/package/documentary)` | | ||
| <a name="tree-directory-args">`%TREE directory ...args%`</a> | Executes the `tree` command with the given arguments. If `tree` is not installed, warns and does not replace the match. | | ||
| Rule | Description | | ||
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| <a name="npm-package-name">`%NPM: package-name%`</a> | Adds an NPM badge, e.g., `[![npm version] (https://badge.fury.io/js/documentary.svg)] (https://npmjs.org/package/documentary)` | | ||
| <a name="tree-directory-args">`%TREE directory ...args%`</a> | Executes the `tree` command with the given arguments. If `tree` is not installed, warns and does not replace the match. | | ||
| <a name="fork-lang-module-args">`%FORK(-lang)? module ...args%`</a> | Forks the Node.js process to execute the module using `child_process.fork`. The output is printed in the code block, with optionally given language. For example: `%FORK-json example.js -o%` | | ||
| <a name="forkerr-lang-module-args">`%FORKERR(-lang)? module ...args%`</a> | Same as `%FORK%` but will print the output of the `stderr`. | | ||
| <a name="forkerr-lang-module-args">`%FORKERR(-lang)? module ...args%`</a> | Same as `%FORK%` but will print the output of the `stderr`. | | ||
### Examples Placement | ||
@@ -777,9 +810,9 @@ | ||
| Name | Type | Description | Default | | ||
| ---- | ---- | ----------- | ------- | | ||
| __root*__ | _string_ | Root directory string. | - | | ||
| maxage | _number_ | Browser cache max-age in milliseconds. | `0` | | ||
| hidden | _boolean_ | Allow transfer of hidden files. | `false` | | ||
| index | _string_ | Default file name. | `index.html` | | ||
| setHeaders | [_SetHeaders_](#setheaders) | Function to set custom headers on response. | - | | ||
| Name | Type | Description | Default | | ||
| ---------- | --------------------------- | ------------------------------------------- | ------------ | | ||
| __root*__ | _string_ | Root directory string. | - | | ||
| maxage | _number_ | Browser cache max-age in milliseconds. | `0` | | ||
| hidden | _boolean_ | Allow transfer of hidden files. | `false` | | ||
| index | _string_ | Default file name. | `index.html` | | ||
| setHeaders | [_SetHeaders_](#setheaders) | Function to set custom headers on response. | - | | ||
@@ -987,11 +1020,11 @@ #### Importing Types | ||
| Flag | Meaning | Description | | ||
| ---- | ------- | ----------- | | ||
| Flag | Meaning | Description | | ||
| --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ||
| `-o path` | <a name="output-location">Output Location</a> | Where to save the processed `README` file. If not specified, the output is written to the `stdout`. | | ||
| `-t` | <a name="only-toc">Only TOC</a> | Only extract and print the table of contents. | | ||
| `-g [path]` | <a name="generate-types">Generate Types</a> | Insert `@typedef` _JSDoc_ into JavaScript files. When no path is given, the files are updated in place, and when `-` is passed, the output is printed to _stdout_. | | ||
| `-e [path]` | <a name="extract-types">Extract Types</a> | Insert `@typedef` JSDoc into JavaScript files. When no path is given, the files are updated in place, and when `-` is passed, the output is printed to _stdout_. | | ||
| `-w` | <a name="watch-mode">Watch Mode</a> | Watch mode: re-run the program when changes to the source file are detected. | | ||
| `-p "commit message"` | <a name="automatic-push">Automatic Push</a> | Watch + push: automatically push changes to a remote git branch by squashing them into a single commit. | | ||
| `-h1` | <a name="h1-in-toc">h1 In Toc</a> | Include `h1` headers in the table of contents. | | ||
| `-t` | <a name="only-toc">Only TOC</a> | Only extract and print the table of contents. | | ||
| `-g [path]` | <a name="generate-types">Generate Types</a> | Insert `@typedef` _JSDoc_ into JavaScript files. When no path is given, the files are updated in place, and when `-` is passed, the output is printed to _stdout_. | | ||
| `-e [path]` | <a name="extract-types">Extract Types</a> | Insert `@typedef` JSDoc into JavaScript files. When no path is given, the files are updated in place, and when `-` is passed, the output is printed to _stdout_. | | ||
| `-w` | <a name="watch-mode">Watch Mode</a> | Watch mode: re-run the program when changes to the source file are detected. | | ||
| `-p "commit message"` | <a name="automatic-push">Automatic Push</a> | Watch + push: automatically push changes to a remote git branch by squashing them into a single commit. | | ||
| `-h1` | <a name="h1-in-toc">h1 In Toc</a> | Include `h1` headers in the table of contents. | | ||
@@ -1121,2 +1154,3 @@ When <a name="node_debugdoc">`NODE_DEBUG=doc`</a> is set, the program will print debug information, e.g., | ||
- [ ] Trigger compilation whenever an embedded example changes. | ||
- [ ] Purge image cache from CLI (e.g., `curl -X https://github.com/artdecocode/documentary/raw/${BRANCH}${PATH}`) | ||
@@ -1123,0 +1157,0 @@ ## Copyright |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
235105
62
1683
1157