| Class | Haml::Buffer |
| In: |
lib/haml/buffer.rb
|
| Parent: | Object |
This class is used only internally. It holds the buffer of XHTML that is eventually output by Haml::Engine‘s to_html method. It‘s called from within the precompiled code, and helps reduce the amount of processing done within instance_eval‘d code.
| active | [W] | See active? |
| buffer | [RW] | The string that holds the compiled XHTML. This is aliased as _erbout for compatibility with ERB-specific code. |
| options | [RW] | The options hash passed in from Haml::Engine. |
| upper | [RW] | The Buffer for the enclosing Haml document. This is set for partials and similar sorts of nested templates. It‘s nil at the top level (see toplevel?). |
# File lib/haml/buffer.rb, line 181
181: def self.merge_attrs(to, from)
182: if to['id'] && from['id']
183: to['id'] << '_' << from.delete('id')
184: elsif to['id'] || from['id']
185: from['id'] ||= to['id']
186: end
187:
188: if to['class'] && from['class']
189: # Make sure we don't duplicate class names
190: from['class'] = (from['class'].split(' ') | to['class'].split(' ')).join(' ')
191: elsif to['class'] || from['class']
192: from['class'] ||= to['class']
193: end
194:
195: to.merge!(from)
196: end
Creates a new buffer.
# File lib/haml/buffer.rb, line 69
69: def initialize(upper = nil, options = {})
70: @active = true
71: @upper = upper
72: @options = {
73: :attr_wrapper => "'",
74: :ugly => false,
75: :format => :xhtml
76: }.merge options
77: @buffer = ""
78: @tabulation = 0
79:
80: # The number of tabs that Engine thinks we should have
81: # @real_tabs + @tabulation is the number of tabs actually output
82: @real_tabs = 0
83: end
True if the format is HTML4
# File lib/haml/buffer.rb, line 35
35: def html4?
36: @options[:format] == :html4
37: end
True if the format is HTML5
# File lib/haml/buffer.rb, line 40
40: def html5?
41: @options[:format] == :html5
42: end
Takes the various information about the opening tag for an element, formats it, and adds it to the buffer.
# File lib/haml/buffer.rb, line 150
150: def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id,
151: nuke_outer_whitespace, nuke_inner_whitespace, obj_ref, content, *attributes_hashes)
152: tabulation = @real_tabs
153:
154: attributes = class_id
155: attributes_hashes.each do |old|
156: self.class.merge_attrs(attributes, old.inject({}) {|h, (key, val)| h[key.to_s] = val; h})
157: end
158: self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
159:
160: if self_closing && xhtml?
161: str = " />" + (nuke_outer_whitespace ? "" : "\n")
162: else
163: str = ">" + ((if self_closing && html?
164: nuke_outer_whitespace
165: else
166: try_one_line || preserve_tag || nuke_inner_whitespace
167: end) ? "" : "\n")
168: end
169:
170: attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
171: @buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}"
172:
173: if content
174: @buffer << "#{content}</#{name}>" << (nuke_outer_whitespace ? "" : "\n")
175: return
176: end
177:
178: @real_tabs += 1 unless self_closing || nuke_inner_whitespace
179: end
Properly formats the output of a script that was run in the instance_eval.
# File lib/haml/buffer.rb, line 103
103: def push_script(result, preserve_script, in_tag = false, preserve_tag = false,
104: escape_html = false, nuke_inner_whitespace = false)
105: tabulation = @real_tabs
106:
107: result = result.to_s.rstrip
108: result = result.lstrip if nuke_inner_whitespace
109: result = html_escape(result) if escape_html
110:
111: if preserve_tag
112: result = Haml::Helpers.preserve(result)
113: elsif preserve_script
114: result = Haml::Helpers.find_and_preserve(result, options[:preserve])
115: end
116:
117: has_newline = result.include?("\n")
118: if in_tag && !nuke_inner_whitespace && (@options[:ugly] || !has_newline || preserve_tag)
119: @buffer << result
120: @real_tabs -= 1
121: return
122: end
123:
124: @buffer << "\n" if in_tag && !nuke_inner_whitespace
125:
126: # Precompiled tabulation may be wrong
127: if @tabulation > 0 && !in_tag
128: result = tabs + result
129: end
130:
131: if has_newline && !@options[:ugly]
132: result = result.gsub "\n", "\n" + tabs(tabulation)
133:
134: # Add tabulation if it wasn't precompiled
135: result = tabs(tabulation) + result if in_tag && !nuke_inner_whitespace
136: end
137: @buffer << "#{result}"
138: @buffer << "\n" unless nuke_inner_whitespace
139:
140: if in_tag && !nuke_inner_whitespace
141: # We never get here if @options[:ugly] is true
142: @buffer << tabs(tabulation-1)
143: @real_tabs -= 1
144: end
145: nil
146: end
Renders text with the proper tabulation. This also deals with making a possible one-line tag one line or not.
# File lib/haml/buffer.rb, line 87
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
94: end
95:
96: @buffer << text
97: @real_tabs += tab_change
98: @dont_tab_up_next_line = false
99: end
Gets the current tabulation of the document.
# File lib/haml/buffer.rb, line 58
58: def tabulation
59: @real_tabs + @tabulation
60: end
Sets the current tabulation of the document.
# File lib/haml/buffer.rb, line 63
63: def tabulation=(val)
64: val = val - @real_tabs
65: @tabulation = val > -1 ? val : 0
66: end
True if this buffer is a top-level template, as opposed to a nested partial.
# File lib/haml/buffer.rb, line 46
46: def toplevel?
47: upper.nil?
48: end
Takes an array of objects and uses the class and id of the first one to create an attributes hash. The second object, if present, is used as a prefix, just like you can do with dom_id() and dom_class() in Rails
# File lib/haml/buffer.rb, line 214
214: def parse_object_ref(ref)
215: prefix = ref[1]
216: ref = ref[0]
217: # Let's make sure the value isn't nil. If it is, return the default Hash.
218: return {} if ref.nil?
219: class_name = underscore(ref.class)
220: id = "#{class_name}_#{ref.id || 'new'}"
221: if prefix
222: class_name = "#{ prefix }_#{ class_name}"
223: id = "#{ prefix }_#{ id }"
224: end
225:
226: {'id' => id, 'class' => class_name}
227: end
Changes a word from camel case to underscores. Based on the method of the same name in Rails’ Inflector, but copied here so it‘ll run properly without Rails.
# File lib/haml/buffer.rb, line 232
232: def underscore(camel_cased_word)
233: camel_cased_word.to_s.gsub(/::/, '_').
234: gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
235: gsub(/([a-z\d])([A-Z])/,'\1_\2').
236: tr("-", "_").
237: downcase
238: end