Getting Prawn to layout text like an absolutely positioned HTML paragraph

StackOverflow https://stackoverflow.com/questions/20087376

  •  02-08-2022
  •  | 
  •  

문제

I'm trying to get Prawn text to act like absolutely positioned paragraphs in HTML, in that the paragraph will only be as wide as the text it contains.

This is best seen by an example:

In HTML, the following:

<p class="left-align">Here's some left-aligned text,<br/>bla bla bla</p>
<p class="center-align">Here's some center-aligned text,<br/>bla bla bla</p>
<p class="right-align">Here's some right-aligned text,<br/>bla bla bla</p>
<style>
p {
    background:yellow;
    border:solid 1px black;
    position:absolute;
}
.left-align {
    text-align:left;
    left:20px; top:0;
}
.center-align {
    text-align:center;
    left:20px; top:50px;
}
.right-align {
    text-align:right;
    left:20px; top:100px;
}
</style>

Will result in this:

enter image description here

As you can see, the paragraphs will only be as wide as their content (See fiddle for complete example).

Layout-wise, this is what I want to achieve in Prawn, but when I try the following:

pdf.text_box "Here's some left text,\nbla bla bla", :at => [20, page_height], :align => :left
pdf.text_box "Here's some center text,\nbla bla bla", :at => [20, page_height-50], :align => :center
pdf.text_box "Here's some right text,\nbla bla bla", :at => [20, page_height-100], :align => :right

I end up with something like this:

enter image description here

which is akin to the adding width:100% to p elements.

도움이 되었습니까?

해결책

You have to provide the width of the text box, otherwise the text_box will use the page width minus the start position.

In order to calculate the string width, you should use the width_of method provided by the Prawn library, but, for some reason, Prawn doesn't recognise the \n char in width_of method, then you must have to split it by hand and calculate the line widths separately, which is not so difficult:

def text_width(pdf, text)
  # slip by new line char and find maximum text width
  text.split("\n").map {|s| pdf.width_of(s)}.max
end

Inserting text_width in your code:

pdf.text_box s = "Here's some left text,\nbla bla bla", 
  :at     => [20, page_height], 
  :align  => :left,
  :width  => text_width(pdf, s)

pdf.text_box s = "Here's some center text,\nbla bla bla", 
  :at     => [20, page_height-50], 
  :align  => :center,
  :width  => text_width(pdf, s)

pdf.text_box s = "Here's some right text,\nbla bla bla", 
  :at     => [20, page_height-100], 
  :align  => :right,
  :width  => text_width(pdf, s)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top