haml 2.0.2 → 2.0.3

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.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.2
1
+ 2.0.3
data/bin/haml CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # The command line Haml parser.
3
3
 
4
- require File.dirname(__FILE__) + '/../lib/haml'
4
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
5
+ require 'haml'
5
6
  require 'haml/exec'
6
7
 
7
8
  opts = Haml::Exec::Haml.new(ARGV)
@@ -23,13 +23,10 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
23
23
  #
24
24
  # == Using Haml
25
25
  #
26
- # Haml can be used in two ways:
26
+ # Haml can be used in three ways:
27
27
  # as a plugin for Ruby on Rails,
28
- # and as a standalone Ruby module.
29
- #
30
- # Sass can be used in several ways:
31
- # As a template engine for Ruby on Rails or Merb,
32
- # or as a standalone engine.
28
+ # as a standalone Ruby module,
29
+ # and as a command-line tool.
33
30
  # The first step for all of these is to install the Haml gem:
34
31
  #
35
32
  # gem install haml
@@ -39,13 +36,15 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
39
36
  #
40
37
  # haml --rails path/to/rails/app
41
38
  #
42
- # Haml is enabled in Merb by default,
43
- # so Merb users don't have to do anything more.
44
- #
45
- # Once it's installed, all view files with the ".haml" extension
46
- # (or ".html.haml" for Merb or edge Rails)
39
+ # Once it's installed, all view files with the ".html.haml" extension
47
40
  # will be compiled using Haml.
48
41
  #
42
+ # To run Haml from the commandline, just use
43
+ #
44
+ # haml input.haml output.html
45
+ #
46
+ # Use <tt>haml --help</tt> for full documentation.
47
+ #
49
48
  # You can access instance variables in Haml templates
50
49
  # the same way you do in ERb templates.
51
50
  # Helper methods are also available in Haml templates.
@@ -606,6 +605,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
606
605
  # <hoo>
607
606
  # I think this might get pretty long so I should probably make it multiline so it doesn't look awful.
608
607
  # </hoo>
608
+ # <p>This is short</p>
609
609
  # </whoo>
610
610
  #
611
611
  # ==== :
@@ -676,17 +676,13 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
676
676
  #
677
677
  # [sass] Parses the filtered text with Sass to produce CSS output.
678
678
  #
679
- # [redcloth] Parses the filtered text with RedCloth (http://whytheluckystiff.net/ruby/redcloth),
680
- # which uses both Textile and Markdown syntax.
681
- # Only works if RedCloth is installed.
682
- #
683
679
  # [textile] Parses the filtered text with Textile (http://www.textism.com/tools/textile).
684
680
  # Only works if RedCloth is installed.
685
681
  #
686
682
  # [markdown] Parses the filtered text with Markdown (http://daringfireball.net/projects/markdown).
687
- # Only works if RedCloth or BlueCloth (http://www.deveiate.org/projects/BlueCloth)
688
- # is installed
689
- # (BlueCloth takes precedence if both are installed).
683
+ # Only works if RDiscount, RPeg-Markdown, Maruku, or BlueCloth are installed.
684
+ #
685
+ # [maruku] Parses the filtered text with Maruku, which has some non-standard extensions to Markdown.
690
686
  #
691
687
  # You can also define your own filters (see Haml::Filters).
692
688
  #
@@ -917,16 +913,16 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
917
913
  # Options can be set by setting the <tt>Haml::Template.options</tt> hash
918
914
  # in <tt>environment.rb</tt> in Rails...
919
915
  #
920
- # Haml::Template.options[:output] = :html5
916
+ # Haml::Template.options[:format] = :html5
921
917
  #
922
918
  # ...or by setting the <tt>Merb::Config[:haml]</tt> hash in <tt>init.rb</tt> in Merb...
923
919
  #
924
- # Merb::Config[:haml][:output] = :html5
920
+ # Merb::Config[:haml][:format] = :html5
925
921
  #
926
922
  # ...or by passing an options hash to Haml::Engine.new.
927
923
  # Available options are:
928
924
  #
929
- # [<tt>:output</tt>] Determines the output format. The default is :xhtml.
925
+ # [<tt>:format</tt>] Determines the output format. The default is :xhtml.
930
926
  # Other options are :html4 and :html5, which are
931
927
  # identical to :xhtml except there are no self-closing tags,
932
928
  # XML prolog is ignored and correct DOCTYPEs are generated.
@@ -1009,7 +1005,8 @@ module Haml
1009
1005
 
1010
1006
  if rev
1011
1007
  @@version[:rev] = rev
1012
- @@version[:string] << "." << rev[0...7]
1008
+ @@version[:string] << "."
1009
+ @@version[:string] << rev[0...7] unless rev[0] == ?(
1013
1010
  end
1014
1011
 
1015
1012
  @@version
@@ -104,15 +104,15 @@ module Haml
104
104
  escape_html = false, nuke_inner_whitespace = false)
105
105
  tabulation = @real_tabs
106
106
 
107
+ result = result.to_s.rstrip
108
+ result = html_escape(result) if escape_html
109
+
107
110
  if preserve_tag
108
111
  result = Haml::Helpers.preserve(result)
109
112
  elsif preserve_script
110
113
  result = Haml::Helpers.find_and_preserve(result, options[:preserve])
111
114
  end
112
115
 
113
- result = result.to_s.rstrip
114
- result = html_escape(result) if escape_html
115
-
116
116
  has_newline = result.include?("\n")
117
117
  if in_tag && !nuke_inner_whitespace && (@options[:ugly] || !has_newline || preserve_tag)
118
118
  @buffer << result
@@ -68,6 +68,7 @@ module Haml
68
68
  :escape_html => false
69
69
  }
70
70
  @options.merge! options
71
+ @index = 0
71
72
 
72
73
  unless [:xhtml, :html4, :html5].include?(@options[:format])
73
74
  raise Haml::Error, "Invalid format #{@options[:format].inspect}"
@@ -77,8 +78,8 @@ module Haml
77
78
  @to_close_stack = []
78
79
  @output_tabs = 0
79
80
  @template_tabs = 0
80
- @index = 0
81
81
  @flat_spaces = -1
82
+ @flat = false
82
83
  @newlines = 0
83
84
  @precompiled = ''
84
85
  @merged_text = ''
@@ -1,6 +1,6 @@
1
1
  module Haml
2
2
  # An exception raised by Haml code.
3
- class Error < Exception
3
+ class Error < StandardError
4
4
  # :stopdoc:
5
5
 
6
6
  # By default, an error is taken to refer to the line of the template
@@ -1,4 +1,3 @@
1
- require File.dirname(__FILE__) + '/../haml'
2
1
  require 'optparse'
3
2
  require 'fileutils'
4
3
 
@@ -211,6 +210,8 @@ END
211
210
  def initialize(args)
212
211
  super
213
212
  @name = "Haml"
213
+ @options[:requires] = []
214
+ @options[:load_paths] = []
214
215
  end
215
216
 
216
217
  def set_opts(opts)
@@ -230,6 +231,14 @@ END
230
231
  'Escape HTML characters (like ampersands and angle brackets) by default.') do
231
232
  @options[:for_engine][:escape_html] = true
232
233
  end
234
+
235
+ opts.on('-r', '--require FILE', "Same as 'ruby -r'.") do |file|
236
+ @options[:requires] << file
237
+ end
238
+
239
+ opts.on('-I', '--load-path PATH', "Same as 'ruby -I'.") do |path|
240
+ @options[:load_paths] << path
241
+ end
233
242
  end
234
243
 
235
244
  def process_result
@@ -246,6 +255,9 @@ END
246
255
  puts "Syntax OK"
247
256
  return
248
257
  end
258
+
259
+ @options[:load_paths].each {|p| $LOAD_PATH << p}
260
+ @options[:requires].each {|f| require f}
249
261
  result = engine.to_html
250
262
  rescue Exception => e
251
263
  raise e if @options[:trace]
@@ -292,6 +304,10 @@ END
292
304
  @module_opts[:rhtml] = true
293
305
  end
294
306
 
307
+ opts.on('--no-rhtml', "Don't parse RHTML tags.") do
308
+ @options[:no_rhtml] = true
309
+ end
310
+
295
311
  opts.on('-x', '--xhtml', 'Parse the input using the more strict XHTML parser.') do
296
312
  @module_opts[:xhtml] = true
297
313
  end
@@ -305,6 +321,9 @@ END
305
321
  input = @options[:input]
306
322
  output = @options[:output]
307
323
 
324
+ @module_opts[:rhtml] ||= input.respond_to?(:path) && input.path =~ /\.(rhtml|erb)$/
325
+ @module_opts[:rhtml] &&= @options[:no_rhtml] != false
326
+
308
327
  output.write(::Haml::HTML.new(input, @module_opts).render)
309
328
  end
310
329
  end
@@ -1,6 +1,3 @@
1
- # This file contains redefinitions of and wrappers around various text
2
- # filters so they can be used as Haml filters.
3
-
4
1
  module Haml
5
2
  # The module containing the default filters,
6
3
  # as well as the base module,
@@ -35,6 +32,7 @@ module Haml
35
32
  def self.included(base) # :nodoc:
36
33
  Filters.defined[base.name.split("::").last.downcase] = base
37
34
  base.extend(base)
35
+ base.instance_variable_set "@lazy_requires", nil
38
36
  end
39
37
 
40
38
  # Takes a string, the source text that should be passed to the filter,
@@ -47,6 +45,12 @@ module Haml
47
45
  raise Error.new("#{self.inspect}#render not defined!")
48
46
  end
49
47
 
48
+ # Same as render, but takes the Haml options hash as well.
49
+ # It's only safe to rely on options made available in Haml::Engine#options_for_buffer.
50
+ def render_with_options(text, options)
51
+ render(text)
52
+ end
53
+
50
54
  def internal_compile(*args) # :nodoc:
51
55
  resolve_lazy_requires
52
56
  compile(*args)
@@ -71,12 +75,12 @@ module Haml
71
75
  return if options[:suppress_eval]
72
76
 
73
77
  push_script(<<RUBY, false)
74
- find_and_preserve(#{filter.inspect}.render(#{unescape_interpolation(text)}))
78
+ find_and_preserve(#{filter.inspect}.render_with_options(#{unescape_interpolation(text)}, _hamlout.options))
75
79
  RUBY
76
80
  return
77
81
  end
78
82
 
79
- rendered = Haml::Helpers::find_and_preserve(filter.render(text), precompiler.options[:preserve])
83
+ rendered = Haml::Helpers::find_and_preserve(filter.render_with_options(text, precompiler.options), precompiler.options[:preserve])
80
84
 
81
85
  if !options[:ugly]
82
86
  push_text(rendered.rstrip.gsub("\n", "\n#{' ' * @output_tabs}"))
@@ -97,7 +101,7 @@ RUBY
97
101
  # For example:
98
102
  #
99
103
  # module Haml::Filters::Markdown
100
- # lazy_require 'bluecloth', 'redcloth'
104
+ # lazy_require 'rdiscount', 'peg_markdown', 'maruku', 'bluecloth'
101
105
  #
102
106
  # ...
103
107
  # end
@@ -123,7 +127,7 @@ RUBY
123
127
  @required = @lazy_requires[-1]
124
128
  require @required
125
129
  rescue LoadError => e
126
- classname = self.class.to_s.gsub(/\w+::/, '')
130
+ classname = self.name.match(/\w+$/)[0]
127
131
 
128
132
  if @lazy_requires.size == 1
129
133
  raise Error.new("Can't run #{classname} filter; required file '#{@lazy_requires.first}' not found")
@@ -153,9 +157,9 @@ module Haml
153
157
  module Javascript
154
158
  include Base
155
159
 
156
- def render(text)
160
+ def render_with_options(text, options)
157
161
  <<END
158
- <script type='text/javascript'>
162
+ <script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>
159
163
  //<![CDATA[
160
164
  #{text.rstrip.gsub("\n", "\n ")}
161
165
  //]]>
@@ -211,7 +215,7 @@ END
211
215
  lazy_require 'sass/engine'
212
216
 
213
217
  def render(text)
214
- ::Sass::Engine.new(text).render
218
+ ::Sass::Engine.new(text,::Sass::Plugin.engine_options).render
215
219
  end
216
220
  end
217
221
 
@@ -226,36 +230,42 @@ END
226
230
  end
227
231
  end
228
232
 
229
- module RedCloth
233
+ module Textile
230
234
  include Base
231
235
  lazy_require 'redcloth'
232
236
 
233
237
  def render(text)
234
- ::RedCloth.new(text).to_html
238
+ ::RedCloth.new(text).to_html(:textile)
235
239
  end
236
240
  end
241
+ RedCloth = Textile
237
242
 
238
- # Uses RedCloth to provide only Textile (not Markdown) parsing
239
- module Textile
243
+ # Uses BlueCloth or RedCloth to provide only Markdown (not Textile) parsing
244
+ module Markdown
240
245
  include Base
241
- lazy_require 'redcloth'
246
+ lazy_require 'rdiscount', 'peg_markdown', 'maruku', 'bluecloth'
242
247
 
243
248
  def render(text)
244
- ::RedCloth.new(text).to_html(:textile)
249
+ engine = case @required
250
+ when 'rdiscount'
251
+ RDiscount
252
+ when 'peg_markdown'
253
+ PEGMarkdown
254
+ when 'maruku'
255
+ Maruku
256
+ when 'bluecloth'
257
+ BlueCloth
258
+ end
259
+ engine.new(text).to_html
245
260
  end
246
261
  end
247
262
 
248
- # Uses BlueCloth or RedCloth to provide only Markdown (not Textile) parsing
249
- module Markdown
263
+ module Maruku
250
264
  include Base
251
- lazy_require 'bluecloth', 'redcloth'
265
+ lazy_require 'maruku'
252
266
 
253
267
  def render(text)
254
- if @required == 'bluecloth'
255
- ::BlueCloth.new(text).to_html
256
- else
257
- ::RedCloth.new(text).to_html(:markdown)
258
- end
268
+ Maruku.new(text).to_html
259
269
  end
260
270
  end
261
271
  end
@@ -397,7 +397,7 @@ module Haml
397
397
  def capture_haml_with_buffer(local_buffer, *args, &block)
398
398
  position = local_buffer.length
399
399
 
400
- block.call *args
400
+ block.call(*args)
401
401
 
402
402
  captured = local_buffer.slice!(position..-1)
403
403
 
@@ -29,7 +29,7 @@ module Haml
29
29
  end
30
30
 
31
31
  method = @@options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
32
- @template = method.call(template)
32
+ @template = method.call(template.gsub('&', '&amp;'))
33
33
  end
34
34
  end
35
35
 
@@ -112,16 +112,13 @@ END
112
112
  Line = Struct.new(:text, :unstripped, :index, :spaces, :tabs)
113
113
 
114
114
  def precompile
115
+ @haml_comment = @dont_indent_next_line = @dont_tab_up_next_text = false
116
+ @indentation = nil
115
117
  old_line = Line.new
116
118
  @template.split(/\r\n|\r|\n/).each_with_index do |text, index|
117
119
  @next_line = line = Line.new(text.strip, text.lstrip.chomp, index)
118
120
  line.spaces, line.tabs = count_soft_tabs(text)
119
121
 
120
- if line.text.empty? && !flat?
121
- newline
122
- next
123
- end
124
-
125
122
  suppress_render = handle_multiline(old_line) unless flat?
126
123
 
127
124
  if old_line.text.nil? || suppress_render
@@ -133,6 +130,11 @@ END
133
130
 
134
131
  process_indent(old_line) unless old_line.text.empty?
135
132
 
133
+ if line.text.empty? && !flat?
134
+ newline
135
+ next
136
+ end
137
+
136
138
  if flat?
137
139
  push_flat(old_line)
138
140
  old_line = line
@@ -699,13 +701,7 @@ END
699
701
  # Starts a filtered block.
700
702
  def start_filtered(name)
701
703
  raise Error.new("Invalid filter name \":#{name}\".") unless name =~ /^\w+$/
702
-
703
- unless filter = Filters.defined[name]
704
- if filter == 'redcloth' || filter == 'markdown' || filter == 'textile'
705
- raise Error.new("You must have the RedCloth gem installed to use \"#{name}\" filter")
706
- end
707
- raise Error.new("Filter \"#{name}\" is not defined.")
708
- end
704
+ raise Error.new("Filter \"#{name}\" is not defined.") unless filter = Filters.defined[name]
709
705
 
710
706
  push_and_tabulate([:filtered, filter])
711
707
  @flat_spaces = @template_tabs * 2
@@ -20,9 +20,10 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
20
20
  #
21
21
  # == Using Sass
22
22
  #
23
- # Sass can be used in several ways:
24
- # As a plugin for Ruby on Rails or Merb,
25
- # or as a standalone parser.
23
+ # Sass can be used in three ways:
24
+ # as a plugin for Ruby on Rails,
25
+ # as a standalone Ruby module,
26
+ # and as a command-line tool.
26
27
  # Sass is bundled with Haml,
27
28
  # so if the Haml plugin or RubyGem is installed,
28
29
  # Sass will already be installed as a plugin or gem, respectively.
@@ -42,7 +43,7 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
42
43
  #
43
44
  # to config/dependencies.rb.
44
45
  #
45
- # Sass templates in Rails and Merb don't quite function in the same way as views,
46
+ # Sass templates in Rails don't quite function in the same way as views,
46
47
  # because they don't contain dynamic content,
47
48
  # and so only need to be compiled when the template file has been updated.
48
49
  # By default (see options, below),
@@ -50,6 +51,12 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
50
51
  # Then, whenever necessary, they're compiled into corresponding CSS files in public/stylesheets.
51
52
  # For instance, public/stylesheets/sass/main.sass would be compiled to public/stylesheets/main.css.
52
53
  #
54
+ # To run Sass from the commandline, just use
55
+ #
56
+ # sass input.sass output.css
57
+ #
58
+ # Use <tt>sass --help</tt> for full documentation.
59
+ #
53
60
  # Using Sass in Ruby code is very simple.
54
61
  # After installing the Haml gem,
55
62
  # you can use it by running <tt>require "sass"</tt>