diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 59906ef77a..bef2dc5a14 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -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; diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx index 101effde43..1956455a82 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx @@ -12,7 +12,7 @@ import { parseCodeBlockTitle, parseLanguage, parseLines, - containsLineNumbers, + getLineNumbersStart, useCodeWordWrap, } from '@docusaurus/theme-common/internal'; import {Highlight, type Language} from 'prism-react-renderer'; @@ -59,8 +59,10 @@ export default function CodeBlockString({ language, magicComments, }); - const showLineNumbers = - showLineNumbersProp ?? containsLineNumbers(metastring); + const lineNumbersStart = getLineNumbersStart({ + showLineNumbers: showLineNumbersProp, + metastring, + }); return ( + lineNumbersStart !== undefined && + styles.codeBlockLinesWithNumbering, + )} + style={ + lineNumbersStart === undefined + ? undefined + : {counterReset: `line-count ${lineNumbersStart - 1}`} + }> {tokens.map((line, i) => ( ))} diff --git a/packages/docusaurus-theme-common/src/internal.ts b/packages/docusaurus-theme-common/src/internal.ts index ea8279af1b..e4a3852774 100644 --- a/packages/docusaurus-theme-common/src/internal.ts +++ b/packages/docusaurus-theme-common/src/internal.ts @@ -37,7 +37,7 @@ export { parseCodeBlockTitle, parseLanguage, parseLines, - containsLineNumbers, + getLineNumbersStart, } from './utils/codeBlockUtils'; export {DEFAULT_SEARCH_TAG} from './utils/searchUtils'; diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index f93ef96be7..305ba3e877 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -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); } /** diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx index cfe3c3bfe6..6b8c896fb9 100644 --- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx +++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx @@ -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). ````md -```jsx {1,4-6,11} showLineNumbers +```jsx showLineNumbers import React from 'react'; -function MyComponent(props) { - if (props.isBar) { - return
Bar
; - } - +export default function MyComponent(props) { return
Foo
; } - -export default MyComponent; ``` ```` @@ -414,18 +408,36 @@ export default MyComponent; ``` -```jsx {1,4-6,11} showLineNumbers +```jsx showLineNumbers import React from 'react'; -function MyComponent(props) { - if (props.isBar) { - return
Bar
; - } - +export default function MyComponent(props) { return
Foo
; } +``` -export default MyComponent; +```mdx-code-block +
+``` + +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
Foo
; +} +``` +```` + +```mdx-code-block + +``` + +```jsx showLineNumbers=3 +export default function MyComponent(props) { + return
Foo
; +} ``` ```mdx-code-block