inversion 1.0.0 → 1.3.1

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.
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" %