Copy a math equation to Word

Double-click on a formula on a webpage to copy it to the clipboard, then paste it into Microsoft Word

2025-02-16 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Copy a math equation to Word
// @namespace    http://tampermonkey.net/
// @version      1.0
// @license      GPLv3
// @description  Double-click on a formula on a webpage to copy it to the clipboard, then paste it into Microsoft Word
// @author       Bui Quoc Dung
// @match        *://*.wikipedia.org/*
// @match        *://*.chatgpt.com/*
// @match        *://*.stackexchange.com/*
// @match        *://*.deepseek.com/*
// ==/UserScript==

(function () {
    'use strict';

    // Insert CSS styles
    const css = `
        .mathml-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; }
        .mathml-copy-success { position: absolute; background-color: rgba(0, 0, 0, 0.7); color: #fff; padding: 5px 10px; border-radius: 5px; font-size: 12px; z-index: 1000; opacity: 1; transition: opacity 0.5s; pointer-events: none; }
    `;
    const styleSheet = document.createElement("style");
    styleSheet.type = "text/css";
    styleSheet.innerText = css;
    document.head.appendChild(styleSheet);

    // Create tooltip element
    const tooltip = document.createElement('div');
    tooltip.classList.add('mathml-tooltip');
    document.body.appendChild(tooltip);

    function getTarget(url) {
        let target = { elementSelector: '', getMathMLString: null };

        function extractMathML(element) {
            let mathML = element.querySelector('math');
            return mathML ? mathML.outerHTML : null;
        }

        if (url.includes('wikipedia.org')) {
            target.elementSelector = 'span.mwe-math-element';
            target.getMathMLString = extractMathML;
        } else if (url.includes('chatgpt.com') || url.includes('deepseek.com')) {
            target.elementSelector = 'span.katex';
            target.getMathMLString = extractMathML;
        } else if (url.includes('stackexchange.com')) {
            target.elementSelector = 'span.math-container';
            target.getMathMLString = extractMathML;
        }

        return target.elementSelector ? target : null;
    }

    function addHandler() {
        let target = getTarget(window.location.href);
        if (!target) return;

        let tooltipTimeout;
        document.querySelectorAll(target.elementSelector).forEach(element => {
            element.addEventListener('mouseenter', function () {
                element.style.cursor = "pointer";
                tooltipTimeout = setTimeout(function () {
                    tooltip.textContent = "Double click to copy MathML";
                    const rect = element.getBoundingClientRect();
                    tooltip.style.left = `${rect.left}px`;
                    tooltip.style.top = `${rect.top - tooltip.offsetHeight - 5}px`;
                    tooltip.style.display = 'block';
                    tooltip.style.opacity = '0.8';
                }, 1000);
            });

            element.addEventListener('mouseleave', function () {
                element.style.cursor = "auto";
                clearTimeout(tooltipTimeout);
                tooltip.style.display = 'none';
                tooltip.style.opacity = '0';
            });

            element.ondblclick = function (event) {
                const mathMLString = target.getMathMLString(element);
                if (mathMLString !== null) {
                    navigator.clipboard.writeText(mathMLString).then(() => {
                        showCopySuccessTooltip(event);
                    });
                }
                window.getSelection().removeAllRanges();
            };
        });
    }

    function showCopySuccessTooltip(event) {
        const copyTooltip = document.createElement("div");
        copyTooltip.className = "mathml-copy-success";
        copyTooltip.innerText = "Copied";
        document.body.appendChild(copyTooltip);

        const rect = event.target.getBoundingClientRect();
        copyTooltip.style.left = `${rect.left + window.scrollX}px`;
        copyTooltip.style.top = `${rect.top + window.scrollY - 25}px`;

        setTimeout(() => {
            copyTooltip.style.opacity = "0";
            setTimeout(() => {
                document.body.removeChild(copyTooltip);
            }, 500);
        }, 1000);
    }

    document.addEventListener('DOMContentLoaded', addHandler);
    new MutationObserver(addHandler).observe(document.documentElement, { childList: true, subtree: true });
})();