Class Haml::Buffer
In: lib/haml/buffer.rb
lib/haml/template/plugin.rb
Parent: Object

This class is used only internally. It holds the buffer of HTML that is eventually output as the resulting document. It‘s called from within the precompiled code, and helps reduce the amount of processing done within `instance_eval`ed code.

Methods

Included Modules

Haml::Helpers Haml::Util

Attributes

active  [W]  @return [Boolean] @see active?
buffer  [RW]  The string that holds the compiled HTML. This is aliased as `_erbout` for compatibility with ERB-specific code.

@return [String]

capture_position  [RW]  nil if there‘s no capture_haml block running, and the position at which it‘s beginning the capture if there is one.

@return [Fixnum, nil]

options  [RW]  The options hash passed in from {Haml::Engine}.

@return [{String => Object}] @see Haml::Engine#options_for_buffer

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?}).

@return [Buffer]

Public Class methods

Merges two attribute hashes. This is the same as `to.merge!(from)`, except that it merges id, class, and data attributes.

ids are concatenated with `"_"`, and classes are concatenated with `" "`. data hashes are simply merged.

Destructively modifies both `to` and `from`.

@param to [{String => String}] The attribute hash to merge into @param from [{String => to_s}] The attribute hash to merge from @return [{String => String}] `to`, after being merged

[Source]

     # File lib/haml/buffer.rb, line 248
248:     def self.merge_attrs(to, from)
249:       from['id'] = Precompiler.filter_and_join(from['id'], '_') if from['id']
250:       if to['id'] && from['id']
251:         to['id'] << '_' << from.delete('id').to_s
252:       elsif to['id'] || from['id']
253:         from['id'] ||= to['id']
254:       end
255: 
256:       from['class'] = Precompiler.filter_and_join(from['class'], ' ') if from['class']
257:       if to['class'] && from['class']
258:         # Make sure we don't duplicate class names
259:         from['class'] = (from['class'].to_s.split(' ') | to['class'].split(' ')).sort.join(' ')
260:       elsif to['class'] || from['class']
261:         from['class'] ||= to['class']
262:       end
263: 
264:       from_data = from['data'].is_a?(Hash)
265:       to_data = to['data'].is_a?(Hash)
266:       if from_data && to_data
267:         to['data'] = to['data'].merge(from['data'])
268:       elsif to_data
269:         to = Haml::Util.map_keys(to.delete('data')) {|name| "data-#{name}"}.merge(to)
270:       elsif from_data
271:         from = Haml::Util.map_keys(from.delete('data')) {|name| "data-#{name}"}.merge(from)
272:       end
273: 
274:       to.merge!(from)
275:     end

@param upper [Buffer] The parent buffer @param options [{Symbol => Object}] An options hash.

  See {Haml::Engine#options\_for\_buffer}

[Source]

     # File lib/haml/buffer.rb, line 90
 90:     def initialize(upper = nil, options = {})
 91:       @active = true
 92:       @upper = upper
 93:       @options = options
 94:       @buffer = ruby1_8? ? "" : "".encode(Encoding.find(options[:encoding]))
 95:       @tabulation = 0
 96: 
 97:       # The number of tabs that Engine thinks we should have
 98:       # @real_tabs + @tabulation is the number of tabs actually output
 99:       @real_tabs = 0
100:     end

Public Instance methods

Whether or not this buffer is currently being used to render a Haml template. Returns `false` if a subtemplate is being rendered, even if it‘s a subtemplate of this buffer‘s template.

@return [Boolean]

[Source]

    # File lib/haml/buffer.rb, line 70
70:     def active?
71:       @active
72:     end

Modifies the indentation of the document.

@param tab_change [Fixnum] The number of tabs by which to increase

  or decrease the document's indentation

[Source]

     # File lib/haml/buffer.rb, line 126
126:     def adjust_tabs(tab_change)
127:       @real_tabs += tab_change
128:     end

[Source]

    # File lib/haml/template/plugin.rb, line 62
62:       def append_if_string=(value)
63:         if value.is_a?(String) && !value.is_a?(ActionView::NonConcattingString)
64:           ActiveSupport::Deprecation.warn("- style block helpers are deprecated. Please use =", caller)
65:           buffer << value
66:         end
67:       end

@return [Boolean] Whether or not the format is HTML4

[Source]

    # File lib/haml/buffer.rb, line 50
50:     def html4?
51:       @options[:format] == :html4
52:     end

@return [Boolean] Whether or not the format is HTML5.

[Source]

    # File lib/haml/buffer.rb, line 55
55:     def html5?
56:       @options[:format] == :html5
57:     end

@return [Boolean] Whether or not the format is any flavor of HTML

[Source]

    # File lib/haml/buffer.rb, line 45
45:     def html?
46:       html4? or html5?
47:     end

Takes the various information about the opening tag for an element, formats it, and appends it to the buffer.

[Source]

     # File lib/haml/buffer.rb, line 193
193:     def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id,
194:                  nuke_outer_whitespace, nuke_inner_whitespace, obj_ref, content, *attributes_hashes)
195:       tabulation = @real_tabs
196: 
197:       attributes = class_id
198:       attributes_hashes.each do |old|
199:         self.class.merge_attrs(attributes, to_hash(old.map {|k, v| [k.to_s, v]}))
200:       end
201:       self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
202: 
203:       if self_closing && xhtml?
204:         str = " />" + (nuke_outer_whitespace ? "" : "\n")
205:       else
206:         str = ">" + ((if self_closing && html?
207:                         nuke_outer_whitespace
208:                       else
209:                         try_one_line || preserve_tag || nuke_inner_whitespace
210:                       end) ? "" : "\n")
211:       end
212: 
213:       attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
214:       @buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}"
215: 
216:       if content
217:         @buffer << "#{content}</#{name}>" << (nuke_outer_whitespace ? "" : "\n")
218:         return
219:       end
220: 
221:       @real_tabs += 1 unless self_closing || nuke_inner_whitespace
222:     end

Appends text to the buffer, properly tabulated. Also modifies the document‘s indentation.

@param text [String] The text to append @param tab_change [Fixnum] The number of tabs by which to increase

  or decrease the document's indentation

@param dont_tab_up [Boolean] If true, don‘t indent the first line of `text`

[Source]

     # File lib/haml/buffer.rb, line 109
109:     def push_text(text, tab_change, dont_tab_up)
110:       if @tabulation > 0
111:         # Have to push every line in by the extra user set tabulation.
112:         # Don't push lines with just whitespace, though,
113:         # because that screws up precompiled indentation.
114:         text.gsub!(/^(?!\s+$)/m, tabs)
115:         text.sub!(tabs, '') if dont_tab_up
116:       end
117: 
118:       @buffer << text
119:       @real_tabs += tab_change
120:     end

Remove the whitespace from the right side of the buffer string. Doesn‘t do anything if we‘re at the beginning of a capture_haml block.

[Source]

     # File lib/haml/buffer.rb, line 226
226:     def rstrip!
227:       if capture_position.nil?
228:         buffer.rstrip!
229:         return
230:       end
231: 
232:       buffer << buffer.slice!(capture_position..-1).rstrip
233:     end

@return [Fixnum] The current indentation level of the document

[Source]

    # File lib/haml/buffer.rb, line 75
75:     def tabulation
76:       @real_tabs + @tabulation
77:     end

Sets the current tabulation of the document.

@param val [Fixnum] The new tabulation

[Source]

    # File lib/haml/buffer.rb, line 82
82:     def tabulation=(val)
83:       val = val - @real_tabs
84:       @tabulation = val > -1 ? val : 0
85:     end

@return [Boolean] Whether or not this buffer is a top-level template,

  as opposed to a nested partial

[Source]

    # File lib/haml/buffer.rb, line 61
61:     def toplevel?
62:       upper.nil?
63:     end

@return [Boolean] Whether or not the format is XHTML

[Source]

    # File lib/haml/buffer.rb, line 40
40:     def xhtml?
41:       not html?
42:     end

Private Instance methods

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

[Source]

     # File lib/haml/buffer.rb, line 290
290:     def parse_object_ref(ref)
291:       prefix = ref[1]
292:       ref = ref[0]
293:       # Let's make sure the value isn't nil. If it is, return the default Hash.
294:       return {} if ref.nil?
295:       class_name =
296:         if ref.respond_to?(:haml_object_ref)
297:           ref.haml_object_ref
298:         else
299:           underscore(ref.class)
300:         end
301:       id = "#{class_name}_#{ref.id || 'new'}"
302:       if prefix
303:         class_name = "#{ prefix }_#{ class_name}"
304:         id = "#{ prefix }_#{ id }"
305:       end
306: 
307:       {'id' => id, 'class' => class_name}
308:     end

Gets `count` tabs. Mostly for internal use.

[Source]

     # File lib/haml/buffer.rb, line 281
281:     def tabs(count = 0)
282:       tabs = [count + @tabulation, 0].max
283:       @@tab_cache[tabs] ||= '  ' * tabs
284:     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.

[Source]

     # File lib/haml/buffer.rb, line 313
313:     def underscore(camel_cased_word)
314:       camel_cased_word.to_s.gsub(/::/, '_').
315:         gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
316:         gsub(/([a-z\d])([A-Z])/,'\1_\2').
317:         tr("-", "_").
318:         downcase
319:     end

[Validate]