Files
markdown-converter/src/renderer/lib/pdf-export.ts
T
amitwh cf6b6817b9 fix: wire orphaned IPC channels, fix data-loss bug, print preview events, sidebar navigation
- Fix file.clearRecent sending IPC to main process instead of clearing openTabs
- Wire show-batch-converter, show-document-compare, open-header-footer-dialog IPC channels
- Add print preview event listeners (mc:print-preview, mc:print-preview-styled) in App.tsx
- Fix sidebar hidden bridge buttons toggling sidebar closed after scroll
- Update sidebar menu labels to match actual sections (Files, Outline, Git)
- Fix ipc.print to be an object with show/doPrint methods (was bare function)
- Update callers: ExportPdfDialog, pdf-export, PrintPreview
- Add 7 regression tests for all fixes
- Clean 2 obsolete snapshots
- Build Linux packages (deb, AppImage, snap) — 549 tests passing
2026-06-11 07:15:33 +05:30

51 lines
1.8 KiB
TypeScript

/**
* Renderer-side Markdown → PDF export.
*
* Opens the file in a hidden iframe with the rendered HTML, then triggers
* `window.print()` with the print stylesheet active. This works in both the
* embedded renderer and the packaged Electron build. For non-interactive
* export we fall back to the legacy `do-print` channel.
*/
import { generateHtml } from './html-export';
import { ipc } from './ipc';
import { toast } from './toast';
export interface PdfExportOptions {
source: string;
title: string;
format: 'letter' | 'a4' | 'legal';
margins: { top: number; right: number; bottom: number; left: number };
embedFonts: boolean;
fontSize: number;
}
const FORMAT_DIMENSIONS: Record<PdfExportOptions['format'], { width: string; height: string }> = {
letter: { width: '8.5in', height: '11in' },
a4: { width: '210mm', height: '297mm' },
legal: { width: '8.5in', height: '14in' },
};
export async function generatePdf(options: PdfExportOptions): Promise<void> {
const html = generateHtml({
source: options.source,
title: options.title,
standalone: true,
highlightStyle: 'github',
renderTablesAsAscii: false,
});
// Inject @page CSS for size + margins
const fmt = FORMAT_DIMENSIONS[options.format];
const m = options.margins;
const pageCss = `@page { size: ${fmt.width} ${fmt.height}; margin: ${m.top}mm ${m.right}mm ${m.bottom}mm ${m.left}mm; }`;
const finalHtml = html.replace('</style>', `${pageCss}</style>`);
// Hand the rendered HTML to the main process for native print-to-PDF.
// This avoids the print dialog and works headlessly.
const result = await ipc.print.show({ html: finalHtml });
if (!result.ok) {
toast.error(`PDF export failed: ${result.error?.message ?? 'unknown error'}`);
} else {
toast.success(`Sent ${options.title} to printer`);
}
}