Mrrrr's Forum (VIEW ONLY)
Un forum care ofera solutii pentru unele probleme legate in general de PC. Pe langa solutii, aici puteti gasi si alte lucruri interesante // A forum that offers solutions to some PC related issues. Besides these, here you can find more interesting stuff.
|
Lista Forumurilor Pe Tematici
|
Mrrrr's Forum (VIEW ONLY) | Reguli | Inregistrare | Login
POZE MRRRR'S FORUM (VIEW ONLY)
Nu sunteti logat.
|
Nou pe simpatie: Ank_beleaua din Bucuresti
 | Femeie 25 ani Bucuresti cauta Barbat 35 - 51 ani |
|
Mrrrr
AdMiN
 Inregistrat: acum 19 ani
Postari: 2387
|
|
Made the following Tampermonkey script with ChatGPT that creates 2 buttons in the bottom right side of the ChatGPT chat allowing Export PDF or Export DOCX.
When previously trying to print page, it would not get everything - some text would be missing, chat would be shortened.
You can add @match for gemini as well, maybe other AIs.
This way you get everything:
// ==UserScript== // @name Local ChatGPT Exporter (PDF & DOCX) // @namespace // @version 1.1 // @description Export ChatGPT chats to PDF or DOCX cleanly without third-party servers. // @author Mrrrr // @match // @match // @run-at document-start // @grant none // ==/UserScript==
(function() { 'use strict';
function createUI() { if (document.getElementById('local-exporter-container')) return;
const container = document.createElement('div'); container.id = 'local-exporter-container'; container.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 99999; display: flex; gap: 8px; background: rgba(0, 0, 0, 0.85); padding: 8px 12px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.4); backdrop-filter: blur(4px); `;
const btnPdf = createButton('📄 Export PDF', '#10a37f', function () { exportChat('pdf'); }); const btnDocx = createButton('📝 Export DOCX', '#2b579a', function () { exportChat('docx'); });
container.appendChild(btnPdf); container.appendChild(btnDocx);
if (document.body) { document.body.appendChild(container); } }
function createButton(text, color, onClick) { const btn = document.createElement('button'); btn.innerText = text; btn.style.cssText = ` background-color: ${color}; color: white; border: none; padding: 8px 14px; border-radius: 6px; font-size: 13px; font-weight: bold; cursor: pointer; transition: opacity 0.2s; `; btn.onmouseover = function () { btn.style.opacity = '0.85'; }; btn.onmouseout = function () { btn.style.opacity = '1'; }; btn.onclick = onClick; return btn; }
function extractTurns() { const turns = []; const seenTexts = new Set();
// Find all message groups/blocks const turnNodes = document.querySelectorAll('[data-message-author-role], article, div[class*="agent-turn"], div[class*="user-turn"]');
if (turnNodes.length > 0) { turnNodes.forEach(function (node) { // Skip hidden duplicate containers generated for internal model state/drafts if (node.offsetParent === null && !node.classList.contains('markdown')) return;
const roleAttr = node.getAttribute('data-message-author-role'); let author = 'ChatGPT';
if (roleAttr === 'user' || node.querySelector('[data-message-author-role="user"]') || node.innerText.includes('You said:')) { author = 'User'; }
// Get inner markdown content const contentNode = node.querySelector('.markdown, [class*="markdown"]') || node; const htmlContent = contentNode.innerHTML; const textContent = contentNode.innerText.trim();
// #### update v1.1 - Loading image added page break in print preview
// Create a temporary element to clean up internal ChatGPT UI clutter const cleanEl = document.createElement('div'); cleanEl.innerHTML = htmlContent;
// 1. Remove loading containers, spinners, and SVG wrappers entirely cleanEl.querySelectorAll('[title="Loading..."], svg, .motion-safe\\:animate-spin').forEach(el => el.remove());
// 2. Remove giant inline width/height attributes from image placeholders cleanEl.querySelectorAll('[style*="2048px"], [style*="aspect-ratio"]').forEach(el => { el.style.width = 'auto'; el.style.height = 'auto'; el.style.aspectRatio = 'auto'; });
const cleanedHtml = cleanEl.innerHTML; // ####
// Deduplicate consecutive or identical responses and skip empty blocks if (textContent.length > 0 && !seenTexts.has(textContent)) { seenTexts.add(textContent); turns.push({ author: author, html: cleanedHtml // #### // html: htmlContent // #### commented this line (the above one replaces it) }); } }); }
return turns; }
function exportChat(type) { const turns = extractTurns();
if (turns.length === 0) { alert('No chat content could be extracted. Please make sure the conversation is open.'); return; }
const rawTitle = document.title.replace(/[^a-zA-Z0-9 _-]/g, '').trim() || 'ChatGPT_Export';
let contentHtml = `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>${rawTitle}</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #111; padding: 30px; max-width: 800px; margin: 0 auto; } .turn { margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid #e5e5e5; page-break-inside: auto; } .author { font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; } .User .author { color: #0066cc; } .ChatGPT .author { color: #10a37f; } pre { background: #f4f4f5; padding: 12px; border-radius: 6px; overflow-x: auto; white-space: pre-wrap; word-break: break-all; font-family: monospace; font-size: 13px; } code { background: #f4f4f5; padding: 2px 5px; border-radius: 4px; font-family: monospace; font-size: 13px; } table { border-collapse: collapse; width: 100%; margin: 14px 0; } th, td { border: 1px solid #e5e5e5; padding: 8px 12px; text-align: left; } th { background-color: #f8f9fa; } .content img { max-height: 16px; object-fit: contain; } button { display: none !important; } svg { display: none !important; } .sr-only { display: none !important; } @media print { body { max-width: 100%; padding: 0; } .turn { page-break-inside: auto; } } </style> </head> <body> <h2>${rawTitle}</h2> <hr style="border: none; border-top: 1px solid #ccc; margin-bottom: 20px;"> `;
turns.forEach(function (turn) { contentHtml += ` <div class="turn ${turn.author}"> <div class="author">${turn.author}</div> <div class="content">${turn.html}</div> </div>`; });
contentHtml += `\n</body>\n</html>`;
if (type === 'docx') { const blob = new Blob(['\ufeff' + contentHtml], { type: 'application/msword' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = rawTitle + '.doc'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } else if (type === 'pdf') { const blob = new Blob([contentHtml], { type: 'text/html' }); const url = URL.createObjectURL(blob); const printWin = window.open(url, '_blank');
if (!printWin) { alert('Pop-up blocked! Please allow pop-ups for ChatGPT to render the printable tab.'); return; }
printWin.onload = function () { printWin.print(); }; } }
setInterval(createUI, 1500);
})(); |
_______________________________________

|
|
| pus acum 2 zile |
|