haml 1.0.5 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (92) hide show
  1. data/README +229 -0
  2. data/Rakefile +56 -60
  3. data/VERSION +1 -1
  4. data/bin/haml +4 -14
  5. data/bin/html2haml +89 -0
  6. data/bin/sass +8 -0
  7. data/init.rb +5 -1
  8. data/lib/haml.rb +643 -0
  9. data/lib/haml/buffer.rb +33 -30
  10. data/lib/haml/engine.rb +258 -75
  11. data/lib/haml/error.rb +43 -0
  12. data/lib/haml/exec.rb +181 -0
  13. data/lib/haml/filters.rb +89 -0
  14. data/lib/haml/helpers.rb +19 -5
  15. data/lib/haml/helpers/action_view_mods.rb +28 -4
  16. data/lib/haml/template.rb +13 -27
  17. data/lib/sass.rb +418 -0
  18. data/lib/sass/constant.rb +190 -0
  19. data/lib/sass/constant/color.rb +77 -0
  20. data/lib/sass/constant/literal.rb +51 -0
  21. data/lib/sass/constant/number.rb +87 -0
  22. data/lib/sass/constant/operation.rb +30 -0
  23. data/lib/sass/constant/string.rb +18 -0
  24. data/lib/sass/engine.rb +179 -0
  25. data/lib/sass/error.rb +35 -0
  26. data/lib/sass/plugin.rb +119 -0
  27. data/lib/sass/tree/attr_node.rb +44 -0
  28. data/lib/sass/tree/node.rb +29 -0
  29. data/lib/sass/tree/rule_node.rb +47 -0
  30. data/lib/sass/tree/value_node.rb +12 -0
  31. data/test/benchmark.rb +16 -19
  32. data/test/haml/engine_test.rb +220 -0
  33. data/test/{helper_test.rb → haml/helper_test.rb} +9 -8
  34. data/test/{mocks → haml/mocks}/article.rb +0 -0
  35. data/test/{results → haml/results}/content_for_layout.xhtml +0 -0
  36. data/test/{results → haml/results}/eval_suppressed.xhtml +0 -0
  37. data/test/haml/results/filters.xhtml +57 -0
  38. data/test/{results → haml/results}/helpers.xhtml +10 -0
  39. data/test/haml/results/helpful.xhtml +8 -0
  40. data/test/{results → haml/results}/just_stuff.xhtml +5 -0
  41. data/test/{results → haml/results}/list.xhtml +0 -0
  42. data/test/{results → haml/results}/original_engine.xhtml +1 -1
  43. data/test/{results → haml/results}/partials.xhtml +0 -0
  44. data/test/{results → haml/results}/silent_script.xhtml +0 -0
  45. data/test/{results → haml/results}/standard.xhtml +2 -1
  46. data/test/{results → haml/results}/tag_parsing.xhtml +0 -0
  47. data/test/{results → haml/results}/very_basic.xhtml +0 -0
  48. data/test/haml/results/whitespace_handling.xhtml +104 -0
  49. data/test/{rhtml → haml/rhtml}/standard.rhtml +4 -1
  50. data/test/{runner.rb → haml/runner.rb} +1 -1
  51. data/test/{template_test.rb → haml/template_test.rb} +28 -23
  52. data/test/{templates → haml/templates}/_partial.haml +0 -0
  53. data/test/{templates → haml/templates}/_text_area.haml +0 -0
  54. data/test/haml/templates/breakage.haml +8 -0
  55. data/test/{templates → haml/templates}/content_for_layout.haml +0 -0
  56. data/test/{templates → haml/templates}/eval_suppressed.haml +0 -0
  57. data/test/haml/templates/filters.haml +53 -0
  58. data/test/{templates → haml/templates}/helpers.haml +10 -1
  59. data/test/{templates → haml/templates}/helpful.haml +3 -0
  60. data/test/{templates → haml/templates}/just_stuff.haml +7 -0
  61. data/test/{templates → haml/templates}/list.haml +0 -0
  62. data/test/haml/templates/original_engine.haml +17 -0
  63. data/test/{templates → haml/templates}/partialize.haml +0 -0
  64. data/test/{templates → haml/templates}/partials.haml +0 -0
  65. data/test/{templates → haml/templates}/silent_script.haml +0 -0
  66. data/test/{templates → haml/templates}/standard.haml +3 -1
  67. data/test/{templates → haml/templates}/tag_parsing.haml +0 -0
  68. data/test/{templates → haml/templates}/very_basic.haml +0 -0
  69. data/test/haml/templates/whitespace_handling.haml +137 -0
  70. data/test/profile.rb +36 -18
  71. data/test/sass/engine_test.rb +87 -0
  72. data/test/sass/plugin_test.rb +103 -0
  73. data/test/sass/results/basic.css +9 -0
  74. data/test/sass/results/compact.css +5 -0
  75. data/test/sass/results/complex.css +86 -0
  76. data/test/sass/results/constants.css +12 -0
  77. data/test/sass/results/expanded.css +18 -0
  78. data/test/sass/results/nested.css +14 -0
  79. data/test/sass/templates/basic.sass +23 -0
  80. data/test/sass/templates/bork.sass +2 -0
  81. data/test/sass/templates/compact.sass +15 -0
  82. data/test/sass/templates/complex.sass +291 -0
  83. data/test/sass/templates/constants.sass +80 -0
  84. data/test/sass/templates/expanded.sass +15 -0
  85. data/test/sass/templates/nested.sass +15 -0
  86. metadata +98 -48
  87. data/REFERENCE +0 -662
  88. data/test/engine_test.rb +0 -93
  89. data/test/results/helpful.xhtml +0 -5
  90. data/test/results/whitespace_handling.xhtml +0 -51
  91. data/test/templates/original_engine.haml +0 -17
  92. data/test/templates/whitespace_handling.haml +0 -66
@@ -0,0 +1,43 @@
1
+ module Haml
2
+ # The abstract type of exception raised by Haml code.
3
+ # Haml::SyntaxError includes this module,
4
+ # as do all exceptions raised by Ruby code within Haml.
5
+ #
6
+ # Haml::Error encapsulates information about the exception,
7
+ # such as the line of the Haml template it was raised on
8
+ # and the Haml file that was being parsed (if applicable).
9
+ # It also provides a handy way to rescue only exceptions raised
10
+ # because of a faulty template.
11
+ module Error
12
+ # The line of the Haml template on which the exception was thrown.
13
+ attr_reader :haml_line
14
+
15
+ # The name of the file that was being parsed when the exception was raised.
16
+ # This will be nil unless Haml is being used as an ActionView plugin.
17
+ attr_reader :haml_filename
18
+
19
+ # Adds a properly formatted entry to the exception's backtrace.
20
+ # +lineno+ should be the line on which the error occurred.
21
+ # +filename+ should be the file in which the error occurred,
22
+ # if applicable (defaults to "(haml)").
23
+ def add_backtrace_entry(lineno, filename = nil) # :nodoc:
24
+ @haml_line = lineno
25
+ @haml_filename = filename
26
+ self.backtrace ||= []
27
+ self.backtrace.unshift "#{filename || '(haml)'}:#{lineno}"
28
+ end
29
+ end
30
+
31
+ # SyntaxError is the type of exception raised when Haml encounters an
32
+ # ill-formatted document.
33
+ # It's not particularly interesting, except in that it includes Haml::Error.
34
+ class SyntaxError < StandardError
35
+ include Haml::Error
36
+ end
37
+
38
+ # HamlError is the type of exception raised when Haml encounters an error
39
+ # not of a syntactical nature, such as an undefined Filter.
40
+ class HamlError < StandardError
41
+ include Haml::Error
42
+ end
43
+ end
@@ -0,0 +1,181 @@
1
+ require File.dirname(__FILE__) + '/../haml'
2
+ require 'optparse'
3
+
4
+ module Haml
5
+ # This module contains code for working with the
6
+ # haml, sass, and haml2html executables,
7
+ # such as command-line parsing stuff.
8
+ # It shouldn't need to be invoked by client code.
9
+ module Exec # :nodoc:
10
+ # A class that encapsulates the executable code
11
+ # for all three executables.
12
+ class Generic # :nodoc:
13
+ def initialize(args)
14
+ @args = args
15
+ @options = {}
16
+ end
17
+
18
+ def parse!
19
+ @opts = OptionParser.new(&(method(:set_opts).to_proc))
20
+ @opts.parse!(@args)
21
+
22
+ process_result
23
+
24
+ @options
25
+ end
26
+
27
+ def to_s
28
+ @opts.to_s
29
+ end
30
+
31
+ private
32
+
33
+ def set_opts(opts)
34
+ opts.on('--stdin', :NONE, 'Read input from standard input instead of an input file') do
35
+ @options[:input] = $stdin
36
+ end
37
+
38
+ opts.on('--stdout', :NONE, 'Print output to standard output instead of an output file') do
39
+ @options[:output] = $stdout
40
+ end
41
+
42
+ opts.on_tail("-?", "-h", "--help", "Show this message") do
43
+ puts opts
44
+ exit
45
+ end
46
+
47
+ opts.on_tail("-v", "--version", "Print version") do
48
+ puts("Haml " + File.read(File.dirname(__FILE__) + '/../../VERSION'))
49
+ exit
50
+ end
51
+ end
52
+
53
+ def process_result
54
+ input = @options[:input]
55
+ output = @options[:output]
56
+
57
+ if input
58
+ output ||= ARGV[0]
59
+ else
60
+ input ||= ARGV[0]
61
+ output ||= ARGV[1]
62
+ end
63
+
64
+ unless input && output
65
+ puts @opts
66
+ exit 1
67
+ end
68
+
69
+ if input.is_a?(String) && !File.exists?(input)
70
+ puts "File #{input} doesn't exist!"
71
+ exit 1
72
+ end
73
+
74
+ unless input.is_a? IO
75
+ input = File.open(input)
76
+ input_file = true
77
+ end
78
+
79
+ unless output.is_a? IO
80
+ output = File.open(output, "w")
81
+ output_file = true
82
+ end
83
+
84
+ @options[:input] = input
85
+ @options[:output] = output
86
+ end
87
+ end
88
+
89
+ # A class encapsulating the executable functionality
90
+ # specific to Haml and Sass.
91
+ class HamlSass < Generic # :nodoc:
92
+ private
93
+
94
+ def set_opts(opts)
95
+ opts.banner = <<END
96
+ Usage: #{@name.downcase} [options] (#{@name.downcase} file) (output file)
97
+
98
+ Description:
99
+ Uses the #{@name} engine to parse the specified template
100
+ and outputs the result to the specified file.
101
+
102
+ Options:
103
+ END
104
+
105
+ super
106
+ end
107
+
108
+ def process_result
109
+ super
110
+ require File.dirname(__FILE__) + "/../#{@name.downcase}"
111
+ end
112
+ end
113
+
114
+ # A class encapsulating executable functionality
115
+ # specific to Sass.
116
+ class Sass < HamlSass # :nodoc:
117
+ def initialize(args)
118
+ super
119
+ @name = "Sass"
120
+ end
121
+
122
+ def process_result
123
+ super
124
+ input = @options[:input]
125
+ output = @options[:output]
126
+
127
+ template = input.read()
128
+ input.close() if input.is_a? File
129
+ result = ::Sass::Engine.new(template).render
130
+ output.write(result)
131
+ output.close() if output.is_a? File
132
+ end
133
+ end
134
+
135
+ # A class encapsulating executable functionality
136
+ # specific to Haml.
137
+ class Haml < HamlSass # :nodoc:
138
+ def initialize(args)
139
+ super
140
+ @name = "Haml"
141
+ end
142
+
143
+ def process_result
144
+ super
145
+ input = @options[:input]
146
+ output = @options[:output]
147
+
148
+ template = input.read()
149
+ input.close() if input.is_a? File
150
+ result = ::Haml::Engine.new(template).to_html
151
+ output.write(result)
152
+ output.close() if output.is_a? File
153
+ end
154
+ end
155
+
156
+ # A class encapsulating executable functionality
157
+ # specific to the html2haml executable.
158
+ class HTML2Haml < Generic # :nodoc:
159
+ def set_opts(opts)
160
+ opts.banner = <<END
161
+ Usage: html2haml [options] (html file) (output file)
162
+
163
+ Description: Transforms an HTML file into corresponding Haml code.
164
+
165
+ Options:
166
+ END
167
+
168
+ super
169
+ end
170
+
171
+ def process_result
172
+ super
173
+
174
+ input = @options[:input]
175
+ output = @options[:output]
176
+
177
+ output.write(Hpricot(input).to_haml)
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,89 @@
1
+ # This file contains redefinitions of and wrappers around various text
2
+ # filters so they can be used as Haml filters.
3
+
4
+ # :stopdoc:
5
+
6
+ require 'erb'
7
+ require 'sass/engine'
8
+ require 'stringio'
9
+
10
+ volatile_requires = ['rubygems', 'redcloth', 'bluecloth']
11
+ NOT_LOADED = [] unless defined?(NOT_LOADED)
12
+ volatile_requires.each do |file|
13
+ begin
14
+ require file
15
+ rescue LoadError
16
+ NOT_LOADED.push file
17
+ end
18
+ end
19
+
20
+ class ERB; alias_method :render, :result; end
21
+
22
+ unless NOT_LOADED.include? 'bluecloth'
23
+ class BlueCloth; alias_method :render, :to_html; end
24
+ end
25
+
26
+ module Haml
27
+ module Filters
28
+ class Plain
29
+ def initialize(text)
30
+ @text = text
31
+ end
32
+
33
+ def render
34
+ @text
35
+ end
36
+ end
37
+
38
+ class Ruby
39
+ def initialize(text)
40
+ @text = text
41
+ end
42
+
43
+ def render
44
+ old_stdout = $stdout
45
+ $stdout = StringIO.new
46
+ Object.new.instance_eval(@text)
47
+ old_stdout, $stdout = $stdout, old_stdout
48
+ old_stdout.pos = 0
49
+ old_stdout.read
50
+ end
51
+ end
52
+
53
+ class Preserve
54
+ def initialize(text)
55
+ @text = text
56
+ end
57
+
58
+ def render
59
+ Haml::Helpers.preserve(@text)
60
+ end
61
+ end
62
+
63
+ unless NOT_LOADED.include? 'bluecloth'
64
+ Markdown = BlueCloth unless defined?(Markdown)
65
+ end
66
+
67
+ unless NOT_LOADED.include? 'redcloth'
68
+ class ::RedCloth; alias_method :render, :to_html; end
69
+
70
+ # Uses RedCloth to provide only Textile (not Markdown) parsing
71
+ class Textile < RedCloth
72
+ def render
73
+ self.to_html(:textile)
74
+ end
75
+ end
76
+
77
+ unless defined?(Markdown)
78
+ # Uses RedCloth to provide only Markdown (not Textile) parsing
79
+ class Markdown < RedCloth
80
+ def render
81
+ self.to_html(:markdown)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ # :startdoc:
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/helpers/action_view_mods'
1
+ require 'haml/helpers/action_view_mods'
2
2
 
3
3
  module Haml
4
4
  # This module contains various helpful methods to make it easier to do
@@ -16,13 +16,25 @@ module Haml
16
16
  @@action_view
17
17
  end
18
18
 
19
+ # Isolates the whitespace-sensitive tags in the string and uses preserve
20
+ # to convert any endlines inside them into HTML entities for endlines.
21
+ def find_and_preserve(input)
22
+ input = input.to_s
23
+ input.scan(/<(textarea|code|pre)[^>]*>(.*?)<\/\1>/im) do |tag, contents|
24
+ input = input.gsub(contents, preserve(contents))
25
+ end
26
+ input
27
+ end
28
+
19
29
  # Takes any string, finds all the endlines and converts them to
20
30
  # HTML entities for endlines so they'll render correctly in
21
31
  # whitespace-sensitive tags without screwing up the indentation.
22
- def flatten(input)
32
+ def preserve(input)
23
33
  input.gsub(/\n/, '&#x000A;').gsub(/\r/, '')
24
34
  end
25
35
 
36
+ alias_method :flatten, :preserve
37
+
26
38
  # Takes an Enumerable object and a block
27
39
  # and iterates over the object,
28
40
  # yielding each element to a Haml block
@@ -228,8 +240,10 @@ module Haml
228
240
  end
229
241
  end
230
242
 
231
- class ActionView::Base # :nodoc:
232
- def is_haml?
233
- false
243
+ module ActionView
244
+ class Base # :nodoc:
245
+ def is_haml?
246
+ false
247
+ end
234
248
  end
235
249
  end
@@ -12,13 +12,18 @@ if action_view_included
12
12
  class ActionView::Base
13
13
  alias_method :old_concat, :concat unless instance_methods.include? "old_concat"
14
14
  alias_method :old_form_tag, :form_tag unless instance_methods.include? "old_form_tag"
15
+
16
+ alias_method :old_form_for, :form_for unless instance_methods.include? "old_form_for"
15
17
  end
16
18
 
17
19
  module Haml
18
20
  module Helpers
19
- # This module overrides various helpers in ActionView to make them
20
- # work more effectively with Haml. It's not available unless ActionView
21
- # is installed.
21
+ # This module overrides various helpers in ActionView
22
+ # to make them work more effectively with Haml.
23
+ # It also defines several helper methods,
24
+ # available from a Haml template,
25
+ # which are only useful within the context of ActionView.
26
+ # It's not available unless ActionView is installed.
22
27
  #
23
28
  #--
24
29
  # Methods in this module should be nodoc'd.
@@ -49,7 +54,26 @@ if action_view_included
49
54
  tab_down
50
55
  end
51
56
  end
52
- old_form_tag(url_for_options, options, *parameters_for_url, &proc)
57
+ res = old_form_tag(url_for_options, options, *parameters_for_url, &proc) + "\n"
58
+ concat "\n" if block_given? && is_haml?
59
+ res
60
+ end
61
+
62
+ def form_for(object_name, *args, &proc) # :nodoc:
63
+ if block_given? && is_haml?
64
+ oldproc = proc
65
+ proc = bind_proc do |*args|
66
+ tab_up
67
+ oldproc.call(*args)
68
+ tab_down
69
+ end
70
+ end
71
+ old_form_for(object_name, *args, &proc)
72
+ concat "\n" if block_given? && is_haml?
73
+ end
74
+
75
+ def generate_content_class_names
76
+ controller.controller_name + " " + controller.action_name
53
77
  end
54
78
  end
55
79
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/engine'
1
+ require 'haml/engine'
2
2
  require 'rubygems'
3
3
  require 'active_support'
4
4
  require 'action_view'
@@ -25,12 +25,12 @@ module Haml
25
25
  class << self
26
26
  @@options = {}
27
27
 
28
- # Gets various options for HAML. See REFERENCE for details.
28
+ # Gets various options for Haml. See README for details.
29
29
  def options
30
30
  @@options
31
31
  end
32
32
 
33
- # Sets various options for HAML. See REFERENCE for details.
33
+ # Sets various options for Haml. See README for details.
34
34
  def options=(value)
35
35
  @@options = value
36
36
  end
@@ -47,18 +47,8 @@ module Haml
47
47
  # with <tt>local_assigns</tt> available as local variables within the template.
48
48
  # Returns the result as a string.
49
49
  def render(template, local_assigns={})
50
- unless @view.instance_variable_get("@assigns_added")
51
- assigns = @view.assigns.dup
52
-
53
- # Get inside the view object's world
54
- @view.instance_eval do
55
- # Set all the instance variables
56
- assigns.each do |key,val|
57
- instance_variable_set "@#{key}", val
58
- end
59
- end
60
-
61
- @view.instance_variable_set("@assigns_added", true)
50
+ @view.instance_eval do
51
+ evaluate_assigns
62
52
  end
63
53
 
64
54
  options = @@options.dup
@@ -68,12 +58,15 @@ module Haml
68
58
 
69
59
  if @view.haml_inline
70
60
  engine = Haml::Engine.new(template, options)
71
- elsif @precompiled = get_precompiled(template)
72
- options[:precompiled] ||= @precompiled
73
- engine = Haml::Engine.new("", options)
74
61
  else
75
- engine = Haml::Engine.new(File.read(template), options)
76
- set_precompiled(template, engine.precompiled)
62
+ options[:filename] ||= template
63
+ if @precompiled = get_precompiled(template)
64
+ options[:precompiled] ||= @precompiled
65
+ engine = Haml::Engine.new("", options)
66
+ else
67
+ engine = Haml::Engine.new(File.read(template), options)
68
+ set_precompiled(template, engine.precompiled)
69
+ end
77
70
  end
78
71
 
79
72
  yield_proc = @view.instance_eval do
@@ -111,15 +104,8 @@ end
111
104
  # here[http://rubyonrails.org/api/classes/ActionView/Base.html].
112
105
  module ActionView
113
106
  class Base # :nodoc:
114
- attr :haml_filename, true
115
107
  attr :haml_inline
116
108
 
117
- alias_method :haml_old_render_file, :render_file
118
- def render_file(template_path, use_full_path = true, local_assigns = {})
119
- @haml_filename = File.basename(template_path)
120
- haml_old_render_file(template_path, use_full_path, local_assigns)
121
- end
122
-
123
109
  alias_method :read_template_file_old, :read_template_file
124
110
  def read_template_file(template_path, extension)
125
111
  if extension =~ /haml/i