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

Merge branch 'master' into new-attrs

Conflicts:
	TODO
	test/haml/engine_test.rb
This commit is contained in:
Nathan Weizenbaum 2009-07-01 23:27:29 -07:00
commit 99f21fb8a2
26 changed files with 356 additions and 108 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
/doc
/pkg
/test/rails
/.sass-cache

View file

@ -1,4 +1,4 @@
Copyright (c) 2006-2008 Hampton Catlin
Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View file

@ -11,24 +11,34 @@ and providing elegant, easily understandable, and powerful syntax.
## Using
There are several ways to use Haml and Sass.
They can be used as a plugin for Rails or Merb,
or embedded on their own in other applications.
The first step of all of these is to install the Haml gem:
Haml and Sass can be used from the command line
or as part of a Ruby web framework.
The first step is to install the gem:
gem install haml
After you convert some HTML to Haml or some CSS to Sass,
you can run
haml document.haml
sass style.sass
to compile them.
For more information on these commands, check out
haml --help
sass --help
To install Haml and Sass as a Rails plugin,
just run `haml --rails path/to/rails/app`
and both Haml and Sass will be installed.
Views with the `.haml` (or `.html.haml` for edge)
extension will automatically use Haml.
Views with the `.html.haml` extension will automatically use Haml.
Sass is a little more complicated;
`.sass` files should be placed in public/stylesheets/sass,
`.sass` files should be placed in `public/stylesheets/sass`,
where they'll be automatically compiled
to corresponding CSS files in public/stylesheets when needed
to corresponding CSS files in `public/stylesheets` when needed
(the Sass template directory is customizable...
see the Sass module docs for details).
see [the Sass reference](http://sass-lang.com/docs/yardoc/SASS_REFERENCE.md.html#template_location-option) for details).
For Merb, `.html.haml` views will work without any further modification.
To enable Sass, you also need to add a dependency.
@ -36,11 +46,11 @@ To do so, just add
dependency "merb-haml"
to config/dependencies.rb (or config/init.rb in a flat/very flat Merb application).
to `config/dependencies.rb` (or `config/init.rb` in a flat/very flat Merb application).
Then it'll work just like it does in Rails.
To use Haml and Sass programatically,
check out the RDocs for the Haml and Sass modules.
check out the [YARD documentation](http://haml-lang.com/docs/yardoc).
## Formatting
@ -302,26 +312,27 @@ See `css2sass --help` for further information and options.
## Authors
Haml and Sass are designed by Hampton Catlin (hcatlin) and he is the author
of the original implementation. However, Hampton doesn't even know his way
around the code anymore and mostly just concentrates on the language issues.
Hampton lives in Toronto, Ontario (though he's an American by birth) and
is a partner at Unspace Interactive.
Haml and Sass were created by [Hampton Catlin](http://hamptoncatlin.com)
(hcatlin) and he is the author of the original implementation. However, Hampton
doesn't even know his way around the code anymore and now occasionally consults
on the language issues. Hampton lives in Jacksonville, Florida and is the lead
mobile developer for Wikimedia.
Nathan Weizenbaum is the primary maintainer and architect of the "modern" Ruby
implementation of Haml. His hard work has kept the project alive by endlessly
answering forum posts, fixing bugs, refactoring, finding speed improvements,
writing documentation, implementing new features, and getting Hampton
coffee (a fitting task for a boy-genius). Nathan lives in Seattle, Washington and
while not being a student at University of Washington he consults for
Unspace Interactive and Microsoft.
[Nathan Weizenbaum](http://nex-3.com) is the primary developer and architect of
the "modern" Ruby implementation of Haml. His hard work has kept the project
alive by endlessly answering forum posts, fixing bugs, refactoring, finding
speed improvements, writing documentation, implementing new features, and
getting Hampton coffee (a fitting task for a boy-genius). Nathan lives in
Seattle, Washington and while not being a student at the University of
Washington or working at an internship, he consults for Unspace Interactive.
Chris Eppstein is a core contributor to Sass and the creator of Compass, the first
Sass-based framework. Chris focuses on making Sass more powerful, easy to use, and
on ways to speed its adoption through the web development community. Chris lives in
San Jose, CA with his wife and daughter. He is the Software Architect for Caring.com,
a website devoted to the 34 Million caregivers whose parents are sick or elderly,
that uses Haml and Sass.
[Chris Eppstein](http://acts-as-architect.blogspot.com) is a core contributor to
Sass and the creator of Compass, the first Sass-based framework. Chris focuses
on making Sass more powerful, easy to use, and on ways to speed its adoption
through the web development community. Chris lives in San Jose, California with
his wife and daughter. He is the Software Architect for
[Caring.com](http://caring.com), a website devoted to the 34 Million caregivers
whose parents are sick or elderly, that uses Haml and Sass.
If you use this software, you must pay Hampton a compliment. And
buy Nathan some jelly beans. Maybe pet a kitten. Yeah. Pet that kitty.

View file

@ -71,8 +71,9 @@ end
desc "Release a new Haml package to Rubyforge. Requires the NAME and VERSION flags."
task :release => [:package] do
name, version = ENV['NAME'], ENV['VERSION']
raise "Must supply NAME and VERSION for release task." unless name && version
name = File.read("VERSION_NAME").strip
version = File.read("VERSION").strip
raise "VERSION_NAME must not be 'Bleeding Edge'" if name == "Bleeding Edge"
sh %{rubyforge login}
sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem}
sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz}
@ -81,6 +82,8 @@ task :release => [:package] do
end
task :release_edge do
puts "#{'=' * 50} Running rake release_edge"
sh %{git checkout edge-gem}
sh %{git reset --hard origin/edge-gem}
sh %{git merge origin/master}
@ -153,11 +156,12 @@ rescue LoadError
end
task :pages do
puts "#{'=' * 50} Running rake pages PROJ=#{ENV["PROJ"].inspect}"
raise 'No ENV["PROJ"]!' unless proj = ENV["PROJ"]
sh %{git checkout #{proj}-pages}
sh %{git reset --hard origin/#{proj}-pages}
sh %{staticmatic build .}
sh %{rake build --trace}
sh %{rsync -av --delete site/ /var/www/#{proj}-pages}
end
@ -246,15 +250,22 @@ end
# ----- Handling Updates -----
task :handle_update do
puts
puts
puts '=' * 150
puts "Running rake handle_update REF=#{ENV["REF"].inspect}"
sh %{git checkout master}
sh %{git fetch origin}
sh %{git reset --hard origin/master}
begin
if ENV["REF"] == "refs/heads/master"
sh %{rake release_edge}
sh %{rake release_edge --trace}
sh %{rake pages --trace PROJ=haml}
sh %{rake pages --trace PROJ=sass}
elsif ENV["REF"] =~ %r{^refs/heads/(haml|sass)-pages$}
sh %{rake pages PROJ=#{$1}}
sh %{rake pages --trace PROJ=#{$1}}
end
ensure
sh %{git reset --hard HEAD}

12
TODO
View file

@ -10,7 +10,19 @@
form_for needs -, not =
* Code
** Haml
Write HAML_CHANGELOG
[2.4] Allow "!!! HTML5" to set :format => :html5 ?
How do we deal with partials?
[2.4] :ugly + :html improvements
Ignore closing tags where we can
http://code.google.com/speed/articles/optimizing-html.html
Requires Haml parsing refactor
Don't quote attributes that don't require it
http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
http://www.w3.org/TR/html5/syntax.html#attributes
** Sass
Add tests for ae4f319 and 4a901ed
[2.4] CSS superset
[2.4] Classes are mixins
Can refer to specific property values? Syntax?

1
VERSION_NAME Normal file
View file

@ -0,0 +1 @@
Bleeding Edge

View file

@ -24,27 +24,29 @@ with some code to generate dynamic content.
## Using Haml
Haml can be used in three ways:
as a command-line tool,
as a plugin for Ruby on Rails,
as a standalone Ruby module,
and as a command-line tool.
and as a standalone Ruby module.
The first step for all of these is to install the Haml gem:
gem install haml
To enable it as a Rails plugin,
then run
haml --rails path/to/rails/app
Once it's installed, all view files with the `".html.haml"` extension
will be compiled using Haml.
To run Haml from the command line, just use
haml input.haml output.html
Use `haml --help` for full documentation.
### Rails/Merb Plugin {#plugin}
To enable Haml as a Rails plugin, run
haml --rails path/to/rails/app
Once it's installed, all view files with the `".html.haml"` extension
will be compiled using Haml.
Haml is enabled by default in Merb.
You can access instance variables in Haml templates
the same way you do in ERB templates.
Helper methods are also available in Haml templates.
@ -153,6 +155,15 @@ Available options are:
Defaults to `['textarea', 'pre']`.
See also [Whitespace Preservation](#whitespace_preservation).
{#encoding-option} `:encoding`
: The encoding to use for the HTML output.
Only available in Ruby 1.9 or higher.
This can be a string or an `Encoding` Object.
Note that Haml **does not** automatically re-encode Ruby values;
any strings coming from outside the application should be converted
before being passed into the Haml template.
Defaults to `Encoding.default_internal` or, if that's not set, `"utf-8"`.
## Plain Text
A substantial portion of any HTML document is its content,
@ -232,7 +243,7 @@ is compiled to:
Any string is a valid element name;
Haml will automatically generate opening and closing tags for any element.
### Attributes: `{}`
### Attributes: `{}` {#attributes}
Brackets represent a Ruby hash
that is used for specifying the attributes of an element.
@ -1011,14 +1022,16 @@ The pipe character designates a multiline string.
It's placed at the end of a line (after some whitespace)
and means that all following lines that end with `|`
will be evaluated as though they were on the same line.
**Note that even the last line in the multiline block
should end wit `|`.**
For example:
%whoo
%hoo I think this might get |
pretty long so I should |
probably make it |
multiline so it doesn't |
look awful. |
pretty long so I should |
probably make it |
multiline so it doesn't |
look awful. |
%p This is short.
is compiled to:
@ -1030,6 +1043,17 @@ is compiled to:
<p>This is short</p>
</whoo>
Using multiline declarations in Haml is intentionally awkward.
This is designed to discourage people from putting lots and lots of Ruby code
in their Haml templates.
If you find yourself using multiline declarations, stop and think:
could I do this better with a helper?
Note that there is one case where it's useful to allow
something to flow over onto multiple lines in a non-awkward manner: attributes.
Some elements just have lots of attributes,
so you can wrap attributes without using `|` (see [Attributes](#attributes)).
## Whitespace Preservation
Sometimes you don't want Haml to indent all your text.

View file

@ -114,7 +114,7 @@ Available options are:
or `:width = !main_width`.
By default, either syntax is valid.
{#cache-option} `cache`
{#cache-option} `:cache`
: Whether parsed Sass files should be cached,
allowing greater speed. Defaults to true.
@ -150,7 +150,7 @@ Available options are:
Defaults to false in production mode, true otherwise.
Only has meaning within Ruby on Rails or Merb.
{#template-location-option} `:template_location`
{#template_location-option} `:template_location`
: A path to the root sass template directory for you application.
If a hash, `:css_location` is ignored and this option designates
both a mapping between input and output directories.
@ -161,7 +161,7 @@ Available options are:
This will be derived from the `:css_location` path list if not provided
by appending a folder of "sass" to each corresponding css location.
{#css-location-option} `:css_location`
{#css_location-option} `:css_location`
: The path where CSS output should be written to.
This option is ignored when `:template_location` is a Hash.
Defaults to `RAILS_ROOT + "/public/stylesheets"`
@ -1032,7 +1032,7 @@ Although the default CSS style that Sass outputs is very nice,
and reflects the structure of the document in a similar way that Sass does,
sometimes it's good to have other formats available.
Sass allows you to choose between three different output styles
Sass allows you to choose between four different output styles
by setting the `:style` option.
In Rails, this is done by setting `Sass::Plugin.options[:style]`;
outside Rails, it's done by passing an options hash with `:style` set.

View file

@ -6,5 +6,5 @@ set :environment, :production
Dir.chdir(File.dirname(__FILE__) + "/..")
post "/" do
system %{rake handle_update REF=#{JSON.parse(params["payload"])["ref"].inspect}}
system %{rake handle_update --trace REF=#{JSON.parse(params["payload"])["ref"].inspect}}
end

View file

@ -90,12 +90,8 @@ module Haml
def initialize(upper = nil, options = {})
@active = true
@upper = upper
@options = {
:attr_wrapper => "'",
:ugly => false,
:format => :xhtml
}.merge options
@buffer = ""
@options = options
@buffer = ruby1_8? ? "" : "".encode(Encoding.find(options[:encoding]))
@tabulation = 0
# The number of tabs that Engine thinks we should have

View file

@ -23,11 +23,6 @@ module Haml
# @return [Hash<Symbol, Object>]
attr_accessor :options
# The source code that is evaluated to produce the Haml document.
#
# @return [String]
attr_accessor :precompiled
# The indentation used in the Haml document,
# or `nil` if the indentation is ambiguous
# (for example, for a single-level document).
@ -55,6 +50,17 @@ module Haml
@options[:format] == :html5
end
# The source code that is evaluated to produce the Haml document.
#
# In Ruby 1.9, this is automatically converted to the correct encoding
# (see {file:HAML_REFERENCE.md#encoding-option the `:encoding` option}).
#
# @return [String]
def precompiled
return @precompiled if ruby1_8?
return @precompiled.encode(Encoding.find(@options[:encoding]))
end
# Precompiles the Haml template.
#
# @param template [String] The Haml template
@ -74,8 +80,11 @@ module Haml
:line => 1,
:ugly => false,
:format => :xhtml,
:escape_html => false
:escape_html => false,
}
unless ruby1_8?
@options[:encoding] = Encoding.default_internal || "utf-8"
end
@options.merge! options
@index = 0
@ -83,6 +92,10 @@ module Haml
raise Haml::Error, "Invalid format #{@options[:format].inspect}"
end
if @options[:encoding] && @options[:encoding].is_a?(Encoding)
@options[:encoding] = @options[:encoding].name
end
# :eod is a special end-of-document marker
@template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
@template_index = 0
@ -169,7 +182,7 @@ END
@haml_buffer = buffer
end
eval(@precompiled, scope, @options[:filename], @options[:line])
eval(precompiled, scope, @options[:filename], @options[:line])
# Get rid of the current buffer
scope_object.instance_eval do
@ -276,7 +289,8 @@ END
:preserve => @options[:preserve],
:attr_wrapper => @options[:attr_wrapper],
:ugly => @options[:ugly],
:format => @options[:format]
:format => @options[:format],
:encoding => @options[:encoding],
}
end

View file

@ -87,10 +87,10 @@ module Haml
def process_result
input, output = @options[:input], @options[:output]
input_file, output_file = if input
[nil, open_file(ARGV[0], 'w')]
[nil, open_file(@args[0], 'w')]
else
@options[:filename] = ARGV[0]
[open_file(ARGV[0]), open_file(ARGV[1], 'w')]
@options[:filename] = @args[0]
[open_file(@args[0]), open_file(@args[1], 'w')]
end
input ||= input_file

View file

@ -101,7 +101,7 @@ END
@haml_buffer = @haml_buffer.upper
_erbout
END
preamble + locals_code(local_names) + @precompiled + postamble
preamble + locals_code(local_names) + precompiled + postamble
end
def locals_code(names)

View file

@ -15,7 +15,7 @@ module Haml
# @param file [String] The filename relative to the Haml root
# @return [String] The filename relative to the the working directory
def scope(file)
File.expand_path File.join(File.dirname(__FILE__), '..', '..', file)
File.join(File.dirname(__FILE__), '..', '..', file)
end
# Converts an array of `[key, value]` pairs to a hash.

View file

@ -10,27 +10,33 @@ module Haml
# Returns a hash representing the version of Haml.
# The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Fixnums.
# The `:name` key has the name of the version.
# The `:string` key contains a human-readable string representation of the version.
# The `:number` key is the major, minor, and teeny keys separated by periods.
# If Haml is checked out from Git, the `:rev` key will have the revision hash.
# For example:
#
# {
# :string=>"2.1.0.9616393",
# :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
# :major => 2, :minor => 1, :teeny => 0
# :string => "2.1.0.9616393",
# :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
# :number => "2.1.0",
# :major => 2, :minor => 1, :teeny => 0
# }
#
# @return [Hash<Symbol, String/Symbol>] The version hash
# @return [Hash<Symbol, String/Fixnum>] The version hash
def version
return @@version if defined?(@@version)
numbers = File.read(scope('VERSION')).strip.split('.').map { |n| n.to_i }
name = File.read(scope('VERSION_NAME')).strip
@@version = {
:major => numbers[0],
:minor => numbers[1],
:teeny => numbers[2]
:teeny => numbers[2],
:name => name
}
@@version[:string] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
@@version[:number] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
@@version[:string] = @@version[:number].dup
if File.exists?(scope('REVISION'))
rev = File.read(scope('REVISION')).strip
@ -47,9 +53,9 @@ module Haml
if rev
@@version[:rev] = rev
unless rev[0] == ?(
@@version[:string] << "."
@@version[:string] << rev[0...7]
@@version[:string] << "." << rev[0...7]
end
@@version[:string] << " (#{name})"
end
@@version

View file

@ -118,7 +118,19 @@ module Sass
#
# @return [Tree::Node] The parsed rule
def rule
return unless rule = @template.scan(/[^\{\};]+/)
rule = ""
loop do
token = @template.scan(/(?:[^\{\};\/\s]|\/[^*])+/)
if token.nil?
return if rule.empty?
break
end
rule << token
break unless @template.match?(/\s|\/\*/)
whitespace
rule << " "
end
rule.strip!
directive = rule[0] == ?@

View file

@ -170,7 +170,10 @@ module Sass
lines = []
string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^.*?$/).each_with_index do |line, index|
index += (@options[:line] || 1)
next if line.strip.empty?
if line.strip.empty?
lines.last.text << "\n" if lines.last && lines.last.comment?
next
end
line_tab_str = line[/^\s*/]
unless line_tab_str.empty?
@ -310,7 +313,7 @@ END
when MIXIN_DEFINITION_CHAR
parse_mixin_definition(line)
when MIXIN_INCLUDE_CHAR
if line.text[1].nil?
if line.text[1].nil? || line.text[1] == ?\s
Tree::RuleNode.new(line.text)
else
parse_mixin_include(line, root)

View file

@ -61,6 +61,21 @@ module Sass::Script
instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
# Creates a {Color} object from red, green, and blue values.
# @param red
# A number between 0 and 255 inclusive
# @param green
# A number between 0 and 255 inclusive
# @param blue
# A number between 0 and 255 inclusive
def rgb(red, green, blue)
[red.value, green.value, blue.value].each do |v|
raise ArgumentError.new("rgb color value of #{v} encountered. Must be between 0 and 255 inclusive.") if v <= 0 || v >= 255
end
Color.new([red.value, green.value, blue.value])
end
# Creates a {Color} object from hue, saturation, and lightness
# as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
#

View file

@ -170,5 +170,8 @@ module Sass::Script
def to_i
raise Sass::SyntaxError.new("#{self.inspect} is not an integer.")
end
# @raise [Sass::SyntaxError] if this literal isn't an integer
def assert_int!; to_i; end
end
end

View file

@ -155,9 +155,20 @@ module Sass::Script
# @param other [Literal] The right-hand side of the operator
# @return [Boolean] Whether this number is equal to the other object
def eq(other)
Sass::Script::Bool.new(super.to_bool &&
self.numerator_units.sort == other.numerator_units.sort &&
self.denominator_units.sort == other.denominator_units.sort)
return Sass::Script::Bool.new(false) unless other.is_a?(Sass::Script::Number)
this = self
begin
if unitless?
this = this.coerce(other.numerator_units, other.denominator_units)
else
other = other.coerce(numerator_units, denominator_units)
end
rescue Sass::SyntaxError => e
raise e unless e.message =~ /^Incompatible units: /
return Sass::Script::Bool.new(false)
end
Sass::Script::Bool.new(this.value == other.value)
end
# The SassScript `>` operation.
@ -249,11 +260,36 @@ module Sass::Script
(numerator_units.empty? || numerator_units.size == 1) && denominator_units.empty?
end
# Returns this number converted to other units.
# The conversion takes into account the relationship between e.g. mm and cm,
# as well as between e.g. in and cm.
#
# If this number has no units, it will simply return itself
# with the given units.
#
# An incompatible coercion, e.g. between px and cm, will raise an error.
#
# @param num_units [Array<String>] The numerator units to coerce this number into.
# See {#numerator\_units}
# @param den_units [Array<String>] The denominator units to coerce this number into.
# See {#denominator\_units}
# @return [Number] The number with the new units
# @raise [Sass::SyntaxError] if the given units are incompatible with the number's
# current units
def coerce(num_units, den_units)
Number.new(if unitless?
self.value
else
self.value * coercion_factor(self.numerator_units, num_units) /
coercion_factor(self.denominator_units, den_units)
end, num_units, den_units)
end
protected
def operate(other, operation)
this = self
if [:+, :-].include?(operation)
if [:+, :-, :<=, :<, :>, :>=].include?(operation)
if unitless?
this = this.coerce(other.numerator_units, other.denominator_units)
else
@ -271,15 +307,6 @@ module Sass::Script
end
end
def coerce(num_units, den_units)
Number.new(if unitless?
self.value
else
self.value * coercion_factor(self.numerator_units, num_units) /
coercion_factor(self.denominator_units, den_units)
end, num_units, den_units)
end
def coercion_factor(from_units, to_units)
# get a list of unmatched units
from_units, to_units = sans_common_units(from_units, to_units)

View file

@ -50,9 +50,13 @@ module Sass::Tree
def to_s(tabs = 0, _ = nil)
return if invisible?
content = (value.split("\n") + lines.map {|l| l.text})
content.map! {|l| (l.empty? ? "" : " ") + l}
content.first.gsub!(/^ /, '')
content.last.gsub!(%r{ ?\*/ *$}, '')
spaces = ' ' * (tabs - 1)
spaces + "/* " + (value.split("\n") + lines.map {|l| l.text}).
map{|l| l.sub(%r{ ?\*/ *$},'')}.join(style == :compact ? ' ' : "\n#{spaces} * ") + " */"
spaces + "/* " + content.join(style == :compact ? '' : "\n#{spaces} *") + " */"
end
# Returns `true` if this is a silent comment

View file

@ -28,14 +28,18 @@ module Sass::Tree
# @return [Array<Tree::Node>] The resulting static nodes
# @see Sass::Tree
def _perform(environment)
from = @from.perform(environment).to_i
to = @to.perform(environment).to_i
range = Range.new(from, to, @exclusive)
from = @from.perform(environment)
to = @to.perform(environment)
from.assert_int!
to.assert_int!
to = to.coerce(from.numerator_units, from.denominator_units)
range = Range.new(from.to_i, to.to_i, @exclusive)
children = []
environment = Sass::Environment.new(environment)
range.each do |i|
environment.set_local_var(@var, Sass::Script::Number.new(i))
environment.set_local_var(@var, Sass::Script::Number.new(i, from.numerator_units, from.denominator_units))
children += perform_children(environment)
end
children

View file

@ -130,7 +130,9 @@ module Sass
result << child_str + (style == :compressed ? '' : "\n")
end
end
style == :compressed ? result+"\n" : result[0...-1]
result.rstrip!
return "" if result.empty?
return result + "\n"
rescue Sass::SyntaxError => e; e.add_metadata(filename, line)
end

View file

@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require File.dirname(__FILE__) + '/../test_helper'
class EngineTest < Test::Unit::TestCase
@ -908,4 +909,55 @@ END
assert_equal("<a a='b' b='c' c='d' d='e'>bar</a>\n",
render("%a{:a => 'b',\n:b => 'c'}(c='d'\nd='e') bar"))
end
# Encodings
unless Haml::Util.ruby1_8?
def test_default_encoding
assert_equal(Encoding.find("utf-8"), render(<<HAML.encode("us-ascii")).encoding)
HTML
%p bar
%p foo
HAML
end
def test_convert_template_render
assert_equal(<<HTML, render(<<HAML.encode("iso-8859-1"), :encoding => "utf-8"))
<p>bâr</p>
<p>föö</p>
HTML
%p bâr
%p föö
HAML
end
def test_convert_template_render_proc
assert_converts_template_properly {|e| e.render_proc.call}
end
def test_convert_template_render
assert_converts_template_properly {|e| e.render}
end
def test_convert_template_def_method
assert_converts_template_properly do |e|
o = Object.new
e.def_method(o, :render)
o.render
end
end
end
private
def assert_converts_template_properly
engine = Haml::Engine.new(<<HAML.encode("iso-8859-1"), :encoding => "utf-8")
%p bâr
%p föö
HAML
assert_equal(<<HTML, yield(engine))
<p>bâr</p>
<p>föö</p>
HTML
end
end

View file

@ -207,6 +207,29 @@ down_here { yeah: true; }
CSS
end
def test_comments_in_selectors
assert_equal(<<SASS, css2sass(<<CSS))
.js
#location-navigation-form .form-submit, #business-listing-form .form-submit, #detailTabs ul, #detailsEnhanced #addTags, #locationSearchList, #moreHoods
display: none
#navListLeft
display: none
SASS
.js #location-navigation-form .form-submit,
.js #business-listing-form .form-submit,
.js #detailTabs ul,
/* .js #addReview, */
/* .js #addTags, */
.js #detailsEnhanced #addTags,
.js #locationSearchList,
.js #moreHoods,
#navListLeft
{ display: none; }
CSS
end
private
def css2sass(string, opts={})

View file

@ -76,8 +76,11 @@ class SassEngineTest < Test::Unit::TestCase
"@if false\n@else if " => "Invalid else directive '@else if': expected 'if <expr>'.",
"a\n !b = 12\nc\n d = !b" => 'Undefined variable: "!b".',
"=foo\n !b = 12\nc\n +foo\n d = !b" => 'Undefined variable: "!b".',
'@for !a from "foo" to 1' => '"foo" is not an integer.',
'@for !a from 1 to "2"' => '"2" is not an integer.',
'@for !a from 1 to "foo"' => '"foo" is not an integer.',
'@for !a from 1 to 1.232323' => '1.232 is not an integer.',
'@for !a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
'@if' => "Invalid if directive '@if': expected expression.",
'@while' => "Invalid while directive '@while': expected expression.",
'@debug' => "Invalid debug directive '@debug': expected expression.",
@ -186,8 +189,8 @@ SASS
end
def test_css_import
assert_equal("@import url(./fonts.css) screen;", render("@import url(./fonts.css) screen"))
assert_equal("@import \"./fonts.css\" screen;", render("@import \"./fonts.css\" screen"))
assert_equal("@import url(./fonts.css) screen;\n", render("@import url(./fonts.css) screen"))
assert_equal("@import \"./fonts.css\" screen;\n", render("@import \"./fonts.css\" screen"))
end
def test_sass_import
@ -273,7 +276,7 @@ SASS
end
def test_directive
assert_equal("@a b;", render("@a b"))
assert_equal("@a b;\n", render("@a b"))
assert_equal("@a {\n b: c; }\n", render("@a\n :b c"))
assert_equal("@a { b: c; }\n", render("@a\n :b c", :style => :compact))
@ -759,6 +762,30 @@ CSS
SASS
end
def test_plus_with_space
assert_equal(<<CSS, render(<<SASS))
a + b {
color: green; }
CSS
a
+ b
color: green
SASS
end
def test_empty_line_comment
assert_equal(<<CSS, render(<<SASS))
/* Foo
*
* Bar */
CSS
/*
Foo
Bar
SASS
end
private
def render(sass, options = {})