Public Access
feat: add markdown rendering support with marked and integrate into Tex component
This commit is contained in:
1 parent
e906951b06
commit
b58500901a
10 files changed
+112
-6
No files matched your search
@@ -242,7 +242,7 @@ export default function ExamRunner({
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<Tex tag="div" className="q-prompt">
|
||||
<Tex tag="div" className="q-prompt" markdown>
|
||||
{q.prompt}
|
||||
</Tex>
|
||||
<QuestionMedia q={q} />
|
||||
|
||||
@@ -200,7 +200,7 @@ export default function Results({ exam, state, onRestart, onExit, onRedoFailed,
|
||||
{openIdx === i && (
|
||||
<div className="review-body">
|
||||
<div className="q-prompt" style={{ fontSize: 20, marginBottom: 20 }}>
|
||||
<Tex>{q.prompt}</Tex>
|
||||
<Tex markdown>{q.prompt}</Tex>
|
||||
</div>
|
||||
<QuestionMedia q={q} />
|
||||
<QuestionRenderer key={q.id} q={q} value={answers[q.id]} onChange={() => {}} locked graded />
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import type React from 'react'
|
||||
import { renderLatex } from '../utils/latex'
|
||||
import { renderMarkdown } from '../utils/markdown'
|
||||
|
||||
interface TexProps {
|
||||
children?: string | null
|
||||
tag?: keyof React.JSX.IntrinsicElements
|
||||
className?: string
|
||||
style?: React.CSSProperties
|
||||
markdown?: boolean
|
||||
}
|
||||
|
||||
// Safe: renderLatex only produces KaTeX-controlled HTML + HTML-escaped plain text.
|
||||
export default function Tex({ children, tag = 'span', className, style }: Readonly<TexProps>) {
|
||||
// When markdown is true, uses renderMarkdown which applies marked + KaTeX + DOMPurify.
|
||||
export default function Tex({ children, tag = 'span', className, style, markdown }: Readonly<TexProps>) {
|
||||
const Tag = tag as React.ElementType
|
||||
const html = String(children ?? '').split('\n').map(renderLatex).join('<br/>')
|
||||
const text = String(children ?? '')
|
||||
const html = markdown
|
||||
? renderMarkdown(text)
|
||||
: text.split('\n').map(renderLatex).join('<br/>')
|
||||
return <Tag className={className} style={style} dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import Tex from '../Tex'
|
||||
import type { Question } from '../../types'
|
||||
|
||||
interface Props {
|
||||
@@ -23,7 +24,7 @@ export default function Flashcard({ q, value, onChange, locked }: Props) {
|
||||
return (
|
||||
<div className="flashcard-wrap">
|
||||
<div className="flashcard-prompt">
|
||||
{q.prompt}
|
||||
<Tex markdown>{q.prompt}</Tex>
|
||||
</div>
|
||||
|
||||
{!revealed ? (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Tex from '../Tex'
|
||||
import type { Question } from '../../types'
|
||||
|
||||
interface Props {
|
||||
@@ -9,6 +10,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function GrammarCorrection({ q, value = '', onChange, locked, graded }: Props) {
|
||||
const displayText = q.textToCorrect || q.prompt
|
||||
return (
|
||||
<div className="answer-input-wrap">
|
||||
<div className="grammar-text-wrap">
|
||||
@@ -16,7 +18,7 @@ export default function GrammarCorrection({ q, value = '', onChange, locked, gra
|
||||
Sentence to correct:
|
||||
</div>
|
||||
<div className="grammar-sentence">
|
||||
{q.textToCorrect || q.prompt}
|
||||
<Tex markdown>{displayText}</Tex>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
|
||||
Reference in new issue
Block a user