OpenAI-ChatGPT LaTeX Auto Render (with MathJax V2)

Auto typeset LaTeX math formulas on OpenAI ChatGPT page.

目前為 2022-12-12 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name OpenAI-ChatGPT LaTeX Auto Render (with MathJax V2)
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.2
  5. // @author Scruel (https://github.com/scruel)
  6. // @description Auto typeset LaTeX math formulas on OpenAI ChatGPT page.
  7. // @description:zh-CN 自动渲染 OpenAI 的 ChatGPT 页面上的 LaTeX 数学公式。
  8. // @match https://chat.openai.com/chat
  9. // @match https://gpt.chatapi.art
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. 'use strict';
  14.  
  15. async function addScript(url) {
  16. const scriptElement = document.createElement('script');
  17. scriptElement.src = url;
  18. scriptElement.async = true;
  19.  
  20. const headElement = document.getElementsByTagName('head')[0] || document.documentElement;
  21. headElement.appendChild(scriptElement);
  22. await waitScriptLoaded();
  23. }
  24.  
  25. function waitScriptLoaded() {
  26. return new Promise(async (resolve, reject) => {
  27. const resolver = () => {
  28. if (MathJax.hasOwnProperty('Hub')) {
  29. resolve();
  30. return;
  31. }
  32. if (window.ChatLatex.loadCount > 100) {
  33. setTipsElementText("Failed to load MathJax, try refresh.");
  34. reject("Failed to load MathJax, try refresh.");
  35. return;
  36. }
  37. window.ChatLatex.loadCount += 1;
  38. window.setTimeout(resolver, 200);
  39. }
  40. resolver();
  41. });
  42. }
  43.  
  44. function renderTrigger() {
  45. setTimeout(renderLatex, window.renderDelay);
  46. }
  47.  
  48. function renderLatex() {
  49. const submitButton = document.querySelector('main form textarea+button');
  50. // console.log(submitButton)
  51. if (submitButton && !submitButton.disabled) {
  52. // console.log("Rendering...")
  53. MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
  54. }
  55. renderTrigger();
  56. }
  57.  
  58. function showTipsElement() {
  59. const tipsElement = window.ChatLatex.tipsElement;
  60. tipsElement.style.position = "fixed";
  61. tipsElement.style.left = "10px";
  62. tipsElement.style.bottom = "10px";
  63. tipsElement.style.background = '#333';
  64. tipsElement.style.color = '#fff';
  65. document.body.appendChild(tipsElement);
  66. }
  67.  
  68. function setTipsElementText(text) {
  69. window.ChatLatex.tipsElement.innerHTML = text;
  70. }
  71.  
  72. function hideTipsElement(timeout=3) {
  73. window.setTimeout(() => {window.ChatLatex.tipsElement.hidden=true}, 3000);
  74. }
  75.  
  76. (async function() {
  77. window.ChatLatex = {
  78. tipsElement: document.createElement("div"),
  79. loadCount: 0
  80. }
  81. window.MathJax = {
  82. tex2jax: {
  83. inlineMath: [['$', '$']],
  84. displayMath : [['$$', '$$']]
  85. },
  86. CommonHTML: { linebreaks: { automatic: true } },
  87. "HTML-CSS": { linebreaks: { automatic: true } },
  88. SVG: { linebreaks: { automatic: true } },
  89. };
  90.  
  91. showTipsElement();
  92. setTipsElementText("Loading MathJax...");
  93. await addScript('https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS_CHTML');
  94. setTipsElementText("MathJax Loaded.");
  95. hideTipsElement();
  96.  
  97. window.renderDelay = 1000;
  98. renderTrigger();
  99. })();