');
+ // 인라인 수식 $...$ — KaTeX가 실려 있으면 삽입 직후 renderKatexIn이 진짜 수식으로
+ // 그려주므로 그냥 둔다(09-24: 다른 앱들은 전부 KaTeX 실려 있었는데 작업실만 빠져 있었다).
+ // KaTeX가 없는 환경의 폴백으로만 이 유니코드 치환을 돌린다. 자주 나오는 LaTeX 기호를
+ // 유니코드로 바꾸고 $를 벗긴다. 내용에 백슬래시(LaTeX 명령)가 없으면 건드리지 않는다 —
+ // 가격 "$19 ... $29" 짝을 수식으로 먹어버리는 사고 방지([[reference_katex_math_rendering]]).
+ if(!(typeof window!=='undefined' && typeof renderKatexIn==='function' && window.katex)){
+ s=s.replace(/\$([^$\n]*\\[^$\n]*)\$/g,(m,body)=>{
+ let t=body;
+ t=t.replace(/\\(?:text|mathrm|mathbf)\s*\{([^{}]*)\}/g,'$1');
+ t=t.replace(/\\times/g,'×').replace(/\\approx/g,'≈').replace(/\\sim/g,'~')
+ .replace(/\\pm/g,'±').replace(/\\cdot/g,'·').replace(/\\le(?:q)?\b/g,'≤')
+ .replace(/\\ge(?:q)?\b/g,'≥').replace(/\\neq?\b/g,'≠')
+ .replace(/\\to\b|\\rightarrow\b/g,'→').replace(/\\leftarrow\b/g,'←')
+ .replace(/\\deg(ree)?\b/g,'°').replace(/\\mu\b/g,'μ').replace(/\\%/g,'%');
+ t=t.replace(/\\[a-zA-Z]+/g,'').replace(/\\([{}])/g,'$1').trim();
+ return t;
+ });
+ }
// 리스트 — 연속하는 [-*] 줄을 하나의
로 묶는다(항목별
이 따로 생기던 버그 수정).
s=s.replace(/(^|\n)([-*]\s+.+(?:\n[-*]\s+.+)*)/g,(m,lead,grp)=>{
const items=grp.split('\n').map(line=>'
'+line.replace(/^[-*]\s+/,'')+'
').join('');
@@ -1417,7 +1441,7 @@ async function callChat(message){
let ev;try{ev=JSON.parse(part.slice(6));}catch{continue;}
if(ev.type==='token'||ev.type==='text_delta'){
textBuf+=(ev.text||'');
- if(bubble){bubble.innerHTML=renderMd(textBuf);msgs.scrollTop=msgs.scrollHeight;}
+ if(bubble){bubble.innerHTML=renderMd(textBuf);if(typeof renderKatexIn==='function')renderKatexIn(bubble);msgs.scrollTop=msgs.scrollHeight;}
}
}
}