适用AI的LaTeX公式格式转换工具

将LaTeX公式格式转换为Markdown格式

  1. // ==UserScript==
  2. // @name 适用AI的LaTeX公式格式转换工具
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0
  5. // @description 将LaTeX公式格式转换为Markdown格式
  6. // @author 榛铭
  7. // @match https://tongyi.aliyun.com/qianwen/*
  8. // @match https://chat.openai.com/*
  9. // @match https://kimi.moonshot.cn/*
  10. // @match https://chatgpt.com/**
  11. // @grant GM_addStyle
  12. // @license MIT
  13. // ==/UserScript==
  14. (function() {
  15. 'use strict';
  16. // 添加 Font Awesome
  17. document.head.appendChild(Object.assign(document.createElement('link'), {
  18. rel: 'stylesheet',
  19. href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css'
  20. }));
  21. // 添加基础样式
  22. GM_addStyle(`
  23. #formula-converter {
  24. position: fixed;
  25. top: 20vh;
  26. right: 0;
  27. background: white;
  28. border: 1px solid #ccc;
  29. border-radius: 8px;
  30. padding: 15px;
  31. width: 500px;
  32. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  33. z-index: 9999;
  34. font-family: Arial, sans-serif;
  35. max-height: 90vh;
  36. display: flex;
  37. flex-direction: column;
  38. transition: width 0.3s ease, height 0.3s ease, padding 0.3s ease;
  39. }
  40. #formula-converter textarea {
  41. width: 100%;
  42. height: 150px;
  43. margin: 10px 0;
  44. padding: 8px;
  45. border: 1px solid #ddd;
  46. border-radius: 4px;
  47. resize: vertical;
  48. }
  49. #formula-converter button {
  50. background: #4CAF50;
  51. color: white;
  52. border: none;
  53. padding: 8px 15px;
  54. border-radius: 4px;
  55. cursor: pointer;
  56. margin: 5px;
  57. display: inline-flex;
  58. align-items: center;
  59. gap: 5px;
  60. }
  61. #formula-converter button:hover {
  62. background: #45a049;
  63. }
  64. #formula-converter .header {
  65. display: flex;
  66. justify-content: space-between;
  67. align-items: center;
  68. margin-bottom: 10px;
  69. }
  70. #formula-converter .minimize-btn {
  71. background: none;
  72. border: none;
  73. color: #666;
  74. padding: 8px;
  75. margin: 0;
  76. border-radius: 50%;
  77. width: 32px;
  78. height: 32px;
  79. display: flex;
  80. align-items: center;
  81. justify-content: center;
  82. }
  83. #formula-converter .minimize-btn:hover {
  84. background: #f0f0f0;
  85. color: #333;
  86. }
  87. #formula-converter .output {
  88. margin-top: 10px;
  89. padding: 8px;
  90. background: #f5f5f5;
  91. border-radius: 4px;
  92. white-space: pre-wrap;
  93. max-height: 200px;
  94. overflow-y: auto;
  95. }
  96. #formula-converter.minimized {
  97. width: 48px;
  98. height: 48px;
  99. padding: 0;
  100. border-radius: 50%;
  101. border: none;
  102. }
  103. #formula-converter.minimized .converter-content,
  104. #formula-converter.minimized .header span {
  105. display: none;
  106. }
  107. #formula-converter.minimized .minimize-btn {
  108. width: 100%;
  109. height: 100%;
  110. display: flex;
  111. align-items: center;
  112. justify-content: center;
  113. background: none;
  114. border-radius: 50%;
  115. }
  116. .toast {
  117. position: fixed;
  118. bottom: 80px;
  119. right: 20px;
  120. padding: 10px 20px;
  121. background: rgba(0,0,0,0.8);
  122. color: white;
  123. border-radius: 4px;
  124. display: none;
  125. z-index: 10000;
  126. }
  127. `);
  128. // 创建转换器界面
  129. const converterHTML = `
  130. <div id="formula-converter">
  131. <div class="header">
  132. <span>公式转换工具</span>
  133. <button class="minimize-btn" title="最小化/展开">
  134. <i class="fas fa-minus"></i>
  135. </button>
  136. </div>
  137. <div class="converter-content">
  138. <textarea placeholder="在此输入带有公式的文本..."></textarea>
  139. <div class="button-group">
  140. <button class="convert-btn" title="转换LaTeX公式">
  141. <i class="fas fa-exchange-alt"></i>
  142. 转换
  143. </button>
  144. <button class="copy-btn" title="复制转换结果">
  145. <i class="fas fa-copy"></i>
  146. 复制结果
  147. </button>
  148. <button class="clear-btn" title="清空入">
  149. <i class="fas fa-trash"></i>
  150. 清空
  151. </button>
  152. </div>
  153. <div class="output"></div>
  154. </div>
  155. <div class="toast">已复制到剪贴板!</div>
  156. </div>
  157. `;
  158. // 添加到页面
  159. document.body.insertAdjacentHTML('beforeend', converterHTML);
  160. // 获取元素
  161. const elements = {
  162. converter: document.getElementById('formula-converter'),
  163. minimizeBtn: document.querySelector('#formula-converter .minimize-btn'),
  164. textarea: document.querySelector('#formula-converter textarea'),
  165. convertBtn: document.querySelector('#formula-converter .convert-btn'),
  166. copyBtn: document.querySelector('#formula-converter .copy-btn'),
  167. output: document.querySelector('#formula-converter .output'),
  168. toast: document.querySelector('#formula-converter .toast'),
  169. clearBtn: document.querySelector('#formula-converter .clear-btn')
  170. };
  171. // 初始化为最小化状态
  172. elements.converter.classList.add('minimized');
  173. elements.minimizeBtn.innerHTML = `
  174. <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512" width="24" height="24">
  175. <g>
  176. <g>
  177. <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"/>
  178. <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"/>
  179. <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"/>
  180. <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"/>
  181. <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"/>
  182. <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"/>
  183. <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"/>
  184. </g>
  185. <g>
  186. <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"/>
  187. </g>
  188. </g>
  189. </svg>
  190. `;
  191. // 转换函数
  192. function convertFormula(text) {
  193. return text
  194. .replace(/\\\((.+?)\\\)/g, '$$$1$')
  195. .replace(/(\s*)\\\[([\s\S]*?)\\\]/g, (_, indent, formula) =>
  196. `${indent}$$${formula.trim()}$$`
  197. );
  198. }
  199. // 显示提示
  200. const showToast = () => {
  201. elements.toast.style.display = 'block';
  202. setTimeout(() => elements.toast.style.display = 'none', 2000);
  203. };
  204. // 事件监听
  205. elements.minimizeBtn.addEventListener('click', () => {
  206. const isMinimized = elements.converter.classList.toggle('minimized');
  207. elements.minimizeBtn.innerHTML = isMinimized
  208. ? `<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512" width="24" height="24">
  209. <g>
  210. <g>
  211. <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"/>
  212. <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"/>
  213. <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"/>
  214. <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"/>
  215. <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"/>
  216. <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"/>
  217. <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"/>
  218. </g>
  219. <g>
  220. <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"/>
  221. </g>
  222. </g>
  223. </svg>`
  224. : `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512">
  225. <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"/>
  226. </svg>`;
  227. });
  228. elements.convertBtn.addEventListener('click', () => {
  229. elements.output.textContent = convertFormula(elements.textarea.value);
  230. });
  231. elements.copyBtn.addEventListener('click', () => {
  232. navigator.clipboard.writeText(elements.output.textContent)
  233. .then(showToast)
  234. .catch(() => alert('复制失败,请手动复制'));
  235. });
  236. elements.clearBtn.addEventListener('click', () => {
  237. elements.textarea.value = '';
  238. });
  239. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址