inversion 0.0.1 → 0.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.
Files changed (50) hide show
  1. data.tar.gz.sig +0 -0
  2. data/Manifest.txt +45 -0
  3. data/lib/inversion.rb +2 -2
  4. data/lib/inversion/template/begintag.rb +122 -0
  5. data/lib/inversion/template/defaulttag.rb +135 -0
  6. data/lib/inversion/template/rescuetag.rb +92 -0
  7. data/lib/inversion/template/timedeltatag.rb +93 -0
  8. data/manual/layouts/default.erb +87 -0
  9. data/manual/lib/api-filter.rb +96 -0
  10. data/manual/lib/editorial-filter.rb +59 -0
  11. data/manual/lib/examples-filter.rb +238 -0
  12. data/manual/lib/links-filter.rb +111 -0
  13. data/manual/resources/css/manual.css +764 -0
  14. data/manual/resources/fonts/GraublauWeb.otf +0 -0
  15. data/manual/resources/fonts/GraublauWebBold.otf +0 -0
  16. data/manual/resources/fonts/Inconsolata.otf +0 -0
  17. data/manual/resources/images/arrow_225_small.png +0 -0
  18. data/manual/resources/images/arrow_315_small.png +0 -0
  19. data/manual/resources/images/arrow_skip.png +0 -0
  20. data/manual/resources/images/cc-by.png +0 -0
  21. data/manual/resources/images/dialog-error.png +0 -0
  22. data/manual/resources/images/dialog-information.png +0 -0
  23. data/manual/resources/images/dialog-warning.png +0 -0
  24. data/manual/resources/images/emblem-important.png +0 -0
  25. data/manual/resources/images/help.png +0 -0
  26. data/manual/resources/images/information.png +0 -0
  27. data/manual/resources/images/magnifier.png +0 -0
  28. data/manual/resources/images/magnifier_left.png +0 -0
  29. data/manual/resources/images/page_white_code.png +0 -0
  30. data/manual/resources/images/page_white_copy.png +0 -0
  31. data/manual/resources/images/printer.png +0 -0
  32. data/manual/resources/images/question.png +0 -0
  33. data/manual/resources/images/scripts_code.png +0 -0
  34. data/manual/resources/images/wrap.png +0 -0
  35. data/manual/resources/images/wrapping.png +0 -0
  36. data/manual/resources/js/jquery-1.4.4.min.js +167 -0
  37. data/manual/resources/js/manual.js +30 -0
  38. data/manual/resources/js/sh.js +580 -0
  39. data/manual/resources/swf/clipboard.swf +0 -0
  40. data/manual/src/examples.page +154 -0
  41. data/manual/src/gettingstarted.page +64 -0
  42. data/manual/src/index.page +97 -0
  43. data/manual/src/tags.page +501 -0
  44. data/manual/src/templates.page +74 -0
  45. data/spec/inversion/template/begintag_spec.rb +217 -0
  46. data/spec/inversion/template/defaulttag_spec.rb +60 -0
  47. data/spec/inversion/template/rescuetag_spec.rb +109 -0
  48. data/spec/inversion/template/timedeltatag_spec.rb +215 -0
  49. metadata +72 -27
  50. metadata.gz.sig +0 -0
data.tar.gz.sig CHANGED
Binary file
data/Manifest.txt CHANGED
@@ -12,12 +12,14 @@ lib/inversion/renderstate.rb
12
12
  lib/inversion/sinatra.rb
13
13
  lib/inversion/template.rb
14
14
  lib/inversion/template/attrtag.rb
15
+ lib/inversion/template/begintag.rb
15
16
  lib/inversion/template/calltag.rb
16
17
  lib/inversion/template/codetag.rb
17
18
  lib/inversion/template/commenttag.rb
18
19
  lib/inversion/template/conditionaltag.rb
19
20
  lib/inversion/template/configtag.rb
20
21
  lib/inversion/template/containertag.rb
22
+ lib/inversion/template/defaulttag.rb
21
23
  lib/inversion/template/elsetag.rb
22
24
  lib/inversion/template/elsiftag.rb
23
25
  lib/inversion/template/endtag.rb
@@ -30,25 +32,66 @@ lib/inversion/template/node.rb
30
32
  lib/inversion/template/parser.rb
31
33
  lib/inversion/template/pptag.rb
32
34
  lib/inversion/template/publishtag.rb
35
+ lib/inversion/template/rescuetag.rb
33
36
  lib/inversion/template/subscribetag.rb
34
37
  lib/inversion/template/tag.rb
35
38
  lib/inversion/template/textnode.rb
39
+ lib/inversion/template/timedeltatag.rb
36
40
  lib/inversion/template/unlesstag.rb
37
41
  lib/inversion/template/uriencodetag.rb
38
42
  lib/inversion/template/yieldtag.rb
39
43
  lib/inversion/tilt.rb
40
44
  lib/inversion/utils.rb
45
+ manual/layouts/default.erb
46
+ manual/lib/api-filter.rb
47
+ manual/lib/editorial-filter.rb
48
+ manual/lib/examples-filter.rb
49
+ manual/lib/links-filter.rb
50
+ manual/resources/css/manual.css
51
+ manual/resources/fonts/GraublauWeb.otf
52
+ manual/resources/fonts/GraublauWebBold.otf
53
+ manual/resources/fonts/Inconsolata.otf
54
+ manual/resources/images/arrow_225_small.png
55
+ manual/resources/images/arrow_315_small.png
56
+ manual/resources/images/arrow_skip.png
57
+ manual/resources/images/cc-by.png
58
+ manual/resources/images/dialog-error.png
59
+ manual/resources/images/dialog-information.png
60
+ manual/resources/images/dialog-warning.png
61
+ manual/resources/images/emblem-important.png
62
+ manual/resources/images/help.png
63
+ manual/resources/images/information.png
64
+ manual/resources/images/magnifier.png
65
+ manual/resources/images/magnifier_left.png
66
+ manual/resources/images/page_white_code.png
67
+ manual/resources/images/page_white_copy.png
68
+ manual/resources/images/printer.png
69
+ manual/resources/images/question.png
70
+ manual/resources/images/scripts_code.png
71
+ manual/resources/images/wrap.png
72
+ manual/resources/images/wrapping.png
73
+ manual/resources/js/jquery-1.4.4.min.js
74
+ manual/resources/js/manual.js
75
+ manual/resources/js/sh.js
76
+ manual/resources/swf/clipboard.swf
77
+ manual/src/examples.page
78
+ manual/src/gettingstarted.page
79
+ manual/src/index.page
80
+ manual/src/tags.page
81
+ manual/src/templates.page
41
82
  spec/data/sinatra/hello.inversion
42
83
  spec/inversion/mixins_spec.rb
43
84
  spec/inversion/monkeypatches_spec.rb
44
85
  spec/inversion/renderstate_spec.rb
45
86
  spec/inversion/sinatra_spec.rb
46
87
  spec/inversion/template/attrtag_spec.rb
88
+ spec/inversion/template/begintag_spec.rb
47
89
  spec/inversion/template/calltag_spec.rb
48
90
  spec/inversion/template/codetag_spec.rb
49
91
  spec/inversion/template/commenttag_spec.rb
50
92
  spec/inversion/template/configtag_spec.rb
51
93
  spec/inversion/template/containertag_spec.rb
94
+ spec/inversion/template/defaulttag_spec.rb
52
95
  spec/inversion/template/elsetag_spec.rb
53
96
  spec/inversion/template/elsiftag_spec.rb
54
97
  spec/inversion/template/endtag_spec.rb
@@ -61,9 +104,11 @@ spec/inversion/template/node_spec.rb
61
104
  spec/inversion/template/parser_spec.rb
62
105
  spec/inversion/template/pptag_spec.rb
63
106
  spec/inversion/template/publishtag_spec.rb
107
+ spec/inversion/template/rescuetag_spec.rb
64
108
  spec/inversion/template/subscribetag_spec.rb
65
109
  spec/inversion/template/tag_spec.rb
66
110
  spec/inversion/template/textnode_spec.rb
111
+ spec/inversion/template/timedeltatag_spec.rb
67
112
  spec/inversion/template/unlesstag_spec.rb
68
113
  spec/inversion/template/uriencodetag_spec.rb
69
114
  spec/inversion/template/yieldtag_spec.rb
data/lib/inversion.rb CHANGED
@@ -26,10 +26,10 @@ module Inversion
26
26
  require 'inversion/monkeypatches'
27
27
 
28
28
  # Library version constant
29
- VERSION = '0.0.1'
29
+ VERSION = '0.0.2'
30
30
 
31
31
  # Version-control revision constant
32
- REVISION = %q$Revision: 73c3d8215868 $
32
+ REVISION = %q$Revision: 08e77b056c67 $
33
33
 
34
34
  #
35
35
  # Logging
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ require 'inversion/mixins'
5
+ require 'inversion/template/attrtag'
6
+ require 'inversion/template/containertag'
7
+ require 'inversion/template/conditionaltag'
8
+ require 'inversion/template/rescuetag'
9
+
10
+
11
+ # Inversion 'begin' tag.
12
+ #
13
+ # This tag causes a section of the template to be rendered only if no exceptions are raised
14
+ # while it's being rendered. If an exception is raised, it is checked against any 'rescue'
15
+ # blocks, and the first one with a matching exception is rendered instead. If no 'rescue' block
16
+ # is found, the exception is handled by the configured exception behavior for the template,
17
+ # and the resulting replaces the block.
18
+ #
19
+ # == Syntax
20
+ #
21
+ # <?begin ?><?call employees.length ?><?end?>
22
+ #
23
+ # <?begin ?>
24
+ # <?for employee in employees.all ?>
25
+ # <?attr employee.name ?> --> <?attr employee.title ?>
26
+ # <?end for?>
27
+ # <?rescue DatabaseError => err ?>
28
+ # Oh no!! I can't talk to the database for some reason. The
29
+ # error was as follows:
30
+ # <pre>
31
+ # <?attr err.message ?>
32
+ # </pre>
33
+ # <?end?>
34
+ #
35
+ class Inversion::Template::BeginTag < Inversion::Template::Tag
36
+ include Inversion::Loggable,
37
+ Inversion::Template::ContainerTag
38
+
39
+
40
+ ### Initialize a new BeginTag.
41
+ def initialize( body='', linenum=nil, colnum=nil ) # :notnew:
42
+ super
43
+ @rescue_clauses = [] # [ [RuntimeError, ArgumentError], [subnodes] ]
44
+ end
45
+
46
+
47
+ ######
48
+ public
49
+ ######
50
+
51
+ # The tuples of rescue clauses handled by the begin
52
+ attr_reader :rescue_clauses
53
+
54
+
55
+ ### Override the append operator to separate out RescueTags and the nodes that follow
56
+ ### them.
57
+ def <<( subnode )
58
+ case
59
+
60
+ # If this node is a <?rescue?>, add a container for the subnodes that belong to it
61
+ # and the list of exception types that it rescues
62
+ when subnode.is_a?( Inversion::Template::RescueTag )
63
+ @rescue_clauses << [ subnode.exception_types, [] ]
64
+
65
+ # If there's already at least one rescue clause in effect, add any subnodes to
66
+ # the last one
67
+ when !@rescue_clauses.empty?
68
+ @rescue_clauses.last[1] << subnode
69
+
70
+ # Append nodes in the begin, but before any rescue to the begin tag
71
+ else
72
+ super
73
+ end
74
+
75
+ return self
76
+ end
77
+
78
+
79
+ ### Render the tag's contents if the condition is true, or any else or elsif sections
80
+ ### if the condition isn't true.
81
+ def render( state )
82
+ output = []
83
+
84
+ errhandler = self.method( :handle_exception )
85
+ state.with_destination( output ) do
86
+ state.with_error_handler( errhandler ) do
87
+ catch( :stop_rendering ) do
88
+ self.render_subnodes( state )
89
+ end
90
+ self.log.debug " leaving the error-handler block"
91
+ end
92
+ self.log.debug " leaving the overridden output block"
93
+ end
94
+
95
+ self.log.debug "Rendered begin section as: %p" % [ output ]
96
+ return output
97
+ end
98
+
99
+
100
+ ### The replacement exception-handler provided to RenderState.
101
+ def handle_exception( state, node, exception )
102
+ self.log.debug "Handling %p raised by %p: %s" % [ exception.class, node, exception.message ]
103
+ state.destination.clear
104
+
105
+ self.rescue_clauses.each do |errclasses, nodes|
106
+ self.log.debug " considering rescue clause: %p -> %p" % [ errclasses, nodes ]
107
+ if errclasses.any? {|eclass| eclass === exception }
108
+ self.log.debug " rescued by a clause for %p" % [ errclasses ]
109
+ nodes.each {|node| state << node }
110
+ throw :stop_rendering
111
+ end
112
+ end
113
+
114
+ # Use the default error handler
115
+ self.log.debug " no rescue clause for a %p: falling back to the default error handler" %
116
+ [ exception.class ]
117
+ state.destination << state.default_error_handler( state, node, exception )
118
+ throw :stop_rendering
119
+ end
120
+
121
+ end # class Inversion::Template::BeginTag
122
+
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ require 'inversion/template/codetag'
5
+
6
+ # Inversion 'default' tag.
7
+ #
8
+ # The default tag sets the default value of an attribute to a constant, the value of
9
+ # another attribute, or the results of evaluating a methodchain on an attribute.
10
+ #
11
+ # == Syntax
12
+ # <!-- Set a default width that can be overridden by the controller -->
13
+ # <?default width to 120 ?>
14
+ # <?default employees to [] ?>
15
+ #
16
+ # <!-- Default an attribute to the value of a second attribute -->
17
+ # <?default content to body ?>
18
+ #
19
+ # <!-- Set the title to the employee's name if it hasn't been set explicitly -->
20
+ # <?default title to "%s, %s" % [ employee.lastname, employee.firstname ] ?>
21
+ #
22
+ class Inversion::Template::DefaultTag < Inversion::Template::CodeTag
23
+
24
+ # <?default «identifier» to "%s" % foo ?>
25
+ tag_pattern '$(ident) sp $(ident) sp tstring_beg $(tstring_content) tstring_end sp* $(op) sp* $( .* )' do |tag, match|
26
+ op = match.string( 4 )
27
+ raise Inversion::ParseError, "expected '%%', got %p instead" % [ op ] unless op == '%'
28
+ raise Inversion::ParseError, "invalid operator: expected 'to', got %p for %p" %
29
+ [ match.string(2), tag.body ] unless match.string(2) == 'to'
30
+
31
+ tag.name = match.string( 1 )
32
+ tag.format = match.string( 3 )
33
+ tag.literal = match.string( 5 )
34
+ end
35
+
36
+ # <?default «identifer» to «identifier».«methodchain» ?>
37
+ tag_pattern "$(ident) sp $(ident) sp $(ident) $( .* )" do |tag, match|
38
+ raise Inversion::ParseError, "invalid operator: expected 'to', got %p for %p" %
39
+ [ match.string(2), tag.body ] unless match.string(2) == 'to'
40
+
41
+ tag.name = match.string( 1 )
42
+ tag.identifiers << match.string( 3 )
43
+ tag.methodchain = match.string( 4 )
44
+ end
45
+
46
+ # <?default «identifer» to «literal» ?>
47
+ tag_pattern "$(ident) sp $(ident) sp $( .* )" do |tag, match|
48
+ raise Inversion::ParseError, "invalid operator: expected 'to', got %p for %p" %
49
+ [ match.string(2), tag.body ] unless match.string(2) == 'to'
50
+
51
+ tag.name = match.string( 1 )
52
+ tag.literal = match.string( 3 )
53
+ end
54
+
55
+
56
+ ### Create a new DefaultTag with the given +name+, which should be a valid
57
+ ### Ruby identifier.
58
+ def initialize( body, linenum=nil, colnum=nil )
59
+ @name = nil
60
+ @methodchain = nil
61
+ @literal = nil
62
+ @format = nil
63
+
64
+ super
65
+
66
+ # Add an identifier for the tag name
67
+ self.identifiers << self.name.untaint.to_sym
68
+ end
69
+
70
+
71
+ ######
72
+ public
73
+ ######
74
+
75
+ # the name of the attribute
76
+ attr_accessor :name
77
+
78
+ # the format string used to format the attribute in the template (if
79
+ # one was declared)
80
+ attr_accessor :format
81
+
82
+ # The literal, if the tag had one (as opposed to an attribute or methodchain)
83
+ attr_accessor :literal
84
+
85
+ # the chain of methods that should be called (if any).
86
+ attr_accessor :methodchain
87
+
88
+
89
+ ### Render the tag as the body of a comment, suitable for template debugging.
90
+ def as_comment_body
91
+ comment = "%s '%s': { " % [ self.tagname, self.name ]
92
+ if self.methodchain
93
+ comment << "template.%s%s" % [ self.identifiers.first, self.methodchain ]
94
+ else
95
+ comment << self.literal
96
+ end
97
+ comment << " }"
98
+ comment << " with format: %p" % [ self.format ] if self.format
99
+
100
+ return comment
101
+ end
102
+
103
+
104
+ ### Set the specified value (if it's nil) before rendering.
105
+ def before_rendering( renderstate )
106
+ if val = renderstate.attributes[ self.name.to_sym ]
107
+ self.log.info "Not defaulting %s: already set to %p" %
108
+ [ self.name, val ]
109
+ return nil
110
+ end
111
+
112
+ default = nil
113
+ if chain = self.methodchain
114
+ self.log.debug "Using methodchain %p to set default for %p" %
115
+ [ chain, self.name ]
116
+ default = renderstate.eval( 'self' + '.' + self.identifiers.first + chain )
117
+ else
118
+ self.log.debug "Using literal %p to set default for %p" %
119
+ [ self.literal, self.name ]
120
+ default = renderstate.eval( self.literal )
121
+ default = self.format % default if self.format
122
+ end
123
+
124
+ self.log.debug " default value: %p" % [ default ]
125
+ renderstate.attributes[ self.name.to_sym ] = default
126
+ end
127
+
128
+
129
+ ### Render as the empty string.
130
+ def render( renderstate )
131
+ return ''
132
+ end
133
+
134
+ end # class Inversion::Template::DefaultTag
135
+
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ require 'inversion/template/tag'
5
+
6
+
7
+ # Inversion 'rescue' tag.
8
+ #
9
+ # This tag adds a logical switch to a BeginTag. If rendering any of the BeginTag's nodes raises
10
+ # an exception of the type specified by the RescueTag, the nodes following the RescueTag are
11
+ # rendered instead.
12
+ #
13
+ # == Syntax
14
+ #
15
+ # <?begin ?>
16
+ # <?for employee in employees.all ?>
17
+ # <?attr employee.name ?> --> <?attr employee.title ?>
18
+ # <?end for?>
19
+ # <?rescue DatabaseError => err ?>
20
+ # Oh no!! I can't talk to the database for some reason. The
21
+ # error was as follows:
22
+ #
23
+ # <?attr err.message ?>
24
+ #
25
+ # <?end?>
26
+ #
27
+ class Inversion::Template::RescueTag < Inversion::Template::Tag
28
+ include Inversion::Loggable
29
+
30
+
31
+ ### Overridden to default body to nothing, and raise an error if it has one.
32
+ def initialize( body='', linenum=nil, colnum=nil ) # :notnew:
33
+ super
34
+ @exception_types = parse_exception_types( self.body )
35
+ end
36
+
37
+
38
+ ######
39
+ public
40
+ ######
41
+
42
+ # The exception classes the rescue will handle (an Array of Class objects)
43
+ attr_reader :exception_types
44
+
45
+
46
+ ### Parsing callback -- check to be sure the node tree can have the
47
+ ### 'else' tag appended to it.
48
+ def before_appending( parsestate )
49
+ condtag = parsestate.node_stack.reverse.find do |node|
50
+ case node
51
+
52
+ # If there was a previous 'begin', the 'rescue' belongs to it. Also
53
+ # allow it to be appended to a 'comment' section so you can comment out a
54
+ # rescue clause without commenting out the begin
55
+ when Inversion::Template::BeginTag,
56
+ Inversion::Template::CommentTag
57
+ break node
58
+
59
+ # If it's some other kind of container, it's an error
60
+ when Inversion::Template::ContainerTag
61
+ raise Inversion::ParseError, "'%s' tags can't have '%s' clauses" %
62
+ [ node.tagname.downcase, self.tagname.downcase ]
63
+ end
64
+ end
65
+
66
+ # If there wasn't a valid container, it's an error too
67
+ raise Inversion::ParseError, "orphaned '%s' tag" % [ self.tagname.downcase ] unless condtag
68
+ end
69
+
70
+
71
+ #######
72
+ private
73
+ #######
74
+
75
+ ### Parse one or more exception classes from the given +rescuespec+ and return them.
76
+ def parse_exception_types( rescuespec )
77
+ return [ ::RuntimeError ] if rescuespec.nil? || rescuespec == ''
78
+
79
+ # Turn a comma-delimited list of exception names into the corresponding classes
80
+ return rescuespec.split( /\s*,\s*/ ).collect do |classname|
81
+ classname.split( '::' ).
82
+ reject( &:empty? ).
83
+ inject( Object ) do |klass, name|
84
+ klass = klass.const_get( name ) or
85
+ raise "No such exception class %s" % [ classname ]
86
+ klass
87
+ end
88
+ end
89
+ end
90
+
91
+ end # class Inversion::Template::RescueTag
92
+