풀이하고 있는 내용 색상 강조

This commit is contained in:
2026-05-31 16:13:14 +09:00
parent ac3c939051
commit 6300fe1082
2 changed files with 63 additions and 2 deletions
@@ -17,8 +17,34 @@ import { DESKTOP_INPUT_DEVICE_QUERY } from "@/lib/input-device";
import KatexRenderer from "@/components/math/KatexRenderer"; import KatexRenderer from "@/components/math/KatexRenderer";
import { useGameStore } from "@/store/gameStore"; import { useGameStore } from "@/store/gameStore";
import type { MaxTermCount, ProblemCount } from "@/store/gameStore"; import type { MaxTermCount, ProblemCount } from "@/store/gameStore";
import type { ParenthesisSignProblem } from "@/lib/engine/types";
const REAL_NUMBER_PATTERN = /^-?\d+(?:\.\d+)?$/; const REAL_NUMBER_PATTERN = /^-?\d+(?:\.\d+)?$/;
const ACTIVE_TERM_COLOR = "#f97316";
function highlightLatex(latex: string) {
return `\\textcolor{${ACTIVE_TERM_COLOR}}{${latex}}`;
}
function formatActiveTermProblemLatex(
problem: ParenthesisSignProblem,
activeTermIndex: number,
) {
const termLatex = problem.terms
.map((term, index) => {
const displayTerm =
index === activeTermIndex ? highlightLatex(`${term}`) : `${term}`;
if (index === 0) return displayTerm;
return `${problem.operators[index - 1]} ${displayTerm}`;
})
.join(" ");
return `${highlightLatex(`${problem.multiplier}`)}${highlightLatex(
"(",
)}${termLatex}${highlightLatex(")")}`;
}
function parseAnswer(value: string) { function parseAnswer(value: string) {
const trimmed = value.trim(); const trimmed = value.trim();
@@ -205,6 +231,9 @@ export default function NumberPlayClient({
const submitted = currentResult !== null; const submitted = currentResult !== null;
const isLastProblem = session.currentIndex === session.problems.length - 1; const isLastProblem = session.currentIndex === session.problems.length - 1;
const problemLatex = submitted
? currentProblem.latexBefore
: formatActiveTermProblemLatex(currentProblem, activeInput);
const pendingAnswerLabels = currentProblem.terms.map((term, index) => { const pendingAnswerLabels = currentProblem.terms.map((term, index) => {
if (index === 0) return String(term); if (index === 0) return String(term);
@@ -239,7 +268,7 @@ export default function NumberPlayClient({
className="rounded-md bg-white px-6 pt-6 pb-4 shadow-sm ring-1 ring-slate-200 sm:p-8" className="rounded-md bg-white px-6 pt-6 pb-4 shadow-sm ring-1 ring-slate-200 sm:p-8"
> >
<div className="text-3xl font-semibold text-slate-950 sm:text-4xl"> <div className="text-3xl font-semibold text-slate-950 sm:text-4xl">
<KatexRenderer latex={currentProblem.latexBefore} displayMode /> <KatexRenderer latex={problemLatex} displayMode />
</div> </div>
<div className="mt-6"> <div className="mt-6">
<StageIndicator <StageIndicator
@@ -10,12 +10,41 @@ import VariableFeedbackPanel from "@/components/game/VariableFeedbackPanel";
import VariableScoreSummary from "@/components/game/VariableScoreSummary"; import VariableScoreSummary from "@/components/game/VariableScoreSummary";
import KatexRenderer from "@/components/math/KatexRenderer"; import KatexRenderer from "@/components/math/KatexRenderer";
import { formatVariableTermLatex } from "@/lib/engine/variable-parenthesis"; import { formatVariableTermLatex } from "@/lib/engine/variable-parenthesis";
import type { VariableParenthesisProblem } from "@/lib/engine/variable-types";
import { import {
useVariableGameStore, useVariableGameStore,
type VariableMaxTermCount, type VariableMaxTermCount,
type VariableProblemCount, type VariableProblemCount,
} from "@/store/variableGameStore"; } from "@/store/variableGameStore";
const ACTIVE_TERM_COLOR = "#f97316";
function highlightLatex(latex: string) {
return `\\textcolor{${ACTIVE_TERM_COLOR}}{${latex}}`;
}
function formatActiveTermProblemLatex(
problem: VariableParenthesisProblem,
activeTermIndex: number,
) {
const termLatex = problem.terms
.map((term, index) => {
const displayTerm =
index === activeTermIndex
? highlightLatex(formatVariableTermLatex(term))
: formatVariableTermLatex(term);
if (index === 0) return displayTerm;
return `${problem.operators[index - 1]} ${displayTerm}`;
})
.join(" ");
return `${highlightLatex(`${problem.multiplier}`)}${highlightLatex(
"(",
)}${termLatex}${highlightLatex(")")}`;
}
interface VariablePlayClientProps { interface VariablePlayClientProps {
problemCount: VariableProblemCount; problemCount: VariableProblemCount;
maxTermCount: VariableMaxTermCount; maxTermCount: VariableMaxTermCount;
@@ -156,6 +185,9 @@ export default function VariablePlayClient({
const submitted = currentResult !== null; const submitted = currentResult !== null;
const isLastProblem = session.currentIndex === session.problems.length - 1; const isLastProblem = session.currentIndex === session.problems.length - 1;
const problemLatex = submitted
? currentProblem.latexBefore
: formatActiveTermProblemLatex(currentProblem, activeTermIndex);
const pendingChoiceLabels = currentProblem.terms.map((term, index) => const pendingChoiceLabels = currentProblem.terms.map((term, index) =>
formatVariableTermLatex({ formatVariableTermLatex({
...term, ...term,
@@ -189,7 +221,7 @@ export default function VariablePlayClient({
<div className="rounded-md bg-white px-6 pt-6 pb-4 shadow-sm ring-1 ring-slate-200 sm:p-8"> <div className="rounded-md bg-white px-6 pt-6 pb-4 shadow-sm ring-1 ring-slate-200 sm:p-8">
<div className="text-3xl font-semibold text-slate-950 sm:text-4xl"> <div className="text-3xl font-semibold text-slate-950 sm:text-4xl">
<KatexRenderer latex={currentProblem.latexBefore} displayMode /> <KatexRenderer latex={problemLatex} displayMode />
</div> </div>
<div className="mt-6"> <div className="mt-6">
<StageIndicator <StageIndicator