Skip to content

Commit 88dc8c1

Browse files
committed
Handle diff code blocks
1 parent fc43e9a commit 88dc8c1

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

docusaurus.config.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import path from 'path';
21
import remarkNpm2Yarn from '@docusaurus/remark-plugin-npm2yarn';
32
import rehypeCodeblockMeta from './src/plugins/rehype-codeblock-meta.mjs';
43

@@ -15,6 +14,15 @@ export default {
1514
prism: {
1615
theme: require('prism-react-renderer').themes.github,
1716
darkTheme: require('prism-react-renderer').themes.dracula,
17+
magicComments: [
18+
{
19+
className: 'theme-code-block-highlighted-line',
20+
line: 'highlight-next-line',
21+
block: { start: 'highlight-start', end: 'highlight-end' },
22+
},
23+
{ className: 'code-block-diff-add-line', line: 'diff-add' },
24+
{ className: 'code-block-diff-remove-line', line: 'diff-remove' },
25+
],
1826
},
1927
algolia: {
2028
appId: 'QCWXRU195A',
@@ -147,7 +155,9 @@ export default {
147155
lastVersion: '6.x',
148156
breadcrumbs: false,
149157
remarkPlugins: [[remarkNpm2Yarn, { sync: true }]],
150-
rehypePlugins: [[rehypeCodeblockMeta, { match: { snack: true } }]],
158+
rehypePlugins: [
159+
[rehypeCodeblockMeta, { match: { snack: true, lang: true } }],
160+
],
151161
},
152162
blog: {
153163
remarkPlugins: [[remarkNpm2Yarn, { sync: true }]],

src/components/Pre.js

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,52 @@ export default function Pre({
8080
'data-snack': snack,
8181
'data-version': version,
8282
'data-dependencies': deps,
83+
'data-lang': lang,
8384
...rest
8485
}) {
8586
const { colorMode } = useColorMode();
87+
const child = React.Children.only(children);
8688

89+
// Handle diffs with language
90+
if (child.props.className === 'language-diff' && lang) {
91+
const code = child.props.children;
92+
93+
if (typeof code !== 'string') {
94+
throw new Error(
95+
'Diff code must be a string, but received ' + typeof code
96+
);
97+
}
98+
99+
// Replace + and - with magic comments
100+
// Need to add following in docusaurus.config.js
101+
// themeConfig.prims.magicComments: [
102+
// { className: 'code-block-diff-add-line', line: 'diff-add' },
103+
// { className: 'code-block-diff-remove-line', line: 'diff-remove' },
104+
// ],
105+
const content = code
106+
.split('\n')
107+
.map((line) => {
108+
if (line.startsWith('+ ')) {
109+
return `// diff-add\n${line.replace(/^\+ /, '')}`;
110+
} else if (line.startsWith('- ')) {
111+
return `// diff-remove\n${line.replace(/^- /, '')}`;
112+
}
113+
114+
return line;
115+
})
116+
.join('\n');
117+
118+
children = React.cloneElement(child, {
119+
className: `language-${lang}`,
120+
children: content,
121+
});
122+
123+
return <MDXPre {...rest}>{children}</MDXPre>;
124+
}
125+
126+
// Handle snack demos
87127
if (snack) {
88-
const code = React.Children.only(children).props.children;
128+
const code = child.props.children;
89129

90130
if (typeof code !== 'string') {
91131
throw new Error(
@@ -228,8 +268,8 @@ export default function Pre({
228268
}
229269
}
230270

231-
children = React.Children.map(children, (child) =>
232-
React.cloneElement(child, { children: content })
271+
children = React.Children.map(children, (c) =>
272+
React.cloneElement(c, { children: content })
233273
);
234274
}
235275

src/css/custom.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,44 @@ samp {
197197
margin-bottom: 25px;
198198
margin-top: -8px;
199199
}
200+
201+
/**
202+
* use magic comments to mark diff blocks
203+
*/
204+
.code-block-diff-add-line {
205+
background-color: var(--ifm-color-success-contrast-background);
206+
display: block;
207+
margin: 0 -2em;
208+
padding: 0 2em;
209+
}
210+
211+
.code-block-diff-add-line::before {
212+
position: absolute;
213+
left: 8px;
214+
padding-right: 8px;
215+
content: '+';
216+
color: var(--ifm-color-success-dark);
217+
}
218+
219+
.code-block-diff-remove-line {
220+
background-color: var(--ifm-color-danger-contrast-background);
221+
display: block;
222+
margin: 0 -2em;
223+
padding: 0 2em;
224+
}
225+
226+
.code-block-diff-remove-line::before {
227+
position: absolute;
228+
left: 8px;
229+
padding-right: 8px;
230+
content: '-';
231+
color: var(--ifm-color-danger-dark);
232+
}
233+
234+
pre code:has(.code-block-diff-add-line) {
235+
padding-left: 2em !important;
236+
}
237+
238+
pre code:has(.code-block-diff-remove-line) {
239+
padding-left: 2em !important;
240+
}

0 commit comments

Comments
 (0)