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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +46 -0
- data/Manifest.txt +0 -1
- data/README.rdoc +10 -4
- data/Rakefile +4 -90
- data/bin/inversion +3 -1
- data/lib/inversion.rb +4 -4
- data/lib/inversion/command.rb +2 -1
- data/lib/inversion/exceptions.rb +4 -1
- data/lib/inversion/mixins.rb +30 -4
- data/lib/inversion/monkeypatches.rb +3 -2
- data/lib/inversion/parser.rb +2 -2
- data/lib/inversion/renderstate.rb +2 -1
- data/lib/inversion/sinatra.rb +4 -1
- data/lib/inversion/template.rb +3 -3
- data/lib/inversion/template/attrtag.rb +8 -6
- data/lib/inversion/template/begintag.rb +3 -1
- data/lib/inversion/template/calltag.rb +3 -1
- data/lib/inversion/template/codetag.rb +13 -2
- data/lib/inversion/template/commenttag.rb +3 -1
- data/lib/inversion/template/configtag.rb +10 -2
- data/lib/inversion/template/containertag.rb +2 -2
- data/lib/inversion/template/defaulttag.rb +4 -2
- data/lib/inversion/template/elsetag.rb +3 -1
- data/lib/inversion/template/elsiftag.rb +36 -7
- data/lib/inversion/template/endtag.rb +3 -3
- data/lib/inversion/template/escapetag.rb +3 -1
- data/lib/inversion/template/fortag.rb +14 -8
- data/lib/inversion/template/fragmenttag.rb +3 -1
- data/lib/inversion/template/iftag.rb +37 -8
- data/lib/inversion/template/importtag.rb +4 -2
- data/lib/inversion/template/includetag.rb +3 -1
- data/lib/inversion/template/node.rb +2 -1
- data/lib/inversion/template/pptag.rb +4 -2
- data/lib/inversion/template/publishtag.rb +3 -1
- data/lib/inversion/template/rescuetag.rb +3 -1
- data/lib/inversion/template/subscribetag.rb +3 -1
- data/lib/inversion/template/tag.rb +4 -4
- data/lib/inversion/template/textnode.rb +3 -1
- data/lib/inversion/template/timedeltatag.rb +16 -3
- data/lib/inversion/template/unlesstag.rb +31 -3
- data/lib/inversion/template/uriencodetag.rb +5 -5
- data/lib/inversion/template/yieldtag.rb +3 -1
- data/lib/inversion/tilt.rb +3 -1
- data/spec/helpers.rb +3 -0
- data/spec/inversion/mixins_spec.rb +14 -14
- data/spec/inversion/renderstate_spec.rb +0 -9
- data/spec/inversion/template/codetag_spec.rb +41 -1
- data/spec/inversion/template/elsiftag_spec.rb +25 -0
- data/spec/inversion/template/fortag_spec.rb +34 -2
- data/spec/inversion/template/iftag_spec.rb +11 -0
- data/spec/inversion/template/pptag_spec.rb +2 -0
- data/spec/inversion/template/timedeltatag_spec.rb +7 -0
- data/spec/inversion/template/unlesstag_spec.rb +11 -0
- data/spec/inversion/template_spec.rb +2 -6
- metadata +84 -121
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -2078
@@ -1,7 +1,9 @@
|
|
1
|
-
|
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,8 +1,11 @@
|
|
1
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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.
|
69
|
+
self.identifiers << self.name.to_sym
|
68
70
|
end
|
69
71
|
|
70
72
|
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
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'
|
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
|
-
#
|
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
|
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
|
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
|
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
|
-
|
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'
|
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
|
-
|
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 ).
|
38
|
-
tag.identifiers << match.string( 3 ).
|
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 ).
|
52
|
-
tag.identifiers << match.string( 3 ).
|
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
|
-
|
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 =
|
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,7 +1,9 @@
|
|
1
|
-
|
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
|
-
#
|
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(
|
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
|
57
|
+
if evaluated_state
|
29
58
|
self.log.debug "Initial state was TRUE; enabling rendering"
|
30
|
-
|
59
|
+
renderstate.enable_rendering
|
31
60
|
else
|
32
61
|
self.log.debug "Initial state was FALSE; disabling rendering"
|
33
|
-
|
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
|
-
|
67
|
+
renderstate.with_tag_data( rendering_was_enabled: renderstate.rendering_enabled? ) do
|
39
68
|
super
|
40
69
|
end
|
41
70
|
|
42
|
-
|
71
|
+
renderstate.enable_rendering
|
43
72
|
return nil
|
44
73
|
end
|
45
74
|
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
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.
|
24
|
+
@attributes = body.split( /\s*,\s*/ ).collect {|name| name.strip.to_sym }
|
23
25
|
end
|
24
26
|
|
25
27
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
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,7 +1,9 @@
|
|
1
|
-
|
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,9 +1,9 @@
|
|
1
|
-
|
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 ]
|
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
|
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" %
|