flecks/packages/dox/build/generate.js

148 lines
5.0 KiB
JavaScript
Raw Normal View History

2022-03-07 02:44:48 -06:00
const makeFilenameRewriter = (filenameRewriters) => (filename, line, column) => (
Object.entries(filenameRewriters)
.reduce(
(filename, [from, to]) => filename.replace(new RegExp(from), to),
`${filename}:${line}:${column}`,
)
);
2024-01-16 00:28:20 -06:00
exports.generateBuildConfigsPage = (buildConfigs) => {
2022-03-09 08:51:10 -06:00
const source = [];
2023-12-31 16:21:43 -06:00
source.push('# Build configuration');
2022-03-09 08:51:10 -06:00
source.push('');
source.push('This page documents all the build configuration files in this project.');
source.push('');
if (buildConfigs.length > 0) {
buildConfigs
.sort(({config: l}, {config: r}) => (l < r ? -1 : 1))
.forEach(({config, comment}) => {
source.push(`## \`${config}\``);
source.push('');
source.push(comment);
source.push('');
});
}
return source.join('\n');
};
2024-01-16 00:28:20 -06:00
exports.generateConfigPage = (configs) => {
2022-03-09 14:43:54 -06:00
const source = [];
2024-01-16 00:28:20 -06:00
source.push("const CodeBlock = require('@theme/CodeBlock');");
2022-03-09 14:43:54 -06:00
source.push('');
2023-12-31 16:21:43 -06:00
source.push('# Fleck configuration');
source.push('');
source.push('<style>td > .theme-code-block \\{ margin: 0; \\}</style>');
source.push('');
source.push('This page documents all configurable flecks in this project.');
2022-03-09 14:43:54 -06:00
source.push('');
Object.entries(configs)
.sort(([l], [r]) => (l < r ? -1 : 1))
.forEach(([fleck, configs]) => {
2023-12-31 16:21:43 -06:00
source.push(`## \`${fleck}\``);
source.push('|Name|Default|Description|');
source.push('|-|-|-|');
2022-03-09 14:43:54 -06:00
configs.forEach(({comment, config, defaultValue}) => {
2023-12-31 16:21:43 -06:00
// Leading and trailing empty cell to make table rendering easier.
const row = ['', config];
let code = defaultValue.replace(/`/g, '\\`');
// Multiline code. Fix indentation.
if (defaultValue.includes('\n')) {
const defaultValueLines = code.split('\n');
const [first, ...rest] = defaultValueLines;
const indent = (rest[0].length - rest[0].trimStart().length) - 2;
code = [first, ...rest.map((line) => line.substring(indent))].join('\\n');
}
row.push(`<CodeBlock language="javascript">{\`${code}\`}</CodeBlock>`);
row.push(comment, '');
source.push(row.join('|'));
2022-03-09 14:43:54 -06:00
});
2023-12-31 16:21:43 -06:00
source.push('');
2022-03-09 14:43:54 -06:00
});
return source.join('\n');
};
2024-01-16 00:28:20 -06:00
exports.generateHookPage = (hooks, flecks) => {
const {filenameRewriters} = flecks.get('@flecks/dox');
2022-03-07 02:44:48 -06:00
const rewriteFilename = makeFilenameRewriter(filenameRewriters);
2022-03-07 00:21:16 -06:00
const source = [];
source.push('# Hooks');
source.push('');
source.push('This page documents all the hooks in this project.');
source.push('');
Object.entries(hooks)
.sort(([lhook], [rhook]) => (lhook < rhook ? -1 : 1))
.forEach(([hook, {implementations = [], invocations = [], specification}]) => {
const {description, example, params} = specification || {
params: [],
};
2023-12-31 16:21:43 -06:00
source.push(`## \`${hook}\``);
source.push('');
2022-03-07 00:21:16 -06:00
if (description) {
2023-12-31 16:21:43 -06:00
source.push(...description.split('\n'));
2022-03-07 00:21:16 -06:00
source.push('');
}
if (params.length > 0) {
params.forEach(({description, name, type}) => {
2023-12-31 16:21:43 -06:00
source.push(`### <code>${name}: ${type}</code>`);
source.push('');
source.push(`<p>${description.trim()}</p>`);
source.push('');
2022-03-07 00:21:16 -06:00
});
source.push('');
}
if (implementations.length > 0) {
source.push('<details>');
source.push('<summary>Implementations</summary>');
source.push('<ul>');
implementations.forEach(({filename, loc: {start: {column, line}}}) => {
2022-03-07 02:44:48 -06:00
source.push(`<li>${rewriteFilename(filename, line, column)}</li>`);
2022-03-07 00:21:16 -06:00
});
source.push('</ul>');
source.push('</details>');
source.push('');
}
if (invocations.length > 0) {
source.push('<details>');
source.push('<summary>Invocations</summary>');
source.push('<ul>');
invocations.forEach(({filename, loc: {start: {column, line}}}) => {
2022-03-07 02:44:48 -06:00
source.push(`<li>${rewriteFilename(filename, line, column)}</li>`);
2022-03-07 00:21:16 -06:00
});
source.push('</ul>');
source.push('</details>');
source.push('');
}
if (example) {
source.push('### Example usage');
source.push('');
source.push('```javascript');
2022-08-11 06:37:54 -05:00
source.push('export const hooks = {');
source.push(` '${hook}': ${example}`);
2022-03-07 00:21:16 -06:00
source.push('};');
source.push('```');
source.push('');
}
});
return source.join('\n');
};
2024-01-16 00:28:20 -06:00
exports.generateTodoPage = (todos, flecks) => {
const {filenameRewriters} = flecks.get('@flecks/dox');
2022-03-07 02:44:48 -06:00
const rewriteFilename = makeFilenameRewriter(filenameRewriters);
2022-03-07 00:21:16 -06:00
const source = [];
2023-12-31 16:21:43 -06:00
source.push('# TODO list');
2022-03-07 00:21:16 -06:00
source.push('');
source.push('This page documents all the TODO items in this project.');
source.push('');
if (todos.length > 0) {
todos.forEach(({filename, loc: {start: {column, line}}, text}) => {
2022-03-07 02:44:48 -06:00
source.push(`- ${rewriteFilename(filename, line, column)}`);
2022-03-07 00:21:16 -06:00
text.split('\n').forEach((line) => {
source.push(` > ${line}`);
});
});
source.push('');
}
return source.join('\n');
};