Skip to content

Commit e594250

Browse files
committed
feat: add syntax highlight to code blocks in dataset detail page
1 parent 37f0066 commit e594250

File tree

4 files changed

+282
-27
lines changed

4 files changed

+282
-27
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@
3333
"jquery": "^3.7.1",
3434
"json-stringify-safe": "^5.0.1",
3535
"jwt-decode": "^3.1.2",
36-
"path-browserify": "^1.0.1",
3736
"pako": "^2.1.0",
37+
"path-browserify": "^1.0.1",
3838
"query-string": "^8.1.0",
3939
"react": "^18.2.0",
4040
"react-dom": "^18.2.0",
4141
"react-json-view": "^1.21.3",
4242
"react-redux": "^8.1.2",
4343
"react-router-dom": "^6.15.0",
4444
"react-scripts": "^5.0.1",
45+
"react-syntax-highlighter": "^15.6.1",
4546
"sharp": "^0.33.5",
4647
"stats-js": "^1.0.1",
4748
"typescript": "^5.1.6",

src/components/DatasetDetailPage/LoadDatasetTabs.tsx

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,24 @@ import { Tabs, Tab, Box, Typography, IconButton, Tooltip } from "@mui/material";
33
import { Colors } from "design/theme";
44
import React from "react";
55
import { useState } from "react";
6+
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
7+
import bash from "react-syntax-highlighter/dist/esm/languages/hljs/bash";
8+
import cpp from "react-syntax-highlighter/dist/esm/languages/hljs/cpp";
9+
import javascript from "react-syntax-highlighter/dist/esm/languages/hljs/javascript";
10+
import matlab from "react-syntax-highlighter/dist/esm/languages/hljs/matlab";
11+
import python from "react-syntax-highlighter/dist/esm/languages/hljs/python";
12+
import {
13+
docco,
14+
atomOneDark,
15+
} from "react-syntax-highlighter/dist/esm/styles/hljs";
16+
import { Color } from "three";
617

18+
// Register them
19+
SyntaxHighlighter.registerLanguage("python", python);
20+
SyntaxHighlighter.registerLanguage("bash", bash);
21+
SyntaxHighlighter.registerLanguage("cpp", cpp);
22+
SyntaxHighlighter.registerLanguage("matlab", matlab);
23+
SyntaxHighlighter.registerLanguage("javascript", javascript);
724
interface LoadDatasetTabsProps {
825
pagename: string;
926
docname: string;
@@ -84,10 +101,36 @@ const LoadDatasetTabs: React.FC<LoadDatasetTabsProps> = ({
84101
);
85102
};
86103

87-
const CopyableCodeBlock = ({ code }: { code: string }) => {
104+
// const CopyableCodeBlock = ({ code }: { code: string }) => {
105+
// const handleCopy = () => {
106+
// navigator.clipboard.writeText(code);
107+
// };
108+
// return (
109+
// <Box sx={{ position: "relative" }}>
110+
// <IconButton
111+
// onClick={handleCopy}
112+
// size="small"
113+
// sx={{ position: "absolute", top: 5, right: 5 }}
114+
// >
115+
// <Tooltip title="Copy to clipboard">
116+
// <ContentCopyIcon fontSize="small" />
117+
// </Tooltip>
118+
// </IconButton>
119+
// <code style={flashcardStyles.codeBlock}>{code}</code>
120+
// </Box>
121+
// );
122+
// };
123+
const CopyableCodeBlock = ({
124+
code,
125+
language = "python", // optionally allow language selection
126+
}: {
127+
code: string;
128+
language?: string;
129+
}) => {
88130
const handleCopy = () => {
89131
navigator.clipboard.writeText(code);
90132
};
133+
91134
return (
92135
<Box sx={{ position: "relative" }}>
93136
<IconButton
@@ -96,10 +139,22 @@ const LoadDatasetTabs: React.FC<LoadDatasetTabsProps> = ({
96139
sx={{ position: "absolute", top: 5, right: 5 }}
97140
>
98141
<Tooltip title="Copy to clipboard">
99-
<ContentCopyIcon fontSize="small" />
142+
<ContentCopyIcon fontSize="small" sx={{ color: Colors.green }} />
100143
</Tooltip>
101144
</IconButton>
102-
<code style={flashcardStyles.codeBlock}>{code}</code>
145+
<SyntaxHighlighter
146+
language={language}
147+
style={atomOneDark}
148+
customStyle={{
149+
padding: "12px",
150+
borderRadius: "5px",
151+
fontSize: "14px",
152+
background: Colors.black,
153+
overflowX: "auto",
154+
}}
155+
>
156+
{code}
157+
</SyntaxHighlighter>
103158
</Box>
104159
);
105160
};
@@ -141,7 +196,10 @@ const LoadDatasetTabs: React.FC<LoadDatasetTabsProps> = ({
141196
Load by URL with REST-API in Python
142197
</Typography>
143198
<Typography>Install:</Typography>
144-
<CopyableCodeBlock code={`pip install jdata bjdata numpy`} />
199+
<CopyableCodeBlock
200+
code={`pip install jdata bjdata numpy`}
201+
language="bash"
202+
/>
145203
<Typography>Load from URL:</Typography>
146204
<CopyableCodeBlock
147205
code={`import jdata as jd
@@ -152,6 +210,7 @@ links = jd.jsonpath(data, '$.._DataLink_')
152210
153211
# Download & cache anatomical nii.gz data for sub-01/sub-02
154212
jd.jdlink(links, {'regex': 'anat/sub-0[12]_.*\\.nii'})`}
213+
language="python"
155214
/>
156215
</Box>
157216
</TabPanel>
@@ -163,7 +222,10 @@ jd.jdlink(links, {'regex': 'anat/sub-0[12]_.*\\.nii'})`}
163222
Load by URL with REST-API in MATLAB
164223
</Typography>
165224
<Typography>Install:</Typography>
166-
<CopyableCodeBlock code={`Download and addpath to JSONLab`} />
225+
<CopyableCodeBlock
226+
code={`Download and addpath to JSONLab`}
227+
language="text"
228+
/>
167229
<Typography>Load from URL:</Typography>
168230
<CopyableCodeBlock
169231
code={`data = loadjson('${datasetUrl}');
@@ -176,6 +238,7 @@ links = jsonpath(data, '$.._DataLink_');
176238
177239
% Download & cache anatomical nii.gz data for sub-01/sub-02
178240
niidata = jdlink(links, 'regex', 'anat/sub-0[12]_.*\\.nii');`}
241+
language="matlab"
179242
/>
180243
</Box>
181244
</TabPanel>
@@ -187,9 +250,15 @@ niidata = jdlink(links, 'regex', 'anat/sub-0[12]_.*\\.nii');`}
187250
Use in MATLAB/Octave
188251
</Typography>
189252
<Typography>Load:</Typography>
190-
<CopyableCodeBlock code={`data = loadjd('${docname}.json');`} />
253+
<CopyableCodeBlock
254+
code={`data = loadjd('${docname}.json');`}
255+
language="matlab"
256+
/>
191257
<Typography>Read value:</Typography>
192-
<CopyableCodeBlock code={`data.(encodevarname('${onekey}'))`} />
258+
<CopyableCodeBlock
259+
code={`data.(encodevarname('${onekey}'))`}
260+
language="matlab"
261+
/>
193262
</Box>
194263
</TabPanel>
195264

@@ -203,9 +272,10 @@ niidata = jdlink(links, 'regex', 'anat/sub-0[12]_.*\\.nii');`}
203272
<CopyableCodeBlock
204273
code={`import jdata as jd
205274
data = jd.load('${docname}.json')`}
275+
language="python"
206276
/>
207277
<Typography>Read value:</Typography>
208-
<CopyableCodeBlock code={`data["${onekey}"]`} />
278+
<CopyableCodeBlock code={`data["${onekey}"]`} language="python" />
209279
</Box>
210280
</TabPanel>
211281

@@ -216,17 +286,24 @@ data = jd.load('${docname}.json')`}
216286
Use in C++
217287
</Typography>
218288
<Typography>Install:</Typography>
219-
<CopyableCodeBlock code={`Download JSON for Modern C++ json.hpp`} />
289+
<CopyableCodeBlock
290+
code={`Download JSON for Modern C++ json.hpp`}
291+
language="text"
292+
/>
220293
<Typography>Load:</Typography>
221294
<CopyableCodeBlock
222295
code={`#include "json.hpp"
223296
using json=nlohmann::ordered_json;
224297
225298
std::ifstream datafile("${docname}.json");
226299
json data(datafile);`}
300+
language="cpp"
227301
/>
228302
<Typography>Read value:</Typography>
229-
<CopyableCodeBlock code={`std::cout << data["${onekey}"];`} />
303+
<CopyableCodeBlock
304+
code={`std::cout << data["${onekey}"];`}
305+
language="cpp"
306+
/>
230307
</Box>
231308
</TabPanel>
232309

@@ -237,7 +314,10 @@ json data(datafile);`}
237314
Use in JS/Node.js
238315
</Typography>
239316
<Typography>Install:</Typography>
240-
<CopyableCodeBlock code={`npm install jda numjs pako atob`} />
317+
<CopyableCodeBlock
318+
code={`npm install jda numjs pako atob`}
319+
language="bash"
320+
/>
241321
<Typography>Load:</Typography>
242322
<CopyableCodeBlock
243323
code={`const fs = require("fs");
@@ -248,9 +328,13 @@ const fn = "${docname}.json";
248328
var jstr = fs.readFileSync(fn).toString().replace(/\\n/g, "");
249329
var data = new jd(JSON.parse(jstr));
250330
data = data.decode();`}
331+
language="javascript"
251332
/>
252333
<Typography>Read value:</Typography>
253-
<CopyableCodeBlock code={`console.log(data.data["${onekey}"]);`} />
334+
<CopyableCodeBlock
335+
code={`console.log(data.data["${onekey}"]);`}
336+
language="javascript"
337+
/>
254338
</Box>
255339
</TabPanel>
256340
</>

src/declare.d.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
declare module '*.png';
2-
declare module '*.svg';
1+
declare module "*.png";
2+
declare module "*.svg";
33

44
declare global {
5-
interface Window {
6-
dopreview: (key: any, idx: number, isinternal: boolean, hastime: any[]) => void;
7-
previewdata: any;
8-
previewdataurl: any;
9-
initcanvas: () => void;
10-
drawpreview: (data: any) => void;
11-
update: () => void;
12-
createStats: () => any;
13-
setControlAngles: (angles: any) => void;
14-
setcrosssectionsizes: (sizes: any) => void;
15-
}
5+
interface Window {
6+
dopreview: (
7+
key: any,
8+
idx: number,
9+
isinternal: boolean,
10+
hastime: any[]
11+
) => void;
12+
previewdata: any;
13+
previewdataurl: any;
14+
initcanvas: () => void;
15+
drawpreview: (data: any) => void;
16+
update: () => void;
17+
createStats: () => any;
18+
setControlAngles: (angles: any) => void;
19+
setcrosssectionsizes: (sizes: any) => void;
20+
}
1621
}
1722

23+
declare module "react-syntax-highlighter";
24+
declare module "react-syntax-highlighter/dist/esm/styles/hljs";
25+
declare module "react-syntax-highlighter/dist/esm/languages/hljs/*";
26+
1827
// declare module "./utils/preview.js" {
1928
// export function dopreview(
2029
// key: any,

0 commit comments

Comments
 (0)