feat(theme): code block showLineNumbers=start metastring (#10846)

This commit is contained in:
Sébastien Lorber 2025-01-16 17:28:04 +01:00 committed by GitHub
parent fcc9e5c56a
commit e59355be76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 74 additions and 25 deletions

View file

@ -412,7 +412,7 @@ declare module '@theme/CodeBlock' {
readonly metastring?: string; readonly metastring?: string;
readonly title?: string; readonly title?: string;
readonly language?: string; readonly language?: string;
readonly showLineNumbers?: boolean; readonly showLineNumbers?: boolean | number;
} }
export default function CodeBlock(props: Props): ReactNode; export default function CodeBlock(props: Props): ReactNode;

View file

@ -12,7 +12,7 @@ import {
parseCodeBlockTitle, parseCodeBlockTitle,
parseLanguage, parseLanguage,
parseLines, parseLines,
containsLineNumbers, getLineNumbersStart,
useCodeWordWrap, useCodeWordWrap,
} from '@docusaurus/theme-common/internal'; } from '@docusaurus/theme-common/internal';
import {Highlight, type Language} from 'prism-react-renderer'; import {Highlight, type Language} from 'prism-react-renderer';
@ -59,8 +59,10 @@ export default function CodeBlockString({
language, language,
magicComments, magicComments,
}); });
const showLineNumbers = const lineNumbersStart = getLineNumbersStart({
showLineNumbersProp ?? containsLineNumbers(metastring); showLineNumbers: showLineNumbersProp,
metastring,
});
return ( return (
<Container <Container
@ -87,8 +89,14 @@ export default function CodeBlockString({
<code <code
className={clsx( className={clsx(
styles.codeBlockLines, styles.codeBlockLines,
showLineNumbers && styles.codeBlockLinesWithNumbering, lineNumbersStart !== undefined &&
)}> styles.codeBlockLinesWithNumbering,
)}
style={
lineNumbersStart === undefined
? undefined
: {counterReset: `line-count ${lineNumbersStart - 1}`}
}>
{tokens.map((line, i) => ( {tokens.map((line, i) => (
<Line <Line
key={i} key={i}
@ -96,7 +104,7 @@ export default function CodeBlockString({
getLineProps={getLineProps} getLineProps={getLineProps}
getTokenProps={getTokenProps} getTokenProps={getTokenProps}
classNames={lineClassNames[i]} classNames={lineClassNames[i]}
showLineNumbers={showLineNumbers} showLineNumbers={lineNumbersStart !== undefined}
/> />
))} ))}
</code> </code>

View file

@ -37,7 +37,7 @@ export {
parseCodeBlockTitle, parseCodeBlockTitle,
parseLanguage, parseLanguage,
parseLines, parseLines,
containsLineNumbers, getLineNumbersStart,
} from './utils/codeBlockUtils'; } from './utils/codeBlockUtils';
export {DEFAULT_SEARCH_TAG} from './utils/searchUtils'; export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';

View file

@ -151,8 +151,37 @@ export function parseCodeBlockTitle(metastring?: string): string {
return metastring?.match(codeBlockTitleRegex)?.groups!.title ?? ''; return metastring?.match(codeBlockTitleRegex)?.groups!.title ?? '';
} }
export function containsLineNumbers(metastring?: string): boolean { function getMetaLineNumbersStart(metastring?: string): number | undefined {
return Boolean(metastring?.includes('showLineNumbers')); const showLineNumbersMeta = metastring
?.split(' ')
.find((str) => str.startsWith('showLineNumbers'));
if (showLineNumbersMeta) {
if (showLineNumbersMeta.startsWith('showLineNumbers=')) {
const value = showLineNumbersMeta.replace('showLineNumbers=', '');
return parseInt(value, 10);
}
return 1;
}
return undefined;
}
export function getLineNumbersStart({
showLineNumbers,
metastring,
}: {
showLineNumbers: boolean | number | undefined;
metastring: string | undefined;
}): number | undefined {
const defaultStart = 1;
if (typeof showLineNumbers === 'boolean') {
return showLineNumbers ? defaultStart : undefined;
}
if (typeof showLineNumbers === 'number') {
return showLineNumbers;
}
return getMetaLineNumbersStart(metastring);
} }
/** /**

View file

@ -395,18 +395,12 @@ The `Line` component will receive the list of class names, based on which you ca
You can enable line numbering for your code block by using `showLineNumbers` key within the language meta string (don't forget to add space directly before the key). You can enable line numbering for your code block by using `showLineNumbers` key within the language meta string (don't forget to add space directly before the key).
````md ````md
```jsx {1,4-6,11} showLineNumbers ```jsx showLineNumbers
import React from 'react'; import React from 'react';
function MyComponent(props) { export default function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>; return <div>Foo</div>;
} }
export default MyComponent;
``` ```
```` ````
@ -414,18 +408,36 @@ export default MyComponent;
<BrowserWindow> <BrowserWindow>
``` ```
```jsx {1,4-6,11} showLineNumbers ```jsx showLineNumbers
import React from 'react'; import React from 'react';
function MyComponent(props) { export default function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>; return <div>Foo</div>;
} }
```
export default MyComponent; ```mdx-code-block
</BrowserWindow>
```
By default, the counter starts at line number 1. It's possible to pass a custom counter start value to split large code blocks for readability:
````md
```jsx showLineNumbers=3
export default function MyComponent(props) {
return <div>Foo</div>;
}
```
````
```mdx-code-block
<BrowserWindow>
```
```jsx showLineNumbers=3
export default function MyComponent(props) {
return <div>Foo</div>;
}
``` ```
```mdx-code-block ```mdx-code-block