Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docusaurus-theme-classic/src/theme-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ declare module '@theme/CodeBlock' {
readonly metastring?: string;
readonly title?: string;
readonly language?: string;
readonly showLineNumbers?: boolean;
readonly showLineNumbers?: boolean | number;
}

export default function CodeBlock(props: Props): ReactNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
getLineNumbersStart,
useCodeWordWrap,
} from '@docusaurus/theme-common/internal';
import {Highlight, type Language} from 'prism-react-renderer';
Expand Down Expand Up @@ -59,8 +59,10 @@ export default function CodeBlockString({
language,
magicComments,
});
const showLineNumbers =
showLineNumbersProp ?? containsLineNumbers(metastring);
const lineNumbersStart = getLineNumbersStart({
showLineNumbers: showLineNumbersProp,
metastring,
});

return (
<Container
Expand All @@ -87,16 +89,22 @@ export default function CodeBlockString({
<code
className={clsx(
styles.codeBlockLines,
showLineNumbers && styles.codeBlockLinesWithNumbering,
)}>
lineNumbersStart !== undefined &&
styles.codeBlockLinesWithNumbering,
)}
style={
lineNumbersStart === undefined
? undefined
: {counterReset: `line-count ${lineNumbersStart - 1}`}
}>
{tokens.map((line, i) => (
<Line
key={i}
line={line}
getLineProps={getLineProps}
getTokenProps={getTokenProps}
classNames={lineClassNames[i]}
showLineNumbers={showLineNumbers}
showLineNumbers={lineNumbersStart !== undefined}
/>
))}
</code>
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-theme-common/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export {
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
getLineNumbersStart,
} from './utils/codeBlockUtils';

export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';
Expand Down
33 changes: 31 additions & 2 deletions packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,37 @@ export function parseCodeBlockTitle(metastring?: string): string {
return metastring?.match(codeBlockTitleRegex)?.groups!.title ?? '';
}

export function containsLineNumbers(metastring?: string): boolean {
return Boolean(metastring?.includes('showLineNumbers'));
function getMetaLineNumbersStart(metastring?: string): number | undefined {
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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,37 +395,49 @@ 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).

````md
```jsx {1,4-6,11} showLineNumbers
```jsx showLineNumbers
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}

export default function MyComponent(props) {
return <div>Foo</div>;
}

export default MyComponent;
```
````

```mdx-code-block
<BrowserWindow>
```

```jsx {1,4-6,11} showLineNumbers
```jsx showLineNumbers
import React from 'react';

function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
export default function MyComponent(props) {
return <div>Foo</div>;
}
```

```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>;
}
```
````

export default MyComponent;
```mdx-code-block
<BrowserWindow>
```

```jsx showLineNumbers=3
export default function MyComponent(props) {
return <div>Foo</div>;
}
```

```mdx-code-block
Expand Down
Loading