You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by lu...@apache.org on 2010/07/09 01:14:21 UTC
svn commit: r961978 [7/13] - in /incubator/deltacloud/trunk/framework: ./
app/ app/controllers/ app/helpers/ app/models/ app/views/
app/views/accounts/ app/views/credentials/ app/views/images/
app/views/instances/ app/views/layouts/ app/views/root/ con...
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/buffer.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/buffer.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/buffer.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/buffer.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,307 @@
+module Haml
+ # 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.
+ class Buffer
+ include Haml::Helpers
+ include Haml::Util
+
+ # The string that holds the compiled HTML. This is aliased as
+ # `_erbout` for compatibility with ERB-specific code.
+ #
+ # @return [String]
+ attr_accessor :buffer
+
+ # The options hash passed in from {Haml::Engine}.
+ #
+ # @return [Hash<String, Object>]
+ # @see Haml::Engine#options_for_buffer
+ attr_accessor :options
+
+ # 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]
+ attr_accessor :upper
+
+ # 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]
+ attr_accessor :capture_position
+
+ # @return [Boolean]
+ # @see #active?
+ attr_writer :active
+
+ # @return [Boolean] Whether or not the format is XHTML
+ def xhtml?
+ not html?
+ end
+
+ # @return [Boolean] Whether or not the format is any flavor of HTML
+ def html?
+ html4? or html5?
+ end
+
+ # @return [Boolean] Whether or not the format is HTML4
+ def html4?
+ @options[:format] == :html4
+ end
+
+ # @return [Boolean] Whether or not the format is HTML5.
+ def html5?
+ @options[:format] == :html5
+ end
+
+ # @return [Boolean] Whether or not this buffer is a top-level template,
+ # as opposed to a nested partial
+ def toplevel?
+ upper.nil?
+ end
+
+ # 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]
+ def active?
+ @active
+ end
+
+ # @return [Fixnum] The current indentation level of the document
+ def tabulation
+ @real_tabs + @tabulation
+ end
+
+ # Sets the current tabulation of the document.
+ #
+ # @param val [Fixnum] The new tabulation
+ def tabulation=(val)
+ val = val - @real_tabs
+ @tabulation = val > -1 ? val : 0
+ end
+
+ # @param upper [Buffer] The parent buffer
+ # @param options [Hash<Symbol, Object>] An options hash.
+ # See {Haml::Engine#options\_for\_buffer}
+ def initialize(upper = nil, options = {})
+ @active = true
+ @upper = upper
+ @options = options
+ @buffer = ruby1_8? ? "" : "".encode(Encoding.find(options[:encoding]))
+ @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
+
+ # 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`
+ def push_text(text, tab_change, dont_tab_up)
+ if @tabulation > 0
+ # 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
+ 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
+ def adjust_tabs(tab_change)
+ @real_tabs += tab_change
+ end
+
+ Haml::Util.def_static_method(self, :format_script, [:result],
+ :preserve_script, :in_tag, :preserve_tag, :escape_html,
+ :nuke_inner_whitespace, :interpolated, :ugly, <<RUBY)
+ <% unless ugly %>
+ # If we're interpolated,
+ # then the custom tabulation is handled in #push_text.
+ # The easiest way to avoid it here is to reset @tabulation.
+ <% if interpolated %>
+ old_tabulation = @tabulation
+ @tabulation = 0
+ <% end %>
+
+ tabulation = @real_tabs
+ result = result.to_s.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
+ <% else %>
+ result = result.to_s<% if nuke_inner_whitespace %>.strip<% end %>
+ <% end %>
+
+ <% if escape_html %> result = html_escape(result) <% end %>
+
+ <% if preserve_tag %>
+ result = Haml::Helpers.preserve(result)
+ <% elsif preserve_script %>
+ result = Haml::Helpers.find_and_preserve(result, options[:preserve])
+ <% end %>
+
+ <% if ugly %>
+ return result
+ <% else %>
+
+ has_newline = result.include?("\\n")
+ <% if in_tag && !nuke_inner_whitespace %>
+ <% unless preserve_tag %> if !has_newline <% end %>
+ @real_tabs -= 1
+ <% if interpolated %> @tabulation = old_tabulation <% end %>
+ return result
+ <% unless preserve_tag %> end <% end %>
+ <% end %>
+
+ # Precompiled tabulation may be wrong
+ <% if !interpolated && !in_tag %>
+ result = tabs + result if @tabulation > 0
+ <% end %>
+
+ if has_newline
+ result = result.gsub "\\n", "\\n" + tabs(tabulation)
+
+ # Add tabulation if it wasn't precompiled
+ <% if in_tag && !nuke_inner_whitespace %> result = tabs(tabulation) + result <% end %>
+ end
+
+ <% if in_tag && !nuke_inner_whitespace %>
+ result = "\\n\#{result}\\n\#{tabs(tabulation-1)}"
+ @real_tabs -= 1
+ <% end %>
+ <% if interpolated %> @tabulation = old_tabulation <% end %>
+ result
+ <% end %>
+RUBY
+
+ # Takes the various information about the opening tag for an element,
+ # formats it, and appends it to the buffer.
+ 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 |old|
+ self.class.merge_attrs(attributes, to_hash(old.map {|k, v| [k.to_s, v]}))
+ end
+ self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
+
+ if self_closing && xhtml?
+ str = " />" + (nuke_outer_whitespace ? "" : "\n")
+ else
+ str = ">" + ((if self_closing && html?
+ nuke_outer_whitespace
+ else
+ try_one_line || preserve_tag || nuke_inner_whitespace
+ end) ? "" : "\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
+
+ # 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.
+ def rstrip!
+ if capture_position.nil?
+ buffer.rstrip!
+ return
+ end
+
+ buffer << buffer.slice!(capture_position..-1).rstrip
+ end
+
+ # Merges two attribute hashes.
+ # This is the same as `to.merge!(from)`,
+ # except that it merges id and class attributes.
+ #
+ # ids are concatenated with `"_"`,
+ # and classes are concatenated with `" "`.
+ #
+ # Destructively modifies both `to` and `from`.
+ #
+ # @param to [Hash<String, String>] The attribute hash to merge into
+ # @param from [Hash<String, String>] The attribute hash to merge from
+ # @return [Hash<String, String>] `to`, after being merged
+ 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(' ')).sort.join(' ')
+ elsif to['class'] || from['class']
+ from['class'] ||= to['class']
+ end
+
+ to.merge!(from)
+ end
+
+ private
+
+ @@tab_cache = {}
+ # Gets `count` tabs. Mostly for internal use.
+ def tabs(count = 0)
+ tabs = [count + @tabulation, 0].max
+ @@tab_cache[tabs] ||= ' ' * tabs
+ 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
+ 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 =
+ if ref.respond_to?(:haml_object_ref)
+ ref.haml_object_ref
+ else
+ underscore(ref.class)
+ end
+ id = "#{class_name}_#{ref.id || 'new'}"
+ if prefix
+ class_name = "#{ prefix }_#{ class_name}"
+ id = "#{ prefix }_#{ id }"
+ end
+
+ {'id' => id, 'class' => class_name}
+ 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.
+ 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
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/engine.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/engine.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/engine.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/engine.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,297 @@
+require 'haml/helpers'
+require 'haml/buffer'
+require 'haml/precompiler'
+require 'haml/filters'
+require 'haml/error'
+
+module Haml
+ # This is the frontend for using Haml programmatically.
+ # It can be directly used by the user by creating a
+ # new instance and calling \{#render} to render the template.
+ # For example:
+ #
+ # template = File.read('templates/really_cool_template.haml')
+ # haml_engine = Haml::Engine.new(template)
+ # output = haml_engine.render
+ # puts output
+ class Engine
+ include Precompiler
+
+ # The options hash.
+ # See {file:HAML_REFERENCE.md#haml_options the Haml options documentation}.
+ #
+ # @return [Hash<Symbol, Object>]
+ attr_accessor :options
+
+ # The indentation used in the Haml document,
+ # or `nil` if the indentation is ambiguous
+ # (for example, for a single-level document).
+ #
+ # @return [String]
+ attr_accessor :indentation
+
+ # @return [Boolean] Whether or not the format is XHTML.
+ def xhtml?
+ not html?
+ end
+
+ # @return [Boolean] Whether or not the format is any flavor of HTML.
+ def html?
+ html4? or html5?
+ end
+
+ # @return [Boolean] Whether or not the format is HTML4.
+ def html4?
+ @options[:format] == :html4
+ end
+
+ # @return [Boolean] Whether or not the format is HTML5.
+ def html5?
+ @options[:format] == :html5
+ end
+
+ # The source code that is evaluated to produce the Haml document.
+ #
+ # In Ruby 1.9, this is automatically converted to the correct encoding
+ # (see {file:HAML_REFERENCE.md#encoding-option the `:encoding` option}).
+ #
+ # @return [String]
+ def precompiled
+ return @precompiled if ruby1_8?
+ return @precompiled.encode(Encoding.find(@options[:encoding]))
+ end
+
+ # Precompiles the Haml template.
+ #
+ # @param template [String] The Haml template
+ # @param options [Hash<Symbol, Object>] An options hash;
+ # see {file:HAML_REFERENCE.md#haml_options the Haml options documentation}
+ # @raise [Haml::Error] if there's a Haml syntax error in the template
+ def initialize(template, options = {})
+ @options = {
+ :suppress_eval => false,
+ :attr_wrapper => "'",
+
+ # Don't forget to update the docs in lib/haml.rb if you update these
+ :autoclose => %w[meta img link br hr input area param col base],
+ :preserve => %w[textarea pre],
+
+ :filename => '(haml)',
+ :line => 1,
+ :ugly => false,
+ :format => :xhtml,
+ :escape_html => false,
+ }
+ unless ruby1_8?
+ @options[:encoding] = Encoding.default_internal || "utf-8"
+ end
+ @options.merge! options
+ @index = 0
+
+ unless [:xhtml, :html4, :html5].include?(@options[:format])
+ raise Haml::Error, "Invalid format #{@options[:format].inspect}"
+ end
+
+ if @options[:encoding] && @options[:encoding].is_a?(Encoding)
+ @options[:encoding] = @options[:encoding].name
+ end
+
+ # :eod is a special end-of-document marker
+ @template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
+ @template_index = 0
+ @to_close_stack = []
+ @output_tabs = 0
+ @template_tabs = 0
+ @flat = false
+ @newlines = 0
+ @precompiled = ''
+ @to_merge = []
+ @tab_change = 0
+ @temp_count = 0
+
+ precompile
+ rescue Haml::Error => e
+ e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}" if @index
+ raise
+ end
+
+ # Processes the template and returns the result as a string.
+ #
+ # `scope` is the context in which the template is evaluated.
+ # If it's a `Binding` or `Proc` object,
+ # Haml uses it as the second argument to `Kernel#eval`;
+ # otherwise, Haml just uses its `#instance_eval` context.
+ #
+ # Note that Haml modifies the evaluation context
+ # (either the scope object or the `self` object of the scope binding).
+ # It extends {Haml::Helpers}, and various instance variables are set
+ # (all prefixed with `haml_`).
+ # For example:
+ #
+ # s = "foobar"
+ # Haml::Engine.new("%p= upcase").render(s) #=> "<p>FOOBAR</p>"
+ #
+ # # s now extends Haml::Helpers
+ # s.responds_to?(:html_attrs) #=> true
+ #
+ # `locals` is a hash of local variables to make available to the template.
+ # For example:
+ #
+ # Haml::Engine.new("%p= foo").render(Object.new, :foo => "Hello, world!") #=> "<p>Hello, world!</p>"
+ #
+ # If a block is passed to render,
+ # that block is run when `yield` is called
+ # within the template.
+ #
+ # Due to some Ruby quirks,
+ # if `scope` is a `Binding` or `Proc` object and a block is given,
+ # the evaluation context may not be quite what the user expects.
+ # In particular, it's equivalent to passing `eval("self", scope)` as `scope`.
+ # This won't have an effect in most cases,
+ # but if you're relying on local variables defined in the context of `scope`,
+ # they won't work.
+ #
+ # @param scope [Binding, Proc, Object] The context in which the template is evaluated
+ # @param locals [Hash<Symbol, Object>] Local variables that will be made available
+ # to the template
+ # @param block [#to_proc] A block that can be yielded to within the template
+ # @return [String] The rendered template
+ def render(scope = Object.new, locals = {}, &block)
+ buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
+
+ if scope.is_a?(Binding) || scope.is_a?(Proc)
+ scope_object = eval("self", scope)
+ scope = scope_object.instance_eval{binding} if block_given?
+ else
+ scope_object = scope
+ scope = scope_object.instance_eval{binding}
+ end
+
+ set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
+
+ scope_object.instance_eval do
+ extend Haml::Helpers
+ @haml_buffer = buffer
+ end
+
+ eval(precompiled, scope, @options[:filename], @options[:line])
+
+ # Get rid of the current buffer
+ scope_object.instance_eval do
+ @haml_buffer = buffer.upper
+ end
+
+ buffer.buffer
+ end
+ alias_method :to_html, :render
+
+ # Returns a proc that, when called,
+ # renders the template and returns the result as a string.
+ #
+ # `scope` works the same as it does for render.
+ #
+ # The first argument of the returned proc is a hash of local variable names to values.
+ # However, due to an unfortunate Ruby quirk,
+ # the local variables which can be assigned must be pre-declared.
+ # This is done with the `local_names` argument.
+ # For example:
+ #
+ # # This works
+ # Haml::Engine.new("%p= foo").render_proc(Object.new, :foo).call :foo => "Hello!"
+ # #=> "<p>Hello!</p>"
+ #
+ # # This doesn't
+ # Haml::Engine.new("%p= foo").render_proc.call :foo => "Hello!"
+ # #=> NameError: undefined local variable or method `foo'
+ #
+ # The proc doesn't take a block; any yields in the template will fail.
+ #
+ # @param scope [Binding, Proc, Object] The context in which the template is evaluated
+ # @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
+ # @return [Proc] The proc that will run the template
+ def render_proc(scope = Object.new, *local_names)
+ if scope.is_a?(Binding) || scope.is_a?(Proc)
+ scope_object = eval("self", scope)
+ else
+ scope_object = scope
+ scope = scope_object.instance_eval{binding}
+ end
+
+ eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
+ precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
+ end
+
+ # Defines a method on `object` with the given name
+ # that renders the template and returns the result as a string.
+ #
+ # If `object` is a class or module,
+ # the method will instead by defined as an instance method.
+ # For example:
+ #
+ # t = Time.now
+ # Haml::Engine.new("%p\n Today's date is\n .date= self.to_s").def_method(t, :render)
+ # t.render #=> "<p>\n Today's date is\n <div class='date'>Fri Nov 23 18:28:29 -0800 2007</div>\n</p>\n"
+ #
+ # Haml::Engine.new(".upcased= upcase").def_method(String, :upcased_div)
+ # "foobar".upcased_div #=> "<div class='upcased'>FOOBAR</div>\n"
+ #
+ # The first argument of the defined method is a hash of local variable names to values.
+ # However, due to an unfortunate Ruby quirk,
+ # the local variables which can be assigned must be pre-declared.
+ # This is done with the `local_names` argument.
+ # For example:
+ #
+ # # This works
+ # obj = Object.new
+ # Haml::Engine.new("%p= foo").def_method(obj, :render, :foo)
+ # obj.render(:foo => "Hello!") #=> "<p>Hello!</p>"
+ #
+ # # This doesn't
+ # obj = Object.new
+ # Haml::Engine.new("%p= foo").def_method(obj, :render)
+ # obj.render(:foo => "Hello!") #=> NameError: undefined local variable or method `foo'
+ #
+ # Note that Haml modifies the evaluation context
+ # (either the scope object or the `self` object of the scope binding).
+ # It extends {Haml::Helpers}, and various instance variables are set
+ # (all prefixed with `haml_`).
+ #
+ # @param object [Object, Module] The object on which to define the method
+ # @param name [String, Symbol] The name of the method to define
+ # @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
+ def def_method(object, name, *local_names)
+ method = object.is_a?(Module) ? :module_eval : :instance_eval
+
+ object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
+ @options[:filename], @options[:line])
+ end
+
+ protected
+
+ # Returns a subset of \{#options}: those that {Haml::Buffer} cares about.
+ # All of the values here are such that when `#inspect` is called on the hash,
+ # it can be `Kernel#eval`ed to get the same result back.
+ #
+ # See {file:HAML_REFERENCE.md#haml_options the Haml options documentation}.
+ #
+ # @return [Hash<Symbol, Object>] The options hash
+ def options_for_buffer
+ {
+ :autoclose => @options[:autoclose],
+ :preserve => @options[:preserve],
+ :attr_wrapper => @options[:attr_wrapper],
+ :ugly => @options[:ugly],
+ :format => @options[:format],
+ :encoding => @options[:encoding],
+ }
+ end
+
+ private
+
+ def set_locals(locals, scope, scope_object)
+ scope_object.send(:instance_variable_set, '@_haml_locals', locals)
+ set_locals = locals.keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
+ eval(set_locals, scope)
+ end
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/error.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/error.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/error.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/error.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,22 @@
+module Haml
+ # An exception raised by Haml code.
+ class Error < StandardError
+ # The line of the template on which the error occurred.
+ #
+ # @return [Fixnum]
+ attr_reader :line
+
+ # @param message [String] The error message
+ # @param line [Fixnum] See \{#line}
+ def initialize(message = nil, line = nil)
+ super(message)
+ @line = line
+ end
+ end
+
+ # SyntaxError is the type of exception raised when Haml encounters an
+ # ill-formatted document.
+ # It's not particularly interesting,
+ # except in that it's a subclass of {Haml::Error}.
+ class SyntaxError < Haml::Error; end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/exec.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/exec.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/exec.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/exec.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,459 @@
+require 'optparse'
+require 'fileutils'
+
+module Haml
+ # This module handles the various Haml executables (`haml`, `sass`, `css2sass`, etc).
+ module Exec
+ # An abstract class that encapsulates the executable code for all three executables.
+ class Generic
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ @args = args
+ @options = {}
+ end
+
+ # Parses the command-line arguments and runs the executable.
+ # Calls `Kernel#exit` at the end, so it never returns.
+ def parse!
+ begin
+ @opts = OptionParser.new(&method(:set_opts))
+ @opts.parse!(@args)
+
+ process_result
+
+ @options
+ rescue Exception => e
+ raise e if @options[:trace] || e.is_a?(SystemExit)
+
+ $stderr.puts e.message
+ exit 1
+ end
+ exit 0
+ end
+
+ # @return [String] A description of the executable
+ def to_s
+ @opts.to_s
+ end
+
+ protected
+
+ # Finds the line of the source template
+ # on which an exception was raised.
+ #
+ # @param exception [Exception] The exception
+ # @return [String] The line number
+ def get_line(exception)
+ # SyntaxErrors have weird line reporting
+ # when there's trailing whitespace,
+ # which there is for Haml documents.
+ return exception.message.scan(/:(\d+)/).first.first if exception.is_a?(::SyntaxError)
+ exception.backtrace[0].scan(/:(\d+)/).first.first
+ end
+
+ # Tells optparse how to parse the arguments
+ # available for all executables.
+ #
+ # This is meant to be overridden by subclasses
+ # so they can add their own options.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ opts.on('-s', '--stdin', :NONE, 'Read input from standard input instead of an input file') do
+ @options[:input] = $stdin
+ end
+
+ opts.on('--trace', :NONE, 'Show a full traceback on error') do
+ @options[:trace] = true
+ end
+
+ opts.on_tail("-?", "-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
+
+ opts.on_tail("-v", "--version", "Print version") do
+ puts("Haml #{::Haml.version[:string]}")
+ exit
+ end
+ end
+
+ # Processes the options set by the command-line arguments.
+ # In particular, sets `@options[:input]` and `@options[:output]`
+ # to appropriate IO streams.
+ #
+ # This is meant to be overridden by subclasses
+ # so they can run their respective programs.
+ def process_result
+ input, output = @options[:input], @options[:output]
+ input_file, output_file = if input
+ [nil, open_file(@args[0], 'w')]
+ else
+ @options[:filename] = @args[0]
+ [open_file(@args[0]), open_file(@args[1], 'w')]
+ end
+
+ input ||= input_file
+ output ||= output_file
+ input ||= $stdin
+ output ||= $stdout
+
+ @options[:input], @options[:output] = input, output
+ end
+
+ private
+
+ def open_file(filename, flag = 'r')
+ return if filename.nil?
+ File.open(filename, flag)
+ end
+ end
+
+ # An abstrac class that encapsulates the code
+ # specific to the `haml` and `sass` executables.
+ class HamlSass < Generic
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ super
+ @options[:for_engine] = {}
+ end
+
+ protected
+
+ # Tells optparse how to parse the arguments
+ # available for the `haml` and `sass` executables.
+ #
+ # This is meant to be overridden by subclasses
+ # so they can add their own options.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ opts.banner = <<END
+Usage: #{@name.downcase} [options] [INPUT] [OUTPUT]
+
+Description:
+ Uses the #{@name} engine to parse the specified template
+ and outputs the result to the specified file.
+
+Options:
+END
+
+ opts.on('--rails RAILS_DIR', "Install Haml and Sass from the Gem to a Rails project") do |dir|
+ original_dir = dir
+
+ dir = File.join(dir, 'vendor', 'plugins')
+
+ unless File.exists?(dir)
+ puts "Directory #{dir} doesn't exist"
+ exit
+ end
+
+ dir = File.join(dir, 'haml')
+
+ if File.exists?(dir)
+ print "Directory #{dir} already exists, overwrite [y/N]? "
+ exit if gets !~ /y/i
+ FileUtils.rm_rf(dir)
+ end
+
+ begin
+ Dir.mkdir(dir)
+ rescue SystemCallError
+ puts "Cannot create #{dir}"
+ exit
+ end
+
+ File.open(File.join(dir, 'init.rb'), 'w') do |file|
+ file.puts "require 'rubygems'"
+ file << File.read(File.dirname(__FILE__) + "/../../init.rb")
+ end
+
+ puts "Haml plugin added to #{original_dir}"
+ exit
+ end
+
+ opts.on('-c', '--check', "Just check syntax, don't evaluate.") do
+ require 'stringio'
+ @options[:check_syntax] = true
+ @options[:output] = StringIO.new
+ end
+
+ super
+ end
+
+ # Processes the options set by the command-line arguments.
+ # In particular, sets `@options[:for_engine][:filename]` to the input filename
+ # and requires the appropriate file.
+ #
+ # This is meant to be overridden by subclasses
+ # so they can run their respective programs.
+ def process_result
+ super
+ @options[:for_engine][:filename] = @options[:filename] if @options[:filename]
+ require File.dirname(__FILE__) + "/../#{@name.downcase}"
+ end
+ end
+
+ # The `sass` executable.
+ class Sass < HamlSass
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ super
+ @name = "Sass"
+ @options[:for_engine][:load_paths] = ['.'] + (ENV['SASSPATH'] || '').split(File::PATH_SEPARATOR)
+ end
+
+ protected
+
+ # Tells optparse how to parse the arguments.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ super
+
+ opts.on('-t', '--style NAME',
+ 'Output style. Can be nested (default), compact, compressed, or expanded.') do |name|
+ @options[:for_engine][:style] = name.to_sym
+ end
+ opts.on('-l', '--line-comments',
+ 'Line Comments. Emit comments in the generated CSS indicating the corresponding sass line.') do
+ @options[:for_engine][:line_comments] = true
+ end
+ opts.on('-i', '--interactive',
+ 'Run an interactive SassScript shell.') do
+ @options[:interactive] = true
+ end
+ opts.on('-I', '--load-path PATH', 'Add a sass import path.') do |path|
+ @options[:for_engine][:load_paths] << path
+ end
+ opts.on('--cache-location', 'The path to put cached Sass files. Defaults to .sass-cache.') do |loc|
+ @options[:for_engine][:cache_location] = path
+ end
+ opts.on('-C', '--no-cache', "Don't cache to sassc files.") do
+ @options[:for_engine][:cache] = false
+ end
+ end
+
+ # Processes the options set by the command-line arguments,
+ # and runs the Sass compiler appropriately.
+ def process_result
+ if @options[:interactive]
+ require 'sass'
+ require 'sass/repl'
+ ::Sass::Repl.new(@options).run
+ return
+ end
+
+ super
+ input = @options[:input]
+ output = @options[:output]
+
+ tree =
+ if input.is_a?(File) && !@options[:check_syntax]
+ ::Sass::Files.tree_for(input.path, @options[:for_engine])
+ else
+ # We don't need to do any special handling of @options[:check_syntax] here,
+ # because the Sass syntax checking happens alongside evaluation
+ # and evaluation doesn't actually evaluate any code anyway.
+ ::Sass::Engine.new(input.read(), @options[:for_engine]).to_tree
+ end
+
+ input.close() if input.is_a?(File)
+
+ output.write(tree.render)
+ output.close() if output.is_a? File
+ rescue ::Sass::SyntaxError => e
+ raise e if @options[:trace]
+ raise "Syntax error on line #{get_line e}: #{e.message}"
+ end
+ end
+
+ # The `haml` executable.
+ class Haml < HamlSass
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ super
+ @name = "Haml"
+ @options[:requires] = []
+ @options[:load_paths] = []
+ end
+
+ # Tells optparse how to parse the arguments.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ super
+
+ opts.on('-t', '--style NAME',
+ 'Output style. Can be indented (default) or ugly.') do |name|
+ @options[:for_engine][:ugly] = true if name.to_sym == :ugly
+ end
+
+ opts.on('-f', '--format NAME',
+ 'Output format. Can be xhtml (default), html4, or html5.') do |name|
+ @options[:for_engine][:format] = name.to_sym
+ end
+
+ opts.on('-e', '--escape-html',
+ 'Escape HTML characters (like ampersands and angle brackets) by default.') do
+ @options[:for_engine][:escape_html] = true
+ end
+
+ opts.on('-r', '--require FILE', "Same as 'ruby -r'.") do |file|
+ @options[:requires] << file
+ end
+
+ opts.on('-I', '--load-path PATH', "Same as 'ruby -I'.") do |path|
+ @options[:load_paths] << path
+ end
+
+ opts.on('--debug', "Print out the precompiled Ruby source.") do
+ @options[:debug] = true
+ end
+ end
+
+ # Processes the options set by the command-line arguments,
+ # and runs the Haml compiler appropriately.
+ def process_result
+ super
+ input = @options[:input]
+ output = @options[:output]
+
+ template = input.read()
+ input.close() if input.is_a? File
+
+ begin
+ engine = ::Haml::Engine.new(template, @options[:for_engine])
+ if @options[:check_syntax]
+ puts "Syntax OK"
+ return
+ end
+
+ @options[:load_paths].each {|p| $LOAD_PATH << p}
+ @options[:requires].each {|f| require f}
+
+ if @options[:debug]
+ puts engine.precompiled
+ puts '=' * 100
+ end
+
+ result = engine.to_html
+ rescue Exception => e
+ raise e if @options[:trace]
+
+ case e
+ when ::Haml::SyntaxError; raise "Syntax error on line #{get_line e}: #{e.message}"
+ when ::Haml::Error; raise "Haml error on line #{get_line e}: #{e.message}"
+ else raise "Exception on line #{get_line e}: #{e.message}\n Use --trace for backtrace."
+ end
+ end
+
+ output.write(result)
+ output.close() if output.is_a? File
+ end
+ end
+
+ # The `html2haml` executable.
+ class HTML2Haml < Generic
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ super
+
+ @module_opts = {}
+
+ begin
+ require 'haml/html'
+ rescue LoadError => err
+ dep = err.message.scan(/^no such file to load -- (.*)/)[0]
+ puts "Required dependency #{dep} not found!"
+ exit 1
+ end
+ end
+
+ # Tells optparse how to parse the arguments.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ opts.banner = <<END
+Usage: html2haml [options] [INPUT] [OUTPUT]
+
+Description: Transforms an HTML file into corresponding Haml code.
+
+Options:
+END
+
+ opts.on('-r', '--rhtml', 'Parse RHTML tags.') do
+ @module_opts[:rhtml] = true
+ end
+
+ opts.on('--no-rhtml', "Don't parse RHTML tags.") do
+ @options[:no_rhtml] = true
+ end
+
+ opts.on('-x', '--xhtml', 'Parse the input using the more strict XHTML parser.') do
+ @module_opts[:xhtml] = true
+ end
+
+ super
+ end
+
+ # Processes the options set by the command-line arguments,
+ # and runs the HTML compiler appropriately.
+ def process_result
+ super
+
+ input = @options[:input]
+ output = @options[:output]
+
+ @module_opts[:rhtml] ||= input.respond_to?(:path) && input.path =~ /\.(rhtml|erb)$/
+ @module_opts[:rhtml] &&= @options[:no_rhtml] != false
+
+ output.write(::Haml::HTML.new(input, @module_opts).render)
+ end
+ end
+
+ # The `css2sass` executable.
+ class CSS2Sass < Generic
+ # @param args [Array<String>] The command-line arguments
+ def initialize(args)
+ super
+
+ @module_opts = {}
+
+ require 'sass/css'
+ end
+
+ # Tells optparse how to parse the arguments.
+ #
+ # @param opts [OptionParser]
+ def set_opts(opts)
+ opts.banner = <<END
+Usage: css2sass [options] [INPUT] [OUTPUT]
+
+Description: Transforms a CSS file into corresponding Sass code.
+
+Options:
+END
+
+ opts.on('--old', 'Output the old-style ":prop val" property syntax') do
+ @module_opts[:old] = true
+ end
+
+ opts.on_tail('-a', '--alternate', 'Ignored') {}
+
+ super
+ end
+
+ # Processes the options set by the command-line arguments,
+ # and runs the CSS compiler appropriately.
+ def process_result
+ super
+
+ input = @options[:input]
+ output = @options[:output]
+
+ output.write(::Sass::CSS.new(input, @module_opts).render)
+ end
+ end
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/filters.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/filters.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/filters.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/filters.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,341 @@
+module Haml
+ # The module containing the default Haml filters,
+ # as well as the base module, {Haml::Filters::Base}.
+ #
+ # @see Haml::Filters::Base
+ module Filters
+ # @return [Hash<String, Haml::Filters::Base>] a hash of filter names to classes
+ def self.defined
+ @defined ||= {}
+ end
+
+ # The base module for Haml filters.
+ # User-defined filters should be modules including this module.
+ # The name of the filter is taken by downcasing the module name.
+ # For instance, if the module is named `FooBar`, the filter will be `:foobar`.
+ #
+ # A user-defined filter should override either \{#render} or {\#compile}.
+ # \{#render} is the most common.
+ # It takes a string, the filter source,
+ # and returns another string, the result of the filter.
+ # For example, the following will define a filter named `:sass`:
+ #
+ # module Haml::Filters::Sass
+ # include Haml::Filters::Base
+ #
+ # def render(text)
+ # ::Sass::Engine.new(text).render
+ # end
+ # end
+ #
+ # For details on overriding \{#compile}, see its documentation.
+ #
+ # Note that filters overriding \{#render} automatically support `#{}`
+ # for interpolating Ruby code.
+ # Those overriding \{#compile} will need to add such support manually
+ # if it's desired.
+ module Base
+ # This method is automatically called when {Base} is included in a module.
+ # It automatically defines a filter
+ # with the downcased name of that module.
+ # For example, if the module is named `FooBar`, the filter will be `:foobar`.
+ #
+ # @param base [Module, Class] The module that this is included in
+ def self.included(base)
+ Filters.defined[base.name.split("::").last.downcase] = base
+ base.extend(base)
+ end
+
+ # Takes the source text that should be passed to the filter
+ # and returns the result of running the filter on that string.
+ #
+ # This should be overridden in most individual filter modules
+ # to render text with the given filter.
+ # If \{#compile} is overridden, however, \{#render} doesn't need to be.
+ #
+ # @param text [String] The source text for the filter to process
+ # @return [String] The filtered result
+ # @raise [Haml::Error] if it's not overridden
+ def render(text)
+ raise Error.new("#{self.inspect}#render not defined!")
+ end
+
+ # Same as \{#render}, but takes a {Haml::Engine} options hash as well.
+ # It's only safe to rely on options made available in {Haml::Engine#options\_for\_buffer}.
+ #
+ # @see #render
+ # @param text [String] The source text for the filter to process
+ # @return [String] The filtered result
+ # @raise [Haml::Error] if it or \{#render} isn't overridden
+ def render_with_options(text, options)
+ render(text)
+ end
+
+ # Same as \{#compile}, but requires the necessary files first.
+ # *This is used by {Haml::Engine} and is not intended to be overridden or used elsewhere.*
+ #
+ # @see #compile
+ def internal_compile(*args)
+ resolve_lazy_requires
+ compile(*args)
+ end
+
+ # This should be overridden when a filter needs to have access to the Haml evaluation context.
+ # Rather than applying a filter to a string at compile-time,
+ # \{#compile} uses the {Haml::Precompiler} instance to compile the string to Ruby code
+ # that will be executed in the context of the active Haml template.
+ #
+ # Warning: the {Haml::Precompiler} interface is neither well-documented
+ # nor guaranteed to be stable.
+ # If you want to make use of it, you'll probably need to look at the source code
+ # and should test your filter when upgrading to new Haml versions.
+ #
+ # @param precompiler [Haml::Precompiler] The precompiler instance
+ # @param text [String] The text of the filter
+ # @raise [Haml::Error] if none of \{#compile}, \{#render}, and \{#render_with_options} are overridden
+ def compile(precompiler, text)
+ resolve_lazy_requires
+ filter = self
+ precompiler.instance_eval do
+ if contains_interpolation?(text)
+ return if options[:suppress_eval]
+
+ push_script <<RUBY, :escape_html => false
+find_and_preserve(#{filter.inspect}.render_with_options(#{unescape_interpolation(text)}, _hamlout.options))
+RUBY
+ return
+ end
+
+ rendered = Haml::Helpers::find_and_preserve(filter.render_with_options(text, precompiler.options), precompiler.options[:preserve])
+
+ if !options[:ugly]
+ push_text(rendered.rstrip.gsub("\n", "\n#{' ' * @output_tabs}"))
+ else
+ push_text(rendered.rstrip)
+ end
+ end
+ end
+
+ # This becomes a class method of modules that include {Base}.
+ # It allows the module to specify one or more Ruby files
+ # that Haml should try to require when compiling the filter.
+ #
+ # The first file specified is tried first, then the second, etc.
+ # If none are found, the compilation throws an exception.
+ #
+ # For example:
+ #
+ # module Haml::Filters::Markdown
+ # lazy_require 'rdiscount', 'peg_markdown', 'maruku', 'bluecloth'
+ #
+ # ...
+ # end
+ #
+ # @param reqs [Array<String>] The requires to run
+ def lazy_require(*reqs)
+ @lazy_requires = reqs
+ end
+
+ private
+
+ def resolve_lazy_requires
+ return unless @lazy_requires
+
+ @lazy_requires[0...-1].each do |req|
+ begin
+ @required = req
+ require @required
+ return
+ rescue LoadError; end # RCov doesn't see this, but it is run
+ end
+
+ begin
+ @required = @lazy_requires[-1]
+ require @required
+ rescue LoadError => e
+ classname = self.name.match(/\w+$/)[0]
+
+ if @lazy_requires.size == 1
+ raise Error.new("Can't run #{classname} filter; required file '#{@lazy_requires.first}' not found")
+ else
+ raise Error.new("Can't run #{classname} filter; required #{@lazy_requires.map { |r| "'#{r}'" }.join(' or ')}, but none were found")
+ end
+ end
+ end
+ end
+ end
+end
+
+begin
+ require 'rubygems'
+rescue LoadError; end
+
+module Haml
+ module Filters
+ # Does not parse the filtered text.
+ # This is useful for large blocks of text without HTML tags,
+ # when you don't want lines starting with `.` or `-`
+ # to be parsed.
+ module Plain
+ include Base
+
+ # @see Base#render
+ def render(text); text; end
+ end
+
+ # Surrounds the filtered text with `<script>` and CDATA tags.
+ # Useful for including inline Javascript.
+ module Javascript
+ include Base
+
+ # @see Base#render_with_options
+ def render_with_options(text, options)
+ <<END
+<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>
+ //<![CDATA[
+ #{text.rstrip.gsub("\n", "\n ")}
+ //]]>
+</script>
+END
+ end
+ end
+
+ # Surrounds the filtered text with CDATA tags.
+ module Cdata
+ include Base
+
+ # @see Base#render
+ def render(text)
+ "<![CDATA[#{("\n" + text).rstrip.gsub("\n", "\n ")}\n]]>"
+ end
+ end
+
+ # Works the same as {Plain}, but HTML-escapes the text
+ # before placing it in the document.
+ module Escaped
+ include Base
+
+ # @see Base#render
+ def render(text)
+ Haml::Helpers.html_escape text
+ end
+ end
+
+ # Parses the filtered text with the normal Ruby interpreter.
+ # All output sent to `$stdout`, such as with `puts`,
+ # is output into the Haml document.
+ # Not available if the {file:HAML_REFERENCE.md#suppress_eval-option `:suppress_eval`} option is set to true.
+ # The Ruby code is evaluated in the same context as the Haml template.
+ module Ruby
+ include Base
+ lazy_require 'stringio'
+
+ # @see Base#compile
+ def compile(precompiler, text)
+ return if precompiler.options[:suppress_eval]
+ precompiler.instance_eval do
+ push_silent <<-FIRST.gsub("\n", ';') + text + <<-LAST.gsub("\n", ';')
+ _haml_old_stdout = $stdout
+ $stdout = StringIO.new(_hamlout.buffer, 'a')
+ FIRST
+ _haml_old_stdout, $stdout = $stdout, _haml_old_stdout
+ _haml_old_stdout.close
+ LAST
+ end
+ end
+ end
+
+ # Inserts the filtered text into the template with whitespace preserved.
+ # `preserve`d blocks of text aren't indented,
+ # and newlines are replaced with the HTML escape code for newlines,
+ # to preserve nice-looking output.
+ #
+ # @see Haml::Helpers#preserve
+ module Preserve
+ include Base
+
+ # @see Base#render
+ def render(text)
+ Haml::Helpers.preserve text
+ end
+ end
+
+ # Parses the filtered text with {Sass} to produce CSS output.
+ module Sass
+ include Base
+ lazy_require 'sass/plugin'
+
+ # @see Base#render
+ def render(text)
+ ::Sass::Engine.new(text, ::Sass::Plugin.engine_options).render
+ end
+ end
+
+ # Parses the filtered text with ERB, like an RHTML template.
+ # Not available if the {file:HAML_REFERENCE.md#suppress_eval-option `:suppress_eval`} option is set to true.
+ # Embedded Ruby code is evaluated in the same context as the Haml template.
+ module ERB
+ include Base
+ lazy_require 'erb'
+
+ # @see Base#compile
+ def compile(precompiler, text)
+ return if precompiler.options[:suppress_eval]
+ src = ::ERB.new(text).src.sub(/^#coding:.*?\n/, '').
+ sub(/^_erbout = '';/, "").gsub("\n", ';')
+ precompiler.send(:push_silent, src)
+ end
+ end
+
+ # Parses the filtered text with [Textile](http://www.textism.com/tools/textile).
+ # Only works if [RedCloth](http://redcloth.org) is installed.
+ module Textile
+ include Base
+ lazy_require 'redcloth'
+
+ # @see Base#render
+ def render(text)
+ ::RedCloth.new(text).to_html(:textile)
+ end
+ end
+ RedCloth = Textile
+ Filters.defined['redcloth'] = RedCloth
+
+ # Parses the filtered text with [Markdown](http://daringfireball.net/projects/markdown).
+ # Only works if [RDiscount](http://github.com/rtomayko/rdiscount),
+ # [RPeg-Markdown](http://github.com/rtomayko/rpeg-markdown),
+ # [Maruku](http://maruku.rubyforge.org),
+ # or [BlueCloth](www.deveiate.org/projects/BlueCloth) are installed.
+ module Markdown
+ include Base
+ lazy_require 'rdiscount', 'peg_markdown', 'maruku', 'bluecloth'
+
+ # @see Base#render
+ def render(text)
+ engine = case @required
+ when 'rdiscount'
+ ::RDiscount
+ when 'peg_markdown'
+ ::PEGMarkdown
+ when 'maruku'
+ ::Maruku
+ when 'bluecloth'
+ ::BlueCloth
+ end
+ engine.new(text).to_html
+ end
+ end
+
+ # Parses the filtered text with [Maruku](http://maruku.rubyforge.org),
+ # which has some non-standard extensions to Markdown.
+ module Maruku
+ include Base
+ lazy_require 'maruku'
+
+ # @see Base#render
+ def render(text)
+ ::Maruku.new(text).to_html
+ end
+ end
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,560 @@
+if defined?(ActionView)
+ require 'haml/helpers/action_view_mods'
+ require 'haml/helpers/action_view_extensions'
+end
+
+module Haml
+ # This module contains various helpful methods to make it easier to do various tasks.
+ # {Haml::Helpers} is automatically included in the context
+ # that a Haml template is parsed in, so all these methods are at your
+ # disposal from within the template.
+ module Helpers
+ # An object that raises an error when \{#to\_s} is called.
+ # It's used to raise an error when the return value of a helper is used
+ # when it shouldn't be.
+ class ErrorReturn
+ # @param message [String] The error message to raise when \{#to\_s} is called
+ def initialize(method)
+ @message = <<MESSAGE
+#{method} outputs directly to the Haml template.
+Disregard its return value and use the - operator,
+or use capture_haml to get the value as a String.
+MESSAGE
+ end
+
+ # Raises an error.
+ #
+ # @raise [Haml::Error] The error
+ def to_s
+ raise Haml::Error.new(@message)
+ rescue Haml::Error => e
+ e.backtrace.shift
+
+ # If the ErrorReturn is used directly in the template,
+ # we don't want Haml's stuff to get into the backtrace,
+ # so we get rid of the format_script line.
+ #
+ # We also have to subtract one from the Haml line number
+ # since the value is passed to format_script the line after
+ # it's actually used.
+ if e.backtrace.first =~ /^\(eval\):\d+:in `format_script/
+ e.backtrace.shift
+ e.backtrace.first.gsub!(/^\(haml\):(\d+)/) {|s| "(haml):#{$1.to_i - 1}"}
+ end
+ raise e
+ end
+
+ # @return [String] A human-readable string representation
+ def inspect
+ "Haml::Helpers::ErrorReturn(#{@message.inspect})"
+ end
+ end
+
+ self.extend self
+
+ @@action_view_defined = defined?(ActionView)
+ @@force_no_action_view = false
+
+ # @return [Boolean] Whether or not ActionView is loaded
+ def self.action_view?
+ @@action_view_defined
+ end
+
+ # Note: this does **not** need to be called when using Haml helpers
+ # normally in Rails.
+ #
+ # Initializes the current object as though it were in the same context
+ # as a normal ActionView instance using Haml.
+ # This is useful if you want to use the helpers in a context
+ # other than the normal setup with ActionView.
+ # For example:
+ #
+ # context = Object.new
+ # class << context
+ # include Haml::Helpers
+ # end
+ # context.init_haml_helpers
+ # context.haml_tag :p, "Stuff"
+ #
+ def init_haml_helpers
+ @haml_buffer = Haml::Buffer.new(@haml_buffer, Haml::Engine.new('').send(:options_for_buffer))
+ nil
+ end
+
+ # Runs a block of code in a non-Haml context
+ # (i.e. \{#is\_haml?} will return false).
+ #
+ # This is mainly useful for rendering sub-templates such as partials in a non-Haml language,
+ # particularly where helpers may behave differently when run from Haml.
+ #
+ # Note that this is automatically applied to Rails partials.
+ #
+ # @yield A block which won't register as Haml
+ def non_haml
+ was_active = @haml_buffer.active?
+ @haml_buffer.active = false
+ yield
+ ensure
+ @haml_buffer.active = was_active
+ end
+
+ # Uses \{#preserve} to convert any newlines inside whitespace-sensitive tags
+ # into the HTML entities for endlines.
+ #
+ # @param tags [Array<String>] Tags that should have newlines escaped
+ #
+ # @overload find_and_preserve(input, tags = haml_buffer.options[:preserve])
+ # Escapes newlines within a string.
+ #
+ # @param input [String] The string within which to escape newlines
+ # @overload find_and_preserve(tags = haml_buffer.options[:preserve])
+ # Escapes newlines within a block of Haml code.
+ #
+ # @yield The block within which to escape newlines
+ def find_and_preserve(input = nil, tags = haml_buffer.options[:preserve], &block)
+ return find_and_preserve(capture_haml(&block), input || tags) if block
+
+ input = input.to_s
+ input.gsub(/<(#{tags.map(&Regexp.method(:escape)).join('|')})([^>]*)>(.*?)(<\/\1>)/im) do
+ "<#{$1}#{$2}>#{preserve($3)}</#{$1}>"
+ end
+ end
+
+ # Takes any string, finds all the newlines, and converts them to
+ # HTML entities so they'll render correctly in
+ # whitespace-sensitive tags without screwing up the indentation.
+ #
+ # @overload perserve(input)
+ # Escapes newlines within a string.
+ #
+ # @param input [String] The string within which to escape all newlines
+ # @overload perserve
+ # Escapes newlines within a block of Haml code.
+ #
+ # @yield The block within which to escape newlines
+ def preserve(input = '', &block)
+ return preserve(capture_haml(&block)) if block
+
+ input.chomp("\n").gsub(/\n/, '
').gsub(/\r/, '')
+ end
+ alias_method :flatten, :preserve
+
+ # Takes an `Enumerable` object and a block
+ # and iterates over the enum,
+ # yielding each element to a Haml block
+ # and putting the result into `<li>` elements.
+ # This creates a list of the results of the block.
+ # For example:
+ #
+ # = list_of([['hello'], ['yall']]) do |i|
+ # = i[0]
+ #
+ # Produces:
+ #
+ # <li>hello</li>
+ # <li>yall</li>
+ #
+ # And
+ #
+ # = list_of({:title => 'All the stuff', :description => 'A book about all the stuff.'}) do |key, val|
+ # %h3= key.humanize
+ # %p= val
+ #
+ # Produces:
+ #
+ # <li>
+ # <h3>Title</h3>
+ # <p>All the stuff</p>
+ # </li>
+ # <li>
+ # <h3>Description</h3>
+ # <p>A book about all the stuff.</p>
+ # </li>
+ #
+ # @param enum [Enumerable] The list of objects to iterate over
+ # @yield [item] A block which contains Haml code that goes within list items
+ # @yieldparam item An element of `enum`
+ def list_of(enum, &block)
+ to_return = enum.collect do |i|
+ result = capture_haml(i, &block)
+
+ if result.count("\n") > 1
+ result.gsub!("\n", "\n ")
+ result = "\n #{result.strip}\n"
+ else
+ result.strip!
+ end
+
+ "<li>#{result}</li>"
+ end
+ to_return.join("\n")
+ end
+
+ # Returns a hash containing default assignments for the `xmlns`, `lang`, and `xml:lang`
+ # attributes of the `html` HTML element.
+ # For example,
+ #
+ # %html{html_attrs}
+ #
+ # becomes
+ #
+ # <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US' lang='en-US'>
+ #
+ # @param lang [String] The value of `xml:lang` and `lang`
+ # @return [Hash<#to_s, String>] The attribute hash
+ def html_attrs(lang = 'en-US')
+ {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang}
+ end
+
+ # Increments the number of tabs the buffer automatically adds
+ # to the lines of the template.
+ # For example:
+ #
+ # %h1 foo
+ # - tab_up
+ # %p bar
+ # - tab_down
+ # %strong baz
+ #
+ # Produces:
+ #
+ # <h1>foo</h1>
+ # <p>bar</p>
+ # <strong>baz</strong>
+ #
+ # @param i [Fixnum] The number of tabs by which to increase the indentation
+ # @see #tab_down
+ def tab_up(i = 1)
+ haml_buffer.tabulation += i
+ end
+
+ # Decrements the number of tabs the buffer automatically adds
+ # to the lines of the template.
+ #
+ # @param i [Fixnum] The number of tabs by which to decrease the indentation
+ # @see #tab_up
+ def tab_down(i = 1)
+ haml_buffer.tabulation -= i
+ end
+
+ # Surrounds a block of Haml code with strings,
+ # with no whitespace in between.
+ # For example:
+ #
+ # = surround '(', ')' do
+ # %a{:href => "food"} chicken
+ #
+ # Produces:
+ #
+ # (<a href='food'>chicken</a>)
+ #
+ # and
+ #
+ # = surround '*' do
+ # %strong angry
+ #
+ # Produces:
+ #
+ # *<strong>angry</strong>*
+ #
+ # @param front [String] The string to add before the Haml
+ # @param back [String] The string to add after the Haml
+ # @yield A block of Haml to surround
+ def surround(front, back = front, &block)
+ output = capture_haml(&block)
+
+ "#{front}#{output.chomp}#{back}\n"
+ end
+
+ # Prepends a string to the beginning of a Haml block,
+ # with no whitespace between.
+ # For example:
+ #
+ # = precede '*' do
+ # %span.small Not really
+ #
+ # Produces:
+ #
+ # *<span class='small'>Not really</span>
+ #
+ # @param str [String] The string to add before the Haml
+ # @yield A block of Haml to prepend to
+ def precede(str, &block)
+ "#{str}#{capture_haml(&block).chomp}\n"
+ end
+
+ # Appends a string to the end of a Haml block,
+ # with no whitespace between.
+ # For example:
+ #
+ # click
+ # = succeed '.' do
+ # %a{:href=>"thing"} here
+ #
+ # Produces:
+ #
+ # click
+ # <a href='thing'>here</a>.
+ #
+ # @param str [String] The string to add after the Haml
+ # @yield A block of Haml to append to
+ def succeed(str, &block)
+ "#{capture_haml(&block).chomp}#{str}\n"
+ end
+
+ # Captures the result of a block of Haml code,
+ # gets rid of the excess indentation,
+ # and returns it as a string.
+ # For example, after the following,
+ #
+ # .foo
+ # - foo = capture_haml(13) do |a|
+ # %p= a
+ #
+ # the local variable `foo` would be assigned to `"<p>13</p>\n"`.
+ #
+ # @param args [Array] Arguments to pass into the block
+ # @yield [args] A block of Haml code that will be converted to a string
+ # @yieldparam args [Array] `args`
+ def capture_haml(*args, &block)
+ buffer = eval('_hamlout', block.binding) rescue haml_buffer
+ with_haml_buffer(buffer) do
+ position = haml_buffer.buffer.length
+
+ haml_buffer.capture_position = position
+ block.call(*args)
+
+ captured = haml_buffer.buffer.slice!(position..-1).split(/^/)
+
+ min_tabs = nil
+ captured.each do |line|
+ tabs = line.index(/[^ ]/) || line.length
+ min_tabs ||= tabs
+ min_tabs = min_tabs > tabs ? tabs : min_tabs
+ end
+
+ captured.map do |line|
+ line[min_tabs..-1]
+ end.join
+ end
+ ensure
+ haml_buffer.capture_position = nil
+ end
+
+ # @deprecated This will be removed in version 2.4.
+ # @see \{#haml\_concat}
+ def puts(*args)
+ warn <<END
+DEPRECATION WARNING:
+The Haml #puts helper is deprecated and will be removed in version 2.4.
+Use the #haml_concat helper instead.
+END
+ haml_concat(*args)
+ end
+
+ # Outputs text directly to the Haml buffer, with the proper indentation.
+ #
+ # @param text [#to_s] The text to output
+ def haml_concat(text = "")
+ haml_buffer.buffer << haml_indent << text.to_s << "\n"
+ ErrorReturn.new("haml_concat")
+ end
+
+ # @return [String] The indentation string for the current line
+ def haml_indent
+ ' ' * haml_buffer.tabulation
+ end
+
+ # Creates an HTML tag with the given name and optionally text and attributes.
+ # Can take a block that will run between the opening and closing tags.
+ # If the block is a Haml block or outputs text using \{#haml\_concat},
+ # the text will be properly indented.
+ #
+ # `flags` is a list of symbol flags
+ # like those that can be put at the end of a Haml tag
+ # (`:/`, `:<`, and `:>`).
+ # Currently, only `:/` and `:<` are supported.
+ #
+ # `haml_tag` outputs directly to the buffer;
+ # its return value should not be used.
+ # If you need to get the results as a string,
+ # use \{#capture\_haml\}.
+ #
+ # For example,
+ #
+ # haml_tag :table do
+ # haml_tag :tr do
+ # haml_tag :td, {:class => 'cell'} do
+ # haml_tag :strong, "strong!"
+ # haml_concat "data"
+ # end
+ # haml_tag :td do
+ # haml_concat "more_data"
+ # end
+ # end
+ # end
+ #
+ # outputs
+ #
+ # <table>
+ # <tr>
+ # <td class='cell'>
+ # <strong>
+ # strong!
+ # </strong>
+ # data
+ # </td>
+ # <td>
+ # more_data
+ # </td>
+ # </tr>
+ # </table>
+ #
+ # @param name [#to_s] The name of the tag
+ # @param flags [Array<Symbol>] Haml end-of-tag flags
+ #
+ # @overload haml_tag(name, *flags, attributes = {})
+ # @yield The block of Haml code within the tag
+ # @overload haml_tag(name, text, *flags, attributes = {})
+ # @param text [#to_s] The text within the tag
+ def haml_tag(name, *rest, &block)
+ ret = ErrorReturn.new("haml_tag")
+
+ name = name.to_s
+ text = rest.shift.to_s unless [Symbol, Hash, NilClass].any? {|t| rest.first.is_a? t}
+ flags = []
+ flags << rest.shift while rest.first.is_a? Symbol
+ attributes = Haml::Precompiler.build_attributes(haml_buffer.html?,
+ haml_buffer.options[:attr_wrapper],
+ rest.shift || {})
+
+ if text.nil? && block.nil? && (haml_buffer.options[:autoclose].include?(name) || flags.include?(:/))
+ haml_concat "<#{name}#{attributes} />"
+ return ret
+ end
+
+ if flags.include?(:/)
+ raise Error.new("Self-closing tags can't have content.") if text
+ raise Error.new("Illegal nesting: nesting within a self-closing tag is illegal.") if block
+ end
+
+ tag = "<#{name}#{attributes}>"
+ if block.nil?
+ tag << text.to_s << "</#{name}>"
+ haml_concat tag
+ return ret
+ end
+
+ if text
+ raise Error.new("Illegal nesting: content can't be both given to haml_tag :#{name} and nested within it.")
+ end
+
+ if flags.include?(:<)
+ tag << capture_haml(&block).strip << "</#{name}>"
+ haml_concat tag
+ return ret
+ end
+
+ haml_concat tag
+ tab_up
+ block.call
+ tab_down
+ haml_concat "</#{name}>"
+
+ ret
+ end
+
+ # Characters that need to be escaped to HTML entities from user input
+ HTML_ESCAPE = { '&'=>'&', '<'=>'<', '>'=>'>', '"'=>'"', "'"=>''', }
+
+ # Returns a copy of `text` with ampersands, angle brackets and quotes
+ # escaped into HTML entities.
+ #
+ # @param text [String] The string to sanitize
+ # @return [String] The sanitized string
+ def html_escape(text)
+ text.to_s.gsub(/[\"><&]/) { |s| HTML_ESCAPE[s] }
+ end
+
+ # Escapes HTML entities in `text`, but without escaping an ampersand
+ # that is already part of an escaped entity.
+ #
+ # @param text [String] The string to sanitize
+ # @return [String] The sanitized string
+ def escape_once(text)
+ text.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |s| HTML_ESCAPE[s] }
+ end
+
+ # Returns whether or not the current template is a Haml template.
+ #
+ # This function, unlike other {Haml::Helpers} functions,
+ # also works in other `ActionView` templates,
+ # where it will always return false.
+ #
+ # @return [Boolean] Whether or not the current template is a Haml template
+ def is_haml?
+ !@haml_buffer.nil? && @haml_buffer.active?
+ end
+
+ # Returns whether or not `block` is defined directly in a Haml template.
+ #
+ # @param block [Proc] A Ruby block
+ # @return [Boolean] Whether or not `block` is defined directly in a Haml template
+ def block_is_haml?(block)
+ eval('_hamlout', block.binding)
+ true
+ rescue
+ false
+ end
+
+ private
+
+ # Runs a block of code with the given buffer as the currently active buffer.
+ #
+ # @param buffer [Haml::Buffer] The Haml buffer to use temporarily
+ # @yield A block in which the given buffer should be used
+ def with_haml_buffer(buffer)
+ @haml_buffer, old_buffer = buffer, @haml_buffer
+ old_buffer.active, was_active = false, old_buffer.active? if old_buffer
+ @haml_buffer.active = true
+ yield
+ ensure
+ @haml_buffer.active = false
+ old_buffer.active = was_active if old_buffer
+ @haml_buffer = old_buffer
+ end
+
+ # The current {Haml::Buffer} object.
+ #
+ # @return [Haml::Buffer]
+ def haml_buffer
+ @haml_buffer
+ end
+
+ # Gives a proc the same local `_hamlout` and `_erbout` variables
+ # that the current template has.
+ #
+ # @param proc [#call] The proc to bind
+ # @return [Proc] A new proc with the new variables bound
+ def haml_bind_proc(&proc)
+ _hamlout = haml_buffer
+ _erbout = _hamlout.buffer
+ proc { |*args| proc.call(*args) }
+ end
+
+ include ActionViewExtensions if self.const_defined? "ActionViewExtensions"
+ end
+end
+
+class Object
+ # Haml overrides various `ActionView` helpers,
+ # which call an \{#is\_haml?} method
+ # to determine whether or not the current context object
+ # is a proper Haml context.
+ # Because `ActionView` helpers may be included in non-`ActionView::Base` classes,
+ # it's a good idea to define \{#is\_haml?} for all objects.
+ def is_haml?
+ false
+ end
+end
+
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_extensions.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_extensions.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_extensions.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_extensions.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,40 @@
+require 'haml/helpers/action_view_mods'
+
+module Haml
+ module Helpers
+ # This module contains various useful helper methods
+ # that either tie into ActionView or the rest of the ActionPack stack,
+ # or are only useful in that context.
+ # Thus, the methods defined here are only available
+ # if ActionView is installed.
+ module ActionViewExtensions
+ # Returns a value for the "class" attribute
+ # unique to this controller/action pair.
+ # This can be used to target styles specifically at this action or controller.
+ # For example, if the current action were `EntryController#show`,
+ #
+ # %div{:class => page_class} My Div
+ #
+ # would become
+ #
+ # <div class="entry show">My Div</div>
+ #
+ # Then, in a stylesheet (shown here as {Sass}),
+ # you could refer to this specific action:
+ #
+ # .entry.show
+ # font-weight: bold
+ #
+ # or to all actions in the entry controller:
+ #
+ # .entry
+ # color: #00f
+ #
+ # @return [String] The class name for the current page
+ def page_class
+ controller.controller_name + " " + controller.action_name
+ end
+ alias_method :generate_content_class_names, :page_class
+ end
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,174 @@
+module ActionView
+ class Base
+ def render_with_haml(*args, &block)
+ options = args.first
+
+ # If render :layout is used with a block,
+ # it concats rather than returning a string
+ # so we need it to keep thinking it's Haml
+ # until it hits the sub-render
+ if is_haml? && !(options.is_a?(Hash) && options[:layout] && block_given?)
+ return non_haml { render_without_haml(*args, &block) }
+ end
+ render_without_haml(*args, &block)
+ end
+ alias_method :render_without_haml, :render
+ alias_method :render, :render_with_haml
+
+ # Rails >2.1
+ if Haml::Util.has?(:instance_method, self, :output_buffer)
+ def output_buffer_with_haml
+ return haml_buffer.buffer if is_haml?
+ output_buffer_without_haml
+ end
+ alias_method :output_buffer_without_haml, :output_buffer
+ alias_method :output_buffer, :output_buffer_with_haml
+
+ def set_output_buffer_with_haml(new)
+ if is_haml?
+ haml_buffer.buffer = new
+ else
+ set_output_buffer_without_haml new
+ end
+ end
+ alias_method :set_output_buffer_without_haml, :output_buffer=
+ alias_method :output_buffer=, :set_output_buffer_with_haml
+ end
+ end
+
+ module Helpers
+ # In Rails <=2.1, we've got to override considerable capturing infrastructure.
+ # In Rails >2.1, we can make do with only overriding #capture
+ # (which no longer behaves differently in helper contexts).
+ unless Haml::Util.has?(:instance_method, ActionView::Base, :output_buffer)
+ module CaptureHelper
+ def capture_with_haml(*args, &block)
+ # Rails' #capture helper will just return the value of the block
+ # if it's not actually in the template context,
+ # as detected by the existance of an _erbout variable.
+ # We've got to do the same thing for compatibility.
+
+ if is_haml? && block_is_haml?(block)
+ capture_haml(*args, &block)
+ else
+ capture_without_haml(*args, &block)
+ end
+ end
+ alias_method :capture_without_haml, :capture
+ alias_method :capture, :capture_with_haml
+
+ def capture_erb_with_buffer_with_haml(buffer, *args, &block)
+ if is_haml?
+ capture_haml(*args, &block)
+ else
+ capture_erb_with_buffer_without_haml(buffer, *args, &block)
+ end
+ end
+ alias_method :capture_erb_with_buffer_without_haml, :capture_erb_with_buffer
+ alias_method :capture_erb_with_buffer, :capture_erb_with_buffer_with_haml
+ end
+
+ module TextHelper
+ def concat_with_haml(string, binding = nil)
+ if is_haml?
+ haml_buffer.buffer.concat(string)
+ else
+ concat_without_haml(string, binding)
+ end
+ end
+ alias_method :concat_without_haml, :concat
+ alias_method :concat, :concat_with_haml
+ end
+ else
+ module CaptureHelper
+ def capture_with_haml(*args, &block)
+ if Haml::Helpers.block_is_haml?(block)
+ capture_haml(*args, &block)
+ else
+ capture_without_haml(*args, &block)
+ end
+ end
+ alias_method :capture_without_haml, :capture
+ alias_method :capture, :capture_with_haml
+ end
+ end
+
+ module TagHelper
+ def content_tag_with_haml(name, *args, &block)
+ return content_tag_without_haml(name, *args, &block) unless is_haml?
+
+ preserve = haml_buffer.options[:preserve].include?(name.to_s)
+
+ if block_given? && block_is_haml?(block) && preserve
+ return content_tag_without_haml(name, *args) {preserve(&block)}
+ end
+
+ returning content_tag_without_haml(name, *args, &block) do |content|
+ return Haml::Helpers.preserve(content) if preserve && content
+ end
+ end
+
+ alias_method :content_tag_without_haml, :content_tag
+ alias_method :content_tag, :content_tag_with_haml
+ end
+
+ class InstanceTag
+ # Includes TagHelper
+
+ def haml_buffer
+ @template_object.send :haml_buffer
+ end
+
+ def is_haml?
+ @template_object.send :is_haml?
+ end
+
+ alias_method :content_tag_without_haml, :content_tag
+ alias_method :content_tag, :content_tag_with_haml
+ end
+
+ module FormTagHelper
+ def form_tag_with_haml(url_for_options = {}, options = {}, *parameters_for_url, &proc)
+ if is_haml?
+ if block_given?
+ oldproc = proc
+ proc = haml_bind_proc do |*args|
+ concat "\n"
+ tab_up
+ oldproc.call(*args)
+ tab_down
+ concat haml_indent
+ end
+ concat haml_indent
+ end
+ res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) + "\n"
+ concat "\n" if block_given?
+ res
+ else
+ form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
+ end
+ end
+ alias_method :form_tag_without_haml, :form_tag
+ alias_method :form_tag, :form_tag_with_haml
+ end
+
+ module FormHelper
+ def form_for_with_haml(object_name, *args, &proc)
+ if block_given? && is_haml?
+ oldproc = proc
+ proc = haml_bind_proc do |*args|
+ tab_up
+ oldproc.call(*args)
+ tab_down
+ concat haml_indent
+ end
+ concat haml_indent
+ end
+ form_for_without_haml(object_name, *args, &proc)
+ concat "\n" if block_given? && is_haml?
+ end
+ alias_method :form_for_without_haml, :form_for
+ alias_method :form_for, :form_for_with_haml
+ end
+ end
+end
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/html.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/html.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/html.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/haml/html.rb Thu Jul 8 23:14:13 2010
@@ -0,0 +1,257 @@
+require File.dirname(__FILE__) + '/../haml'
+
+require 'haml/engine'
+require 'rubygems'
+require 'cgi'
+
+module Haml
+ class HTML
+ # A module containing utility methods that every Hpricot node
+ # should have.
+ module Node
+ # Returns the Haml representation of the given node.
+ #
+ # @param tabs [Fixnum] The indentation level of the resulting Haml.
+ # @option options (see Haml::HTML#initialize)
+ def to_haml(tabs, options)
+ parse_text(self.to_s, tabs)
+ end
+
+ private
+
+ def tabulate(tabs)
+ ' ' * tabs
+ end
+
+ def parse_text(text, tabs)
+ text.strip!
+ if text.empty?
+ String.new
+ else
+ lines = text.split("\n")
+
+ lines.map do |line|
+ line.strip!
+ "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
+ end.join
+ end
+ end
+ end
+ end
+end
+
+# Haml monkeypatches various Hpricot classes
+# to add methods for conversion to Haml.
+module Hpricot
+ # @see Hpricot
+ module Node
+ include Haml::HTML::Node
+ end
+
+ # @see Hpricot
+ class BaseEle
+ include Haml::HTML::Node
+ end
+end
+
+require 'hpricot'
+
+module Haml
+ # Converts HTML documents into Haml templates.
+ # Depends on [Hpricot](http://code.whytheluckystiff.net/hpricot/) for HTML parsing.
+ #
+ # Example usage:
+ #
+ # Haml::Engine.new("<a href='http://google.com'>Blat</a>").render
+ # #=> "%a{:href => 'http://google.com'} Blat"
+ class HTML
+ # @param template [String, Hpricot::Node] The HTML template to convert
+ # @option options :rhtml [Boolean] (false) Whether or not to parse
+ # ERB's `<%= %>` and `<% %>` into Haml's `=` and `-`
+ # @option options :xhtml [Boolean] (false) Whether or not to parse
+ # the HTML strictly as XHTML
+ def initialize(template, options = {})
+ @options = options
+
+ if template.is_a? Hpricot::Node
+ @template = template
+ else
+ if template.is_a? IO
+ template = template.read
+ end
+
+ if @options[:rhtml]
+ match_to_html(template, /<%=(.*?)-?%>/m, 'loud')
+ match_to_html(template, /<%-?(.*?)-?%>/m, 'silent')
+ end
+
+ method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
+ @template = method.call(template.gsub('&', '&'))
+ end
+ end
+
+ # Processes the document and returns the result as a string
+ # containing the Haml template.
+ def render
+ @template.to_haml(0, @options)
+ end
+ alias_method :to_haml, :render
+
+ TEXT_REGEXP = /^(\s*).*$/
+
+ # @see Hpricot
+ class ::Hpricot::Doc
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ (children || []).inject('') {|s, c| s << c.to_haml(0, options)}
+ end
+ end
+
+ # @see Hpricot
+ class ::Hpricot::XMLDecl
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ "#{tabulate(tabs)}!!! XML\n"
+ end
+ end
+
+ # @see Hpricot
+ class ::Hpricot::CData
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ "#{tabulate(tabs)}:cdata\n#{parse_text(self.content, tabs + 1)}"
+ end
+ end
+
+ # @see Hpricot
+ class ::Hpricot::DocType
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ attrs = public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
+ if attrs == nil
+ raise Exception.new("Invalid doctype")
+ end
+
+ type, version, strictness = attrs.map { |a| a.downcase }
+ if type == "html"
+ version = "1.0"
+ strictness = "transitional"
+ end
+
+ if version == "1.0" || version.empty?
+ version = nil
+ end
+
+ if strictness == 'transitional' || strictness.empty?
+ strictness = nil
+ end
+
+ version = " #{version}" if version
+ if strictness
+ strictness[0] = strictness[0] - 32
+ strictness = " #{strictness}"
+ end
+
+ "#{tabulate(tabs)}!!!#{version}#{strictness}\n"
+ end
+ end
+
+ # @see Hpricot
+ class ::Hpricot::Comment
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ "#{tabulate(tabs)}/\n#{parse_text(self.content, tabs + 1)}"
+ end
+ end
+
+ # @see Hpricot
+ class ::Hpricot::Elem
+ # @see Haml::HTML::Node#to_haml
+ def to_haml(tabs, options)
+ output = "#{tabulate(tabs)}"
+ if options[:rhtml] && name[0...5] == 'haml:'
+ return output + send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text))
+ end
+
+ output += "%#{name}" unless name == 'div' &&
+ (static_id?(options) || static_classname?(options))
+
+ if attributes
+ if static_id?(options)
+ output += "##{attributes['id']}"
+ remove_attribute('id')
+ end
+ if static_classname?(options)
+ attributes['class'].split(' ').each { |c| output += ".#{c}" }
+ remove_attribute('class')
+ end
+ output += haml_attributes(options) if attributes.length > 0
+ end
+
+ (self.children || []).inject(output + "\n") do |output, child|
+ output + child.to_haml(tabs + 1, options)
+ end
+ end
+
+ private
+
+ def dynamic_attributes
+ @dynamic_attributes ||= begin
+ Haml::Util.map_hash(attributes) do |name, value|
+ next if value.empty?
+ full_match = nil
+ ruby_value = value.gsub(%r{<haml:loud>\s*(.+?)\s*</haml:loud>}) do
+ full_match = $`.empty? && $'.empty?
+ full_match ? $1: "\#{#{$1}}"
+ end
+ next if ruby_value == value
+ [name, full_match ? ruby_value : %("#{ruby_value}")]
+ end
+ end
+ end
+
+ def haml_tag_loud(text)
+ "= #{text.gsub(/\n\s*/, ' ').strip}\n"
+ end
+
+ def haml_tag_silent(text)
+ text.split("\n").map { |line| "- #{line.strip}\n" }.join
+ end
+
+ def static_attribute?(name, options)
+ attributes[name] and !dynamic_attribute?(name, options)
+ end
+
+ def dynamic_attribute?(name, options)
+ options[:rhtml] and dynamic_attributes.key?(name)
+ end
+
+ def static_id?(options)
+ static_attribute?('id', options)
+ end
+
+ def static_classname?(options)
+ static_attribute?('class', options)
+ end
+
+ # Returns a string representation of an attributes hash
+ # that's prettier than that produced by Hash#inspect
+ def haml_attributes(options)
+ attrs = attributes.map do |name, value|
+ value = dynamic_attribute?(name, options) ? dynamic_attributes[name] : value.inspect
+ name = name.index(/\W/) ? name.inspect : ":#{name}"
+ "#{name} => #{value}"
+ end
+ "{ #{attrs.join(', ')} }"
+ end
+ end
+
+ private
+
+ def match_to_html(string, regex, tag)
+ string.gsub!(regex) do
+ "<haml:#{tag}>#{CGI.escapeHTML($1)}</haml:#{tag}>"
+ end
+ end
+ end
+end