mack-haml 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/gems.rb +13 -0
- data/lib/gems/haml-2.0.4/VERSION +1 -0
- data/lib/gems/haml-2.0.4/bin/css2sass +7 -0
- data/lib/gems/haml-2.0.4/bin/haml +9 -0
- data/lib/gems/haml-2.0.4/bin/html2haml +7 -0
- data/lib/gems/haml-2.0.4/bin/sass +8 -0
- data/lib/gems/haml-2.0.4/lib/haml.rb +1040 -0
- data/lib/gems/haml-2.0.4/lib/haml/buffer.rb +239 -0
- data/lib/gems/haml-2.0.4/lib/haml/engine.rb +265 -0
- data/lib/gems/haml-2.0.4/lib/haml/error.rb +22 -0
- data/lib/gems/haml-2.0.4/lib/haml/exec.rb +364 -0
- data/lib/gems/haml-2.0.4/lib/haml/filters.rb +275 -0
- data/lib/gems/haml-2.0.4/lib/haml/helpers.rb +453 -0
- data/lib/gems/haml-2.0.4/lib/haml/helpers/action_view_extensions.rb +45 -0
- data/lib/gems/haml-2.0.4/lib/haml/helpers/action_view_mods.rb +179 -0
- data/lib/gems/haml-2.0.4/lib/haml/html.rb +227 -0
- data/lib/gems/haml-2.0.4/lib/haml/precompiler.rb +805 -0
- data/lib/gems/haml-2.0.4/lib/haml/template.rb +51 -0
- data/lib/gems/haml-2.0.4/lib/haml/template/patch.rb +58 -0
- data/lib/gems/haml-2.0.4/lib/haml/template/plugin.rb +72 -0
- data/lib/gems/haml-2.0.4/lib/sass.rb +863 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant.rb +214 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/color.rb +101 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/literal.rb +54 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/nil.rb +9 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/number.rb +87 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/operation.rb +30 -0
- data/lib/gems/haml-2.0.4/lib/sass/constant/string.rb +22 -0
- data/lib/gems/haml-2.0.4/lib/sass/css.rb +394 -0
- data/lib/gems/haml-2.0.4/lib/sass/engine.rb +466 -0
- data/lib/gems/haml-2.0.4/lib/sass/error.rb +35 -0
- data/lib/gems/haml-2.0.4/lib/sass/plugin.rb +169 -0
- data/lib/gems/haml-2.0.4/lib/sass/plugin/merb.rb +56 -0
- data/lib/gems/haml-2.0.4/lib/sass/plugin/rails.rb +24 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/attr_node.rb +53 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/comment_node.rb +20 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/directive_node.rb +46 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/node.rb +42 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/rule_node.rb +89 -0
- data/lib/gems/haml-2.0.4/lib/sass/tree/value_node.rb +16 -0
- data/lib/gems/haml-2.0.4/rails/init.rb +1 -0
- data/lib/mack-haml.rb +1 -0
- metadata +65 -16
@@ -0,0 +1,35 @@
|
|
1
|
+
module Sass
|
2
|
+
# Sass::SyntaxError encapsulates information about the exception,
|
3
|
+
# such as the line of the Sass template it was raised on
|
4
|
+
# and the Sass file that was being parsed (if applicable).
|
5
|
+
# It also provides a handy way to rescue only exceptions raised
|
6
|
+
# because of a faulty template.
|
7
|
+
class SyntaxError < StandardError
|
8
|
+
# The line of the Sass template on which the exception was thrown.
|
9
|
+
attr_accessor :sass_line
|
10
|
+
|
11
|
+
# The name of the file that was being parsed when the exception was raised.
|
12
|
+
# This will be nil unless Sass is being used as an ActionView plugin.
|
13
|
+
attr_reader :sass_filename
|
14
|
+
|
15
|
+
# Creates a new SyntaxError.
|
16
|
+
# +lineno+ should be the line of the Sass template on which the error occurred.
|
17
|
+
def initialize(msg, lineno = nil)
|
18
|
+
@message = msg
|
19
|
+
@sass_line = lineno
|
20
|
+
end
|
21
|
+
|
22
|
+
# Adds a properly formatted entry to the exception's backtrace.
|
23
|
+
# +filename+ should be the file in which the error occurred,
|
24
|
+
# if applicable (defaults to "(sass)").
|
25
|
+
def add_backtrace_entry(filename) # :nodoc:
|
26
|
+
@sass_filename ||= filename
|
27
|
+
self.backtrace ||= []
|
28
|
+
self.backtrace.unshift "#{@sass_filename || '(sass)'}:#{@sass_line}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s # :nodoc:
|
32
|
+
@message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'sass/engine'
|
2
|
+
|
3
|
+
module Sass
|
4
|
+
# This module contains methods to aid in using Sass
|
5
|
+
# as a stylesheet-rendering plugin for various systems.
|
6
|
+
# Currently Rails/ActionController and Merb are supported out of the box.
|
7
|
+
module Plugin
|
8
|
+
class << self
|
9
|
+
@@options = {
|
10
|
+
:template_location => './public/stylesheets/sass',
|
11
|
+
:css_location => './public/stylesheets',
|
12
|
+
:always_update => false,
|
13
|
+
:always_check => true,
|
14
|
+
:full_exception => true
|
15
|
+
}
|
16
|
+
@@checked_for_updates = false
|
17
|
+
|
18
|
+
# Whether or not Sass has *ever* checked if the stylesheets need updates
|
19
|
+
# (in this Ruby instance).
|
20
|
+
def checked_for_updates
|
21
|
+
@@checked_for_updates
|
22
|
+
end
|
23
|
+
|
24
|
+
# Gets various options for Sass. See README.rdoc for details.
|
25
|
+
#--
|
26
|
+
# TODO: *DOCUMENT OPTIONS*
|
27
|
+
#++
|
28
|
+
def options
|
29
|
+
@@options
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets various options for Sass.
|
33
|
+
def options=(value)
|
34
|
+
@@options.merge!(value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the options ready to be passed to the Sass::Engine
|
38
|
+
def engine_options(additional_options = {})
|
39
|
+
opts = options.dup.merge(additional_options)
|
40
|
+
opts[:load_paths] = load_paths(opts)
|
41
|
+
opts
|
42
|
+
end
|
43
|
+
|
44
|
+
# Checks each stylesheet in <tt>options[:css_location]</tt>
|
45
|
+
# to see if it needs updating,
|
46
|
+
# and updates it using the corresponding template
|
47
|
+
# from <tt>options[:templates]</tt>
|
48
|
+
# if it does.
|
49
|
+
def update_stylesheets
|
50
|
+
return if options[:never_update]
|
51
|
+
|
52
|
+
@@checked_for_updates = true
|
53
|
+
Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file|
|
54
|
+
|
55
|
+
# Get the relative path to the file with no extension
|
56
|
+
name = file.sub(options[:template_location] + "/", "")[0...-5]
|
57
|
+
|
58
|
+
if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name))
|
59
|
+
css = css_filename(name)
|
60
|
+
File.delete(css) if File.exists?(css)
|
61
|
+
|
62
|
+
filename = template_filename(name)
|
63
|
+
engine = Engine.new(File.read(filename), engine_options(:filename => filename))
|
64
|
+
result = begin
|
65
|
+
engine.render
|
66
|
+
rescue Exception => e
|
67
|
+
exception_string(e)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create any directories that might be necessary
|
71
|
+
dirs = [options[:css_location]]
|
72
|
+
name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" }
|
73
|
+
dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
|
74
|
+
|
75
|
+
# Finally, write the file
|
76
|
+
File.open(css, 'w') do |file|
|
77
|
+
file.print(result)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def load_paths(opts = options)
|
86
|
+
(opts[:load_paths] || []) + [options[:template_location]]
|
87
|
+
end
|
88
|
+
|
89
|
+
def exception_string(e)
|
90
|
+
if options[:full_exception]
|
91
|
+
e_string = "#{e.class}: #{e.message}"
|
92
|
+
|
93
|
+
if e.is_a? Sass::SyntaxError
|
94
|
+
e_string << "\non line #{e.sass_line}"
|
95
|
+
|
96
|
+
if e.sass_filename
|
97
|
+
e_string << " of #{e.sass_filename}"
|
98
|
+
|
99
|
+
if File.exists?(e.sass_filename)
|
100
|
+
e_string << "\n\n"
|
101
|
+
|
102
|
+
min = [e.sass_line - 5, 0].max
|
103
|
+
File.read(e.sass_filename).rstrip.split("\n")[
|
104
|
+
min .. e.sass_line + 5
|
105
|
+
].each_with_index do |line, i|
|
106
|
+
e_string << "#{min + i + 1}: #{line}\n"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
<<END
|
112
|
+
/*
|
113
|
+
#{e_string}
|
114
|
+
|
115
|
+
Backtrace:\n#{e.backtrace.join("\n")}
|
116
|
+
*/
|
117
|
+
body:before {
|
118
|
+
white-space: pre;
|
119
|
+
font-family: monospace;
|
120
|
+
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
121
|
+
END
|
122
|
+
# Fix an emacs syntax-highlighting hiccup: '
|
123
|
+
else
|
124
|
+
"/* Internal stylesheet error */"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def template_filename(name)
|
129
|
+
"#{options[:template_location]}/#{name}.sass"
|
130
|
+
end
|
131
|
+
|
132
|
+
def css_filename(name)
|
133
|
+
"#{options[:css_location]}/#{name}.css"
|
134
|
+
end
|
135
|
+
|
136
|
+
def forbid_update?(name)
|
137
|
+
name.sub(/^.*\//, '')[0] == ?_
|
138
|
+
end
|
139
|
+
|
140
|
+
def stylesheet_needs_update?(name)
|
141
|
+
if !File.exists?(css_filename(name))
|
142
|
+
return true
|
143
|
+
else
|
144
|
+
css_mtime = File.mtime(css_filename(name))
|
145
|
+
File.mtime(template_filename(name)) > css_mtime ||
|
146
|
+
dependencies(template_filename(name)).any?(&dependency_updated?(css_mtime))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def dependency_updated?(css_mtime)
|
151
|
+
lambda do |dep|
|
152
|
+
File.mtime(dep) > css_mtime ||
|
153
|
+
dependencies(dep).any?(&dependency_updated?(css_mtime))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def dependencies(filename)
|
158
|
+
File.readlines(filename).grep(/^@import /).map do |line|
|
159
|
+
line[8..-1].split(',').map do |inc|
|
160
|
+
Sass::Engine.find_file_to_import(inc.strip, load_paths)
|
161
|
+
end
|
162
|
+
end.flatten.grep(/\.sass$/)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
require 'sass/plugin/rails' if defined?(ActionController)
|
169
|
+
require 'sass/plugin/merb' if defined?(Merb::Plugins)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
unless defined?(Sass::MERB_LOADED)
|
2
|
+
Sass::MERB_LOADED = true
|
3
|
+
|
4
|
+
version = Merb::VERSION.split('.').map { |n| n.to_i }
|
5
|
+
if version[0] <= 0 && version[1] < 5
|
6
|
+
root = MERB_ROOT
|
7
|
+
env = MERB_ENV
|
8
|
+
else
|
9
|
+
root = Merb.root.to_s
|
10
|
+
env = Merb.environment
|
11
|
+
end
|
12
|
+
|
13
|
+
Sass::Plugin.options.merge!(:template_location => root + '/public/stylesheets/sass',
|
14
|
+
:css_location => root + '/public/stylesheets',
|
15
|
+
:always_check => env != "production",
|
16
|
+
:full_exception => env != "production")
|
17
|
+
config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
|
18
|
+
|
19
|
+
if defined? config.symbolize_keys!
|
20
|
+
config.symbolize_keys!
|
21
|
+
end
|
22
|
+
|
23
|
+
Sass::Plugin.options.merge!(config)
|
24
|
+
|
25
|
+
if version[0] > 0 || version[1] >= 9
|
26
|
+
|
27
|
+
class Merb::Rack::Application # :nodoc:
|
28
|
+
def call_with_sass(env)
|
29
|
+
if !Sass::Plugin.checked_for_updates ||
|
30
|
+
Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
|
31
|
+
Sass::Plugin.update_stylesheets
|
32
|
+
end
|
33
|
+
|
34
|
+
call_without_sass(env)
|
35
|
+
end
|
36
|
+
alias_method :call_without_sass, :call
|
37
|
+
alias_method :call, :call_with_sass
|
38
|
+
end
|
39
|
+
|
40
|
+
else
|
41
|
+
|
42
|
+
class MerbHandler # :nodoc:
|
43
|
+
def process_with_sass(request, response)
|
44
|
+
if !Sass::Plugin.checked_for_updates ||
|
45
|
+
Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
|
46
|
+
Sass::Plugin.update_stylesheets
|
47
|
+
end
|
48
|
+
|
49
|
+
process_without_sass(request, response)
|
50
|
+
end
|
51
|
+
alias_method :process_without_sass, :process
|
52
|
+
alias_method :process, :process_with_sass
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
unless defined?(Sass::RAILS_LOADED)
|
2
|
+
Sass::RAILS_LOADED = true
|
3
|
+
|
4
|
+
Sass::Plugin.options.merge!(:template_location => RAILS_ROOT + '/public/stylesheets/sass',
|
5
|
+
:css_location => RAILS_ROOT + '/public/stylesheets',
|
6
|
+
:always_check => RAILS_ENV != "production",
|
7
|
+
:full_exception => RAILS_ENV != "production")
|
8
|
+
|
9
|
+
# :stopdoc:
|
10
|
+
module ActionController
|
11
|
+
class Base
|
12
|
+
alias_method :sass_old_process, :process
|
13
|
+
def process(*args)
|
14
|
+
if !Sass::Plugin.checked_for_updates ||
|
15
|
+
Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
|
16
|
+
Sass::Plugin.update_stylesheets
|
17
|
+
end
|
18
|
+
|
19
|
+
sass_old_process(*args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# :startdoc:
|
24
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'sass/tree/node'
|
2
|
+
|
3
|
+
module Sass::Tree
|
4
|
+
class AttrNode < ValueNode
|
5
|
+
attr_accessor :name
|
6
|
+
|
7
|
+
def initialize(name, value, style)
|
8
|
+
@name = name
|
9
|
+
super(value, style)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s(tabs, parent_name = nil)
|
13
|
+
if value[-1] == ?;
|
14
|
+
raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump} (This isn't CSS!).", @line)
|
15
|
+
end
|
16
|
+
real_name = name
|
17
|
+
real_name = "#{parent_name}-#{real_name}" if parent_name
|
18
|
+
|
19
|
+
if value.empty? && children.empty?
|
20
|
+
raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump}.", @line)
|
21
|
+
end
|
22
|
+
|
23
|
+
join_string = case @style
|
24
|
+
when :compact; ' '
|
25
|
+
when :compressed; ''
|
26
|
+
else "\n"
|
27
|
+
end
|
28
|
+
spaces = ' ' * (tabs - 1)
|
29
|
+
to_return = ''
|
30
|
+
if !value.empty?
|
31
|
+
to_return << "#{spaces}#{real_name}:#{@style == :compressed ? '' : ' '}#{value};#{join_string}"
|
32
|
+
end
|
33
|
+
|
34
|
+
children.each do |kid|
|
35
|
+
to_return << "#{kid.to_s(tabs, real_name)}" << join_string
|
36
|
+
end
|
37
|
+
|
38
|
+
(@style == :compressed && parent_name) ? to_return : to_return[0...-1]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def declaration
|
44
|
+
":#{name} #{value}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def invalid_child?(child)
|
48
|
+
if !child.is_a?(AttrNode) && !child.is_a?(CommentNode)
|
49
|
+
"Illegal nesting: Only attributes may be nested beneath attributes."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sass/tree/node'
|
2
|
+
|
3
|
+
module Sass::Tree
|
4
|
+
class CommentNode < ValueNode
|
5
|
+
def initialize(value, style)
|
6
|
+
super(value[2..-1].strip, style)
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s(tabs = 0, parent_name = nil)
|
10
|
+
return if @style == :compressed
|
11
|
+
|
12
|
+
spaces = ' ' * (tabs - 1)
|
13
|
+
join_string = @style == :compact ? ' ' : "\n#{spaces} * "
|
14
|
+
str = "#{spaces}/* #{value}"
|
15
|
+
str << join_string unless children.empty?
|
16
|
+
str << "#{children.join join_string} */"
|
17
|
+
str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'sass/tree/node'
|
2
|
+
require 'sass/tree/value_node'
|
3
|
+
|
4
|
+
module Sass::Tree
|
5
|
+
class DirectiveNode < ValueNode
|
6
|
+
def to_s(tabs)
|
7
|
+
if children.empty?
|
8
|
+
value + ";"
|
9
|
+
else
|
10
|
+
result = if @style == :compressed
|
11
|
+
"#{value}{"
|
12
|
+
else
|
13
|
+
"#{' ' * (tabs - 1)}#{value} {" + (@style == :compact ? ' ' : "\n")
|
14
|
+
end
|
15
|
+
was_attr = false
|
16
|
+
first = true
|
17
|
+
children.each do |child|
|
18
|
+
if @style == :compact
|
19
|
+
if child.is_a?(AttrNode)
|
20
|
+
result << "#{child.to_s(first || was_attr ? 1 : tabs + 1)} "
|
21
|
+
else
|
22
|
+
if was_attr
|
23
|
+
result[-1] = "\n"
|
24
|
+
end
|
25
|
+
rendered = child.to_s(tabs + 1)
|
26
|
+
rendered.lstrip! if first
|
27
|
+
result << rendered
|
28
|
+
end
|
29
|
+
was_attr = child.is_a?(AttrNode)
|
30
|
+
first = false
|
31
|
+
elsif @style == :compressed
|
32
|
+
result << (was_attr ? ";#{child.to_s(1)}" : child.to_s(1))
|
33
|
+
was_attr = child.is_a?(AttrNode)
|
34
|
+
else
|
35
|
+
result << child.to_s(tabs + 1) + "\n"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
result.rstrip + if @style == :compressed
|
39
|
+
"}"
|
40
|
+
else
|
41
|
+
(@style == :expanded ? "\n" : " ") + "}\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Sass
|
2
|
+
module Tree
|
3
|
+
class Node
|
4
|
+
attr_accessor :children
|
5
|
+
attr_accessor :line
|
6
|
+
attr_accessor :filename
|
7
|
+
|
8
|
+
def initialize(style)
|
9
|
+
@style = style
|
10
|
+
@children = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def <<(child)
|
14
|
+
if msg = invalid_child?(child)
|
15
|
+
raise Sass::SyntaxError.new(msg, child.line)
|
16
|
+
end
|
17
|
+
@children << child
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
result = String.new
|
22
|
+
children.each do |child|
|
23
|
+
if child.is_a? AttrNode
|
24
|
+
raise SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line)
|
25
|
+
else
|
26
|
+
result << "#{child.to_s(1)}" + (@style == :compressed ? '' : "\n")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@style == :compressed ? result+"\n" : result[0...-1]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# This method should be overridden by subclasses to return an error message
|
35
|
+
# if the given child node is invalid,
|
36
|
+
# and false or nil otherwise.
|
37
|
+
def invalid_child?(child)
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|