Froze rails gems
[depot.git] / vendor / rails / activesupport / lib / active_support / vendor / builder-2.1.2 / builder / css.rb
diff --git a/vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb b/vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb
new file mode 100644 (file)
index 0000000..e086a1b
--- /dev/null
@@ -0,0 +1,250 @@
+#!/usr/bin/env ruby
+#--
+# Copyright 2004, 2005 by Jim Weirich  (jim@weirichhouse.org).
+# Copyright       2005 by Scott Barron (scott@elitists.net).
+# All rights reserved.
+#
+# Permission is granted for use, copying, modification, distribution,
+# and distribution of modified versions of this work as long as the
+# above copyright notice is included.
+#
+# Much of this is taken from Jim's work in xmlbase.rb and xmlmarkup.rb.
+# Documentation has also been copied and pasted and modified to reflect
+# that we're building CSS here instead of XML.  Jim is conducting the
+# orchestra here and I'm just off in the corner playing a flute.
+#++
+
+# Provide a flexible and easy to use Builder for creating Cascading
+# Style Sheets (CSS).
+
+
+require 'builder/blankslate'
+
+module Builder
+
+  # Create a Cascading Style Sheet (CSS) using Ruby.
+  #
+  # Example usage:
+  #
+  #   css = Builder::CSS.new
+  #
+  #   text_color      = '#7F7F7F'
+  #   preferred_fonts = 'Helvetica, Arial, sans_serif'
+  #
+  #   css.comment! 'This is our stylesheet'
+  #   css.body {
+  #     background_color '#FAFAFA'
+  #     font_size        'small'
+  #     font_family      preferred_fonts
+  #     color            text_color
+  #   }
+  #
+  #   css.id!('navbar') {
+  #     width            '500px'
+  #   }
+  #
+  #   css.class!('navitem') {
+  #     color            'red'
+  #   }
+  #
+  #   css.a :hover {
+  #     text_decoration  'underline'
+  #   }
+  #
+  #   css.div(:id => 'menu') {
+  #     background       'green'
+  #   }
+  #
+  #   css.div(:class => 'foo') {
+  #     background       'red'
+  #   }
+  #
+  # This will yield the following stylesheet:
+  #
+  #   /* This is our stylesheet */
+  #   body {
+  #     background_color: #FAFAFA;
+  #     font_size:        small;
+  #     font_family:      Helvetica, Arial, sans_serif;
+  #     color:            #7F7F7F;
+  #   }
+  #
+  #   #navbar {
+  #     width:            500px;
+  #   }
+  #
+  #   .navitem {
+  #     color:            red;
+  #   }
+  #
+  #   a:hover {
+  #     text_decoration:  underline;
+  #   }
+  #
+  #   div#menu {
+  #     background:       green;
+  #   }
+  #
+  #   div.foo {
+  #     background:       red;
+  #   }
+  #
+  class CSS < BlankSlate
+
+    # Create a CSS builder.
+    #
+    # out::     Object receiving the markup.1  +out+ must respond to
+    #           <tt><<</tt>.
+    # indent::  Number of spaces used for indentation (0 implies no
+    #           indentation and no line breaks).
+    #
+    def initialize(indent=2)
+      @indent      = indent
+      @target      = []
+      @parts       = []
+      @library     = {}
+    end
+
+    def +(part)
+      _join_with_op! '+'
+      self
+    end
+
+    def >>(part)
+      _join_with_op! ''
+      self
+    end
+
+    def >(part)
+      _join_with_op! '>'
+      self
+    end
+
+    def |(part)
+      _join_with_op! ','
+      self
+    end
+
+    # Return the target of the builder
+    def target!
+      @target * ''
+    end
+
+    # Create a comment string in the output.
+    def comment!(comment_text)
+      @target << "/* #{comment_text} */\n"
+    end
+
+    def id!(arg, &block)
+      _start_container('#'+arg.to_s, nil, block_given?)
+      _css_block(block) if block
+      _unify_block
+      self
+    end
+
+    def class!(arg, &block)
+      _start_container('.'+arg.to_s, nil, block_given?)
+      _css_block(block) if block
+      _unify_block
+      self
+    end
+
+    def store!(sym, &block)
+      @library[sym] = block.to_proc
+    end
+
+    def group!(*args, &block)
+      args.each do |arg|
+        if arg.is_a?(Symbol)
+          instance_eval(&@library[arg])
+        else
+          instance_eval(&arg)
+        end
+        _text ', ' unless arg == args.last
+      end
+      if block
+        _css_block(block)
+        _unify_block
+      end
+    end
+
+    def method_missing(sym, *args, &block)
+      sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
+      if block
+        _start_container(sym, args.first)
+        _css_block(block)
+        _unify_block
+      elsif @in_block
+        _indent
+        _css_line(sym, *args)
+        _newline
+        return self
+      else
+        _start_container(sym, args.first, false)
+        _unify_block
+      end
+      self
+    end
+
+    # "Cargo culted" from Jim who also "cargo culted" it.  See xmlbase.rb.
+    def nil?
+      false
+    end
+
+    private
+    def _unify_block
+      @target << @parts * ''
+      @parts = []
+    end
+
+    def _join_with_op!(op)
+      rhs, lhs = @target.pop, @target.pop
+      @target << "#{lhs} #{op} #{rhs}"
+    end
+
+    def _text(text)
+      @parts << text
+    end
+
+    def _css_block(block)
+      _newline
+      _nested_structures(block)
+      _end_container
+      _end_block
+    end
+
+    def _end_block
+      _newline
+      _newline
+    end
+
+    def _newline
+      _text "\n"
+    end
+
+    def _indent
+      _text ' ' * @indent
+    end
+
+    def _nested_structures(block)
+      @in_block = true
+      self.instance_eval(&block)
+      @in_block = false
+    end
+
+    def _start_container(sym, atts = {}, with_bracket = true)
+      selector = sym.to_s
+      selector << ".#{atts[:class]}" if atts && atts[:class]
+      selector << '#' + "#{atts[:id]}" if atts && atts[:id]
+      @parts << "#{selector}#{with_bracket ? ' {' : ''}"
+    end
+
+    def _end_container
+      @parts << "}"
+    end
+
+    def _css_line(sym, *args)
+      _text("#{sym.to_s.gsub('_','-')}: #{args * ' '};")
+    end
+  end
+end