forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			86 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			86 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | // Set these to how you want inline and display math to be delimited.
 | ||
|  | const defaultCopyDelimiters = { | ||
|  |   inline: ['$', '$'], | ||
|  |   // alternative: ['\(', '\)']
 | ||
|  |   display: ['$$', '$$'] // alternative: ['\[', '\]']
 | ||
|  | 
 | ||
|  | }; // Replace .katex elements with their TeX source (<annotation> element).
 | ||
|  | // Modifies fragment in-place.  Useful for writing your own 'copy' handler,
 | ||
|  | // as in copy-tex.js.
 | ||
|  | 
 | ||
|  | const katexReplaceWithTex = function katexReplaceWithTex(fragment, copyDelimiters) { | ||
|  |   if (copyDelimiters === void 0) { | ||
|  |     copyDelimiters = defaultCopyDelimiters; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Remove .katex-html blocks that are preceded by .katex-mathml blocks
 | ||
|  |   // (which will get replaced below).
 | ||
|  |   const katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html'); | ||
|  | 
 | ||
|  |   for (let i = 0; i < katexHtml.length; i++) { | ||
|  |     const element = katexHtml[i]; | ||
|  | 
 | ||
|  |     if (element.remove) { | ||
|  |       element.remove(null); | ||
|  |     } else { | ||
|  |       element.parentNode.removeChild(element); | ||
|  |     } | ||
|  |   } // Replace .katex-mathml elements with their annotation (TeX source)
 | ||
|  |   // descendant, with inline delimiters.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   const katexMathml = fragment.querySelectorAll('.katex-mathml'); | ||
|  | 
 | ||
|  |   for (let i = 0; i < katexMathml.length; i++) { | ||
|  |     const element = katexMathml[i]; | ||
|  |     const texSource = element.querySelector('annotation'); | ||
|  | 
 | ||
|  |     if (texSource) { | ||
|  |       if (element.replaceWith) { | ||
|  |         element.replaceWith(texSource); | ||
|  |       } else { | ||
|  |         element.parentNode.replaceChild(texSource, element); | ||
|  |       } | ||
|  | 
 | ||
|  |       texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1]; | ||
|  |     } | ||
|  |   } // Switch display math to display delimiters.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   const displays = fragment.querySelectorAll('.katex-display annotation'); | ||
|  | 
 | ||
|  |   for (let i = 0; i < displays.length; i++) { | ||
|  |     const element = displays[i]; | ||
|  |     element.innerHTML = copyDelimiters.display[0] + element.innerHTML.substr(copyDelimiters.inline[0].length, element.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length) + copyDelimiters.display[1]; | ||
|  |   } | ||
|  | 
 | ||
|  |   return fragment; | ||
|  | }; | ||
|  | 
 | ||
|  | document.addEventListener('copy', function (event) { | ||
|  |   const selection = window.getSelection(); | ||
|  | 
 | ||
|  |   if (selection.isCollapsed) { | ||
|  |     return; // default action OK if selection is empty
 | ||
|  |   } | ||
|  | 
 | ||
|  |   const fragment = selection.getRangeAt(0).cloneContents(); | ||
|  | 
 | ||
|  |   if (!fragment.querySelector('.katex-mathml')) { | ||
|  |     return; // default action OK if no .katex-mathml elements
 | ||
|  |   } // Preserve usual HTML copy/paste behavior.
 | ||
|  | 
 | ||
|  | 
 | ||
|  |   const html = []; | ||
|  | 
 | ||
|  |   for (let i = 0; i < fragment.childNodes.length; i++) { | ||
|  |     html.push(fragment.childNodes[i].outerHTML); | ||
|  |   } | ||
|  | 
 | ||
|  |   event.clipboardData.setData('text/html', html.join('')); // Rewrite plain-text version.
 | ||
|  | 
 | ||
|  |   event.clipboardData.setData('text/plain', katexReplaceWithTex(fragment).textContent); // Prevent normal copy handling.
 | ||
|  | 
 | ||
|  |   event.preventDefault(); | ||
|  | }); |