// ==UserScript==
// @name 适用AI的LaTeX公式格式转换工具
// @namespace http://tampermonkey.net/
// @version 2.0
// @description 将LaTeX公式格式转换为Markdown格式
// @author 榛铭
// @match https://tongyi.aliyun.com/qianwen/*
// @match https://chat.openai.com/*
// @match https://kimi.moonshot.cn/*
// @match https://chatgpt.com/**
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 添加 Font Awesome
document.head.appendChild(Object.assign(document.createElement('link'), {
rel: 'stylesheet',
href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css'
}));
// 添加基础样式
GM_addStyle(`
#formula-converter {
position: fixed;
top: 20vh;
right: 0;
background: white;
border: 1px solid #ccc;
border-radius: 8px;
padding: 15px;
width: 500px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
z-index: 9999;
font-family: Arial, sans-serif;
max-height: 90vh;
display: flex;
flex-direction: column;
transition: width 0.3s ease, height 0.3s ease, padding 0.3s ease;
}
#formula-converter textarea {
width: 100%;
height: 150px;
margin: 10px 0;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
}
#formula-converter button {
background: #4CAF50;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
display: inline-flex;
align-items: center;
gap: 5px;
}
#formula-converter button:hover {
background: #45a049;
}
#formula-converter .header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
#formula-converter .minimize-btn {
background: none;
border: none;
color: #666;
padding: 8px;
margin: 0;
border-radius: 50%;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
#formula-converter .minimize-btn:hover {
background: #f0f0f0;
color: #333;
}
#formula-converter .output {
margin-top: 10px;
padding: 8px;
background: #f5f5f5;
border-radius: 4px;
white-space: pre-wrap;
max-height: 200px;
overflow-y: auto;
}
#formula-converter.minimized {
width: 48px;
height: 48px;
padding: 0;
border-radius: 50%;
border: none;
}
#formula-converter.minimized .converter-content,
#formula-converter.minimized .header span {
display: none;
}
#formula-converter.minimized .minimize-btn {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: none;
border-radius: 50%;
}
.toast {
position: fixed;
bottom: 80px;
right: 20px;
padding: 10px 20px;
background: rgba(0,0,0,0.8);
color: white;
border-radius: 4px;
display: none;
z-index: 10000;
}
`);
// 创建转换器界面
const converterHTML = `
<div id="formula-converter">
<div class="header">
<span>公式转换工具</span>
<button class="minimize-btn" title="最小化/展开">
<i class="fas fa-minus"></i>
</button>
</div>
<div class="converter-content">
<textarea placeholder="在此输入带有公式的文本..."></textarea>
<div class="button-group">
<button class="convert-btn" title="转换LaTeX公式">
<i class="fas fa-exchange-alt"></i>
转换
</button>
<button class="copy-btn" title="复制转换结果">
<i class="fas fa-copy"></i>
复制结果
</button>
<button class="clear-btn" title="清空入">
<i class="fas fa-trash"></i>
清空
</button>
</div>
<div class="output"></div>
</div>
<div class="toast">已复制到剪贴板!</div>
</div>
`;
// 添加到页面
document.body.insertAdjacentHTML('beforeend', converterHTML);
// 获取元素
const elements = {
converter: document.getElementById('formula-converter'),
minimizeBtn: document.querySelector('#formula-converter .minimize-btn'),
textarea: document.querySelector('#formula-converter textarea'),
convertBtn: document.querySelector('#formula-converter .convert-btn'),
copyBtn: document.querySelector('#formula-converter .copy-btn'),
output: document.querySelector('#formula-converter .output'),
toast: document.querySelector('#formula-converter .toast'),
clearBtn: document.querySelector('#formula-converter .clear-btn')
};
// 初始化为最小化状态
elements.converter.classList.add('minimized');
elements.minimizeBtn.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512" width="24" height="24">
<g>
<g>
<path style="fill:#5596FB;" d="M441,61H341c-5.522,0-10,4.478-10,10s4.478,10,10,10h100c5.514,0,10,4.486,10,10v220 c0,5.514-4.486,10-10,10H71c-5.514,0-10-4.486-10-10V91c0-5.514,4.486-10,10-10h100c5.522,0,10-4.478,10-10s-4.478-10-10-10H71 c-16.542,0-30,13.458-30,30v220c0,16.542,13.458,30,30,30h370c16.542,0,30-13.458,30-30V91C471,74.458,457.542,61,441,61z"/>
<path style="fill:#5596FB;" d="M181,246h-20c-5.522,0-10,4.478-10,10s4.478,10,10,10h20c5.522,0,10-4.478,10-10 S186.522,246,181,246z"/>
<path style="fill:#5596FB;" d="M161,206c-5.522,0-10,4.478-10,10s4.478,10,10,10h20c5.522,0,10-4.478,10-10s-4.478-10-10-10H161z"/>
<path style="fill:#5596FB;" d="M121,206c5.522,0,10-4.478,10-10s-4.478-10-10-10H91c-5.522,0-10,4.478-10,10v80 c0,5.522,4.478,10,10,10h30c5.522,0,10-4.478,10-10s-4.478-10-10-10h-20v-20h20c5.522,0,10-4.478,10-10s-4.478-10-10-10h-20v-20 H121z"/>
<path style="fill:#5596FB;" d="M221,286c5.522,0,10-4.478,10-10v-35c0-8.271,6.729-15,15-15s15,6.729,15,15v35 c0,5.522,4.478,10,10,10s10-4.478,10-10v-35c0-8.271,6.729-15,15-15s15,6.729,15,15v35c0,5.522,4.478,10,10,10s10-4.478,10-10 v-35c0-19.299-15.701-35-35-35c-9.786,0-18.642,4.042-25,10.539c-10.807-11.043-26.954-13.371-40-7.159V206 c0-5.522-4.478-10-10-10s-10,4.478-10,10v70C211,281.522,215.478,286,221,286z"/>
<path style="fill:#5596FB;" d="M358.574,275.749c13.646,13.646,35.849,13.646,49.497,0c3.905-3.905,3.905-10.237,0-14.143 c-3.906-3.904-10.236-3.904-14.143,0c-5.846,5.85-15.363,5.849-21.213,0c-5.849-5.849-5.849-15.364-0.001-21.213 c5.85-5.849,15.366-5.848,21.214,0c3.906,3.904,10.236,3.904,14.143,0c3.905-3.905,3.905-10.237,0-14.143 c-13.647-13.646-35.851-13.646-49.498,0C344.927,239.897,344.927,262.103,358.574,275.749z"/>
<path style="fill:#5596FB;" d="M407,154l-32,24c-3.443,2.583-4.848,7.079-3.487,11.162c1.361,4.084,5.183,6.838,9.487,6.838h40 c5.522,0,10-4.478,10-10s-4.478-10-10-10h-10l8-6c7.514-5.636,12-14.607,12-24c0-16.542-13.458-30-30-30s-30,13.458-30,30 c0,5.522,4.478,10,10,10s10-4.478,10-10c0-5.514,4.486-10,10-10s10,4.486,10,10C411,149.131,409.505,152.121,407,154z"/>
</g>
<g>
<path style="fill:#283954;" d="M461,21H349.28C345.152,9.361,334.036,1,321,1H191c-13.036,0-24.152,8.361-28.28,20H51 C23.43,21,1,43.43,1,71v260c0,27.57,22.43,50,50,50h61.461l-28.055,91.178C78.466,491.485,92.875,511,113.079,511h18.149 c13.253,0,24.775-8.511,28.673-21.178L165.693,471h180.614l5.792,18.822c3.897,12.667,15.42,21.178,28.673,21.178h18.149 c20.199,0,34.614-19.511,28.673-38.822L399.539,381H461c27.57,0,50-22.43,50-50V71C511,43.43,488.57,21,461,21z M191,21h130 c5.514,0,10,4.486,10,10v40c0,5.514-4.486,10-10,10H191c-5.514,0-10-4.486-10-10V31C181,25.486,185.486,21,191,21z M131.229,491 h-18.149c-6.734,0-11.537-6.504-9.558-12.941L133.386,381h39.074c-3.407,11.073-28.244,91.793-31.674,102.941 C139.487,488.163,135.646,491,131.229,491z M318.615,381l9.231,30H184.155l9.231-30H318.615z M171.847,451l6.154-20h155.999 l6.154,20H171.847z M408.479,478.059c1.979,6.436-2.822,12.941-9.558,12.941h-18.149c-4.417,0-8.259-2.837-9.558-7.059 c-3.43-11.148-28.267-91.868-31.674-102.941h39.074L408.479,478.059z M491,331c0,16.542-13.458,30-30,30 c-49.548,0-84.553,0-135,0c-17.513,0-263.04,0-275,0c-16.542,0-30-13.458-30-30V71c0-16.542,13.458-30,30-30h110v30 c0,16.542,13.458,30,30,30h130c16.542,0,30-13.458,30-30V41h110c16.542,0,30,13.458,30,30V331z"/>
</g>
</g>
</svg>
`;
// 转换函数
function convertFormula(text) {
return text
.replace(/\\\((.+?)\\\)/g, '$$$1$')
.replace(/(\s*)\\\[([\s\S]*?)\\\]/g, (_, indent, formula) =>
`${indent}$$${formula.trim()}$$`
);
}
// 显示提示
const showToast = () => {
elements.toast.style.display = 'block';
setTimeout(() => elements.toast.style.display = 'none', 2000);
};
// 事件监听
elements.minimizeBtn.addEventListener('click', () => {
const isMinimized = elements.converter.classList.toggle('minimized');
elements.minimizeBtn.innerHTML = isMinimized
? `<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512" width="24" height="24">
<g>
<g>
<path style="fill:#5596FB;" d="M441,61H341c-5.522,0-10,4.478-10,10s4.478,10,10,10h100c5.514,0,10,4.486,10,10v220 c0,5.514-4.486,10-10,10H71c-5.514,0-10-4.486-10-10V91c0-5.514,4.486-10,10-10h100c5.522,0,10-4.478,10-10s-4.478-10-10-10H71 c-16.542,0-30,13.458-30,30v220c0,16.542,13.458,30,30,30h370c16.542,0,30-13.458,30-30V91C471,74.458,457.542,61,441,61z"/>
<path style="fill:#5596FB;" d="M181,246h-20c-5.522,0-10,4.478-10,10s4.478,10,10,10h20c5.522,0,10-4.478,10-10 S186.522,246,181,246z"/>
<path style="fill:#5596FB;" d="M161,206c-5.522,0-10,4.478-10,10s4.478,10,10,10h20c5.522,0,10-4.478,10-10s-4.478-10-10-10H161z"/>
<path style="fill:#5596FB;" d="M121,206c5.522,0,10-4.478,10-10s-4.478-10-10-10H91c-5.522,0-10,4.478-10,10v80 c0,5.522,4.478,10,10,10h30c5.522,0,10-4.478,10-10s-4.478-10-10-10h-20v-20h20c5.522,0,10-4.478,10-10s-4.478-10-10-10h-20v-20 H121z"/>
<path style="fill:#5596FB;" d="M221,286c5.522,0,10-4.478,10-10v-35c0-8.271,6.729-15,15-15s15,6.729,15,15v35 c0,5.522,4.478,10,10,10s10-4.478,10-10v-35c0-8.271,6.729-15,15-15s15,6.729,15,15v35c0,5.522,4.478,10,10,10s10-4.478,10-10 v-35c0-19.299-15.701-35-35-35c-9.786,0-18.642,4.042-25,10.539c-10.807-11.043-26.954-13.371-40-7.159V206 c0-5.522-4.478-10-10-10s-10,4.478-10,10v70C211,281.522,215.478,286,221,286z"/>
<path style="fill:#5596FB;" d="M358.574,275.749c13.646,13.646,35.849,13.646,49.497,0c3.905-3.905,3.905-10.237,0-14.143 c-3.906-3.904-10.236-3.904-14.143,0c-5.846,5.85-15.363,5.849-21.213,0c-5.849-5.849-5.849-15.364-0.001-21.213 c5.85-5.849,15.366-5.848,21.214,0c3.906,3.904,10.236,3.904,14.143,0c3.905-3.905,3.905-10.237,0-14.143 c-13.647-13.646-35.851-13.646-49.498,0C344.927,239.897,344.927,262.103,358.574,275.749z"/>
<path style="fill:#5596FB;" d="M407,154l-32,24c-3.443,2.583-4.848,7.079-3.487,11.162c1.361,4.084,5.183,6.838,9.487,6.838h40 c5.522,0,10-4.478,10-10s-4.478-10-10-10h-10l8-6c7.514-5.636,12-14.607,12-24c0-16.542-13.458-30-30-30s-30,13.458-30,30 c0,5.522,4.478,10,10,10s10-4.478,10-10c0-5.514,4.486-10,10-10s10,4.486,10,10C411,149.131,409.505,152.121,407,154z"/>
</g>
<g>
<path style="fill:#283954;" d="M461,21H349.28C345.152,9.361,334.036,1,321,1H191c-13.036,0-24.152,8.361-28.28,20H51 C23.43,21,1,43.43,1,71v260c0,27.57,22.43,50,50,50h61.461l-28.055,91.178C78.466,491.485,92.875,511,113.079,511h18.149 c13.253,0,24.775-8.511,28.673-21.178L165.693,471h180.614l5.792,18.822c3.897,12.667,15.42,21.178,28.673,21.178h18.149 c20.199,0,34.614-19.511,28.673-38.822L399.539,381H461c27.57,0,50-22.43,50-50V71C511,43.43,488.57,21,461,21z M191,21h130 c5.514,0,10,4.486,10,10v40c0,5.514-4.486,10-10,10H191c-5.514,0-10-4.486-10-10V31C181,25.486,185.486,21,191,21z M131.229,491 h-18.149c-6.734,0-11.537-6.504-9.558-12.941L133.386,381h39.074c-3.407,11.073-28.244,91.793-31.674,102.941 C139.487,488.163,135.646,491,131.229,491z M318.615,381l9.231,30H184.155l9.231-30H318.615z M171.847,451l6.154-20h155.999 l6.154,20H171.847z M408.479,478.059c1.979,6.436-2.822,12.941-9.558,12.941h-18.149c-4.417,0-8.259-2.837-9.558-7.059 c-3.43-11.148-28.267-91.868-31.674-102.941h39.074L408.479,478.059z M491,331c0,16.542-13.458,30-30,30 c-49.548,0-84.553,0-135,0c-17.513,0-263.04,0-275,0c-16.542,0-30-13.458-30-30V71c0-16.542,13.458-30,30-30h110v30 c0,16.542,13.458,30,30,30h130c16.542,0,30-13.458,30-30V41h110c16.542,0,30,13.458,30,30V331z"/>
</g>
</g>
</svg>`
: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512">
<path fill="currentColor" d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/>
</svg>`;
});
elements.convertBtn.addEventListener('click', () => {
elements.output.textContent = convertFormula(elements.textarea.value);
});
elements.copyBtn.addEventListener('click', () => {
navigator.clipboard.writeText(elements.output.textContent)
.then(showToast)
.catch(() => alert('复制失败,请手动复制'));
});
elements.clearBtn.addEventListener('click', () => {
elements.textarea.value = '';
});
})();