13

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

在此处输入图像描述

这是一个非常基本的布局方案,但我不明白如何在 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

但这只会继续显示每一页的标题空间:

在此处输入图像描述

这样做的正确方法是什么?

4

5 回答 5

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 的级别很低,是一把双刃剑,它有时无法满足您的需求,但可以使用工具来扩展和构建更复杂的结构。

于 2013-07-04T03:50:59.733 回答
8

我知道这很旧,但我想我会分享一个新选项已添加到v0.14.0.

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

column_box(reflow_margins: true, columns: 3)
于 2014-07-25T13:43:31.717 回答
2

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

现在的问题是,如何使用 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

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

于 2013-06-29T13:41:02.777 回答
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
于 2014-04-21T13:43:47.950 回答
-1

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

于 2013-06-29T15:11:12.413 回答