1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Don't render unsightly XHTML newline escapes.

If we know we're rendering a top-level template,
we can un-escape XHTML newlines and thus prettify the output.
This commit is contained in:
Nathan Weizenbaum 2008-04-24 12:35:42 -07:00
parent 817448d31e
commit 0d4010cbaa
8 changed files with 155 additions and 32 deletions

View file

@ -367,6 +367,24 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
#
# <p>hello</p>
#
# ==== ~
#
# ~ works just like =, except that it runs Haml::Helpers#find_and_preserve on its input.
# For example,
#
# ~ "Foo\n<pre>Bar\nBaz</pre>"
#
# is the same as:
#
# = find_and_preserve("Foo\n<pre>Bar\nBaz</pre>")
#
# and is compiled to:
#
# Foo
# <pre>Bar&#x000A;Baz</pre>
#
# See also Whitespace Preservation, below.
#
# === XHTML Helpers
#
# ==== No Special Character
@ -595,6 +613,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
# <tt>preserve</tt>d blocks of text aren't indented,
# and newlines are replaced with the HTML escape code for newlines,
# to preserve nice-looking output.
# See also Whitespace Preservation, below.
#
# [erb] Parses the filtered text with ERB, like an RHTML template.
# Not available if the <tt>suppress_eval</tt> option is set to true.
@ -814,6 +833,27 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
#
# == Other Useful Things
#
# === Whitespace Preservation
#
# Sometimes you don't want Haml to indent all your text.
# For example, tags like +pre+ and +textarea+ are whitespace-sensitive;
# indenting the text makes them render wrong.
#
# Haml deals with this by "preserving" newlines before they're put into the document --
# converting them to the XHTML whitespace escape code, <tt>&#x000A;</tt>.
# Then Haml won't try to re-format the indentation.
#
# Literal +textarea+ and +pre+ tags automatically preserve their content.
# Dynamically can't be caught automatically,
# and so should be passed through Haml::Helpers#find_and_preserve or the <tt>~</tt> command,
# which has the same effect (see above).
#
# Blocks of literal text can be preserved using the :preserve filter (see above).
#
# After the top-level Haml template has been processed,
# all newline escapes are converted back into literal newlines
# to make the source code more readable.
#
# === Helpers
#
# Haml offers a bunch of helpers that are useful
@ -880,6 +920,8 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
#
# Defaults to <tt>['textarea', 'pre']</tt>.
#
# See also Whitespace Preservation, above.
#
module Haml
# Returns a hash representing the version of Haml.
# The :major, :minor, and :teeny keys have their respective numbers.

View file

@ -87,6 +87,13 @@ module Haml
@real_tabs = 0
end
# Returns the compiled string.
# This is distinct from #buffer in that some post-processing is done.
def result
return buffer unless @options[:ugly] || toplevel?
buffer.gsub('&#x000A;', "\n")
end
# Renders +text+ with the proper tabulation. This also deals with
# making a possible one-line tag one line or not.
def push_text(text, tab_change = 0)

View file

@ -171,7 +171,7 @@ END
@haml_buffer = buffer.upper
end
buffer.buffer
buffer.result
end
alias_method :to_html, :render

View file

@ -102,7 +102,7 @@ _erbout = _hamlout.buffer
END
postamble = <<END.gsub("\n", ";")
@haml_buffer = @haml_buffer.upper
_erbout
_hamlout.result
END
preamble + locals_code(local_names) + @precompiled + postamble
end

View file

@ -121,10 +121,10 @@ END
end
def test_textareas
assert_equal("<textarea>Foo&#x000A; bar&#x000A; baz</textarea>\n",
assert_equal("<textarea>Foo\n bar\n baz</textarea>\n",
render('%textarea= "Foo\n bar\n baz"'))
assert_equal("<pre>Foo&#x000A; bar&#x000A; baz</pre>\n",
assert_equal("<pre>Foo\n bar\n baz</pre>\n",
render('%pre= "Foo\n bar\n baz"'))
assert_equal("<textarea>#{'a' * 100}</textarea>\n",

View file

@ -82,13 +82,13 @@ class HelperTest < Test::Unit::TestCase
end
def test_text_area
assert_equal(%(<textarea id="body" name="body">Foo&#x000A;Bar&#x000A; Baz&#x000A; Boom</textarea>\n),
assert_equal(%(<textarea id="body" name="body">Foo\nBar\n Baz\n Boom</textarea>\n),
render('= text_area_tag "body", "Foo\nBar\n Baz\n Boom"', :action_view))
assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">Foo bar&#x000A;baz</textarea>\n),
assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">Foo bar\nbaz</textarea>\n),
render('= text_area :post, :body', :action_view))
assert_equal(%(<pre>Foo bar&#x000A; baz</pre>\n),
assert_equal(%(<pre>Foo bar\n baz</pre>\n),
render('= content_tag "pre", "Foo bar\n baz"', :action_view))
end
@ -141,12 +141,12 @@ class HelperTest < Test::Unit::TestCase
end
def test_find_and_preserve_with_block
assert_equal("<pre>&#x000A; Foo&#x000A; Bar&#x000A;</pre>\nFoo\nBar\n",
assert_equal("<pre>\n Foo\n Bar\n</pre>\nFoo\nBar\n",
render("= find_and_preserve do\n %pre\n Foo\n Bar\n Foo\n Bar"))
end
def test_preserve_with_block
assert_equal("<pre>&#x000A; Foo&#x000A; Bar&#x000A;</pre>&#x000A;Foo&#x000A;Bar&#x000A;\n",
assert_equal("<pre>\n Foo\n Bar\n</pre>\nFoo\nBar\n\n",
render("= preserve do\n %pre\n Foo\n Bar\n Foo\n Bar"))
end

View file

@ -41,8 +41,14 @@ This
\\
<p>
<pre>
This pre is pretty deeply&#x000A; nested.&#x000A; Does interpolation work?&#x000A;
This one is, too.&#x000A;Nested, that is.&#x000A;&#x000A;
This pre is pretty deeply
nested.
Does interpolation work?
This one is, too.
Nested, that is.
</pre>
</p>
<ul>

View file

@ -5,30 +5,38 @@
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Oneline</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
<div id='flattened'>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
</div>
</div>
<div class='hithere'>
Foo bar
<pre>foo bar</pre>
<pre>foo&#x000A;bar</pre>
<p><pre>foo&#x000A;bar</pre></p>
<pre>foo
bar</pre>
<p><pre>foo
bar</pre></p>
<p>
foo
bar
@ -36,7 +44,13 @@
</div>
<div class='foo'>
13
<textarea>&#x000A;a&#x000A;</textarea><textarea>&#x000A;b&#x000A;</textarea><textarea>&#x000A;c&#x000A;</textarea>
<textarea>
a
</textarea><textarea>
b
</textarea><textarea>
c
</textarea>
</div>
<div id='whitespace_test'>
<div class='text_area_test_area'>
@ -45,40 +59,89 @@
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Oneline</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
<div id='flattened'>
<div class='text_area_test_area'>
<textarea>Two&#x000A;lines</textarea>
<textarea>Two
lines</textarea>
</div>
<textarea>BLAH&#x000A;</textarea>
<textarea>BLAH
</textarea>
</div>
</div>
<div class='hithere'>
Foo bar
<pre>foo bar</pre>
<pre>foo&#x000A;bar</pre>
<p><pre>foo&#x000A;bar</pre></p>
<pre>foo
bar</pre>
<p><pre>foo
bar</pre></p>
<p>
foo
bar
</p>
<pre>
___&#x000A; ,o88888&#x000A; ,o8888888'&#x000A; ,:o:o:oooo. ,8O88Pd8888"&#x000A; ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"&#x000A; ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"&#x000A; , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"&#x000A; , ..:.::o:ooOoOO8O888O8O,COCOO"&#x000A; , . ..:.::o:ooOoOOOO8OOOOCOCO"&#x000A; . ..:.::o:ooOoOoOO8O8OCCCC"o&#x000A; . ..:.::o:ooooOoCoCCC"o:o&#x000A; . ..:.::o:o:,cooooCo"oo:o:&#x000A; ` . . ..:.:cocoooo"'o:o:::'&#x000A; .` . ..::ccccoc"'o:o:o:::'&#x000A; :.:. ,c:cccc"':.:.:.:.:.'&#x000A; ..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/&#x000A; ...:.'.:.::::"' . . . . .'&#x000A; .. . ....:."' ` . . . ''&#x000A; . . . ...."'&#x000A; .. . ."' -hrr-&#x000A; .&#x000A;&#x000A;&#x000A; It's a planet!&#x000A;%strong This shouldn't be bold!&#x000A;
___
,o88888
,o8888888'
,:o:o:oooo. ,8O88Pd8888"
,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
, ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
, ..:.::o:ooOoOO8O888O8O,COCOO"
, . ..:.::o:ooOoOOOO8OOOOCOCO"
. ..:.::o:ooOoOoOO8O8OCCCC"o
. ..:.::o:ooooOoCoCCC"o:o
. ..:.::o:o:,cooooCo"oo:o:
` . . ..:.:cocoooo"'o:o:::'
.` . ..::ccccoc"'o:o:o:::'
:.:. ,c:cccc"':.:.:.:.:.'
..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/
...:.'.:.::::"' . . . . .'
.. . ....:."' ` . . . ''
. . . ...."'
.. . ."' -hrr-
.
It's a planet!
%strong This shouldn't be bold!
</pre>
<strong>This should!</strong>
<textarea>
___ ___ ___ ___ &#x000A; /\__\ /\ \ /\__\ /\__\&#x000A; /:/ / /::\ \ /::| | /:/ /&#x000A; /:/__/ /:/\:\ \ /:|:| | /:/ / &#x000A; /::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ / &#x000A; /:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/ &#x000A; \/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \ &#x000A; \::/ / \::/ / /:/ / \:\ \ &#x000A; /:/ / /:/ / /:/ / \:\ \ &#x000A; /:/ / /:/ / /:/ / \:\__\&#x000A; \/__/ \/__/ \/__/ \/__/&#x000A;&#x000A; Many&#x000A; thanks&#x000A; to&#x000A; http://www.network-science.de/ascii/&#x000A;
___ ___ ___ ___
/\__\ /\ \ /\__\ /\__\
/:/ / /::\ \ /::| | /:/ /
/:/__/ /:/\:\ \ /:|:| | /:/ /
/::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ /
/:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/
\/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \
\::/ / \::/ / /:/ / \:\ \
/:/ / /:/ / /:/ / \:\ \
/:/ / /:/ / /:/ / \:\__\
\/__/ \/__/ \/__/ \/__/
Many
thanks
to
http://www.network-science.de/ascii/
<strong>indeed!</strong>
</textarea>
</div>
@ -86,9 +149,14 @@
13
</div>
<pre>
__ ______ __ ______&#x000A;.----.| |--.|__ |.----.| |--..--------.| __ |&#x000A;| __|| ||__ || __|| < | || __ |&#x000A;|____||__|__||______||____||__|__||__|__|__||______|&#x000A;
__ ______ __ ______
.----.| |--.|__ |.----.| |--..--------.| __ |
| __|| ||__ || __|| < | || __ |
|____||__|__||______||____||__|__||__|__|__||______|
</pre>
<pre>
foo&#x000A;
foo
bar
</pre>