Automatically delete all newline from Haml output

I use Haml in a Rails 3 application and its new lines put me nuts! For instance,

%span foo 

displayed as

 <span> foo </span> 

But I would really like to

 <span>foo</foo> 

The reason (besides pure XML) is that extra line breaks are a problem for my Selenium tests because they ruined the ability to execute XPath queries, such as "//span[.='foo']" . "//span[.='foo']" So I would have to write '\nfoo\n' instead of (ew!) Or use //span[contains(text(), 'foo')] , which matches too broadly.

I know that I could use alligator operators ("<" and ">") to separate spaces, but since I never had a case where I want newlines to appear on the output, I would just end up adding them mechanically at the end of each line. And it just seems very unfortunate.

So now I see two solutions:

  • Force Haml will never produce newlines unless they receive a Ruby expression. I see some nuke_inner_whitespace / nuke_outer_whitespace variables distributed around Haml code that can do the job, but I'm not sure how to change them without resorting to free monkey fixes.
  • Connect to Rails to apply gsub!("\n", "") to all displayed HTML. (For textarea and pre's, I could still use ~ "foo\nbar" to make Haml emit foo&#x000A;bar .) But where is the right place to connect to Rails? I lost a little code.

Any pointers or other suggestions appreciated!

Update: I used the Jason Monkey patch below for a while, and I'm starting to think it is not worth it. For instance. if I want to get <span>[del]</span> <span>foo</span> , it’s hard not to have a space between the core kernels. Even the following will display as [del]foo on the page:

 %span = '[del] ' %span foo 

So, I think I'll get back to adding alligator operators manually (see my own answer below). Live and learn.

Thanks again to Jason! :)

+4
source share
4 answers

If you place a character less than at the end of the element name, spaces around the content will be suppressed:

 %span< foo 

For more information, see removing spaces in the Haml link.

There seems to be no clean way to force these flags on for all tags, but the following monkey patch works fine with 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 

It would probably not be easy to remake Haml and add the Engine option to always have gaps in nuclear weapons. The parse_tag method can check this parameter, if enabled, and set the internal and external flags to true. I will leave this as an exercise for the reader. :)

+11
source

A few ways to do this:

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

As in @yfeldblum's answer, I decided to just split into new lines and join spaces to avoid new lines appearing in html passed to js. For instance:

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

and then later

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

Well, I think I will try to answer my question - there probably isn’t a clean / reasonable way to delete all new lines, but maybe I really don’t need it. For typical XPath test expressions, working well is enough if inline elements do not have new lines around them.

So, I guess I would just put inside-whitespace-eater ("<") after any tag that contains inline elements (p, li, span, a, etc.). It seems to work quite well so far. For instance.

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

And all the rest (that is, most) of new lines can remain and will not do any harm.

Sorry everyone for the messy question!

0
source

All Articles