Skip to content

Commit

Permalink
doc,tools: use only one level 1 header per page
Browse files Browse the repository at this point in the history
Increment the header levels from markdown files when producing HTML
documents. This is both better semantically (as the two h1 headers in
current docs are not actually equivalent level semantically--the second
belongs below/inside the first) and better for accessibility. (It is
valid HTML to have multiple h1 headers in a document, but it can be bad
for screen reader experience.)

PR-URL: #37839
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Pooja D P <Pooja.D.P@ibm.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
Trott authored and targos committed May 1, 2021
1 parent b51651c commit eb6ea85
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 23 deletions.
38 changes: 19 additions & 19 deletions test/doctool/test-doctool-html.js
Expand Up @@ -60,25 +60,25 @@ function toHTML({ input, filename, nodeVersion, versions }) {
const testData = [
{
file: fixtures.path('order_of_end_tags_5873.md'),
html: '<h3>Static method: Buffer.from(array) <span> ' +
html: '<h4>Static method: Buffer.from(array) <span> ' +
'<a class="mark" href="#foo_static_method_buffer_from_array" ' +
'id="foo_static_method_buffer_from_array">#</a> </span> </h3>' +
'id="foo_static_method_buffer_from_array">#</a> </span> </h4>' +
'<ul><li><code>array</code><a ' +
'href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/' +
'Reference/Global_Objects/Array" class="type">&#x3C;Array></a></li></ul>'
},
{
file: fixtures.path('doc_with_yaml.md'),
html: '<h1>Sample Markdown with YAML info' +
html: '<h2>Sample Markdown with YAML info' +
'<span><a class="mark" href="#foo_sample_markdown_with_yaml_info" ' +
' id="foo_sample_markdown_with_yaml_info">#</a></span></h1>' +
'<section><h2>Foobar<span><a class="mark" href="#foo_foobar" ' +
'id="foo_foobar">#</a></span></h2>' +
' id="foo_sample_markdown_with_yaml_info">#</a></span></h2>' +
'<section><h3>Foobar<span><a class="mark" href="#foo_foobar" ' +
'id="foo_foobar">#</a></span></h3>' +
'<div class="api_metadata"><span>Added in: v1.0.0</span></div> ' +
'<p>Describe <code>Foobar</code> in more detail here.</p>' +
'</section><section>' +
'<h2>Foobar II<span><a class="mark" href="#foo_foobar_ii" ' +
'id="foo_foobar_ii">#</a></span></h2><div class="api_metadata">' +
'<h3>Foobar II<span><a class="mark" href="#foo_foobar_ii" ' +
'id="foo_foobar_ii">#</a></span></h3><div class="api_metadata">' +
'<details class="changelog"><summary>History</summary>' +
'<table><tbody><tr><th>Version</th><th>Changes</th></tr>' +
'<tr><td>v5.3.0, v4.2.0</td>' +
Expand All @@ -88,15 +88,15 @@ const testData = [
'<p>Describe <code>Foobar II</code> in more detail here.' +
'<a href="http://man7.org/linux/man-pages/man1/fg.1.html"><code>fg(1)' +
'</code></a></p></section><section>' +
'<h2>Deprecated thingy<span><a class="mark" ' +
'<h3>Deprecated thingy<span><a class="mark" ' +
'href="#foo_deprecated_thingy" id="foo_deprecated_thingy">#</a>' +
'</span></h2><div class="api_metadata"><span>Added in: v1.0.0</span>' +
'</span></h3><div class="api_metadata"><span>Added in: v1.0.0</span>' +
'<span>Deprecated since: v2.0.0</span></div><p>Describe ' +
'<code>Deprecated thingy</code> in more detail here.' +
'<a href="http://man7.org/linux/man-pages/man1/fg.1p.html"><code>fg(1p)' +
'</code></a></p></section><section>' +
'<h2>Something<span><a class="mark" href="#foo_something' +
'" id="foo_something">#</a></span></h2> ' +
'<h3>Something<span><a class="mark" href="#foo_something' +
'" id="foo_something">#</a></span></h3> ' +
'<!-- This is not a metadata comment --> ' +
'<p>Describe <code>Something</code> in more detail here. </p></section>'
},
Expand All @@ -111,19 +111,19 @@ const testData = [
},
{
file: fixtures.path('document_with_links.md'),
html: '<h1>Usage and Example<span><a class="mark"' +
html: '<h2>Usage and Example<span><a class="mark"' +
'href="#foo_usage_and_example" id="foo_usage_and_example">#</a>' +
'</span></h1><section><h2>Usage<span><a class="mark" href="#foo_usage"' +
'id="foo_usage">#</a></span></h2><p><code>node \\[options\\] index.js' +
'</span></h2><section><h3>Usage<span><a class="mark" href="#foo_usage"' +
'id="foo_usage">#</a></span></h3><p><code>node \\[options\\] index.js' +
'</code></p><p>Please see the<a href="cli.html#cli-options">' +
'Command Line Options</a>document for more information.</p>' +
'</section><section><h2>' +
'</section><section><h3>' +
'Example<span><a class="mark" href="#foo_example" id="foo_example">' +
'#</a></span></h2><p>An example of a<a href="example.html">' +
'#</a></span></h3><p>An example of a<a href="example.html">' +
'webserver</a>written with Node.js which responds with<code>' +
'\'Hello, World!\'</code>:</p></section><section>' +
'<h2>See also<span><a class="mark"' +
'href="#foo_see_also" id="foo_see_also">#</a></span></h2><p>Check' +
'<h3>See also<span><a class="mark"' +
'href="#foo_see_also" id="foo_see_also">#</a></span></h3><p>Check' +
'out also<a href="https://nodejs.org/">this guide</a></p></section>'
},
{
Expand Down
17 changes: 13 additions & 4 deletions tools/doc/html.js
Expand Up @@ -66,10 +66,19 @@ const gtocHTML = unified()
const templatePath = path.join(docPath, 'template.html');
const template = fs.readFileSync(templatePath, 'utf8');

function wrapSections(content) {
function processContent(content) {
content = content.toString();
// Increment header tag levels to avoid multiple h1 tags in a doc.
// This means we can't already have an <h6>.
if (content.includes('<h6>')) {
throw new Error('Cannot increment a level 6 header');
}
// `++level` to convert the string to a number and increment it.
content = content.replace(/(?<=<\/?h)[1-5](?=[^<>]*>)/g, (level) => ++level);
// Wrap h3 tags in section tags.
let firstTime = true;
return content.toString()
.replace(/<h2/g, (heading) => {
return content
.replace(/<h3/g, (heading) => {
if (firstTime) {
firstTime = false;
return '<section>' + heading;
Expand All @@ -91,7 +100,7 @@ function toHTML({ input, content, filename, nodeVersion, versions }) {
.replace('__GTOC__', gtocHTML.replace(
`class="nav-${id}"`, `class="nav-${id} active"`))
.replace('__EDIT_ON_GITHUB__', editOnGitHub(filename))
.replace('__CONTENT__', wrapSections(content));
.replace('__CONTENT__', processContent(content));

const docCreated = input.match(
/<!--\s*introduced_in\s*=\s*v([0-9]+)\.([0-9]+)\.[0-9]+\s*-->/);
Expand Down

0 comments on commit eb6ea85

Please sign in to comment.