我有以下Ruby脚本:

require 'nokogiri'
require 'erb'

listing = %Q{<% listing "app/controllers/purchases_controller.rb", :id => "ch01_724" do %>
foo
<% end %>}
erb = ERB.new(listing, nil, nil, "@output")

def listing(title, attributes={})
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.example(attributes) do
      xml.title "Listing 1.1 #{title}"
      xml.programlisting do
        yield
      end
    end
  end
  @output.concat(builder.doc.root.to_xml)
end

p erb.result(binding)

运行时,输出以下内容:
"\n      foo\n    <example id=\"ch01_724\">\n  <title>Listing 1.1 app/controllers/purchases_controller.rb</title>\n  <programlisting/>\n</example>"

这个字符串的“foo”部分应该在programlisting元素中,但是由于某些原因,它的前缀是字符串的开头。
这是为什么,我该怎么解决?

最佳答案

这是因为通过产生,您将控制权传递给erb,erb将获得“foo”,然后您将在之后连接方法的输出。
rails是如何通过使用capture来实现这一点的,capture基本上是为一个新字符串切换输出缓冲区,然后连接这个新字符串。
像这样的事情似乎奏效了:

def listing(title, attributes={}, &block)
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.example(attributes) do
      xml.title "Listing 1.1 #{title}"
      xml.programlisting capture(&block)
    end
  end
  @output.concat(builder.doc.root.to_xml)
end

def capture
  @_out, @output = @output, ""
  yield
ensure
  @output = @_out
end

关于ruby - Nokogiri + ERB标签无序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9855072/

10-14 01:34