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

Json is inconvenient

This commit is contained in:
Takashi Kokubun 2015-10-11 20:45:15 +09:00
parent c9007ea44b
commit 1cd324151d
5 changed files with 547 additions and 675 deletions

View file

@ -2,7 +2,7 @@ $:.unshift File.expand_path('../lib', __FILE__)
require 'hamlit'
require 'faml'
require 'json'
require 'yaml'
class Benchmark
def self.bench
@ -52,8 +52,8 @@ namespace :benchmark do
haml_benchmark = Benchmark.new('haml ')
faml_benchmark = Benchmark.new('faml ')
hamlit_benchmark = Benchmark.new('hamlit')
json_path = File.expand_path('../test/haml-spec/tests.json', __dir__)
contexts = JSON.parse(File.read(json_path))
yaml_path = File.expand_path('../test/haml-spec/tests.yml', __dir__)
contexts = YAML.load(File.read(yaml_path))
faml_engine = Faml::Engine.new(filename: '')
hamlit_engine = Hamlit::Engine.new

View file

@ -1,12 +1,12 @@
$:.unshift File.expand_path('../lib', __FILE__)
require 'hamlit'
require 'json'
require 'yaml'
desc 'Profile compilation'
task :profile do
json_path = File.expand_path('../test/haml-spec/tests.json', __dir__)
contexts = JSON.parse(File.read(json_path))
yaml_path = File.expand_path('../test/haml-spec/tests.yml', __dir__)
contexts = YAML.load(File.read(yaml_path))
hamlit_engine = Hamlit::Engine.new

View file

@ -1,16 +1,15 @@
require 'rubygems'
require 'minitest/autorun'
require 'json'
require 'yaml'
require 'haml'
require 'hamlit'
class HamlTest < MiniTest::Test
contexts = JSON.parse(File.read(File.dirname(__FILE__) + '/tests.json'))
contexts = YAML.load(File.read(File.expand_path('./tests.yml', __dir__)))
contexts.each do |context|
context[1].each do |name, test|
[{ ugly: true }].each do |base_options|
define_method("test_#{base_options[:ugly] ? 'ugly' : 'pretty'}_spec: #{name} (#{context[0]})") do
define_method("test_#{ base_options[:ugly] ? 'ugly' : 'pretty' }_spec: #{name} (#{context[0]})") do
haml = test['haml']
locals = Hash[(test['locals'] || {}).map {|x, y| [x.to_sym, y]}]
options = Hash[(test['config'] || {}).map {|x, y| [x.to_sym, y]}]

View file

@ -1,665 +0,0 @@
{
"headers" : {
"an XHTML XML prolog" : {
"haml" : "!!! XML",
"html" : "<?xml version='1.0' encoding='utf-8' ?>",
"config" : {
"format" : "xhtml"
}
},
"an XHTML default (transitional) doctype" : {
"haml" : "!!!",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
"config" : {
"format" : "xhtml"
}
},
"an XHTML 1.1 doctype" : {
"haml" : "!!! 1.1",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">",
"config" : {
"format" : "xhtml"
}
},
"an XHTML 1.2 mobile doctype" : {
"haml" : "!!! mobile",
"html" : "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">",
"config" : {
"format" : "xhtml"
}
},
"an XHTML 1.1 basic doctype" : {
"haml" : "!!! basic",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">",
"config" : {
"format" : "xhtml"
}
},
"an XHTML 1.0 frameset doctype" : {
"haml" : "!!! frameset",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
"config" : {
"format" : "xhtml"
}
},
"an HTML 5 doctype with XHTML syntax" : {
"haml" : "!!! 5",
"html" : "<!DOCTYPE html>",
"config" : {
"format" : "xhtml"
}
},
"an HTML 5 XML prolog (silent)" : {
"haml" : "!!! XML",
"html" : "",
"config" : {
"format" : "html5"
}
},
"an HTML 5 doctype" : {
"haml" : "!!!",
"html" : "<!DOCTYPE html>",
"config" : {
"format" : "html5"
}
},
"an HTML 4 XML prolog (silent)" : {
"haml" : "!!! XML",
"html" : "",
"config" : {
"format" : "html4"
}
},
"an HTML 4 default (transitional) doctype" : {
"haml" : "!!!",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">",
"config" : {
"format" : "html4"
}
},
"an HTML 4 frameset doctype" : {
"haml" : "!!! frameset",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">",
"config" : {
"format" : "html4"
}
},
"an HTML 4 strict doctype" : {
"haml" : "!!! strict",
"html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">",
"config" : {
"format" : "html4"
}
}
},
"basic Haml tags and CSS": {
"a simple Haml tag" : {
"haml" : "%p",
"html" : "<p></p>"
},
"a self-closing tag (XHTML)" : {
"haml" : "%meta",
"html" : "<meta />",
"config" : {
"format" : "xhtml"
}
},
"a self-closing tag (HTML4)" : {
"haml" : "%meta",
"html" : "<meta>",
"config" : {
"format" : "html4"
}
},
"a self-closing tag (HTML5)" : {
"haml" : "%meta",
"html" : "<meta>",
"config" : {
"format" : "html5"
}
},
"a self-closing tag ('/' modifier + XHTML)" : {
"haml" : "%zzz/",
"html" : "<zzz />",
"config" : {
"format" : "xhtml"
}
},
"a self-closing tag ('/' modifier + HTML5)" : {
"haml" : "%zzz/",
"html" : "<zzz>",
"config" : {
"format" : "html5"
}
},
"a tag with a CSS class" : {
"haml" : "%p.class1",
"html" : "<p class='class1'></p>"
},
"a tag with multiple CSS classes" : {
"haml" : "%p.class1.class2",
"html" : "<p class='class1 class2'></p>"
},
"a tag with a CSS id" : {
"haml" : "%p#id1",
"html" : "<p id='id1'></p>"
},
"a tag with multiple CSS id's" : {
"haml" : "%p#id1#id2",
"html" : "<p id='id2'></p>"
},
"a tag with a class followed by an id" : {
"haml" : "%p.class1#id1",
"html" : "<p class='class1' id='id1'></p>"
},
"a tag with an id followed by a class" : {
"haml" : "%p#id1.class1",
"html" : "<p class='class1' id='id1'></p>"
},
"an implicit div with a CSS id" : {
"haml" : "#id1",
"html" : "<div id='id1'></div>"
},
"an implicit div with a CSS class" : {
"haml" : ".class1",
"html" : "<div class='class1'></div>"
},
"multiple simple Haml tags" : {
"haml" : "%div\n %div\n %p",
"html" : "<div>\n <div>\n <p></p>\n </div>\n</div>"
}
},
"tags with unusual HTML characters" : {
"a tag with colons" : {
"haml" : "%ns:tag",
"html" : "<ns:tag></ns:tag>"
},
"a tag with underscores" : {
"haml" : "%snake_case",
"html" : "<snake_case></snake_case>"
},
"a tag with dashes" : {
"haml" : "%dashed-tag",
"html" : "<dashed-tag></dashed-tag>"
},
"a tag with camelCase" : {
"haml" : "%camelCase",
"html" : "<camelCase></camelCase>"
},
"a tag with PascalCase" : {
"haml" : "%PascalCase",
"html" : "<PascalCase></PascalCase>"
}
},
"tags with unusual CSS identifiers" : {
"an all-numeric class" : {
"haml" : ".123",
"html" : "<div class='123'></div>"
},
"a class with underscores" : {
"haml" : ".__",
"html" : "<div class='__'></div>"
},
"a class with dashes" : {
"haml" : ".--",
"html" : "<div class='--'></div>"
}
},
"tags with inline content" : {
"Inline content simple tag" : {
"haml" : "%p hello",
"html" : "<p>hello</p>"
},
"Inline content tag with CSS" : {
"haml" : "%p.class1 hello",
"html" : "<p class='class1'>hello</p>"
},
"Inline content multiple simple tags" : {
"haml" : "%div\n %div\n %p text",
"html" : "<div>\n <div>\n <p>text</p>\n </div>\n</div>"
}
},
"tags with nested content" : {
"Nested content simple tag" : {
"haml" : "%p\n hello",
"html" : "<p>\n hello\n</p>"
},
"Nested content tag with CSS" : {
"haml" : "%p.class1\n hello",
"html" : "<p class='class1'>\n hello\n</p>"
},
"Nested content multiple simple tags" : {
"haml" : "%div\n %div\n %p\n text",
"html" : "<div>\n <div>\n <p>\n text\n </p>\n </div>\n</div>"
}
},
"tags with HTML-style attributes": {
"HTML-style one attribute" : {
"haml" : "%p(a='b')",
"html" : "<p a='b'></p>"
},
"HTML-style multiple attributes" : {
"haml" : "%p(a='b' c='d')",
"html" : "<p a='b' c='d'></p>"
},
"HTML-style attributes separated with newlines" : {
"haml" : "%p(a='b'\n c='d')",
"html" : "<p a='b' c='d'></p>"
},
"HTML-style interpolated attribute" : {
"haml" : "%p(a=\"#{var}\")",
"html" : "<p a='value'></p>",
"locals" : {
"var" : "value"
}
},
"HTML-style 'class' as an attribute" : {
"haml" : "%p(class='class1')",
"html" : "<p class='class1'></p>"
},
"HTML-style tag with a CSS class and 'class' as an attribute" : {
"haml" : "%p.class2(class='class1')",
"html" : "<p class='class1 class2'></p>"
},
"HTML-style tag with 'id' as an attribute" : {
"haml" : "%p(id='1')",
"html" : "<p id='1'></p>"
},
"HTML-style tag with a CSS id and 'id' as an attribute" : {
"haml" : "%p#id(id='1')",
"html" : "<p id='id_1'></p>"
},
"HTML-style tag with a variable attribute" : {
"haml" : "%p(class=var)",
"html" : "<p class='hello'></p>",
"locals" : {
"var" : "hello"
}
},
"HTML-style tag with a CSS class and 'class' as a variable attribute" : {
"haml" : ".hello(class=var)",
"html" : "<div class='hello world'></div>",
"locals" : {
"var" : "world"
}
},
"HTML-style tag multiple CSS classes (sorted correctly)" : {
"haml" : ".z(class=var)",
"html" : "<div class='a z'></div>",
"locals" : {
"var" : "a"
}
},
"HTML-style tag with an atomic attribute" : {
"haml" : "%a(flag)",
"html" : "<a flag></a>"
}
},
"tags with Ruby-style attributes": {
"Ruby-style one attribute" : {
"haml" : "%p{:a => 'b'}",
"html" : "<p a='b'></p>",
"optional" : true
},
"Ruby-style attributes hash with whitespace" : {
"haml" : "%p{ :a => 'b' }",
"html" : "<p a='b'></p>",
"optional" : true
},
"Ruby-style interpolated attribute" : {
"haml" : "%p{:a =>\"#{var}\"}",
"html" : "<p a='value'></p>",
"optional" : true,
"locals" : {
"var" : "value"
}
},
"Ruby-style multiple attributes" : {
"haml" : "%p{ :a => 'b', 'c' => 'd' }",
"html" : "<p a='b' c='d'></p>",
"optional" : true
},
"Ruby-style attributes separated with newlines" : {
"haml" : "%p{ :a => 'b',\n 'c' => 'd' }",
"html" : "<p a='b' c='d'></p>",
"optional" : true
},
"Ruby-style 'class' as an attribute" : {
"haml" : "%p{:class => 'class1'}",
"html" : "<p class='class1'></p>",
"optional" : true
},
"Ruby-style tag with a CSS class and 'class' as an attribute" : {
"haml" : "%p.class2{:class => 'class1'}",
"html" : "<p class='class1 class2'></p>",
"optional" : true
},
"Ruby-style tag with 'id' as an attribute" : {
"haml" : "%p{:id => '1'}",
"html" : "<p id='1'></p>",
"optional" : true
},
"Ruby-style tag with a CSS id and 'id' as an attribute" : {
"haml" : "%p#id{:id => '1'}",
"html" : "<p id='id_1'></p>",
"optional" : true
},
"Ruby-style tag with a CSS id and a numeric 'id' as an attribute" : {
"haml" : "%p#id{:id => 1}",
"html" : "<p id='id_1'></p>",
"optional" : true
},
"Ruby-style tag with a variable attribute" : {
"haml" : "%p{:class => var}",
"html" : "<p class='hello'></p>",
"optional" : true,
"locals" : {
"var" : "hello"
}
},
"Ruby-style tag with a CSS class and 'class' as a variable attribute" : {
"haml" : ".hello{:class => var}",
"html" : "<div class='hello world'></div>",
"optional" : true,
"locals" : {
"var" : "world"
}
},
"Ruby-style tag multiple CSS classes (sorted correctly)" : {
"haml" : ".z{:class => var}",
"html" : "<div class='a z'></div>",
"optional" : true,
"locals" : {
"var" : "a"
}
}
},
"silent comments" : {
"an inline silent comment" : {
"haml" : "-# hello",
"html" : ""
},
"a nested silent comment" : {
"haml" : "-#\n hello",
"html" : ""
},
"a multiply nested silent comment" : {
"haml" : "-#\n %div\n foo",
"html" : ""
},
"a multiply nested silent comment with inconsistent indents" : {
"haml" : "-#\n %div\n foo",
"html" : ""
}
},
"markup comments" : {
"an inline markup comment" : {
"haml" : "/ comment",
"html" : "<!-- comment -->"
},
"a nested markup comment" : {
"haml" : "/\n comment\n comment2",
"html" : "<!--\n comment\n comment2\n-->"
}
},
"conditional comments": {
"a conditional comment" : {
"haml" : "/[if IE]\n %p a",
"html" : "<!--[if IE]>\n <p>a</p>\n<![endif]-->"
}
},
"internal filters": {
"content in an 'escaped' filter" : {
"haml" : ":escaped\n <&\">",
"html" : "&lt;&amp;&quot;&gt;"
},
"content in a 'preserve' filter" : {
"haml" : ":preserve\n hello\n\n%p",
"html" : "hello&#x000A;\n<p></p>"
},
"content in a 'plain' filter" : {
"haml" : ":plain\n hello\n\n%p",
"html" : "hello\n<p></p>"
},
"content in a 'css' filter (XHTML)" : {
"haml" : ":css\n hello\n\n%p",
"html" : "<style type='text/css'>\n /*<![CDATA[*/\n hello\n /*]]>*/\n</style>\n<p></p>",
"config" : {
"format" : "xhtml"
}
},
"content in a 'javascript' filter (XHTML)" : {
"haml" : ":javascript\n a();\n%p",
"html" : "<script type='text/javascript'>\n //<![CDATA[\n a();\n //]]>\n</script>\n<p></p>",
"config" : {
"format" : "xhtml"
}
},
"content in a 'css' filter (HTML)" : {
"haml" : ":css\n hello\n\n%p",
"html" : "<style>\n hello\n</style>\n<p></p>",
"config" : {
"format" : "html5"
}
},
"content in a 'javascript' filter (HTML)" : {
"haml" : ":javascript\n a();\n%p",
"html" : "<script>\n a();\n</script>\n<p></p>",
"config" : {
"format" : "html5"
}
}
},
"Ruby-style interpolation": {
"interpolation inside inline content" : {
"haml" : "%p #{var}",
"html" : "<p>value</p>",
"optional" : true,
"locals" : {
"var" : "value"
}
},
"no interpolation when escaped" : {
"haml" : "%p \\#{var}",
"html" : "<p>#{var}</p>",
"optional" : true,
"locals" : {
"var" : "value"
}
},
"interpolation when the escape character is escaped" : {
"haml" : "%p \\\\#{var}",
"html" : "<p>\\value</p>",
"optional" : true,
"locals" : {
"var" : "value"
}
},
"interpolation inside filtered content" : {
"haml" : ":plain\n #{var} interpolated: #{var}",
"html" : "value interpolated: value",
"optional" : true,
"locals" : {
"var" : "value"
}
}
},
"HTML escaping" : {
"code following '&='" : {
"haml" : "&= '<\"&>'",
"html" : "&lt;&quot;&amp;&gt;"
},
"code following '=' when escape_haml is set to true" : {
"haml" : "= '<\"&>'",
"html" : "&lt;&quot;&amp;&gt;",
"config" : {
"escape_html" : "true"
}
},
"code following '!=' when escape_haml is set to true" : {
"haml" : "!= '<\"&>'",
"html" : "<\"&>",
"config" : {
"escape_html" : "true"
}
}
},
"boolean attributes" : {
"boolean attribute with XHTML" : {
"haml" : "%input(checked=true)",
"html" : "<input checked='checked' />",
"config" : {
"format" : "xhtml"
}
},
"boolean attribute with HTML" : {
"haml" : "%input(checked=true)",
"html" : "<input checked>",
"config" : {
"format" : "html5"
}
}
},
"whitespace preservation" : {
"following the '~' operator" : {
"haml" : "~ \"Foo\\n<pre>Bar\\nBaz</pre>\"",
"html" : "Foo\n<pre>Bar&#x000A;Baz</pre>",
"optional" : true
},
"inside a textarea tag" : {
"haml" : "%textarea\n hello\n hello",
"html" : "<textarea>hello\nhello</textarea>"
},
"inside a pre tag" : {
"haml" : "%pre\n hello\n hello",
"html" : "<pre>hello\nhello</pre>"
}
},
"whitespace removal" : {
"a tag with '>' appended and inline content" : {
"haml" : "%li hello\n%li> world\n%li again",
"html" : "<li>hello</li><li>world</li><li>again</li>"
},
"a tag with '>' appended and nested content" : {
"haml" : "%li hello\n%li>\n world\n%li again",
"html" : "<li>hello</li><li>\n world\n</li><li>again</li>"
},
"a tag with '<' appended" : {
"haml" : "%p<\n hello\n world",
"html" : "<p>hello\nworld</p>"
}
}
}

538
test/haml-spec/tests.yml Normal file
View file

@ -0,0 +1,538 @@
---
headers:
an XHTML XML prolog:
haml: "!!! XML"
html: "<?xml version='1.0' encoding='utf-8' ?>"
config:
format: xhtml
an XHTML default (transitional) doctype:
haml: "!!!"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
config:
format: xhtml
an XHTML 1.1 doctype:
haml: "!!! 1.1"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
config:
format: xhtml
an XHTML 1.2 mobile doctype:
haml: "!!! mobile"
html: <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
config:
format: xhtml
an XHTML 1.1 basic doctype:
haml: "!!! basic"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
config:
format: xhtml
an XHTML 1.0 frameset doctype:
haml: "!!! frameset"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
config:
format: xhtml
an HTML 5 doctype with XHTML syntax:
haml: "!!! 5"
html: "<!DOCTYPE html>"
config:
format: xhtml
an HTML 5 XML prolog (silent):
haml: "!!! XML"
html: ''
config:
format: html5
an HTML 5 doctype:
haml: "!!!"
html: "<!DOCTYPE html>"
config:
format: html5
an HTML 4 XML prolog (silent):
haml: "!!! XML"
html: ''
config:
format: html4
an HTML 4 default (transitional) doctype:
haml: "!!!"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
config:
format: html4
an HTML 4 frameset doctype:
haml: "!!! frameset"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
config:
format: html4
an HTML 4 strict doctype:
haml: "!!! strict"
html: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
config:
format: html4
basic Haml tags and CSS:
a simple Haml tag:
haml: "%p"
html: "<p></p>"
a self-closing tag (XHTML):
haml: "%meta"
html: "<meta />"
config:
format: xhtml
a self-closing tag (HTML4):
haml: "%meta"
html: "<meta>"
config:
format: html4
a self-closing tag (HTML5):
haml: "%meta"
html: "<meta>"
config:
format: html5
a self-closing tag ('/' modifier + XHTML):
haml: "%zzz/"
html: "<zzz />"
config:
format: xhtml
a self-closing tag ('/' modifier + HTML5):
haml: "%zzz/"
html: "<zzz>"
config:
format: html5
a tag with a CSS class:
haml: "%p.class1"
html: "<p class='class1'></p>"
a tag with multiple CSS classes:
haml: "%p.class1.class2"
html: "<p class='class1 class2'></p>"
a tag with a CSS id:
haml: "%p#id1"
html: "<p id='id1'></p>"
a tag with multiple CSS id's:
haml: "%p#id1#id2"
html: "<p id='id2'></p>"
a tag with a class followed by an id:
haml: "%p.class1#id1"
html: "<p class='class1' id='id1'></p>"
a tag with an id followed by a class:
haml: "%p#id1.class1"
html: "<p class='class1' id='id1'></p>"
an implicit div with a CSS id:
haml: "#id1"
html: "<div id='id1'></div>"
an implicit div with a CSS class:
haml: ".class1"
html: "<div class='class1'></div>"
multiple simple Haml tags:
haml: |-
%div
%div
%p
html: |-
<div>
<div>
<p></p>
</div>
</div>
tags with unusual HTML characters:
a tag with colons:
haml: "%ns:tag"
html: "<ns:tag></ns:tag>"
a tag with underscores:
haml: "%snake_case"
html: "<snake_case></snake_case>"
a tag with dashes:
haml: "%dashed-tag"
html: "<dashed-tag></dashed-tag>"
a tag with camelCase:
haml: "%camelCase"
html: "<camelCase></camelCase>"
a tag with PascalCase:
haml: "%PascalCase"
html: "<PascalCase></PascalCase>"
tags with unusual CSS identifiers:
an all-numeric class:
haml: ".123"
html: "<div class='123'></div>"
a class with underscores:
haml: ".__"
html: "<div class='__'></div>"
a class with dashes:
haml: ".--"
html: "<div class='--'></div>"
tags with inline content:
Inline content simple tag:
haml: "%p hello"
html: "<p>hello</p>"
Inline content tag with CSS:
haml: "%p.class1 hello"
html: "<p class='class1'>hello</p>"
Inline content multiple simple tags:
haml: |-
%div
%div
%p text
html: |-
<div>
<div>
<p>text</p>
</div>
</div>
tags with nested content:
Nested content simple tag:
haml: |-
%p
hello
html: |-
<p>
hello
</p>
Nested content tag with CSS:
haml: |-
%p.class1
hello
html: |-
<p class='class1'>
hello
</p>
Nested content multiple simple tags:
haml: |-
%div
%div
%p
text
html: |-
<div>
<div>
<p>
text
</p>
</div>
</div>
tags with HTML-style attributes:
HTML-style one attribute:
haml: "%p(a='b')"
html: "<p a='b'></p>"
HTML-style multiple attributes:
haml: "%p(a='b' c='d')"
html: "<p a='b' c='d'></p>"
HTML-style attributes separated with newlines:
haml: |-
%p(a='b'
c='d')
html: "<p a='b' c='d'></p>"
HTML-style interpolated attribute:
haml: '%p(a="#{var}")'
html: "<p a='value'></p>"
locals:
var: value
HTML-style 'class' as an attribute:
haml: "%p(class='class1')"
html: "<p class='class1'></p>"
HTML-style tag with a CSS class and 'class' as an attribute:
haml: "%p.class2(class='class1')"
html: "<p class='class1 class2'></p>"
HTML-style tag with 'id' as an attribute:
haml: "%p(id='1')"
html: "<p id='1'></p>"
HTML-style tag with a CSS id and 'id' as an attribute:
haml: "%p#id(id='1')"
html: "<p id='id_1'></p>"
HTML-style tag with a variable attribute:
haml: "%p(class=var)"
html: "<p class='hello'></p>"
locals:
var: hello
HTML-style tag with a CSS class and 'class' as a variable attribute:
haml: ".hello(class=var)"
html: "<div class='hello world'></div>"
locals:
var: world
HTML-style tag multiple CSS classes (sorted correctly):
haml: ".z(class=var)"
html: "<div class='a z'></div>"
locals:
var: a
HTML-style tag with an atomic attribute:
haml: "%a(flag)"
html: "<a flag></a>"
tags with Ruby-style attributes:
Ruby-style one attribute:
haml: "%p{:a => 'b'}"
html: "<p a='b'></p>"
optional: true
Ruby-style attributes hash with whitespace:
haml: "%p{ :a => 'b' }"
html: "<p a='b'></p>"
optional: true
Ruby-style interpolated attribute:
haml: '%p{:a =>"#{var}"}'
html: "<p a='value'></p>"
optional: true
locals:
var: value
Ruby-style multiple attributes:
haml: "%p{ :a => 'b', 'c' => 'd' }"
html: "<p a='b' c='d'></p>"
optional: true
Ruby-style attributes separated with newlines:
haml: |-
%p{ :a => 'b',
'c' => 'd' }
html: "<p a='b' c='d'></p>"
optional: true
Ruby-style 'class' as an attribute:
haml: "%p{:class => 'class1'}"
html: "<p class='class1'></p>"
optional: true
Ruby-style tag with a CSS class and 'class' as an attribute:
haml: "%p.class2{:class => 'class1'}"
html: "<p class='class1 class2'></p>"
optional: true
Ruby-style tag with 'id' as an attribute:
haml: "%p{:id => '1'}"
html: "<p id='1'></p>"
optional: true
Ruby-style tag with a CSS id and 'id' as an attribute:
haml: "%p#id{:id => '1'}"
html: "<p id='id_1'></p>"
optional: true
Ruby-style tag with a CSS id and a numeric 'id' as an attribute:
haml: "%p#id{:id => 1}"
html: "<p id='id_1'></p>"
optional: true
Ruby-style tag with a variable attribute:
haml: "%p{:class => var}"
html: "<p class='hello'></p>"
optional: true
locals:
var: hello
Ruby-style tag with a CSS class and 'class' as a variable attribute:
haml: ".hello{:class => var}"
html: "<div class='hello world'></div>"
optional: true
locals:
var: world
Ruby-style tag multiple CSS classes (sorted correctly):
haml: ".z{:class => var}"
html: "<div class='a z'></div>"
optional: true
locals:
var: a
silent comments:
an inline silent comment:
haml: "-# hello"
html: ''
a nested silent comment:
haml: |-
-#
hello
html: ''
a multiply nested silent comment:
haml: |-
-#
%div
foo
html: ''
a multiply nested silent comment with inconsistent indents:
haml: |-
-#
%div
foo
html: ''
markup comments:
an inline markup comment:
haml: "/ comment"
html: "<!-- comment -->"
a nested markup comment:
haml: |-
/
comment
comment2
html: |-
<!--
comment
comment2
-->
conditional comments:
a conditional comment:
haml: |-
/[if IE]
%p a
html: |-
<!--[if IE]>
<p>a</p>
<![endif]-->
internal filters:
content in an 'escaped' filter:
haml: |-
:escaped
<&">
html: "&lt;&amp;&quot;&gt;"
content in a 'preserve' filter:
haml: |-
:preserve
hello
%p
html: |-
hello&#x000A;
<p></p>
content in a 'plain' filter:
haml: |-
:plain
hello
%p
html: |-
hello
<p></p>
content in a 'css' filter (XHTML):
haml: |-
:css
hello
%p
html: |-
<style type='text/css'>
/*<![CDATA[*/
hello
/*]]>*/
</style>
<p></p>
config:
format: xhtml
content in a 'javascript' filter (XHTML):
haml: |-
:javascript
a();
%p
html: |-
<script type='text/javascript'>
//<![CDATA[
a();
//]]>
</script>
<p></p>
config:
format: xhtml
content in a 'css' filter (HTML):
haml: |-
:css
hello
%p
html: |-
<style>
hello
</style>
<p></p>
config:
format: html5
content in a 'javascript' filter (HTML):
haml: |-
:javascript
a();
%p
html: |-
<script>
a();
</script>
<p></p>
config:
format: html5
Ruby-style interpolation:
interpolation inside inline content:
haml: "%p #{var}"
html: "<p>value</p>"
optional: true
locals:
var: value
no interpolation when escaped:
haml: "%p \\#{var}"
html: "<p>#{var}</p>"
optional: true
locals:
var: value
interpolation when the escape character is escaped:
haml: "%p \\\\#{var}"
html: "<p>\\value</p>"
optional: true
locals:
var: value
interpolation inside filtered content:
haml: |-
:plain
#{var} interpolated: #{var}
html: 'value interpolated: value'
optional: true
locals:
var: value
HTML escaping:
code following '&=':
haml: '&= ''<"&>'''
html: "&lt;&quot;&amp;&gt;"
code following '=' when escape_haml is set to true:
haml: = '<"&>'
html: "&lt;&quot;&amp;&gt;"
config:
escape_html: 'true'
code following '!=' when escape_haml is set to true:
haml: '!= ''<"&>'''
html: <"&>
config:
escape_html: 'true'
boolean attributes:
boolean attribute with XHTML:
haml: "%input(checked=true)"
html: "<input checked='checked' />"
config:
format: xhtml
boolean attribute with HTML:
haml: "%input(checked=true)"
html: "<input checked>"
config:
format: html5
whitespace preservation:
following the '~' operator:
haml: ~ "Foo\n<pre>Bar\nBaz</pre>"
html: |-
Foo
<pre>Bar&#x000A;Baz</pre>
optional: true
inside a textarea tag:
haml: |-
%textarea
hello
hello
html: |-
<textarea>hello
hello</textarea>
inside a pre tag:
haml: |-
%pre
hello
hello
html: |-
<pre>hello
hello</pre>
whitespace removal:
a tag with '>' appended and inline content:
haml: |-
%li hello
%li> world
%li again
html: "<li>hello</li><li>world</li><li>again</li>"
a tag with '>' appended and nested content:
haml: |-
%li hello
%li>
world
%li again
html: |-
<li>hello</li><li>
world
</li><li>again</li>
a tag with '<' appended:
haml: |-
%p<
hello
world
html: |-
<p>hello
world</p>