Plutobook
Paged HTML Rendering Library
Install / Use
/learn @plutoprint/PlutobookREADME
Prefer Python? Try PlutoPrint — a Python library built on PlutoBook for easy paged HTML rendering.
PlutoBook
PlutoBook is a robust HTML rendering library tailored for paged media. It takes HTML or XML as input, applies CSS stylesheets, and lays out elements across one or more pages, which can then be rendered as Bitmap images or PDF documents.
[!NOTE] PlutoBook implements its own rendering engine and does not depend on rendering engines like Chromium, WebKit, or Gecko.
The engine is designed to be robust, lightweight, and memory-efficient, leveraging modern C++ features such asstd::pmr::monotonic_buffer_resourceto minimize memory fragmentation and optimize allocation performance.
Testimonial
"PlutoBook is incredibly fast and lightweight. In my invoicing app (built in 2010), I replaced headless Chrome with PlutoBook and saw at least a 10× speed improvement and 10× lower memory usage, while achieving similar output quality."
— Nikola Radovanović
Basic Usage
This example creates a PDF from inline HTML using plutobook. It sets up a book with A4 page size and narrow margins (36 points or 0.5 inches on all sides), then writes the output to hello.pdf.
#include <plutobook.hpp>
static const char kHTMLContent[] = R"HTML(
<!DOCTYPE html>
<html lang="la">
<head>
<meta charset="UTF-8">
<title>Magnum Scopulum Corallinum</title>
<style>
body { font-family: "Segoe UI", sans-serif; line-height: 1.6; margin: 40px auto; max-width: 800px; color: #222; }
h1 { font-size: 2.5em; margin-bottom: 20px; }
img { width: 100%; border-radius: 6px; margin-bottom: 20px; }
p { font-size: 1.05em; text-align: justify; }
</style>
</head>
<body>
<h1>Magnum Scopulum Corallinum</h1>
<img src="https://picsum.photos/id/128/800/400" alt="Magnum Scopulum Corallinum">
<p>Magnum Scopulum Corallinum est maximum systema scopulorum corallinorum in mundo, quod per plus quam 2,300 chiliometra oram septentrionalem-orientalem Australiae extenditur. Ex milibus scopulorum individualium et centenis insularum constat, e spatio videri potest et inter mirabilia naturalia mundi numeratur.</p>
<p>Domus est incredibili diversitati vitae marinae, cum plus quam 1,500 speciebus piscium, 400 generibus corallii, et innumerabilibus aliis organismis. Partem vitalem agit in salute oecosystematis marini conservanda et sustentat victum communitatum litoralium per otium et piscationem.</p>
<p>Quamquam pulchritudinem ac significationem oecologicam praebet, Magnum Scopulum Corallinum minas continenter patitur ex mutatione climatis, pollutione, et nimia piscatione. Eventus albi corallii ex temperaturis marinis crescentibus magnam partem scopuli nuper laeserunt. Conatus conservatorii toto orbe suscipiuntur ad hunc magnificum oecosystema subaquaneum tuendum et restaurandum.</p>
</body>
</html>
)HTML";
int main()
{
plutobook::Book book(plutobook::PageSize::A4, plutobook::PageMargins::Narrow);
book.loadHtml(kHTMLContent);
book.writeToPdf("hello.pdf");
return 0;
}
<details>
<summary><b>Equivalent in C</b></summary>
#include <plutobook.h>
static const char kHTMLContent[] =
"<!DOCTYPE html>\n"
"<html lang=\"la\">\n"
"<head>\n"
" <meta charset=\"UTF-8\">\n"
" <title>Magnum Scopulum Corallinum</title>\n"
" <style>\n"
" body { font-family: \"Segoe UI\", sans-serif; line-height: 1.6; margin: 40px auto; max-width: 800px; color: #222; }\n"
" h1 { font-size: 2.5em; margin-bottom: 20px; }\n"
" img { width: 100%; border-radius: 6px; margin-bottom: 20px; }\n"
" p { font-size: 1.05em; text-align: justify; }\n"
" </style>\n"
"</head>\n"
"<body>\n"
" <h1>Magnum Scopulum Corallinum</h1>\n"
" <img src=\"https://picsum.photos/id/128/800/400\" alt=\"Magnum Scopulum Corallinum\">\n"
" <p>Magnum Scopulum Corallinum est maximum systema scopulorum corallinorum in mundo, quod per plus quam 2,300 chiliometra oram septentrionalem-orientalem Australiae extenditur. Ex milibus scopulorum individualium et centenis insularum constat, e spatio videri potest et inter mirabilia naturalia mundi numeratur.</p>\n"
" <p>Domus est incredibili diversitati vitae marinae, cum plus quam 1,500 speciebus piscium, 400 generibus corallii, et innumerabilibus aliis organismis. Partem vitalem agit in salute oecosystematis marini conservanda et sustentat victum communitatum litoralium per otium et piscationem.</p>\n"
" <p>Quamquam pulchritudinem ac significationem oecologicam praebet, Magnum Scopulum Corallinum minas continenter patitur ex mutatione climatis, pollutione, et nimia piscatione. Eventus albi corallii ex temperaturis marinis crescentibus magnam partem scopuli nuper laeserunt. Conatus conservatorii toto orbe suscipiuntur ad hunc magnificum oecosystema subaquaneum tuendum et restaurandum.</p>\n"
"</body>\n"
"</html>\n";
int main()
{
plutobook_t* book = plutobook_create(
PLUTOBOOK_PAGE_SIZE_A4,
PLUTOBOOK_PAGE_MARGINS_NARROW,
PLUTOBOOK_MEDIA_TYPE_PRINT
);
plutobook_load_html(book, kHTMLContent, -1, "", "", "");
plutobook_write_to_pdf(book, "hello.pdf");
plutobook_destroy(book);
return 0;
}
</details>
Example output:
<p align="center"><img src="https://github.com/user-attachments/assets/dc069903-2dad-47a2-ac5a-9854a617f7ae" alt="hello.pdf" width="650"></p>Page Rendering
PlutoBook supports precise page-level rendering, allowing individual pages to be drawn onto different canvas types, including bitmap canvases and PDF outputs. For custom rendering workflows, it integrates directly with Cairo, enabling advanced use cases like drawing onto custom surfaces or embedding within existing rendering pipelines. This page-specific approach improves efficiency by avoiding full document processing and is well-suited for previews, selective exports, and on-demand rendering.
This example loads Alice’s Adventures in Wonderland from Project Gutenberg, renders the first three pages as PNG images, and also exports them as a PDF.
#include <plutobook.hpp>
#include <cmath>
int main()
{
// Create a plutobook instance with A4 page size, narrow margins, and print media type
plutobook::Book book(plutobook::PageSize::A4, plutobook::PageMargins::Narrow, plutobook::MediaType::Print);
// Load the HTML content from file
book.loadUrl("Alice’s Adventures in Wonderland.html");
// Get page size in points and convert to pixel dimensions
const plutobook::PageSize& pageSize = book.pageSize();
int pageWidth = std::ceil(pageSize.width() / plutobook::units::px);
int pageHeight = std::ceil(pageSize.height() / plutobook::units::px);
// Create a canvas to render pages as images
plutobook::ImageCanvas canvas(pageWidth, pageHeight);
// Render the first 3 pages to PNG files
for(int pageIndex = 0; pageIndex < 3; ++pageIndex) {
auto filename = "page-" + std::to_string(pageIndex + 1) + ".png";
// Clear the canvas to white before rendering each page
canvas.clearSurface(1, 1, 1, 1);
// Render the page onto the canvas
book.renderPage(canvas, pageIndex);
// Save the canvas to a PNG file
canvas.writeToPng(filename);
}
// Export pages 1 to 3 (inclusive) to PDF with step=1 (every page in order)
book.writeToPdf("Alice’s Adventures in Wonderland.pdf", 1, 3, 1);
return 0;
}
<details>
<summary><b>Equivalent in C</b></summary>
#include <plutobook.h>
#include <stdio.h>
#include <math.h>
int main()
{
// Create a plutobook instance with A4 page size, narrow margins, and print media type
plutobook_t* book = plutobook_create(
PLUTOBOOK_PAGE_SIZE_A4,
PLUTOBOOK_PAGE_MARGINS_NARROW,
PLUTOBOOK_MEDIA_TYPE_PRINT
);
// Load the HTML content from file
plutobook_load_url(book, "Alice’s Adventures in Wonderland.html", "", "");
// Get page size in points and convert to pixel dimensions
plutobook_page_size_t page_size = plutobook_get_page_size(book);
int page_width = (int)ceilf(page_size.width / PLUTOBOOK_UNITS_PX);
int page_height = (int)ceilf(page_size.height / PLUTOBOOK_UNITS_PX);
// Create a canvas to render pages as images
plutobook_canvas_t* canvas = plutobook_image_canvas_create(
page_width,
page_height,
PLUTOBOOK_IMAGE_FORMAT_ARGB32
);
// Render the first 3 pages to PNG files
for(int page_index = 0; page_index < 3; ++page_index) {
char filename[64];
sprintf(filename, "page-%d.png", page_index + 1);
// Clear the canvas to white before rendering each page
plutobook_canvas_clear_surface(canvas, 1, 1, 1, 1);
// Render the page onto the canvas
plutobook_render_page(book, canvas, page_index);
// Save the canvas to a PNG file
plutobook_image_canvas_write_to_png(canvas, filename);
}
// Export pages 1 to 3 (inclusive) to PDF with step=1 (every page in order)
plutobook_write_to_pdf_range(book, "Alice’s Adventures in Wonderland.pdf", 1, 3, 1);
// Clean up resources
plutobook_canvas_destroy(canvas);
Related Skills
node-connect
340.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
summarize
340.5kSummarize or extract text/transcripts from URLs, podcasts, and local files (great fallback for “transcribe this YouTube/video”).
feishu-doc
340.5k|
