Compare PDF and Markdown conversion
Share conversion settings and reuse one document session for PDF and Markdown output.
Export both formats from one session
Open the document through the PDF package to get one font-backed layout for both formats. The following example exports Markdown with images and a PDF, then disposes the session:
import { readFile } from 'node:fs/promises';
import { openDocumentForExport, exportPdfFrom } from '@docx-editor.dev/docx-to-pdf';
import { exportMarkdownFrom } from '@docx-editor.dev/docx-to-markdown';
const opened = await openDocumentForExport(await readFile('document.docx'), {
displayMode: 'proposed',
useSystemFonts: false,
});
if (!opened.ok) throw new Error(opened.reason);
try {
const markdown = await exportMarkdownFrom(opened.session, { images: true });
const pdf = await exportPdfFrom(opened.session);
console.log(markdown.pages.length, pdf.pageCount);
} finally {
opened.session.dispose();
}You own the session. Dispose it in finally, because a failed export never disposes it. Both exporters read the same cached layout, font evidence, and PDF shaping policy.
Choose shared settings
If you convert each format separately with exportPdf and exportMarkdown, pass matching settings:
| Setting | Guidance |
|---|---|
fonts, fallbackFonts | Pass the same sources to both. Both packages export createFontSource and defineFontResolver. |
fontPolicy, onFontResolution | Same meaning in both. Strict checks coverage and source failures, not author font selection. |
displayMode | Both default to 'all-markup'. Set it explicitly to match. |
signal, resourceTimeoutMs | Same meaning in both. |
useSystemFonts: false | PDF only. Matches the Markdown default, which skips installed fonts. |
documentLigatures: false | PDF only. Matches the Markdown default, which leaves optional ligatures off. |
Matching settings do not guarantee identical pagination. Missing glyphs, fallback faces, and unsupported features can still differ.
Compare format behavior
| Area | Markdown | |
|---|---|---|
| Source | DOCX bytes or supported live views | DOCX bytes only |
| Primary output | result.markdown | result.bytes |
| Page data | result.pages | result.pageCount |
| Page metadata | result.pagination.layoutRevision and .displayMode | result.layoutRevision and .displayMode |
| Content notices | result.warnings | result.diagnostics, with severity |
| Notice page location | Optional one-based pageNumber | One-based pageNumber and zero-based pageIndex |
| Open refusal | DocumentOpenError | PdfDocumentOpenError |
| Font discovery | Packaged and embedded sources | Installed, packaged, and embedded sources |
| Optional ligatures | Off | On unless documentLigatures is false |
| Unsupported content | Warnings for omissions | Strict refusal by default; fidelityPolicy: 'best-effort' |
| Comments | Structured review data | Native PDF annotations, unless comments is false |
| Charts | Saved fallback picture | Drawn by the drawing module, or the saved fallback |
| Reuse | Export sessions and detached layouts | Font-backed export sessions only |
| PDF-only controls | None | fidelityPolicy, timeoutMs, maxPages, maxOutputBytes |
Limits
- Markdown image output needs
images: true, also from a shared session. - Markdown-opened sessions use other font and ligature settings. Strict PDF conversion can refuse them for missing font identities or unshaped text.
exportPdfFromacceptsdisplayModefor another cached projection. The session default stays the same.- Add one to a PDF
pageIndexbefore you compare it to a MarkdownpageNumber. - Layout revisions are not persistent document identifiers. Store the input version with page references.
- For cancellation and session ownership, see Reuse a session. For chart rendering, see Use the module without an editor.