Magic Markdown Copy (GF-Approved)

Automatically converts selected Markdown to rich text HTML in your clipboard when you press Ctrl+C.

As of 2025-06-28. See the latest version.

// ==UserScript==
// @name         Magic Markdown Copy (GF-Approved)
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Automatically converts selected Markdown to rich text HTML in your clipboard when you press Ctrl+C.
// @author       Your Name
// @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 ---
    // Set to 'true' if you only want to convert text that contains common markdown characters.
    // Set to 'false' to attempt to convert ANY copied text.
    const SMART_DETECTION = true;

    // --- Main Logic: Intercept the "copy" event ---
    document.addEventListener('copy', (event) => {
        // 1. Get the text the user has selected
        const selectedText = window.getSelection().toString();

        if (selectedText.trim().length === 0) {
            // Nothing selected, let the default copy action proceed
            return;
        }

        // 2. Smart Detection (Optional but Recommended)
        // Only proceed if the text looks like it might be Markdown.
        const markdownChars = /[\*\_#\`\[\]\->\!]/;
        if (SMART_DETECTION && !markdownChars.test(selectedText)) {
            console.log('No Markdown characters detected. Performing normal copy.');
            return;
        }

        // 3. Convert the Markdown to HTML using the 'marked' library
        // The 'breaks: true' option adds <br> for single newlines, which is great for prose.
        const generatedHtml = marked.parse(selectedText, { gfm: true, breaks: true });

        // 4. Prevent the default copy action
        event.preventDefault();

        // 5. Create a rich text clipboard item
        // This is the magic part that allows pasting styled text.
        const blobHtml = new Blob([generatedHtml], { type: 'text/html' });
        const blobText = new Blob([selectedText], { type: 'text/plain' });
        const clipboardItem = new ClipboardItem({
            'text/html': blobHtml,
            'text/plain': blobText,
        });

        // 6. Write the new rich text content to the clipboard
        navigator.clipboard.write([clipboardItem]).then(() => {
            console.log('Markdown successfully converted and copied as rich text.');
            // Use GM_notification for a native-like OS notification
            GM_notification({
                text: 'Converted to HTML and copied!',
                title: 'Markdown Magic Copy',
                timeout: 2000 // Notification will disappear after 2 seconds
            });
        }).catch(err => {
            console.error('Failed to copy rich text to clipboard:', err);
            GM_notification({
                text: 'Error: Could not copy to clipboard.',
                title: 'Markdown Magic Copy',
                timeout: 4000
            });
        });
    });

    console.log('Magic Markdown Copy script (GF-Approved) is active.');

})();