markaby 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/markaby.rb ADDED
@@ -0,0 +1,16 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+
3
+ module Markaby
4
+ VERSION = '0.2'
5
+ end
6
+
7
+ unless defined?(Builder)
8
+ require 'rubygems'
9
+ require 'builder'
10
+ end
11
+
12
+ require 'markaby/builder'
13
+ require 'markaby/cssproxy'
14
+ require 'markaby/metaid'
15
+ require 'markaby/tags'
16
+ require 'markaby/template'
@@ -0,0 +1,123 @@
1
+ module Markaby
2
+ class Builder
3
+
4
+ attr_accessor :output_helpers
5
+
6
+ def initialize(assigns, helpers, &block)
7
+ @assigns = assigns
8
+ @helpers = helpers.dup
9
+ @stream = []
10
+ @builder = ::Builder::XmlMarkup.new(:indent => 2, :target => @stream)
11
+ @output_helpers = true
12
+
13
+ for iv in helpers.instance_variables
14
+ instance_variable_set(iv, helpers.instance_variable_get(iv))
15
+ end
16
+ for iv, val in assigns
17
+ instance_variable_set("@#{iv}", val)
18
+ @helpers.instance_variable_set("@#{iv}", val)
19
+ end
20
+
21
+ if block
22
+ r = instance_eval &block
23
+ text(r) if to_s.empty?
24
+ end
25
+ end
26
+
27
+ def to_s
28
+ @builder.target!
29
+ end
30
+
31
+ def text(string)
32
+ @builder << "#{string}"
33
+ nil
34
+ end
35
+ alias_method :<<, :text
36
+
37
+ def capture(&block)
38
+ assigns = instance_variables.inject({}) do |hsh, iv|
39
+ unless ['@stream', '@builder', '@assigns', '@helpers'].include?(iv)
40
+ hsh[iv[1..-1]] = instance_variable_get(iv)
41
+ end
42
+ hsh
43
+ end
44
+ self.class.new(assigns, @helpers, &block).to_s
45
+ end
46
+
47
+ def content_for(name, &block)
48
+ eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)"
49
+ end
50
+
51
+ def tag!(tag, *args, &block)
52
+ if block
53
+ str = capture &block
54
+ block = proc { text(str) }
55
+ end
56
+ @builder.method_missing(tag, *args, &block)
57
+ end
58
+
59
+ def method_missing(tag, *args, &block)
60
+ args.each do |arg|
61
+ @stream.delete_if { |x| x.object_id == arg.object_id }
62
+ end
63
+
64
+ if (TAGS + BIG_TAGS).include?(tag)
65
+ if args.empty? and block.nil?
66
+ return CssProxy.new do |args, block|
67
+ tag!(tag, *args, &block)
68
+ end
69
+ end
70
+ end
71
+
72
+ if TAGS.include?(tag)
73
+ tag!(tag, *args, &block)
74
+ elsif BIG_TAGS.include?(tag)
75
+ tag!(tag, *args, &block)
76
+ elsif SELF_CLOSING_TAGS.include?(tag)
77
+ tag!(tag, *args)
78
+ elsif instance_variable_get("@#{tag}")
79
+ instance_variable_get("@#{tag}")
80
+ elsif @helpers.respond_to?(tag)
81
+ r = @helpers.send(tag, *args, &block)
82
+ @builder << r if @output_helpers
83
+ r
84
+ else
85
+ tag!(tag, *args, &block)
86
+ end
87
+ end
88
+
89
+ def p(*args, &block)
90
+ method_missing(:p, *args, &block)
91
+ end
92
+
93
+ @@default_image_tag_options ||= { :border => '0', :alt => '' }
94
+
95
+ def img(opts = {})
96
+ opts[:border] ||= '0'
97
+ opts[:alt] ||= ''
98
+ tag!(:img, @@default_image_tag_options.merge(opts))
99
+ end
100
+
101
+ def head(*args, &block)
102
+ tag!(:head, *args) do
103
+ tag!(:meta, 'http-equiv' => 'Content-Type', 'content' => 'text/html; charset=utf-8')
104
+ instance_eval &block
105
+ end
106
+ end
107
+
108
+ def html(*args, &block)
109
+ if args.empty?
110
+ args = ["-//W3C//DTD XHTML 1.0 Transitional//EN", "DTD/xhtml1-transitional.dtd"]
111
+ end
112
+ @builder.instruct!
113
+ @builder.declare!(:DOCTYPE, :html, :PUBLIC, *args)
114
+ tag!(:html, :xmlns => "http://www.w3.org/1999/xhtml",
115
+ "xml:lang" => "en", :lang => "en", &block)
116
+ end
117
+ alias_method :xhtml_transitional, :html
118
+
119
+ def xhtml_strict(&block)
120
+ html("-//W3C//DTD XHTML 1.0 Strict//EN", "DTD/xhtml1-strict.dtd", &block)
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,28 @@
1
+ module Markaby
2
+ class CssProxy
3
+
4
+ def initialize(opts = {}, &blk)
5
+ @opts = opts
6
+ @blk = blk
7
+ end
8
+
9
+ def method_missing(id_or_class, *args, &blk)
10
+ idc = id_or_class.to_s
11
+ case idc
12
+ when /!$/
13
+ @opts[:id] = $`
14
+ else
15
+ @opts[:class] = "#{@opts[:class]} #{idc}".strip
16
+ end
17
+ if args.empty? and blk.nil?
18
+ self
19
+ else
20
+ if args.last.respond_to? :to_hash
21
+ @opts.merge!(args.pop.to_hash)
22
+ end
23
+ args.push @opts
24
+ @blk.call(args, blk)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ # metaprogramming assistant -- metaid.rb
2
+ class Object
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,30 @@
1
+ module Markaby
2
+
3
+ TAGS = [
4
+ :a, :abbr, :acronym, :span, :b, :caption, :del, :cite, :code, :col,
5
+ :colgroup, :dd, :dfn, :dt, :em, :fieldset, :i, :img, :ins, :kbd, :p,
6
+ :label, :legend, :li, :optgroup, :option, :select, :small, :span, :strong,
7
+ :sub, :sup, :tbody, :td, :textarea, :thead, :title, :th, :tr, :tfoot, :tt
8
+ ]
9
+
10
+ BIG_TAGS = [
11
+ :address, :blockquote, :body, :div, :dl, :form, :h1, :h2, :h3, :head,
12
+ :noscript, :object, :ol, :pre, :q, :samp, :script, :style, :table, :ul
13
+ ]
14
+
15
+ SELF_CLOSING_TAGS = [
16
+ :hr, :br, :link, :meta, :input
17
+ ]
18
+
19
+ # tag categories
20
+ # --------------
21
+ #
22
+ # inline
23
+ # self_closing
24
+ #
25
+ # block
26
+ # cdata
27
+ # large (seperated by extra space)
28
+ #
29
+
30
+ end
@@ -0,0 +1,12 @@
1
+ module Markaby
2
+ class Template
3
+ def initialize(template)
4
+ @template = template
5
+ end
6
+ def render(*args)
7
+ output = Builder.new(*args)
8
+ output.instance_eval @template
9
+ return output.to_s
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Markaby
2
+ class View
3
+ def initialize(action_view)
4
+ @action_view = action_view
5
+ end
6
+ def render(template, local_assigns = {})
7
+ Template.new(template).render(@action_view.assigns.merge(local_assigns), @action_view)
8
+ end
9
+ end
10
+ end
data/test/example.rb ADDED
@@ -0,0 +1,48 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'markaby'
4
+
5
+ module Helpers
6
+ def self.link_to(person)
7
+ %{<a href="/person/#{person.id}">#{capitalize(person.name)}</a>}
8
+ end
9
+ def self.capitalize(text)
10
+ text.sub(/([a-z])/) { $1.upcase }
11
+ end
12
+ def self.p(text)
13
+ "<p>#{text}</p>"
14
+ end
15
+ end
16
+
17
+ class Person < Struct.new(:id, :name)
18
+ def self.all
19
+ @@people ||= []
20
+ end
21
+ def self.<<(name)
22
+ all << new(name)
23
+ end
24
+ def initialize(name)
25
+ super(self.class.all.size + 1, name)
26
+ end
27
+ end
28
+
29
+ Person << 'tim'
30
+ Person << 'sophie'
31
+
32
+ template = <<-EOT
33
+
34
+ link :rel => 'stylesheet'
35
+
36
+ ul do
37
+ people.each do |person|
38
+ li { link_to(person) }
39
+ end
40
+ end
41
+
42
+ hr
43
+
44
+ div { p("foo") }
45
+
46
+ EOT
47
+
48
+ puts Markaby::Template.new(template).render({'people' => Person.all}, Helpers)
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: markaby
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.2"
7
+ date: 2006-01-17 00:00:00 -07:00
8
+ summary: "Markup as Ruby, write HTML in your native Ruby tongue"
9
+ require_paths:
10
+ - lib
11
+ email: why@ruby-lang.org
12
+ homepage: http://whytheluckystiff.net/markaby/
13
+ rubyforge_project: hobix
14
+ description:
15
+ autorequire: markaby
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - why the lucky stiff
31
+ files:
32
+ - test/example.rb
33
+ - lib/markaby
34
+ - lib/markaby.rb
35
+ - lib/markaby/metaid.rb
36
+ - lib/markaby/tags.rb
37
+ - lib/markaby/builder.rb
38
+ - lib/markaby/cssproxy.rb
39
+ - lib/markaby/view.rb
40
+ - lib/markaby/template.rb
41
+ test_files: []
42
+ rdoc_options: []
43
+ extra_rdoc_files: []
44
+ executables: []
45
+ extensions: []
46
+ requirements: []
47
+ dependencies:
48
+ - !ruby/object:Gem::Dependency
49
+ name: builder
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Version::Requirement
52
+ requirements:
53
+ -
54
+ - ">"
55
+ - !ruby/object:Gem::Version
56
+ version: 0.0.0
57
+ version: