inversion 1.0.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +46 -0
  5. data/Manifest.txt +0 -1
  6. data/README.rdoc +10 -4
  7. data/Rakefile +4 -90
  8. data/bin/inversion +3 -1
  9. data/lib/inversion.rb +4 -4
  10. data/lib/inversion/command.rb +2 -1
  11. data/lib/inversion/exceptions.rb +4 -1
  12. data/lib/inversion/mixins.rb +30 -4
  13. data/lib/inversion/monkeypatches.rb +3 -2
  14. data/lib/inversion/parser.rb +2 -2
  15. data/lib/inversion/renderstate.rb +2 -1
  16. data/lib/inversion/sinatra.rb +4 -1
  17. data/lib/inversion/template.rb +3 -3
  18. data/lib/inversion/template/attrtag.rb +8 -6
  19. data/lib/inversion/template/begintag.rb +3 -1
  20. data/lib/inversion/template/calltag.rb +3 -1
  21. data/lib/inversion/template/codetag.rb +13 -2
  22. data/lib/inversion/template/commenttag.rb +3 -1
  23. data/lib/inversion/template/configtag.rb +10 -2
  24. data/lib/inversion/template/containertag.rb +2 -2
  25. data/lib/inversion/template/defaulttag.rb +4 -2
  26. data/lib/inversion/template/elsetag.rb +3 -1
  27. data/lib/inversion/template/elsiftag.rb +36 -7
  28. data/lib/inversion/template/endtag.rb +3 -3
  29. data/lib/inversion/template/escapetag.rb +3 -1
  30. data/lib/inversion/template/fortag.rb +14 -8
  31. data/lib/inversion/template/fragmenttag.rb +3 -1
  32. data/lib/inversion/template/iftag.rb +37 -8
  33. data/lib/inversion/template/importtag.rb +4 -2
  34. data/lib/inversion/template/includetag.rb +3 -1
  35. data/lib/inversion/template/node.rb +2 -1
  36. data/lib/inversion/template/pptag.rb +4 -2
  37. data/lib/inversion/template/publishtag.rb +3 -1
  38. data/lib/inversion/template/rescuetag.rb +3 -1
  39. data/lib/inversion/template/subscribetag.rb +3 -1
  40. data/lib/inversion/template/tag.rb +4 -4
  41. data/lib/inversion/template/textnode.rb +3 -1
  42. data/lib/inversion/template/timedeltatag.rb +16 -3
  43. data/lib/inversion/template/unlesstag.rb +31 -3
  44. data/lib/inversion/template/uriencodetag.rb +5 -5
  45. data/lib/inversion/template/yieldtag.rb +3 -1
  46. data/lib/inversion/tilt.rb +3 -1
  47. data/spec/helpers.rb +3 -0
  48. data/spec/inversion/mixins_spec.rb +14 -14
  49. data/spec/inversion/renderstate_spec.rb +0 -9
  50. data/spec/inversion/template/codetag_spec.rb +41 -1
  51. data/spec/inversion/template/elsiftag_spec.rb +25 -0
  52. data/spec/inversion/template/fortag_spec.rb +34 -2
  53. data/spec/inversion/template/iftag_spec.rb +11 -0
  54. data/spec/inversion/template/pptag_spec.rb +2 -0
  55. data/spec/inversion/template/timedeltatag_spec.rb +7 -0
  56. data/spec/inversion/template/unlesstag_spec.rb +11 -0
  57. data/spec/inversion/template_spec.rb +2 -6
  58. metadata +84 -121
  59. metadata.gz.sig +0 -0
  60. data/ChangeLog +0 -2078
@@ -1,7 +1,9 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'ripper'
6
+ require 'inversion/template' unless defined?( Inversion::Template )
5
7
  require 'inversion/template/tag'
6
8
 
7
9
  # The base class for Inversion tags that parse the body section of the tag using
@@ -52,7 +54,7 @@ class Inversion::Template::CodeTag < Inversion::Template::Tag
52
54
  "invalid char in pattern: #{m[0].inspect}"
53
55
  end
54
56
 
55
- buf = '^'
57
+ buf = String.new( '^' )
56
58
  pattern.scan( /(?:\w+|\$\(|[()\[\]\{\}?*+\.]+)/ ) do |tok|
57
59
  case tok
58
60
  when /\w/
@@ -100,6 +102,15 @@ class Inversion::Template::CodeTag < Inversion::Template::Tag
100
102
  end
101
103
 
102
104
 
105
+ ### Declarative that forces a tag to inherit existing patterns from
106
+ ### its parent, rather than replacing them. Afterwards, you can use
107
+ ### +tag_pattern+ regularly, appending to the list.
108
+ def self::inherit_tag_patterns
109
+ raise ScriptError, "Patterns already exist for this tag." if defined?( @tag_patterns )
110
+ @tag_patterns = self.superclass.tag_patterns
111
+ end
112
+
113
+
103
114
  #################################################################
104
115
  ### I N S T A N C E M E T H O D S
105
116
  #################################################################
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
  require 'inversion/template/containertag'
6
8
 
@@ -1,8 +1,11 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'yaml'
6
+
5
7
  require 'inversion/mixins'
8
+ require 'inversion/template' unless defined?( Inversion::Template )
6
9
  require 'inversion/template/tag'
7
10
 
8
11
 
@@ -34,7 +37,12 @@ class Inversion::Template::ConfigTag < Inversion::Template::Tag
34
37
  raise Inversion::ParseError, 'Empty config settings' if
35
38
  body.nil? || body.strip.empty?
36
39
 
37
- opts = YAML.load( body )
40
+ opts = if defined?( SafeYAML ) then
41
+ YAML.load( body, safe: true )
42
+ else
43
+ YAML.load( body )
44
+ end
45
+
38
46
  @options = symbolify_keys( opts )
39
47
 
40
48
  super
@@ -1,7 +1,7 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
- require 'inversion' unless defined?( Inversion )
5
5
  require 'inversion/template' unless defined?( Inversion::Template )
6
6
 
7
7
  # A mixin for a tag that allows it to contain other nodes.
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/codetag'
5
7
 
6
8
  # Inversion 'default' tag.
@@ -64,7 +66,7 @@ class Inversion::Template::DefaultTag < Inversion::Template::CodeTag
64
66
  super
65
67
 
66
68
  # Add an identifier for the tag name
67
- self.identifiers << self.name.untaint.to_sym
69
+ self.identifiers << self.name.to_sym
68
70
  end
69
71
 
70
72
 
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
 
6
8
 
@@ -1,10 +1,11 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/attrtag'
5
7
  require 'inversion/template/commenttag'
6
- require 'inversion/template/iftag' unless
7
- defined?( Inversion::Template::IfTag )
8
+ require 'inversion/template/iftag'
8
9
 
9
10
 
10
11
  # Inversion 'elsif' tag.
@@ -24,7 +25,31 @@ require 'inversion/template/iftag' unless
24
25
  #
25
26
  class Inversion::Template::ElsifTag < Inversion::Template::AttrTag
26
27
 
27
- # Inherits AttrTag's tag patterns
28
+ # Inherit AttrTag's tag patterns first.
29
+ inherit_tag_patterns
30
+
31
+ # Append a 'not' tag matcher.
32
+ # <?elsif ! foo ?>, <?elsif !foo ?>
33
+ #
34
+ tag_pattern '$(op) sp* $(ident)' do |tag, match|
35
+ op = match.string( 1 )
36
+ raise Inversion::ParseError, "expected '!', got %p instead" % [ op ] unless op == '!'
37
+
38
+ tag.send( :log ).debug " Identifier is: %p (inverted)" % [ match.string(2) ]
39
+ tag.name = match.string( 2 ).to_sym
40
+ tag.inverted = true
41
+ end
42
+
43
+
44
+ ### Create a new ElsifTag.
45
+ def initialize( body, linenum=nil, colnum=nil )
46
+ @inverted = false
47
+ super
48
+ end
49
+
50
+ # Invert the tag's renderstate if created with the 'not' operator.
51
+ attr_accessor :inverted
52
+
28
53
 
29
54
  ### Parsing callback -- check to be sure the node tree can have an
30
55
  ### 'elsif' tag appended to it (i.e., it has an opening 'if' tag).
@@ -46,19 +71,23 @@ class Inversion::Template::ElsifTag < Inversion::Template::AttrTag
46
71
  end
47
72
 
48
73
 
49
- ### Always remder as an empty string.
74
+ ### Always render as an empty string.
50
75
  def render( * )
51
76
  nil
52
77
  end
53
78
 
54
79
 
55
- ### Toggle rendering for the iftag's container if rendering hasn't yet been
80
+ ### Toggle rendering for the elsiftag's container if rendering hasn't yet been
56
81
  ### toggled.
57
82
  def before_rendering( renderstate )
83
+
84
+ evaluated_state = self.evaluate( renderstate )
85
+ evaluated_state = ! evaluated_state if self.inverted
86
+
58
87
  if renderstate.tag_data[ :rendering_was_enabled ]
59
88
  self.log.debug "Rendering was previously enabled; disabling"
60
89
  renderstate.disable_rendering
61
- elsif self.evaluate( renderstate )
90
+ elsif evaluated_state
62
91
  self.log.debug "Rendering was previously disabled, and condition is true; enabling"
63
92
  renderstate.tag_data[ :rendering_was_enabled ] = true
64
93
  renderstate.enable_rendering
@@ -1,9 +1,9 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
- require 'inversion' unless defined?( Inversion )
5
5
  require 'inversion/template' unless defined?( Inversion::Template )
6
- require 'inversion/template/tag' unless defined?( Inversion::Template::Tag )
6
+ require 'inversion/template/tag'
7
7
 
8
8
  # Closing tag class
9
9
  class Inversion::Template::EndTag < Inversion::Template::Tag
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/attrtag'
5
7
 
6
8
  # Inversion escaping tag.
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/codetag'
5
7
  require 'inversion/template/containertag'
6
8
 
@@ -34,8 +36,8 @@ class Inversion::Template::ForTag < Inversion::Template::CodeTag
34
36
  raise Inversion::ParseError, "invalid keyword: expected 'in', got %p for %p" %
35
37
  [ match.string(2), tag.body ] unless match.string(2) == 'in'
36
38
 
37
- tag.block_args << match.string( 1 ).untaint.to_sym
38
- tag.identifiers << match.string( 3 ).untaint.to_sym
39
+ tag.block_args << match.string( 1 ).to_sym
40
+ tag.identifiers << match.string( 3 ).to_sym
39
41
 
40
42
  tag.enumerator = match.string( 3 )
41
43
  tag.enumerator << match.string( 4 ) if match.string( 4 )
@@ -48,8 +50,8 @@ class Inversion::Template::ForTag < Inversion::Template::CodeTag
48
50
  raise Inversion::ParseError, "invalid keyword: expected 'in', got %p for %p" %
49
51
  [ match.string(2), tag.body ] unless match.string(2) == 'in'
50
52
 
51
- tag.block_args += match.string( 1 ).untaint.split(/,\s?/).map( &:to_sym )
52
- tag.identifiers << match.string( 3 ).untaint.to_sym
53
+ tag.block_args += match.string( 1 ).split(/,\s?/).map( &:to_sym )
54
+ tag.identifiers << match.string( 3 ).to_sym
53
55
 
54
56
  tag.enumerator = match.string( 3 )
55
57
  tag.enumerator << match.string( 4 ) if match.string( 4 )
@@ -84,16 +86,20 @@ class Inversion::Template::ForTag < Inversion::Template::CodeTag
84
86
  lvalue = state.eval( self.enumerator ) or return nil
85
87
  lvalue = lvalue.each unless lvalue.respond_to?( :next )
86
88
 
87
- # self.log.debug "Rendering %p via block args: %p" % [ lvalue, self.block_args ]
89
+ self.log.debug "Rendering %p via block args: %p" % [ lvalue, self.block_args ]
88
90
 
89
91
  # Loop will exit as soon as the Enumerator runs out of elements
90
92
  loop do
91
93
  args = lvalue.next
92
- args = [ args ] unless args.is_a?( Array )
93
94
 
94
95
  # Turn the block arguments into an overrides hash by zipping up
95
96
  # the arguments names and values
96
- overrides = Hash[ self.block_args.zip(args) ]
97
+ overrides = if self.block_args.size > 1
98
+ args = [ args ] unless args.is_a?( Array )
99
+ Hash[ self.block_args.zip(args) ]
100
+ else
101
+ { self.block_args.first => args }
102
+ end
97
103
 
98
104
  # Overlay the block args from the 'for' over the template attributes and render
99
105
  # each subnode
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
  require 'inversion/template/containertag'
6
8
 
@@ -1,7 +1,9 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'inversion/mixins'
6
+ require 'inversion/template' unless defined?( Inversion::Template )
5
7
  require 'inversion/template/attrtag'
6
8
  require 'inversion/template/containertag'
7
9
 
@@ -18,28 +20,55 @@ require 'inversion/template/containertag'
18
20
  class Inversion::Template::IfTag < Inversion::Template::AttrTag
19
21
  include Inversion::Template::ContainerTag
20
22
 
21
- # Inherits AttrTag's tag patterns
23
+ # Inherit AttrTag's tag patterns first.
24
+ inherit_tag_patterns
25
+
26
+ # Append a 'not' tag matcher.
27
+ # <?if ! foo ?>, <?if !foo ?>
28
+ #
29
+ tag_pattern '$(op) sp* $(ident)' do |tag, match|
30
+ op = match.string( 1 )
31
+ raise Inversion::ParseError, "expected '!', got %p instead" % [ op ] unless op == '!'
32
+
33
+ tag.send( :log ).debug " Identifier is: %p (inverted)" % [ match.string(2) ]
34
+ tag.name = match.string( 2 ).to_sym
35
+ tag.inverted = true
36
+ end
37
+
38
+
39
+ ### Create a new IfTag.
40
+ def initialize( body, linenum=nil, colnum=nil )
41
+ @inverted = false
42
+ super
43
+ end
44
+
45
+ # Invert the tag's renderstate if created with the 'not' operator.
46
+ attr_accessor :inverted
47
+
22
48
 
23
49
  ### Render the tag's contents if the condition is true, or any else or elsif sections
24
50
  ### if the condition isn't true.
25
- def render( state )
51
+ def render( renderstate )
52
+
53
+ evaluated_state = self.evaluate( renderstate )
54
+ evaluated_state = ! evaluated_state if self.inverted
26
55
 
27
56
  # Start out with rendering enabled if the tag body evaluates trueishly
28
- if self.evaluate( state )
57
+ if evaluated_state
29
58
  self.log.debug "Initial state was TRUE; enabling rendering"
30
- state.enable_rendering
59
+ renderstate.enable_rendering
31
60
  else
32
61
  self.log.debug "Initial state was FALSE; disabling rendering"
33
- state.disable_rendering
62
+ renderstate.disable_rendering
34
63
  end
35
64
 
36
65
  # Set the tag state to track whether or not rendering has been enabled during the
37
66
  # 'if' for an 'else' or 'elsif' tag.
38
- state.with_tag_data( rendering_was_enabled: state.rendering_enabled? ) do
67
+ renderstate.with_tag_data( rendering_was_enabled: renderstate.rendering_enabled? ) do
39
68
  super
40
69
  end
41
70
 
42
- state.enable_rendering
71
+ renderstate.enable_rendering
43
72
  return nil
44
73
  end
45
74
 
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
 
6
8
  # Inversion import tag.
@@ -19,7 +21,7 @@ class Inversion::Template::ImportTag < Inversion::Template::Tag
19
21
  ### Ruby identifier.
20
22
  def initialize( body, linenum=nil, colnum=nil )
21
23
  super
22
- @attributes = body.split( /\s*,\s*/ ).collect {|name| name.untaint.strip.to_sym }
24
+ @attributes = body.split( /\s*,\s*/ ).collect {|name| name.strip.to_sym }
23
25
  end
24
26
 
25
27
 
@@ -1,8 +1,10 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'pathname'
5
6
  require 'inversion/mixins'
7
+ require 'inversion/template' unless defined?( Inversion::Template )
6
8
  require 'inversion/template/tag'
7
9
 
8
10
 
@@ -1,4 +1,5 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'loggability'
@@ -1,7 +1,9 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'pp'
6
+ require 'inversion/template' unless defined?( Inversion::Template )
5
7
  require 'inversion/template/calltag'
6
8
 
7
9
  # Inversion object inspection tag.
@@ -19,7 +21,7 @@ class Inversion::Template::PpTag < Inversion::Template::CallTag
19
21
  ### and return them.
20
22
  def render( render_state )
21
23
  raw = super
22
- buf = ''
24
+ buf = String.new( '' )
23
25
  PP.pp( raw, buf )
24
26
  return self.escape( buf.chomp, render_state )
25
27
  end
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
  require 'inversion/template/containertag'
6
8
 
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
 
6
8
 
@@ -1,6 +1,8 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
5
+ require 'inversion/template' unless defined?( Inversion::Template )
4
6
  require 'inversion/template/tag'
5
7
 
6
8
  # Inversion subscription tag.
@@ -1,9 +1,9 @@
1
- #!/usr/bin/env ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
  # vim: set noet nosta sw=4 ts=4 :
3
4
 
4
5
  require 'loggability'
5
6
 
6
- require 'inversion' unless defined?( Inversion )
7
7
  require 'inversion/template' unless defined?( Inversion::Template )
8
8
 
9
9
  require 'inversion/template/node'
@@ -66,7 +66,7 @@ class Inversion::Template::Tag < Inversion::Template::Node
66
66
  tags = {}
67
67
 
68
68
  Gem.find_files( TAG_PLUGIN_PATTERN ).each do |tagfile|
69
- tagname = tagfile[ %r{/(\w+?)_?tag\.rb$}, 1 ].untaint
69
+ tagname = tagfile[ %r{/(\w+?)_?tag\.rb$}, 1 ]
70
70
  next unless tagname
71
71
 
72
72
  self.load( tagfile )
@@ -121,7 +121,7 @@ class Inversion::Template::Tag < Inversion::Template::Node
121
121
  ### Create a new Inversion::Template::Tag from the specified +tagname+ and +body+.
122
122
  def self::create( tagname, body, linenum=nil, colnum=nil )
123
123
  tagname =~ /^(\w+)$/i or raise ArgumentError, "invalid tag name %p" % [ tagname ]
124
- tagtype = $1.downcase.untaint
124
+ tagtype = $1.downcase
125
125
 
126
126
  unless tagclass = self.types[ tagtype.to_sym ]
127
127
  Inversion.log.warn "Unknown tag type %p; registered: %p" %