Wiki LaTeX Copier

Copy selected text from wiki with equations in LaTeX format

目前为 2024-10-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Wiki LaTeX Copier
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Copy selected text from wiki with equations in LaTeX format
  6. // @author Jie-Qiao
  7. // @match *://*.wikipedia.org/*
  8. // @match *://*.stackexchange.com/*
  9. // @match *://alejandroschuler.github.io/*
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. function getTextContentWithReplacements(url,node) {
  15. let text = '';
  16. if (node && node.childNodes) {
  17. node.childNodes.forEach(child => {
  18. // URL-specific processing rules
  19. if (url.includes('wikipedia.org')) {
  20. if (child.nodeType === Node.ELEMENT_NODE && child.nodeName.toLowerCase() === 'span') {
  21. if (child.querySelectorAll('math').length > 0) {
  22. text += '$' + child.getElementsByTagName('math')[0].getAttribute('alttext') + '$';
  23. } else if (child.querySelectorAll('img').length > 0) {
  24. text += '$' + child.querySelectorAll('img')[0].getAttribute('alt') + '$';
  25. }
  26. } else if (child.nodeType === Node.ELEMENT_NODE) {
  27. child.querySelectorAll('img').forEach(img => {
  28. text += '$' + img.getAttribute('alt') + '$';
  29. });
  30. }
  31. } else if (url.includes('stackexchange.com')) {
  32. if (child.nodeType === Node.ELEMENT_NODE && child.nodeName.toLowerCase() === 'span') {
  33. if (child.getElementsByTagName('script').length > 0) {
  34. text += '$' + child.getElementsByTagName('script')[0].textContent + '$';
  35. }
  36. }
  37. if (child.nodeType === Node.ELEMENT_NODE && child.nodeName.toLowerCase() === 'script') {
  38. text += '$' + child.textContent + '$';
  39. }
  40. } else if (url.includes('alejandroschuler.github.io')) {
  41. if (child.nodeType === Node.ELEMENT_NODE && child.nodeName.toLowerCase() === 'span') {
  42. if (child.getElementsByTagName('annotation').length > 0) {
  43. text += '$' + child.getElementsByTagName('annotation')[0].textContent + '$';
  44. }
  45. }
  46. }
  47.  
  48. // Default behavior for text nodes
  49. if (child.nodeType === Node.TEXT_NODE) {
  50. text += child.textContent;
  51. }
  52.  
  53. // For other elements, recurse into their children
  54. if (child.nodeType === Node.ELEMENT_NODE && !['span', 'script', 'math', 'img'].includes(child.nodeName.toLowerCase())) {
  55. text += getTextContentWithReplacements(url,child);
  56. }
  57. });
  58. }
  59. return text;
  60. }
  61.  
  62. (function() {
  63. 'use strict';
  64.  
  65. // Create the button element
  66. const button = document.createElement('button');
  67. button.textContent = 'Copy';
  68. button.style.position = 'absolute';
  69. button.style.display = 'none';
  70. button.style.zIndex = '1000';
  71.  
  72. // Append the button to the body
  73. document.body.appendChild(button);
  74.  
  75. // Function to handle button click
  76. button.addEventListener('click', function() {
  77. const selectedText = window.getSelection();
  78. if (selectedText) {
  79. myfunction(selectedText);
  80. }
  81. button.style.display = 'none'; // Hide the button after click
  82. });
  83.  
  84. // Function to show the button when text is selected
  85. document.addEventListener('mouseup', function(event) {
  86. const selectedText = window.getSelection().toString().trim();
  87. if (selectedText) {
  88. const x = event.pageX;
  89. const y = event.pageY;
  90. button.style.left = `${x}px`;
  91. button.style.top = `${y}px`;
  92. button.style.display = 'block';
  93. } else {
  94. button.style.display = 'none';
  95. }
  96. });
  97.  
  98. // Custom function to process the selected text
  99. function myfunction(selection) {
  100. let url = window.location.href
  101. let range = selection.getRangeAt(0);
  102. //console.log('Text selected:', selection.toString()); // Log selected text
  103. let c=range.cloneContents();
  104. let text = getTextContentWithReplacements(url,c);
  105. // let text=""
  106. // var node;
  107. // console.log('Processed text:', textContent);
  108. // for (var i=0;i<c.childNodes.length;i++)
  109. // {
  110. // node=c.childNodes[i]
  111. // if (node.nodeType === Node.TEXT_NODE || node.nodeName.toLowerCase() === 'p' ) {
  112. // text+=node.textContent;
  113. // continue;
  114. // }
  115. // if (url.includes('wikipedia.org')) {
  116. // // If the node is a span, handle it with specific code
  117. // if (node.nodeType === Node.ELEMENT_NODE && node.nodeName.toLowerCase() === 'span') {
  118. // if(node.querySelectorAll('math').length>0){
  119. // text+= '$' + node.getElementsByTagName('math')[0].getAttribute('alttext') + '$';
  120. // }else if(node.querySelectorAll('img').length>0){
  121. // text+= '$' + node.querySelectorAll('img')[0].getAttribute('alt') + '$';
  122. // }
  123. // // if(node.querySelectorAll('img').length>0){
  124. // // text+= '$' + node.querySelectorAll('img')[0].getAttribute('alt') + '$';
  125. // // }
  126. // // Add your specific code for span elements here
  127. // }
  128. // else if(node.nodeType === Node.ELEMENT_NODE){
  129. // for (var j=0;j<node.querySelectorAll('img').length;j++){
  130. // text+= '$' + node.querySelectorAll('img')[j].getAttribute('alt') + '$';
  131. // }
  132. // }
  133. // }
  134. // else if(url.includes('stackexchange.com')){
  135. // // If the node is a span, handle it with specific code
  136.  
  137. // if (node.nodeType === Node.ELEMENT_NODE && node.nodeName.toLowerCase() === 'span') {
  138. // if (node.getElementsByTagName('script').length>0){
  139. // text+= '$' + node.getElementsByTagName('script')[0].textContent + '$';
  140. // }
  141. // }
  142. // if (node.nodeType === Node.ELEMENT_NODE && node.nodeName.toLowerCase() === 'script') {
  143. // text+= '$' + node.textContent + '$';
  144. // }
  145. // }else if (url.includes('alejandroschuler.github.io')){
  146. // if (node.nodeType === Node.ELEMENT_NODE && node.nodeName.toLowerCase() === 'span') {
  147. // if (node.getElementsByTagName('annotation').length>0){
  148. // text+= '$' + node.getElementsByTagName('annotation')[0].textContent + '$';
  149. // }
  150. // }
  151. // }
  152. // }
  153. // console.log(text);
  154. navigator.clipboard.writeText(text);
  155. }
  156. })();