Nokogiri + ERB标签无法订购

Rya*_*igg 2 ruby nokogiri

我有以下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)
Run Code Online (Sandbox Code Playgroud)

运行时,它输出以下内容:

"\n      foo\n    <example id=\"ch01_724\">\n  <title>Listing 1.1 app/controllers/purchases_controller.rb</title>\n  <programlisting/>\n</example>"
Run Code Online (Sandbox Code Playgroud)

此字符串的"foo"部分应位于programlisting元素内部,但由于某种原因,它将作为字符串开头的前缀.

为什么会这样,我该如何解决?

Nic*_*tti 6

那是因为通过屈服你将控制传递给ERB,它获得了"foo",然后你就连接了该方法的输出.

如何通过使用捕获来实现这一点,捕获基本上将输出缓冲区切换为新字符串,然后连接该新字符串.

这样的东西似乎有效:

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
Run Code Online (Sandbox Code Playgroud)