From fc6bfb3003e34bf3151a1b1e8ca0f1ab5d2db58c Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sun, 26 Oct 2025 21:22:36 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20critical=20bugs=20in=20v1.7.8:=20file=20a?= =?UTF-8?q?ssociation=20and=20print=20preview=20-=20Fixed=20command-line?= =?UTF-8?q?=20argument=20parsing=20for=20packaged=20apps=20using=20app.isP?= =?UTF-8?q?ackaged=20-=20Fixed=20print=20preview=20to=20show=20markdown=20?= =?UTF-8?q?content=20instead=20of=20toolbar=20-=20Rewrote=20print=20handle?= =?UTF-8?q?r=20to=20rely=20on=20CSS=20@media=20print=20rules=20-=20Enhance?= =?UTF-8?q?d=20CSS=20with=20attribute=20selectors=20for=20dynamic=20previe?= =?UTF-8?q?w=20panes=20-=20Removed=20DevTools=20auto-open=20for=20producti?= =?UTF-8?q?on=20build=20-=20Updated=20version=20to=201.7.8=20across=20all?= =?UTF-8?q?=20files=20=F0=9F=A4=96=20Generated=20with=20[Claude=20Code](ht?= =?UTF-8?q?tps://claude.com/claude-code)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 115 ++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- src/main.js | 64 ++++++++++++++++++--------- src/renderer.js | 64 +++++---------------------- src/styles.css | 24 ++++++++-- 5 files changed, 186 insertions(+), 83 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b8e3a2e..5605d40 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ **PanConverter** is a cross-platform Markdown editor and converter powered by Pandoc, built with Electron. It provides professional-grade editing capabilities with comprehensive export options. -**Current Version**: v1.7.7 +**Current Version**: v1.7.8 **Author**: Amit Haridas (amit.wh@gmail.com) **License**: MIT **Repository**: https://github.com/amitwh/pan-converter @@ -113,7 +113,109 @@ gh release create v1.2.1 --title "Title" --notes "Release notes" \ ## Feature Implementation Guide -### v1.7.7 Print & Enhanced PDF Support (Latest) +### v1.7.8 Critical Bug Fixes (Latest) + +#### 🐛 File Association Fix for Packaged Apps +**Fixed Command-Line Argument Parsing** (`src/main.js:1598-1627`, `src/main.js:70-90`) +- **Root Cause**: `process.argv.slice(2)` works in development but fails in packaged apps +- **Solution**: Detect if app is packaged using `app.isPackaged` and use correct slice index + - Development: `process.argv.slice(2)` - ['electron', 'app.js', 'file.md'] + - Packaged: `process.argv.slice(1)` - ['PanConverter.exe', 'file.md'] +- **Path Resolution**: Added proper path resolution for both absolute and relative paths +- **Comprehensive Logging**: Added detailed console logs to debug file loading issues +- **Second Instance Handler**: Also fixed second-instance handler to use same logic + +**Technical Implementation:** +```javascript +// Detect packaged vs development mode +const startIndex = app.isPackaged ? 1 : 2; +const fileArgs = process.argv.slice(startIndex); + +// Resolve paths properly +for (const arg of fileArgs) { + if ((arg.endsWith('.md') || arg.endsWith('.markdown'))) { + const resolvedPath = path.isAbsolute(arg) ? arg : path.resolve(process.cwd(), arg); + if (fs.existsSync(resolvedPath)) { + app.pendingFile = resolvedPath; + break; + } + } +} +``` + +**Fixed Issues:** +- ✅ Files now open correctly on first double-click in packaged app +- ✅ Command-line arguments properly parsed in both dev and production +- ✅ Relative and absolute paths handled correctly +- ✅ Comprehensive logging for debugging file association issues + +#### 🖨️ Print Preview Fix +**Fixed Print Output to Show Preview Content** (`src/renderer.js:1178-1204`, `src/styles.css:2828-3014`) +- **Root Cause**: Manual DOM manipulation conflicted with CSS `@media print` rules +- **Solution**: Simplified handler to rely on CSS `@media print` for hiding UI elements +- **CSS Enhancements**: + - Added selectors for dynamic preview panes `[id^="preview-pane-"]` and `[id^="editor-pane-"]` + - Added `.tab-content` to ensure full-width rendering + - Added body class-based styling for no-styles mode +- **Removed Manual Hiding**: Eliminated manual `display: none` manipulation in favor of CSS + +**Technical Implementation:** +```javascript +// Simplified print handler - let CSS do the work +function handlePrintPreview(withStyles) { + const activeTabId = tabManager ? tabManager.activeTabId : 1; + const previewContent = document.getElementById(`preview-${activeTabId}`); + + if (!previewContent || !previewContent.innerHTML.trim()) { + alert('Nothing to print...'); + return; + } + + // Add body classes for CSS styling + if (!withStyles) { + document.body.classList.add('printing-no-styles'); + } + document.body.classList.add('printing'); + + setTimeout(() => { + ipcRenderer.send('do-print', { withStyles }); + setTimeout(() => { + document.body.classList.remove('printing', 'printing-no-styles'); + }, 1000); + }, 100); +} +``` + +**CSS Updates:** +```css +@media print { + /* Hide all UI elements */ + #toolbar, #tab-bar, .editor-pane, [id^="editor-pane-"] { + display: none !important; + } + + /* Show preview in full width */ + [id^="preview-"], [id^="preview-pane-"], .tab-content { + display: block !important; + width: 100% !important; + padding: 20px !important; + } +} +``` + +**Fixed Issues:** +- ✅ Print now correctly renders preview content, not toolbar +- ✅ Both print modes work (with styles and without styles) +- ✅ Clean, professional print output with proper formatting +- ✅ Proper page breaks, typography, and layout optimization + +#### 🔧 Development Cleanup +**Removed Debugging Code** (`src/main.js:120-123`) +- Removed auto-opening of DevTools +- Clean production-ready build +- Debugging logs remain for troubleshooting but DevTools disabled by default + +### v1.7.7 Print & Enhanced PDF Support #### 🖨️ Native Print Functionality **Added Print Submenu to File Menu** (`src/main.js:202-215`, `src/renderer.js:1152-1188`, `src/styles.css:2828-2994`) @@ -782,5 +884,10 @@ if (!gotTheLock) { --- -**Last Updated**: October 24, 2025 -**Claude Assistant**: Development completed for v1.7.7 with enhanced print menu featuring two print options: "Print Preview" (Ctrl+P, black text, ink-saving) and "Print Preview (With Styles)" (full colors). Implemented comprehensive print handler that hides editor UI and shows only the rendered preview. Added extensive CSS print stylesheet with smart page breaks, optimized formatting for all markdown elements, and professional typography. Added PDFKit and html2pdf libraries for native PDF support without Pandoc dependency. Previous releases include v1.7.6 table header styling cleanup and v1.7.5 critical file association fix. \ No newline at end of file +**Last Updated**: October 26, 2025 +**Claude Assistant**: Development completed for v1.7.8 with critical bug fixes: +1. **File Association Fix**: Fixed command-line argument parsing to properly detect packaged vs development mode using `app.isPackaged`, enabling files to open correctly on first double-click in packaged app +2. **Print Preview Fix**: Completely rewrote print handler to rely on CSS `@media print` rules instead of manual DOM manipulation, ensuring preview content (not toolbar) is printed +3. **Code Cleanup**: Removed auto-opening DevTools for production-ready build + +Previous releases: v1.7.7 (print menu with two options, PDFKit/html2pdf integration), v1.7.6 (table header styling cleanup), v1.7.5 (single-instance lock). \ No newline at end of file diff --git a/package.json b/package.json index ea59d3c..cf7ded9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pan-converter", - "version": "1.7.7", + "version": "1.7.8", "description": "Cross-platform Markdown editor and converter using Pandoc", "main": "src/main.js", "scripts": { diff --git a/src/main.js b/src/main.js index e21557f..d292b52 100644 --- a/src/main.js +++ b/src/main.js @@ -68,17 +68,24 @@ if (!gotTheLock) { } // Check if a file was passed to the second instance - // commandLine is an array like: ['electron.exe', 'app.asar', 'file.md'] - const fileArgs = commandLine.slice(2); + // commandLine is an array like: ['PanConverter.exe', 'file.md'] + console.log('[MAIN] Second instance commandLine:', JSON.stringify(commandLine)); + const startIndex = app.isPackaged ? 1 : 2; + const fileArgs = commandLine.slice(startIndex); + console.log('[MAIN] Second instance file args:', fileArgs); for (const arg of fileArgs) { - if ((arg.endsWith('.md') || arg.endsWith('.markdown')) && fs.existsSync(arg)) { - // Open the file in the existing instance - if (rendererReady) { - openFileFromPath(arg); - } else { - app.pendingFile = arg; + if ((arg.endsWith('.md') || arg.endsWith('.markdown'))) { + const resolvedPath = path.isAbsolute(arg) ? arg : path.resolve(workingDirectory, arg); + console.log('[MAIN] Second instance resolved path:', resolvedPath); + if (fs.existsSync(resolvedPath)) { + // Open the file in the existing instance + if (rendererReady) { + openFileFromPath(resolvedPath); + } else { + app.pendingFile = resolvedPath; + } + break; } - break; } } }); @@ -112,9 +119,6 @@ function createWindow() { mainWindow.loadFile(path.join(__dirname, 'index.html')); - // Open DevTools for debugging - mainWindow.webContents.openDevTools(); - createMenu(); mainWindow.on('closed', () => { @@ -463,7 +467,7 @@ function createMenu() { type: 'info', title: 'About PanConverter', message: 'PanConverter', - detail: 'A cross-platform Markdown editor and converter using Pandoc.\n\nVersion: 1.7.7\nAuthor: Amit Haridas\nEmail: amit.wh@gmail.com\nLicense: MIT\n\nFeatures:\n• Modern glassmorphism UI with gradient backgrounds\n• Comprehensive PDF Editor (merge, split, compress, rotate, watermark, encrypt)\n• Universal File Converter (LibreOffice, ImageMagick, FFmpeg, Pandoc)\n• Windows Explorer context menu integration\n• Tabbed interface for multiple files\n• Advanced markdown editing with live preview\n• Real-time preview updates while typing\n• Full toolbar markdown editing functions\n• Enhanced PDF export with built-in Electron fallback\n• File association support for .md files\n• Command-line interface for batch conversion\n• Advanced export options with templates and metadata\n• Batch file conversion with progress tracking\n• Improved preview typography and spacing\n• Adjustable font sizes via menu (Ctrl+Shift+Plus/Minus)\n• Complete theme support including Monokai fixes\n• Find & replace with match highlighting\n• Line numbers and auto-indentation\n• Export to multiple formats via Pandoc\n• PowerPoint & presentation export\n• Export tables to Excel/ODS spreadsheets\n• Document import & conversion\n• Table creation helper\n• 22 beautiful themes (including Dracula, Nord, Tokyo Night, Gruvbox, Ayu, Concrete, and more)\n• Undo/redo functionality\n• Live word count and statistics', + detail: 'A cross-platform Markdown editor and converter using Pandoc.\n\nVersion: 1.7.8\nAuthor: Amit Haridas\nEmail: amit.wh@gmail.com\nLicense: MIT\n\nFeatures:\n• Modern glassmorphism UI with gradient backgrounds\n• Comprehensive PDF Editor (merge, split, compress, rotate, watermark, encrypt)\n• Universal File Converter (LibreOffice, ImageMagick, FFmpeg, Pandoc)\n• Windows Explorer context menu integration\n• Tabbed interface for multiple files\n• Advanced markdown editing with live preview\n• Real-time preview updates while typing\n• Full toolbar markdown editing functions\n• Enhanced PDF export with built-in Electron fallback\n• File association support for .md files\n• Command-line interface for batch conversion\n• Advanced export options with templates and metadata\n• Batch file conversion with progress tracking\n• Improved preview typography and spacing\n• Adjustable font sizes via menu (Ctrl+Shift+Plus/Minus)\n• Complete theme support including Monokai fixes\n• Find & replace with match highlighting\n• Line numbers and auto-indentation\n• Export to multiple formats via Pandoc\n• PowerPoint & presentation export\n• Export tables to Excel/ODS spreadsheets\n• Document import & conversion\n• Table creation helper\n• 22 beautiful themes (including Dracula, Nord, Tokyo Night, Gruvbox, Ayu, Concrete, and more)\n• Undo/redo functionality\n• Live word count and statistics', buttons: ['OK'] }); } @@ -1596,16 +1600,32 @@ app.whenReady().then(() => { createWindow(); // Handle file association on app startup - // Process all command line arguments except the first two (node and script path) - const fileArgs = process.argv.slice(2); - console.log('[MAIN] Command line args:', process.argv); - console.log('[MAIN] File args to process:', fileArgs); + // In packaged apps, process.argv structure is different: + // Development: ['electron', 'app.js', 'file.md'] - need slice(2) + // Packaged: ['PanConverter.exe', 'file.md'] - need slice(1) + // We'll check all arguments after the executable + console.log('[MAIN] Full command line args:', JSON.stringify(process.argv)); + console.log('[MAIN] App is packaged:', app.isPackaged); + + // Start from index 1 (skip executable) and check each argument + const startIndex = app.isPackaged ? 1 : 2; + const fileArgs = process.argv.slice(startIndex); + console.log('[MAIN] File args to process (starting from index', startIndex + '):', fileArgs); + for (const arg of fileArgs) { - if ((arg.endsWith('.md') || arg.endsWith('.markdown')) && fs.existsSync(arg)) { - // Store the file to open after window is ready - console.log('[MAIN] Setting pendingFile to:', arg); - app.pendingFile = arg; - break; + console.log('[MAIN] Checking arg:', arg); + if ((arg.endsWith('.md') || arg.endsWith('.markdown'))) { + // Try to resolve the path (might be relative) + const resolvedPath = path.isAbsolute(arg) ? arg : path.resolve(process.cwd(), arg); + console.log('[MAIN] Resolved path:', resolvedPath); + if (fs.existsSync(resolvedPath)) { + // Store the file to open after window is ready + console.log('[MAIN] Setting pendingFile to:', resolvedPath); + app.pendingFile = resolvedPath; + break; + } else { + console.log('[MAIN] File does not exist:', resolvedPath); + } } } console.log('[MAIN] Final app.pendingFile:', app.pendingFile); diff --git a/src/renderer.js b/src/renderer.js index b919a63..b92d3e3 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -1184,65 +1184,23 @@ function handlePrintPreview(withStyles) { return; } - // Hide UI elements - const toolbar = document.getElementById('toolbar'); - const tabBar = document.getElementById('tab-bar'); - const statusBar = document.getElementById('status-bar'); - - if (toolbar) toolbar.style.display = 'none'; - if (tabBar) tabBar.style.display = 'none'; - if (statusBar) statusBar.style.display = 'none'; - - const editorPane = document.getElementById(`editor-pane-${activeTabId}`); - if (editorPane) { - editorPane.style.display = 'none'; + // Add print style classes to body for styling control + // The @media print CSS will handle hiding toolbar/tabs automatically + if (!withStyles) { + document.body.classList.add('printing-no-styles'); } + document.body.classList.add('printing'); - // Hide all dialogs - const dialogs = [ - 'export-dialog', 'batch-dialog', 'pdf-editor-dialog', - 'converter-dialog', 'find-dialog' - ]; - dialogs.forEach(id => { - const dialog = document.getElementById(id); - if (dialog) dialog.style.display = 'none'; - }); - - // Apply print-mode to preview pane - const previewPane = document.getElementById(`preview-pane-${activeTabId}`); - if (previewPane) { - previewPane.classList.add('print-mode'); - if (!withStyles) { - previewPane.classList.add('print-no-styles'); - } - } - - // Wait for DOM to render the changes before printing - // Use setTimeout to ensure browser has time to repaint + // Give browser time to apply classes before printing setTimeout(() => { - // Tell main process to print - the DOM is now fully rendered + // Tell main process to print ipcRenderer.send('do-print', { withStyles }); - // Restore UI after a delay (printer will have captured the output by then) + // Restore classes after print dialog appears setTimeout(() => { - if (toolbar) toolbar.style.display = ''; - if (tabBar) tabBar.style.display = ''; - if (statusBar) statusBar.style.display = ''; - - if (editorPane) { - editorPane.style.display = ''; - } - - dialogs.forEach(id => { - const dialog = document.getElementById(id); - if (dialog) dialog.style.display = ''; - }); - - if (previewPane) { - previewPane.classList.remove('print-mode', 'print-no-styles'); - } - }, 500); - }, 300); + document.body.classList.remove('printing', 'printing-no-styles'); + }, 1000); + }, 100); } // Export Dialog functionality diff --git a/src/styles.css b/src/styles.css index f96185f..1af5189 100644 --- a/src/styles.css +++ b/src/styles.css @@ -2833,14 +2833,19 @@ body.theme-concrete-warm .status-bar { #editor-container, .editor-container, #status-bar, - .status-bar { + .status-bar, + .editor-pane, + [id^="editor-pane-"] { display: none !important; } /* Show preview in full width */ #preview, .preview, - .preview-content { + .preview-content, + [id^="preview-"], + [id^="preview-pane-"], + .tab-content { display: block !important; width: 100% !important; max-width: 100% !important; @@ -2848,10 +2853,12 @@ body.theme-concrete-warm .status-bar { margin: 0 !important; padding: 20px !important; overflow: visible !important; + position: static !important; } /* Optimize preview content for printing */ - .preview-content { + .preview-content, + [id^="preview-"] { line-height: 1.6; font-size: 12pt; color: #000 !important; @@ -2969,11 +2976,20 @@ body.theme-concrete-warm .status-bar { display: block !important; } +/* No-styles printing mode */ +body.printing-no-styles .preview-content, +body.printing-no-styles [id^="preview-"], .print-no-styles .preview-content { color: #000 !important; background: white !important; } +body.printing-no-styles .preview-content h1, +body.printing-no-styles .preview-content h2, +body.printing-no-styles .preview-content h3, +body.printing-no-styles .preview-content h4, +body.printing-no-styles .preview-content h5, +body.printing-no-styles .preview-content h6, .print-no-styles .preview-content h1, .print-no-styles .preview-content h2, .print-no-styles .preview-content h3, @@ -2984,11 +3000,13 @@ body.theme-concrete-warm .status-bar { border-color: #999 !important; } +body.printing-no-styles .preview-content code, .print-no-styles .preview-content code { background: #f5f5f5 !important; color: #000 !important; } +body.printing-no-styles .preview-content pre, .print-no-styles .preview-content pre { background: #f5f5f5 !important; color: #000 !important;