diff --git a/utils/doclint/cli.js b/utils/doclint/cli.js index e8be4c9e37..a99efd84e4 100755 --- a/utils/doclint/cli.js +++ b/utils/doclint/cli.js @@ -37,18 +37,6 @@ run().catch(e => { });; async function run() { - const apiDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api')); - apiDocumentation.filterForLanguage('js'); - const testDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-api'), path.join(PROJECT_DIR, 'docs', 'src', 'api', 'params.md')); - testDocumentation.filterForLanguage('js'); - const testRerpoterDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-reporter-api')); - testRerpoterDocumentation.filterForLanguage('js'); - const documentation = apiDocumentation.mergeWith(testDocumentation).mergeWith(testRerpoterDocumentation); - documentation.mergeWith(testDocumentation); - - // This validates member links. - documentation.setLinkRenderer(() => undefined); - // Patch README.md const versions = await getBrowserVersions(); { @@ -108,16 +96,41 @@ async function run() { // Validate links { - for (const file of fs.readdirSync(path.join(PROJECT_DIR, 'docs', 'src'))) { - if (!file.endsWith('.md')) - continue; - const data = fs.readFileSync(path.join(PROJECT_DIR, 'docs', 'src', file)).toString(); - documentation.renderLinksInText(md.parse(data)); + const langs = ['js', 'java', 'python', 'csharp']; + for (const lang of langs) { + try { + let documentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api')); + documentation.filterForLanguage(lang); + if (lang === 'js') { + const testDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-api'), path.join(PROJECT_DIR, 'docs', 'src', 'api', 'params.md')); + testDocumentation.filterForLanguage('js'); + const testRerpoterDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'test-reporter-api')); + testRerpoterDocumentation.filterForLanguage('js'); + documentation = documentation.mergeWith(testDocumentation).mergeWith(testRerpoterDocumentation); + } + + // This validates member links. + documentation.setLinkRenderer(() => undefined); + + for (const file of fs.readdirSync(path.join(PROJECT_DIR, 'docs', 'src'))) { + if (!file.endsWith('.md')) + continue; + if (langs.some(other => other !== lang && file.endsWith(`-${other}.md`))) + continue; + const data = fs.readFileSync(path.join(PROJECT_DIR, 'docs', 'src', file)).toString(); + documentation.renderLinksInText(md.filterNodesForLanguage(md.parse(data), lang)); + } + } catch (e) { + e.message = `While processing "${lang}"\n` + e.message; + throw e; + } } } // Check for missing docs { + const apiDocumentation = parseApi(path.join(PROJECT_DIR, 'docs', 'src', 'api')); + apiDocumentation.filterForLanguage('js'); const srcClient = path.join(PROJECT_DIR, 'src', 'client'); const sources = fs.readdirSync(srcClient).map(n => path.join(srcClient, n)); const errors = missingDocs(apiDocumentation, sources, path.join(srcClient, 'api.ts')); diff --git a/utils/markdown.js b/utils/markdown.js index 699c8b7e07..936e586921 100644 --- a/utils/markdown.js +++ b/utils/markdown.js @@ -386,4 +386,31 @@ function generateToc(nodes, h3) { return result.join('\n'); } -module.exports = { parse, render, clone, visitAll, visit, generateToc }; +/** + * @param {MarkdownNode[]} nodes + * @param {string} language + * @return {MarkdownNode[]} + */ +function filterNodesForLanguage(nodes, language) { + const result = nodes.filter(node => { + if (!node.children) + return true; + for (let i = 0; i < node.children.length; i++) { + const child = node.children[i]; + if (child.type !== 'li' || child.liType !== 'bullet' || !child.text.startsWith('langs:')) + continue; + const only = child.text.substring('langs:'.length).split(',').map(l => l.trim()); + node.children.splice(i, 1); + return only.includes(language); + } + return true; + }); + result.forEach(n => { + if (!n.children) + return; + n.children = filterNodesForLanguage(n.children, language); + }); + return result; +} + +module.exports = { parse, render, clone, visitAll, visit, generateToc, filterNodesForLanguage };