diff --git a/docs/comparison.md b/docs/comparison.md index e2cb35c..5ca345c 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -58,8 +58,8 @@ The comparison does not represent equivalent feature sets. It shows the cost of The generated [compatibility report](https://github.com/TanStack/markdown/blob/main/reports/conformance.md) tracks matches against all 652 CommonMark 0.31.2 examples after serializer normalization. Every established match is protected individually by the regression suite. The count is accounting, not a conformance claim or a target to maximize. Selected official GFM examples separately cover tables, task lists, and strikethrough. -Use [commonmark.js](https://github.com/commonmark/commonmark.js), micromark, or a unified pipeline when exact specification behavior is a requirement. Use TanStack Markdown when your corpus fits the [documented profile](core-concepts/syntax-profile) and the smaller, controlled renderer is the better product tradeoff. +Use [commonmark.js](https://github.com/commonmark/commonmark.js), micromark, or a unified pipeline when exact specification behavior is a requirement. Use TanStack Markdown when your corpus fits the [documented profile](./core-concepts/syntax-profile.md) and the smaller, controlled renderer is the better product tradeoff. ## Performance -Across the maintained fixtures, TanStack Markdown is competitive with the JavaScript renderers in the suite, but it is not the fastest result in every fixture. Pre-parsed AST rendering is its cheapest path. The defensible advantage is the combined size, output contract, and focused feature set. See [Performance](guides/performance) for methodology and current results. +Across the maintained fixtures, TanStack Markdown is competitive with the JavaScript renderers in the suite, but it is not the fastest result in every fixture. Pre-parsed AST rendering is its cheapest path. The defensible advantage is the combined size, output contract, and focused feature set. See [Performance](./guides/performance.md) for methodology and current results. diff --git a/docs/core-concepts/document-model.md b/docs/core-concepts/document-model.md index ecbc617..1878cce 100644 --- a/docs/core-concepts/document-model.md +++ b/docs/core-concepts/document-model.md @@ -62,7 +62,7 @@ for (const block of document.children) { } ``` -The complete node contracts are in the [Types Reference](../reference/types). +The complete node contracts are in the [Types Reference](../reference/types.md). ## Derived document data diff --git a/docs/core-concepts/parsing.md b/docs/core-concepts/parsing.md index 31fbd2e..d96f14c 100644 --- a/docs/core-concepts/parsing.md +++ b/docs/core-concepts/parsing.md @@ -58,7 +58,7 @@ The `references`, `footnotes`, `footnoteOrder`, and `footnoteCounts` fields in ` ## Extensions -Extensions may claim a block, transform inline nodes, transform the completed document, or render custom HTML. They run in array order. See [Extensions](../guides/extensions) for lifecycle and examples. +Extensions may claim a block, transform inline nodes, transform the completed document, or render custom HTML. They run in array order. See [Extensions](../guides/extensions.md) for lifecycle and examples. ## Complexity bounds diff --git a/docs/core-concepts/security.md b/docs/core-concepts/security.md index 2276d81..1da5001 100644 --- a/docs/core-concepts/security.md +++ b/docs/core-concepts/security.md @@ -61,7 +61,7 @@ renderHtml(source, { highlighter }) Only use a highlighter that escapes source code and returns trusted markup. TanStack Markdown cannot distinguish token markup from an injection in the returned string. -The tested [TanStack Highlight adapter](../guides/syntax-highlighting#tanstack-highlight-adapter) returns escaped inner token markup without duplicating Markdown's `
` containers.
+The tested [TanStack Highlight adapter](../guides/syntax-highlighting.md#tanstack-highlight-adapter) returns escaped inner token markup without duplicating Markdown's `` containers.
## Extensions
diff --git a/docs/core-concepts/syntax-profile.md b/docs/core-concepts/syntax-profile.md
index 2e378e5..9d1b3af 100644
--- a/docs/core-concepts/syntax-profile.md
+++ b/docs/core-concepts/syntax-profile.md
@@ -61,7 +61,7 @@ The docs extension entry points add:
- comment-delimited component blocks
- file, package-manager, bundler, and framework transforms
-See the [Docs Preset](../guides/docs-preset) guide.
+See the [Docs Preset](../guides/docs-preset.md) guide.
## Deliberate limits
diff --git a/docs/guides/docs-preset.md b/docs/guides/docs-preset.md
index 9c4db0e..d3613d3 100644
--- a/docs/guides/docs-preset.md
+++ b/docs/guides/docs-preset.md
@@ -93,4 +93,4 @@ The transforms emit custom element names and JSON `data-*` properties. Your appl
`framework` blocks split top-level framework headings into `md-framework-panel` elements. Nested headings receive a framework label, while top-level selector headings are omitted from collected table-of-contents data.
-Use the individual [extension entry points](../reference/extensions) when the complete preset is more than your site needs.
+Use the individual [extension entry points](../reference/extensions.md) when the complete preset is more than your site needs.
diff --git a/docs/installation.md b/docs/installation.md
index 38a9879..9ba1326 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -71,4 +71,4 @@ TanStack Markdown ships ESM JavaScript and TypeScript declarations. Its synchron
## Optional capabilities
-Syntax highlighting is supplied as a callback, so install only the highlighter your application uses. Docs-specific behavior is available through separately importable [extensions](guides/extensions).
+Syntax highlighting is supplied as a callback, so install only the highlighter your application uses. Docs-specific behavior is available through separately importable [extensions](./guides/extensions.md).
diff --git a/docs/overview.md b/docs/overview.md
index f814fbb..c06f599 100644
--- a/docs/overview.md
+++ b/docs/overview.md
@@ -43,15 +43,15 @@ Raw HTML is escaped unless `allowHtml` is enabled. Executable URL protocols such
### Focused compatibility
-The supported contract is the [TanStack docs syntax profile](core-concepts/syntax-profile), not full CommonMark or GFM. Compatibility is continuously measured so established behavior cannot regress silently.
+The supported contract is the [TanStack docs syntax profile](./core-concepts/syntax-profile.md), not full CommonMark or GFM. Compatibility is continuously measured so established behavior cannot regress silently.
### AI streaming without parser state
-The optional [AI streaming profile](guides/ai-streaming) reparses accumulated response text and suppresses incomplete trailing block placeholders. It adds 0.2 KB gzip to the React path while leaving the core parser and renderers unchanged.
+The optional [AI streaming profile](./guides/ai-streaming.md) reparses accumulated response text and suppresses incomplete trailing block placeholders. It adds 0.2 KB gzip to the React path while leaving the core parser and renderers unchanged.
## Choose your starting point
-- Continue to [Installation](installation) for package and runtime requirements.
-- Use [Quick Start](quick-start) for HTML, React, and Octane examples.
-- Read [Comparison](comparison) to evaluate the tradeoffs.
-- Review the [Syntax Profile](core-concepts/syntax-profile) before migrating an existing content corpus.
+- Continue to [Installation](./installation.md) for package and runtime requirements.
+- Use [Quick Start](./quick-start.md) for HTML, React, and Octane examples.
+- Read [Comparison](./comparison.md) to evaluate the tradeoffs.
+- Review the [Syntax Profile](./core-concepts/syntax-profile.md) before migrating an existing content corpus.
diff --git a/docs/project/faq.md b/docs/project/faq.md
index e254fdc..ce97f26 100644
--- a/docs/project/faq.md
+++ b/docs/project/faq.md
@@ -42,4 +42,4 @@ It is public and typed, but the package is pre-1.0. Pin a version for persisted
## How do I decide before migrating?
-Review the [Syntax Profile](../core-concepts/syntax-profile), run your content through the [downstream corpus test](../guides/testing), and inspect the generated output. Choose a broader parser when unsupported syntax is a content requirement rather than an incidental edge case.
+Review the [Syntax Profile](../core-concepts/syntax-profile.md), run your content through the [downstream corpus test](../guides/testing.md), and inspect the generated output. Choose a broader parser when unsupported syntax is a content requirement rather than an incidental edge case.
diff --git a/docs/quick-start.md b/docs/quick-start.md
index 708f905..cc6d600 100644
--- a/docs/quick-start.md
+++ b/docs/quick-start.md
@@ -123,16 +123,16 @@ const document = parseMarkdown(source, options)
const html = renderHtml(document, options)
```
-The preset adds callouts, heading collection, and TanStack-style comment components without changing the core entry points. See the [Docs Preset](guides/docs-preset) guide.
+The preset adds callouts, heading collection, and TanStack-style comment components without changing the core entry points. See the [Docs Preset](./guides/docs-preset.md) guide.
## Highlight code
TanStack Markdown owns each `` tree and accepts trusted inner token markup through its `highlighter` callback. TanStack Highlight provides `createTanStackMarkdownHighlighter()` for this boundary; do not pass a high-level method that returns another code-block wrapper.
-See [Syntax Highlighting](guides/syntax-highlighting) for the complete React and HTML setup, explicit language registration, light and dark themes, line numbers, and security boundary.
+See [Syntax Highlighting](./guides/syntax-highlighting.md) for the complete React and HTML setup, explicit language registration, light and dark themes, line numbers, and security boundary.
## Next steps
-- Confirm your content fits the [Syntax Profile](core-concepts/syntax-profile).
-- Review the [Security](core-concepts/security) boundary before enabling HTML or highlighting.
-- Use the [API Reference](reference/index) for complete options and signatures.
+- Confirm your content fits the [Syntax Profile](./core-concepts/syntax-profile.md).
+- Review the [Security](./core-concepts/security.md) boundary before enabling HTML or highlighting.
+- Use the [API Reference](./reference/index.md) for complete options and signatures.
diff --git a/docs/reference/default-entry.md b/docs/reference/default-entry.md
index d8860b7..eb0e9b2 100644
--- a/docs/reference/default-entry.md
+++ b/docs/reference/default-entry.md
@@ -30,7 +30,7 @@ function parseMarkdown(
): MarkdownDocument
```
-Parses a complete Markdown document. See the [Parser Reference](parser).
+Parses a complete Markdown document. See the [Parser Reference](./parser.md).
### `parseInline`
@@ -58,8 +58,8 @@ Renders one `BlockNode` to HTML.
Renders one `InlineNode` to HTML.
-Signatures and rendering options are documented in the [HTML Reference](html).
+Signatures and rendering options are documented in the [HTML Reference](./html.md).
## Type exports
-The default entry exports every AST node, parser context, render option, extension contract, and supporting definition from the [Types Reference](types).
+The default entry exports every AST node, parser context, render option, extension contract, and supporting definition from the [Types Reference](./types.md).
diff --git a/docs/reference/index.md b/docs/reference/index.md
index e56eb47..d42922f 100644
--- a/docs/reference/index.md
+++ b/docs/reference/index.md
@@ -23,12 +23,12 @@ TanStack Markdown uses explicit subpath exports so applications can import only
## Reference pages
-- [Default Entry](default-entry)
-- [Parser](parser)
-- [HTML](html)
-- [React](react)
-- [Octane](octane)
-- [Types](types)
-- [Extensions](extensions)
+- [Default Entry](./default-entry.md)
+- [Parser](./parser.md)
+- [HTML](./html.md)
+- [React](./react.md)
+- [Octane](./octane.md)
+- [Types](./types.md)
+- [Extensions](./extensions.md)
Prefer narrow entry points in application code. The default entry is convenient when parser, HTML renderer, and public types are used together.
diff --git a/docs/reference/octane.md b/docs/reference/octane.md
index 837faa6..dc730d5 100644
--- a/docs/reference/octane.md
+++ b/docs/reference/octane.md
@@ -78,4 +78,4 @@ function renderInlineOctane(
Renders one inline node.
-See the [Octane Guide](../guides/octane) for TSRX, component mapping, and SSR usage.
+See the [Octane Guide](../guides/octane.md) for TSRX, component mapping, and SSR usage.
diff --git a/docs/reference/parser.md b/docs/reference/parser.md
index 6747c9b..e03f156 100644
--- a/docs/reference/parser.md
+++ b/docs/reference/parser.md
@@ -26,7 +26,7 @@ Normalizes and parses a complete Markdown source string into a deterministic `Ma
| Option | Default | Behavior |
| --- | --- | --- |
| `allowHtml` | `false` | Recognize raw block and inline HTML nodes |
-| `urlTransform` | built-in policy | Override parsed link and image URLs; see [Custom URL policy](../core-concepts/security#custom-url-policy) |
+| `urlTransform` | built-in policy | Override parsed link and image URLs; see [Custom URL policy](../core-concepts/security.md#custom-url-policy) |
| `frontmatter` | `true` | Extract a leading `---` frontmatter block |
| `headingIds` | `true` | Generate IDs, disable them, or provide an ID function |
| `extensions` | `[]` | Run custom parser and transform hooks in array order |
@@ -41,4 +41,4 @@ The last four state fields are public so extension-driven nested parsing can pre
The result always has `type: 'root'` and a `children` array. It may also include raw `frontmatter` and extension-derived `headings`.
-See [Parsing](../core-concepts/parsing) for behavior and [Types](types) for complete contracts.
+See [Parsing](../core-concepts/parsing.md) for behavior and [Types](./types.md) for complete contracts.
diff --git a/docs/reference/react.md b/docs/reference/react.md
index c6e2c77..4e2e445 100644
--- a/docs/reference/react.md
+++ b/docs/reference/react.md
@@ -88,4 +88,4 @@ function renderInlineReact(
Renders one inline node.
-See the [React Guide](../guides/react) for component mapping and SSR usage.
+See the [React Guide](../guides/react.md) for component mapping and SSR usage.
diff --git a/docs/reference/types.md b/docs/reference/types.md
index fd7a737..b7032d2 100644
--- a/docs/reference/types.md
+++ b/docs/reference/types.md
@@ -126,7 +126,7 @@ Contains raw inline HTML `value`. It is created only when HTML parsing is enable
### `InlineComponentNode`
-Contains `type: 'inlineComponent'`, `name`, source `attributes`, inline `children`, and optional rendered `tagName` and string `properties`. Uses the same component replacements as `ComponentNode`, with a `` fallback when no tag is provided. See [Custom components](../guides/extensions#custom-components).
+Contains `type: 'inlineComponent'`, `name`, source `attributes`, inline `children`, and optional rendered `tagName` and string `properties`. Uses the same component replacements as `ComponentNode`, with a `` fallback when no tag is provided. See [Custom components](../guides/extensions.md#custom-components).
## Parsing and rendering options
@@ -136,7 +136,7 @@ Configures `allowHtml`, `urlTransform`, `frontmatter`, `headingIds`, and `extens
### `UrlTransform`
-Synchronous callback `(url: string, kind: 'link' | 'image', defaultUrl: string) => string | null`. Return the default screened URL, a trusted replacement, or `null` to keep only the label content. Applies during Markdown parsing, not to raw HTML or supplied ASTs. See [Custom URL policy](../core-concepts/security#custom-url-policy).
+Synchronous callback `(url: string, kind: 'link' | 'image', defaultUrl: string) => string | null`. Return the default screened URL, a trusted replacement, or `null` to keep only the label content. Applies during Markdown parsing, not to raw HTML or supplied ASTs. See [Custom URL policy](../core-concepts/security.md#custom-url-policy).
### `RenderOptions`
diff --git a/scripts/verify-docs.mjs b/scripts/verify-docs.mjs
index a6a016d..2b0496b 100644
--- a/scripts/verify-docs.mjs
+++ b/scripts/verify-docs.mjs
@@ -133,6 +133,12 @@ async function validateLinks(file, source) {
continue
}
+ if (pathPart && !/\.(?:md|mdx)$/.test(pathPart)) {
+ failures.push(
+ `Local link must include the .md extension so GitHub can resolve it in ${toPosix(path.relative(root, file))}: ${target}`,
+ )
+ }
+
if (fragment) {
const anchors = await getAnchors(markdownPath)
const anchor = decodeURIComponent(fragment).toLowerCase()