@@ -5,7 +5,7 @@ import { PythonEmbeddedTerminal } from "../terminal/python/embedded";
55import { Heading } from "./section" ;
66import { type AceLang , EditorComponent } from "../terminal/editor" ;
77import { ExecFile , ExecLang } from "../terminal/exec" ;
8- import { ChangeTheme } from "./themeToggle" ;
8+ import { useChangeTheme } from "./themeToggle" ;
99import { tomorrow } from "react-syntax-highlighter/dist/esm/styles/hljs" ;
1010import { twilight } from "react-syntax-highlighter/dist/esm/styles/prism" ;
1111
@@ -45,130 +45,133 @@ const components: Components = {
4545 ) ,
4646 hr : ( { node, ...props } ) => < hr className = "border-primary my-4" { ...props } /> ,
4747 pre : ( { node, ...props } ) => props . children ,
48- code : ( { node, className, ref, style, ...props } ) => {
49- const match = / ^ l a n g u a g e - ( \w + ) ( - r e p l | - e x e c | - r e a d o n l y ) ? \: ? ( .+ ) ? $ / . exec (
50- className || ""
51- ) ;
52- if ( match ) {
53- if ( match [ 2 ] === "-exec" && match [ 3 ] ) {
54- /*
55- ```python-exec:main.py
48+ code : ( { node, className, ref, style, ...props } ) => < CodeComponent { ...{ node, className, ref, style, ...props } } /> ,
49+ } ;
50+ function CodeComponent ( { node, className, ref, style, ...props } : { node : any ; className ?: string ; ref ?: any ; style ?: any ; [ key : string ] : any } ) {
51+ const theme = useChangeTheme ( ) ;
52+ const codetheme = theme === "tomorrow" ? tomorrow : twilight ;
53+ const match = / ^ l a n g u a g e - ( \w + ) ( - r e p l | - e x e c | - r e a d o n l y ) ? \: ? ( .+ ) ? $ / . exec (
54+ className || ""
55+ ) ;
56+ if ( match ) {
57+ if ( match [ 2 ] === "-exec" && match [ 3 ] ) {
58+ /*
59+ ```python-exec:main.py
60+ hello, world!
61+ ```
62+ ↓
63+ ---------------------------
64+ [▶ 実行] `python main.py`
5665 hello, world!
57- ```
58- ↓
59- ---------------------------
60- [▶ 実行] `python main.py`
61- hello, world!
62- ---------------------------
63- */
64- let execLang : ExecLang | undefined = undefined ;
65- switch ( match [ 1 ] ) {
66- case "python" :
67- execLang = "python" ;
68- break ;
69- case "cpp" :
70- case "c++" :
71- execLang = "cpp" ;
72- break ;
73- default :
74- console . warn ( `Unsupported language for exec: ${ match [ 1 ] } ` ) ;
75- break ;
76- }
77- if ( execLang ) {
78- return (
79- < div className = "border border-primary border-2 shadow-md m-2 rounded-lg" >
80- < ExecFile
81- language = { execLang }
82- filenames = { match [ 3 ] . split ( "," ) }
83- content = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
84- />
85- </ div >
86- ) ;
87- }
88- } else if ( match [ 3 ] ) {
89- // ファイル名指定がある場合、ファイルエディター
90- let aceLang : AceLang | undefined = undefined ;
91- switch ( match [ 1 ] ) {
92- case "python" :
93- aceLang = "python" ;
94- break ;
95- case "cpp" :
96- case "c++" :
97- aceLang = "c_cpp" ;
98- break ;
99- case "json" :
100- aceLang = "json" ;
101- break ;
102- case "csv" :
103- aceLang = "csv" ;
104- break ;
105- case "text" :
106- case "txt" :
107- aceLang = "text" ;
108- break ;
109- default :
110- console . warn ( `Unsupported language for editor: ${ match [ 1 ] } ` ) ;
111- break ;
112- }
66+ ---------------------------
67+ */
68+ let execLang : ExecLang | undefined = undefined ;
69+ switch ( match [ 1 ] ) {
70+ case "python" :
71+ execLang = "python" ;
72+ break ;
73+ case "cpp" :
74+ case "c++" :
75+ execLang = "cpp" ;
76+ break ;
77+ default :
78+ console . warn ( `Unsupported language for exec: ${ match [ 1 ] } ` ) ;
79+ break ;
80+ }
81+ if ( execLang ) {
11382 return (
11483 < div className = "border border-primary border-2 shadow-md m-2 rounded-lg" >
115- < EditorComponent
116- language = { aceLang }
117- tabSize = { 4 }
118- filename = { match [ 3 ] }
119- readonly = { match [ 2 ] === "-readonly" }
120- initContent = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
84+ < ExecFile
85+ language = { execLang }
86+ filenames = { match [ 3 ] . split ( "," ) }
87+ content = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
12188 />
12289 </ div >
12390 ) ;
124- } else if ( match [ 2 ] === "-repl" ) {
125- // repl付きの言語指定
126- // 現状はPythonのみ対応
127- switch ( match [ 1 ] ) {
128- case "python" :
129- return (
130- < div className = "bg-base-300 border border-primary border-2 shadow-md m-2 p-4 pr-1 rounded-lg" >
131- < PythonEmbeddedTerminal
132- content = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
133- />
134- </ div >
135- ) ;
136- default :
137- console . warn ( `Unsupported language for repl: ${ match [ 1 ] } ` ) ;
138- break ;
139- }
91+ }
92+ } else if ( match [ 3 ] ) {
93+ // ファイル名指定がある場合、ファイルエディター
94+ let aceLang : AceLang | undefined = undefined ;
95+ switch ( match [ 1 ] ) {
96+ case "python" :
97+ aceLang = "python" ;
98+ break ;
99+ case "cpp" :
100+ case "c++" :
101+ aceLang = "c_cpp" ;
102+ break ;
103+ case "json" :
104+ aceLang = "json" ;
105+ break ;
106+ case "csv" :
107+ aceLang = "csv" ;
108+ break ;
109+ case "text" :
110+ case "txt" :
111+ aceLang = "text" ;
112+ break ;
113+ default :
114+ console . warn ( `Unsupported language for editor: ${ match [ 1 ] } ` ) ;
115+ break ;
140116 }
141117 return (
142- < SyntaxHighlighter
143- language = { match [ 1 ] }
144- PreTag = "div"
145- className = "border border-base-content/50 mx-2 my-2 rounded-lg text-sm p-4!"
146- style = { tomorrow } // todo dark theme (editor.tsx で指定したのと同じテーマを選ぶようにすること)
147- { ...props }
148- >
149- { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
150- </ SyntaxHighlighter >
151- ) ;
152- } else if ( String ( props . children ) . includes ( "\n" ) ) {
153- // 言語指定なしコードブロック
154- return (
155- < SyntaxHighlighter
156- PreTag = "div"
157- className = "border border-base-content/50 mx-2 my-2 rounded-lg text-sm p-4!"
158- style = { tomorrow } // todo dark theme
159- { ...props }
160- >
161- { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
162- </ SyntaxHighlighter >
163- ) ;
164- } else {
165- // inline
166- return (
167- < code
168- className = "bg-base-200/60 border border-base-300 px-1 py-0.5 rounded text-sm "
169- { ...props }
170- />
118+ < div className = "border border-primary border-2 shadow-md m-2 rounded-lg" >
119+ < EditorComponent
120+ language = { aceLang }
121+ tabSize = { 4 }
122+ filename = { match [ 3 ] }
123+ readonly = { match [ 2 ] === "-readonly" }
124+ initContent = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
125+ />
126+ </ div >
171127 ) ;
128+ } else if ( match [ 2 ] === "-repl" ) {
129+ // repl付きの言語指定
130+ // 現状はPythonのみ対応
131+ switch ( match [ 1 ] ) {
132+ case "python" :
133+ return (
134+ < div className = "bg-base-300 border border-primary border-2 shadow-md m-2 p-4 pr-1 rounded-lg" >
135+ < PythonEmbeddedTerminal
136+ content = { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
137+ />
138+ </ div >
139+ ) ;
140+ default :
141+ console . warn ( `Unsupported language for repl: ${ match [ 1 ] } ` ) ;
142+ break ;
143+ }
172144 }
173- } ,
174- } ;
145+ return (
146+ < SyntaxHighlighter
147+ language = { match [ 1 ] }
148+ PreTag = "div"
149+ className = "border border-base-content/50 mx-2 my-2 rounded-lg text-sm p-4!"
150+ style = { codetheme }
151+ { ...props }
152+ >
153+ { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
154+ </ SyntaxHighlighter >
155+ ) ;
156+ } else if ( String ( props . children ) . includes ( "\n" ) ) {
157+ // 言語指定なしコードブロック
158+ return (
159+ < SyntaxHighlighter
160+ PreTag = "div"
161+ className = "border border-base-content/50 mx-2 my-2 rounded-lg text-sm p-4!"
162+ style = { codetheme }
163+ { ...props }
164+ >
165+ { String ( props . children || "" ) . replace ( / \n $ / , "" ) }
166+ </ SyntaxHighlighter >
167+ ) ;
168+ } else {
169+ // inline
170+ return (
171+ < code
172+ className = "bg-base-200/60 border border-base-300 px-1 py-0.5 rounded text-sm "
173+ { ...props }
174+ />
175+ ) ;
176+ }
177+ }
0 commit comments