从Haml输出中自动删除所有换行符

时间:2010-12-01 00:26:50

标签: ruby-on-rails haml ruby-on-rails-3

我在Rails 3应用程序中使用Haml,它的新行让我疯了!例如,

%span
  foo

呈现为

<span>
foo
</span>

但我更想要

<span>foo</foo>

原因(除了更清晰的XML)之外,额外的换行是我的Selenium测试的一个问题,因为它们搞乱了执行像"//span[.='foo']"这样的XPath查询的能力。所以我必须改为编写'\nfoo\n'(ew!),或使用匹配得过于宽泛的//span[contains(text(), 'foo')]

我知道我可以使用鳄鱼操作符(“&lt;”和“&gt;”)去除空格,但是因为我没有一个我想要出现新行的情况在输出中,我最终会在每行末尾机械地添加它们。而这似乎非常不合适。

所以现在我看到两个解决方案:

  1. 强制Haml永远不会发出新行,除非它们来自Ruby表达式。我看到一些nuke_inner_whitespace / nuke_outer_whitespace变量遍布Haml代码,可能会完成这项工作,但我不确定如何更改它们而不采用无偿的猴子修补。
  2. 挂钩到Rails,将gsub!("\n", "")应用于所有呈现的HTML。 (对于textarea和pre,我仍然可以使用~ "foo\nbar"让Haml发出foo&#x000A;bar。)但是哪里是正确的地方可以挂钩?我在代码中有点迷失。
  3. 赞赏任何指针或其他建议!

    更新:我已经在下面使用了Jason的猴子补丁一段时间了,我开始认为这不值得。例如。如果我想获得<span>[del]</span> <span>foo</span>,则很难在nuked之间留有空白。即使以下内容也会在页面上呈现为[del]foo

    %span
      = '[del] '
    %span
      foo
    

    所以我想我会回去手动添加鳄鱼操作员(参见下面的自我回答)。生活和学习。

    再次感谢杰森! :)

4 个答案:

答案 0 :(得分:11)

如果在元素名称的末尾放置一个小于号的符号,则内容周围的空格将被抑制:

%span<
  foo

有关详细信息,请参阅Haml参考中的whitespace removal

似乎没有任何干净的方法强制所有标签上的这些标志,但以下猴子补丁适用于Haml 3.0.24:

module Haml::Precompiler
  def parse_tag_with_nuked_whitespace(line)
    result = parse_tag_without_nuked_whitespace line
    unless result.size == 9 && [false,true].include?(result[4]) && [false,true].include?(result[5])
      raise "Unexpected parse_tag output: #{result.inspect}"
    end
    result[4] = true # nuke_outer_whitespace
    result[5] = true # nuke_inner_whitespace
    result
  end
  alias_method_chain :parse_tag, :nuked_whitespace
end

将Haml分叉并为Engine选项添加一个选项以永远核对空格可能并不困难。如果启用,parse_tag方法可以检查此选项,并将内部和外部标志设置为true。我会将此作为练习留给读者。 :)

答案 1 :(得分:2)

有几种方法可以做到:

%span foo

%span= "foo"

- foo = ["f", "o", "o"].join("")
%span= foo

%span #{"foo"}

- foo = ["f", "o", "o"].join("")
%span #{foo}

答案 2 :(得分:1)

与@ yfeldblum的答案类似,我决定简单地拆分换行符并加入空格,以避免将html中的换行符渲染为js。例如:

- content = capture_haml do
  %div
    %ul
      %li Stuff
# ...

然后,

:javascript
  var stuff = "#{content.split("\n").join(" ")}";
  // ...

答案 3 :(得分:0)

好吧,我想我会尝试自我回答我的问题 - 可能没有干净/明智的方法来删除所有换行符,但也许我实际上并不需要这样做。对于典型的XPath测试表达式来说,如果 inline 元素周围没有换行符就足够了。

所以我想我只会在包含内联元素(p,li,span,a等)的任何标记之后放置一个内部空格食者(“&lt;”)。到目前为止,这似乎运作得相当好。 E.g。

%div
  %ul
    %li<
      %span<
        stuff...

所有其他(即大多数)新行都可以保留,不会造成任何伤害。

对于这个凌乱的问题,大家抱歉!