From 4b23d768f29476fdec66004a7db819ab545f4f8b Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Mon, 15 Jun 2026 12:05:47 +0300 Subject: [PATCH] =?UTF-8?q?fix(ct-math):=20=D0=BB=D0=B8=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=83=D0=B3=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D0=B5=20=D1=81=D0=BA=D0=BE=D0=B1=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B2=20=D1=84=D0=BE=D1=80=D0=BC=D1=83=D0=BB=D0=B0=D1=85=20?= =?UTF-8?q?=D1=83=D1=80=D0=BE=D0=BA=D0=BE=D0=B2=20=D0=BB=D0=BE=D0=BC=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=20KaTeX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Блок formula вставляет tex в HTML без экранирования, поэтому литеральная "меньше"-скобка (напр. в "0 le r lt d") принималась браузером за HTML-тег и формула не рендерилась (показывался сырой $$...$$). Заменено на \lt и \gt (KaTeX рендерит их как отношения). - seed_ctmath_lessons_rest.js: исправлены 4 формулы в исходнике (числа, модуль, показ/лог равносильности, производная-монотонность). - fix_ctmath_formula_lt.js: фикс уже залитых блоков курса 13 (dry/--apply). Флешкарты не затронуты (mathHtmlFC через textContent экранирует сам). Запись (UPDATE 4 блоков) запускает пользователь. Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/scripts/fix_ctmath_formula_lt.js | 29 +++++++++++++++++++++ backend/scripts/seed_ctmath_lessons_rest.js | 8 +++--- 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 backend/scripts/fix_ctmath_formula_lt.js diff --git a/backend/scripts/fix_ctmath_formula_lt.js b/backend/scripts/fix_ctmath_formula_lt.js new file mode 100644 index 0000000..789af86 --- /dev/null +++ b/backend/scripts/fix_ctmath_formula_lt.js @@ -0,0 +1,29 @@ +'use strict'; +/* + * Фикс: блок formula вставляет tex в HTML БЕЗ экранирования ($$...$$), поэтому + * литеральные '<' / '>' в формуле браузер принимает за HTML-тег → KaTeX не рендерит. + * Заменяем литеральные '<' → '\lt', '>' → '\gt' в tex всех formula-блоков курса 13 + * (KaTeX их рендерит как отношения). Идемпотентно. dry по умолчанию, запись --apply. + * node backend/scripts/fix_ctmath_formula_lt.js [--apply] + */ +const db = require('../src/db/db'); +const APPLY = process.argv.includes('--apply'); + +const rows = db.prepare(`SELECT lb.id, lb.lesson_id, lb.data FROM lesson_blocks lb + JOIN lessons l ON l.id=lb.lesson_id WHERE l.course_id=13 AND lb.type='formula'`).all(); + +const upd = db.prepare('UPDATE lesson_blocks SET data=? WHERE id=?'); +let changed = 0; +for (const r of rows) { + let d; try { d = JSON.parse(r.data); } catch { continue; } + if (!d.tex || !/[<>]/.test(d.tex)) continue; + const before = d.tex; + d.tex = d.tex.replace(//g, '\\gt '); + changed++; + console.log(`block ${r.id} (lesson ${r.lesson_id}):`); + console.log(' было:', before); + console.log(' стало:', d.tex); + if (APPLY) upd.run(JSON.stringify(d), r.id); +} +console.log(`\n${APPLY ? 'Обновлено' : '(dry) к обновлению'}: ${changed} формул.`); +if (!APPLY) console.log('Запись: --apply'); diff --git a/backend/scripts/seed_ctmath_lessons_rest.js b/backend/scripts/seed_ctmath_lessons_rest.js index 755d666..e2c97ee 100644 --- a/backend/scripts/seed_ctmath_lessons_rest.js +++ b/backend/scripts/seed_ctmath_lessons_rest.js @@ -27,7 +27,7 @@ const LESSONS = [ { section: 'Числа и вычисления', title: 'Числа, делимость и проценты', read: 8, blocks: [ H('Числа, делимость и проценты'), P('Действительные числа на координатной прямой нужно уметь оценивать и сравнивать. Деление с остатком записывается формулой ниже.'), - F('n = d\\cdot q + r,\\qquad 0\\le r0', 'Равносильные переходы'), + F('a^{f}=a^{g}\\Leftrightarrow f=g;\\qquad \\log_a f=\\log_a g\\Leftrightarrow f=g\\gt 0', 'Равносильные переходы'), F('\\sqrt{f}=g\\ \\Leftrightarrow\\ \\begin{cases}g\\ge0\\\\ f=g^2\\end{cases}', 'Иррациональное уравнение'), CI('Метод рационализации (для неравенств): знак $\\log_a f-\\log_a g$ совпадает со знаком $(a-1)(f-g)$; знак $a^{f}-a^{g}$ — со знаком $(a-1)(f-g)$. Экономит время на сложных неравенствах.'), CW('В логарифмических всегда выписывайте ОДЗ: аргумент $>0$, основание $>0$ и $\\ne1$.'), @@ -99,7 +99,7 @@ const LESSONS = [ H('Функции: свойства, графики, производная'), P('Ключевые свойства: ОДЗ, чётность (если $f(-x)=f(x)$ — чётная, график симметричен относительно $Oy$; если $f(-x)=-f(x)$ — нечётная), монотонность, нули.'), SIM('graphtransform', 'Преобразования графиков: сдвиги и растяжения'), - F('f\'>0\\Rightarrow\\text{возрастает};\\quad f\'<0\\Rightarrow\\text{убывает};\\quad f\'=0\\ \\text{со сменой знака}\\Rightarrow\\text{экстремум}', 'Производная и поведение функции'), + F('f\'\\gt 0\\Rightarrow\\text{возрастает};\\quad f\'\\lt 0\\Rightarrow\\text{убывает};\\quad f\'=0\\ \\text{со сменой знака}\\Rightarrow\\text{экстремум}', 'Производная и поведение функции'), H('Разбор В2 (квадратичная)', 3), P('$f(x)=x^2-6x+5$: нули $1$ и $5$ (их сумма $6$); $f(0)=5$; вершина при $x=3$, наименьшее значение $f(3)=-4$.'), CS('Сумма нулей $=6$; наименьшее значение $=-4$.'),