I'm using Prawn gem to generate PDF documents within my Rails Application. I've successfully created the PDFs But I have a table of contents and I wonder is it possible Or Is there is a way to create the leader dots effect in Prawn ?
3
votes
2 Answers
4
votes
Yes, there is a way to create the leader dots effect in Praw.
If you have:
- the total available width
- width of the table of content entry
- width of the page number
- width of a single leader dot
space_for_dots = 1. - 2. - 3.
dots = (space_for_dots / 4) * '.'
toc_entry = entry_string + dots + entry_page_number
To calculate the width of a string in prawn, you can use compute_width_of, which is part of the font classes.
An example for the picture you added could look like this:
def build_toc_entry(left_text, right_text, available_width, text_size)
left_text_width = font(YOUR_FONT).compute_width_of(left_text, size: text_size)
right_text_width = font(YOUR_FONT).compute_width_of(right_text, size: text_size)
dot_width = font(YOUR_FONT).compute_width_of('.', size: text_size)
space_width = font(YOUR_FONT).compute_width_of(' ', size: text_size)
space_for_dots = available_width - left_text_width - right_text_width - space_width * 2
dots = '.' * (space_for_dots / dot_width)
"#{left_text} #{dots} #{right_text}" # return the finished toc entry
end
text 'Locate the information on the page indicated.'
text build_toc_entry('Leader Dots', '3', 350, 8)
text build_toc_entry('Dingbats', '5', 350, 8)
text build_toc_entry('Bullets', '8', 350, 8)
0
votes
This is a little late but here is what I did to get the dots to align properly with only left side text. But I think it would be reasonably easy to modify for left and right text:
def build_dots(text, available_width, text_size)
dots_hash = {}
current_font = font.inspect.split('<')[1].split(':')[0].strip
text_width = font(current_font).compute_width_of(text, size: text_size)
dot_width = font(current_font).compute_width_of('.', size: text_size)
space_width = font(current_font).compute_width_of(' ', size: text_size)
space_for_dots = available_width - text_width - space_width * 2
dots = '.' * (space_for_dots / dot_width)
dots_width = font(current_font).compute_width_of(dots, size: text_size)
dots_start = available_width - dots_width - (space_width * 2)
dots_hash[:dots] = dots
dots_hash[:position] = dots_start
return dots_hash
end
dot_values = build_dots(officer.title,150,text_size)
p = 0
float {
text "#{officer.title}", size: text_size
}
indent(dot_values[:position]) do
float {
text dot_values[:dots], size: text_size
}
end
p += 150
indent(p,0) do
text "#{officer.name}", size: text_size
end