July 21, 2024
O Wolfson
How to convert a Markdown file to a PDF using Node.js. We'll use the puppeteer-core library to generate the PDF and markdown-it to parse the Markdown content. Additionally, we'll add custom styling, including margins and page breaks.
Here is a deployed version of the code: https://md2pdf.owolf.com/
Before we begin, ensure you have Node.js installed. You'll also need to install the following packages:
puppeteer-coremarkdown-itmarkdown-it-containerYou can install these packages using npm:
bashnpm install puppeteer-core markdown-it markdown-it-container
First, create a new file called convertMarkdownToPdf.js and add the following code:
javascriptconst fs = require("fs");
const path = require("path");
const puppeteer = require("puppeteer-core");
const markdownIt = require("markdown-it");
const markdownItContainer = require("markdown-it-container");
This code imports the necessary modules:
fs and path for file system operations.puppeteer-core to generate the PDF.markdown-it and markdown-it-container to parse the Markdown content and handle custom HTML containers.Next, we configure markdown-it to use the markdown-it-container plugin for custom HTML containers:
javascriptconst md = markdownIt().use(markdownItContainer, "pagebreak", {
render(tokens, idx) {
if (tokens[idx].nesting === 1) {
return '<div style="page-break-after: always;"></div>';
} else {
return "";
}
},
});
This configuration allows us to use ::: pagebreak ::: in our Markdown file to insert a page break in the PDF.
We create a function to convert Markdown content to HTML and include custom styling:
javascriptfunction convertMarkdownToHtml(markdown) {
const htmlContent = md.render(markdown);
return `
<html>
<head>
<style>
body {
padding: 20px;
font-family: Arial, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 20px;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
}
</style>
</head>
<body>
${htmlContent}
</body>
</html>
`;
}
This function takes the Markdown content, converts it to HTML, and wraps it with additional styling for padding and margins.
We then create a function to convert the HTML content to a PDF using Puppeteer:
javascriptasync function convertHtmlToPdf(html, outputPath) {
const browser = await puppeteer.launch({
executablePath:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", // Update this path
});
const page = await browser.newPage();
await page.setContent(html, { waitUntil: "networkidle0" });
await page.pdf({
path: outputPath,
format: "A4",
margin: {
top: "20mm",
right: "20mm",
bottom: "20mm",
left: "20mm",
},
});
await browser.close();
console.log(`Converted to PDF: ${outputPath}`);
}
Ensure the executablePath points to your Chrome executable. You can find the path using:
which /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chromewhich google-chromeC:\Program Files\Google\Chrome\Application\chrome.exeFinally, we create the main function to read the Markdown file, convert it to HTML, and then to a PDF:
javascriptasync function convertMarkdownToPdf(inputPath, outputPath) {
const markdown = fs.readFileSync(inputPath, "utf-8");
const html = convertMarkdownToHtml(markdown);
await convertHtmlToPdf(html, outputPath);
}
// Example usage
const inputMarkdownPath = path.join(__dirname, "example.md");
const outputPdfPath = path.join(__dirname, "example.pdf");
// Ensure the markdown file exists
if (fs.existsSync(inputMarkdownPath)) {
convertMarkdownToPdf(inputMarkdownPath, outputPdfPath).catch(console.error);
} else {
console.log(`Markdown file not found: ${inputMarkdownPath}`);
}
This function reads the content of example.md, converts it to HTML, and then generates a PDF example.pdf.
Ensure your example.md file is in the same directory as the script. The Markdown file can contain the following content for testing:
markdown# Example Markdown
This is a sample markdown file.
## Section 1
Here is some content for section 1.
::: pagebreak :::
## Section 2
Here is some content for section 2.
---
Some more content after a horizontal rule.
Run the script using Node.js:
bashnode convertMarkdownToPdf.js
This will generate example.pdf with the specified formatting and page breaks.
By following this guide, you can convert Markdown files to PDFs with custom styling and page breaks using Node.js, Puppeteer, and Markdown-it. This method provides a flexible way to generate professional-looking PDFs from Markdown content.