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-core
markdown-it
markdown-it-container
You 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\ Chrome
which google-chrome
C:\Program Files\Google\Chrome\Application\chrome.exe
Finally, 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.