dinsley-markaby 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/README +256 -0
  2. data/Rakefile +49 -0
  3. data/VERSION.yml +4 -0
  4. data/lib/markaby/builder.rb +289 -0
  5. data/lib/markaby/cssproxy.rb +48 -0
  6. data/lib/markaby/metaid.rb +16 -0
  7. data/lib/markaby/rails/action_controller_helpers.rb +13 -0
  8. data/lib/markaby/rails/template_handler.rb +21 -0
  9. data/lib/markaby/tags.rb +179 -0
  10. data/lib/markaby.rb +39 -0
  11. data/test/app_root/app/controllers/application_controller.rb +2 -0
  12. data/test/app_root/app/controllers/markaby_controller.rb +37 -0
  13. data/test/app_root/app/helpers/test_helper.rb +7 -0
  14. data/test/app_root/app/views/markaby/_monkeys.mab +12 -0
  15. data/test/app_root/app/views/markaby/broken.mab +7 -0
  16. data/test/app_root/app/views/markaby/create.mab +9 -0
  17. data/test/app_root/app/views/markaby/index.mab +7 -0
  18. data/test/app_root/app/views/markaby/multiple_forms.mab +7 -0
  19. data/test/app_root/config/boot.rb +115 -0
  20. data/test/app_root/config/database.yml +31 -0
  21. data/test/app_root/config/environment.rb +14 -0
  22. data/test/app_root/config/environments/in_memory.rb +0 -0
  23. data/test/app_root/config/environments/mysql.rb +0 -0
  24. data/test/app_root/config/environments/postgresql.rb +0 -0
  25. data/test/app_root/config/environments/sqlite.rb +0 -0
  26. data/test/app_root/config/environments/sqlite3.rb +0 -0
  27. data/test/app_root/config/routes.rb +4 -0
  28. data/test/app_root/lib/console_with_fixtures.rb +4 -0
  29. data/test/app_root/log/in_memory.log +4215 -0
  30. data/test/app_root/script/console +7 -0
  31. data/test/markaby_controller_test.rb +73 -0
  32. data/test/markaby_test.rb +122 -0
  33. data/test/monkeys.html +13 -0
  34. data/test/test_helper.rb +28 -0
  35. metadata +102 -0
@@ -0,0 +1,48 @@
1
+ module Markaby
2
+ # Class used by Markaby::Builder to store element options. Methods called
3
+ # against the CssProxy object are added as element classes or IDs.
4
+ #
5
+ # See the README for examples.
6
+ class CssProxy
7
+
8
+ # Creates a CssProxy object.
9
+ def initialize(builder, stream, sym)
10
+ @builder, @stream, @sym, @attrs = builder, stream, sym, {}
11
+
12
+ @original_stream_length = @stream.length
13
+
14
+ @builder.tag! @sym
15
+ end
16
+
17
+ # Adds attributes to an element. Bang methods set the :id attribute.
18
+ # Other methods add to the :class attribute.
19
+ def method_missing(id_or_class, *args, &block)
20
+ if (idc = id_or_class.to_s) =~ /!$/
21
+ @attrs[:id] = $`
22
+ else
23
+ @attrs[:class] = @attrs[:class].nil? ? idc : "#{@attrs[:class]} #{idc}".strip
24
+ end
25
+
26
+ unless args.empty?
27
+ if args.last.respond_to? :to_hash
28
+ @attrs.merge! args.pop.to_hash
29
+ end
30
+ end
31
+
32
+ args.push(@attrs)
33
+
34
+ while @stream.length > @original_stream_length
35
+ @stream.pop
36
+ end
37
+
38
+ if block
39
+ @builder.tag! @sym, *args, &block
40
+ else
41
+ @builder.tag! @sym, *args
42
+ end
43
+
44
+ return self
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ # metaprogramming assistant -- metaid.rb
2
+ class Object # :nodoc:
3
+ # The hidden singleton lurks behind everyone
4
+ def metaclass; class << self; self; end; end
5
+ def meta_eval(&blk); metaclass.instance_eval(&blk); end
6
+
7
+ # Adds methods to a metaclass
8
+ def meta_def(name, &blk)
9
+ meta_eval { define_method(name, &blk) }
10
+ end
11
+
12
+ # Defines an instance method within a class
13
+ def class_def(name, &blk)
14
+ class_eval { define_method(name, &blk) }
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Markaby
2
+ module Rails
3
+ module ActionControllerHelpers
4
+ # Returns a string of HTML built from the attached +block+. Any +options+ are
5
+ # passed into the render method.
6
+ #
7
+ # Use this method in your controllers to output Markaby directly from inside.
8
+ def render_markaby(options = {}, &block)
9
+ render options.merge({ :text => Builder.new(options[:locals], self, &block).to_s })
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module Markaby
2
+ module Rails
3
+ class TemplateHandler < ActionView::TemplateHandler
4
+ include ActionView::TemplateHandlers::Compilable
5
+
6
+ def compile(template)
7
+ <<-CODE
8
+ @output_buffer = '' if @output_buffer.blank?;
9
+
10
+ variables = @controller.instance_variable_names;
11
+ variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables);
12
+ variables.each { |name| assigns[name.gsub('@','')] = @controller.instance_variable_get(name); };
13
+
14
+ output = Markaby::Builder.new(assigns.merge!(local_assigns), self);
15
+ output.instance_eval(#{template.source.dump});
16
+ output.to_s;
17
+ CODE
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,179 @@
1
+ module Markaby
2
+
3
+ FORM_TAGS = [ :form, :input, :select, :textarea ]
4
+ SELF_CLOSING_TAGS = [ :base, :meta, :link, :hr, :br, :param, :img, :area, :input, :col, :frame ]
5
+
6
+ # Common sets of attributes.
7
+ AttrCore = [:id, :class, :style, :title]
8
+ AttrI18n = [:lang, 'xml:lang'.intern, :dir]
9
+ AttrEvents = [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, :onmousemove,
10
+ :onmouseout, :onkeypress, :onkeydown, :onkeyup]
11
+ AttrFocus = [:accesskey, :tabindex, :onfocus, :onblur]
12
+ AttrHAlign = [:align, :char, :charoff]
13
+ AttrVAlign = [:valign]
14
+ Attrs = AttrCore + AttrI18n + AttrEvents
15
+
16
+ # All the tags and attributes from XHTML 1.0 Strict
17
+ class XHTMLStrict
18
+ class << self
19
+ attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
20
+ end
21
+ @doctype = ['-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd']
22
+ @tagset = {
23
+ :html => AttrI18n + [:id, :xmlns],
24
+ :head => AttrI18n + [:id, :profile],
25
+ :title => AttrI18n + [:id],
26
+ :base => [:href, :id],
27
+ :meta => AttrI18n + [:id, :http, :name, :content, :scheme, 'http-equiv'.intern],
28
+ :link => Attrs + [:charset, :href, :hreflang, :type, :rel, :rev, :media],
29
+ :style => AttrI18n + [:id, :type, :media, :title, 'xml:space'.intern],
30
+ :script => [:id, :charset, :type, :src, :defer, 'xml:space'.intern],
31
+ :noscript => Attrs,
32
+ :body => Attrs + [:onload, :onunload],
33
+ :div => Attrs,
34
+ :p => Attrs,
35
+ :ul => Attrs,
36
+ :ol => Attrs,
37
+ :li => Attrs,
38
+ :dl => Attrs,
39
+ :dt => Attrs,
40
+ :dd => Attrs,
41
+ :address => Attrs,
42
+ :hr => Attrs,
43
+ :pre => Attrs + ['xml:space'.intern],
44
+ :blockquote => Attrs + [:cite],
45
+ :ins => Attrs + [:cite, :datetime],
46
+ :del => Attrs + [:cite, :datetime],
47
+ :a => Attrs + AttrFocus + [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords],
48
+ :span => Attrs,
49
+ :bdo => AttrCore + AttrEvents + [:lang, 'xml:lang'.intern, :dir],
50
+ :br => AttrCore,
51
+ :em => Attrs,
52
+ :strong => Attrs,
53
+ :dfn => Attrs,
54
+ :code => Attrs,
55
+ :samp => Attrs,
56
+ :kbd => Attrs,
57
+ :var => Attrs,
58
+ :cite => Attrs,
59
+ :abbr => Attrs,
60
+ :acronym => Attrs,
61
+ :q => Attrs + [:cite],
62
+ :sub => Attrs,
63
+ :sup => Attrs,
64
+ :tt => Attrs,
65
+ :i => Attrs,
66
+ :b => Attrs,
67
+ :big => Attrs,
68
+ :small => Attrs,
69
+ :object => Attrs + [:declare, :classid, :codebase, :data, :type, :codetype, :archive, :standby, :height, :width, :usemap, :name, :tabindex],
70
+ :param => [:id, :name, :value, :valuetype, :type],
71
+ :img => Attrs + [:src, :alt, :longdesc, :height, :width, :usemap, :ismap],
72
+ :map => AttrI18n + AttrEvents + [:id, :class, :style, :title, :name],
73
+ :area => Attrs + AttrFocus + [:shape, :coords, :href, :nohref, :alt],
74
+ :form => Attrs + [:action, :method, :enctype, :onsubmit, :onreset, :accept, :accept],
75
+ :label => Attrs + [:for, :accesskey, :onfocus, :onblur],
76
+ :input => Attrs + AttrFocus + [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength, :src, :alt, :usemap, :onselect, :onchange, :accept],
77
+ :select => Attrs + [:name, :size, :multiple, :disabled, :tabindex, :onfocus, :onblur, :onchange],
78
+ :optgroup => Attrs + [:disabled, :label],
79
+ :option => Attrs + [:selected, :disabled, :label, :value],
80
+ :textarea => Attrs + AttrFocus + [:name, :rows, :cols, :disabled, :readonly, :onselect, :onchange],
81
+ :fieldset => Attrs,
82
+ :legend => Attrs + [:accesskey],
83
+ :button => Attrs + AttrFocus + [:name, :value, :type, :disabled],
84
+ :table => Attrs + [:summary, :width, :border, :frame, :rules, :cellspacing, :cellpadding],
85
+ :caption => Attrs,
86
+ :colgroup => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
87
+ :col => Attrs + AttrHAlign + AttrVAlign + [:span, :width],
88
+ :thead => Attrs + AttrHAlign + AttrVAlign,
89
+ :tfoot => Attrs + AttrHAlign + AttrVAlign,
90
+ :tbody => Attrs + AttrHAlign + AttrVAlign,
91
+ :tr => Attrs + AttrHAlign + AttrVAlign,
92
+ :th => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
93
+ :td => Attrs + AttrHAlign + AttrVAlign + [:abbr, :axis, :headers, :scope, :rowspan, :colspan],
94
+ :h1 => Attrs,
95
+ :h2 => Attrs,
96
+ :h3 => Attrs,
97
+ :h4 => Attrs,
98
+ :h5 => Attrs,
99
+ :h6 => Attrs
100
+ }
101
+
102
+ @tags = @tagset.keys
103
+ @forms = @tags & FORM_TAGS
104
+ @self_closing = @tags & SELF_CLOSING_TAGS
105
+ end
106
+
107
+ # Additional tags found in XHTML 1.0 Transitional
108
+ class XHTMLTransitional
109
+ class << self
110
+ attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
111
+ end
112
+ @doctype = ['-//W3C//DTD XHTML 1.0 Transitional//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd']
113
+ @tagset = XHTMLStrict.tagset.merge \
114
+ :strike => Attrs,
115
+ :center => Attrs,
116
+ :dir => Attrs + [:compact],
117
+ :noframes => Attrs,
118
+ :basefont => [:id, :size, :color, :face],
119
+ :u => Attrs,
120
+ :menu => Attrs + [:compact],
121
+ :iframe => AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :scrolling, :align, :height, :width],
122
+ :font => AttrCore + AttrI18n + [:size, :color, :face],
123
+ :s => Attrs,
124
+ :applet => AttrCore + [:codebase, :archive, :code, :object, :alt, :name, :width, :height, :align, :hspace, :vspace],
125
+ :isindex => AttrCore + AttrI18n + [:prompt]
126
+
127
+ # Additional attributes found in XHTML 1.0 Transitional
128
+ { :script => [:language],
129
+ :a => [:target],
130
+ :td => [:bgcolor, :nowrap, :width, :height],
131
+ :p => [:align],
132
+ :h5 => [:align],
133
+ :h3 => [:align],
134
+ :li => [:type, :value],
135
+ :div => [:align],
136
+ :pre => [:width],
137
+ :body => [:background, :bgcolor, :text, :link, :vlink, :alink],
138
+ :ol => [:type, :compact, :start],
139
+ :h4 => [:align],
140
+ :h2 => [:align],
141
+ :object => [:align, :border, :hspace, :vspace],
142
+ :img => [:name, :align, :border, :hspace, :vspace],
143
+ :link => [:target],
144
+ :legend => [:align],
145
+ :dl => [:compact],
146
+ :input => [:align],
147
+ :h6 => [:align],
148
+ :hr => [:align, :noshade, :size, :width],
149
+ :base => [:target],
150
+ :ul => [:type, :compact],
151
+ :br => [:clear],
152
+ :form => [:name, :target],
153
+ :area => [:target],
154
+ :h1 => [:align]
155
+ }.each do |k, v|
156
+ @tagset[k] += v
157
+ end
158
+
159
+ @tags = @tagset.keys
160
+ @forms = @tags & FORM_TAGS
161
+ @self_closing = @tags & SELF_CLOSING_TAGS
162
+ end
163
+
164
+ # Additional tags found in XHTML 1.0 Frameset
165
+ class XHTMLFrameset
166
+ class << self
167
+ attr_accessor :tags, :tagset, :forms, :self_closing, :doctype
168
+ end
169
+ @doctype = ['-//W3C//DTD XHTML 1.0 Frameset//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd']
170
+ @tagset = XHTMLTransitional.tagset.merge \
171
+ :frameset => AttrCore + [:rows, :cols, :onload, :onunload],
172
+ :frame => AttrCore + [:longdesc, :name, :src, :frameborder, :marginwidth, :marginheight, :noresize, :scrolling]
173
+
174
+ @tags = @tagset.keys
175
+ @forms = @tags & FORM_TAGS
176
+ @self_closing = @tags & SELF_CLOSING_TAGS
177
+ end
178
+
179
+ end
data/lib/markaby.rb ADDED
@@ -0,0 +1,39 @@
1
+ # = About lib/markaby.rb
2
+ #
3
+ # By requiring <tt>lib/markaby</tt>, you can load Markaby's dependency (the Builder library,)
4
+ # as well as the full set of Markaby classes.
5
+ #
6
+ # For a full list of features and instructions, see the README.
7
+ $:.unshift File.expand_path(File.dirname(__FILE__))
8
+
9
+ # Markaby is a module containing all of the great Markaby classes that
10
+ # do such an excellent job.
11
+ #
12
+ # * Markaby::Builder: the class for actually calling the Ruby methods
13
+ # which write the HTML.
14
+ # * Markaby::CSSProxy: a class which adds element classes and IDs to
15
+ # elements when used within Markaby::Builder.
16
+ # * Markaby::MetAid: metaprogramming helper methods.
17
+ # * Markaby::Tags: lists the roles of various XHTML tags to help Builder
18
+ # use these tags as they are intended.
19
+ module Markaby
20
+ VERSION = '0.5'
21
+
22
+ class InvalidXhtmlError < StandardError; end
23
+ end
24
+
25
+ unless defined?(Builder)
26
+ require 'rubygems'
27
+ require 'builder'
28
+ end
29
+
30
+ require 'markaby/builder'
31
+ require 'markaby/cssproxy'
32
+ require 'markaby/metaid'
33
+
34
+ module Kernel
35
+ # Shortcut for creating a quick block of Markaby.
36
+ def mab(*args, &block)
37
+ Markaby::Builder.new(*args, &block).to_s
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,37 @@
1
+ class MarkabyController < ApplicationController
2
+ helper :test
3
+
4
+ @@locals = { :monkeys => Monkey.find(:all) }
5
+
6
+ def rescue_action(e) raise e end;
7
+
8
+ def index
9
+ @monkeys = Monkey.find(:all)
10
+ end
11
+
12
+ def create
13
+ flash[:message] = 'Hello World'
14
+ end
15
+
16
+ def broken
17
+ end
18
+
19
+ def multiple_forms
20
+ end
21
+
22
+ def partial_rendering
23
+ render :partial => 'monkeys', :locals => @@locals
24
+ end
25
+
26
+ def partial_rendering_with_stringy_keys_in_local_assigns
27
+ render :partial => 'monkeys', :locals => { 'monkeys' => Monkey.find(:all) }
28
+ end
29
+
30
+ def inline_helper_rendering
31
+ render_markaby(:locals => @@locals) { ul { monkeys.each { |m| li m.name } } }
32
+ end
33
+
34
+ def basic_inline_rendering
35
+ render :inline => mab { ul { Monkey.find(:all).each { |m| li m.name } } }
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ module TestHelper
2
+ def check_ivar_exists(name)
3
+ unless instance_variables.include?(ivar_name = "@#{name}")
4
+ raise "#{ivar_name} does not exist"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ html {
2
+ head {
3
+ title "List 'o Monkeys"
4
+ }
5
+ body {
6
+ ul {
7
+ monkeys.each { |monkey|
8
+ li monkey.name
9
+ }
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,7 @@
1
+ div {
2
+ ul {
3
+ li 'one'
4
+ li 'two'
5
+ li supercalifragilisticexpialidocious
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ unless flash[:message].nil?
2
+ p { flash[:message] }
3
+ end
4
+
5
+ form_tag '/monkeys' do
6
+ div {
7
+ submit_tag 'Save'
8
+ }
9
+ end
@@ -0,0 +1,7 @@
1
+ ul {
2
+ check_ivar_exists :monkeys
3
+
4
+ @monkeys.each { |monkey|
5
+ li monkey.name
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ form_tag '/monkeys', :id => 'monkeys' do
2
+ div { submit_tag 'Save' }
3
+ end
4
+
5
+ form_tag '/bananas', :id => 'bananas' do
6
+ div { submit_tag 'Save' }
7
+ end
@@ -0,0 +1,115 @@
1
+ # Allow customization of the rails framework path
2
+ RAILS_FRAMEWORK_ROOT = (ENV['RAILS_FRAMEWORK_ROOT'] || "#{File.dirname(__FILE__)}/../../../../../../vendor/rails") unless defined?(RAILS_FRAMEWORK_ROOT)
3
+
4
+ # Don't change this file!
5
+ # Configure your app in config/environment.rb and config/environments/*.rb
6
+
7
+ RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
8
+
9
+ module Rails
10
+ class << self
11
+ def boot!
12
+ unless booted?
13
+ preinitialize
14
+ pick_boot.run
15
+ end
16
+ end
17
+
18
+ def booted?
19
+ defined? Rails::Initializer
20
+ end
21
+
22
+ def pick_boot
23
+ (vendor_rails? ? VendorBoot : GemBoot).new
24
+ end
25
+
26
+ def vendor_rails?
27
+ File.exist?(RAILS_FRAMEWORK_ROOT)
28
+ end
29
+
30
+ def preinitialize
31
+ load(preinitializer_path) if File.exist?(preinitializer_path)
32
+ end
33
+
34
+ def preinitializer_path
35
+ "#{RAILS_ROOT}/config/preinitializer.rb"
36
+ end
37
+ end
38
+
39
+ class Boot
40
+ def run
41
+ load_initializer
42
+ Rails::Initializer.run(:set_load_path)
43
+ end
44
+ end
45
+
46
+ class VendorBoot < Boot
47
+ def load_initializer
48
+ require "#{RAILS_FRAMEWORK_ROOT}/railties/lib/initializer"
49
+ Rails::Initializer.run(:install_gem_spec_stubs)
50
+ Rails::GemDependency.add_frozen_gem_path
51
+ end
52
+ end
53
+
54
+ class GemBoot < Boot
55
+ def load_initializer
56
+ self.class.load_rubygems
57
+ load_rails_gem
58
+ require 'initializer'
59
+ end
60
+
61
+ def load_rails_gem
62
+ if version = self.class.gem_version
63
+ gem 'rails', version
64
+ else
65
+ gem 'rails'
66
+ end
67
+ rescue Gem::LoadError => load_error
68
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
69
+ exit 1
70
+ end
71
+
72
+ class << self
73
+ def rubygems_version
74
+ Gem::RubyGemsVersion rescue nil
75
+ end
76
+
77
+ def gem_version
78
+ if defined? RAILS_GEM_VERSION
79
+ RAILS_GEM_VERSION
80
+ elsif ENV.include?('RAILS_GEM_VERSION')
81
+ ENV['RAILS_GEM_VERSION']
82
+ else
83
+ parse_gem_version(read_environment_rb)
84
+ end
85
+ end
86
+
87
+ def load_rubygems
88
+ require 'rubygems'
89
+ min_version = '1.3.1'
90
+ unless rubygems_version >= min_version
91
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
92
+ exit 1
93
+ end
94
+
95
+ rescue LoadError
96
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
97
+ exit 1
98
+ end
99
+
100
+ def parse_gem_version(text)
101
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
102
+ end
103
+
104
+ private
105
+ def read_environment_rb
106
+ environment_rb = "#{RAILS_ROOT}/config/environment.rb"
107
+ environment_rb = "#{HELPER_RAILS_ROOT}/config/environment.rb" unless File.exists?(environment_rb)
108
+ File.read(environment_rb)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ # All that for this:
115
+ Rails.boot!