Skip to content

Commit ee22ed9

Browse files
committed
feat(theme-common, theme-classic): Improve CodeBlock Extensibility
1 parent 502b900 commit ee22ed9

File tree

11 files changed

+606
-216
lines changed

11 files changed

+606
-216
lines changed

packages/docusaurus-theme-classic/src/theme-classic.d.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,12 @@ declare module '@theme/BlogLayout' {
405405

406406
declare module '@theme/CodeBlock' {
407407
import type {ReactNode} from 'react';
408+
import type {CodeBlockMeta} from '@docusaurus/theme-common';
408409

409410
export interface Props {
410411
readonly children: ReactNode;
411412
readonly className?: string;
412-
readonly metastring?: string;
413+
readonly metastring?: string | CodeBlockMeta;
413414
readonly title?: ReactNode;
414415
readonly language?: string;
415416
readonly showLineNumbers?: boolean | number;
@@ -481,13 +482,26 @@ declare module '@theme/CodeBlock/Line' {
481482
readonly line: Token[];
482483
readonly classNames: string[] | undefined;
483484
readonly showLineNumbers: boolean;
485+
readonly meta?: CodeBlockMeta;
484486
readonly getLineProps: (input: LineInputProps) => LineOutputProps;
485487
readonly getTokenProps: (input: TokenInputProps) => TokenOutputProps;
486488
}
487489

488490
export default function CodeBlockLine(props: Props): ReactNode;
489491
}
490492

493+
declare module '@theme/CodeBlock/Token' {
494+
import type {ReactNode} from 'react';
495+
import type {TokenOutputProps} from 'prism-react-renderer';
496+
497+
export interface Props {
498+
readonly output: TokenOutputProps;
499+
readonly meta?: CodeBlockMeta;
500+
}
501+
502+
export default function CodeBlockToken(props: Props): ReactNode;
503+
}
504+
491505
declare module '@theme/CodeBlock/WordWrapButton' {
492506
import type {ReactNode} from 'react';
493507

packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx

+9-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import React, {type ReactNode} from 'react';
99
import clsx from 'clsx';
1010
import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
1111
import {
12-
parseCodeBlockTitle,
1312
parseLanguage,
1413
parseLines,
1514
getLineNumbersStart,
@@ -51,19 +50,19 @@ export default function CodeBlockString({
5150
const wordWrap = useCodeWordWrap();
5251
const isBrowser = useIsBrowser();
5352

54-
// We still parse the metastring in case we want to support more syntax in the
55-
// future. Note that MDX doesn't strip quotes when parsing metastring:
56-
// "title=\"xyz\"" => title: "\"xyz\""
57-
const title = parseCodeBlockTitle(metastring) || titleProp;
58-
59-
const {lineClassNames, code} = parseLines(children, {
53+
const {meta, code} = parseLines(children, {
6054
metastring,
6155
language,
6256
magicComments,
6357
});
58+
59+
// Note that MDX doesn't strip quotes when parsing metastring:
60+
// "title=\"xyz\"" => title: "\"xyz\""
61+
const title = meta.options.title ?? titleProp;
62+
6463
const lineNumbersStart = getLineNumbersStart({
6564
showLineNumbers: showLineNumbersProp,
66-
metastring,
65+
meta,
6766
});
6867

6968
return (
@@ -105,7 +104,8 @@ export default function CodeBlockString({
105104
line={line}
106105
getLineProps={getLineProps}
107106
getTokenProps={getTokenProps}
108-
classNames={lineClassNames[i]}
107+
classNames={meta.lineClassNames[i]}
108+
meta={meta}
109109
showLineNumbers={lineNumbersStart !== undefined}
110110
/>
111111
))}

packages/docusaurus-theme-classic/src/theme/CodeBlock/Line/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import React, {type ReactNode} from 'react';
99
import clsx from 'clsx';
1010
import type {Props} from '@theme/CodeBlock/Line';
1111

12+
import CodeBlockToken from '@theme/CodeBlock/Token';
1213
import styles from './styles.module.css';
1314

1415
type Token = Props['line'][number];
@@ -41,7 +42,7 @@ export default function CodeBlockLine({
4142
});
4243

4344
const lineTokens = line.map((token, key) => (
44-
<span key={key} {...getTokenProps({token})} />
45+
<CodeBlockToken key={key} output={getTokenProps({token})} />
4546
));
4647

4748
return (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import React, {type ReactNode} from 'react';
9+
import type {Props} from '@theme/CodeBlock/Token';
10+
11+
export default function CodeBlockToken({output}: Props): ReactNode {
12+
return <span {...output} />;
13+
}

packages/docusaurus-theme-common/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,8 @@ export {
144144
ErrorBoundaryErrorMessageFallback,
145145
ErrorCauseBoundary,
146146
} from './utils/errorBoundaryUtils';
147+
148+
export {
149+
type CodeBlockMeta,
150+
type CodeMetaOptionValue,
151+
} from './utils/codeBlockUtils';

packages/docusaurus-theme-common/src/internal.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export {ColorModeProvider} from './contexts/colorMode';
3434
export {useAlternatePageUtils} from './utils/useAlternatePageUtils';
3535

3636
export {
37-
parseCodeBlockTitle,
37+
parseCodeBlockMeta,
3838
parseLanguage,
3939
parseLines,
4040
getLineNumbersStart,

0 commit comments

Comments
 (0)