diff --git a/docs/api.md b/docs/api.md index d3ab1f23e55..63a6a853561 100644 --- a/docs/api.md +++ b/docs/api.md @@ -9,8 +9,7 @@ ##### Table of Contents - - + - [Overview](#overview) - [Environment Variables](#environment-variables) - [class: Puppeteer](#class-puppeteer) @@ -70,9 +69,9 @@ * [event: 'workercreated'](#event-workercreated) * [event: 'workerdestroyed'](#event-workerdestroyed) * [page.$(selector)](#pageselector) - * [page.$$(selector)](#pageselector) + * [page.$$(selector)](#pageselector-1) * [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args) - * [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args) + * [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args-1) * [page.$x(expression)](#pagexexpression) * [page.addScriptTag(options)](#pageaddscripttagoptions) * [page.addStyleTag(options)](#pageaddstyletagoptions) @@ -163,9 +162,9 @@ * [consoleMessage.type()](#consolemessagetype) - [class: Frame](#class-frame) * [frame.$(selector)](#frameselector) - * [frame.$$(selector)](#frameselector) + * [frame.$$(selector)](#frameselector-1) * [frame.$$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args) - * [frame.$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args) + * [frame.$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args-1) * [frame.$x(expression)](#framexexpression) * [frame.addScriptTag(options)](#frameaddscripttagoptions) * [frame.addStyleTag(options)](#frameaddstyletagoptions) @@ -204,9 +203,9 @@ * [jsHandle.jsonValue()](#jshandlejsonvalue) - [class: ElementHandle](#class-elementhandle) * [elementHandle.$(selector)](#elementhandleselector) - * [elementHandle.$$(selector)](#elementhandleselector) + * [elementHandle.$$(selector)](#elementhandleselector-1) * [elementHandle.$$eval(selector, pageFunction, ...args)](#elementhandleevalselector-pagefunction-args) - * [elementHandle.$eval(selector, pageFunction, ...args)](#elementhandleevalselector-pagefunction-args) + * [elementHandle.$eval(selector, pageFunction, ...args)](#elementhandleevalselector-pagefunction-args-1) * [elementHandle.$x(expression)](#elementhandlexexpression) * [elementHandle.asElement()](#elementhandleaselement) * [elementHandle.boundingBox()](#elementhandleboundingbox) @@ -272,8 +271,7 @@ * [coverage.startJSCoverage(options)](#coveragestartjscoverageoptions) * [coverage.stopCSSCoverage()](#coveragestopcsscoverage) * [coverage.stopJSCoverage()](#coveragestopjscoverage) - - + ### Overview diff --git a/package.json b/package.json index 6c2be60dd2e..5f6e9229b51 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "cross-env": "^5.0.5", "eslint": "^4.19.1", "esprima": "^4.0.0", - "markdown-toc": "^1.2.0", "minimist": "^1.2.0", "ncp": "^2.0.0", "pdfjs-dist": "^1.8.595", diff --git a/utils/doclint/preprocessor/index.js b/utils/doclint/preprocessor/index.js index 251b772b987..94bdddbd426 100644 --- a/utils/doclint/preprocessor/index.js +++ b/utils/doclint/preprocessor/index.js @@ -56,6 +56,8 @@ module.exports = function(sources, version) { newText = isReleaseVersion ? '' : command.originalText; else if (command.name === 'last-released-api') newText = lastReleasedAPILink; + else if (command.name === 'toc') + newText = generateTableOfContents(command.source.text().substring(command.to)); if (newText === null) messages.push(Message.error(`Unknown command 'gen:${command.name}'`)); else if (applyCommand(command, newText)) @@ -77,3 +79,30 @@ function applyCommand(command, editText) { return command.source.setText(newText); } +function generateTableOfContents(mdText) { + const ids = new Set(); + const titles = mdText.split('\n').map(line => line.trim()).filter(line => line.startsWith('#')); + const tocEntries = []; + for (const title of titles) { + const [, nesting, name] = title.match(/^(#+)\s+(.*)$/); + const id = name.trim().toLowerCase().replace(/\s/g, '-').replace(/[^-0-9a-zа-яё]/ig, ''); + let dedupId = id; + let counter = 0; + while (ids.has(dedupId)) + dedupId = id + '-' + (++counter); + ids.add(dedupId); + tocEntries.push({ + level: nesting.length, + name, + id: dedupId + }); + } + + const minLevel = Math.min(...tocEntries.map(entry => entry.level)); + tocEntries.forEach(entry => entry.level -= minLevel); + return '\n' + tocEntries.map(entry => { + const prefix = entry.level % 2 === 0 ? '-' : '*'; + const padding = ' '.repeat(entry.level); + return `${padding}${prefix} [${entry.name}](#${entry.id})`; + }).join('\n') + '\n'; +} diff --git a/utils/doclint/preprocessor/test.js b/utils/doclint/preprocessor/test.js index 3b91c1724e9..32bde186335 100644 --- a/utils/doclint/preprocessor/test.js +++ b/utils/doclint/preprocessor/test.js @@ -126,6 +126,26 @@ describe('preprocessor', function() { `); }); }); + describe('gen:toc', function() { + it('should work', () => { + const source = new Source('doc.md', `XXX + ### class: page + #### page.$ + #### page.$$`); + const messages = preprocessor([source], '1.3.0'); + expect(messages.length).toBe(1); + expect(messages[0].type).toBe('warning'); + expect(messages[0].text).toContain('doc.md'); + expect(source.text()).toBe(` +- [class: page](#class-page) + * [page.$](#page) + * [page.$$](#page-1) + + ### class: page + #### page.$ + #### page.$$`); + }); + }); it('should work with multiple commands', function() { const source = new Source('doc.md', ` XXX