Multi-Column Layout for printing (Print Only)

Convert single column layout to multi-column layout only when printing. Double-press Ctrl key to open settings.

当前为 2024-11-05 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Multi-Column Layout for printing (Print Only)
// @namespace    http://tampermonkey.net/
// @license MIT
// @version      2.1
// @description  Convert single column layout to multi-column layout only when printing. Double-press Ctrl key to open settings.
// @author       KQ yang
// @match        *://*
// @match        file:///*
// @match        http://127.0.0.1:*/*
// @match        http://localhost:*/*
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Default configuration
    const DEFAULT_CONFIG = {
        columns: 2,
        columnGap: '30px',
        fontSize: '16px',
        paragraphSpacing: '1em',
        enablePageBreak: true,
        lineHeight: '1.5',
    };

    // Load config from localStorage or use defaults
    let CONFIG = loadConfig();

    function loadConfig() {
        const savedConfig = localStorage.getItem('printLayoutConfig');
        return savedConfig ? {...DEFAULT_CONFIG, ...JSON.parse(savedConfig)} : DEFAULT_CONFIG;
    }

    function saveConfig(config) {
        localStorage.setItem('printLayoutConfig', JSON.stringify(config));
        CONFIG = config;
        updateStyles();
    }

    // Create and inject the configuration UI
    function createConfigUI() {
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.3);
            z-index: 9999;
            display: none;
        `;

        modal.innerHTML = `
            <h3 style="margin-top: 0;">Print Layout Settings</h3>
            <div style="margin-bottom: 10px;">
                <label>Columns (1-4): </label>
                <input type="number" id="columns" min="1" max="4" value="${CONFIG.columns}">
            </div>
            <div style="margin-bottom: 10px;">
                <label>Column Gap: </label>
                <input type="text" id="columnGap" value="${CONFIG.columnGap}">
            </div>
            <div style="margin-bottom: 10px;">
                <label>Font Size: </label>
                <input type="text" id="fontSize" value="${CONFIG.fontSize}">
            </div>
            <div style="margin-bottom: 10px;">
                <label>Paragraph Spacing: </label>
                <input type="text" id="paragraphSpacing" value="${CONFIG.paragraphSpacing}">
            </div>
            <div style="margin-bottom: 10px;">
                <label>Line Height: </label>
                <input type="text" id="lineHeight" value="${CONFIG.lineHeight}">
            </div>
            <div style="margin-bottom: 10px;">
                <label>Enable Page Break: </label>
                <input type="checkbox" id="enablePageBreak" ${CONFIG.enablePageBreak ? 'checked' : ''}>
            </div>
            <div style="text-align: right; margin-top: 20px;">
                <button id="saveConfig" style="padding: 5px 10px;">Save</button>
            </div>
        `;

        document.body.appendChild(modal);

        // Save button handler
        document.getElementById('saveConfig').addEventListener('click', () => {
            const newConfig = {
                columns: parseInt(document.getElementById('columns').value, 10),
                columnGap: document.getElementById('columnGap').value,
                fontSize: document.getElementById('fontSize').value,
                paragraphSpacing: document.getElementById('paragraphSpacing').value,
                lineHeight: document.getElementById('lineHeight').value,
                enablePageBreak: document.getElementById('enablePageBreak').checked
            };
            saveConfig(newConfig);
            modal.style.display = 'none';
        });

        return modal;
    }

    // Create and update styles based on current config
    function updateStyles() {
        const styleSheet = `
            /* 打印样式优化 */
            @media print {
                html, body {
                    margin: 0 !important;
                    padding: 0 !important;
                    min-height: 0 !important;
                    height: auto !important;
                }
                .print-column-container {
                    column-count: ${CONFIG.columns} !important;
                    column-gap: ${CONFIG.columnGap} !important;
                    column-rule: 1px solid #ddd !important;
                    width: 100% !important;
                    margin: 0 !important;
                    padding: 0 !important;
                    min-height: 0 !important;
                    height: auto !important;
                    overflow: visible !important;
                    box-sizing: border-box !important;
                    font-size: ${CONFIG.fontSize} !important;
                    line-height: ${CONFIG.lineHeight} !important;
                    ${CONFIG.enablePageBreak ? '' : 'page-break-inside: avoid !important;'}
                }
                .print-column-container > * {
                    break-inside: avoid !important;
                    margin-bottom: ${CONFIG.paragraphSpacing} !important;
                    max-width: 100% !important;
                    box-sizing: border-box !important;
                    page-break-inside: avoid !important;
                }
                .print-column-container img {
                    max-width: 100% !important;
                    height: auto !important;
                    page-break-inside: avoid !important;
                }
            }
        `;

        // Remove existing style if any
        const existingStyle = document.getElementById('print-layout-style');
        if (existingStyle) {
            existingStyle.remove();
        }

        // Add new style
        const style = document.createElement('style');
        style.id = 'print-layout-style';
        style.textContent = styleSheet;
        document.head.appendChild(style);
    }

    // Apply columns to main content
    function applyPrintColumns() {
        const mainContent = document.querySelector('.target-content') || document.body;
        mainContent.classList.add('print-column-container');

        const printStyle = document.createElement('style');
        printStyle.media = 'print';
        printStyle.textContent = `
            @page {
                margin: 1cm !important;
                padding: 0 !important;
                size: auto !important;
            }
        `;
        document.head.appendChild(printStyle);
    }

    // Initialize
    let lastCtrlPress = 0;
    const configModal = createConfigUI();

    // Handle double Ctrl press
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Control') {
            const now = Date.now();
            if (now - lastCtrlPress < 300) {  // 300ms threshold for double press
                configModal.style.display = configModal.style.display === 'none' ? 'block' : 'none';
            }
            lastCtrlPress = now;
        }
    });

    // Initial style application
    updateStyles();

    // Apply columns when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', applyPrintColumns);
    } else {
        applyPrintColumns();
    }

    // Log usage instructions to console
    console.log(`
    Multi-Column Layout Userscript Usage:
    -----------------------------------
    1. Double-press Ctrl key to open settings
    2. Adjust your preferences:
       - Columns: Number of columns (1-4)
       - Column Gap: Space between columns
       - Font Size: Text size in print
       - Paragraph Spacing: Space between paragraphs
       - Line Height: Text line height
       - Enable Page Break: Allow/prevent content breaks across pages
    3. Click Save to apply changes
    4. Settings are automatically saved between sessions
    5. Press Ctrl+P to see the print preview with your settings

    Current configuration:`, CONFIG);

})();