5381679c68
Зафиксирована накопленная незакоммиченная работа рабочего дерева, КРОМЕ файлов учебника «Химия 7» (migration 046, chemistry_7_*.html, chem7_svg.js, тест — оставлены незакоммиченными по запросу). Включает: модуль биохимии (ядро BIO, 3D VSEPR, химдвижок, баланс, challenges, пути из БД), System Health Level 1 (вердикт/мониторинг), а также frontend- страницы и lab/textbooks-правки параллельной сессии. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
86 lines
4.1 KiB
JavaScript
86 lines
4.1 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const dir = path.join(__dirname, '..', '..', 'frontend', 'textbooks');
|
|
const files = ['geometry_10_hub.html','geometry_10_r1.html','geometry_10_r2.html','geometry_10_r3.html','geometry_10_r4.html'];
|
|
|
|
const cmds = ['dfrac','sqrt','sin','cos','tan','angle','vec','triangle','Rightarrow','cdot','ne','le','ge','pi','alpha','beta','gamma','delta','varphi','circ','perp','parallel','frac','tfrac','overline','left','right','begin','end','boxed','cot','arcsin','arccos','arctan','log','ln','lim','sum','int','infty','Delta','theta','lambda','mu','rho','sigma','tau','omega','Omega','phi','psi','xi','zeta','eta','epsilon','varepsilon','Pi','Sigma','approx','equiv','pm','mp','times','div','leq','geq','neq','sim','cong','subset','supset','cup','cap','forall','exists','overrightarrow','overleftarrow','widehat','widetilde','mathbf','mathrm','mathbb','mathcal','quad','qquad','hline','cline','displaystyle','textstyle','scriptstyle','underline','operatorname','land','lor','lnot','mapsto','Leftrightarrow','Leftarrow','leftarrow','rightarrow','uparrow','downarrow','prime','colon'];
|
|
|
|
for (const f of files) {
|
|
const fp = path.join(dir, f);
|
|
if (!fs.existsSync(fp)) { console.log('MISSING', f); continue; }
|
|
const txt = fs.readFileSync(fp, 'utf8');
|
|
|
|
const scriptRe = /<script(?![^>]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/g;
|
|
let m;
|
|
let totalKatexErrs = 0;
|
|
const errSamples = [];
|
|
let scriptBlocks = 0;
|
|
let combinedJs = '';
|
|
|
|
while ((m = scriptRe.exec(txt)) !== null) {
|
|
scriptBlocks++;
|
|
const body = m[1];
|
|
combinedJs += body + ';\n';
|
|
const cmdRe = /(^|[^\\])\\([a-zA-Z]+)/g;
|
|
let cm;
|
|
while ((cm = cmdRe.exec(body)) !== null) {
|
|
const cmd = cm[2];
|
|
if (cmds.includes(cmd)) {
|
|
totalKatexErrs++;
|
|
const idxAbs = m.index + cm.index + cm[1].length;
|
|
const before = txt.slice(0, idxAbs);
|
|
const line = (before.match(/\n/g) || []).length + 1;
|
|
if (errSamples.length < 10) errSamples.push({line, cmd, ctx: body.slice(Math.max(0,cm.index-30), cm.index+50).replace(/\n/g,' ')});
|
|
}
|
|
}
|
|
}
|
|
|
|
// <option> raw KaTeX
|
|
const optRe = /<option[^>]*>([\s\S]*?)<\/option>/g;
|
|
let om;
|
|
let optionRaw = 0;
|
|
const optionSamples = [];
|
|
while ((om = optRe.exec(txt)) !== null) {
|
|
const content = om[1];
|
|
if (/\$[^\$]+\$/.test(content) || /\\(dfrac|sqrt|frac|angle|vec|sin|cos|alpha|beta|pi|circ|triangle|Rightarrow)/.test(content)) {
|
|
optionRaw++;
|
|
const before = txt.slice(0, om.index);
|
|
const line = (before.match(/\n/g) || []).length + 1;
|
|
if (optionSamples.length < 8) optionSamples.push({line, content: content.slice(0,90)});
|
|
}
|
|
}
|
|
|
|
// Emoji
|
|
const emojiRe = /[\u{1F300}-\u{1FAFF}\u{1F000}-\u{1F02F}\u{2700}-\u{27BF}\u{2600}-\u{26FF}]/gu;
|
|
let em;
|
|
let emoji = 0;
|
|
const emojiSamples = [];
|
|
while ((em = emojiRe.exec(txt)) !== null) {
|
|
emoji++;
|
|
const before = txt.slice(0, em.index);
|
|
const line = (before.match(/\n/g) || []).length + 1;
|
|
if (emojiSamples.length < 10) emojiSamples.push({line, ch: em[0], cp: em[0].codePointAt(0).toString(16), ctx: txt.slice(Math.max(0,em.index-25), em.index+25).replace(/\n/g,' ')});
|
|
}
|
|
|
|
let authors = [];
|
|
if (f.includes('hub')) {
|
|
for (const a of ['Латотин','Чеботаревский','Горбунова','Шлыков']) {
|
|
if (txt.includes(a)) authors.push(a);
|
|
}
|
|
}
|
|
|
|
let parseErr = null;
|
|
try { new Function(combinedJs); } catch(e) { parseErr = e.message.slice(0,200); }
|
|
|
|
console.log('=== ' + f + ' ===');
|
|
console.log(' size:', txt.length, 'scripts:', scriptBlocks);
|
|
console.log(' KaTeX single-backslash errors:', totalKatexErrs);
|
|
for (const s of errSamples) console.log(' line ' + s.line + ' \\' + s.cmd + ' ctx: ' + s.ctx);
|
|
console.log(' <option> raw KaTeX:', optionRaw);
|
|
for (const s of optionSamples) console.log(' line ' + s.line + ': ' + s.content);
|
|
console.log(' Emoji symbols:', emoji);
|
|
for (const s of emojiSamples) console.log(' line ' + s.line + ' U+' + s.cp + ' ctx: ' + s.ctx);
|
|
if (authors.length) console.log(' Authors in hub:', authors.join(', '));
|
|
console.log(' JS parse:', parseErr ? 'ERROR: ' + parseErr : 'OK');
|
|
}
|