Make a PDF file by writing kind of like HTML and CSS.

Overview

markup-pdf-rs

The Rust library for making a PDF files by writing kind of like HTML and CSS. Inspired by Satori and React-pdf. This library makes a PDF file with taffy and printpdf.

⚠️ This library is a prototype so we don't recommend using it in production.

Usage

use std::{
    fs::{File},
    io::BufWriter,
};

use markup_pdf_rs::{assets::Assets, document::Document, dom, style::Style};
use taffy::{
    prelude::{Rect, Size},
    style::{
        Dimension::{self, Points},
        FlexDirection, JustifyContent,
    },
};

fn main() {
    // Define styles like CSS used by XML.
    let mut assets = Assets::default();
    assets.styles.add(
        // Specify the name of the style
        // You can use this style by setting the `style` attribute to an element
        // e.g. `<Layer style="page" />`
        "page",
        Style {
            // These styles are basically the same as taffy.
            size: Size {
                width: Points(210.0),
                height: Points(297.0),
            },
            ..Style::DEFAULT
        },
    );
    assets.styles.add(
        "main",
        Style {
            gap: Size {
                width: Dimension::Auto,
                height: Points(6.0),
            },
            flex_grow: 1.0,
            flex_direction: FlexDirection::Column,
            justify_content: JustifyContent::FlexStart,
            padding: Rect::from_points(15.0, 15.0, 15.0, 15.0),
            ..Style::DEFAULT
        },
    );
    assets.styles.add(
        "title",
        Style {
            font_size: 20.0,
            size: Size {
                width: Dimension::Auto,
                height: Points(10.0),
            },
            ..Style::DEFAULT
        },
    );
    assets.styles.add(
        "paragraph",
        Style {
            size: Size {
                width: Dimension::Auto,
                height: Points(15.0),
            },
            ..Style::DEFAULT
        },
    );
    assets.styles.add(
        "blockquote",
        Style {
            background_color: Some("#eeeeee"),
            size: Size {
                width: Dimension::Auto,
                height: Points(23.0),
            },
            ..Style::DEFAULT
        },
    );
    assets.styles.add(
        "blockquote-text",
        Style {
            flex_grow: 1.0,
            margin: Rect::from_points(5.0, 5.0, 5.0, 5.0),
            size: Size {
                width: Dimension::Auto,
                height: Points(20.0),
            },
            ..Style::DEFAULT
        },
    );

    // Define fonts
    assets.fonts.add(
        // You can use this font by setting the `font-family` property to a style
        // The name of `default` means the default font if `font-family` is not specified
        "default",
        include_bytes!("assets/fonts/Roboto-Regular.ttf").as_slice(),
    );

    // Pass a XML string to `dom::parse`.
    let root = dom::parse(r#"
        <Document title="recipe">
            <Page style="page">
                <Layer style="main">
                    <Text style="title">Lorem Ipsum</Text>
                    <Text style="paragraph">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sollicitudin mollis ipsum, eu aliquam est consequat vitae.</Text>
                    <Layer style="blockquote">
                        <Text style="blockquote-text">Donec nunc erat, porttitor eu massa blandit, pulvinar aliquam turpis. Maecenas augue justo, auctor ornare eleifend sed, suscipit ut mauris.</Text>
                    </Layer>
                    <Text style="paragraph">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sollicitudin mollis ipsum, eu aliquam est consequat vitae.</Text>
                    <Text style="paragraph">Mauris in mattis lectus. Nulla eget iaculis ligula, eu pulvinar leo.</Text>
                    <Text style="paragraph">vitae laoreet erat mauris sed ipsum.</Text>
                </Layer>
            </Page>
        </Document>
    "#).unwrap();

    // Build `PdfDocumentReference` (this struct is in printpdf) by passing a XML and assets.
    let doc = Document::new(&root, assets)
        .unwrap()
        .build()
        .unwrap();

    // Call the `save` to export a PDF.
    let buf = &mut BufWriter::new(File::create("dist/simple.pdf").unwrap());
    doc.save(buf).unwrap();
}

The code above will make a PDF like below.

Result

Try with examples

You can try this library by running example codes included in the repository.

# Clone this repository.
$ git clone [email protected]:ktmouk/markup-pdf-rs.git
$ cd markup-pdf-rs

# Download some fonts from Google Fonts and put them on the `examples/assets/fonts/` dir.
$ ./examples/assets/fonts/install.sh

# Try some example codes that make a PDF file.
# PDF files will be made in the `dist/` dir.
$ cargo run --example recipe
$ cargo run --example resume

Examples

Simple Nikujaga Recipe (JP) Japanese Resume (JP)
Code Code Code

Elements

Name Usage
<Document> XML must start with this element. It can have only <Page> elements as children.
<Page> This element means one page of PDF. It should have a fixed size defined in the style to determined the page size. It can have <Layer> and <Text> elements as children.
<Layer> This element is like <div> of HTML. You can use it for setting the styles. It can have <Layer> and <Text> elements as children.
<Text> You can use this element to write texts. It can have only string as a child. ⚠️ Currently, this element doesn't support calculating the width and height basing on the text automatically, so you need to specify the width and height by hand.

Styles

Styles are basically the same as taffy apart from some of property for specifying colors. You can check the style.rs.

You might also like...
Moonshine CSS - 🥃 High-proof atomic CSS framework

Moonshine CSS - 🥃 High-proof atomic CSS framework

Converts books written in Markdown to HTML, LaTeX/PDF and EPUB

Crowbook Crowbook's aim is to allow you to write a book in Markdown without worrying about formatting or typography, and let the program generate HTML

Tools - The Rome Toolchain. A linter, compiler, bundler, and more for JavaScript, TypeScript, HTML, Markdown, and CSS.
Tools - The Rome Toolchain. A linter, compiler, bundler, and more for JavaScript, TypeScript, HTML, Markdown, and CSS.

Rome is currently being rewritten in Rust. Read more about it in our latest blog post. The documentation below is out of date and available for poster

A Faster(⚡)  formatter, linter, bundler, and more for JavaScript, TypeScript, JSON, HTML, Markdown, and CSS Lapce Plugin
A Faster(⚡) formatter, linter, bundler, and more for JavaScript, TypeScript, JSON, HTML, Markdown, and CSS Lapce Plugin

Lapce Plugin for Rome Lapce-rome is a Lapce plugin for rome, The Rome is faster ⚡ , A formatter, linter, compiler, bundler, and more for JavaScript, T

Scraper - HTML parsing and querying with CSS selectors

scraper HTML parsing and querying with CSS selectors. scraper is on Crates.io and GitHub. Scraper provides an interface to Servo's html5ever and selec

A small application to convert a 3D model in .obj format into HTML and CSS

obj-to-html is a small application that converts a 3D model in .obj format into HTML and CSS that will display that model in a web browser, spinning a

A minimal browser with a super simple rendering engine for HTML and CSS, using Rust.

minimal-browser A minimal browser with a super simple rendering engine for HTML and CSS, using Rust. Credit: https://github.com/mbrubeck and https://l

Generate html/js/css with rust
Generate html/js/css with rust

Generate html/js/css with rust

An easy-to-use library for writing PDF in Rust

printpdf printpdf is a library designed for creating printable PDF documents. Crates.io | Documentation [dependencies] printpdf = "0.3.2" Features Cur

🖼️Combines a Javascript and WASM file into a single executable polygot PNG+HTML file.

WASIMAGE Combines a Javascript and WASM file into a single executable polygot PNG+HTML file. Usage: cargo install wasimage wasimage --wasm-file my.was

Distribute a wasm SPA as HTML by wrapping it as a polyglot "html+wasm+zip"

A packer that adds a webpage to WASM module, making it self-hosted! Motivation At the moment, Browsers can not execute WebAssembly as a native single

SVG to PDF file conversion based on "svg2pdf" and "resvg" Rust projects

pysvg2pdf Blazingly Fast ™️ SVG to PDF file conversion for Python. This project is based on Rust's svg2pdf and resvg projects. The project uses pyo3 a

A new kind of terminal
A new kind of terminal

notty - not a typewriter notty is a virtual terminal like xterm, gnome-vte, sh, or rxvt. Unlike these programs, notty is not intended to emulate a DEC

Simple library to host lv2 plugins. Is not meant to support any kind of GUI.

lv2-host-minimal Simple library to host lv2 plugins. Is not meant to support any kind of GUI. Host fx plugins (audio in, audio out) Set parameters Hos

Inkwell - It's a New Kind of Wrapper for Exposing LLVM (Safely)

Inkwell(s) It's a New Kind of Wrapper for Exposing LLVM (Safely) Inkwell aims to help you pen your own programming languages by safely wrapping llvm-s

Api testing tool made with rust to use for api developement (Kind of Tui)
Api testing tool made with rust to use for api developement (Kind of Tui)

Api testing tool made with rust to use for api developement (Kind of Tui) This Rust project provides a simple yet powerful tool for making HTTP reques

Costless typed identifiers backed by UUID, with kind readable in serialized versions

Why kind ? With kind, you use typed identifiers in Rust, with no overhead over Uuid have the type be human readable and obvious in JSON and any export

The simplest build-time framework for writing web apps with html templates and typescript

Encoped A build-time fast af tool to write static apps with html and TypeScript Features Template-based ESLint, Prettier and Rollup integration No ext

My own image file format created for fun! Install the "hif_opener.exe" to open hif files. clone the repo and compile to make your own hif file

Why am i creating this? I wanted to create my own image format since I was 12 years old using Windows 7, tryna modify GTA San Andreas. That day, when

Owner
null
An easy-to-use library for writing PDF in Rust

printpdf printpdf is a library designed for creating printable PDF documents. Crates.io | Documentation [dependencies] printpdf = "0.3.2" Features Cur

Felix M. Schütt 592 Jan 8, 2023
docx-you-want is a tool to convert a PDF document into a .docx file

ddocx-you-want is a tool to convert a PDF document into a .docx file ... in an unusual way. Since these two formats are inherently differ

null 45 Dec 23, 2022
Generate PDF files with JavaScript and WASM (WebAssembly)

WASM-PDF Generates PDF files directly in the browser with JavaScript and WASM (WebAssembly). Idea here is to push all the work involved in creating a

Jussi Niinikoski 369 Jan 2, 2023
PDF Structure Viewer, This tool is useful for when working with PDFs and/or lopdf.

PDF Structure Viewer Inspect how the PDF's structure looks. This tool is useful for when working with PDFs and/or lopdf. This application is used lopd

Ralph Bisschops 13 Nov 21, 2022
Image cropper (and colorizer) for pdf scans

Image cropper for personal use (might not work with your pdfs) Requires pdfimages on the path to work properly It's thought just for my workflow so is

cdecompilador 2 Nov 7, 2022
Generating PDF files in pure Rust

pdf-canvas A pure rust library for generating PDF files. Currently, simple vector graphics and text set in the 14 built-in fonts are supported. To use

Rasmus Kaj 128 Jan 1, 2023
A Rust library for PDF document manipulation.

lopdf A Rust library for PDF document manipulation. Example Code Create PDF document #[macro_use] extern crate lopdf; use lopdf::{Document, Object, St

Junfeng Liu 1.1k Dec 30, 2022
PDF command-line utils written in Rust

rpdf PDF command-line utils written in Rust. rpdf makes working with PDF annotions super easy! It can merge annotations from multiple files, some show

Jérome Eertmans 13 May 9, 2023
A tool for creating code documentation and manuals for software/codefiles

Auto-Doc A tool, written in Rust, for creating code documentation and manuals for software/code files written in Python (for now) NOTE: This is the fi

Owen Hoglund 4 Oct 19, 2022
Like jq, but for HTML. Uses CSS selectors to extract bits content from HTML files.

Like jq, but for HTML. Uses CSS selectors to extract bits content from HTML files. Mozilla's MDN has a good reference for CSS selector syntax.

Michael Maclean 6.3k Jan 3, 2023