fix(exam-prep): normalize LaTeX in dashboard preview text
Recent-attempts widget on /exam-prep/:examKey was showing raw LaTeX
like '\dfrac{7}{9}' because stripPreview only removed HTML tags.
Now it also converts common LaTeX to readable unicode (fractions →
a/b, \sqrt → √, \cdot → ·, comparisons → ≤≥≠, Greek letters, etc.)
before truncating.
KaTeX rendering would be overkill for a 100-char preview row; this
just makes the existing text legible.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -796,13 +796,39 @@ router.get('/:examKey/dashboard', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
/* Lightweight preview: strip tags, normalize whitespace, truncate. */
|
||||
/* Lightweight preview: strip HTML, normalize LaTeX to readable unicode,
|
||||
collapse whitespace, truncate. Used in dashboard "recent attempts" rows
|
||||
where rendering KaTeX would be overkill but raw `$\dfrac{7}{9}$` is
|
||||
ugly. Matches the spirit of tag-exam-tasks.js#stripText. */
|
||||
function stripPreview(html) {
|
||||
const text = String(html || '')
|
||||
let text = String(html || '')
|
||||
.replace(/<svg[\s\S]*?<\/svg>/gi, '')
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/<[^>]+>/g, ' ');
|
||||
|
||||
// Common LaTeX → unicode/plain. Order matters: handle fractions/roots
|
||||
// before stripping bare backslash commands.
|
||||
text = text
|
||||
.replace(/\\d?frac\s*\{([^{}]+)\}\s*\{([^{}]+)\}/g, '$1/$2')
|
||||
.replace(/\\sqrt\s*\{([^{}]+)\}/g, '√($1)')
|
||||
.replace(/\\cdot/g, '·')
|
||||
.replace(/\\times/g, '×')
|
||||
.replace(/\\pm/g, '±')
|
||||
.replace(/\\mp/g, '∓')
|
||||
.replace(/\\leq?/g, '≤')
|
||||
.replace(/\\geq?/g, '≥')
|
||||
.replace(/\\neq/g, '≠')
|
||||
.replace(/\\approx/g, '≈')
|
||||
.replace(/\\infty/g, '∞')
|
||||
.replace(/\\pi/g, 'π')
|
||||
.replace(/\\alpha/g, 'α').replace(/\\beta/g, 'β').replace(/\\gamma/g, 'γ')
|
||||
.replace(/\\(?:left|right)/g, '')
|
||||
.replace(/\\[a-zA-Z]+\s*/g, ' ') // any remaining LaTeX command
|
||||
.replace(/[{}]/g, '') // leftover braces
|
||||
.replace(/\$+/g, '') // math delimiters
|
||||
.replace(/&[a-z]+;/gi, ' ') // html entities
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
|
||||
return text.length > 100 ? text.slice(0, 100) + '…' : text;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user