haml 1.8.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/FAQ +138 -0
 - data/MIT-LICENSE +1 -1
 - data/{README → README.rdoc} +66 -3
 - data/Rakefile +111 -147
 - data/VERSION +1 -1
 - data/bin/css2sass +0 -0
 - data/bin/haml +0 -0
 - data/bin/html2haml +0 -0
 - data/bin/sass +0 -0
 - data/init.rb +6 -1
 - data/lib/haml.rb +464 -201
 - data/lib/haml/buffer.rb +117 -63
 - data/lib/haml/engine.rb +63 -44
 - data/lib/haml/error.rb +16 -6
 - data/lib/haml/exec.rb +37 -7
 - data/lib/haml/filters.rb +213 -68
 - data/lib/haml/helpers.rb +95 -60
 - data/lib/haml/helpers/action_view_extensions.rb +1 -1
 - data/lib/haml/helpers/action_view_mods.rb +54 -6
 - data/lib/haml/html.rb +6 -6
 - data/lib/haml/precompiler.rb +254 -133
 - data/lib/haml/template.rb +3 -6
 - data/lib/haml/template/patch.rb +9 -2
 - data/lib/haml/template/plugin.rb +52 -23
 - data/lib/sass.rb +157 -12
 - data/lib/sass/constant.rb +22 -22
 - data/lib/sass/constant/color.rb +13 -13
 - data/lib/sass/constant/literal.rb +7 -7
 - data/lib/sass/constant/number.rb +9 -9
 - data/lib/sass/constant/operation.rb +4 -4
 - data/lib/sass/constant/string.rb +3 -3
 - data/lib/sass/css.rb +104 -31
 - data/lib/sass/engine.rb +120 -39
 - data/lib/sass/error.rb +1 -1
 - data/lib/sass/plugin.rb +14 -3
 - data/lib/sass/plugin/merb.rb +6 -2
 - data/lib/sass/tree/attr_node.rb +5 -5
 - data/lib/sass/tree/directive_node.rb +2 -7
 - data/lib/sass/tree/node.rb +1 -12
 - data/lib/sass/tree/rule_node.rb +39 -31
 - data/lib/sass/tree/value_node.rb +1 -1
 - data/test/benchmark.rb +67 -80
 - data/test/haml/engine_test.rb +284 -84
 - data/test/haml/helper_test.rb +51 -15
 - data/test/haml/results/content_for_layout.xhtml +1 -2
 - data/test/haml/results/eval_suppressed.xhtml +2 -4
 - data/test/haml/results/filters.xhtml +44 -15
 - data/test/haml/results/helpers.xhtml +2 -3
 - data/test/haml/results/just_stuff.xhtml +2 -6
 - data/test/haml/results/nuke_inner_whitespace.xhtml +34 -0
 - data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
 - data/test/haml/results/original_engine.xhtml +3 -7
 - data/test/haml/results/partials.xhtml +1 -0
 - data/test/haml/results/tag_parsing.xhtml +1 -6
 - data/test/haml/results/very_basic.xhtml +2 -4
 - data/test/haml/results/whitespace_handling.xhtml +13 -21
 - data/test/haml/template_test.rb +8 -15
 - data/test/haml/templates/_partial.haml +1 -0
 - data/test/haml/templates/filters.haml +48 -7
 - data/test/haml/templates/just_stuff.haml +1 -2
 - data/test/haml/templates/nuke_inner_whitespace.haml +26 -0
 - data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
 - data/test/haml/templates/tag_parsing.haml +0 -3
 - data/test/haml/test_helper.rb +15 -0
 - data/test/sass/engine_test.rb +80 -34
 - data/test/sass/plugin_test.rb +1 -1
 - data/test/sass/results/import.css +2 -2
 - data/test/sass/results/mixins.css +95 -0
 - data/test/sass/results/multiline.css +24 -0
 - data/test/sass/templates/import.sass +4 -1
 - data/test/sass/templates/importee.sass +4 -0
 - data/test/sass/templates/mixins.sass +76 -0
 - data/test/sass/templates/multiline.sass +20 -0
 - metadata +65 -51
 - data/lib/haml/util.rb +0 -18
 - data/test/haml/runner.rb +0 -16
 - data/test/profile.rb +0 -65
 
    
        data/lib/haml/buffer.rb
    CHANGED
    
    | 
         @@ -6,11 +6,6 @@ module Haml 
     | 
|
| 
       6 
6 
     | 
    
         
             
              class Buffer
         
     | 
| 
       7 
7 
     | 
    
         
             
                include Haml::Helpers
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                # Set the maximum length for a line to be considered a one-liner.
         
     | 
| 
       10 
     | 
    
         
            -
                # Lines <= the maximum will be rendered on one line,
         
     | 
| 
       11 
     | 
    
         
            -
                # i.e. <tt><p>Hello world</p></tt>
         
     | 
| 
       12 
     | 
    
         
            -
                ONE_LINER_LENGTH     = 50
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
9 
     | 
    
         
             
                # The string that holds the compiled XHTML. This is aliased as
         
     | 
| 
       15 
10 
     | 
    
         
             
                # _erbout for compatibility with ERB-specific code.
         
     | 
| 
       16 
11 
     | 
    
         
             
                attr_accessor :buffer
         
     | 
| 
         @@ -18,6 +13,47 @@ module Haml 
     | 
|
| 
       18 
13 
     | 
    
         
             
                # The options hash passed in from Haml::Engine.
         
     | 
| 
       19 
14 
     | 
    
         
             
                attr_accessor :options
         
     | 
| 
       20 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
                # The Buffer for the enclosing Haml document.
         
     | 
| 
      
 17 
     | 
    
         
            +
                # This is set for partials and similar sorts of nested templates.
         
     | 
| 
      
 18 
     | 
    
         
            +
                # It's nil at the top level (see #toplevel?).
         
     | 
| 
      
 19 
     | 
    
         
            +
                attr_accessor :upper
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                # See #active?
         
     | 
| 
      
 22 
     | 
    
         
            +
                attr_writer :active
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # True if the format is XHTML
         
     | 
| 
      
 25 
     | 
    
         
            +
                def xhtml?
         
     | 
| 
      
 26 
     | 
    
         
            +
                  not html?
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                # True if the format is any flavor of HTML
         
     | 
| 
      
 30 
     | 
    
         
            +
                def html?
         
     | 
| 
      
 31 
     | 
    
         
            +
                  html4? or html5?
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                # True if the format is HTML4
         
     | 
| 
      
 35 
     | 
    
         
            +
                def html4?
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @options[:format] == :html4
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                # True if the format is HTML5
         
     | 
| 
      
 40 
     | 
    
         
            +
                def html5?
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @options[:format] == :html5
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # True if this buffer is a top-level template,
         
     | 
| 
      
 45 
     | 
    
         
            +
                # as opposed to a nested partial.
         
     | 
| 
      
 46 
     | 
    
         
            +
                def toplevel?
         
     | 
| 
      
 47 
     | 
    
         
            +
                  upper.nil?
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # True if this buffer is currently being used to render a Haml template.
         
     | 
| 
      
 51 
     | 
    
         
            +
                # However, this returns false if a subtemplate is being rendered,
         
     | 
| 
      
 52 
     | 
    
         
            +
                # even if it's a subtemplate of this buffer's template.
         
     | 
| 
      
 53 
     | 
    
         
            +
                def active?
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @active
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       21 
57 
     | 
    
         
             
                # Gets the current tabulation of the document.
         
     | 
| 
       22 
58 
     | 
    
         
             
                def tabulation
         
     | 
| 
       23 
59 
     | 
    
         
             
                  @real_tabs + @tabulation
         
     | 
| 
         @@ -30,9 +66,13 @@ module Haml 
     | 
|
| 
       30 
66 
     | 
    
         
             
                end
         
     | 
| 
       31 
67 
     | 
    
         | 
| 
       32 
68 
     | 
    
         
             
                # Creates a new buffer.
         
     | 
| 
       33 
     | 
    
         
            -
                def initialize(options = {})
         
     | 
| 
      
 69 
     | 
    
         
            +
                def initialize(upper = nil, options = {})
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @active = true
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @upper = upper
         
     | 
| 
       34 
72 
     | 
    
         
             
                  @options = {
         
     | 
| 
       35 
     | 
    
         
            -
                    :attr_wrapper => "'"
         
     | 
| 
      
 73 
     | 
    
         
            +
                    :attr_wrapper => "'",
         
     | 
| 
      
 74 
     | 
    
         
            +
                    :ugly => false,
         
     | 
| 
      
 75 
     | 
    
         
            +
                    :format => :xhtml
         
     | 
| 
       36 
76 
     | 
    
         
             
                  }.merge options
         
     | 
| 
       37 
77 
     | 
    
         
             
                  @buffer = ""
         
     | 
| 
       38 
78 
     | 
    
         
             
                  @tabulation = 0
         
     | 
| 
         @@ -44,56 +84,72 @@ module Haml 
     | 
|
| 
       44 
84 
     | 
    
         | 
| 
       45 
85 
     | 
    
         
             
                # Renders +text+ with the proper tabulation. This also deals with
         
     | 
| 
       46 
86 
     | 
    
         
             
                # making a possible one-line tag one line or not.
         
     | 
| 
       47 
     | 
    
         
            -
                def push_text(text, tab_change = 0)
         
     | 
| 
       48 
     | 
    
         
            -
                  if 
     | 
| 
       49 
     | 
    
         
            -
                    # Have to push every line in by the extra user set tabulation
         
     | 
| 
       50 
     | 
    
         
            -
                     
     | 
| 
      
 87 
     | 
    
         
            +
                def push_text(text, dont_tab_up = false, tab_change = 0)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  if @tabulation > 0 && !@options[:ugly]
         
     | 
| 
      
 89 
     | 
    
         
            +
                    # Have to push every line in by the extra user set tabulation.
         
     | 
| 
      
 90 
     | 
    
         
            +
                    # Don't push lines with just whitespace, though,
         
     | 
| 
      
 91 
     | 
    
         
            +
                    # because that screws up precompiled indentation.
         
     | 
| 
      
 92 
     | 
    
         
            +
                    text.gsub!(/^(?!\s+$)/m, tabs)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    text.sub!(tabs, '') if dont_tab_up
         
     | 
| 
       51 
94 
     | 
    
         
             
                  end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  @buffer <<  
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  @buffer << text
         
     | 
| 
       54 
97 
     | 
    
         
             
                  @real_tabs += tab_change
         
     | 
| 
      
 98 
     | 
    
         
            +
                  @dont_tab_up_next_line = false
         
     | 
| 
       55 
99 
     | 
    
         
             
                end
         
     | 
| 
       56 
100 
     | 
    
         | 
| 
       57 
101 
     | 
    
         
             
                # Properly formats the output of a script that was run in the
         
     | 
| 
       58 
102 
     | 
    
         
             
                # instance_eval.
         
     | 
| 
       59 
     | 
    
         
            -
                def push_script(result,  
     | 
| 
      
 103 
     | 
    
         
            +
                def push_script(result, preserve_script, in_tag = false, preserve_tag = false,
         
     | 
| 
      
 104 
     | 
    
         
            +
                                escape_html = false, nuke_inner_whitespace = false)
         
     | 
| 
       60 
105 
     | 
    
         
             
                  tabulation = @real_tabs
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                  if  
     | 
| 
       63 
     | 
    
         
            -
                    result = Haml::Helpers. 
     | 
| 
       64 
     | 
    
         
            -
                   
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  result = result.to_s
         
     | 
| 
       67 
     | 
    
         
            -
                  while result[-1] == ?\n
         
     | 
| 
       68 
     | 
    
         
            -
                    # String#chomp is slow
         
     | 
| 
       69 
     | 
    
         
            -
                    result = result[0...-1]
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  if preserve_tag
         
     | 
| 
      
 108 
     | 
    
         
            +
                    result = Haml::Helpers.preserve(result)
         
     | 
| 
      
 109 
     | 
    
         
            +
                  elsif preserve_script
         
     | 
| 
      
 110 
     | 
    
         
            +
                    result = Haml::Helpers.find_and_preserve(result, options[:preserve])
         
     | 
| 
       70 
111 
     | 
    
         
             
                  end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                   
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  result = result.to_s.rstrip
         
     | 
| 
      
 114 
     | 
    
         
            +
                  result = html_escape(result) if escape_html
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  has_newline = result.include?("\n")
         
     | 
| 
      
 117 
     | 
    
         
            +
                  if in_tag && (@options[:ugly] || !has_newline || preserve_tag)
         
     | 
| 
       73 
118 
     | 
    
         
             
                    @buffer << result
         
     | 
| 
       74 
     | 
    
         
            -
                    @buffer << "</#{close_tag}>\n"
         
     | 
| 
       75 
119 
     | 
    
         
             
                    @real_tabs -= 1
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                    
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                     
     | 
| 
      
 120 
     | 
    
         
            +
                    return
         
     | 
| 
      
 121 
     | 
    
         
            +
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  @buffer << "\n" if in_tag && !nuke_inner_whitespace
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  # Precompiled tabulation may be wrong
         
     | 
| 
      
 126 
     | 
    
         
            +
                  if @tabulation > 0 && !in_tag
         
     | 
| 
      
 127 
     | 
    
         
            +
                    result = tabs + result
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  if has_newline && !@options[:ugly]
         
     | 
| 
      
 131 
     | 
    
         
            +
                    result = result.gsub "\n", "\n" + tabs(tabulation)
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                    # Add tabulation if it wasn't precompiled
         
     | 
| 
      
 134 
     | 
    
         
            +
                    result = tabs(tabulation) + result if in_tag && !nuke_inner_whitespace
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                  @buffer << "#{result}"
         
     | 
| 
      
 137 
     | 
    
         
            +
                  @buffer << "\n" unless nuke_inner_whitespace
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  if in_tag && !nuke_inner_whitespace
         
     | 
| 
      
 140 
     | 
    
         
            +
                    # We never get here if @options[:ugly] is true
         
     | 
| 
      
 141 
     | 
    
         
            +
                    @buffer << tabs(tabulation-1)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    @real_tabs -= 1
         
     | 
| 
       88 
143 
     | 
    
         
             
                  end
         
     | 
| 
       89 
144 
     | 
    
         
             
                  nil
         
     | 
| 
       90 
145 
     | 
    
         
             
                end
         
     | 
| 
       91 
146 
     | 
    
         | 
| 
       92 
147 
     | 
    
         
             
                # Takes the various information about the opening tag for an
         
     | 
| 
       93 
148 
     | 
    
         
             
                # element, formats it, and adds it to the buffer.
         
     | 
| 
       94 
     | 
    
         
            -
                def open_tag(name,  
     | 
| 
      
 149 
     | 
    
         
            +
                def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id,
         
     | 
| 
      
 150 
     | 
    
         
            +
                             nuke_outer_whitespace, nuke_inner_whitespace, obj_ref, content, *attributes_hashes)
         
     | 
| 
       95 
151 
     | 
    
         
             
                  tabulation = @real_tabs
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
       97 
153 
     | 
    
         
             
                  attributes = class_id
         
     | 
| 
       98 
154 
     | 
    
         
             
                  attributes_hashes.each do |attributes_hash|
         
     | 
| 
       99 
155 
     | 
    
         
             
                    attributes_hash.keys.each { |key| attributes_hash[key.to_s] = attributes_hash.delete(key) }
         
     | 
| 
         @@ -101,23 +157,21 @@ module Haml 
     | 
|
| 
       101 
157 
     | 
    
         
             
                  end
         
     | 
| 
       102 
158 
     | 
    
         
             
                  self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
         
     | 
| 
       103 
159 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
                  if  
     | 
| 
       105 
     | 
    
         
            -
                    str = "  
     | 
| 
       106 
     | 
    
         
            -
                  elsif try_one_line
         
     | 
| 
       107 
     | 
    
         
            -
                    str = ">"
         
     | 
| 
      
 160 
     | 
    
         
            +
                  if self_closing
         
     | 
| 
      
 161 
     | 
    
         
            +
                    str = " />" + (nuke_outer_whitespace ? "" : "\n")
         
     | 
| 
       108 
162 
     | 
    
         
             
                  else
         
     | 
| 
       109 
     | 
    
         
            -
                    str = " 
     | 
| 
      
 163 
     | 
    
         
            +
                    str = ">" + (try_one_line || preserve_tag || nuke_inner_whitespace ? "" : "\n")
         
     | 
| 
       110 
164 
     | 
    
         
             
                  end
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                  attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  @buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}"
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
       112 
169 
     | 
    
         
             
                  if content
         
     | 
| 
       113 
     | 
    
         
            -
                     
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                    else
         
     | 
| 
       116 
     | 
    
         
            -
                      @buffer << "\n#{tabs(@real_tabs+1)}#{content}\n#{tabs(@real_tabs)}</#{name}>\n"
         
     | 
| 
       117 
     | 
    
         
            -
                    end
         
     | 
| 
       118 
     | 
    
         
            -
                  elsif !atomic
         
     | 
| 
       119 
     | 
    
         
            -
                    @real_tabs += 1
         
     | 
| 
      
 170 
     | 
    
         
            +
                    @buffer << "#{content}</#{name}>" << (nuke_outer_whitespace ? "" : "\n")
         
     | 
| 
      
 171 
     | 
    
         
            +
                    return
         
     | 
| 
       120 
172 
     | 
    
         
             
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                  @real_tabs += 1 unless self_closing || nuke_inner_whitespace
         
     | 
| 
       121 
175 
     | 
    
         
             
                end
         
     | 
| 
       122 
176 
     | 
    
         | 
| 
       123 
177 
     | 
    
         
             
                def self.merge_attrs(to, from)
         
     | 
| 
         @@ -137,33 +191,33 @@ module Haml 
     | 
|
| 
       137 
191 
     | 
    
         
             
                  to.merge!(from)
         
     | 
| 
       138 
192 
     | 
    
         
             
                end
         
     | 
| 
       139 
193 
     | 
    
         | 
| 
      
 194 
     | 
    
         
            +
                private
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
       140 
196 
     | 
    
         
             
                # Some of these methods are exposed as public class methods
         
     | 
| 
       141 
197 
     | 
    
         
             
                # so they can be re-used in helpers.
         
     | 
| 
       142 
198 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
                # Returns whether or not the given value is short enough to be rendered
         
     | 
| 
       144 
     | 
    
         
            -
                # on one line.
         
     | 
| 
       145 
     | 
    
         
            -
                def self.one_liner?(value)
         
     | 
| 
       146 
     | 
    
         
            -
                  value.length <= ONE_LINER_LENGTH && value.scan(/\n/).empty?
         
     | 
| 
       147 
     | 
    
         
            -
                end
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
                private
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
199 
     | 
    
         
             
                @@tab_cache = {}
         
     | 
| 
       152 
200 
     | 
    
         
             
                # Gets <tt>count</tt> tabs. Mostly for internal use.
         
     | 
| 
       153 
     | 
    
         
            -
                def tabs(count)
         
     | 
| 
      
 201 
     | 
    
         
            +
                def tabs(count = 0)
         
     | 
| 
       154 
202 
     | 
    
         
             
                  tabs = count + @tabulation
         
     | 
| 
       155 
     | 
    
         
            -
                  '  ' * tabs
         
     | 
| 
       156 
203 
     | 
    
         
             
                  @@tab_cache[tabs] ||= '  ' * tabs
         
     | 
| 
       157 
204 
     | 
    
         
             
                end
         
     | 
| 
       158 
205 
     | 
    
         | 
| 
       159 
206 
     | 
    
         
             
                # Takes an array of objects and uses the class and id of the first
         
     | 
| 
       160 
207 
     | 
    
         
             
                # one to create an attributes hash.
         
     | 
| 
      
 208 
     | 
    
         
            +
                # The second object, if present, is used as a prefix,
         
     | 
| 
      
 209 
     | 
    
         
            +
                # just like you can do with dom_id() and dom_class() in Rails
         
     | 
| 
       161 
210 
     | 
    
         
             
                def parse_object_ref(ref)
         
     | 
| 
      
 211 
     | 
    
         
            +
                  prefix = ref[1]
         
     | 
| 
       162 
212 
     | 
    
         
             
                  ref = ref[0]
         
     | 
| 
       163 
213 
     | 
    
         
             
                  # Let's make sure the value isn't nil. If it is, return the default Hash.
         
     | 
| 
       164 
214 
     | 
    
         
             
                  return {} if ref.nil?
         
     | 
| 
       165 
215 
     | 
    
         
             
                  class_name = underscore(ref.class)
         
     | 
| 
       166 
216 
     | 
    
         
             
                  id = "#{class_name}_#{ref.id || 'new'}"
         
     | 
| 
      
 217 
     | 
    
         
            +
                  if prefix
         
     | 
| 
      
 218 
     | 
    
         
            +
                    class_name = "#{ prefix }_#{ class_name}"
         
     | 
| 
      
 219 
     | 
    
         
            +
                    id = "#{ prefix }_#{ id }"
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
       167 
221 
     | 
    
         | 
| 
       168 
222 
     | 
    
         
             
                  {'id' => id, 'class' => class_name}
         
     | 
| 
       169 
223 
     | 
    
         
             
                end
         
     | 
    
        data/lib/haml/engine.rb
    CHANGED
    
    | 
         @@ -3,7 +3,6 @@ require 'haml/buffer' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'haml/precompiler'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'haml/filters'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'haml/error'
         
     | 
| 
       6 
     | 
    
         
            -
            require 'haml/util'
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         
             
            module Haml
         
     | 
| 
       9 
8 
     | 
    
         
             
              # This is the class where all the parsing and processing of the Haml
         
     | 
| 
         @@ -24,57 +23,75 @@ module Haml 
     | 
|
| 
       24 
23 
     | 
    
         
             
                # to produce the Haml document.
         
     | 
| 
       25 
24 
     | 
    
         
             
                attr :precompiled, true
         
     | 
| 
       26 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
                # True if the format is XHTML
         
     | 
| 
      
 27 
     | 
    
         
            +
                def xhtml?
         
     | 
| 
      
 28 
     | 
    
         
            +
                  not html?
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # True if the format is any flavor of HTML
         
     | 
| 
      
 32 
     | 
    
         
            +
                def html?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  html4? or html5?
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # True if the format is HTML4
         
     | 
| 
      
 37 
     | 
    
         
            +
                def html4?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @options[:format] == :html4
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                # True if the format is HTML5
         
     | 
| 
      
 42 
     | 
    
         
            +
                def html5?
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @options[:format] == :html5
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       27 
46 
     | 
    
         
             
                # Creates a new instace of Haml::Engine that will compile the given
         
     | 
| 
       28 
47 
     | 
    
         
             
                # template string when <tt>render</tt> is called.
         
     | 
| 
       29 
     | 
    
         
            -
                # See README for available options.
         
     | 
| 
      
 48 
     | 
    
         
            +
                # See README.rdoc for available options.
         
     | 
| 
       30 
49 
     | 
    
         
             
                #
         
     | 
| 
       31 
50 
     | 
    
         
             
                #--
         
     | 
| 
       32 
51 
     | 
    
         
             
                # When adding options, remember to add information about them
         
     | 
| 
       33 
     | 
    
         
            -
                # to README!
         
     | 
| 
      
 52 
     | 
    
         
            +
                # to README.rdoc!
         
     | 
| 
       34 
53 
     | 
    
         
             
                #++
         
     | 
| 
       35 
54 
     | 
    
         
             
                #
         
     | 
| 
       36 
55 
     | 
    
         
             
                def initialize(template, options = {})
         
     | 
| 
       37 
56 
     | 
    
         
             
                  @options = {
         
     | 
| 
       38 
57 
     | 
    
         
             
                    :suppress_eval => false,
         
     | 
| 
       39 
58 
     | 
    
         
             
                    :attr_wrapper => "'",
         
     | 
| 
       40 
     | 
    
         
            -
                    :autoclose => ['meta', 'img', 'link', 'br', 'hr', 'input', 'area'],
         
     | 
| 
       41 
     | 
    
         
            -
                    :filters => {
         
     | 
| 
       42 
     | 
    
         
            -
                      'sass' => Sass::Engine,
         
     | 
| 
       43 
     | 
    
         
            -
                      'plain' => Haml::Filters::Plain,
         
     | 
| 
       44 
     | 
    
         
            -
                      'preserve' => Haml::Filters::Preserve,
         
     | 
| 
       45 
     | 
    
         
            -
                      'redcloth' => Haml::Filters::RedCloth,
         
     | 
| 
       46 
     | 
    
         
            -
                      'textile' => Haml::Filters::Textile,
         
     | 
| 
       47 
     | 
    
         
            -
                      'markdown' => Haml::Filters::Markdown },
         
     | 
| 
       48 
     | 
    
         
            -
                    :filename => '(haml)'
         
     | 
| 
       49 
     | 
    
         
            -
                  }
         
     | 
| 
       50 
     | 
    
         
            -
                  @options.rec_merge! options
         
     | 
| 
       51 
59 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                     
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                      'ruby' => Haml::Filters::Ruby
         
     | 
| 
       56 
     | 
    
         
            -
                    })
         
     | 
| 
       57 
     | 
    
         
            -
                  end
         
     | 
| 
       58 
     | 
    
         
            -
                  @options[:filters].rec_merge! options[:filters] if options[:filters]
         
     | 
| 
      
 60 
     | 
    
         
            +
                    # Don't forget to update the docs in lib/haml.rb if you update these
         
     | 
| 
      
 61 
     | 
    
         
            +
                    :autoclose => %w[meta img link br hr input area param col base],
         
     | 
| 
      
 62 
     | 
    
         
            +
                    :preserve => %w[textarea pre],
         
     | 
| 
       59 
63 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                     
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
      
 64 
     | 
    
         
            +
                    :filename => '(haml)',
         
     | 
| 
      
 65 
     | 
    
         
            +
                    :line => 1,
         
     | 
| 
      
 66 
     | 
    
         
            +
                    :ugly => false,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    :format => :xhtml,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    :escape_html => false
         
     | 
| 
      
 69 
     | 
    
         
            +
                  }
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @options.merge! options
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  unless [:xhtml, :html4, :html5].include?(@options[:format])
         
     | 
| 
      
 73 
     | 
    
         
            +
                    raise Haml::Error, "Invalid format #{@options[:format].inspect}"
         
     | 
| 
       66 
74 
     | 
    
         
             
                  end
         
     | 
| 
       67 
75 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                  @template = template. 
     | 
| 
      
 76 
     | 
    
         
            +
                  @template = template.rstrip #String
         
     | 
| 
       69 
77 
     | 
    
         
             
                  @to_close_stack = []
         
     | 
| 
       70 
78 
     | 
    
         
             
                  @output_tabs = 0
         
     | 
| 
       71 
79 
     | 
    
         
             
                  @template_tabs = 0
         
     | 
| 
       72 
80 
     | 
    
         
             
                  @index = 0
         
     | 
| 
       73 
81 
     | 
    
         
             
                  @flat_spaces = -1
         
     | 
| 
      
 82 
     | 
    
         
            +
                  @newlines = 0
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  if @options[:filters]
         
     | 
| 
      
 85 
     | 
    
         
            +
                    warn <<END
         
     | 
| 
      
 86 
     | 
    
         
            +
            DEPRECATION WARNING:
         
     | 
| 
      
 87 
     | 
    
         
            +
            The Haml :filters option is deprecated and will be removed in version 2.1.
         
     | 
| 
      
 88 
     | 
    
         
            +
            Filters are now automatically registered.
         
     | 
| 
      
 89 
     | 
    
         
            +
            END
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
       74 
91 
     | 
    
         | 
| 
       75 
92 
     | 
    
         
             
                  precompile
         
     | 
| 
       76 
93 
     | 
    
         
             
                rescue Haml::Error
         
     | 
| 
       77 
     | 
    
         
            -
                  $!.backtrace.unshift "#{@options[:filename]}:#{@index}"
         
     | 
| 
      
 94 
     | 
    
         
            +
                  $!.backtrace.unshift "#{@options[:filename]}:#{@index + $!.line_offset + @options[:line] - 1}" if @index
         
     | 
| 
       78 
95 
     | 
    
         
             
                  raise
         
     | 
| 
       79 
96 
     | 
    
         
             
                end
         
     | 
| 
       80 
97 
     | 
    
         | 
| 
         @@ -84,7 +101,7 @@ END 
     | 
|
| 
       84 
101 
     | 
    
         
             
                # If it's a Binding or Proc object,
         
     | 
| 
       85 
102 
     | 
    
         
             
                # Haml uses it as the second argument to Kernel#eval;
         
     | 
| 
       86 
103 
     | 
    
         
             
                # otherwise, Haml just uses its #instance_eval context.
         
     | 
| 
       87 
     | 
    
         
            -
                # 
     | 
| 
      
 104 
     | 
    
         
            +
                #
         
     | 
| 
       88 
105 
     | 
    
         
             
                # Note that Haml modifies the evaluation context
         
     | 
| 
       89 
106 
     | 
    
         
             
                # (either the scope object or the "self" object of the scope binding).
         
     | 
| 
       90 
107 
     | 
    
         
             
                # It extends Haml::Helpers, and various instance variables are set
         
     | 
| 
         @@ -114,8 +131,7 @@ END 
     | 
|
| 
       114 
131 
     | 
    
         
             
                # but if you're relying on local variables defined in the context of scope,
         
     | 
| 
       115 
132 
     | 
    
         
             
                # they won't work.
         
     | 
| 
       116 
133 
     | 
    
         
             
                def render(scope = Object.new, locals = {}, &block)
         
     | 
| 
       117 
     | 
    
         
            -
                   
     | 
| 
       118 
     | 
    
         
            -
                  buffer = Haml::Buffer.new(options_for_buffer)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
         
     | 
| 
       119 
135 
     | 
    
         | 
| 
       120 
136 
     | 
    
         
             
                  if scope.is_a?(Binding) || scope.is_a?(Proc)
         
     | 
| 
       121 
137 
     | 
    
         
             
                    scope_object = eval("self", scope)
         
     | 
| 
         @@ -129,17 +145,14 @@ END 
     | 
|
| 
       129 
145 
     | 
    
         | 
| 
       130 
146 
     | 
    
         
             
                  scope_object.instance_eval do
         
     | 
| 
       131 
147 
     | 
    
         
             
                    extend Haml::Helpers
         
     | 
| 
       132 
     | 
    
         
            -
                    @ 
     | 
| 
       133 
     | 
    
         
            -
                    @haml_stack.push(buffer)
         
     | 
| 
       134 
     | 
    
         
            -
                    @haml_is_haml = true
         
     | 
| 
      
 148 
     | 
    
         
            +
                    @haml_buffer = buffer
         
     | 
| 
       135 
149 
     | 
    
         
             
                  end
         
     | 
| 
       136 
150 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
                  eval(@precompiled, scope, @options[:filename],  
     | 
| 
      
 151 
     | 
    
         
            +
                  eval(@precompiled, scope, @options[:filename], @options[:line])
         
     | 
| 
       138 
152 
     | 
    
         | 
| 
       139 
153 
     | 
    
         
             
                  # Get rid of the current buffer
         
     | 
| 
       140 
154 
     | 
    
         
             
                  scope_object.instance_eval do
         
     | 
| 
       141 
     | 
    
         
            -
                    @ 
     | 
| 
       142 
     | 
    
         
            -
                    @haml_is_haml = false
         
     | 
| 
      
 155 
     | 
    
         
            +
                    @haml_buffer = buffer.upper
         
     | 
| 
       143 
156 
     | 
    
         
             
                  end
         
     | 
| 
       144 
157 
     | 
    
         | 
| 
       145 
158 
     | 
    
         
             
                  buffer.buffer
         
     | 
| 
         @@ -176,7 +189,7 @@ END 
     | 
|
| 
       176 
189 
     | 
    
         
             
                  end
         
     | 
| 
       177 
190 
     | 
    
         | 
| 
       178 
191 
     | 
    
         
             
                  eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
         
     | 
| 
       179 
     | 
    
         
            -
                       precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename],  
     | 
| 
      
 192 
     | 
    
         
            +
                       precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
         
     | 
| 
       180 
193 
     | 
    
         
             
                end
         
     | 
| 
       181 
194 
     | 
    
         | 
| 
       182 
195 
     | 
    
         
             
                # Defines a method on +object+
         
     | 
| 
         @@ -193,7 +206,7 @@ END 
     | 
|
| 
       193 
206 
     | 
    
         
             
                #
         
     | 
| 
       194 
207 
     | 
    
         
             
                #   Haml::Engine.new(".upcased= upcase").def_method(String, :upcased_div)
         
     | 
| 
       195 
208 
     | 
    
         
             
                #   "foobar".upcased_div #=> "<div class='upcased'>FOOBAR</div>\n"
         
     | 
| 
       196 
     | 
    
         
            -
                # 
     | 
| 
      
 209 
     | 
    
         
            +
                #
         
     | 
| 
       197 
210 
     | 
    
         
             
                # The first argument of the defined method is a hash of local variable names to values.
         
     | 
| 
       198 
211 
     | 
    
         
             
                # However, due to an unfortunate Ruby quirk,
         
     | 
| 
       199 
212 
     | 
    
         
             
                # the local variables which can be assigned must be pre-declared.
         
     | 
| 
         @@ -209,7 +222,7 @@ END 
     | 
|
| 
       209 
222 
     | 
    
         
             
                #   obj = Object.new
         
     | 
| 
       210 
223 
     | 
    
         
             
                #   Haml::Engine.new("%p= foo").def_method(obj, :render)
         
     | 
| 
       211 
224 
     | 
    
         
             
                #   obj.render(:foo => "Hello!") #=> NameError: undefined local variable or method `foo'
         
     | 
| 
       212 
     | 
    
         
            -
                # 
     | 
| 
      
 225 
     | 
    
         
            +
                #
         
     | 
| 
       213 
226 
     | 
    
         
             
                # Note that Haml modifies the evaluation context
         
     | 
| 
       214 
227 
     | 
    
         
             
                # (either the scope object or the "self" object of the scope binding).
         
     | 
| 
       215 
228 
     | 
    
         
             
                # It extends Haml::Helpers, and various instance variables are set
         
     | 
| 
         @@ -218,7 +231,7 @@ END 
     | 
|
| 
       218 
231 
     | 
    
         
             
                  method = object.is_a?(Module) ? :module_eval : :instance_eval
         
     | 
| 
       219 
232 
     | 
    
         | 
| 
       220 
233 
     | 
    
         
             
                  object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
         
     | 
| 
       221 
     | 
    
         
            -
                              @options[:filename],  
     | 
| 
      
 234 
     | 
    
         
            +
                              @options[:filename], @options[:line])
         
     | 
| 
       222 
235 
     | 
    
         
             
                end
         
     | 
| 
       223 
236 
     | 
    
         | 
| 
       224 
237 
     | 
    
         
             
                private
         
     | 
| 
         @@ -230,9 +243,15 @@ END 
     | 
|
| 
       230 
243 
     | 
    
         
             
                end
         
     | 
| 
       231 
244 
     | 
    
         | 
| 
       232 
245 
     | 
    
         
             
                # Returns a hash of options that Haml::Buffer cares about.
         
     | 
| 
       233 
     | 
    
         
            -
                # This should remain loadable  
     | 
| 
      
 246 
     | 
    
         
            +
                # This should remain loadable from #inspect.
         
     | 
| 
       234 
247 
     | 
    
         
             
                def options_for_buffer
         
     | 
| 
       235 
     | 
    
         
            -
                  { 
     | 
| 
      
 248 
     | 
    
         
            +
                  {
         
     | 
| 
      
 249 
     | 
    
         
            +
                    :autoclose => @options[:autoclose],
         
     | 
| 
      
 250 
     | 
    
         
            +
                    :preserve => @options[:preserve],
         
     | 
| 
      
 251 
     | 
    
         
            +
                    :attr_wrapper => @options[:attr_wrapper],
         
     | 
| 
      
 252 
     | 
    
         
            +
                    :ugly => @options[:ugly],
         
     | 
| 
      
 253 
     | 
    
         
            +
                    :format => @options[:format]
         
     | 
| 
      
 254 
     | 
    
         
            +
                  }
         
     | 
| 
       236 
255 
     | 
    
         
             
                end
         
     | 
| 
       237 
256 
     | 
    
         
             
              end
         
     | 
| 
       238 
257 
     | 
    
         
             
            end
         
     |