首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Prawn控制内容流

使用Prawn控制内容流
EN

Stack Overflow用户
提问于 2013-06-25 02:09:19
回答 5查看 4.8K关注 0票数 13

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

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

以下是从他们的在线文档中派生的一些示例代码:

代码语言:javascript
复制
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

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

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

EN

回答 5

Stack Overflow用户

发布于 2013-07-04 11:51:00

我一直在与同样的问题作斗争。我最终实现了ColumnBox的子类化,并添加了一个助手来调用它,如下所示:

代码语言:javascript
复制
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

然后,它就像普通的列框一样被调用,但在下一个分页符将回流到父级边界框。更改您的行:

代码语言:javascript
复制
  column_box([0, cursor], :columns => 3, :width => bounds.width) do

代码语言:javascript
复制
  reflow_column_box([0, cursor], :columns => 3, :width => bounds.width) do

希望能对你有所帮助。对虾的水平非常低,这是一把双刃剑,它有时无法完成你需要的事情,但工具是用来扩展和构建更复杂的结构的。

票数 10
EN

Stack Overflow用户

发布于 2014-07-25 21:43:32

我知道这是旧的,但是我想我应该分享一下,在v0.14.0中添加了一个新的选项来解决这个问题。

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

代码语言:javascript
复制
column_box(reflow_margins: true, columns: 3)
票数 8
EN

Stack Overflow用户

发布于 2013-06-29 21:41:03

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

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

代码语言:javascript
复制
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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17282100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档