11import Markdown , { Components } from "react-markdown" ;
22import remarkGfm from "remark-gfm" ;
33import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" ;
4- import { PythonEmbeddedTerminal } from "../terminal/python/embedded" ;
4+ import { PythonEmbeddedTerminal , PythonExecFile } from "../terminal/python/embedded" ;
55import { Heading } from "./section" ;
6+ import { EditorComponent } from "../terminal/editor" ;
67
78export function StyledMarkdown ( { content } : { content : string } ) {
89 return (
@@ -32,52 +33,86 @@ const components: Components = {
3233 strong : ( { node, ...props } ) => (
3334 < strong className = "text-primary" { ...props } />
3435 ) ,
36+ hr : ( { node, ...props } ) => < hr className = "border-primary my-4" { ...props } /> ,
37+ pre : ( { node, ...props } ) => props . children ,
3538 code : ( { node, className, ref, style, ...props } ) => {
36- const match = / ^ l a n g u a g e - ( \w + ) ( - r e p l ) ? \: ? ( .+ ) ? $ / . exec ( className || "" ) ;
39+ const match = / ^ l a n g u a g e - ( \w + ) ( - r e p l | - e x e c ) ? \: ? ( .+ ) ? $ / . exec ( className || "" ) ;
3740 if ( match ) {
38- if ( match [ 2 ] ) {
39- // repl付きの言語指定
41+ if ( match [ 2 ] === "-exec" && match [ 3 ] ) {
42+ /*
43+ ```python-exec:main.py
44+ hello, world!
45+ ```
46+ ↓
47+ ---------------------------
48+ [▶ 実行] `python main.py`
49+ hello, world!
50+ ---------------------------
51+ */
52+ switch ( match [ 1 ] ) {
53+ case "python" :
54+ return (
55+ < div className = "border border-primary m-2 rounded-lg" >
56+ < PythonExecFile filename = { match [ 3 ] } content = { String ( props . children ) . replace ( / \n $ / , "" ) } />
57+ </ div >
58+ ) ;
59+ default :
60+ console . warn ( `Unsupported language for exec: ${ match [ 1 ] } ` ) ;
61+ break ;
62+ }
63+ } else if ( match [ 3 ] ) {
64+ // ファイル名指定がある場合、ファイルエディター
4065 // 現状はPythonのみ対応
4166 switch ( match [ 1 ] ) {
4267 case "python" :
4368 return (
44- < PythonEmbeddedTerminal
45- content = { String ( props . children ) . replace ( / \n $ / , "" ) }
46- />
69+ < div className = "border border-primary m-2 rounded-lg" >
70+ < EditorComponent
71+ language = { match [ 1 ] }
72+ tabSize = { 4 }
73+ filename = { match [ 3 ] }
74+ initContent = { String ( props . children ) . replace ( / \n $ / , "" ) }
75+ />
76+ </ div >
4777 ) ;
4878 default :
49- console . warn ( `Unsupported language for repl: ${ match [ 1 ] } ` ) ;
79+ console . warn ( `Unsupported language for editor: ${ match [ 1 ] } ` ) ;
80+ break ;
81+ }
82+ } else if ( match [ 2 ] === "-repl" ) {
83+ // repl付きの言語指定
84+ // 現状はPythonのみ対応
85+ switch ( match [ 1 ] ) {
86+ case "python" :
5087 return (
51- < SyntaxHighlighter
52- language = { match [ 1 ] }
53- PreTag = "div"
54- className = "px-4! py-4! m-0! font-mono!"
55- // style={todo dark theme?}
56- { ...props }
57- >
58- { String ( props . children ) . replace ( / \n $ / , "" ) }
59- </ SyntaxHighlighter >
88+ < div className = "bg-base-300 border border-primary m-2 p-4 rounded-lg" >
89+ < PythonEmbeddedTerminal
90+ content = { String ( props . children ) . replace ( / \n $ / , "" ) }
91+ />
92+ </ div >
6093 ) ;
94+ default :
95+ console . warn ( `Unsupported language for repl: ${ match [ 1 ] } ` ) ;
96+ break ;
6197 }
62- } else {
63- return (
64- < SyntaxHighlighter
65- language = { match [ 1 ] }
66- PreTag = "div"
67- className = "px-4! py-4! m-0! font-mono!"
68- // style={todo dark theme?}
69- { ...props }
70- >
71- { String ( props . children ) . replace ( / \n $ / , "" ) }
72- </ SyntaxHighlighter >
73- ) ;
7498 }
99+ return (
100+ < SyntaxHighlighter
101+ language = { match [ 1 ] }
102+ PreTag = "div"
103+ className = "border border-primary mx-2 my-2 rounded-lg text-sm! m-2! p-4! font-mono!"
104+ // style={todo dark theme?}
105+ { ...props }
106+ >
107+ { String ( props . children ) . replace ( / \n $ / , "" ) }
108+ </ SyntaxHighlighter >
109+ ) ;
75110 } else if ( String ( props . children ) . includes ( "\n" ) ) {
76111 // 言語指定なしコードブロック
77112 return (
78113 < SyntaxHighlighter
79114 PreTag = "div"
80- className = "px-4! py-4 ! m-0 ! font-mono!"
115+ className = "border border-primary mx-2 my-2 rounded-lg text-sm ! m-2! p-4 ! font-mono!"
81116 // style={todo dark theme?}
82117 { ...props }
83118 >
@@ -94,11 +129,4 @@ const components: Components = {
94129 ) ;
95130 }
96131 } ,
97- pre : ( { node, ...props } ) => (
98- < pre
99- className = "bg-base-200 border border-primary mx-2 my-2 rounded-lg text-sm overflow-x-auto"
100- { ...props }
101- />
102- ) ,
103- hr : ( { node, ...props } ) => < hr className = "border-primary my-4" { ...props } /> ,
104132} ;
0 commit comments