fix: 작업실 채팅에 KaTeX 도입 — 앱 중 유일하게 수식 렌더러가 빠져 있었음
09-24 실측: "12MP $\times$ 60fps $\approx$ 수 Gbps"가 그대로 노출. 다른 앱들 (의사·법률·투자 등)은 전부 vendor katex + katex-inline.js를 실어 다음 앱들은 정상인데 작업실만 없었다. doctor-app과 동일 구성(스타일시트+3스크립트+ katex-inline.js)으로 도입하고 addMsg/스트리밍 완료 시 renderKatexIn 호출. renderMd의 유니코드 폴백(\times→× 등, 가격 "$19..$29" 보호)은 KaTeX가 없는 환경에서만 발동 — KaTeX 있으면 $...$를 그대로 남겨 renderKatexIn이 맡는다. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -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;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/vendor/katex/katex.min.css">
|
||||
<script src="/vendor/katex/katex.min.js"></script>
|
||||
<script src="/vendor/katex/auto-render.min.js"></script>
|
||||
<script src="/vendor/katex/mhchem.min.js"></script>
|
||||
<script src="../js/app/katex-inline.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -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,'<code>$1</code>')
|
||||
.replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>')
|
||||
.replace(/^#{1,3}\s+(.+)$/gm,'<h3>$1</h3>');
|
||||
// 인라인 수식 $...$ — 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;
|
||||
});
|
||||
}
|
||||
// 리스트 — 연속하는 [-*] 줄을 하나의 <ul>로 묶는다(항목별 <ul>이 따로 생기던 버그 수정).
|
||||
s=s.replace(/(^|\n)([-*]\s+.+(?:\n[-*]\s+.+)*)/g,(m,lead,grp)=>{
|
||||
const items=grp.split('\n').map(line=>'<li>'+line.replace(/^[-*]\s+/,'')+'</li>').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;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user