Magic Markdown Copy (Ctrl+C & Button)

Automatically converts Markdown to rich HTML on copy, both from user selection (Ctrl+C) and from website "Copy" buttons.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Magic Markdown Copy (Ctrl+C & Button)
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Automatically converts Markdown to rich HTML on copy, both from user selection (Ctrl+C) and from website "Copy" buttons.
// @author       Tertium
// @match        *://*/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/marked/5.1.2/marked.min.js
// @grant        GM_notification
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    const SMART_DETECTION = true; // Set to false to attempt conversion on ALL copied text.
    const MD_CHARS = /[\*\_#\`\[\]\->\!]/; // Regex to detect Markdown characters

    /**
     * The core conversion function. Takes Markdown text and writes rich HTML to the clipboard.
     * @param {string} markdownText - The text to convert.
     * @returns {Promise<void>}
     */
    async function convertAndCopyToClipboard(markdownText) {
        console.log('Attempting to convert Markdown:', markdownText.substring(0, 80) + '...');
        try {
            // Convert the Markdown to HTML using the 'marked' library
            const generatedHtml = marked.parse(markdownText, { gfm: true, breaks: true });

            // Create a rich text clipboard item that has both HTML and plain text fallbacks
            const blobHtml = new Blob([generatedHtml], { type: 'text/html' });
            const blobText = new Blob([markdownText], { type: 'text/plain' });
            const clipboardItem = new ClipboardItem({
                'text/html': blobHtml,
                'text/plain': blobText,
            });

            // Write the new rich text content to the clipboard
            await navigator.clipboard.write([clipboardItem]);
            console.log('Markdown successfully converted and copied as rich text.');
            GM_notification({
                text: 'Converted to HTML and copied!',
                title: 'Markdown Magic Copy',
                timeout: 2000
            });
        } catch (err) {
            console.error('Failed to convert or copy:', err);
            GM_notification({
                text: 'Error during conversion.',
                title: 'Markdown Magic Copy',
                timeout: 4000
            });
        }
    }


    // --- FEATURE 1: Intercept User Selection (Ctrl+C) ---
    document.addEventListener('copy', (event) => {
        const selectedText = window.getSelection().toString();
        if (selectedText.trim().length === 0) return;

        // If smart detection is on, only proceed if text looks like Markdown
        if (SMART_DETECTION && !MD_CHARS.test(selectedText)) {
            console.log('No Markdown characters in selection. Performing normal copy.');
            return;
        }

        // Prevent the default copy action and run our conversion
        event.preventDefault();
        convertAndCopyToClipboard(selectedText);
    });


    // --- FEATURE 2: Intercept Website "Copy" Buttons ---
    // We "monkey-patch" the clipboard API to intercept programmatic copies.
    if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
        const originalWriteText = navigator.clipboard.writeText;

        navigator.clipboard.writeText = async function(textToCopy) {
            // If smart detection is on, check if the text looks like Markdown
            if (SMART_DETECTION && (typeof textToCopy !== 'string' || !MD_CHARS.test(textToCopy))) {
                // If not, use the original, unmodified function
                return originalWriteText.apply(this, arguments);
            }

            // If it looks like Markdown, run our custom conversion function instead!
            // We don't need to prevent a default action here because we are replacing the function.
            try {
                await convertAndCopyToClipboard(textToCopy);
            } catch (err) {
                // If our function fails for any reason, fall back to the original to avoid breaking the site.
                console.error("Conversion failed, falling back to original copy function.", err);
                return originalWriteText.apply(this, arguments);
            }
        };
        console.log('Magic Markdown Copy: Intercepting copy buttons.');
    }

    console.log('Magic Markdown Copy script is fully active.');

})();