您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Export your ChatGPT conversations as clean Markdown files
// ==UserScript== // @name ChatGPT Chat Exporter - Markdown // @namespace https://github.com/rashidazarang/chatgpt-chat-exporter // @version 1.0.0 // @description Export your ChatGPT conversations as clean Markdown files // @author Rashid Azarang // @match https://chat.openai.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com // @grant none // @license MIT // @homepageURL https://github.com/rashidazarang/chatgpt-chat-exporter // @supportURL https://github.com/rashidazarang/chatgpt-chat-exporter/issues // ==/UserScript== (function() { 'use strict'; // Add a button to the ChatGPT interface function addExportButton() { // Check if our button already exists if (document.getElementById('export-markdown-button')) return; // Find a suitable location to add the button const targetElement = document.querySelector('nav'); if (!targetElement) return; // Create the button const button = document.createElement('button'); button.id = 'export-markdown-button'; button.innerHTML = 'Export as Markdown'; button.style.cssText = ` margin: 10px; padding: 10px; border-radius: 5px; background-color: #10a37f; color: white; border: none; cursor: pointer; font-size: 14px; width: calc(100% - 20px); `; // Add click event listener button.addEventListener('click', exportMarkdown); // Add button to the page targetElement.appendChild(button); } function formatDate(date = new Date()) { return date.toISOString().split('T')[0]; } function escapeMarkdown(text) { return text .replace(/\\/g, '\\\\') .replace(/\*/g, '\\*') .replace(/_/g, '\\_') .replace(/`/g, '\\`') .replace(/\n{3,}/g, '\n\n'); } function processMessageContent(element) { const clone = element.cloneNode(true); // Replace <pre><code> blocks clone.querySelectorAll('pre').forEach(pre => { const code = pre.innerText.trim(); const langMatch = pre.querySelector('code')?.className?.match(/language-([a-zA-Z0-9]+)/); const lang = langMatch ? langMatch[1] : ''; pre.replaceWith(`\n\n\`\`\`${lang}\n${code}\n\`\`\`\n`); }); // Replace images and canvas with placeholders clone.querySelectorAll('img, canvas').forEach(el => { el.replaceWith('[Image or Canvas]'); }); // Convert remaining HTML to plain markdown-style text return escapeMarkdown(clone.innerText.trim()); } function exportMarkdown() { const messages = document.querySelectorAll('div[class*="group"]'); const lines = []; const title = 'Conversation with ChatGPT'; const date = formatDate(); const url = window.location.href; lines.push(`# ${title}\n`); lines.push(`**Date:** ${date}`); lines.push(`**Source:** [chat.openai.com](${url})\n`); lines.push(`---\n`); messages.forEach(group => { const isUser = !!group.querySelector('img'); const sender = isUser ? 'You' : 'ChatGPT'; const block = group.querySelector('.markdown, .prose, .whitespace-pre-wrap'); if (block) { const content = processMessageContent(block); if (content) { lines.push(`### **${sender}**\n`); lines.push(content); lines.push('\n---\n'); } } }); const markdown = lines.join('\n').trim(); const blob = new Blob([markdown], { type: 'text/markdown' }); const a = document.createElement('a'); a.download = `ChatGPT_Conversation_${date}.md`; a.href = URL.createObjectURL(blob); document.body.appendChild(a); a.click(); document.body.removeChild(a); } // Add the export button when the DOM is fully loaded if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', addExportButton); } else { addExportButton(); } // Check periodically if the button needs to be added (for SPAs like ChatGPT) setInterval(addExportButton, 3000); })();