Determine variable outer bounding box height with stretchy inner boxes

25 views
Skip to first unread message

Nicholas Shirley

unread,
Oct 10, 2017, 10:42:07 AM10/10/17
to Prawn
Hi all, I'm working on a project that outputs info from a database into a pdf. Each entry is contained within one bounding box (box A) and inside that, there are 3 nested bounding boxes distributed horizontally (B, C, D). The content of boxes B and D will vary based on entry so that either one can be taller in different entries with one edge case where box C could be the tallest. I found this question, which was similar, but not sure what the outcome was.

What I'd like to do is determine the height of box A, or the lowest y position on the page after each write, so that I can do two things: (1) compare the space remaining to how tall the next entry box will be and create a new page if necessary and (2) begin the next entry (box A) below the proceeding box. I think that ever after I determine where the ending y is, I still need to calculate the next entry, but not sure what's the best way to accomplish this.

Here is the code from the file, but if it's easier you can also clone this repo and run 'hard-coded-test.rb' which executes the pdf output with the sample database info.

All the best
Nicholas

require 'prawn'
require 'json'

user
= File.read('user.json')
user_hash
= JSON.parse(user)
deals
= File.read('deals.json')
deals_hash
= JSON.parse(deals)

pdf
= Prawn::Document.new

pdf
.move_cursor_to 720

# This is the user info boudning box, it's not expected that the height will
# ever exceed 1 line per item
pdf
.bounding_box([0, pdf.cursor], :width => 540) do
  pdf
.font_size 16
  pdf
.text "#{user_hash['data']['first_name']} #{user_hash['data']['last_name']}"
  pdf
.font_size 12
  pdf
.text "#{user_hash['data']['title']}"
  pdf
.text "#{user_hash['data']['company']}"
  pdf
.text "#{user_hash['data']['email']}"
end

pdf
.move_down 15

# Begin loop for all user deals
# bounds are stroked only for illustration, will not be in final
deals_hash
.each do |key, value|
 
# Outer bounding box (Box A in Google group question)
  pdf
.bounding_box([0, pdf.cursor], :width => 540) do
    pdf
.font_size 16
    pdf
.text "#{key['headline']}"
    pdf
.move_down 10
   
# Inner bounding box containing client names (box B in question)
    pdf
.bounding_box([0, pdf.cursor], :width => 235) do
      pdf
.font_size 12
      key
['clients'].each do |client|
        pdf
.bounding_box([0, pdf.cursor], :width => 135) do
          pdf
.text client['client']
       
end
        pdf
.stroke_bounds
     
end
     
# Inner bounding box (Box C in question)
     
# In one edge case it could be taller than Box B
      pdf
.move_cursor_to pdf.bounds.top
      key
['clients'].each do |role|
        pdf
.bounding_box([136, pdf.cursor], :width => 100) do
          pdf
.text role['role']
       
end
        pdf
.stroke_bounds
     
end
      pdf
.move_cursor_to pdf.bounds.top
   
end
   
# Final inner bounding box (Box D in question)
    pdf
.bounding_box([236, pdf.cursor], :width => 304) do
      pdf
.text key['summary_tasks']
      pdf
.stroke_bounds
   
end
    pdf
.stroke_bounds
 
end
 
# This was my last attempt to determine the bottom of the bouding box, but
 
# as you can see from the pdf, it's not working
  pdf
.move_down(pdf.bounds.absolute_bottom - 15)
end

pdf
.render_file("list test.pdf")

Reply all
Reply to author
Forward
0 new messages