1+ import 'katex/dist/katex.min.css'
2+
13import { Box , Grid , Text , VStack } from '@devup-ui/react'
24import { readFile } from 'fs/promises'
35import { Metadata } from 'next'
6+ import Latex from 'react-latex-next'
47
58import TestCaseCircle from '@/components/test-case/TestCaseCircle'
69
@@ -81,24 +84,34 @@ export default async function TestCasePage() {
8184 gridTemplateColumns = "repeat(auto-fill, minmax(16px, 1fr))"
8285 >
8386 { testStatus [ key ] [ 2 ] . map (
84- ( [ text , expected , actual , isSuccess ] , idx ) => (
85- < TestCaseCircle key = { text + idx } isSuccess = { isSuccess } >
86- < Text
87- color = "#FFF"
88- typography = "body"
89- whiteSpace = "nowrap"
90- wordBreak = "keep-all"
91- >
92- { text }
93- < br />
94- 정답 : { expected }
95- < br />
96- 결과 : { actual }
97- < br />
98- { isSuccess ? '✅ 테스트 성공' : '❌ 테스트 실패' }
99- </ Text >
100- </ TestCaseCircle >
101- ) ,
87+ ( [ text , expected , actual , isSuccess ] , idx ) => {
88+ const textParts = parseTextWithLaTeX ( text )
89+
90+ return (
91+ < TestCaseCircle key = { text + idx } isSuccess = { isSuccess } >
92+ < Text
93+ color = "#FFF"
94+ typography = "body"
95+ whiteSpace = "nowrap"
96+ wordBreak = "keep-all"
97+ >
98+ { textParts . map ( ( part , partIdx ) =>
99+ part . type === 'latex' ? (
100+ < Latex key = { partIdx } > ${ part . content } $</ Latex >
101+ ) : (
102+ < span key = { partIdx } > { part . content } </ span >
103+ ) ,
104+ ) }
105+ < br />
106+ 정답 : { expected }
107+ < br />
108+ 결과 : { actual }
109+ < br />
110+ { isSuccess ? '✅ 테스트 성공' : '❌ 테스트 실패' }
111+ </ Text >
112+ </ TestCaseCircle >
113+ )
114+ } ,
102115 ) }
103116 </ Grid >
104117 </ VStack >
@@ -107,3 +120,50 @@ export default async function TestCasePage() {
107120 </ Box >
108121 )
109122}
123+
124+ /**
125+ * This function parses text with LaTeX expressions and returns an array of parts.
126+ * It assumes that LaTeX is wrapped in double dollar delimiters ($$...$$).
127+ * Note that single dollar delimiters ($...$) are not rendered.
128+ * @param input - The input text to parse.
129+ * @returns An array of parts, where each part is either a text or a LaTeX expression.
130+ */
131+ const parseTextWithLaTeX = ( input : string ) => {
132+ const parts : Array < {
133+ type : 'text' | 'latex'
134+ content : string
135+ } > = [ ]
136+ const latexRegex = / \$ \$ ( [ ^ $ ] + (?: \$ (? ! \$ ) [ ^ $ ] * ) * ) \$ \$ / g
137+ let lastIndex = 0
138+ let match
139+
140+ while ( ( match = latexRegex . exec ( input ) ) !== null ) {
141+ // if there is text before the LaTeX expression, add it as a text part:
142+ if ( match . index > lastIndex ) {
143+ const textContent = input . slice ( lastIndex , match . index )
144+ if ( textContent ) {
145+ parts . push ( { type : 'text' , content : textContent } )
146+ }
147+ }
148+
149+ // add the LaTeX expression from double dollars:
150+ const latexContent = match [ 1 ]
151+ parts . push ( { type : 'latex' , content : latexContent } )
152+ lastIndex = match . index + match [ 0 ] . length
153+ }
154+
155+ // add remaining text after the last LaTeX expression:
156+ if ( lastIndex < input . length ) {
157+ const remainingText = input . slice ( lastIndex )
158+ if ( remainingText ) {
159+ parts . push ( { type : 'text' , content : remainingText } )
160+ }
161+ }
162+
163+ // if no LaTeX found, return the original text as a single text part:
164+ if ( ! parts . length ) {
165+ parts . push ( { type : 'text' , content : input } )
166+ }
167+
168+ return parts
169+ }
0 commit comments