"""HTML 美化:注入 MathJax / 样式 / 导航 / 统计""" import re import os import shutil import urllib.request # --- 常量 --- NAV = ('') STYLE = ('' '') MATHJAX_TAG = ('' '') ASSETS_DIR = os.path.expanduser('~/.hermes/mcp/assets') MATHJAX_FILE = os.path.join(ASSETS_DIR, 'tex-svg.js') MATHJAX_MIRROR = 'https://registry.npmmirror.com/mathjax/3.2.2/files/es5/tex-svg.js' def _fix_math(m): inner = (m.group(1).replace(' ', ' ').replace('&', '&') .replace('<', '<').replace('>', '>').replace(' ', ' ')) return r'\(' + re.sub(r'[ \t]{2,}', ' ', inner).strip() + r'\)' def clean_html(content: str, mathjax: bool = True) -> str: """原始 HTML → 加 MathJax + 导航 + 样式""" c = re.sub(r'^<\?xml[^>]*\?>\s*', '', content) c = re.sub(r']*>', '', c, count=1) c = re.sub(r'\\\((.*?)\\\)', _fix_math, c, flags=re.S) inject = STYLE + (MATHJAX_TAG if mathjax else '') c = c.replace('', inject + '', 1) if '' in c else inject + c m = re.search(r']*>', c, re.I) c = (c[:m.end()] + NAV + c[m.end():]) if m else (NAV + c) return c def stats(html: str) -> dict: """HTML 统计:字符 / 公式 / 图片 / 未包裹 LaTeX""" stripped = re.sub(r'\\\(.*?\\\)', '', html, flags=re.S) return { 'chars': len(html), 'formulas': len(re.findall(r'\\\(', html)), 'images': html.count(' str: """下载/复用 MathJax 离线文件 → 返回路径""" os.makedirs(ASSETS_DIR, exist_ok=True) if not os.path.exists(MATHJAX_FILE) or os.path.getsize(MATHJAX_FILE) < 500_000: urllib.request.urlretrieve(MATHJAX_MIRROR, MATHJAX_FILE) return MATHJAX_FILE def copy_mathjax_to(out_dir: str) -> str: """把 MathJax 复制到 out_dir,返回目标路径""" src = ensure_mathjax() dst = os.path.join(out_dir, 'tex-svg.js') shutil.copy(src, dst) return dst