mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 10:00:17 +05:30
Enhance print menu with preview-only printing options (v1.7.7)
- Added Print submenu to File menu with two print options: * Print Preview (Ctrl+P): Black text, no colors, ink-saving * Print Preview (With Styles): Full colors and styling - Implemented print handler that hides all editor UI and shows only preview - Editor, toolbar, tabs, and status bar hidden during printing - Added comprehensive CSS print stylesheet with: * Smart page breaks for headings, tables, and paragraphs * Optimized formatting for code blocks, lists, and tables * Professional typography (12pt font size, 1.6 line height) * Image optimization and proper link handling * Support for blockquotes, horizontal rules, and other elements - Print-specific CSS classes for styling control - Preview automatically restored after printing Features: - Prints only the rendered markdown preview (not source) - Two print modes: simple (black) and styled (colored) - Native OS print dialogs for all platforms - Professional output formatting with page breaks - Cross-platform support (Windows, macOS, Linux) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
@@ -116,38 +116,91 @@ gh release create v1.2.1 --title "Title" --notes "Release notes" \
|
|||||||
### v1.7.7 Print & Enhanced PDF Support (Latest)
|
### v1.7.7 Print & Enhanced PDF Support (Latest)
|
||||||
|
|
||||||
#### 🖨️ Native Print Functionality
|
#### 🖨️ Native Print Functionality
|
||||||
**Added Print Command** (`src/main.js:202-206`, `src/renderer.js:1152-1162`)
|
**Added Print Submenu to File Menu** (`src/main.js:202-215`, `src/renderer.js:1152-1188`, `src/styles.css:2828-2994`)
|
||||||
- **Print Menu Item**: Added to File menu with `Ctrl+P` keyboard shortcut
|
- **Print Menu**: Submenu in File menu with two print options
|
||||||
|
- **Print Preview** (`Ctrl+P`) - Prints preview in black text, no background colors (ink-saving)
|
||||||
|
- **Print Preview (With Styles)** - Prints with full theme colors and styling
|
||||||
|
- **Preview-Only Printing**: Only renders the markdown preview, hides all editor UI
|
||||||
- **Native Print Dialog**: Uses Electron's webContents.print() for native OS print dialogs
|
- **Native Print Dialog**: Uses Electron's webContents.print() for native OS print dialogs
|
||||||
- **Print Settings**: Configured with background color printing and proper margins
|
- **Professional Output**: Automatically hides editor, toolbar, tabs, and status bar during print
|
||||||
- **Preview-Based Printing**: Prints the rendered markdown preview for professional output
|
- **Print Optimization**: Smart page breaks, proper formatting for headings, code blocks, tables
|
||||||
- **Cross-Platform**: Works on Windows, macOS, and Linux with native printer support
|
- **Cross-Platform**: Works on Windows, macOS, and Linux with native printer support
|
||||||
|
|
||||||
|
**Print Options:**
|
||||||
|
1. **Print Preview** (Ctrl+P)
|
||||||
|
- Black text on white background for professional printing
|
||||||
|
- No background colors to save ink
|
||||||
|
- Perfect for documents and reports
|
||||||
|
- Minimal ink consumption
|
||||||
|
|
||||||
|
2. **Print Preview (With Styles)**
|
||||||
|
- Full theme colors and styling
|
||||||
|
- Preserves markdown formatting with visual hierarchy
|
||||||
|
- Better for design-focused documents
|
||||||
|
- Shows code blocks with colored syntax highlighting
|
||||||
|
|
||||||
**Technical Implementation:**
|
**Technical Implementation:**
|
||||||
```javascript
|
```javascript
|
||||||
// Main process handler
|
// Main process - two print handlers
|
||||||
ipcMain.on('print-document', (event) => {
|
ipcMain.on('print-preview', (event) => {
|
||||||
if (mainWindow) {
|
mainWindow.webContents.send('prepare-print-preview', false);
|
||||||
|
setTimeout(() => {
|
||||||
|
mainWindow.webContents.print({
|
||||||
|
silent: false,
|
||||||
|
printBackground: false,
|
||||||
|
color: true,
|
||||||
|
margin: { marginType: 'default' }
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.on('print-preview-styled', (event) => {
|
||||||
|
mainWindow.webContents.send('prepare-print-preview', true);
|
||||||
|
setTimeout(() => {
|
||||||
mainWindow.webContents.print({
|
mainWindow.webContents.print({
|
||||||
silent: false,
|
silent: false,
|
||||||
printBackground: true,
|
printBackground: true,
|
||||||
color: true,
|
color: true,
|
||||||
margin: { marginType: 'default' }
|
margin: { marginType: 'default' }
|
||||||
});
|
});
|
||||||
}
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Renderer process handler
|
// Renderer process - prepares preview for printing
|
||||||
ipcRenderer.on('print-document', () => {
|
ipcRenderer.on('prepare-print-preview', (event, withStyles) => {
|
||||||
const previewContent = document.getElementById('preview');
|
// Hide editor and UI elements
|
||||||
if (previewContent && previewContent.innerHTML.trim()) {
|
document.getElementById('editor-container').style.display = 'none';
|
||||||
window.print();
|
document.getElementById('toolbar').style.display = 'none';
|
||||||
} else {
|
document.getElementById('tab-bar').style.display = 'none';
|
||||||
alert('Nothing to print. Please create or open a document and ensure the preview is visible.');
|
document.getElementById('status-bar').style.display = 'none';
|
||||||
|
|
||||||
|
// Add print mode classes
|
||||||
|
const preview = document.getElementById('preview');
|
||||||
|
preview.classList.add('print-mode');
|
||||||
|
if (!withStyles) {
|
||||||
|
preview.classList.add('print-no-styles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore UI after print
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById('editor-container').style.display = '';
|
||||||
|
document.getElementById('toolbar').style.display = '';
|
||||||
|
document.getElementById('tab-bar').style.display = '';
|
||||||
|
document.getElementById('status-bar').style.display = '';
|
||||||
|
preview.classList.remove('print-mode', 'print-no-styles');
|
||||||
|
}, 500);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**CSS Print Styles** (`src/styles.css:2828-2994`)
|
||||||
|
- Comprehensive @media print stylesheet
|
||||||
|
- Hides all UI elements in print view
|
||||||
|
- Optimizes preview for paper output
|
||||||
|
- Smart page breaks for headings and tables
|
||||||
|
- Proper formatting for code blocks, lists, tables
|
||||||
|
- Image optimization and link handling
|
||||||
|
- Professional typography with 12pt font size
|
||||||
|
|
||||||
#### 📦 Enhanced PDF Export Dependencies
|
#### 📦 Enhanced PDF Export Dependencies
|
||||||
**Added Native PDF Generation Libraries** (package.json)
|
**Added Native PDF Generation Libraries** (package.json)
|
||||||
- **PDFKit** (v0.14.0) - Native PDF generation without Pandoc dependency
|
- **PDFKit** (v0.14.0) - Native PDF generation without Pandoc dependency
|
||||||
@@ -730,4 +783,4 @@ if (!gotTheLock) {
|
|||||||
---
|
---
|
||||||
|
|
||||||
**Last Updated**: October 24, 2025
|
**Last Updated**: October 24, 2025
|
||||||
**Claude Assistant**: Development completed for v1.7.7 with native print functionality (Ctrl+P) and enhanced PDF support through PDFKit and html2pdf libraries. Added print command with native OS print dialogs for cross-platform printing of rendered markdown. Remapped Toggle Preview from Ctrl+P to Ctrl+Shift+P. Previous releases include v1.7.6 table header styling cleanup for cleaner preview appearance, and v1.7.5 critical file association fix with single-instance lock implementation.
|
**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.
|
||||||
+34
-4
@@ -201,8 +201,17 @@ function createMenu() {
|
|||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: 'Print',
|
label: 'Print',
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Print Preview',
|
||||||
accelerator: 'CmdOrCtrl+P',
|
accelerator: 'CmdOrCtrl+P',
|
||||||
click: () => mainWindow.webContents.send('print-document')
|
click: () => mainWindow.webContents.send('print-preview')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Print Preview (With Styles)',
|
||||||
|
click: () => mainWindow.webContents.send('print-preview-styled')
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
@@ -1157,16 +1166,37 @@ ipcMain.on('set-current-file', (event, filePath) => {
|
|||||||
currentFile = filePath;
|
currentFile = filePath;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle print document
|
// Handle print preview
|
||||||
ipcMain.on('print-document', (event) => {
|
ipcMain.on('print-preview', (event) => {
|
||||||
if (mainWindow) {
|
if (mainWindow) {
|
||||||
// Open native print dialog
|
// Prepare for printing preview only (black text, no colors)
|
||||||
|
mainWindow.webContents.send('prepare-print-preview', false);
|
||||||
|
// Give renderer time to prepare, then print
|
||||||
|
setTimeout(() => {
|
||||||
|
mainWindow.webContents.print({
|
||||||
|
silent: false,
|
||||||
|
printBackground: false,
|
||||||
|
color: true,
|
||||||
|
margin: { marginType: 'default' }
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle print preview with styles
|
||||||
|
ipcMain.on('print-preview-styled', (event) => {
|
||||||
|
if (mainWindow) {
|
||||||
|
// Prepare for printing preview with colors
|
||||||
|
mainWindow.webContents.send('prepare-print-preview', true);
|
||||||
|
// Give renderer time to prepare, then print
|
||||||
|
setTimeout(() => {
|
||||||
mainWindow.webContents.print({
|
mainWindow.webContents.print({
|
||||||
silent: false,
|
silent: false,
|
||||||
printBackground: true,
|
printBackground: true,
|
||||||
color: true,
|
color: true,
|
||||||
margin: { marginType: 'default' }
|
margin: { marginType: 'default' }
|
||||||
});
|
});
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+33
-7
@@ -1149,16 +1149,42 @@ ipcRenderer.on('adjust-font-size', (event, action) => {
|
|||||||
updateFontSizes(currentFontSize);
|
updateFontSizes(currentFontSize);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Print document handler
|
// Print preview handler - prepare for printing
|
||||||
ipcRenderer.on('print-document', () => {
|
ipcRenderer.on('prepare-print-preview', (event, withStyles) => {
|
||||||
// Use the preview pane for printing
|
|
||||||
const previewContent = document.getElementById('preview');
|
const previewContent = document.getElementById('preview');
|
||||||
if (previewContent && previewContent.innerHTML.trim()) {
|
|
||||||
// Create a print window with the preview content
|
if (!previewContent || !previewContent.innerHTML.trim()) {
|
||||||
window.print();
|
|
||||||
} else {
|
|
||||||
alert('Nothing to print. Please create or open a document and ensure the preview is visible.');
|
alert('Nothing to print. Please create or open a document and ensure the preview is visible.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide editor and other UI elements for print
|
||||||
|
document.getElementById('editor-container').style.display = 'none';
|
||||||
|
document.getElementById('toolbar').style.display = 'none';
|
||||||
|
document.getElementById('tab-bar').style.display = 'none';
|
||||||
|
document.getElementById('status-bar').style.display = 'none';
|
||||||
|
|
||||||
|
// Show preview in full width
|
||||||
|
const preview = document.getElementById('preview');
|
||||||
|
if (preview) {
|
||||||
|
preview.classList.add('print-mode');
|
||||||
|
if (!withStyles) {
|
||||||
|
preview.classList.add('print-no-styles');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-show everything after print
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById('editor-container').style.display = '';
|
||||||
|
document.getElementById('toolbar').style.display = '';
|
||||||
|
document.getElementById('tab-bar').style.display = '';
|
||||||
|
document.getElementById('status-bar').style.display = '';
|
||||||
|
|
||||||
|
const preview = document.getElementById('preview');
|
||||||
|
if (preview) {
|
||||||
|
preview.classList.remove('print-mode', 'print-no-styles');
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export Dialog functionality
|
// Export Dialog functionality
|
||||||
|
|||||||
+168
@@ -2824,3 +2824,171 @@ body.theme-concrete-warm .status-bar {
|
|||||||
border-top-color: #9a9696;
|
border-top-color: #9a9696;
|
||||||
color: #e3e3e3;
|
color: #e3e3e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print Styles */
|
||||||
|
@media print {
|
||||||
|
/* Hide UI elements for clean print output */
|
||||||
|
#toolbar,
|
||||||
|
#tab-bar,
|
||||||
|
#editor-container,
|
||||||
|
.editor-container,
|
||||||
|
#status-bar,
|
||||||
|
.status-bar {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show preview in full width */
|
||||||
|
#preview,
|
||||||
|
.preview,
|
||||||
|
.preview-content {
|
||||||
|
display: block !important;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
height: auto !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 20px !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optimize preview content for printing */
|
||||||
|
.preview-content {
|
||||||
|
line-height: 1.6;
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #000 !important;
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text formatting */
|
||||||
|
.preview-content h1,
|
||||||
|
.preview-content h2,
|
||||||
|
.preview-content h3,
|
||||||
|
.preview-content h4,
|
||||||
|
.preview-content h5,
|
||||||
|
.preview-content h6 {
|
||||||
|
page-break-after: avoid;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content p {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
.preview-content pre {
|
||||||
|
background: #f5f5f5 !important;
|
||||||
|
border: 1px solid #ddd !important;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content code {
|
||||||
|
background: #f5f5f5 !important;
|
||||||
|
color: #000 !important;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
.preview-content ul,
|
||||||
|
.preview-content ol {
|
||||||
|
margin-left: 20px;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content li {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
.preview-content table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content th,
|
||||||
|
.preview-content td {
|
||||||
|
border: 1px solid #999 !important;
|
||||||
|
padding: 8px !important;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content th {
|
||||||
|
background: #f0f0f0 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links - remove underline for print */
|
||||||
|
.preview-content a {
|
||||||
|
color: #000 !important;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blockquotes */
|
||||||
|
.preview-content blockquote {
|
||||||
|
border-left: 3px solid #ccc;
|
||||||
|
padding-left: 15px;
|
||||||
|
margin-left: 0;
|
||||||
|
color: #333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Images */
|
||||||
|
.preview-content img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal rules */
|
||||||
|
.preview-content hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #999;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print mode classes */
|
||||||
|
.print-mode {
|
||||||
|
display: block !important;
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content {
|
||||||
|
color: #000 !important;
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content h1,
|
||||||
|
.print-no-styles .preview-content h2,
|
||||||
|
.print-no-styles .preview-content h3,
|
||||||
|
.print-no-styles .preview-content h4,
|
||||||
|
.print-no-styles .preview-content h5,
|
||||||
|
.print-no-styles .preview-content h6 {
|
||||||
|
color: #000 !important;
|
||||||
|
border-color: #999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content code {
|
||||||
|
background: #f5f5f5 !important;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content pre {
|
||||||
|
background: #f5f5f5 !important;
|
||||||
|
color: #000 !important;
|
||||||
|
border-color: #999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content a {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-no-styles .preview-content blockquote {
|
||||||
|
color: #333 !important;
|
||||||
|
border-color: #999 !important;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user