# File lib/erector/output.rb, line 9 def initialize(options = {}) @prettyprint = options.fetch(:prettyprint, AbstractWidget.prettyprint_default) @indentation = options.fetch(:indentation, 0) @current_line_length = 0 @max_length = options[:max_length] @widgets = [] @get_buffer = if options[:buffer] and options[:buffer].respond_to? :call options[:buffer] elsif options[:buffer] lambda { options[:buffer] } else buffer = [] lambda { buffer } end end
# File lib/erector/output.rb, line 30 def <<(s) # raise s.inspect unless s.is_a? String # s = s.to_s unless s.is_a? String append_indentation if @max_length && s.length + @current_line_length > @max_length leading_spaces = s =~ /^( +)/ ? $1.size : 0 trailing_spaces = s =~ /( +)$/ ? $1.size : 0 append(" " * leading_spaces) need_space = false words = s.split(/ /) words.each do |word| if (need_space ? 1 : 0) + word.length > space_left append_newline append_indentation need_space = false end append(" ") if need_space append(word) need_space = true end append(" " * trailing_spaces) else append(s) end self end
always append a newline, regardless of prettyprint setting
todo: test
# File lib/erector/output.rb, line 98 def append_newline buffer << "\n" @current_line_length = 0 end
# File lib/erector/output.rb, line 84 def at_line_start? @current_line_length == 0 end
# File lib/erector/output.rb, line 26 def buffer @get_buffer.call end
# File lib/erector/output.rb, line 88 def indent @indentation += 1 if prettyprint end
# File lib/erector/output.rb, line 103 def mark @mark = buffer.size end
# File lib/erector/output.rb, line 78 def newline if prettyprint append_newline end end
Inserts a blank string into the output stream and returns a pointer to it. If the caller holds on to this pointer, she can later go back and insert text earlier in the stream. This is used for, e.g., inserting stuff inside the HEAD element that is not known until after the entire page renders.
# File lib/erector/output.rb, line 64 def placeholder s = "" buffer << s s end
# File lib/erector/output.rb, line 107 def rewind pos = @mark if buffer.kind_of?(Array) buffer.slice!(pos..-1) elsif (Object.const_defined?(:ActiveSupport) and buffer.kind_of?(ActiveSupport::SafeBuffer)) # monkey patch to get around SafeBuffer's well-meaning paranoia # see http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/ # and http://weblog.rubyonrails.org/2011/6/8/potential-xss-vulnerability-in-ruby-on-rails-applications String.instance_method(:slice!).bind(buffer).call(pos..-1) elsif buffer.kind_of?(String) buffer.slice!(pos..-1) else raise "Don't know how to rewind a #{buffer.class}" end end
# File lib/erector/output.rb, line 74 def to_a buffer.kind_of?(Array) ? buffer : [buffer] end
# File lib/erector/output.rb, line 70 def to_s RawString.new(buffer.kind_of?(String) ? buffer : buffer.join) end
# File lib/erector/output.rb, line 92 def undent @indentation -= 1 if prettyprint end
# File lib/erector/output.rb, line 126 def append(s) buffer << s @current_line_length += s.length end
# File lib/erector/output.rb, line 135 def append_indentation if prettyprint and at_line_start? spaces = " " * ([@indentation, 0].max * SPACES_PER_INDENT) buffer << spaces @current_line_length += spaces.length end end
# File lib/erector/output.rb, line 131 def space_left @max_length - @current_line_length end