@docusaurus/theme-classic 0.0.0-4183 → 0.0.0-4191
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/theme/CodeBlock/index.js +13 -137
- package/lib-next/theme/CodeBlock/index.js +12 -145
- package/package.json +12 -13
- package/src/theme/CodeBlock/index.tsx +13 -158
|
@@ -13,16 +13,14 @@ var _prismReactRenderer = _interopRequireWildcard(require("prism-react-renderer"
|
|
|
13
13
|
|
|
14
14
|
var _copyTextToClipboard = _interopRequireDefault(require("copy-text-to-clipboard"));
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _Translate = _interopRequireWildcard(require("@docusaurus/Translate"));
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _themeCommon = require("@docusaurus/theme-common");
|
|
19
19
|
|
|
20
|
-
var
|
|
20
|
+
var _usePrismTheme = _interopRequireDefault(require("@theme/hooks/usePrismTheme"));
|
|
21
21
|
|
|
22
22
|
var _stylesModule = _interopRequireDefault(require("./styles.module.css"));
|
|
23
23
|
|
|
24
|
-
var _themeCommon = require("@docusaurus/theme-common");
|
|
25
|
-
|
|
26
24
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
25
|
|
|
28
26
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -35,79 +33,14 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
35
33
|
* This source code is licensed under the MIT license found in the
|
|
36
34
|
* LICENSE file in the root directory of this source tree.
|
|
37
35
|
*/
|
|
38
|
-
const HighlightLinesRangeRegex = /{([\d,-]+)}/;
|
|
39
|
-
const HighlightLanguages = ['js', 'jsBlock', 'jsx', 'python', 'html'];
|
|
40
|
-
// Supported types of highlight comments
|
|
41
|
-
const HighlightComments = {
|
|
42
|
-
js: {
|
|
43
|
-
start: '\\/\\/',
|
|
44
|
-
end: ''
|
|
45
|
-
},
|
|
46
|
-
jsBlock: {
|
|
47
|
-
start: '\\/\\*',
|
|
48
|
-
end: '\\*\\/'
|
|
49
|
-
},
|
|
50
|
-
jsx: {
|
|
51
|
-
start: '\\{\\s*\\/\\*',
|
|
52
|
-
end: '\\*\\/\\s*\\}'
|
|
53
|
-
},
|
|
54
|
-
python: {
|
|
55
|
-
start: '#',
|
|
56
|
-
end: ''
|
|
57
|
-
},
|
|
58
|
-
html: {
|
|
59
|
-
start: '<!--',
|
|
60
|
-
end: '-->'
|
|
61
|
-
}
|
|
62
|
-
}; // Supported highlight directives
|
|
63
|
-
|
|
64
|
-
const HighlightDirectives = ['highlight-next-line', 'highlight-start', 'highlight-end'];
|
|
65
|
-
|
|
66
|
-
const getHighlightDirectiveRegex = (languages = HighlightLanguages) => {
|
|
67
|
-
// to be more reliable, the opening and closing comment must match
|
|
68
|
-
const commentPattern = languages.map(lang => {
|
|
69
|
-
const {
|
|
70
|
-
start,
|
|
71
|
-
end
|
|
72
|
-
} = HighlightComments[lang];
|
|
73
|
-
return `(?:${start}\\s*(${HighlightDirectives.join('|')})\\s*${end})`;
|
|
74
|
-
}).join('|'); // white space is allowed, but otherwise it should be on it's own line
|
|
75
|
-
|
|
76
|
-
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
|
|
77
|
-
}; // select comment styles based on language
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const highlightDirectiveRegex = lang => {
|
|
81
|
-
switch (lang) {
|
|
82
|
-
case 'js':
|
|
83
|
-
case 'javascript':
|
|
84
|
-
case 'ts':
|
|
85
|
-
case 'typescript':
|
|
86
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock']);
|
|
87
|
-
|
|
88
|
-
case 'jsx':
|
|
89
|
-
case 'tsx':
|
|
90
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']);
|
|
91
|
-
|
|
92
|
-
case 'html':
|
|
93
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']);
|
|
94
|
-
|
|
95
|
-
case 'python':
|
|
96
|
-
case 'py':
|
|
97
|
-
return getHighlightDirectiveRegex(['python']);
|
|
98
|
-
|
|
99
|
-
default:
|
|
100
|
-
// all comment types
|
|
101
|
-
return getHighlightDirectiveRegex();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
36
|
function CodeBlock({
|
|
106
37
|
children,
|
|
107
38
|
className: blockClassName,
|
|
108
39
|
metastring,
|
|
109
40
|
title
|
|
110
41
|
}) {
|
|
42
|
+
var _parseLanguage;
|
|
43
|
+
|
|
111
44
|
const {
|
|
112
45
|
prism
|
|
113
46
|
} = (0, _themeCommon.useThemeConfig)();
|
|
@@ -127,71 +60,14 @@ function CodeBlock({
|
|
|
127
60
|
// (note: title="xyz" => title prop still has the quotes)
|
|
128
61
|
|
|
129
62
|
const codeBlockTitle = (0, _themeCommon.parseCodeBlockTitle)(metastring) || title;
|
|
130
|
-
const button = (0, _react.useRef)(null);
|
|
131
|
-
let highlightLines = [];
|
|
132
63
|
const prismTheme = (0, _usePrismTheme.default)(); // In case interleaved Markdown (e.g. when using CodeBlock as standalone component).
|
|
133
64
|
|
|
134
65
|
const content = Array.isArray(children) ? children.join('') : children;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const languageClassName = blockClassName === null || blockClassName === void 0 ? void 0 : blockClassName.split(' ').find(str => str.startsWith('language-'));
|
|
143
|
-
let language = languageClassName === null || languageClassName === void 0 ? void 0 : languageClassName.replace(/language-/, '');
|
|
144
|
-
|
|
145
|
-
if (!language && prism.defaultLanguage) {
|
|
146
|
-
language = prism.defaultLanguage;
|
|
147
|
-
} // only declaration OR directive highlight can be used for a block
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
let code = content.replace(/\n$/, '');
|
|
151
|
-
|
|
152
|
-
if (highlightLines.length === 0 && language !== undefined) {
|
|
153
|
-
let range = '';
|
|
154
|
-
const directiveRegex = highlightDirectiveRegex(language); // go through line by line
|
|
155
|
-
|
|
156
|
-
const lines = content.replace(/\n$/, '').split('\n');
|
|
157
|
-
let blockStart; // loop through lines
|
|
158
|
-
|
|
159
|
-
for (let index = 0; index < lines.length;) {
|
|
160
|
-
const line = lines[index]; // adjust for 0-index
|
|
161
|
-
|
|
162
|
-
const lineNumber = index + 1;
|
|
163
|
-
const match = line.match(directiveRegex);
|
|
164
|
-
|
|
165
|
-
if (match !== null) {
|
|
166
|
-
const directive = match.slice(1).reduce((final, item) => final || item, undefined);
|
|
167
|
-
|
|
168
|
-
switch (directive) {
|
|
169
|
-
case 'highlight-next-line':
|
|
170
|
-
range += `${lineNumber},`;
|
|
171
|
-
break;
|
|
172
|
-
|
|
173
|
-
case 'highlight-start':
|
|
174
|
-
blockStart = lineNumber;
|
|
175
|
-
break;
|
|
176
|
-
|
|
177
|
-
case 'highlight-end':
|
|
178
|
-
range += `${blockStart}-${lineNumber - 1},`;
|
|
179
|
-
break;
|
|
180
|
-
|
|
181
|
-
default:
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
lines.splice(index, 1);
|
|
186
|
-
} else {
|
|
187
|
-
// lines without directives are unchanged
|
|
188
|
-
index += 1;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
highlightLines = (0, _parseNumericRange.default)(range);
|
|
193
|
-
code = lines.join('\n');
|
|
194
|
-
}
|
|
66
|
+
const language = (_parseLanguage = (0, _themeCommon.parseLanguage)(blockClassName)) !== null && _parseLanguage !== void 0 ? _parseLanguage : prism.defaultLanguage;
|
|
67
|
+
const {
|
|
68
|
+
highlightLines,
|
|
69
|
+
code
|
|
70
|
+
} = (0, _themeCommon.parseLines)(content, metastring, language);
|
|
195
71
|
|
|
196
72
|
const handleCopyCode = () => {
|
|
197
73
|
(0, _copyTextToClipboard.default)(code);
|
|
@@ -206,7 +82,7 @@ function CodeBlock({
|
|
|
206
82
|
tokens,
|
|
207
83
|
getLineProps,
|
|
208
84
|
getTokenProps
|
|
209
|
-
}) => <div className={(0, _clsx.default)(_stylesModule.default.codeBlockContainer, blockClassName
|
|
85
|
+
}) => <div className={(0, _clsx.default)(_stylesModule.default.codeBlockContainer, blockClassName)}>
|
|
210
86
|
{codeBlockTitle && <div style={style} className={_stylesModule.default.codeBlockTitle}>
|
|
211
87
|
{codeBlockTitle}
|
|
212
88
|
</div>}
|
|
@@ -225,7 +101,7 @@ function CodeBlock({
|
|
|
225
101
|
key: i
|
|
226
102
|
});
|
|
227
103
|
|
|
228
|
-
if (highlightLines.includes(i
|
|
104
|
+
if (highlightLines.includes(i)) {
|
|
229
105
|
lineProps.className += ' docusaurus-highlight-code-line';
|
|
230
106
|
}
|
|
231
107
|
|
|
@@ -240,7 +116,7 @@ function CodeBlock({
|
|
|
240
116
|
</code>
|
|
241
117
|
</pre>
|
|
242
118
|
|
|
243
|
-
<button
|
|
119
|
+
<button type="button" aria-label={(0, _Translate.translate)({
|
|
244
120
|
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
245
121
|
message: 'Copy code to clipboard',
|
|
246
122
|
description: 'The ARIA label for copy code blocks button'
|
|
@@ -4,84 +4,19 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, {useEffect, useState
|
|
7
|
+
import React, {useEffect, useState} from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import Highlight, {defaultProps} from 'prism-react-renderer';
|
|
10
10
|
import copy from 'copy-text-to-clipboard';
|
|
11
|
-
import rangeParser from 'parse-numeric-range';
|
|
12
|
-
import usePrismTheme from '@theme/hooks/usePrismTheme';
|
|
13
11
|
import Translate, {translate} from '@docusaurus/Translate';
|
|
12
|
+
import {
|
|
13
|
+
useThemeConfig,
|
|
14
|
+
parseCodeBlockTitle,
|
|
15
|
+
parseLanguage,
|
|
16
|
+
parseLines,
|
|
17
|
+
} from '@docusaurus/theme-common';
|
|
18
|
+
import usePrismTheme from '@theme/hooks/usePrismTheme';
|
|
14
19
|
import styles from './styles.module.css';
|
|
15
|
-
import {useThemeConfig, parseCodeBlockTitle} from '@docusaurus/theme-common';
|
|
16
|
-
const HighlightLinesRangeRegex = /{([\d,-]+)}/;
|
|
17
|
-
const HighlightLanguages = ['js', 'jsBlock', 'jsx', 'python', 'html'];
|
|
18
|
-
// Supported types of highlight comments
|
|
19
|
-
const HighlightComments = {
|
|
20
|
-
js: {
|
|
21
|
-
start: '\\/\\/',
|
|
22
|
-
end: '',
|
|
23
|
-
},
|
|
24
|
-
jsBlock: {
|
|
25
|
-
start: '\\/\\*',
|
|
26
|
-
end: '\\*\\/',
|
|
27
|
-
},
|
|
28
|
-
jsx: {
|
|
29
|
-
start: '\\{\\s*\\/\\*',
|
|
30
|
-
end: '\\*\\/\\s*\\}',
|
|
31
|
-
},
|
|
32
|
-
python: {
|
|
33
|
-
start: '#',
|
|
34
|
-
end: '',
|
|
35
|
-
},
|
|
36
|
-
html: {
|
|
37
|
-
start: '<!--',
|
|
38
|
-
end: '-->',
|
|
39
|
-
},
|
|
40
|
-
}; // Supported highlight directives
|
|
41
|
-
|
|
42
|
-
const HighlightDirectives = [
|
|
43
|
-
'highlight-next-line',
|
|
44
|
-
'highlight-start',
|
|
45
|
-
'highlight-end',
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
const getHighlightDirectiveRegex = (languages = HighlightLanguages) => {
|
|
49
|
-
// to be more reliable, the opening and closing comment must match
|
|
50
|
-
const commentPattern = languages
|
|
51
|
-
.map((lang) => {
|
|
52
|
-
const {start, end} = HighlightComments[lang];
|
|
53
|
-
return `(?:${start}\\s*(${HighlightDirectives.join('|')})\\s*${end})`;
|
|
54
|
-
})
|
|
55
|
-
.join('|'); // white space is allowed, but otherwise it should be on it's own line
|
|
56
|
-
|
|
57
|
-
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
|
|
58
|
-
}; // select comment styles based on language
|
|
59
|
-
|
|
60
|
-
const highlightDirectiveRegex = (lang) => {
|
|
61
|
-
switch (lang) {
|
|
62
|
-
case 'js':
|
|
63
|
-
case 'javascript':
|
|
64
|
-
case 'ts':
|
|
65
|
-
case 'typescript':
|
|
66
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock']);
|
|
67
|
-
|
|
68
|
-
case 'jsx':
|
|
69
|
-
case 'tsx':
|
|
70
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']);
|
|
71
|
-
|
|
72
|
-
case 'html':
|
|
73
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']);
|
|
74
|
-
|
|
75
|
-
case 'python':
|
|
76
|
-
case 'py':
|
|
77
|
-
return getHighlightDirectiveRegex(['python']);
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
// all comment types
|
|
81
|
-
return getHighlightDirectiveRegex();
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
20
|
export default function CodeBlock({
|
|
86
21
|
children,
|
|
87
22
|
className: blockClassName,
|
|
@@ -105,74 +40,11 @@ export default function CodeBlock({
|
|
|
105
40
|
// (note: title="xyz" => title prop still has the quotes)
|
|
106
41
|
|
|
107
42
|
const codeBlockTitle = parseCodeBlockTitle(metastring) || title;
|
|
108
|
-
const button = useRef(null);
|
|
109
|
-
let highlightLines = [];
|
|
110
43
|
const prismTheme = usePrismTheme(); // In case interleaved Markdown (e.g. when using CodeBlock as standalone component).
|
|
111
44
|
|
|
112
45
|
const content = Array.isArray(children) ? children.join('') : children;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// Tested above
|
|
116
|
-
const highlightLinesRange = metastring.match(HighlightLinesRangeRegex)[1];
|
|
117
|
-
highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const languageClassName = blockClassName
|
|
121
|
-
?.split(' ')
|
|
122
|
-
.find((str) => str.startsWith('language-'));
|
|
123
|
-
let language = languageClassName?.replace(/language-/, '');
|
|
124
|
-
|
|
125
|
-
if (!language && prism.defaultLanguage) {
|
|
126
|
-
language = prism.defaultLanguage;
|
|
127
|
-
} // only declaration OR directive highlight can be used for a block
|
|
128
|
-
|
|
129
|
-
let code = content.replace(/\n$/, '');
|
|
130
|
-
|
|
131
|
-
if (highlightLines.length === 0 && language !== undefined) {
|
|
132
|
-
let range = '';
|
|
133
|
-
const directiveRegex = highlightDirectiveRegex(language); // go through line by line
|
|
134
|
-
|
|
135
|
-
const lines = content.replace(/\n$/, '').split('\n');
|
|
136
|
-
let blockStart; // loop through lines
|
|
137
|
-
|
|
138
|
-
for (let index = 0; index < lines.length; ) {
|
|
139
|
-
const line = lines[index]; // adjust for 0-index
|
|
140
|
-
|
|
141
|
-
const lineNumber = index + 1;
|
|
142
|
-
const match = line.match(directiveRegex);
|
|
143
|
-
|
|
144
|
-
if (match !== null) {
|
|
145
|
-
const directive = match
|
|
146
|
-
.slice(1)
|
|
147
|
-
.reduce((final, item) => final || item, undefined);
|
|
148
|
-
|
|
149
|
-
switch (directive) {
|
|
150
|
-
case 'highlight-next-line':
|
|
151
|
-
range += `${lineNumber},`;
|
|
152
|
-
break;
|
|
153
|
-
|
|
154
|
-
case 'highlight-start':
|
|
155
|
-
blockStart = lineNumber;
|
|
156
|
-
break;
|
|
157
|
-
|
|
158
|
-
case 'highlight-end':
|
|
159
|
-
range += `${blockStart}-${lineNumber - 1},`;
|
|
160
|
-
break;
|
|
161
|
-
|
|
162
|
-
default:
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
lines.splice(index, 1);
|
|
167
|
-
} else {
|
|
168
|
-
// lines without directives are unchanged
|
|
169
|
-
index += 1;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
highlightLines = rangeParser(range);
|
|
174
|
-
code = lines.join('\n');
|
|
175
|
-
}
|
|
46
|
+
const language = parseLanguage(blockClassName) ?? prism.defaultLanguage;
|
|
47
|
+
const {highlightLines, code} = parseLines(content, metastring, language);
|
|
176
48
|
|
|
177
49
|
const handleCopyCode = () => {
|
|
178
50
|
copy(code);
|
|
@@ -188,11 +60,7 @@ export default function CodeBlock({
|
|
|
188
60
|
code={code}
|
|
189
61
|
language={language}>
|
|
190
62
|
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
|
191
|
-
<div
|
|
192
|
-
className={clsx(
|
|
193
|
-
styles.codeBlockContainer,
|
|
194
|
-
blockClassName?.replace(/language-[^ ]+/, ''),
|
|
195
|
-
)}>
|
|
63
|
+
<div className={clsx(styles.codeBlockContainer, blockClassName)}>
|
|
196
64
|
{codeBlockTitle && (
|
|
197
65
|
<div style={style} className={styles.codeBlockTitle}>
|
|
198
66
|
{codeBlockTitle}
|
|
@@ -215,7 +83,7 @@ export default function CodeBlock({
|
|
|
215
83
|
key: i,
|
|
216
84
|
});
|
|
217
85
|
|
|
218
|
-
if (highlightLines.includes(i
|
|
86
|
+
if (highlightLines.includes(i)) {
|
|
219
87
|
lineProps.className += ' docusaurus-highlight-code-line';
|
|
220
88
|
}
|
|
221
89
|
|
|
@@ -238,7 +106,6 @@ export default function CodeBlock({
|
|
|
238
106
|
</pre>
|
|
239
107
|
|
|
240
108
|
<button
|
|
241
|
-
ref={button}
|
|
242
109
|
type="button"
|
|
243
110
|
aria-label={translate({
|
|
244
111
|
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/theme-classic",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-4191",
|
|
4
4
|
"description": "Classic theme for Docusaurus",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/types.d.ts",
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
"update-code-translations": "node -e 'require(\"./update-code-translations.js\").run()'"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@docusaurus/core": "0.0.0-
|
|
27
|
-
"@docusaurus/plugin-content-blog": "0.0.0-
|
|
28
|
-
"@docusaurus/plugin-content-docs": "0.0.0-
|
|
29
|
-
"@docusaurus/plugin-content-pages": "0.0.0-
|
|
30
|
-
"@docusaurus/theme-common": "0.0.0-
|
|
31
|
-
"@docusaurus/types": "0.0.0-
|
|
32
|
-
"@docusaurus/utils": "0.0.0-
|
|
33
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
34
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
26
|
+
"@docusaurus/core": "0.0.0-4191",
|
|
27
|
+
"@docusaurus/plugin-content-blog": "0.0.0-4191",
|
|
28
|
+
"@docusaurus/plugin-content-docs": "0.0.0-4191",
|
|
29
|
+
"@docusaurus/plugin-content-pages": "0.0.0-4191",
|
|
30
|
+
"@docusaurus/theme-common": "0.0.0-4191",
|
|
31
|
+
"@docusaurus/types": "0.0.0-4191",
|
|
32
|
+
"@docusaurus/utils": "0.0.0-4191",
|
|
33
|
+
"@docusaurus/utils-common": "0.0.0-4191",
|
|
34
|
+
"@docusaurus/utils-validation": "0.0.0-4191",
|
|
35
35
|
"@mdx-js/mdx": "^1.6.21",
|
|
36
36
|
"@mdx-js/react": "^1.6.21",
|
|
37
37
|
"chalk": "^4.1.2",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"globby": "^11.0.2",
|
|
42
42
|
"infima": "0.2.0-alpha.34",
|
|
43
43
|
"lodash": "^4.17.20",
|
|
44
|
-
"parse-numeric-range": "^1.3.0",
|
|
45
44
|
"postcss": "^8.3.7",
|
|
46
45
|
"prism-react-renderer": "^1.2.1",
|
|
47
46
|
"prismjs": "^1.23.0",
|
|
@@ -50,7 +49,7 @@
|
|
|
50
49
|
"rtlcss": "^3.3.0"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
52
|
+
"@docusaurus/module-type-aliases": "0.0.0-4191",
|
|
54
53
|
"@types/mdx-js__react": "^1.5.4",
|
|
55
54
|
"@types/parse-numeric-range": "^0.0.1",
|
|
56
55
|
"@types/rtlcss": "^3.1.1",
|
|
@@ -64,5 +63,5 @@
|
|
|
64
63
|
"engines": {
|
|
65
64
|
"node": ">=14"
|
|
66
65
|
},
|
|
67
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "1167674fef3ac565a20faeb41f11180ed80ffd0d"
|
|
68
67
|
}
|
|
@@ -5,100 +5,22 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, {useEffect, useState
|
|
8
|
+
import React, {useEffect, useState} from 'react';
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import Highlight, {defaultProps, Language} from 'prism-react-renderer';
|
|
11
11
|
import copy from 'copy-text-to-clipboard';
|
|
12
|
-
import
|
|
12
|
+
import Translate, {translate} from '@docusaurus/Translate';
|
|
13
|
+
import {
|
|
14
|
+
useThemeConfig,
|
|
15
|
+
parseCodeBlockTitle,
|
|
16
|
+
parseLanguage,
|
|
17
|
+
parseLines,
|
|
18
|
+
} from '@docusaurus/theme-common';
|
|
13
19
|
import usePrismTheme from '@theme/hooks/usePrismTheme';
|
|
14
20
|
import type {Props} from '@theme/CodeBlock';
|
|
15
|
-
import Translate, {translate} from '@docusaurus/Translate';
|
|
16
21
|
|
|
17
22
|
import styles from './styles.module.css';
|
|
18
23
|
|
|
19
|
-
import {useThemeConfig, parseCodeBlockTitle} from '@docusaurus/theme-common';
|
|
20
|
-
|
|
21
|
-
const HighlightLinesRangeRegex = /{([\d,-]+)}/;
|
|
22
|
-
|
|
23
|
-
const HighlightLanguages = ['js', 'jsBlock', 'jsx', 'python', 'html'] as const;
|
|
24
|
-
type HighlightLanguage = typeof HighlightLanguages[number];
|
|
25
|
-
|
|
26
|
-
type HighlightLanguageConfig = {
|
|
27
|
-
start: string;
|
|
28
|
-
end: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Supported types of highlight comments
|
|
32
|
-
const HighlightComments: Record<HighlightLanguage, HighlightLanguageConfig> = {
|
|
33
|
-
js: {
|
|
34
|
-
start: '\\/\\/',
|
|
35
|
-
end: '',
|
|
36
|
-
},
|
|
37
|
-
jsBlock: {
|
|
38
|
-
start: '\\/\\*',
|
|
39
|
-
end: '\\*\\/',
|
|
40
|
-
},
|
|
41
|
-
jsx: {
|
|
42
|
-
start: '\\{\\s*\\/\\*',
|
|
43
|
-
end: '\\*\\/\\s*\\}',
|
|
44
|
-
},
|
|
45
|
-
python: {
|
|
46
|
-
start: '#',
|
|
47
|
-
end: '',
|
|
48
|
-
},
|
|
49
|
-
html: {
|
|
50
|
-
start: '<!--',
|
|
51
|
-
end: '-->',
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Supported highlight directives
|
|
56
|
-
const HighlightDirectives = [
|
|
57
|
-
'highlight-next-line',
|
|
58
|
-
'highlight-start',
|
|
59
|
-
'highlight-end',
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const getHighlightDirectiveRegex = (
|
|
63
|
-
languages: readonly HighlightLanguage[] = HighlightLanguages,
|
|
64
|
-
) => {
|
|
65
|
-
// to be more reliable, the opening and closing comment must match
|
|
66
|
-
const commentPattern = languages
|
|
67
|
-
.map((lang) => {
|
|
68
|
-
const {start, end} = HighlightComments[lang];
|
|
69
|
-
return `(?:${start}\\s*(${HighlightDirectives.join('|')})\\s*${end})`;
|
|
70
|
-
})
|
|
71
|
-
.join('|');
|
|
72
|
-
// white space is allowed, but otherwise it should be on it's own line
|
|
73
|
-
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// select comment styles based on language
|
|
77
|
-
const highlightDirectiveRegex = (lang: string) => {
|
|
78
|
-
switch (lang) {
|
|
79
|
-
case 'js':
|
|
80
|
-
case 'javascript':
|
|
81
|
-
case 'ts':
|
|
82
|
-
case 'typescript':
|
|
83
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock']);
|
|
84
|
-
|
|
85
|
-
case 'jsx':
|
|
86
|
-
case 'tsx':
|
|
87
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'jsx']);
|
|
88
|
-
|
|
89
|
-
case 'html':
|
|
90
|
-
return getHighlightDirectiveRegex(['js', 'jsBlock', 'html']);
|
|
91
|
-
|
|
92
|
-
case 'python':
|
|
93
|
-
case 'py':
|
|
94
|
-
return getHighlightDirectiveRegex(['python']);
|
|
95
|
-
|
|
96
|
-
default:
|
|
97
|
-
// all comment types
|
|
98
|
-
return getHighlightDirectiveRegex();
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
24
|
export default function CodeBlock({
|
|
103
25
|
children,
|
|
104
26
|
className: blockClassName,
|
|
@@ -124,10 +46,6 @@ export default function CodeBlock({
|
|
|
124
46
|
// so we probably don't need to parse the metastring
|
|
125
47
|
// (note: title="xyz" => title prop still has the quotes)
|
|
126
48
|
const codeBlockTitle = parseCodeBlockTitle(metastring) || title;
|
|
127
|
-
|
|
128
|
-
const button = useRef(null);
|
|
129
|
-
let highlightLines: number[] = [];
|
|
130
|
-
|
|
131
49
|
const prismTheme = usePrismTheme();
|
|
132
50
|
|
|
133
51
|
// In case interleaved Markdown (e.g. when using CodeBlock as standalone component).
|
|
@@ -135,67 +53,9 @@ export default function CodeBlock({
|
|
|
135
53
|
? children.join('')
|
|
136
54
|
: (children as string);
|
|
137
55
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const languageClassName = blockClassName
|
|
145
|
-
?.split(' ')
|
|
146
|
-
.find((str) => str.startsWith('language-'));
|
|
147
|
-
let language = languageClassName?.replace(/language-/, '') as Language;
|
|
148
|
-
|
|
149
|
-
if (!language && prism.defaultLanguage) {
|
|
150
|
-
language = prism.defaultLanguage as Language;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// only declaration OR directive highlight can be used for a block
|
|
154
|
-
let code = content.replace(/\n$/, '');
|
|
155
|
-
if (highlightLines.length === 0 && language !== undefined) {
|
|
156
|
-
let range = '';
|
|
157
|
-
const directiveRegex = highlightDirectiveRegex(language);
|
|
158
|
-
// go through line by line
|
|
159
|
-
const lines = content.replace(/\n$/, '').split('\n');
|
|
160
|
-
let blockStart: number;
|
|
161
|
-
// loop through lines
|
|
162
|
-
for (let index = 0; index < lines.length; ) {
|
|
163
|
-
const line = lines[index];
|
|
164
|
-
// adjust for 0-index
|
|
165
|
-
const lineNumber = index + 1;
|
|
166
|
-
const match = line.match(directiveRegex);
|
|
167
|
-
if (match !== null) {
|
|
168
|
-
const directive = match
|
|
169
|
-
.slice(1)
|
|
170
|
-
.reduce(
|
|
171
|
-
(final: string | undefined, item) => final || item,
|
|
172
|
-
undefined,
|
|
173
|
-
);
|
|
174
|
-
switch (directive) {
|
|
175
|
-
case 'highlight-next-line':
|
|
176
|
-
range += `${lineNumber},`;
|
|
177
|
-
break;
|
|
178
|
-
|
|
179
|
-
case 'highlight-start':
|
|
180
|
-
blockStart = lineNumber;
|
|
181
|
-
break;
|
|
182
|
-
|
|
183
|
-
case 'highlight-end':
|
|
184
|
-
range += `${blockStart!}-${lineNumber - 1},`;
|
|
185
|
-
break;
|
|
186
|
-
|
|
187
|
-
default:
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
lines.splice(index, 1);
|
|
191
|
-
} else {
|
|
192
|
-
// lines without directives are unchanged
|
|
193
|
-
index += 1;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
highlightLines = rangeParser(range);
|
|
197
|
-
code = lines.join('\n');
|
|
198
|
-
}
|
|
56
|
+
const language =
|
|
57
|
+
parseLanguage(blockClassName) ?? (prism.defaultLanguage as Language);
|
|
58
|
+
const {highlightLines, code} = parseLines(content, metastring, language);
|
|
199
59
|
|
|
200
60
|
const handleCopyCode = () => {
|
|
201
61
|
copy(code);
|
|
@@ -212,11 +72,7 @@ export default function CodeBlock({
|
|
|
212
72
|
code={code}
|
|
213
73
|
language={language}>
|
|
214
74
|
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
|
215
|
-
<div
|
|
216
|
-
className={clsx(
|
|
217
|
-
styles.codeBlockContainer,
|
|
218
|
-
blockClassName?.replace(/language-[^ ]+/, ''),
|
|
219
|
-
)}>
|
|
75
|
+
<div className={clsx(styles.codeBlockContainer, blockClassName)}>
|
|
220
76
|
{codeBlockTitle && (
|
|
221
77
|
<div style={style} className={styles.codeBlockTitle}>
|
|
222
78
|
{codeBlockTitle}
|
|
@@ -236,7 +92,7 @@ export default function CodeBlock({
|
|
|
236
92
|
|
|
237
93
|
const lineProps = getLineProps({line, key: i});
|
|
238
94
|
|
|
239
|
-
if (highlightLines.includes(i
|
|
95
|
+
if (highlightLines.includes(i)) {
|
|
240
96
|
lineProps.className += ' docusaurus-highlight-code-line';
|
|
241
97
|
}
|
|
242
98
|
|
|
@@ -253,7 +109,6 @@ export default function CodeBlock({
|
|
|
253
109
|
</pre>
|
|
254
110
|
|
|
255
111
|
<button
|
|
256
|
-
ref={button}
|
|
257
112
|
type="button"
|
|
258
113
|
aria-label={translate({
|
|
259
114
|
id: 'theme.CodeBlock.copyButtonAriaLabel',
|