Greasy Fork

Greasy Fork is available in English.

Linux.do 下崽器 (新版)

备份你珍贵的水贴为Markdown。

当前为 2024-10-08 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Linux.do 下崽器 (新版)
// @namespace    http://linux.do/
// @version      1.0.3
// @description  备份你珍贵的水贴为Markdown。
// @author       PastKing
// @match        https://www.linux.do/t/topic/*
// @match        https://linux.do/t/topic/*
// @license      MIT
// @icon         https://cdn.linux.do/uploads/default/optimized/1X/3a18b4b0da3e8cf96f7eea15241c3d251f28a39b_2_32x32.png
// @grant        none
// @require      https://unpkg.com/[email protected]/dist/turndown.js
// ==/UserScript==

(function() {
    'use strict';

    // 创建并插入下载按钮
    function createDownloadButton() {
        const button = document.createElement('button');
        button.textContent = '下载为 Markdown';
        button.style.cssText = `
            padding: 10px 15px;
            font-size: 14px;
            font-weight: bold;
            color: #ffffff;
            background-color: #0f9d58;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s ease;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);

        `;

        // 添加悬停效果
        button.onmouseover = function() {
            this.style.backgroundColor = '#0b8043';
        };
        button.onmouseout = function() {
            this.style.backgroundColor = '#0f9d58';
        };

        // 插入按钮
        const topicTitle = document.querySelector('#ember38 > div.timeline-container > div > div.timeline-scrollarea-wrapper');
        const postsContainer = document.querySelector('#ember38 > div.timeline-container > div > div.timeline-footer-controls');
        if (topicTitle && postsContainer) {
            topicTitle.parentNode.insertBefore(button, postsContainer);
        } else {
            console.error('无法找到合适的位置插入按钮');
            document.body.appendChild(button);
        }

        return button;
    }

    // 获取文章内容
    function getArticleContent() {
        const titleElement = document.querySelector('#topic-title > div > h1 > a.fancy-title > span');
        const contentElement = document.querySelector('#post_1 > div.row > div.topic-body.clearfix > div.regular.contents > div.cooked');

        if (!titleElement || !contentElement) {
            console.error('无法找到文章标题或内容');
            return null;
        }

        return {
            title: titleElement.textContent.trim(),
            content: contentElement.innerHTML
        };
    }

    // 转换为Markdown并下载
    function downloadAsMarkdown() {
        const article = getArticleContent();
        if (!article) {
            alert('无法获取文章内容,请检查网页结构是否变更。');
            return;
        }

        const turndownService = new TurndownService({
            headingStyle: 'atx',
            codeBlockStyle: 'fenced'
        });

        // 自定义规则处理图片和链接
        turndownService.addRule('images_and_links', {
            filter: ['a', 'img'],
            replacement: function (content, node) {
                // 处理图片
                if (node.nodeName === 'IMG') {
                    const alt = node.alt || '';
                    const src = node.getAttribute('src') || '';
                    const title = node.title ? ` "${node.title}"` : '';
                    return `![${alt}](${src}${title})`;
                }
                // 处理链接
                else if (node.nodeName === 'A') {
                    const href = node.getAttribute('href');
                    const title = node.title ? ` "${node.title}"` : '';
                    // 检查链接是否包含图片
                    const img = node.querySelector('img');
                    if (img) {
                        const alt = img.alt || '';
                        const src = img.getAttribute('src') || '';
                        const imgTitle = img.title ? ` "${img.title}"` : '';
                        return `[![${alt}](${src}${imgTitle})](${href}${title})`;
                    }
                    // 普通链接
                    return `[${node.textContent}](${href}${title})`;
                }
            }
        });

        const markdown = `# ${article.title}\n\n${turndownService.turndown(article.content)}`;

        const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${article.title}.md`;
        a.click();
        URL.revokeObjectURL(url);
    }

    // 主函数
    function main() {
        const downloadButton = createDownloadButton();
        downloadButton.addEventListener('click', downloadAsMarkdown);
    }

    // 运行主函数
    main();
})();