Coder Social home page Coder Social logo

prawn's Introduction

Prawn: Fast, Nimble PDF Generation For Ruby

Gem Version Build Status Code Climate Maintained: yes

Prawn is a pure Ruby PDF generation library that provides a lot of great functionality while trying to remain simple and reasonably performant. Here are some of the important features we provide:

  • Vector drawing support, including lines, polygons, curves, ellipses, etc.
  • Extensive text rendering support, including flowing text and limited inline formatting options.
  • Support for both PDF builtin fonts as well as embedded TrueType fonts
  • A variety of low level tools for basic layout needs, including a simple grid system
  • PNG and JPG image embedding, with flexible scaling options
  • Security features including encryption and password protection
  • Tools for rendering repeatable content (i.e headers, footers, and page numbers)
  • Comprehensive internationalization features, including full support for UTF-8 based fonts, right-to-left text rendering, fallback font support, and extension points for customizable text wrapping.
  • Support for PDF outlines for document navigation
  • Low level PDF features, allowing users to create custom extensions by dropping down all the way to the PDF object tree layer. (Mostly useful to those with knowledge of the PDF specification)
  • Lots of other stuff!

Should You Use Prawn?

If you are looking for a highly flexible PDF document generation system, Prawn might be the tool for you. It is not a reporting tool or a publishing toolchain, though it could be fairly easily used to build those things.

One thing Prawn is not, and will never be, is an HTML to PDF generator. For those needs, consider looking into FlyingSaucer via JRuby, or one of the WebKit based tools, like Wicked or PDFKit. We do have basic support for inline styling but it is limited to a very small subset of functionality and is not suitable for rendering rich HTML documents.

Supported Ruby Versions and Implementations

Because Prawn is pure Ruby and all of its runtime dependencies are maintained by us, it should work pretty much anywhere. We officially support all Ruby versions suported by Ruby Core Team and JRuby versions of matching Ruby version. However we will accept patches to fix problems on other Ruby platforms if they aren't too invasive.

Installing Prawn

Prawn is distributed via RubyGems, and can be installed the usual way that you install gems: by simply typing gem install prawn on the command line.

You can also install from git if you'd like, the master branch contains the latest developments. We're trying to keep master branch in working order but you may encounter some rough edges and fresh bugs along with bugfixes. We encourage you to try master branch with your application.

Hello World!

If the following code runs and produces a working PDF file, you've successfully installed Prawn.

require "prawn"

Prawn::Document.generate("hello.pdf") do
  text "Hello World!"
end

Of course, you'll probably want to do more interesting things than that...

Manual

The manual is a series of examples that demonstrate use of the wide range of features Prawn provides. You can get a generated version of the latest released Prawn version on the Prawn website. The examples themselves can be found in the manual directory in this repository.

Please note that while the manual is a great introduction and guide to Prawn it's not exhaustive. Please refer to API docs for more complete information on what Prawn provides and how to use it.

To build the manual, here's what you need to do:

  1. Clone the repository
  2. Run gem install -g
  3. Run rake manual, which will generate manual.pdf in the project root

Release Policies

We're trying to not break things unnecessarily but we don't formally follow Semantic Versioning. The reason is that we release a number of experimental APIs. We don't make any promises on their stability. You can assume the stable portion of the API follows Semantic Versioning.

Also note that bug fixes can change behaviour. We don't consider that to be a breaking change for the purposes of versioning. Please test your applications after updating Prawn.

Be sure to read the release notes in CHANGELOG.md each time we cut a new release, and lock your gems accordingly.

Support

The easiest way to get help with Prawn is to post a message to our Discussions.

Feel free to post any Prawn related question there, our community is very responsive and will be happy to help you figure out how to use Prawn, or help you determine whether it's the right tool for the task you are working on.

Please make your posts as specific as possible, including code samples and output where relevant. Do not post any information that should not be shared publicly, and be sure to reduce your example code as much as possible so that those who are responding to your question can more easily see what the issue might be.

Code of Conduct

Prawn adheres to the Contributor Covenant. Unacceptable behavior can be reported to [email protected] which is monitored by the core team.

Contributing

If you've found a bug or want to submit a patch, please enter a ticket into our GitHub tracker.

We strongly encourage bug reports to come with failing tests or at least a reduced example that demonstrates the problem. Similarly, patches should include tests, API documentation, and an update to the manual where relevant. Feel free to send a pull request early though, if you just want some feedback or a code review before preparing your code to be merged.

If you are unsure about whether or not you've found a bug, or want to check to see whether we'd be interested in the feature you want to add before you start working on it, feel free to post to our mailing list.

You can run our test suite in a few different ways:

  1. Running rake will run the entire test suite excluding any unresolved issues
  2. Running rspec will run the entire test suite including unresolved issues
  3. Running rspec -t unresolved will run only unresolved issues
  4. Running rspec -t issue:NUMBER will run the tests for a specific issue

These filters make it possible for us to add failing test cases for bugs that are currently being researched or worked on, without breaking the typical full suite run.

Maintenance team

Prawn has always been heavily dependent on community contributions, with dozens of people contributing code over the years. In that sense, the lines have blurred to the point where we no longer have a strong distinction between core developers and contributors.

That said, there are a few folks who have been responsible for cutting releases, merging important pull requests, and making major decisions about the overall direction of the project.

Current maintainers

These are the folks to contact if you have a maintenance-related issue with Prawn:

Inactive maintainers

These folks have helped out in a maintenance role in the past, but are no longer actively involved in the project:

License

Prawn is released under a slightly modified form of the License of Ruby, allowing you to choose between Matz's terms, the GPLv2, or GPLv3. For details, please see the LICENSE, GPLv2, and GPLv3 files.

If you contribute to Prawn, you will retain your own copyright but must agree to license your code under the same terms as the project itself.

History

Prawn was originally developed by Gregory Brown, under the auspices of the Ruby Mendicant Project, a grassroots initiative in which the Ruby community collectively provided funding so that Gregory could take several months off from work to focus on this project.

Over the last several years, we've received code contributions from dozens of people, which is amazing considering the low-level nature of this project. You can find the full list of folks who have at least one patch accepted to Prawn on GitHub Contributors page.

After a long period of inactivity, Prawn reached its 1.0 milestone in 2014 thanks to some modest funding provided to Gregory by Madriska, Inc. (Brad Ediger's company).

prawn's People

Contributors

alexdowad avatar andrewo avatar andrewtimberlake avatar astjohn avatar bradediger avatar caifara avatar donv avatar esb avatar fidothe avatar gettalong avatar giuseb avatar hbrandl avatar huerlisi avatar jamis avatar jeremyf avatar jessedoyle avatar kennethkalmer avatar mojavelinux avatar murrekatt avatar p8 avatar packetmonkey avatar petergoldstein avatar pointlessone avatar practicingruby avatar riopro avatar sigmike avatar viguini avatar willbryant avatar wpiekutowski avatar yob 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  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  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  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

prawn's Issues

require "enumerator" in graphics.rb should be removed

In ruby 1.8.7, enumerator.rb doesn't exist. It's not a problem if a script using prawn is executed by ruby interpreter, however, a Windows binary generated by exerb from the script cannot execute correctly because the binary tries to load enumerator.so but cannot load it.

Please fix this issue. Thanks!

PDF Meta Data

In PDF::Writer I could set the document properties “author”, “title”, “keywords”, “subject”, “creator”, “producer”.

(It’s been my experience that these help with SEO.)

center layout incorrect

using center layout in prawn is not correct as the length of lines is not correctly determined (incloding '\n' character)

This was published and discussed on in google group:
http://groups.google.com/group/prawn-ruby/browse_thread/thread/6754ada443dd22cd
workaround is to overwrite width_of method by manually removing tailing '\n' characters. (sorry the layout is broken as githup is always reformating this as coding)

module Prawn
class Document
alias_method :orig_width_of, :width_of
def width_of(string, options={})
orig_width_of(string.gsub(/\n\z/,""),options)
end
end
end

rounded_rectangle

I have looked through the PDF-reference and can't find a way to do rectangles with rounded corners at the PDF-level, so it seems this should be done like PDF-writer did it, by drawing lines and curves.

A working method was submitted by Benjamín Cárdenas Salamandra in this thread:
http://groups.google.com/group/prawn-ruby/browse_thread/thread/9505ce1a5fade296

Here it is again:

def rectangle_rounded(point,width,height,radius) 
  x,y = point
  line [x+radius,y],[x+width-radius,y]
  line [x+radius,y-height],[x+width-radius,y-height]
  line [x,y-radius],[x,y-height+radius]
  line [x+width,y-radius],[x+width,y-height+radius]
  l1 = radius * KAPPA
  y1 = y-radius+l1
  x1 = x+radius-l1
  x2 = x+width-radius+l1
  y2 = y-height+radius-l1
  curve [x,y-radius],[x+radius,y], :bounds => [[x,y1],[x1,y]]
  curve [x+width-radius,y],[x+width,y-radius], :bounds => [[x2,y],[x+width,y1]]
  curve [x+width,y-height+radius],[x+width-radius,y-height], :bounds => [[x+width,y2],[x2,y-height]]
  curve [x+radius,y-height],[x,y-height+radius], :bounds => [[x1,y-height],[x,y2]]
end

UPDATE: This method works well for stroked rounded rectangles, but not if you fill it. I'm working on an implementation that works for both cases, but haven't finished it yet.

unfilter_image_data is a dog

Including a PNG with RGB+alpha (color type 6) in a PDF is not feasible because the method "unfilter_image_data" is incredibly slow. A quick benchmark of spec/png_spec.rb with and without the tests that hit this method:

(2.4GHz Intel Core 2 Duo)
with: "Finished in 13.779863 seconds."
w/out: "Finished in 0.391898 seconds."

That's on a 320x240 pixel PNG. It gets a lot worse the bigger they get. I have a use case where a 474x719 PNG is included in a PDF and it takes 24 seconds to create.

The bummer here is that many graphical apps (Pixelmator, Illustrator, etc) always flip the alpha transparency bit so this affects many images.

Tweak Document#text_box to implement some features from PDF::Writer#add_text_wrap

This is a request for several enhancements to Prawn#text_box so that it would support the features of #add_text_wrap in PDF::Writer.
1. When Prawn#textbox is called with the :truncate or :ellipses option the text which is not displayed in the text box is returned. (Implemented by geeksam and merged for 0.6)_
2.

When Prawn#text_box is called with the :angle => (int in range 0..259) option, the text is rotated as it would be using PDF::Writer #add_text_wrap 3. When Prawn#text_box is called with the :justification => :left | :center option, the text is justified as it would be using PDF::Writer #add_text_wrap

text method :at and :align options

Having both :at and :align options on the text method, makes you think they would work together, which they don't. This should be fixed, or reflected in the documentation.

Make bounding_box fully enclose nested elements

As per Greg’s request in the following mailing list post, here’s a feature request: http://groups.google.com/group/prawn-ruby/browse_thread/thread/229740129eb9a506

The behaviour of bounding_box should be changed to fully enclose nested elements, such that Prawn elements that follow a bounding box containing multiple nested elements with varying heights will align with the bottom edge of the bounding_box, and not the bottom edge of the last rendered nested element. This should obviously only be the case if the following element uses ‘cursor’ to denote it’s y-axis alignment.

I hope I’ve elucidated adequately.

Samå

move_cursor_to

having to do pdf.y = dy + bounds.absolute_bottom sucks.

Prawn PNG Issues

https://prawn.lighthouseapp.com/attachments/61121/interlaced.png

Here’s a sample image Prawn chokes on. This is your dice.png. I just reopened it in Photoshop and resaved it with the interlaced setting on. Prawn now chokes on parsing it, reporting the wrong error mid-parse.

In addition, see the discussion at:
https://prawn.lighthouseapp.com/projects/9398-prawn/tickets/82-adding-a-png-to-a-pdf-appears-corrupted

Ghostscript and ImageMagick need \n after %%EOF

ImageMagick (and reportedly Ghostscript) doesn't like Prawn's EOF syntax. I don't believe the particular file in question is relevant -- any PDF from Prawn spits out this error:

$ convert --version
Version: ImageMagick 6.5.1-0 2009-05-23 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC

$ convert -quality 100 out/0000.pdf out/0000.jpg

**** This file has a corrupted %%EOF marker, or garbage after the %%EOF.
**** The file was produced by Prawn:
**** please notify the author of this software
**** that the file does not conform to Adobe's published PDF
**** specification.  Processing of the file will continue normally.

Of course, this is a lie; the file is in compliance with the Adobe spec, but ImageMagick expected a newline after the %%EOF marker. Adding the newline silences that warning. According to the PDF spec (reference 1.3, appendix H, implementation note 15), Adobe readers accept %%EOF anywhere in the last 1024 bytes of the file.

Patched at bradediger/prawn@f8f5257. Hopefully patches are accepted to make my life easier on busted unsupported viewers.

NameTree insertion bug

I just found what i think is a bug in the nametree << method :
That code taken from name_tree_spec.rb works ok:

  it "should keep tree balanced when subtree split cascades to root" do
    node = Prawn::NameTree::Node.new(@pdf, 3)
    tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
    tree_add(node, ["five", 5], ["six", 6], ["seven", 7], ["eight", 8])
    tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
  end

but the same code with the values pre-ordered doesn't :

  it "should keep tree balanced when subtree split cascades to root" do
    node = Prawn::NameTree::Node.new(@pdf, 3)
    tree_add(node, ["eight", 8], ["five", 5], ["four", 4,],  ["one",1]
    tree_add(node, ['seven', 7], ['six', 6], ['three', 3], ['two', 2])
    tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
  end

Here is the output :

/usr/lib/ruby/gems/1.9.1/gems/prawn-core-0.5.1/lib/prawn/name_tree.rb:83:in `<<': undefined method `<<' for nil:NilClass (NoMethodError)
        from /usr/lib/ruby/gems/1.9.1/gems/prawn-core-0.5.1/lib/prawn/
name_tree.rb:42:in `add'
        from name_tree_spec.rb:13:in `block in tree_add'
        from name_tree_spec.rb:12:in `each'
        from name_tree_spec.rb:12:in `tree_add'

nametree.rb:83 is "fit << value"
but fit is nil because in the previous line : fit = children.detect { |
child| child >= value }
"child >= value" is always false if the values inserted are already
ordered.

This patch fixes it for me :

diff --git a/lib/prawn/name_tree.rb b/lib/prawn/name_tree.rb
index 267a6e9..c7d20c8 100644
--- a/lib/prawn/name_tree.rb
+++ b/lib/prawn/name_tree.rb
@@ -79,6 +79,7 @@ module Prawn
           split! if children.length > limit
         else
           fit = children.detect { |child| child >= value }
+          fit = children.last unless fit
           fit << value
         end

jlh

column_box doesn't flow between columns when displaying tables instead of text

While trying to work with column_box I found out that plain text works well but tables don't flow properly.

This works fine:
column_box [0,cursor], :width => bounds.width, :columns => 2 do
text " This is a test " * 100
end

This just causes the tables to continue in the first column over multiple pages, never flowing into the second column:
column_box [0,cursor], :width => bounds.width, :columns => 2 do
table data, :headers => headers,
:header_color => 'C0C0C0',
:font_size => 7,
:border_style => :grid,
:border_width => 0.5,
:width => bounds.width-10
end

:column_color

A clone of :row_color but for the columns of a table.

Transparency and stamp changes made

Greg, Brad, I've incorporated the changes you recommended and made a few other improvements (such as a couple new specs). Please note that everything for both transparency and stamp is now on the master of my Prawn fork: http://github.com/bluejade/prawn. I hope that works okay for you.

Please let me know if anything else should be done on these.

Best,

Daniel

Prawn::Format issue on tag

Hi,
I got an error
/usr/lib64/ruby/gems/1.8/gems/prawn-format-0.2.0.1/lib/prawn/
format/parser.rb:120:in `start_parse': closing b, but no tags are open
(Prawn::Format::Parser::TagError)

when displaying text like that
pdf.text "this is simple plain text where plain = true
", :plain => true

This is working fine in earlier version.

Document#grouped

A bit pie in the sky at the moment, but....

grouped do
   # ...
end

Would attempt to keep contents on the same page

Add DeviceN colorspace support

This is a prerequisite for a project aimed at creating a duotone tool in ruby. Necessary for all documents using spot colors. BTW I guess there is no reason why Prawn should not support all the remaining colorspaces that PDF offers.

Embed other PDF images

Trying to keep my images in a vector format so that printing and scaling of the prawn generated document stays crisp and lightweight. Would love to be able to embed either EPS or PDF vector art into my prawn generated document.

Table breaks with non-standard leading (:spacing)

Hello

As I already reported in a ticket on prawn.lighthouseapp.com/ (URL: http://is.gd/1bGe3 ) for 0.4 in 0.5.1 remains a bug with table cells and a :leading greater than 0. In particular the bug is in prawn/document/text/wrapping.rb and does probably not only concern tables.

A sample script that produces the misbehavior is here: https://prawn.lighthouseapp.com/attachments/128185/prawntest.rb

I fixed it for me in the following way (diff for wrapping.rb):

22c22,23
<           string.lines.to_a.length * font.height_at(size)

---
>           lcount = string.lines.to_a.length
>           lcount * font.height_at(size) + ( lcount - 1 ) * text_options[:spacing].to_f

So long, T.

Binary sentinel in header needs to be in PDF comment

The four binary characters recommended by the spec (as a sentinel for file-transfer programs) should be in a PDF comment: "it is recommended that the header line be immediately followed by a
comment line containing at least four binary characters". Confirmed that at least Apple's PDF framework does this correctly.

Fixed in bradediger/prawn@a14f21e4. Sending pull request.

please include min_version patch

The min_version() method in my fork will be useful for extensions that use features that require PDF versions > 1.3

Most readers seem to ignore the version anyway, but we probably should at least try to be good PDF citizens.

Vertical align for cells

It would be very convenient to a project I’m doing if it were possibly to do, e.g.

pdf.cell blahblah, :vertical_align => :center

and have that work as easily as :horizontal_align => :center does. You can “fake it” with vertical padding fairly easily… right until you end up word wrapping.

I’m currently banging my head against this for my project but if I get a generalizable solution working I’ll try getting you guys the code.

compute_width_of() seems to consider unicode as single byte character-set

Hello

For example for german umlauts compute_width_of() reports up to the double width of the same character without diaeresis (e.g. Ü has twice the width of U).

Here some sample code:

#!/usr/local/bin/ruby
  
require 'rubygems'
require 'prawn'

pdf = Prawn::Document.new

%w(wertbestätigung wertbestatigung Ä A Ü U Ö O Â A).each do |heading|
  str_width = pdf.font.compute_width_of(heading)
  pdf.text "#{heading} width: '#{str_width}' "
end

def print_stretched pdf, string, gap, position_y
  char_h = {}
  string_width = 0.0
  offset = 0
  char_a = string.split('')
  char_a.each { |c| string_width += char_h[c] = pdf.font.compute_width_of(c).to_f }
  string_width += ( char_a.length - 1 ) * gap
  position_x = pdf.bounds.width / 2 - string_width / 2
  char_a.each do |c|
    pdf.text c, :at => [position_x+offset, position_y]
    offset += char_h[c] + gap
  end
end

pos = 400
%w(rechnung kostenvoranschlag wertbestätigung angebot).each do |heading|
  print_stretched pdf, heading, 2.0, pos
  pos+= 30
end

pdf.render_file('stretched.pdf')

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.