class Haml::Buffer
processing done within instance_eval’d code.
from within the precompiled code, and helps reduce the amount of
is eventually output by Haml::Engine’s to_html method. It’s called
This class is used only internally. It holds the buffer of XHTML that
def self.merge_attrs(to, from)
def self.merge_attrs(to, from) if to['id'] && from['id'] to['id'] << '_' << from.delete('id') elsif to['id'] || from['id'] from['id'] ||= to['id'] end if to['class'] && from['class'] # Make sure we don't duplicate class names from['class'] = (from['class'].split(' ') | to['class'].split(' ')).join(' ') elsif to['class'] || from['class'] from['class'] ||= to['class'] end to.merge!(from) end
def active?
However, this returns false if a subtemplate is being rendered,
True if this buffer is currently being used to render a Haml template.
def active? @active end
def html4?
def html4? @options[:format] == :html4 end
def html5?
def html5? @options[:format] == :html5 end
def html?
def html? html4? or html5? end
def initialize(upper = nil, options = {})
def initialize(upper = nil, options = {}) @active = true @upper = upper @options = { :attr_wrapper => "'", :ugly => false, :format => :xhtml }.merge options @buffer = "" @tabulation = 0 # The number of tabs that Engine thinks we should have # @real_tabs + @tabulation is the number of tabs actually output @real_tabs = 0 end
def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id,
Takes the various information about the opening tag for an
def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id, nuke_outer_whitespace, nuke_inner_whitespace, obj_ref, content, *attributes_hashes) tabulation = @real_tabs attributes = class_id attributes_hashes.each do |attributes_hash| attributes_hash.keys.each { |key| attributes_hash[key.to_s] = attributes_hash.delete(key) } self.class.merge_attrs(attributes, attributes_hash) end self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref if self_closing str = " />" + (nuke_outer_whitespace ? "" : "\n") else str = ">" + (try_one_line || preserve_tag || nuke_inner_whitespace ? "" : "\n") end attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes) @buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}" if content @buffer << "#{content}</#{name}>" << (nuke_outer_whitespace ? "" : "\n") return end @real_tabs += 1 unless self_closing || nuke_inner_whitespace end
def parse_object_ref(ref)
The second object, if present, is used as a prefix,
one to create an attributes hash.
Takes an array of objects and uses the class and id of the first
def parse_object_ref(ref) prefix = ref[1] ref = ref[0] # Let's make sure the value isn't nil. If it is, return the default Hash. return {} if ref.nil? class_name = underscore(ref.class) id = "#{class_name}_#{ref.id || 'new'}" if prefix class_name = "#{ prefix }_#{ class_name}" id = "#{ prefix }_#{ id }" end {'id' => id, 'class' => class_name} end
def push_script(result, preserve_script, in_tag = false, preserve_tag = false,
Properly formats the output of a script that was run in the
def push_script(result, preserve_script, in_tag = false, preserve_tag = false, escape_html = false, nuke_inner_whitespace = false) tabulation = @real_tabs if preserve_tag result = Haml::Helpers.preserve(result) elsif preserve_script result = Haml::Helpers.find_and_preserve(result, options[:preserve]) end result = result.to_s.rstrip result = html_escape(result) if escape_html has_newline = result.include?("\n") if in_tag && !nuke_inner_whitespace && (@options[:ugly] || !has_newline || preserve_tag) @buffer << result @real_tabs -= 1 return end @buffer << "\n" if in_tag && !nuke_inner_whitespace # Precompiled tabulation may be wrong if @tabulation > 0 && !in_tag result = tabs + result end if has_newline && !@options[:ugly] result = result.gsub "\n", "\n" + tabs(tabulation) # Add tabulation if it wasn't precompiled result = tabs(tabulation) + result if in_tag && !nuke_inner_whitespace end @buffer << "#{result}" @buffer << "\n" unless nuke_inner_whitespace if in_tag && !nuke_inner_whitespace # We never get here if @options[:ugly] is true @buffer << tabs(tabulation-1) @real_tabs -= 1 end nil end
def push_text(text, dont_tab_up = false, tab_change = 0)
Renders +text+ with the proper tabulation. This also deals with
def push_text(text, dont_tab_up = false, tab_change = 0) if @tabulation > 0 && !@options[:ugly] # Have to push every line in by the extra user set tabulation. # Don't push lines with just whitespace, though, # because that screws up precompiled indentation. text.gsub!(/^(?!\s+$)/m, tabs) text.sub!(tabs, '') if dont_tab_up end @buffer << text @real_tabs += tab_change @dont_tab_up_next_line = false end
def tabs(count = 0)
def tabs(count = 0) tabs = [count + @tabulation, 0].max @@tab_cache[tabs] ||= ' ' * tabs end
def tabulation
def tabulation @real_tabs + @tabulation end
def tabulation=(val)
def tabulation=(val) val = val - @real_tabs @tabulation = val > -1 ? val : 0 end
def toplevel?
True if this buffer is a top-level template,
def toplevel? upper.nil? end
def underscore(camel_cased_word)
Based on the method of the same name in Rails' Inflector,
Changes a word from camel case to underscores.
def underscore(camel_cased_word) camel_cased_word.to_s.gsub(/::/, '_'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). tr("-", "_"). downcase end
def xhtml?
def xhtml? not html? end