您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Export ChatGPT conversations to clean, readable Markdown with proper role labels and preserved code formatting.
- // ==UserScript==
- // @name ChatGPT Markdown Export
- // @namespace https://github.com/dankCodeNugs/greasyScripts
- // @version 1.0.0
- // @description Export ChatGPT conversations to clean, readable Markdown with proper role labels and preserved code formatting.
- // @author Anonymous
- // @match https://chat.openai.com/*
- // @match https://chatgpt.com/*
- // @license Dual license anti-copyleft & BSD-2-Clause
- // @grant none
- // ==/UserScript==
- (function () {
- 'use strict';
- const BUTTON_ID = 'export-md-button';
- const style = `
- #${BUTTON_ID} {
- position: fixed;
- top: 10px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 9999;
- padding: 6px 14px;
- font-size: 14px;
- font-weight: 500;
- background: rgba(255, 255, 255, 0.1);
- color: #fff;
- border: 1px solid rgba(255, 255, 255, 0.4);
- border-radius: 6px;
- backdrop-filter: blur(6px);
- cursor: pointer;
- transition: background 0.2s, color 0.2s;
- }
- #${BUTTON_ID}:hover {
- background: rgba(255, 255, 255, 0.2);
- color: #000;
- }
- `;
- function injectStyle() {
- const tag = document.createElement('style');
- tag.textContent = style;
- document.head.appendChild(tag);
- }
- function sanitizeClone(el) {
- const clone = el.cloneNode(true);
- clone.querySelectorAll('button, .copy-button, .absolute, .overflow-hidden, svg').forEach(e => e.remove());
- return clone;
- }
- function extractMarkdownFromElement(el) {
- const blocks = [];
- const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT, null, false);
- while (walker.nextNode()) {
- const node = walker.currentNode;
- if (node.tagName === 'PRE' && node.querySelector('code')) {
- const code = node.querySelector('code').textContent.trim();
- blocks.push("```");
- blocks.push(code);
- blocks.push("```");
- walker.currentNode = node;
- } else if (node.tagName === 'P') {
- const text = node.textContent.trim();
- if (text.length > 0) {
- blocks.push(text);
- }
- }
- }
- if (blocks.length === 0) {
- blocks.push(el.innerText.trim());
- }
- return blocks.join('\n\n');
- }
- function getSpeakerFromRole(role) {
- if (role === 'user') return 'User';
- if (role === 'assistant') return 'ChatGPT';
- return 'Unknown';
- }
- function collectMessages() {
- const transcript = [];
- const messages = document.querySelectorAll('main div[data-message-author-role]');
- messages.forEach(msg => {
- const role = msg.getAttribute('data-message-author-role');
- const speaker = getSpeakerFromRole(role);
- let content = '';
- const markdownEl = msg.querySelector('.markdown, .prose');
- const plainEl = msg.querySelector('.whitespace-pre-wrap');
- if (markdownEl) {
- const clean = sanitizeClone(markdownEl);
- content = extractMarkdownFromElement(clean);
- } else if (plainEl) {
- content = plainEl.textContent.trim();
- }
- if (content && content.length > 0) {
- transcript.push(`### ${speaker}:\n\n${content}`);
- }
- });
- return transcript.join('\n\n---\n\n');
- }
- function downloadMarkdown(content) {
- const blob = new Blob([content], { type: 'text/markdown' });
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
- a.href = url;
- a.download = `chatgpt-session-${timestamp}.md`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- }
- function addExportButton() {
- const btn = document.createElement('button');
- btn.id = BUTTON_ID;
- btn.textContent = 'Export to MD';
- btn.addEventListener('click', () => {
- const md = collectMessages();
- if (md.length === 0) {
- alert('No messages found.');
- return;
- }
- downloadMarkdown(md);
- });
- document.body.appendChild(btn);
- }
- const waitForMain = setInterval(() => {
- const main = document.querySelector('main');
- if (main && !document.getElementById(BUTTON_ID)) {
- clearInterval(waitForMain);
- injectStyle();
- addExportButton();
- }
- }, 500);
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址