Skip to content

Commit a0c5962

Browse files
committed
fix: unblock gmate deploy build path
1 parent 3f58abb commit a0c5962

3 files changed

Lines changed: 121 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
7+
"prebuild": "node scripts/cleanup-legacy-routes.js",
78
"build": "next build",
89
"start": "next start",
910
"lint": "eslint"

scripts/cleanup-legacy-routes.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
const repoRoot = process.cwd();
7+
const legacyDirs = [
8+
path.join(repoRoot, 'src', 'app', 'progress'),
9+
path.join(repoRoot, 'src', 'app', 'questions'),
10+
path.join(repoRoot, 'src', 'app', 'review'),
11+
path.join(repoRoot, 'src', 'app', 'sessions'),
12+
];
13+
14+
for (const dir of legacyDirs) {
15+
try {
16+
fs.rmSync(dir, { recursive: true, force: true });
17+
} catch (error) {
18+
console.warn(`cleanup warning for ${dir}:`, error.message);
19+
}
20+
}

src/components/ui/math-text.tsx

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"use client";
2+
3+
import { useMemo } from "react";
4+
import katex from "katex";
5+
6+
/**
7+
* Renders text that may contain LaTeX math delimiters.
8+
* - $$...$$ for display (block) math
9+
* - $...$ for inline math
10+
* Non-math text is rendered as-is with whitespace preserved.
11+
*/
12+
export function MathText({
13+
children,
14+
className,
15+
}: {
16+
children: string;
17+
className?: string;
18+
}) {
19+
const html = useMemo(() => renderMathInText(children), [children]);
20+
21+
return (
22+
<span
23+
className={className}
24+
dangerouslySetInnerHTML={{ __html: html }}
25+
/>
26+
);
27+
}
28+
29+
// Split text on $$...$$ and $...$ delimiters, render math segments with KaTeX
30+
function renderMathInText(text: string): string {
31+
// Match $$...$$ (display) first, then $...$ (inline)
32+
// Uses a regex that captures the delimiter type and content
33+
const parts: string[] = [];
34+
let remaining = text;
35+
36+
while (remaining.length > 0) {
37+
// Try display math first: $$...$$
38+
const displayMatch = remaining.match(/\$\$([\s\S]+?)\$\$/);
39+
// Try inline math: $...$ (not preceded/followed by $)
40+
const inlineMatch = remaining.match(/(?<!\$)\$(?!\$)((?:[^$\\]|\\.)+?)\$(?!\$)/);
41+
42+
if (!displayMatch && !inlineMatch) {
43+
parts.push(escapeHtml(remaining));
44+
break;
45+
}
46+
47+
// Pick whichever comes first in the string
48+
const displayIdx = displayMatch ? remaining.indexOf(displayMatch[0]) : Infinity;
49+
const inlineIdx = inlineMatch ? remaining.indexOf(inlineMatch[0]) : Infinity;
50+
51+
if (displayIdx <= inlineIdx && displayMatch) {
52+
// Add text before the match
53+
if (displayIdx > 0) {
54+
parts.push(escapeHtml(remaining.slice(0, displayIdx)));
55+
}
56+
// Render display math
57+
try {
58+
parts.push(
59+
katex.renderToString(displayMatch[1], {
60+
displayMode: true,
61+
throwOnError: false,
62+
output: "htmlAndMathml",
63+
})
64+
);
65+
} catch {
66+
parts.push(escapeHtml(displayMatch[0]));
67+
}
68+
remaining = remaining.slice(displayIdx + displayMatch[0].length);
69+
} else if (inlineMatch) {
70+
// Add text before the match
71+
if (inlineIdx > 0) {
72+
parts.push(escapeHtml(remaining.slice(0, inlineIdx)));
73+
}
74+
// Render inline math
75+
try {
76+
parts.push(
77+
katex.renderToString(inlineMatch[1], {
78+
displayMode: false,
79+
throwOnError: false,
80+
output: "htmlAndMathml",
81+
})
82+
);
83+
} catch {
84+
parts.push(escapeHtml(inlineMatch[0]));
85+
}
86+
remaining = remaining.slice(inlineIdx + inlineMatch[0].length);
87+
}
88+
}
89+
90+
return parts.join("");
91+
}
92+
93+
function escapeHtml(text: string): string {
94+
return text
95+
.replace(/&/g, "&amp;")
96+
.replace(/</g, "&lt;")
97+
.replace(/>/g, "&gt;")
98+
.replace(/"/g, "&quot;")
99+
.replace(/\n/g, "<br />");
100+
}

0 commit comments

Comments
 (0)