复制ChatGPT的LaTex公式(Word文档专用)

双击网页中的LaTeX公式,将其复制到剪切板,粘贴到Word文档中自动转为公式编辑器

  1. // ==UserScript==
  2. // @name 复制ChatGPT的LaTex公式(Word文档专用)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1.1
  5. // @license GPLv3
  6. // @description 双击网页中的LaTeX公式,将其复制到剪切板,粘贴到Word文档中自动转为公式编辑器
  7. // @description:en Double click the LaTeX formula in the webpage, copy it to the clipboard, paste it into a Word document, and it will automatically convert to a formula editor
  8. // @author Chsengni
  9. // @match *://*.wikipedia.org/*
  10. // @match *://*.zhihu.com/*
  11. // @match *://*.chatgpt.com/*
  12. // @match *://*.moonshot.cn/*
  13. // @match *://*.stackexchange.com/*
  14. // @require https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. // 插入样式表
  21. const css = `
  22. .latex-tooltip { position: fixed; background-color: rgba(0, 0, 0, 0.7); color: #fff; padding: 5px 10px; border-radius: 5px; font-size: 11px; z-index: 1000; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
  23. .latex-copy-success { position: fixed; bottom: 10%; left: 50%; transform: translateX(-50%); background-color: rgba(0, 0, 0, 0.7); color: #fff; padding: 10px 20px; border-radius: 5px; font-size: 12px; z-index: 1000; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
  24. `;
  25. const styleSheet = document.createElement("style");
  26. styleSheet.type = "text/css";
  27. styleSheet.innerText = css;
  28. document.head.appendChild(styleSheet);
  29.  
  30. // 创建提示框元素
  31. const tooltip = document.createElement('div');
  32. tooltip.classList.add('latex-tooltip');
  33. document.body.appendChild(tooltip);
  34.  
  35. // 创建复制功能
  36. function copyToClip(text) {
  37. const input = document.createElement("input");
  38. input.setAttribute("value", text);
  39. document.body.appendChild(input);
  40. input.select();
  41. document.execCommand("copy");
  42. document.body.removeChild(input);
  43. }
  44.  
  45. // 创建 LaTeX 复制功能
  46. function copyMLToClip(latexInput) {
  47. // Reset MathJax
  48. MathJax.texReset();
  49. // Convert LaTeX to MathML
  50. MathJax.tex2mmlPromise(latexInput).then(function(mathML) {
  51. // Copy the MathML to clipboard
  52. copyToClip(mathML);
  53. showCopySuccessTooltip();
  54. }).catch(function(error) {
  55. console.error(error);
  56. });
  57. }
  58.  
  59. // 获取对象和公式方法
  60. function getTarget(url) {
  61. const targets = {
  62. 'wikipedia.org': { elementSelector: 'span.mwe-math-element', getLatexString: el => el.querySelector('math').getAttribute('alttext') },
  63. 'zhihu.com': { elementSelector: 'span.ztext-math', getLatexString: el => el.getAttribute('data-tex') },
  64. 'chatgpt.com': { elementSelector: 'span.katex', getLatexString: el => el.querySelector('annotation').textContent },
  65. 'moonshot.cn': { elementSelector: 'span.katex', getLatexString: el => el.querySelector('annotation').textContent },
  66. 'stackexchange.com': { elementSelector: 'span.math-container', getLatexString: el => el.querySelector('script').textContent }
  67. };
  68.  
  69. for (const [key, value] of Object.entries(targets)) {
  70. if (url.includes(key)) {
  71. return value;
  72. }
  73. }
  74. return null;
  75. }
  76.  
  77. // 绑定事件到元素
  78. function addHandler() {
  79. const target = getTarget(window.location.href);
  80. if (!target) return;
  81.  
  82. document.querySelectorAll(target.elementSelector).forEach(element => {
  83. const latexString = target.getLatexString(element);
  84.  
  85. element.addEventListener('mouseenter', function () {
  86. element.style.cursor = "pointer";
  87. tooltip.textContent = latexString;
  88. const rect = element.getBoundingClientRect();
  89. tooltip.style.left = `${rect.left}px`;
  90. tooltip.style.top = `${rect.top - tooltip.offsetHeight - 5}px`;
  91. tooltip.style.opacity = '0.8';
  92. });
  93.  
  94. element.addEventListener('mouseleave', function () {
  95. element.style.cursor = "auto";
  96. tooltip.style.opacity = '0';
  97. });
  98.  
  99. element.addEventListener('dblclick', function() {
  100. copyMLToClip(latexString);
  101. window.getSelection().removeAllRanges();
  102. });
  103. });
  104. }
  105.  
  106. // 显示复制成功提示
  107. function showCopySuccessTooltip() {
  108. const copyTooltip = document.createElement("div");
  109. copyTooltip.className = "latex-copy-success";
  110. copyTooltip.innerText = "已复制LaTeX公式";
  111. document.body.appendChild(copyTooltip);
  112. setTimeout(() => {
  113. copyTooltip.style.opacity = "0";
  114. setTimeout(() => {
  115. document.body.removeChild(copyTooltip);
  116. }, 200);
  117. }, 1000);
  118. }
  119.  
  120. // 监听页面加载或变化,绑定事件
  121. document.addEventListener('DOMContentLoaded', addHandler);
  122. new MutationObserver(addHandler).observe(document.documentElement, { childList: true, subtree: true });
  123. })();

QingJ © 2025

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