ruty 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ # = Ruty Capture Tag
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ class Ruty::Tags::Capture < Ruty::Tag
10
+
11
+ def initialize parser, argstring
12
+ if not argstring =~ /^as\s+([a-zA-Z_][a-zA-Z0-9_]*)$/
13
+ parser.fail('syntax for capture tag: {% capture as <variable> %}')
14
+ end
15
+
16
+ @name = $1.to_sym
17
+ @nodelist = parser.parse_until { |n, a| n == :endcapture }
18
+ end
19
+
20
+ def render_node context, stream
21
+ substream = ''
22
+ @nodelist.render(context, substream)
23
+ context[@name] = substream
24
+ end
25
+
26
+ Ruty::Tags.register(self, :include)
27
+
28
+ end
@@ -0,0 +1,59 @@
1
+ # = Ruty Conditional Tags
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ class Ruty::Tags::If < Ruty::Tag
10
+
11
+ def initialize parser, argstring
12
+ # parse everything until the next else or endif tag
13
+ # and save in a variable if it was a else tag for
14
+ # postprocessing.
15
+ was_else = false
16
+ @body = parser.parse_until do |name, a|
17
+ if [:endif, :else].include? name
18
+ was_else = name == :else
19
+ true
20
+ end
21
+ end
22
+
23
+ args = parser.parse_arguments(argstring)
24
+ @else_body = parser.parse_until { |name, a| name == :endif } if was_else
25
+
26
+ if not [1, 2].include?(args.length) or \
27
+ (args.length == 2 and args[0] != :not)
28
+ parser.fail('invalid syntax for if tag')
29
+ end
30
+
31
+ @negated = args.length == 2
32
+ @item = @negated ? args[1] : args[0]
33
+ end
34
+
35
+ def render_node context, stream
36
+ item = context.resolve(@item)
37
+ if item == false
38
+ val = false
39
+ elsif item.respond_to?(:nonzero?)
40
+ val = item.nonzero?
41
+ elsif item.respond_to?(:empty?)
42
+ val = !item.empty?
43
+ elsif item.respond_to?(:size)
44
+ val = item.size > 0
45
+ elsif item.respond_to?(:length)
46
+ val = item.length > 0
47
+ else
48
+ val = !item.nil?
49
+ end
50
+ if @negated ? !val : val
51
+ @body.render_node(context, stream)
52
+ elsif @else_body
53
+ @else_body.render_node(context, stream)
54
+ end
55
+ end
56
+
57
+ Ruty::Tags.register(self, :if)
58
+
59
+ end
@@ -0,0 +1,28 @@
1
+ # = Ruty Debug Tag
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ require 'stringio'
10
+ require 'pp'
11
+
12
+ class Ruty::Tags::Debug < Ruty::Tag
13
+
14
+ def initialize parser, argstring
15
+ parser.fail('debug tag takes no arguments') if not argstring.empty?
16
+ end
17
+
18
+ def render_node context, stream
19
+ buffer = StringIO.new
20
+ PP.pp(context, buffer)
21
+ buffer.rewind
22
+ stream << buffer.read.strip
23
+ buffer.close
24
+ end
25
+
26
+ Ruty::Tags.register(self, :debug)
27
+
28
+ end
@@ -0,0 +1,27 @@
1
+ # = Ruty Filter Tag
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ class Ruty::Tags::Filter < Ruty::Tag
10
+
11
+ def initialize parser, argstring
12
+ @filters = parser.parse_arguments('|' + argstring)
13
+ parser.fail('filter tag requires at least on filter') if @filters.empty?
14
+ @nodelist = parser.parse_until { |n, a| n == :endfilter }
15
+ end
16
+
17
+ def render_node context, stream
18
+ substream = Ruty::Datastructure::OutputStream.new
19
+ @nodelist.render_node(context, substream)
20
+ value = context.apply_filters(substream.to_s, @filters).to_s
21
+ stream << value if not value.empty?
22
+ nil
23
+ end
24
+
25
+ Ruty::Tags.register(self, :filter)
26
+
27
+ end
@@ -0,0 +1,83 @@
1
+ # = Ruty For Loop Tag
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ class Ruty::Tags::ForLoop < Ruty::Tag
10
+
11
+ def initialize parser, argstring
12
+ # parse everything until the next else or endfor tag
13
+ # and save in a variable if it was a else tag or an
14
+ # endfor tag so that we can parse the second part if
15
+ # required later.
16
+ was_else = false
17
+ @body = parser.parse_until do |name, a|
18
+ if [:endfor, :else].include? name
19
+ was_else = name == :else
20
+ true
21
+ end
22
+ end
23
+
24
+ args = parser.parse_arguments(argstring)
25
+ @else_body = parser.parse_until { |name, a| name == :endfor } if was_else
26
+ if args.length != 3 or args[1] != :in
27
+ parser.fail('invalid syntax for for-loop tag')
28
+ end
29
+ @item = args[0]
30
+ @iterable = args[2]
31
+ end
32
+
33
+ def render_node context, stream
34
+ iterable = context.resolve(@iterable)
35
+ length = 0
36
+ if iterable.respond_to?(:each)
37
+ if iterable.respond_to?(:size)
38
+ length = iterable.size
39
+ elsif iterable.respond_to?(:length)
40
+ length = iterable.length
41
+ end
42
+ end
43
+
44
+ if length > 0
45
+ index = 0
46
+ parent = context[:loop]
47
+ context.push
48
+
49
+ iterable.each do |item|
50
+ break if index == length
51
+ context[@item] = item
52
+ context[:loop] = {
53
+ :parent => parent,
54
+ :index => index + 1,
55
+ :index0 => index,
56
+ :revindex => length - index,
57
+ :revindex0 => length - index - 1,
58
+ :first => index == 0,
59
+ :last => length - index == 1,
60
+ :length => length,
61
+ :even => index % 2 != 0,
62
+ :odd => index % 2 == 0
63
+ }
64
+ @body.render_node(context, stream)
65
+ index += 1
66
+ end
67
+ if index != 0
68
+ context.pop
69
+ return nil
70
+ end
71
+ end
72
+
73
+ # if we reach this point there was no iteration. either because
74
+ # we tried to iterate something without a size or it was an object
75
+ # that isn't iterable, render the else_body if given
76
+ @else_body.render_node(context, stream) if @else_body
77
+ context.pop
78
+ nil
79
+ end
80
+
81
+ Ruty::Tags.register(self, :for)
82
+
83
+ end
@@ -0,0 +1,31 @@
1
+ # = Ruty Include Tags
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ # simple include tag. just includes another template at
10
+ # the current position. (for header/footer inclusion for
11
+ # example, although it's better to use extends in combination
12
+ # with some blocks)
13
+ class Ruty::Tags::Include < Ruty::Tag
14
+
15
+ def initialize parser, argstring
16
+ if not argstring =~ /^("')(.*?)\1$/
17
+ parser.fail('include takes exactly one argument which must be ' +
18
+ 'an hardcoded string')
19
+ end
20
+
21
+ # load given template using the load_local function of the parser
22
+ @nodelist = parser.load_local(argstring[1...-1])
23
+ end
24
+
25
+ def render_node context, stream
26
+ @nodelist.render_node(context, stream)
27
+ end
28
+
29
+ Ruty::Tags.register(self, :include)
30
+
31
+ end
@@ -0,0 +1,80 @@
1
+ # = Ruty Template Inheritance
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ # special tag that marks a part of a template for inheritance.
10
+ # If a template extends from a template with a block tag with
11
+ # the same name it will replace the block in the inherited
12
+ # template with the block with the same name in the current
13
+ # template.
14
+ class Ruty::Tags::Block < Ruty::Tag
15
+
16
+ def initialize parser, argstring
17
+ if not argstring =~ /^[a-zA-Z_][a-zA-Z0-9_]*$/
18
+ parser.fail('Invalid syntax for block tag')
19
+ end
20
+ @name = argstring.to_sym
21
+ @stack = [parser.parse_until { |name, a| name == :endblock }]
22
+
23
+ blocks = (parser.storage[:blocks] ||= {})
24
+ parser.fail("block '#{@name}' defined twice") if blocks.include?(@name)
25
+ blocks[@name] = self
26
+ end
27
+
28
+ def add_layer nodelist
29
+ @stack << nodelist
30
+ end
31
+
32
+ def render_node context, stream, index=-1
33
+ context.push
34
+ context[:block] = Ruty::Datastructure::Deferred.new(
35
+ :super => Proc.new {
36
+ render_node(context, stream, index - 1) if index.abs <= @stack.size
37
+ },
38
+ :depth => Proc.new { index.abs },
39
+ :name => Proc.new { @name }
40
+ )
41
+ @stack[index].render_node(context, stream)
42
+ context.pop
43
+ nil
44
+ end
45
+
46
+ Ruty::Tags.register(self, :block)
47
+
48
+ end
49
+
50
+ # tag used to load a template from another file. must be the first
51
+ # tag of a document!
52
+ class Ruty::Tags::Extends < Ruty::Tag
53
+
54
+ def initialize parser, argstring
55
+ if not parser.first
56
+ parser.fail('extends tag must be at the beginning of a template')
57
+ elsif not argstring =~ /^(["'])(.*?)\1$/
58
+ parser.fail('extends takes exactly one argument which must be ' +
59
+ 'an hardcoded string')
60
+ end
61
+
62
+ # parse the template to the end and load parent nodelist
63
+ parser.parse_all
64
+ @nodelist = parser.load_local(argstring[1...-1])
65
+ blocks = @nodelist.parser.storage[:blocks] || {}
66
+
67
+ # iterate over all blocks found while parsing and add them
68
+ # to the parent nodelist which will be the new nodelist
69
+ (parser.storage[:blocks] || []).each do |name, tag|
70
+ blocks[name].add_layer(tag) if blocks.include?(name)
71
+ end
72
+ end
73
+
74
+ def render_node context, stream
75
+ @nodelist.render_node(context, stream)
76
+ end
77
+
78
+ Ruty::Tags.register(self, :extends)
79
+
80
+ end
@@ -0,0 +1,85 @@
1
+ # = Ruty Loop Tool Tags
2
+ #
3
+ # Author:: Armin Ronacher
4
+ #
5
+ # Copyright (c) 2006 by Armin Ronacher
6
+ #
7
+ # You can redistribute it and/or modify it under the terms of the BSD license.
8
+
9
+ # A tag that cycles through a list of values each iteration
10
+ # Useful for example if you want alternating rows:
11
+ #
12
+ # {% for row in rows %}
13
+ # <tr class="{% cycle 'row1', 'row2' %}">
14
+ # <td>..</td>
15
+ # </tr>
16
+ # {% endfor %}
17
+ class Ruty::Tags::Cycle < Ruty::Tag
18
+
19
+ def initialize parser, argstring
20
+ args = parser.parse_arguments(argstring)
21
+ parser.fail('At least one item is required for cycle') if args.empty?
22
+ @items = args
23
+ end
24
+
25
+ def render_node context, stream
26
+ item = @items[context[self] = ((context[self] || -1) + 1) % @items.length]
27
+ item = context.resolve(item) if item.is_a?(Symbol)
28
+ stream << item.to_s
29
+ nil
30
+ end
31
+
32
+ Ruty::Tags.register(self, :cycle)
33
+
34
+ end
35
+
36
+
37
+ # just render everything between the tag and the closing
38
+ # endifchanged tag if the given variable hasn't changed
39
+ # from the last iteration. If no variable is given the
40
+ # block will check it's own rendering against the
41
+ # rendering of the last iteration.
42
+ #
43
+ # {% for day in days %}
44
+ # <div class="day">
45
+ # <h2>{{ day.name|escape }}</h2>
46
+ # {% for entry in day.entries %}
47
+ # {% ifchanged entry.pub_date.hour %}
48
+ # <h3>{{ entry.pub_date }}</h3>
49
+ # {% endifchanged %}
50
+ # ...
51
+ # {% endfor %}
52
+ # </div>
53
+ # {% endfor %}
54
+ class Ruty::Tags::IfChanged < Ruty::Tag
55
+
56
+ def initialize parser, argstring
57
+ args = parser.parse_arguments(argstring)
58
+ if not [0, 1].include?(args.length)
59
+ parser.fail('ifchanged-tag takes at most one argument')
60
+ end
61
+ @arg = args[0]
62
+ @body = parser.parse_until { |name, a| name == :endifchanged }
63
+ end
64
+
65
+ def render_node context, stream
66
+ if not @arg
67
+ substream = Datastructure::OutputStream.new
68
+ @body.render_node(context, substream)
69
+ this_iteration = substream.to_s
70
+ if this_iteration != context[self]
71
+ block << this_iteration
72
+ context[self] = this_iteration
73
+ end
74
+ else
75
+ item = (@arg.is_a?(Symbol)) ? context.resolve(@arg) : @arg
76
+ if item != context[self]
77
+ @body.render_node(context, stream)
78
+ context[self] = item
79
+ end
80
+ end
81
+ nil
82
+ end
83
+
84
+ Ruty::Tags.register(self, :ifchanged)
85
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: ruty
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-01-21 00:00:00 +01:00
8
+ summary: A Template-Engine inspired by the jinja engine
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: "true"
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Armin Ronacher
31
+ files:
32
+ - lib/ruty
33
+ - lib/ruty.rb
34
+ - lib/ruty/constants.rb
35
+ - lib/ruty/context.rb
36
+ - lib/ruty/datastructure.rb
37
+ - lib/ruty/filters.rb
38
+ - lib/ruty/loaders
39
+ - lib/ruty/loaders.rb
40
+ - lib/ruty/parser.rb
41
+ - lib/ruty/tags
42
+ - lib/ruty/tags.rb
43
+ - lib/ruty/loaders/filesystem.rb
44
+ - lib/ruty/tags/capture.rb
45
+ - lib/ruty/tags/conditional.rb
46
+ - lib/ruty/tags/debug.rb
47
+ - lib/ruty/tags/filter.rb
48
+ - lib/ruty/tags/forloop.rb
49
+ - lib/ruty/tags/inclusion.rb
50
+ - lib/ruty/tags/inheritance.rb
51
+ - lib/ruty/tags/looptools.rb
52
+ test_files: []
53
+
54
+ rdoc_options: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ requirements: []
63
+
64
+ dependencies: []
65
+