From c375cf0f00bf1f9d483dd8fe7a676026b05a0d20 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 7 May 2024 16:01:16 -0700 Subject: [PATCH 1/3] doc: mention quicker way to build docs `make doc-only` skips the process of building Node, which speeds things up considerably for new contributors. --- doc/contributing/api-documentation.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/contributing/api-documentation.md b/doc/contributing/api-documentation.md index af58c6e53a482c..d7c879d9a94421 100644 --- a/doc/contributing/api-documentation.md +++ b/doc/contributing/api-documentation.md @@ -4,9 +4,8 @@ The Node.js API documentation is generated by an in-house tooling that resides within the [tools/doc](https://github.com/nodejs/node/tree/main/tools/doc) directory. -The build process (using `make doc`) uses this tooling to parse the markdown -files in [doc/api](https://github.com/nodejs/node/tree/main/doc/api) and -generate the following: +The build process (using `make doc` or `make doc-only`) uses this tooling to +parse the markdown files in [doc/api][] and generate the following: 1. Human-readable HTML in `out/doc/api/*.html` 2. A JSON representation in `out/doc/api/*.json` @@ -302,3 +301,5 @@ mutate the data and appends it to the final JSON object. For a more in-depth information we recommend to refer to the `json.mjs` file as it contains a lot of comments. + +[doc/api]: https://github.com/nodejs/node/tree/main/doc/api From 490b02ac554a35b9cccb476255df2dfa29c81bf0 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 7 May 2024 16:47:16 -0700 Subject: [PATCH 2/3] tools: support rewriting links in code blocks Within the API documentation for modules, there is a section of pseudo-code which contains links to another file. This pseudo-code is inside of a pre-formatted element (`
`), but that prevents the
build process from rewriting those links from the Markdown source to
their corresponding HTML output.

This addresses that by adding a new language, "pre", whose output
remains unformatted but allows code fences to be annotated with
metadata - code fences must have a language before the metadata. When
the right metadata ("html") is present, it indicates that the code
block should be processed so that anchor tags are rewritten just like
other references.

The actual change to the documentation will happen in a later commit.
---
 tools/doc/html.mjs        | 3 +++
 tools/doc/markdown.mjs    | 9 +++++++++
 tools/lint-md/lint-md.mjs | 1 +
 3 files changed, 13 insertions(+)

diff --git a/tools/doc/html.mjs b/tools/doc/html.mjs
index ff1c6854b58e22..428a7c761208db 100644
--- a/tools/doc/html.mjs
+++ b/tools/doc/html.mjs
@@ -205,6 +205,7 @@ function linkJsTypeDocs(text) {
 }
 
 const isJSFlavorSnippet = (node) => node.lang === 'cjs' || node.lang === 'mjs';
+const isPreSnippet = (node) => node.lang === 'pre';
 
 // Preprocess headers, stability blockquotes, and YAML blocks.
 export function preprocessElements({ filename }) {
@@ -265,6 +266,8 @@ export function preprocessElements({ filename }) {
             // Isolated JS snippet, no need to add the checkbox.
             node.value = `
${highlighted} ${copyButton}
`; } + } else if (isPreSnippet(node)) { + node.value = `
${node.value}
`; } else { node.value = `
${highlighted} ${copyButton}
`; } diff --git a/tools/doc/markdown.mjs b/tools/doc/markdown.mjs index 21104e592b8a24..f148b0ecc6fea6 100644 --- a/tools/doc/markdown.mjs +++ b/tools/doc/markdown.mjs @@ -1,6 +1,7 @@ import { visit } from 'unist-util-visit'; export const referenceToLocalMdFile = /^(?![+a-z]+:)([^#?]+)\.md(#.+)?$/i; +export const referenceToLocalMdFileInPre = //g; export function replaceLinks({ filename, linksMapper }) { return (tree) => { @@ -14,6 +15,14 @@ export function replaceLinks({ filename, linksMapper }) { ); } }); + visit(tree, 'code', (node) => { + if (node.meta === 'html') { + node.value = node.value.replace( + referenceToLocalMdFileInPre, + (_, path, fragment) => ``, + ); + } + }); visit(tree, 'definition', (node) => { const htmlUrl = fileHtmlUrls && fileHtmlUrls[node.identifier]; diff --git a/tools/lint-md/lint-md.mjs b/tools/lint-md/lint-md.mjs index 2130891fe75d43..5758d70c9b5d45 100644 --- a/tools/lint-md/lint-md.mjs +++ b/tools/lint-md/lint-md.mjs @@ -23409,6 +23409,7 @@ const plugins = [ "markdown", "mjs", "powershell", + "pre", "r", "text", "ts", From f125d7c1f5b42f55a6f6078379d4edd91a553674 Mon Sep 17 00:00:00 2001 From: Alex Crawford Date: Tue, 7 May 2024 15:00:57 -0700 Subject: [PATCH 3/3] doc: fix links to ECMAScript module resolution The heading in esm.md was changed from "Resolver Algorithm Specification" to "Resolution Algorithm Specification" back in ccada8bc. This also makes use of the changes in the previous commit to rewrite the links to point to the generated HTML. --- doc/api/modules.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/api/modules.md b/doc/api/modules.md index e04eef782f2143..2f18863fd1971b 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -235,7 +235,7 @@ the `require.resolve()` function. Putting together all of the above, here is the high-level algorithm in pseudocode of what `require()` does: -
+```pre html
 require(X) from module at path Y
 1. If X is a core module,
    a. return the core module
@@ -256,7 +256,7 @@ MAYBE_DETECT_AND_LOAD(X)
 1. If X parses as a CommonJS module, load X as a CommonJS module. STOP.
 2. Else, if `--experimental-require-module` and `--experimental-detect-module` are
   enabled, and the source code of X can be parsed as ECMAScript module using
-  DETECT_MODULE_SYNTAX defined in
+  DETECT_MODULE_SYNTAX defined in
   the ESM resolver,
   a. Load X as an ECMAScript module. STOP.
 3. THROW the SyntaxError from attempting to parse X as CommonJS in 1. STOP.
@@ -318,7 +318,7 @@ LOAD_PACKAGE_IMPORTS(X, DIR)
 2. If no scope was found, return.
 3. If the SCOPE/package.json "imports" is null or undefined, return.
 4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
-  ["node", "require"]) defined in the ESM resolver.
+  ["node", "require"]) defined in the ESM resolver.
 5. RESOLVE_ESM_MATCH(MATCH).
 
 LOAD_PACKAGE_EXPORTS(X, DIR)
@@ -329,7 +329,7 @@ LOAD_PACKAGE_EXPORTS(X, DIR)
 3. Parse DIR/NAME/package.json, and look for "exports" field.
 4. If "exports" is null or undefined, return.
 5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
-   `package.json` "exports", ["node", "require"]) defined in the ESM resolver.
+   `package.json` "exports", ["node", "require"]) defined in the ESM resolver.
 6. RESOLVE_ESM_MATCH(MATCH)
 
 LOAD_PACKAGE_SELF(X, DIR)
@@ -339,7 +339,7 @@ LOAD_PACKAGE_SELF(X, DIR)
 4. If the SCOPE/package.json "name" is not the first segment of X, return.
 5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
    "." + X.slice("name".length), `package.json` "exports", ["node", "require"])
-   defined in the ESM resolver.
+   defined in the ESM resolver.
 6. RESOLVE_ESM_MATCH(MATCH)
 
 RESOLVE_ESM_MATCH(MATCH)
@@ -347,7 +347,7 @@ RESOLVE_ESM_MATCH(MATCH)
 2. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension
    format. STOP
 3. THROW "not found"
-
+``` ## Caching