@tanstack/markdown 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -42,6 +42,8 @@ export function Article({ source }: { source: string }) @{
42
42
 
43
43
  TanStack Markdown targets controlled technical content. It supports the Markdown used by blogs and docs, then spends its remaining complexity budget on deterministic output, renderer parity, malformed-input resilience, and small entry points. It is intentionally not a complete CommonMark, GFM, MDX, or general content-processing implementation.
44
44
 
45
+ For syntax highlighting, use the tested [TanStack Highlight adapter](./docs/guides/syntax-highlighting.md#tanstack-highlight-adapter). It registers only the languages you choose and returns escaped token markup inside Markdown-owned code containers.
46
+
45
47
  ## Documentation
46
48
 
47
49
  - [Overview](./docs/overview.md)
package/dist/html.js CHANGED
@@ -83,7 +83,7 @@ function renderInlines(nodes, options) {
83
83
  function renderCodeBlock(node, options) {
84
84
  const lang = node.lang ?? 'plaintext';
85
85
  const preAttrs = [
86
- 'class="tm-code"',
86
+ `class="tm-code${options.codeLineNumbers ? ' tm-code--line-numbers' : ''}"`,
87
87
  `data-lang="${escapeAttr(lang)}"`,
88
88
  node.title ? `data-code-title="${escapeAttr(node.title)}"` : '',
89
89
  node.file ? `data-filename="${escapeAttr(node.file)}"` : '',
package/dist/octane.js CHANGED
@@ -88,7 +88,7 @@ function renderCodeBlockOctane(node, options, key) {
88
88
  }
89
89
  : undefined;
90
90
  const pre = h(options, 'pre', {
91
- className: 'tm-code',
91
+ className: `tm-code${options.codeLineNumbers ? ' tm-code--line-numbers' : ''}`,
92
92
  'data-lang': lang,
93
93
  ...(node.title ? { 'data-code-title': node.title } : {}),
94
94
  ...(node.file ? { 'data-filename': node.file } : {}),
package/dist/react.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import type { ComponentType, ReactElement, ReactNode } from 'react';
1
+ import type { ComponentPropsWithoutRef, ComponentType, JSX, ReactElement, ReactNode } from 'react';
2
2
  import type { BlockNode, InlineNode, MarkdownInput, RenderOptions } from './types.js';
3
+ type IntrinsicElementName = keyof JSX.IntrinsicElements;
3
4
  type ComponentMap = Partial<Record<string, string | ComponentType<any>>>;
5
+ export type MarkdownComponentProps<TagName extends IntrinsicElementName> = ComponentPropsWithoutRef<TagName>;
6
+ export type MarkdownComponents = Partial<{
7
+ [TagName in IntrinsicElementName]: IntrinsicElementName | ComponentType<MarkdownComponentProps<TagName>>;
8
+ }> & Record<string, string | ComponentType<any> | undefined>;
4
9
  export interface MarkdownReactOptions extends RenderOptions {
5
10
  components?: ComponentMap;
6
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAmC,UAAU,EAAE,aAAa,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAErI,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAExE,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,UAAU,CAAC,EAAE,YAAY,CAAA;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,QAAQ,EAAE,aAAa,CAAA;CACxB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,aAAa,GAAG,YAAY,CAE9E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAGvG;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CA+DhH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAwC/G"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAElG,OAAO,KAAK,EAAE,SAAS,EAAmC,UAAU,EAAE,aAAa,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAErI,KAAK,oBAAoB,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAA;AACvD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAExE,MAAM,MAAM,sBAAsB,CAAC,OAAO,SAAS,oBAAoB,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAA;AAE5G,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC;KACtC,OAAO,IAAI,oBAAoB,GAAG,oBAAoB,GAAG,aAAa,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;CACzG,CAAC,GACA,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAA;AAEzD,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,UAAU,CAAC,EAAE,YAAY,CAAA;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,QAAQ,EAAE,aAAa,CAAA;CACxB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,aAAa,GAAG,YAAY,CAE9E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAGvG;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CA+DhH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAwC/G"}
package/dist/react.js CHANGED
@@ -91,7 +91,7 @@ function renderCodeBlockReact(node, options, key) {
91
91
  }
92
92
  : undefined;
93
93
  const pre = h(options, 'pre', {
94
- className: 'tm-code',
94
+ className: `tm-code${options.codeLineNumbers ? ' tm-code--line-numbers' : ''}`,
95
95
  'data-lang': lang,
96
96
  ...(node.title ? { 'data-code-title': node.title } : {}),
97
97
  ...(node.file ? { 'data-filename': node.file } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/markdown",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "description": "A tiny, fast, deterministic Markdown renderer for blogs and documentation.",
6
6
  "license": "MIT",
@@ -12,6 +12,7 @@
12
12
  "bugs": {
13
13
  "url": "https://github.com/TanStack/markdown/issues"
14
14
  },
15
+ "packageManager": "pnpm@11.4.0",
15
16
  "sideEffects": false,
16
17
  "files": [
17
18
  "dist",
@@ -70,6 +71,27 @@
70
71
  "import": "./dist/extensions/tabs.js"
71
72
  }
72
73
  },
74
+ "scripts": {
75
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
76
+ "typecheck": "tsc --noEmit",
77
+ "test": "vitest run",
78
+ "test:corpus": "vitest run tests/corpus.test.tsx",
79
+ "corpus:audit": "tsx scripts/audit-corpus.ts",
80
+ "corpus:audit:tanstack": "tsx scripts/audit-tanstack-corpus.ts",
81
+ "corpus:audit:external": "tsx scripts/audit-external-corpus.ts",
82
+ "docs:verify": "node scripts/verify-docs.mjs",
83
+ "test:skills": "intent validate skills --check && pnpm run skills:check-version",
84
+ "skills:check-version": "node scripts/sync-skill-version.mjs --check",
85
+ "skills:sync-version": "node scripts/sync-skill-version.mjs",
86
+ "skills:stale": "intent stale",
87
+ "conformance": "tsx scripts/conformance.ts",
88
+ "bench": "tsx scripts/bench.ts",
89
+ "size": "tsx scripts/measure-size.ts",
90
+ "research": "pnpm run conformance && pnpm run size && pnpm run bench",
91
+ "verify": "pnpm test && pnpm run typecheck && pnpm run build && pnpm run docs:verify && pnpm run test:skills && pnpm run research && pnpm pack --dry-run",
92
+ "prepublishOnly": "pnpm run verify",
93
+ "version": "pnpm run skills:sync-version"
94
+ },
73
95
  "publishConfig": {
74
96
  "access": "public"
75
97
  },
@@ -86,6 +108,7 @@
86
108
  }
87
109
  },
88
110
  "devDependencies": {
111
+ "@tanstack/highlight": "0.0.6",
89
112
  "@tanstack/intent": "^0.3.6",
90
113
  "@types/node": "^24.0.0",
91
114
  "@types/react": "^19.0.0",
@@ -110,22 +133,5 @@
110
133
  },
111
134
  "keywords": [
112
135
  "tanstack-intent"
113
- ],
114
- "scripts": {
115
- "build": "rm -rf dist && tsc -p tsconfig.build.json",
116
- "typecheck": "tsc --noEmit",
117
- "test": "vitest run",
118
- "test:corpus": "vitest run tests/corpus.test.tsx",
119
- "corpus:audit": "tsx scripts/audit-corpus.ts",
120
- "corpus:audit:tanstack": "tsx scripts/audit-tanstack-corpus.ts",
121
- "corpus:audit:external": "tsx scripts/audit-external-corpus.ts",
122
- "docs:verify": "node scripts/verify-docs.mjs",
123
- "test:skills": "intent validate skills --check",
124
- "skills:stale": "intent stale",
125
- "conformance": "tsx scripts/conformance.ts",
126
- "bench": "tsx scripts/bench.ts",
127
- "size": "tsx scripts/measure-size.ts",
128
- "research": "pnpm run conformance && pnpm run size && pnpm run bench",
129
- "verify": "pnpm test && pnpm run typecheck && pnpm run build && pnpm run docs:verify && pnpm run test:skills && pnpm run research && pnpm pack --dry-run"
130
- }
131
- }
136
+ ]
137
+ }
@@ -7,7 +7,7 @@ description: >
7
7
  metadata:
8
8
  type: core
9
9
  library: '@tanstack/markdown'
10
- library_version: '0.0.10'
10
+ library_version: '0.0.12'
11
11
  requires:
12
12
  - 'render-markdown'
13
13
  sources:
@@ -9,7 +9,7 @@ description: >
9
9
  metadata:
10
10
  type: core
11
11
  library: '@tanstack/markdown'
12
- library_version: '0.0.10'
12
+ library_version: '0.0.12'
13
13
  requires:
14
14
  - 'render-markdown'
15
15
  sources:
@@ -392,11 +392,10 @@ export const html = renderHtml(source)
392
392
  Correct:
393
393
 
394
394
  ````ts
395
- import {
396
- renderNodesToHtml,
397
- renderTokens,
398
- tokenize,
399
- } from '@tanstack/highlight'
395
+ import { createHighlighter } from '@tanstack/highlight/core'
396
+ import { plaintext } from '@tanstack/highlight/languages/plaintext'
397
+ import { ts } from '@tanstack/highlight/languages/ts'
398
+ import { createTanStackMarkdownHighlighter } from '@tanstack/highlight/markdown'
400
399
  import { renderHtml } from '@tanstack/markdown/html'
401
400
 
402
401
  const source = `\`\`\`ts file="app.ts" {2}
@@ -404,18 +403,12 @@ const one = 1
404
403
  const two = 2
405
404
  \`\`\``
406
405
 
406
+ const highlighter = createHighlighter({
407
+ languages: [plaintext, ts],
408
+ })
409
+
407
410
  export const html = renderHtml(source, {
408
- highlighter(code, lang, options) {
409
- const result = tokenize(code, { lang })
410
- return renderNodesToHtml(
411
- renderTokens(result.tokens, {
412
- decorations: options?.highlightLines?.map((line) => ({
413
- lines: line,
414
- className: 'is-highlighted',
415
- })),
416
- }),
417
- )
418
- },
411
+ highlighter: createTanStackMarkdownHighlighter(highlighter),
419
412
  })
420
413
  ````
421
414
 
@@ -9,7 +9,7 @@ metadata:
9
9
  type: framework
10
10
  library: '@tanstack/markdown'
11
11
  framework: 'octane'
12
- library_version: '0.0.10'
12
+ library_version: '0.0.12'
13
13
  requires:
14
14
  - 'render-markdown'
15
15
  sources:
@@ -8,7 +8,7 @@ description: >
8
8
  metadata:
9
9
  type: lifecycle
10
10
  library: '@tanstack/markdown'
11
- library_version: '0.0.10'
11
+ library_version: '0.0.12'
12
12
  requires:
13
13
  - 'render-markdown'
14
14
  sources:
@@ -58,23 +58,15 @@ Fix: Separate trusted and untrusted entry points, keep trusted callbacks disable
58
58
  ### Check: Return trusted code contents only
59
59
 
60
60
  Expected:
61
-
62
61
  ```ts
63
62
  import { renderHtml } from '@tanstack/markdown/html'
64
- import {
65
- renderNodesToHtml,
66
- renderTokens,
67
- tokenize,
68
- } from '@tanstack/highlight'
69
-
70
- const source = '```ts {1}\nconst answer = 42\n```'
71
-
72
- export const html = renderHtml(source, {
73
- highlighter(code, lang, options) {
74
- const result = tokenize(code, { lang: lang ?? 'plaintext' })
75
- const decorations = options?.highlightLines?.map((lines) => ({ lines, className: 'is-highlighted' }))
76
- return renderNodesToHtml(renderTokens(result.tokens, { lineNumbers: options?.lineNumbers, decorations }))
77
- },
63
+ import { createHighlighter } from '@tanstack/highlight/core'
64
+ import { plaintext } from '@tanstack/highlight/languages/plaintext'
65
+ import { ts } from '@tanstack/highlight/languages/ts'
66
+ import { createTanStackMarkdownHighlighter } from '@tanstack/highlight/markdown'
67
+ const highlighter = createHighlighter({ languages: [plaintext, ts] })
68
+ export const html = renderHtml('```ts {1}\nconst answer = 42\n```', {
69
+ highlighter: createTanStackMarkdownHighlighter(highlighter),
78
70
  })
79
71
  ```
80
72
 
@@ -135,7 +127,7 @@ import { parseMarkdown } from '@tanstack/markdown/parser'
135
127
  const cache = new Map<string, MarkdownDocument>()
136
128
 
137
129
  export function renderCachedArticle(key: string, source: string): string {
138
- const cacheKey = `markdown-0.0.10:${key}`
130
+ const cacheKey = `markdown-0.0.12:${key}`
139
131
  let document = cache.get(cacheKey)
140
132
  if (!document) {
141
133
  document = parseMarkdown(source, {
@@ -9,7 +9,7 @@ metadata:
9
9
  type: framework
10
10
  library: '@tanstack/markdown'
11
11
  framework: 'react'
12
- library_version: '0.0.10'
12
+ library_version: '0.0.12'
13
13
  requires:
14
14
  - 'render-markdown'
15
15
  sources:
@@ -48,31 +48,34 @@ export function Article({ source }: { source: string }) {
48
48
  ### Replace emitted links with an application component
49
49
 
50
50
  ```tsx
51
- import type { ComponentProps } from 'react'
52
- import { Markdown } from '@tanstack/markdown/react'
53
-
54
- function ArticleLink(props: ComponentProps<'a'>) {
55
- const external = props.href?.startsWith('http') ?? false
56
-
57
- return (
58
- <a
59
- {...props}
60
- rel={external ? 'noreferrer' : props.rel}
61
- target={external ? '_blank' : props.target}
62
- />
63
- )
64
- }
51
+ import {
52
+ Markdown,
53
+ type MarkdownComponents,
54
+ } from '@tanstack/markdown/react'
55
+
56
+ const components = {
57
+ a(props) {
58
+ const external = props.href?.startsWith('http') ?? false
59
+ return (
60
+ <a
61
+ {...props}
62
+ rel={external ? 'nofollow noopener noreferrer' : props.rel}
63
+ target={external ? '_blank' : props.target}
64
+ />
65
+ )
66
+ },
67
+ } satisfies MarkdownComponents
65
68
 
66
69
  export function Article({ source }: { source: string }) {
67
70
  return (
68
71
  <article>
69
- <Markdown components={{ a: ArticleLink }}>{source}</Markdown>
72
+ <Markdown components={components}>{source}</Markdown>
70
73
  </article>
71
74
  )
72
75
  }
73
76
  ```
74
77
 
75
- `components` is keyed by emitted intrinsic or custom-element tag names.
78
+ Known intrinsic keys infer their matching React props. Arbitrary extension component tag names remain supported.
76
79
 
77
80
  ### Parse once before repeated React rendering
78
81
 
@@ -9,7 +9,7 @@ description: >
9
9
  metadata:
10
10
  type: core
11
11
  library: '@tanstack/markdown'
12
- library_version: '0.0.10'
12
+ library_version: '0.0.12'
13
13
  sources:
14
14
  - 'TanStack/markdown:docs/quick-start.md'
15
15
  - 'TanStack/markdown:docs/core-concepts/document-model.md'
@@ -1,6 +1,6 @@
1
1
  # AST and Options Reference
2
2
 
3
- This reference targets `@tanstack/markdown@0.0.10`. Shared public types are
3
+ This reference targets `@tanstack/markdown@0.0.12`. Shared public types are
4
4
  exported from `@tanstack/markdown`.
5
5
 
6
6
  ## Entry Points