mirror of
https://github.com/visgl/react-map-gl.git
synced 2026-01-18 15:54:22 +00:00
145 lines
5.2 KiB
TypeScript
145 lines
5.2 KiB
TypeScript
/**
|
|
* This script adds custom heading ids to all files in the docs directory.
|
|
* The headings in our API reference may have format such as
|
|
|
|
+ ### `opacity` (Number, optional)
|
|
+ ### `opacity?: number`
|
|
+ ### `getPosition` ([Function](../../developer-guide/using-layers.md#accessors), optional) 
|
|
+ ### `needsRedraw(options?: {clearRedrawFlags?: boolean}): string | false`
|
|
|
|
* The default generated hash id by Docusaurus will be something like:
|
|
|
|
+ #-opacity-number-optional
|
|
+ #-opacity-number-
|
|
+ #-getposition-functiondeveloper-guideusing-layersmdaccessors-optional-transition-enabledhttpsimgshieldsiobadgetransition-enabled-greensvgstyleflat-square
|
|
+ #-needsredraw-options-clearredrawflags-boolean-string-false-
|
|
|
|
* They are long, difficult to read, subject to how the documentation is written, and when the call signature changes.
|
|
* This script appends a custom id tag to the end of such headings, so that their hash ids will look like:
|
|
|
|
+ #opacity
|
|
+ #opacity
|
|
+ #getposition
|
|
+ #needsredraw
|
|
|
|
*/
|
|
const fs = require('fs/promises');
|
|
const path = require('path');
|
|
|
|
const docsDir: string = path.resolve(__dirname, '../docs');
|
|
/** Should match if the line is a header */
|
|
const headerTest = /^(#+)\s+(?<headerContent>.*?)\s*(?<customId>\{#[\w\-]+\})?$/;
|
|
/** Should match if the header describes an API */
|
|
const apiTest = /^`((?<code>\w+)[^`]*)`(\s*\(.*?\)|:.*?|$)/;
|
|
|
|
test();
|
|
main();
|
|
|
|
/** Test that getCustomId handles different formats correctly */
|
|
function test() {
|
|
expect(
|
|
getCustomId(
|
|
`The line width of each object, in units specified by widthUnits (default pixels). `
|
|
)?.[2],
|
|
undefined,
|
|
'not header'
|
|
);
|
|
expect(getCustomId(`## Learning deck.gl`)?.[2], undefined, 'does not contain code');
|
|
expect(getCustomId(`## Changes to \`TileLayer\``)?.[2], undefined, 'is not api');
|
|
expect(getCustomId(`## \`pickObjects\``)?.[2], '{#pickobjects}', 'single word api');
|
|
expect(getCustomId(`## \`@deck.gl/extensions\``)?.[2], undefined, 'Package name');
|
|
expect(
|
|
getCustomId(`## \`strokeOpacity\` (Number)`)?.[2],
|
|
'{#strokeopacity}',
|
|
'with type annotation 1'
|
|
);
|
|
expect(
|
|
getCustomId(`## \`backgroundPadding:number[]\``)?.[2],
|
|
'{#backgroundpadding}',
|
|
'with type annotation 2'
|
|
);
|
|
expect(
|
|
getCustomId(`## \`onBeforeRender(gl: WebGLRenderingContext)\``)?.[2],
|
|
'{#onbeforerender}',
|
|
'with call signature'
|
|
);
|
|
expect(
|
|
getCustomId(
|
|
`##### \`getWidth\` ([Function](../../developer-guide/using-layers.md#accessors)|Number, optional) `
|
|
)?.[2],
|
|
'{#getwidth}',
|
|
'with extra flag'
|
|
);
|
|
console.log('All tests pass!\n');
|
|
}
|
|
|
|
/** Traverse all files in the docs directory, append custom ids if necessary */
|
|
async function main() {
|
|
const files = await listFiles(docsDir, '.md');
|
|
for (const f of files) {
|
|
await processFile(f);
|
|
}
|
|
}
|
|
|
|
/** Parse a single line of text in a .md file.
|
|
* @returns new content in 3 parts if custom id is needed, null otherwise.
|
|
*/
|
|
function getCustomId(line: string): [hash: string, headerContent: string, customId: string] | null {
|
|
const m = line.trim().match(headerTest);
|
|
if (!m) {
|
|
return null;
|
|
}
|
|
const m1 = m.groups!.headerContent.match(apiTest);
|
|
if (!m1) {
|
|
return null;
|
|
}
|
|
const customId = m1.groups!.code.toLowerCase();
|
|
return [m[1], m[2], `{#${customId}}`];
|
|
}
|
|
|
|
/** Process a md file. Rewrites the file content if custom ids are needed. */
|
|
async function processFile(path: string): Promise<void> {
|
|
const context = await fs.readFile(path, {encoding: 'utf-8'});
|
|
let changed = false;
|
|
const lines = context.split('\n').map(line => {
|
|
const customId = getCustomId(line);
|
|
if (customId) {
|
|
changed = true;
|
|
return customId.join(' ');
|
|
}
|
|
return line;
|
|
});
|
|
if (changed) {
|
|
console.log(path);
|
|
await fs.writeFile(path, lines.join('\n'));
|
|
}
|
|
}
|
|
|
|
/** Recursively get all files within the given directory. */
|
|
async function listFiles(path: string, extension: string): Promise<string[]> {
|
|
const result: string[] = [];
|
|
const items = await fs.readdir(path);
|
|
for (const item of items) {
|
|
const itemPath = `${path}/${item}`;
|
|
const info = await fs.lstat(itemPath);
|
|
if (item.endsWith(extension) && info.isFile()) {
|
|
result.push(itemPath);
|
|
} else if (info.isDirectory()) {
|
|
const files = await listFiles(itemPath, extension);
|
|
result.push(...files);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/* Test utils */
|
|
|
|
function expect(value1: any, value2: any, message: string) {
|
|
if (value1 === value2) {
|
|
console.log('Ok', message, value2 || '');
|
|
} else {
|
|
console.log('Not ok', message);
|
|
throw new Error(`Expect ${value2}, got ${value1}`);
|
|
}
|
|
}
|
|
|