diff options
Diffstat (limited to 'activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb')
-rw-r--r-- | activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb new file mode 100644 index 0000000000..e086a1b132 --- /dev/null +++ b/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb @@ -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 |