diff --git a/web-ui/html/workshop-app.html b/web-ui/html/workshop-app.html index 0353b05..9ac10b9 100644 --- a/web-ui/html/workshop-app.html +++ b/web-ui/html/workshop-app.html @@ -195,6 +195,11 @@ body{background:var(--bg);color:var(--text);font-family:system-ui,sans-serif;dis .rb-file-card:hover .rb-file-stl-sel,.rb-file-stl-sel:checked{opacity:1;} .rb-file-card.stl-selected{outline:2px solid #f59e0b;outline-offset:-1px;} + + + + + @@ -1314,6 +1319,7 @@ function addMsg(role,html){ const msgs=document.getElementById('chat-msgs'); const div=document.createElement('div');div.className='rb-msg '+role; const b=document.createElement('div');b.className='rb-bubble';b.innerHTML=html; + if(typeof renderKatexIn==='function')renderKatexIn(b); div.appendChild(b); msgs.appendChild(div);msgs.scrollTop=msgs.scrollHeight; return b; @@ -1332,6 +1338,24 @@ function renderMd(text){ s=s.replace(/`([^`]+)`/g,'$1') .replace(/\*\*(.+?)\*\*/g,'$1') .replace(/^#{1,3}\s+(.+)$/gm,'

$1

'); + // 인라인 수식 $...$ — 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; + }); + } // 리스트 — 연속하는 [-*] 줄을 하나의