arrow 1.0.7

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 (198) hide show
  1. data/ChangeLog +1590 -0
  2. data/LICENSE +28 -0
  3. data/README +75 -0
  4. data/Rakefile +366 -0
  5. data/Rakefile.local +63 -0
  6. data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
  7. data/data/arrow/applets/args.rb +50 -0
  8. data/data/arrow/applets/config.rb +55 -0
  9. data/data/arrow/applets/error.rb +63 -0
  10. data/data/arrow/applets/files.rb +46 -0
  11. data/data/arrow/applets/inspect.rb +46 -0
  12. data/data/arrow/applets/nosuchapplet.rb +31 -0
  13. data/data/arrow/applets/status.rb +92 -0
  14. data/data/arrow/applets/test.rb +133 -0
  15. data/data/arrow/applets/tutorial/counter.rb +96 -0
  16. data/data/arrow/applets/tutorial/dingus.rb +67 -0
  17. data/data/arrow/applets/tutorial/hello.rb +34 -0
  18. data/data/arrow/applets/tutorial/hello2.rb +73 -0
  19. data/data/arrow/applets/tutorial/imgtext.rb +90 -0
  20. data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
  21. data/data/arrow/applets/tutorial/index.rb +36 -0
  22. data/data/arrow/applets/tutorial/logo.rb +98 -0
  23. data/data/arrow/applets/tutorial/memcache.rb +61 -0
  24. data/data/arrow/applets/tutorial/missing.rb +37 -0
  25. data/data/arrow/applets/tutorial/protected.rb +100 -0
  26. data/data/arrow/applets/tutorial/redirector.rb +52 -0
  27. data/data/arrow/applets/tutorial/rndimages.rb +159 -0
  28. data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
  29. data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
  30. data/data/arrow/applets/tutorial/superhello.rb +72 -0
  31. data/data/arrow/applets/tutorial/timeclock.rb +78 -0
  32. data/data/arrow/applets/view-applet.rb +123 -0
  33. data/data/arrow/applets/view-template.rb +85 -0
  34. data/data/arrow/applets/wiki.rb +274 -0
  35. data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
  36. data/data/arrow/templates/applet-status.tmpl +153 -0
  37. data/data/arrow/templates/args-display.tmpl +120 -0
  38. data/data/arrow/templates/config/display-table.tmpl +36 -0
  39. data/data/arrow/templates/config/display.tmpl +36 -0
  40. data/data/arrow/templates/counter-deleted.tmpl +33 -0
  41. data/data/arrow/templates/counter.tmpl +59 -0
  42. data/data/arrow/templates/dingus.tmpl +55 -0
  43. data/data/arrow/templates/enumtable.tmpl +8 -0
  44. data/data/arrow/templates/error-display.tmpl +92 -0
  45. data/data/arrow/templates/filemap.tmpl +89 -0
  46. data/data/arrow/templates/hello-world-src.tmpl +34 -0
  47. data/data/arrow/templates/hello-world.tmpl +60 -0
  48. data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
  49. data/data/arrow/templates/imgtext/form.tmpl +70 -0
  50. data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
  51. data/data/arrow/templates/imgtext/reload.tmpl +55 -0
  52. data/data/arrow/templates/inspect/display.tmpl +80 -0
  53. data/data/arrow/templates/loginform.tmpl +64 -0
  54. data/data/arrow/templates/logout.tmpl +32 -0
  55. data/data/arrow/templates/memcache/display.tmpl +41 -0
  56. data/data/arrow/templates/navbar.incl +27 -0
  57. data/data/arrow/templates/nosuchapplet.tmpl +32 -0
  58. data/data/arrow/templates/printsource.tmpl +35 -0
  59. data/data/arrow/templates/protected.tmpl +36 -0
  60. data/data/arrow/templates/rndimages.tmpl +38 -0
  61. data/data/arrow/templates/service-response.tmpl +13 -0
  62. data/data/arrow/templates/sharenotes/display.tmpl +38 -0
  63. data/data/arrow/templates/status.tmpl +120 -0
  64. data/data/arrow/templates/templateviewer.tmpl +43 -0
  65. data/data/arrow/templates/test/harness.tmpl +57 -0
  66. data/data/arrow/templates/test/list.tmpl +48 -0
  67. data/data/arrow/templates/test/problem.tmpl +42 -0
  68. data/data/arrow/templates/tutorial/index.tmpl +37 -0
  69. data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
  70. data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
  71. data/data/arrow/templates/view-applet.tmpl +40 -0
  72. data/data/arrow/templates/view-template.tmpl +83 -0
  73. data/data/arrow/templates/wiki/formerror.tmpl +47 -0
  74. data/data/arrow/templates/wiki/markup_help.incl +6 -0
  75. data/data/arrow/templates/wiki/new.tmpl +56 -0
  76. data/data/arrow/templates/wiki/new_system.tmpl +122 -0
  77. data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
  78. data/data/arrow/templates/wiki/show.tmpl +34 -0
  79. data/docs/manual/layouts/default.page +43 -0
  80. data/docs/manual/lib/api-filter.rb +81 -0
  81. data/docs/manual/lib/editorial-filter.rb +64 -0
  82. data/docs/manual/lib/examples-filter.rb +244 -0
  83. data/docs/manual/lib/links-filter.rb +117 -0
  84. data/lib/apache/fakerequest.rb +448 -0
  85. data/lib/apache/logger.rb +33 -0
  86. data/lib/arrow.rb +51 -0
  87. data/lib/arrow/acceptparam.rb +207 -0
  88. data/lib/arrow/applet.rb +725 -0
  89. data/lib/arrow/appletmixins.rb +218 -0
  90. data/lib/arrow/appletregistry.rb +590 -0
  91. data/lib/arrow/applettestcase.rb +503 -0
  92. data/lib/arrow/broker.rb +255 -0
  93. data/lib/arrow/cache.rb +176 -0
  94. data/lib/arrow/config-loaders/yaml.rb +75 -0
  95. data/lib/arrow/config.rb +615 -0
  96. data/lib/arrow/constants.rb +24 -0
  97. data/lib/arrow/cookie.rb +359 -0
  98. data/lib/arrow/cookieset.rb +108 -0
  99. data/lib/arrow/dispatcher.rb +368 -0
  100. data/lib/arrow/dispatcherloader.rb +50 -0
  101. data/lib/arrow/exceptions.rb +61 -0
  102. data/lib/arrow/fallbackhandler.rb +48 -0
  103. data/lib/arrow/formvalidator.rb +631 -0
  104. data/lib/arrow/htmltokenizer.rb +343 -0
  105. data/lib/arrow/logger.rb +488 -0
  106. data/lib/arrow/logger/apacheoutputter.rb +69 -0
  107. data/lib/arrow/logger/arrayoutputter.rb +63 -0
  108. data/lib/arrow/logger/coloroutputter.rb +111 -0
  109. data/lib/arrow/logger/fileoutputter.rb +96 -0
  110. data/lib/arrow/logger/htmloutputter.rb +54 -0
  111. data/lib/arrow/logger/outputter.rb +123 -0
  112. data/lib/arrow/mixins.rb +425 -0
  113. data/lib/arrow/monkeypatches.rb +94 -0
  114. data/lib/arrow/object.rb +117 -0
  115. data/lib/arrow/path.rb +196 -0
  116. data/lib/arrow/service.rb +447 -0
  117. data/lib/arrow/session.rb +289 -0
  118. data/lib/arrow/session/dbstore.rb +100 -0
  119. data/lib/arrow/session/filelock.rb +160 -0
  120. data/lib/arrow/session/filestore.rb +132 -0
  121. data/lib/arrow/session/id.rb +98 -0
  122. data/lib/arrow/session/lock.rb +253 -0
  123. data/lib/arrow/session/md5id.rb +42 -0
  124. data/lib/arrow/session/nulllock.rb +42 -0
  125. data/lib/arrow/session/posixlock.rb +166 -0
  126. data/lib/arrow/session/sha1id.rb +54 -0
  127. data/lib/arrow/session/store.rb +366 -0
  128. data/lib/arrow/session/usertrackid.rb +52 -0
  129. data/lib/arrow/spechelpers.rb +73 -0
  130. data/lib/arrow/template.rb +713 -0
  131. data/lib/arrow/template/attr.rb +31 -0
  132. data/lib/arrow/template/call.rb +31 -0
  133. data/lib/arrow/template/comment.rb +33 -0
  134. data/lib/arrow/template/container.rb +118 -0
  135. data/lib/arrow/template/else.rb +41 -0
  136. data/lib/arrow/template/elsif.rb +44 -0
  137. data/lib/arrow/template/escape.rb +53 -0
  138. data/lib/arrow/template/export.rb +87 -0
  139. data/lib/arrow/template/for.rb +145 -0
  140. data/lib/arrow/template/if.rb +78 -0
  141. data/lib/arrow/template/import.rb +119 -0
  142. data/lib/arrow/template/include.rb +206 -0
  143. data/lib/arrow/template/iterator.rb +208 -0
  144. data/lib/arrow/template/nodes.rb +734 -0
  145. data/lib/arrow/template/parser.rb +571 -0
  146. data/lib/arrow/template/prettyprint.rb +53 -0
  147. data/lib/arrow/template/render.rb +191 -0
  148. data/lib/arrow/template/selectlist.rb +94 -0
  149. data/lib/arrow/template/set.rb +87 -0
  150. data/lib/arrow/template/timedelta.rb +81 -0
  151. data/lib/arrow/template/unless.rb +78 -0
  152. data/lib/arrow/template/urlencode.rb +51 -0
  153. data/lib/arrow/template/yield.rb +139 -0
  154. data/lib/arrow/templatefactory.rb +125 -0
  155. data/lib/arrow/testcase.rb +567 -0
  156. data/lib/arrow/transaction.rb +608 -0
  157. data/rake/191_compat.rb +26 -0
  158. data/rake/dependencies.rb +76 -0
  159. data/rake/documentation.rb +114 -0
  160. data/rake/helpers.rb +502 -0
  161. data/rake/hg.rb +282 -0
  162. data/rake/manual.rb +787 -0
  163. data/rake/packaging.rb +129 -0
  164. data/rake/publishing.rb +278 -0
  165. data/rake/style.rb +62 -0
  166. data/rake/svn.rb +668 -0
  167. data/rake/testing.rb +187 -0
  168. data/rake/verifytask.rb +64 -0
  169. data/spec/arrow/acceptparam_spec.rb +157 -0
  170. data/spec/arrow/applet_spec.rb +575 -0
  171. data/spec/arrow/appletmixins_spec.rb +409 -0
  172. data/spec/arrow/appletregistry_spec.rb +294 -0
  173. data/spec/arrow/broker_spec.rb +153 -0
  174. data/spec/arrow/config_spec.rb +224 -0
  175. data/spec/arrow/cookieset_spec.rb +164 -0
  176. data/spec/arrow/dispatcher_spec.rb +137 -0
  177. data/spec/arrow/dispatcherloader_spec.rb +65 -0
  178. data/spec/arrow/formvalidator_spec.rb +781 -0
  179. data/spec/arrow/logger_spec.rb +346 -0
  180. data/spec/arrow/mixins_spec.rb +120 -0
  181. data/spec/arrow/service_spec.rb +645 -0
  182. data/spec/arrow/session_spec.rb +121 -0
  183. data/spec/arrow/template/iterator_spec.rb +222 -0
  184. data/spec/arrow/templatefactory_spec.rb +185 -0
  185. data/spec/arrow/transaction_spec.rb +319 -0
  186. data/spec/arrow_spec.rb +37 -0
  187. data/spec/lib/appletmatchers.rb +281 -0
  188. data/spec/lib/constants.rb +77 -0
  189. data/spec/lib/helpers.rb +41 -0
  190. data/spec/lib/matchers.rb +44 -0
  191. data/tests/cookie.tests.rb +310 -0
  192. data/tests/path.tests.rb +157 -0
  193. data/tests/session.tests.rb +111 -0
  194. data/tests/session_id.tests.rb +82 -0
  195. data/tests/session_lock.tests.rb +191 -0
  196. data/tests/session_store.tests.rb +53 -0
  197. data/tests/template.tests.rb +1360 -0
  198. metadata +339 -0
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arrow/exceptions'
4
+ require 'arrow/path'
5
+ require 'arrow/template/call'
6
+
7
+ require 'pp'
8
+
9
+ # The Arrow::Template::PrettyPrintDirective class, a
10
+ # derivative of Arrow::Template::CallDirective. This is the class which
11
+ # defines the behaviour of the 'prettyprint' template directive, which
12
+ # prettyprints and HTML-escapes its associated attribute/s.
13
+ #
14
+ # == Syntax
15
+ #
16
+ # <pre><?prettyprint object ?></pre>
17
+ #
18
+ # == Authors
19
+ #
20
+ # * Michael Granger <ged@FaerieMUD.org>
21
+ #
22
+ # Please see the file LICENSE in the top-level directory for licensing details.
23
+ #
24
+ class Arrow::Template::PrettyPrintDirective < Arrow::Template::CallDirective # :nodoc:
25
+
26
+ # SVN Revision
27
+ SVNRev = %q$Rev$
28
+
29
+ # SVN Id
30
+ SVNId = %q$Id$
31
+
32
+
33
+ ### Render the content and return it as prettyprinted text.
34
+ def render( template, scope )
35
+ rawary = super
36
+ rary = []
37
+
38
+ rawary.each do |item|
39
+ ppstring = ''
40
+ PP.pp( item, ppstring )
41
+
42
+ rary << ppstring.
43
+ gsub( /&/, '&amp;' ).
44
+ gsub( /</, '&lt;' ).
45
+ gsub( />/, '&gt;' )
46
+ end
47
+
48
+ return rary
49
+ end
50
+
51
+ end # class Arrow::Template::PrettyPrint
52
+
53
+
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arrow/template/nodes'
4
+ require 'arrow/template/parser'
5
+
6
+ # The Arrow::Template::RenderDirective class, a derivative of
7
+ # Arrow::Template::Directive. This is the class which defines the
8
+ # behaviour of the 'render' template directive.
9
+ #
10
+ # === Syntax
11
+ #
12
+ # <?render foo as bar in baz.tmpl ?>
13
+ #
14
+ # == VCS Id
15
+ #
16
+ # $Id$
17
+ #
18
+ # == Authors
19
+ #
20
+ # * Michael Granger <ged@FaerieMUD.org>
21
+ #
22
+ # Please see the file LICENSE in the top-level directory for licensing details.
23
+ #
24
+ class Arrow::Template::RenderDirective < Arrow::Template::AttributeDirective # :nodoc:
25
+ include Arrow::Template::Parser::Patterns
26
+
27
+
28
+ # Parse tokens
29
+ AS = /\s+as\s+/i
30
+ IN = /in/i
31
+
32
+
33
+ #############################################################
34
+ ### C L A S S M E T H O D S
35
+ #############################################################
36
+
37
+ ### Disallow formats
38
+ def self::allows_format?; false; end
39
+
40
+
41
+ #############################################################
42
+ ### I N S T A N C E M E T H O D S
43
+ #############################################################
44
+
45
+ ### Create a new RenderDirective object.
46
+ def initialize( type, parser, state )
47
+ @target = nil
48
+ @subtemplate = nil
49
+
50
+ state[:templateCache] ||= {}
51
+
52
+ super
53
+ end
54
+
55
+
56
+ ######
57
+ public
58
+ ######
59
+
60
+ # An Array of Regexp objects which match the names of attributes to be
61
+ # rendered.
62
+ attr_reader :subtemplate
63
+
64
+
65
+ ### Return a human-readable version of the object suitable for debugging
66
+ ### messages.
67
+ def inspect
68
+ %Q{<%s %s%s as %s in %s>} % [
69
+ @type.capitalize,
70
+ @name,
71
+ @methodchain.strip.empty? ? "" : "." + @methodchain,
72
+ @target,
73
+ @subtemplate._file,
74
+ ]
75
+ end
76
+
77
+
78
+
79
+ #########
80
+ protected
81
+ #########
82
+
83
+ ### Parse the contents of the directive.
84
+ def parse_directive_contents( parser, state )
85
+ scanner = state.scanner
86
+
87
+ @name = parser.scan_for_identifier( state, true ) or
88
+ raise Arrow::ParseError, "missing or malformed identifier"
89
+
90
+ # If there's an infix operator, the rest of the tag up to the 'as' is
91
+ # the methodchain. Can't use the parser's
92
+ # #scan_for_methodchain because it just scans the rest of the tag.
93
+ if scanner.scan( INFIX )
94
+ # If the 'infix' was actually the left side of an index operator,
95
+ # include it in the methodchain.
96
+ start = scanner.matched == "[" ? scanner.pos - 1 : scanner.pos
97
+
98
+ # Find the end of the methodchain
99
+ # :FIXME: This will screw up if the methodchain itself has an ' as ' in it.
100
+ scanner.scan_until( AS ) or
101
+ raise Arrow::ParseError, "invalid render tag: no 'as' found"
102
+
103
+ # StringScanner#pre_match is broken, so we have to do the equivalent
104
+ # ourselves.
105
+ offset = scanner.pos - scanner.matched.length - 1
106
+ @methodchain = scanner.string[ start..offset ]
107
+
108
+ # No methodchain
109
+ else
110
+ scanner.scan_until( AS ) or
111
+ raise Arrow::ParseError, "invalid render tag: no 'as' found"
112
+ @methodchain = ''
113
+ self.log.debug "No methodchain parsed"
114
+ end
115
+
116
+ # Parse the target identifier
117
+ @target = parser.scan_for_identifier( state ) or
118
+ raise Arrow::ParseError, "missing or malformed target identifier"
119
+ self.log.debug "Parsed target identifier: %p" % [@target]
120
+
121
+ # Skip over the ' in ' bit
122
+ scanner.skip( WHITESPACE )
123
+ scanner.skip( IN ) or
124
+ raise Arrow::ParseError, "invalid render tag: no 'in'"
125
+ scanner.skip( WHITESPACE )
126
+
127
+ # Parse the filename of the subtemplate to load
128
+ filename = parser.scan_for_pathname( state ) or
129
+ raise Arrow::ParseError, "No filename found for 'render'"
130
+ filename.untaint
131
+ self.log.debug "Parsed subtemplate filename: %p" % [filename]
132
+
133
+ # Load and parse the subtemplate
134
+ @subtemplate = self.loadSubtemplate( filename, parser, state )
135
+ self.log.debug "Subtemplate set to: %p" % [@subtemplate]
136
+
137
+ return true
138
+ end
139
+
140
+
141
+ ### Render the directive's value via the specified attribute in the delegate
142
+ ### template.
143
+ def render_contents( template, scope )
144
+ data = super
145
+
146
+ @subtemplate.send( "#{@target}=", data )
147
+ self.log.debug "Rendering %p" % [@subtemplate]
148
+ return @subtemplate.render( nil, scope, template )
149
+ end
150
+
151
+
152
+ ### Load and parse a subtemplate from the given filename using the specified
153
+ ### parser.
154
+ def loadSubtemplate( filename, parser, state )
155
+ nodes = nil
156
+ load_path = state.template._load_path
157
+ path = Arrow::Template.find_file( filename, load_path )
158
+ subtemplate = nil
159
+
160
+ # If the template has already been loaded, just reuse the nodelist
161
+ state.data[:loadCache] ||= {}
162
+ if state.data[:loadCache].include?( path )
163
+ self.log.debug "Re-using cache template instance for %p" % path
164
+ subtemplate = state.data[:loadCache][ path ]
165
+
166
+ else
167
+ # Load the content of the file and untaint it
168
+ self.log.debug "Loading %p for the first time" % path
169
+ content = File.read( path )
170
+ content.untaint
171
+
172
+ # Load a blank template object, cache it, then parse the content
173
+ # into nodes and install the resulting syntax tree in the
174
+ # template. The template object is created before parsing so that
175
+ # recursive renders work.
176
+ initialData = state.data.dup
177
+ subtemplate = initialData[:loadCache][ path ] = Arrow::Template.new()
178
+ nodes = parser.parse( content, state.template, initialData )
179
+ subtemplate.install_syntax_tree( nodes )
180
+ end
181
+
182
+ return subtemplate
183
+ rescue Arrow::TemplateError, ::IOError => err
184
+ msg = "#{err.class.name}: Render with #{filename}: #{err.message}"
185
+ @nodes = [ Arrow::Template::CommentNode.new(msg) ]
186
+ end
187
+
188
+
189
+ end # class Arrow::Template::RenderDirective
190
+
191
+
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arrow/exceptions'
4
+ require 'arrow/path'
5
+ require 'arrow/template/nodes'
6
+
7
+ # The Arrow::Template::SelectListDirective class, a derivative of
8
+ # Arrow::Template::AttributeDirective. This is the class which defines the
9
+ # behaviour of the 'selectlist' template directive.
10
+ #
11
+ # == Syntax
12
+ #
13
+ # <?selectlist categories ?><?end?>
14
+ # <?selectlist category FROM categories ?><?end?>
15
+ # <?selectlist category FROM categories.sort_by {|c| c.name } ?><?end?>
16
+ #
17
+ # == VCS Id
18
+ #
19
+ # $Id$
20
+ #
21
+ # == Authors
22
+ #
23
+ # * Michael Granger <mgranger@rubycrafters.com>
24
+ #
25
+ # Please see the file LICENSE in the top-level directory for licensing details.
26
+ #
27
+ class Arrow::Template::SelectListDirective < Arrow::Template::BracketingDirective
28
+ include Arrow::Template::Parser::Patterns
29
+
30
+ # SVN Revision
31
+ SVNRev = %q$Rev$
32
+
33
+ # SVN Id
34
+ SVNId = %q$Id$
35
+
36
+ NAMEDLIST = CAPTURE[ IDENTIFIER ] + /\s+from\s+/i
37
+
38
+
39
+ ### This directive doesn't allow formatting.
40
+ def self::allows_format?
41
+ false
42
+ end
43
+
44
+
45
+ ### Create a new Arrow::Template::SelectListDirective object.
46
+ def initialize( body, parser, state )
47
+ @select_name = nil
48
+ super
49
+ end
50
+
51
+
52
+ ######
53
+ public
54
+ ######
55
+
56
+ attr_reader :select_name
57
+
58
+
59
+
60
+ #########
61
+ protected
62
+ #########
63
+
64
+ ### Parse the contents of the directive
65
+ def parse_directive_contents( parser, state )
66
+ state.scanner.skip( WHITESPACE )
67
+
68
+ if state.scanner.scan( NAMEDLIST )
69
+ @select_name = state.scanner[1]
70
+ end
71
+
72
+ super
73
+
74
+ return true
75
+ end
76
+
77
+
78
+ ### Render the directive's bracketed nodes once for each item in the
79
+ ### iterated content.
80
+ def render_subnodes( attribute, template, scope )
81
+ res = []
82
+
83
+ res << %{<select name="%s">\n} % [ self.select_name || self.name ]
84
+ attribute.each do |attrib|
85
+ res << %{ <option value="%s">%s</option>\n} % [ attrib, attrib ]
86
+ end
87
+ res << %{</select>\n}
88
+
89
+ return *res
90
+ end
91
+
92
+
93
+ end # class Arrow::Template::SelectListDirective
94
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arrow/template/nodes'
4
+
5
+ # The Arrow::Template::SetDirective class, a derivative of
6
+ # Arrow::Template::Directive. This is the class which defines the behaviour of
7
+ # the 'set' template directive.
8
+ #
9
+ # == Syntax
10
+ #
11
+ # <?set foo 1?>
12
+ #
13
+ # == Authors
14
+ #
15
+ # * Michael Granger <ged@FaerieMUD.org>
16
+ #
17
+ # Please see the file LICENSE in the top-level directory for licensing details.
18
+ #
19
+ class Arrow::Template::SetDirective < Arrow::Template::Directive # :nodoc:
20
+
21
+ # SVN Revision
22
+ SVNRev = %q$Rev$
23
+
24
+ # SVN Id
25
+ SVNId = %q$Id$
26
+
27
+
28
+ ### Create and return a new Arrow::Template::SetDirective object.
29
+ def initialize( type, parser, state )
30
+ @name = nil
31
+ @value = nil
32
+
33
+ super
34
+ end
35
+
36
+
37
+ ######
38
+ public
39
+ ######
40
+
41
+ # The name of the definition set by this directive.
42
+ attr_reader :name
43
+
44
+ # The raw (unevaluated) value of the definition
45
+ attr_reader :value
46
+
47
+
48
+ ### Render the directive. This adds the defined variable to the
49
+ ### +template+'s rendering +scope+ and returns an empty string (or a
50
+ ### comment if +:debuggingComments+ is turned on in the template.
51
+ def render( template, scope )
52
+ rval = super
53
+
54
+ self.log.debug "Evaling <%s> for 'set' directive." % @value
55
+ template[@name] = eval( @value, scope.get_binding, __FILE__, __LINE__ )
56
+
57
+ if template._config[:debuggingComments]
58
+ rval << template.render_comment( "Set '%s' to '%s'" %
59
+ [ @name, template[@name] ] )
60
+ end
61
+
62
+ return rval
63
+ end
64
+
65
+
66
+ #########
67
+ protected
68
+ #########
69
+
70
+ ### Parse the contents of the directive.
71
+ def parse_directive_contents( parser, state )
72
+ @name = parser.scan_for_identifier( state )
73
+
74
+ state.scanner.skip( /\s*=\s*/ )
75
+
76
+ @value = parser.scan_for_identifier( state ) ||
77
+ parser.scan_for_quoted_string( state ) or
78
+ raise Arrow::ParseError, "No value for 'set' directive"
79
+
80
+ if (( chain = parser.scan_for_methodchain(state) ))
81
+ @value << chain
82
+ end
83
+ end
84
+
85
+ end # class Arrow::Template::SetDirective
86
+
87
+
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arrow/exceptions'
4
+ require 'arrow/path'
5
+ require 'arrow/template/nodes'
6
+ require 'arrow/template/call'
7
+
8
+ # The Arrow::Template::TimeDeltaDirective class, a derivative of
9
+ # Arrow::Template::CallDirective. This plugin defines the 'timedelta' template directive.
10
+ #
11
+ # === Syntax
12
+ #
13
+ # <?timedelta process.uptime ?>
14
+ #
15
+ # == Authors
16
+ #
17
+ # * Michael Granger <ged@FaerieMUD.org>
18
+ #
19
+ #:include: LICENSE
20
+ #
21
+ #--
22
+ #
23
+ # Please see the file LICENSE in the 'docs' directory for licensing details.
24
+ #
25
+ class Arrow::Template::TimeDeltaDirective < Arrow::Template::CallDirective # :nodoc:
26
+
27
+ # Approximate Time Constants (in seconds)
28
+ MINUTES = 60
29
+ HOURS = 60 * MINUTES
30
+ DAYS = 24 * HOURS
31
+ WEEKS = 7 * DAYS
32
+ MONTHS = 30 * DAYS
33
+ YEARS = 365.25 * DAYS
34
+
35
+ ######
36
+ public
37
+ ######
38
+
39
+ ### Render the content and return it as URL-escaped text.
40
+ def render( template, scope )
41
+ rawary = super
42
+ rary = []
43
+
44
+ # Try our best to skip debugging comments
45
+ if template._config[:debuggingComments]
46
+ rary.push( rawary.shift ) if /^<!--.*-->$/ =~ rawary.first
47
+ end
48
+
49
+ rawary.each do |line|
50
+ rary << time_delta_string( line.to_i )
51
+ end
52
+
53
+ return rary
54
+ end
55
+
56
+
57
+ #######
58
+ private
59
+ #######
60
+
61
+ ### Return a string describing the amount of time in the given number of
62
+ ### seconds in terms a human can understand easily.
63
+ def time_delta_string( seconds )
64
+ return 'less than a minute' if seconds < 60
65
+
66
+ if seconds < 50 * 60
67
+ return "%d minute%s" % [seconds / 60, seconds/60 == 1 ? '' : 's']
68
+ end
69
+
70
+ return 'about an hour' if seconds < 90 * MINUTES
71
+ return "%d hours" % [seconds / HOURS] if seconds < 18 * HOURS
72
+ return 'one day' if seconds < 1 * DAYS
73
+ return 'about a day' if seconds < 2 * DAYS
74
+ return "%d days" % [seconds / DAYS] if seconds < 1 * WEEKS
75
+ return 'about a week' if seconds < 2 * WEEKS
76
+ return "%d weeks" % [seconds / WEEKS] if seconds < 3 * MONTHS
77
+ return "%d months" % [seconds / MONTHS] if seconds < 2 * YEARS
78
+ return "%d years" % [seconds / YEARS]
79
+ end
80
+
81
+ end # class Arrow::Template::URLEncodeDirective