Skip to content

Commit 562bd7f

Browse files
committed
chore: undraft line numbers transformer
1 parent ce259f5 commit 562bd7f

File tree

9 files changed

+151
-140
lines changed

9 files changed

+151
-140
lines changed

docs/astro.config.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,6 @@ import {
22
rehypePrettyCode,
33
type RehypePrettyCodeOptions,
44
} from 'rehype-pretty-code';
5-
import {
6-
transformerNotationDiff,
7-
transformerNotationFocus,
8-
transformerMetaHighlight,
9-
transformerRenderWhitespace,
10-
transformerNotationHighlight,
11-
transformerCompactLineOptions,
12-
transformerNotationErrorLevel,
13-
transformerNotationWordHighlight,
14-
} from '@shikijs/transformers';
155
import {
166
transformerCopyButton,
177
transformerLineNumbers,
@@ -27,7 +17,6 @@ import { rehypeHeadingIds } from '@astrojs/markdown-remark';
2717
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
2818
import starlightHeadingBadges from 'starlight-heading-badges';
2919
import starlightLinksValidator from 'starlight-links-validator';
30-
import { transformerTwoslash, rendererRich } from '@shikijs/twoslash';
3120
import moonlightTheme from './public/theme/moonlight-ii.json' with {
3221
type: 'json',
3322
};
@@ -55,24 +44,11 @@ export default defineConfig({
5544
keepBackground: true,
5645
theme: moonlightTheme as unknown as RawTheme,
5746
transformers: [
58-
// twoslash is WIP
59-
transformerTwoslash({
60-
explicitTrigger: true,
61-
renderer: rendererRich(),
62-
}),
6347
transformerCopyButton({
6448
visibility: 'always',
6549
feedbackDuration: 2_500,
6650
}),
6751
transformerLineNumbers({ autoApply: false }),
68-
transformerNotationDiff(),
69-
transformerNotationFocus(),
70-
transformerMetaHighlight(),
71-
transformerRenderWhitespace(),
72-
transformerNotationHighlight(),
73-
transformerCompactLineOptions(),
74-
transformerNotationErrorLevel(),
75-
transformerNotationWordHighlight(),
7652
],
7753
} satisfies RehypePrettyCodeOptions,
7854
],

docs/src/content/docs/plugins/line-numbers.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
title: Line Numbers
3-
draft: true
43
description: A shiki transformer that adds line numbers to code blocks
54
---
65
import { Aside, Badge } from '@astrojs/starlight/components';
@@ -31,7 +30,7 @@ You can use this as a [`shiki` transformer](https://shiki.style/guide/transforme
3130

3231
### Examples
3332

34-
#### with `rehype-pretty-code`
33+
###### with `rehype-pretty-code`
3534

3635
```ts
3736
import { unified } from 'unified'

examples/next/next.config.mjs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
* @typedef {import('webpack').Configuration} WebpackConfiguration
55
*/
66

7-
import { rehypePrettyCode } from 'rehype-pretty-code';
87
import nextMDX from '@next/mdx';
98
import rehypeSlug from 'rehype-slug';
10-
import { transformerCopyButton } from '@rehype-pretty/transformers';
9+
import { rehypePrettyCode } from 'rehype-pretty-code';
1110
import moonlightTheme from './assets/moonlight-ii.json' with { type: 'json' };
11+
import {
12+
transformerCopyButton,
13+
transformerLineNumbers,
14+
} from '@rehype-pretty/transformers';
1215

1316
/** @type {NextConfigPlugins} */
1417
const plugins = [];
@@ -19,9 +22,6 @@ const nextConfig = {
1922
cleanDistDir: true,
2023
reactStrictMode: true,
2124
poweredByHeader: false,
22-
experimental: {
23-
useLightningcss: false, // lightningcss doesn't work with postcss-loader
24-
},
2525
pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],
2626
env: {
2727
NEXT_TELEMETRY_DISABLED: '1',
@@ -39,6 +39,7 @@ const options = {
3939
visibility: 'always',
4040
feedbackDuration: 2_500,
4141
}),
42+
transformerLineNumbers({ autoApply: false }),
4243
],
4344
};
4445

examples/sveltekit/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
"tailwindcss": "4.0.0-alpha.20"
2121
},
2222
"devDependencies": {
23-
"@sveltejs/adapter-static": "^3.0.4",
24-
"@sveltejs/kit": "^2.5.26",
25-
"@sveltejs/vite-plugin-svelte": "^3.1.2",
26-
"magic-string": "^0.30.11",
27-
"svelte": "5.0.0-next.242",
28-
"svelte-check": "^4.0.1",
29-
"tslib": "^2.7.0",
23+
"@sveltejs/adapter-static": "^3.0.6",
24+
"@sveltejs/kit": "^2.7.4",
25+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
26+
"magic-string": "^0.30.12",
27+
"svelte": "^5.1.9",
28+
"svelte-check": "^4.0.5",
29+
"tslib": "^2.8.1",
3030
"typescript": "^5.6.3",
3131
"vite": "^5.4.10"
3232
}

examples/sveltekit/src/routes/+page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const load = (async (_event) => {
2020
import: 'default',
2121
});
2222

23-
const parsedSnippets = [];
23+
const parsedSnippets: Array<{ filename: string; code: string }> = [];
2424
for await (const [path, snippetPromise] of Object.entries(rawSnippets)) {
2525
const filename = path.split('/').pop();
2626
if (!filename) throw new Error('Invalid filename');

packages/transformers/README.md

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ You can use this as a [`shiki` transformer](https://shiki.style/guide/transforme
2727
- `feedbackDuration`: `number` (default: `3_000`)
2828
- `copyIcon`: `string` (default: an inline SVG of a copy icon)
2929
- `successIcon`: `string` (default: an inline SVG of a green checkmark icon)
30+
- `jsx`: `boolean` (default: `false`) (required as `true` for React-based usage)
3031

3132
### `transformerLineNumbers`
3233

@@ -38,15 +39,15 @@ You can use this as a [`shiki` transformer](https://shiki.style/guide/transforme
3839

3940
#### Examples
4041

41-
##### with `rehype-pretty-code`
42+
##### direct
4243

4344
```ts
4445
import { unified } from 'unified'
4546
import remarkParse from 'remark-parse'
4647
import remarkRehype from 'remark-rehype'
4748
import rehypeStringify from 'rehype-stringify'
48-
import rehypePrettyCode from 'rehype-pretty-code'
49-
import { transformerCopyButton, transformerLineNumbers } from '@rehype-pretty/transformers'
49+
import { rehypePrettyCode } from 'rehype-pretty-code'
50+
import { transformerCopyButton } from '@rehype-pretty/transformers'
5051

5152
const file = await unified()
5253
.use(remarkParse)
@@ -57,7 +58,7 @@ You can use this as a [`shiki` transformer](https://shiki.style/guide/transforme
5758
visibility: 'always',
5859
feedbackDuration: 3_000,
5960
}),
60-
transformerLineNumbers({ autoApply: true }),
61+
transformerLineNumbers({ autoApply: false }),
6162
],
6263
})
6364
.use(rehypeStringify)
@@ -66,21 +67,66 @@ You can use this as a [`shiki` transformer](https://shiki.style/guide/transforme
6667
console.log(String(file))
6768
```
6869

69-
##### with `shiki`
70+
##### In React / Next.js
71+
72+
In Next.js you st it up in `next.config.js` as you'd expect with `jsx: true`
73+
74+
```js
75+
// next.config.js
76+
77+
import nextMDX from '@next/mdx';
78+
import rehypeSlug from 'rehype-slug';
79+
import { rehypePrettyCode } from 'rehype-pretty-code';
80+
import { transformerCopyButton } from '@rehype-pretty/transformers';
81+
82+
const plugins = [];
83+
84+
const nextConfig = {
85+
output: 'export',
86+
pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],
87+
};
88+
89+
const const rehypePrettyCodeOptions = {
90+
theme: 'github-dark',
91+
keepBackground: false,
92+
transformers: [
93+
transformerCopyButton({
94+
jsx: true, // required for React
95+
visibility: 'always',
96+
feedbackDuration: 2_500,
97+
}),
98+
],
99+
};
100+
101+
plugins.push(
102+
nextMDX({
103+
extension: /\.(md|mdx)$/,
104+
options: {
105+
remarkPlugins: [],
106+
rehypePlugins: [[rehypePrettyCode, rehypePrettyCodeOptions], rehypeSlug],
107+
},
108+
}),
109+
);
110+
111+
export default () => plugins.reduce((_, plugin) => plugin(_), nextConfig);
112+
```
70113

71-
```ts
72-
import { codeToHtml } from 'shiki'
73-
import { transformerCopyButton, transformerLineNumbers } from '@rehype-pretty/transformers'
74-
75-
const code = await codeToHtml('console.log("Hello World")', {
76-
lang: 'ts',
77-
theme: 'vitesse-light',
78-
transformers: [
79-
transformerCopyButton({
80-
visibility: 'always',
81-
feedbackDuration: 3_000,
82-
}),
83-
transformerLineNumbers({ autoApply: true }),
84-
]
85-
})
86-
```
114+
Then in your client component, import the `registerCopyButton` function and call it in your the outermost **client** component.
115+
116+
```tsx
117+
'use client';
118+
119+
import { registerCopyButton } from '@rehype-pretty/transformers';
120+
121+
export default function Home() {
122+
React.useEffect(() => {
123+
registerCopyButton();
124+
}, []);
125+
126+
return (
127+
<MDXProvider disableParentContext={false}>
128+
<Index />
129+
</MDXProvider>
130+
);
131+
}
132+
```

packages/transformers/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rehype-pretty/transformers",
3-
"description": "Shiki transformer that adds a copy button to code blocks",
3+
"description": "Shiki transformers to add interactivity to code blocks",
44
"version": "0.13.2",
55
"homepage": "https://rehype-pretty.pages.dev",
66
"type": "module",
@@ -33,8 +33,8 @@
3333
"devDependencies": {
3434
"@arethetypeswrong/cli": "^0.16.4",
3535
"@types/node": "^22.8.6",
36+
"shiki": "^1.22.2",
3637
"tsup": "^8.3.5",
37-
"tsx": "^4.19.2",
3838
"typescript": "^5.6.3"
3939
},
4040
"engines": {

packages/transformers/src/line-numbers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ interface LineNumbersOptions {
44
autoApply?: boolean;
55
}
66

7+
/**
8+
* A transformer that adds line numbers to code blocks.
9+
* @param {Object} options - Options for the line numbers behavior and appearance.
10+
* @param {boolean} options.autoApply - Whether to apply line numbers automatically to every code block.
11+
* @returns A Shiki transformer.
12+
*
13+
* @example
14+
* ```ts
15+
* import { codeToHtml } from 'shiki'
16+
* import { transformerLineNumbers } from '@rehype-pretty/transformers'
17+
*
18+
* const html = await codeToHtml(`console.log('hello, world')`, {
19+
* lang: 'ts',
20+
* theme: 'vitesse-light',
21+
* transformers: [
22+
* transformerLineNumbers({ autoApply: true }),
23+
* ]
24+
* })
25+
* ```
26+
*/
727
export function transformerLineNumbers(
828
options: LineNumbersOptions = { autoApply: true },
929
): ShikiTransformer {
@@ -84,6 +104,9 @@ export function transformerLineNumbers(
84104
};
85105
}
86106

107+
/**
108+
* Returns the CSS styles for line numbers.
109+
*/
87110
function lineNumbersStyle() {
88111
return /* css */ `
89112
pre[data-show-line-numbers='true'], code[data-show-line-numbers='true'] {

0 commit comments

Comments
 (0)