prawn
prawn copied to clipboard
:overflow => :ellipses not working
Hi,
Creating a PDF doc and passing the overflow option as ellipses is not adding ...
at the end of text, it is just truncating the text.
I've tried to quickly debugging prawn to find the issue and search on the source code for ellilpses and couldn't find anything
Example of code not working:
Prawn::Document.generate("prawn.pdf") do
string = "This is the beginning of the text. It will be cut somewhere and " +
"the rest of the text will procede to be rendered this time by " +
"calling another method."
y_position = cursor - 20
excess_text = text_box string,
:width => 300,
:height => 50,
:overflow => :ellipses,
:at => [100, y_position],
:size => 18,
end
Thank you
Hi,
I don't think Prawn supports :ellipses
overflow mode.
Did you see it in the documentation or code somewhere?
@pointlessone yes, I saw it here https://www.rubydoc.info/gems/prawn-core/0.7.2/Prawn%2FText:text_box
Perhaps documentation is wrong or it was supported in an older version and it isn't anymore?
Thanks
Also came here to report the same issue
@sherisoli as a workaround I ended up doing something like this:
def truncate string, coord_x, coord_y
params = { size: 12, leading: 10, width: 500, height: 90, at: [coord_x, coord_y - 30] }
excess_text = pdf.text_box(string, params.merge(dry_run: true, mode: :invisible))
if excess_text.empty?
pdf.text_box(string, params.merge(dry_run: false))
else
# omission set to "" so spaces can be removed from the end
# before adding ...more
new_text = string.truncate(string.length - excess_text.length - ELLIPSIS_LENGTH, omission: "")
other_content = "http://somelink"
pdf.formatted_text_box([
{ text: new_text.strip.chomp + "..." },
{ text: "more", color: "006FFF", link: other_content }
], params.merge(dry_run: false))
end
end
You may need to adapt according to your use case, the key is to use dry_run and invisible to get the excess_text and use it to truncate the original string with the ellipsis length then call the method again without dry_run and invisible using the truncated string.
@jcarlos There is no Ruby String#truncate
method... See https://ruby-doc.org/core-2.7.1/String.html
@gettalong sorry, I’m using that code as part of a Rails application: https://apidock.com/rails/ActionView/Helpers/TextHelper/truncate
You may want to use that ActionView helper as a gem, or check its source code to see how it does it. Alternatively replace truncate
with slice
https://ruby-doc.org/core-2.5.1/String.html#method-i-slice
Looks like it was intentionally removed in 526cbfcc back in 2011. Here's the google groups conversation about the removal (also linked in the commit).
I'm DRYing up text per my previous post and have come up against the ellipses overflow option again in Text::Box. I had made it unsupported in formatted text because it is more complicated there than for regular text, and it wasn't clear to me how it should be handled. Now that I'm making all text resolve to formatted text, I'm facing failing specs. I don't particularly like the way I implemented the ellipses overflow option last time (and I'm not sure how related that was to the original implementation I was replacing). It also added extra complexity. But beyond that, is adding ellipses really a necessary low-level feature of Prawn? I'd say not.
What would you think about removing the :ellipses overflow option from Text::Box?
Thank You, Daniel
I'm all for it. If there ends up being a nice way to expose an API so that end-user code can reimplement this, all the better. But I don't think we need this in core.
-be [Brad Ediger]
I ended up with this for myself:
def truncate(string, max_width)
# if you're worried about performance here, prawn basically does the same
# thing with font sizes when you use shrink_to_fit with text_box.
if width_of(string) > max_width
string.size.downto(1) do |length|
if width_of(truncated = string.truncate(length)) < max_width
return truncated
end
end
end
string
end
This version doesn't iterate, but yields more ragged results:
def truncate(string, max_width)
if width_of(string) > max_width
rendered_width = width_of("#{string}...")
rendered_pct = max_width / (rendered_width * 1.0)
pct_margin = 0.02
characters = (string.size * (rendered_pct - pct_margin)).to_i
string.truncate(characters)
else
string
end
end
I don't know what that gem is. This repo never had this options. I'm glad you guys are having fun implementing the feature though.
I don't even know what resolution to assign to this issue. Is it "out of scope"? Is it "has workaround"? Anyway, I don't have anything to here so I'm closing it.