使用Prawn控制内容流

时间:2013-06-24 18:09:19

标签: ruby prawn

我们想说我们想在第一页上显示一个占据页面上半部分的标题。然后页面的下半部分应该填写我们的文章文本,文本应该继续流入后续页面,直到它用完为止:

enter image description here

这是一个非常基本的布局方案,但我不明白如何在Prawn中实现它。

以下是一些源自其在线文档的示例代码:

pdf = Prawn::Document.new do
  text "The Prince", :align => :center, :size => 48
  text "Niccolò Machiavelli", :align => :center, :size => 20
  move_down 42

  column_box([0, cursor], :columns => 3, :width => bounds.width) do
  text((<<-END.gsub(/\s+/, ' ') + "\n\n") * 20)
   All the States and Governments by which men are or ever have been ruled,
   have been and are either Republics or Princedoms. Princedoms are either
   hereditary, in which the bla bla bla bla .....
   END
  end
end.render

但是这将继续显示每个页面的标题空间:

enter image description here

正确的方法是什么?

5 个答案:

答案 0 :(得分:10)

我一直在与同样的问题作斗争。我最后继承了ColumnBox并添加了一个帮助器来调用它:

module Prawn
  class Document

    def reflow_column_box(*args, &block)
      init_column_box(block) do |parent_box|
        map_to_absolute!(args[0])
        @bounding_box = ReflowColumnBox.new(self, parent_box, *args)
      end
    end

    private

    class ReflowColumnBox < ColumnBox 
      def move_past_bottom 
        @current_column = (@current_column + 1) % @columns
        @document.y = @y
        if 0 == @current_column
          @y = @parent.absolute_top
          @document.start_new_page
        end
      end
    end
  end
end

然后它就像普通的列框一样被调用,但是在下一个页面中,它将重排为父项边界框。改变你的行:

  column_box([0, cursor], :columns => 3, :width => bounds.width) do

  reflow_column_box([0, cursor], :columns => 3, :width => bounds.width) do

希望它对你有所帮助。 Prawn相当低级,这是一把双刃剑,它有时无法满足您的需求,但是工具可以扩展并构建更复杂的结构。

答案 1 :(得分:8)

我知道这已经过时了,但我想我已经分享了在v0.14.0中添加了一个新选项以解决此问题。

:reflow_margins是一个选项,用于设置列框以在新页面创建时填充其父框。

column_box(reflow_margins: true, columns: 3)

答案 2 :(得分:2)

因此,column_box方法创建了一个边界框。边界框的记录行为是,如果它变为下一页,它将从与上一页相同的位置开始。所以你看到的行为基本上是正确的,也不是你想要的。我通过Google搜索找到的建议解决方法是使用span代替,因为跨度没有此行为。

现在的问题是,如何使用跨度构建文本列?它们似乎本身不支持跨度。我试图构建一个小脚本,用跨度模拟列。它为每列创建一个跨度并相应地对齐它们。然后,文本使用text_box编写,其中overflow: :truncate选项。这使得该方法返回不适合文本框的文本,以便可以在下一列中呈现此文本。代码可能需要一些调整,但它应该足以演示如何执行此操作。

require 'prawn'

text_to_write = ((<<-END.gsub(/\s+/, ' ') + "\n\n") * 20)
 All the States and Governments by which men are or ever have been ruled,
 have been and are either Republics or Princedoms. Princedoms are either
 hereditary, in which the bla bla bla bla .....
 END

pdf = Prawn::Document.generate("test.pdf") do
  text "The Prince", :align => :center, :size => 48
  text "Niccolò Machiavelli", :align => :center, :size => 20
  move_down 42

  starting_y = cursor
  starting_page = page_number

  span(bounds.width / 3, position: :left) do
    text_to_write = text_box text_to_write, at: [bounds.left, 0], overflow: :truncate
  end

  go_to_page(starting_page)
  move_cursor_to(starting_y)

  span(bounds.width / 3, position: :center) do
    text_to_write = text_box text_to_write, at: [bounds.left, 0], overflow: :truncate
  end

  go_to_page(starting_page)
  move_cursor_to(starting_y)

  span(bounds.width / 3, position: :right) do
    text_box text_to_write, at: [bounds.left, 0]
  end
end

我知道这不是一个理想的解决方案。然而,这是我能想到的最好的。

答案 3 :(得分:2)

使用浮动。

float do
        span((bounds.width / 3) - 20, :position => :left) do
                # Row Table Code
        end
end

float do
        span((bounds.width / 3) - 20, :position => :center) do
                # Row Table Code
        end
end

float do
        span((bounds.width / 3) - 20, :position => :right) do
                # Row Table Code
        end
end

答案 4 :(得分:-1)

使用Prawns网格布局。它有很好的文档记录......并且更容易控制您的布局。