Giter Club home page Giter Club logo

prawn-html's Introduction

Prawn HTML

gem version gem downloads maintainability linters specs

HTML to PDF renderer using Prawn PDF.

Features:

  • support a good set of HTML tags and CSS properties;
  • handle document styles;
  • custom data attributes for Prawn PDF features;
  • no extra settings: it just parses an input HTML and outputs to a Prawn PDF document.

Notice: render HTML documents properly is not an easy task, this gem support only some HTML tags and a small set of CSS attributes. If you need more rendering accuracy take a look at other projects like WickedPDF or PDFKit.

prawn-styled-text rewritten from scratch, finally!

Please โญ if you like it.

Install

  • Add to your Gemfile: gem 'prawn-html' (and execute bundle)
  • Just call PrawnHtml.append_html on a Prawn::Document instance (see the examples)

Examples

require 'prawn-html'
pdf = Prawn::Document.new(page_size: 'A4')
PrawnHtml.append_html(pdf, '<h1 style="text-align: center">Just a test</h1>')
pdf.render_file('test.pdf')

To check some examples with the PDF output see examples folder.

Alternative form using PrawnHtml::Instance to preserve the context:

require 'prawn-html'
pdf = Prawn::Document.new(page_size: 'A4')
phtml = PrawnHtml::Instance.new(pdf)
css = <<~CSS
  h1 { color: green }
  i { color: red }
CSS
phtml.append(css: css)
phtml.append(html: '<h1>Some <i>HTML</i> before</h1>')
pdf.text 'Some Prawn text'
phtml.append(html: '<h1>Some <i>HTML</i> after</h1>')
pdf.render_file('test.pdf')

Supported tags & attributes

HTML tags (using MDN definitions):

  • a: the Anchor element
  • b: the Bring Attention To element
  • blockquote: the Block Quotation element
  • br: the Line Break element
  • code: the Inline Code element
  • del: the Deleted Text element
  • div: the Content Division element
  • em: the Emphasis element
  • h1 - h6: the HTML Section Heading elements
  • hr: the Thematic Break (Horizontal Rule) element
  • i: the Idiomatic Text element
  • ins: the added text element
  • img: the Image Embed element
  • li: the list item element
  • mark: the Mark Text element
  • ol: the Ordered List element
  • p: the Paragraph element
  • pre: the Preformatted Text element
  • s: the strike-through text element
  • small: the side comment element
  • span: the generic inline element
  • strong: the Strong Importance element
  • sub: the Subscript element
  • sup: the Superscript element
  • u: the Unarticulated Annotation (Underline) element
  • ul: the Unordered List element

CSS attributes (dimensional units are ignored and considered in pixel):

  • background: for mark tag (3/6 hex digits or RGB or color name), ex. style="background: #FECD08"
  • break-after: go to a new page after some elements, ex. style="break-after: auto"
  • break-before: go to a new page before some elements, ex. style="break-before: auto"
  • color: (3/6 hex digits or RGB or color name) ex. style="color: #FB1"
  • font-family: font must be registered, quotes are optional, ex. style="font-family: Courier"
  • font-size: ex. style="font-size: 20px"
  • font-style: values: :italic, ex. style="font-style: italic"
  • font-weight: values: :bold, ex. style="font-weight: bold"
  • height: for img tag, ex. <img src="image.jpg" style="height: 200px"/>
  • href: for a tag, ex. <a href="http://www.google.com/">Google</a>
  • left: see position (absolute)
  • letter-spacing: ex. style="letter-spacing: 1.5"
  • line-height: ex. style="line-height: 10px"
  • list-style-type: for ul, a string, ex. style="list-style-type: '- '"
  • margin-bottom: ex. style="margin-bottom: 10px"
  • margin-left: ex. style="margin-left: 15px"
  • margin-top: ex. style="margin-top: 20px"
  • position: absolute, ex. style="position: absolute; left: 20px; top: 100px"
  • src: for img tag, ex. <img src="image.jpg"/>
  • text-align: left | center | right | justify, ex. style="text-align: center"
  • text-decoration: underline, ex. style="text-decoration: underline"
  • top: see position (absolute)
  • width: for img tag, support also percentage, ex. <img src="image.jpg" style="width: 50%; height: 200px"/>

The above attributes supports the initial value to reset them to their original value.

For colors, the supported formats are:

  • 3 hex digits, ex. color: #FB1;
  • 6 hex digits, ex. color: #abcdef;
  • RGB, ex. color: RGB(64, 0, 128);
  • color name, ex. color: yellow.

Data attributes

Some custom data attributes are used to pass options:

  • dash: for hr tag, accepts an integer or a list of integers), ex. data-data="2, 4, 3"
  • mode: allow to specify the text mode (stroke|fill||fill_stroke), ex. data-mode="stroke"

Document styles

You can define document CSS rules inside an head tag. Example:

<!DOCTYPE html>
<html>
<head>
  <title>A test</title>
  <style>
    body { color: #abbccc }
    .green {
      color: #0f0;
      font-family: Courier;
    }
    #test-1 { font-weight: bold }
  </style>
</head>
<body>
  <div class="green">
    Div content
    <span id="test-1">Span content</span>
  </div>
</body>
</html>

Additional notes

Rails: generate PDF on the fly

Sample controller's action to create a PDF from Rails:

class SomeController < ApplicationController
  def sample_action
    respond_to do |format|
      format.pdf do
        pdf = Prawn::Document.new
        PrawnHtml.append_html(pdf, '<h1 style="text-align: center">Just a test</h1>')
        send_data(pdf.render, filename: 'sample.pdf', type: 'application/pdf')
      end
    end
  end
end

More details in this blogpost: generate PDF from HTML

Do you like it? Star it!

If you use this component just star it. A developer is more motivated to improve a project when there is some interest.

Or consider offering me a coffee, it's a small thing but it is greatly appreciated: about me.

Contributors

License

The gem is available as open-source under the terms of the MIT.

prawn-html's People

Contributors

blocknotes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

prawn-html's Issues

How to perform look ahead calculations

Hello,

Is there a way to perform look ahead calculations when rendering bits of html. I would like to process small bits of html and save the vertical height that it has consumed before it is rendered on the page that way I know how far to move the cursor down. Much like how prawn allows you to use their dry_run options with their formatted text box as seen in their source code https://github.com/prawnpdf/prawn/blob/538cde7781208c5382a35d9b1a9b51d2bf63da36/lib/prawn/text/formatted/box.rb

svg images?

prawn-svg adds support for SVG images to prawn. However, it does so by adding a new svg method to prawn, where you give it SVG source.

I wonder if there's any sane way to combine that with prawn-html, such that HTML tags can somehow point to SVGs....

Any thoughts?

Exception raised when presented with `font-family: inherit`

We are using quilljs for WYSIWYG editing of contents, that are later rendered into a PDF via prawn-html. Sometimes, this results in markup like this:

<strong style="font-family: inherit">text</strong>

which results in the following error when rendering:

Prawn::Errors::UnknownFont (inherit (normal) is not a known font.)

for other similar CSS directives such as background-color: inherit; there does not seem to be a problem.

Minimal reproducible example:

require 'prawn-html'
pdf = Prawn::Document.new
PrawnHtml.append_html(pdf, '<strong style="font-family: inherit">text</strong>')
# Prawn::Errors::UnknownFont: inherit (normal) is not a known font.

List elements beginning with nested tags are rendered incorrectly

When rendering a list element there seems to be a bug which makes the bullet (or numbering, for <ol>) disappear. However it seems to work fine iff there is also text within the <li> element before any tags occur.

Example:

<p>Unordered List:</p>
<ul>
  <li>foo</li>
  <li>bar <strong>baz</strong></li>
  <li><strong>quux</strong></li>
</ul>

<p>Numbered List:</p>
<ol>
  <li>foo</li>
  <li><em>bar</em> baz</li>
  <li><u>quux</u></li>
</ol>

This is rendered as:

Screenshot 2022-05-03 at 13 05 04

Upgrading from prawn-styled-text

Hi, thanks for these awesome libraries!

I would like to upgrade from prawn-styled-text, and I'm wondering if you can give one or both of the following:

  • A comprehensive list of what elements render differently in prawn-html vs prawn-styled-text.
  • A stylesheet that will reset prawn-html to render the same as prawn-styled-text by default.

We have an application with a lot of content that gets rendered with prawn-styled-text right now and I'm interested in switching. It is an absolute requirement to have rendering parity though. Is this possible?

Thanks again.

Tag `li`: duplicated prefix content

Failing example:

PrawnHtml.append_html(pdf, "<ol><li>Text that is <b>bold</b> and <i>italic</i> also.</li><li>Second <b>line</b>.</li></ol>")

Invalid output:

  1. Text that is bold1. and italic 1. also.
  2. Second line2. .

Reported by Daniel P.

how make image and text on one line

hi need your suggestion, how i can make image and text on same line, image always different line with text,
for example i create
pdf = Prawn::Document.new(bottom_margin: 72) PrawnHtml.append_html(pdf, '<p style="display:inline;"><img height="26" width="26" src="image_path" cc-icon-id="1">test</p>')

the image and text not in same line, how i can make the text and image on same line?

image doesn't work

My HTML contains an image but I keep getting image_url not found so I changed it to base64 but now I am getting base64 not found

PS: I am using image_url and base64 as placeholders in the above

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.