AI PLAY玩法更新持续收录
← 回到更新流

2026-10-15 · 原文发布日

把LaTeX存进网址:可分享的在线渲染器

Simon Willison受Tiny Little Office启发,用Claude Code做了一个纯网页LaTeX渲染器:粘贴或从URL、Gist载入源码,编辑器与渲染视图可切换,单条公式走MathJax、整篇文档走faster-latex。所有内容编码进URL的#fragment,渲染结果本身就是可收藏、可分享的链接,文中还附了他逐条提需求的完整提示词和iframe沙箱防XSS思路。

原文要点

Simon Willison受Tiny Little Office启发,用Claude Code做了一个纯网页LaTeX渲染器:源码既可粘贴输入也可从URL或Gist载入,编辑/渲染视图可切换;单条公式用MathJax排版,整篇文档用faster-latex。所有内容编码进URL的#fragment,渲染页本身就是可分享链接;支持自定义压缩字典(Pako)缩短链接,并借鉴其SVG工具的iframe sandbox机制防XSS。文中列出依赖版本:Pako 2.1.0、MathJax 4.1.3、faster-latex 0.3.1、DOMPurify 3.4.16。

这次做成什么

照着做一个最小可用的单文件LaTeX渲染页:粘贴LaTeX→即时渲染→生成含源码的可分享URL;并给出一段可直接喂给AI编程助手的完整提示词,复刻原作者的提需求方式。

准备什么

  • 一个纯文本编辑器(如VS Code)和现代浏览器
  • 能访问CDN加载MathJax、Pako、DOMPurify(离线需自备库文件)
  • 本地静态服务器(如python -m http.server),避免file://下fetch受限

具体怎么做

  1. 新建单文件页面骨架

    创建latex-share.html,写编辑器textarea与渲染div两个区域,加一个“编辑/渲染”切换按钮;在head里用script标签从CDN引入MathJax、Pako、DOMPurify三个库。

  2. 实现源码进URL

    点“渲染”时取textarea内容,用pako.deflate压缩后经btoa转base64,拼成location.hash='#p:'+base64;页面加载时若hash以#p:开头则解压还原源码,若以#开头则按encodeURIComponent解码,再写入编辑器并触发渲染。

  3. 渲染并消毒

    把LaTeX源码交给MathJax排版(MathJax.typesetPromise),输出HTML先经DOMPurify.sanitize再写入渲染区,防止源码中夹带<script>之类的注入。

  4. 加iframe沙箱(可选加固)

    若想彻底隔离,可把渲染页放进<iframe sandbox="allow-scripts">,父页只通过postMessage传源码,仿照原文借用的SVG工具防护思路。

  5. 验证分享链路

    输入一段公式,点渲染,复制地址栏完整URL发给另一浏览器窗口打开,确认无需任何服务器存储即可还原同样渲染结果。

可直接复制的材料

最小可运行单文件latex-share.html

本站独立编写的精简示例,仅覆盖hash存取+MathJax+DOMPurify主链路;faster-latex整文档模式与自定义压缩字典未实现,如需请按原思路扩展。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>LaTeX分享渲染器</title>
<script src="https://cdn.jsdelivr.net/npm/pako@2.1.0/dist/pako.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.4.16/dist/purify.min.js"></script>
<script>
window.MathJax={tex:{inlineMath:[['$','$'],['\\(','\\)']]},svg:{fontCache:'global'}};
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@4.1.3/es5/tex-svg.js"></script>
</head>
<body>
<button id="toggle">切换渲染</button>
<textarea id="src" rows="8" cols="60" placeholder="粘贴LaTeX源码"></textarea>
<div id="out"></div>
<script>
const src=document.getElementById('src'),out=document.getElementById('out'),tg=document.getElementById('toggle');
function toHash(t){const c=pako.deflate(t);const b=btoa(String.fromCharCode(...c));location.hash='p:'+b;}
function fromHash(){const h=location.hash.slice(1);if(h.startsWith('p:')){const bin=atob(h.slice(2));const arr=Uint8Array.from(bin,c=>c.charCodeAt(0));return new TextDecoder().decode(pako.inflate(arr));}return decodeURIComponent(h);}
async function render(){toHash(src.value);const html=DOMPurify.sanitize(src.value);out.innerHTML=html;src.style.display='none';out.style.display='block';await MathJax.typesetPromise([out]);tg.textContent='编辑源码';}
tg.onclick=()=>{if(src.style.display==='none'){src.style.display='block';out.style.display='none';tg.textContent='切换渲染';}else{render();}};
if(location.hash.length>1){src.value=fromHash();render();}
</script>
</body>
</html>

给AI编程助手的复刻提示词

本站按原文公开的需求顺序改写的中文提示词,可直接粘贴给Claude Code等助手,逐条对应原文列出的几轮需求。

我要一个纯前端工具:可以用#片段链接(#后面接LaTeX代码)直接渲染该代码,排版效果要好;还要支持一个p:前缀,表示LaTeX先经deflate压缩再base64编码,以缩短链接。从CDN引入最合适的LaTeX渲染库(单条公式用MathJax,整篇文档可考虑WebAssembly方案)。无hash加载时显示编辑器,可粘贴LaTeX并切换到“渲染”视图,渲染视图本身要可收藏分享;从#片段链接打开时也要能切回编辑源码。渲染输出必须先经DOMPurify消毒;为防XSS,渲染区可放进iframe沙箱,参考既有SVG渲染项目的做法。再加一个从URL或GitHub Gist载入LaTeX源码的选项。

输入与输出示例

本站虚构演示,hash值为示意,未实际运行;实际base64取决于压缩结果。

输入

在编辑器粘贴:欧拉恒等式 $e^{i\pi}+1=0$ 被称为最美的公式。

对应输出

点“切换渲染”后地址栏变为 latex-share.html#p:eJxLTS5JLU5RyM...(示意base64),页面显示排版后的公式“e^{iπ}+1=0”与中文句子同行;把完整URL发到新窗口打开,无需服务器即还原同一渲染。

做完检查这些

  • 新开浏览器窗口粘贴分享链接,能直接看到渲染结果而不是编辑器空白页
  • 源码中含<script>alert(1)</script>时渲染页不弹窗,说明消毒生效
  • 无hash打开页面时出现编辑器且可正常切换到渲染视图
  • 地址栏hash以p:开头且长度明显短于encodeURIComponent直编码版本

容易卡住的地方

  • file://协议直接打开时部分浏览器限制CDN脚本或fetch,建议用本地静态服务器
  • MathJax排版是异步的,写入DOM后必须等typesetPromise完成再算渲染完成
  • base64含+/=字符,放hash前最好换成URL安全字符或在解码端兼容处理
  • 整篇LaTeX文档(含\documentclass)MathJax排不了,需引入faster-latex之类方案

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
LaTeX renderer
原作者
Simon Willison
原始发布日期
2026-10-15
来源
https://simonwillison.net/2026/Oct/15/latex/