utopia 0.10.0 → 0.11.0

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 (62) hide show
  1. data/.gitignore +17 -0
  2. data/.travis.yml +9 -0
  3. data/Gemfile +8 -0
  4. data/README.md +72 -0
  5. data/Rakefile +9 -0
  6. data/bin/utopia +42 -13
  7. data/lib/utopia/extensions/array.rb +19 -3
  8. data/lib/utopia/extensions/date.rb +19 -3
  9. data/lib/utopia/extensions/hash.rb +19 -3
  10. data/lib/utopia/extensions/maybe.rb +19 -0
  11. data/lib/utopia/extensions/rack.rb +21 -3
  12. data/lib/utopia/extensions/regexp.rb +19 -3
  13. data/lib/utopia/extensions/string.rb +19 -3
  14. data/lib/utopia/http.rb +56 -0
  15. data/lib/utopia/link.rb +19 -3
  16. data/lib/utopia/middleware/all.rb +19 -3
  17. data/lib/utopia/middleware/content/node.rb +21 -5
  18. data/lib/utopia/middleware/content/processor.rb +118 -0
  19. data/lib/utopia/middleware/content.rb +22 -7
  20. data/lib/utopia/middleware/controller.rb +19 -7
  21. data/lib/utopia/middleware/directory_index.rb +19 -3
  22. data/lib/utopia/middleware/localization/name.rb +19 -3
  23. data/lib/utopia/middleware/localization.rb +19 -3
  24. data/lib/utopia/middleware/logger.rb +19 -3
  25. data/lib/utopia/middleware/redirector.rb +19 -5
  26. data/lib/utopia/middleware/requester.rb +19 -3
  27. data/lib/utopia/middleware/static.rb +20 -6
  28. data/lib/utopia/middleware.rb +22 -5
  29. data/lib/utopia/path.rb +26 -6
  30. data/lib/utopia/session/encrypted_cookie.rb +19 -3
  31. data/lib/utopia/setup/Gemfile +8 -0
  32. data/lib/utopia/setup/config.ru +4 -13
  33. data/lib/utopia/setup.rb +25 -4
  34. data/lib/utopia/tag.rb +45 -24
  35. data/lib/utopia/tags/all.rb +19 -3
  36. data/lib/utopia/tags/deferred.rb +19 -3
  37. data/lib/utopia/tags/environment.rb +29 -0
  38. data/lib/utopia/tags/node.rb +19 -3
  39. data/lib/utopia/tags/override.rb +19 -3
  40. data/lib/utopia/tags.rb +19 -3
  41. data/lib/utopia/time_store.rb +19 -3
  42. data/lib/utopia/version.rb +20 -10
  43. data/lib/utopia.rb +20 -17
  44. data/test/content_root/_heading.xnode +1 -0
  45. data/test/content_root/index.xnode +1 -0
  46. data/test/test_content_middleware.rb +86 -0
  47. data/test/test_path.rb +32 -0
  48. data/utopia.gemspec +31 -0
  49. metadata +56 -42
  50. data/ext/utopia/xnode/fast_scanner/extconf.rb +0 -6
  51. data/ext/utopia/xnode/fast_scanner/parser.c +0 -289
  52. data/lib/utopia/http_status_codes.rb +0 -39
  53. data/lib/utopia/middleware/benchmark.rb +0 -29
  54. data/lib/utopia/middleware/filter.rb +0 -35
  55. data/lib/utopia/tags/env.rb +0 -13
  56. data/lib/utopia/tags/fortune.rb +0 -9
  57. data/lib/utopia/tags/gallery.rb +0 -275
  58. data/lib/utopia/tags/google_analytics.rb +0 -21
  59. data/lib/utopia/trenni.rb +0 -149
  60. data/lib/utopia/xnode/processor.rb +0 -86
  61. data/lib/utopia/xnode/scanner.rb +0 -159
  62. data/lib/utopia/xnode.rb +0 -6
data/lib/utopia/trenni.rb DELETED
@@ -1,149 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is released under the MIT license.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- require 'strscan'
6
-
7
- module Utopia
8
- class Trenni
9
- # The output variable that will be used in templates:
10
- OUT = '_out'
11
-
12
- # Returns the output produced by calling the given block.
13
- def self.capture(*args, &block)
14
- out = eval(OUT, block.binding)
15
- top = out.size
16
-
17
- block.call *args
18
-
19
- return out.pop(out.size - top).join
20
- end
21
-
22
- # Returns the buffer used for capturing output.
23
- def self.buffer(binding)
24
- eval(OUT, binding)
25
- end
26
-
27
- class Buffer
28
- def initialize
29
- @parts = []
30
- end
31
-
32
- attr :parts
33
-
34
- def text(text)
35
- text = text.gsub('\\', '\\\\\\').gsub('@', '\\@')
36
-
37
- @parts << "#{OUT} << %q@#{text}@ ; "
38
- end
39
-
40
- def expression(text)
41
- @parts << "#{text} ; "
42
- end
43
-
44
- def output(text)
45
- @parts << "#{OUT} << (#{text}) ; "
46
- end
47
-
48
- def code
49
- parts = ["#{OUT} = [] ; "] + @parts + ["#{OUT}.join"]
50
-
51
- code = parts.join
52
- end
53
- end
54
-
55
- class Scanner < StringScanner
56
- TEXT = /([^<#]|<(?!\?r)|#(?!\{)){1,1024}/m
57
-
58
- def initialize(callback, string)
59
- @callback = callback
60
- super(string)
61
- end
62
-
63
- def parse
64
- until eos?
65
- pos = self.pos
66
-
67
- scan_text
68
- scan_expression
69
-
70
- if pos == self.pos
71
- raise StandardError.new "Could not scan current input #{self.pos} #{eos?}!"
72
- end
73
- end
74
- end
75
-
76
- def scan_text
77
- if scan(TEXT)
78
- @callback.text(matched)
79
- end
80
- end
81
-
82
- def scan_expression
83
- if scan(/\#\{/)
84
- level = 1
85
- code = ""
86
-
87
- until eos? || level == 0
88
- if scan(/[^"'\{\}]+/m)
89
- code << matched
90
- end
91
-
92
- if scan(/"(\\"|[^"])*"/m)
93
- code << matched
94
- end
95
-
96
- if scan(/'(\\'|[^'])*'/m)
97
- code << matched
98
- end
99
-
100
- if scan(/\{/)
101
- code << matched
102
- level += 1
103
- end
104
-
105
- if scan(/\}/)
106
- code << matched if level > 1
107
- level -= 1
108
- end
109
- end
110
-
111
- if level == 0
112
- @callback.output(code)
113
- else
114
- raise StandardError.new "Could not find end of expression #{self}!"
115
- end
116
- elsif scan(/<\?r/)
117
- if scan_until(/(.*?)\?>/m)
118
- @callback.expression(self[1])
119
- else
120
- raise StandardError.new "Could not find end of expression #{self}!"
121
- end
122
- end
123
- end
124
- end
125
-
126
- def self.load(path)
127
- return self.new(File.read(path), path)
128
- end
129
-
130
- def initialize(template, filename = '<Trenni>')
131
- @template = template
132
- @filename = filename
133
- compile!
134
- end
135
-
136
- def compile!(filename = @filename)
137
- buffer = Buffer.new
138
- scanner = Scanner.new(buffer, @template)
139
-
140
- scanner.parse
141
-
142
- @code = buffer.code
143
- end
144
-
145
- def result(binding)
146
- eval(@code, binding, @filename)
147
- end
148
- end
149
- end
@@ -1,86 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is released under the MIT license.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- require 'utopia/tag'
6
-
7
- module Utopia
8
- module XNode
9
- OPENED_TAG = 0
10
- CLOSED_TAG = 1
11
-
12
- class UnbalancedTagError < StandardError
13
- def initialize(scanner, start_pos, current_tag, closing_tag)
14
- @scanner = scanner
15
- @start_pos = start_pos
16
- @current_tag = current_tag
17
- @closing_tag = closing_tag
18
-
19
- @starting_line = @scanner.calculate_line_number(@start_pos)
20
- @ending_line = @scanner.calculate_line_number
21
- end
22
-
23
- def to_s
24
- "UnbalancedTagError: Tag #{@current_tag} (line #{@starting_line[0]}: #{@starting_line[4]}) has been closed by #{@closing_tag} (line #{@ending_line[0]}: #{@ending_line[4]})."
25
- end
26
- end
27
-
28
- class Processor
29
- def initialize(content, delegate, options = {})
30
- @delegate = delegate
31
- @stack = []
32
-
33
- @scanner = (options[:scanner] || Scanner).new(self, content)
34
- end
35
-
36
- def parse
37
- @scanner.parse
38
- end
39
-
40
- def cdata(text)
41
- @delegate.cdata(text)
42
- end
43
-
44
- def comment(text)
45
- cdata("<!#{text}>")
46
- end
47
-
48
- def begin_tag(tag_name, begin_tag_type)
49
- if begin_tag_type == OPENED_TAG
50
- @stack << [Tag.new(tag_name, {}), @scanner.pos]
51
- else
52
- cur, pos = @stack.pop
53
-
54
- if (tag_name != cur.name)
55
- raise UnbalancedTagError.new(@scanner, pos, cur.name, tag_name)
56
- end
57
-
58
- @delegate.tag_end(cur)
59
- end
60
- end
61
-
62
- def finish_tag(begin_tag_type, end_tag_type)
63
- if begin_tag_type == OPENED_TAG # <...
64
- if end_tag_type == CLOSED_TAG # <.../>
65
- cur, pos = @stack.pop
66
- cur.closed = true
67
-
68
- @delegate.tag_complete(cur)
69
- elsif end_tag_type == OPENED_TAG # <...>
70
- cur, pos = @stack.last
71
-
72
- @delegate.tag_begin(cur)
73
- end
74
- end
75
- end
76
-
77
- def attribute(name, value)
78
- @stack.last[0].attributes[name] = value
79
- end
80
-
81
- def instruction(content)
82
- cdata("<?#{content}?>")
83
- end
84
- end
85
- end
86
- end
@@ -1,159 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is released under the MIT license.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- require 'strscan'
6
- require 'tempfile'
7
-
8
- module Utopia
9
- module XNode
10
- class ScanError < StandardError
11
- def initialize(message, scanner)
12
- @message = message
13
-
14
- @pos = scanner.pos
15
- @line = scanner.calculate_line_number
16
- end
17
-
18
- def to_s
19
- if @line
20
- "Scan Error: #{@message} @ [#{@line[0]}:#{@line[2]}]: #{@line[4]}"
21
- else
22
- "Scan Error [#{@pos}]: #{@message}"
23
- end
24
- end
25
- end
26
-
27
- class Scanner < StringScanner
28
- CDATA = /[^<]+/m
29
- # Parse an attribute in the form of key="value" or key.
30
- ATTRIBUTE_NAME = /\s*([^\s=\/>]+)/um
31
- ATTRIBUTE_VALUE = /=((['"])(.*?)\2)/um
32
-
33
- def initialize(callback, string)
34
- @callback = callback
35
- super(string)
36
- end
37
-
38
- def calculate_line_number(at = pos)
39
- line_no = 1
40
- line_offset = offset = 0
41
-
42
- string.lines.each do |line|
43
- line_offset = offset
44
- offset += line.size
45
-
46
- if offset >= at
47
- return [line_no, line_offset, at - line_offset, offset, line]
48
- end
49
-
50
- line_no += 1
51
- end
52
-
53
- return nil
54
- end
55
-
56
- def parse
57
- until eos?
58
- pos = self.pos
59
-
60
- scan_cdata
61
- scan_tag
62
-
63
- if pos == self.pos
64
- raise ScanError.new("Scanner didn't move", self)
65
- end
66
- end
67
- end
68
-
69
- def scan_cdata
70
- if scan(CDATA)
71
- @callback.cdata(matched)
72
- end
73
- end
74
-
75
- def scan_tag
76
- if scan(/</)
77
- if scan(/\//)
78
- scan_tag_normal(CLOSED_TAG)
79
- elsif scan(/!\[CDATA\[/)
80
- scan_tag_cdata
81
- elsif scan(/!/)
82
- scan_tag_comment
83
- elsif scan(/\?/)
84
- scan_tag_instruction
85
- else
86
- scan_tag_normal
87
- end
88
- end
89
- end
90
-
91
- def scan_attributes
92
- while scan(ATTRIBUTE_NAME)
93
- name = self[1]
94
- if scan(ATTRIBUTE_VALUE)
95
- @callback.attribute(name, self[3])
96
- else
97
- @callback.attribute(name, nil)
98
- end
99
- end
100
- end
101
-
102
- def scan_tag_normal(begin_tag_type = OPENED_TAG)
103
- if scan(/[^\s\/>]+/)
104
- @callback.begin_tag(matched, begin_tag_type)
105
-
106
- scan(/\s*/)
107
-
108
- scan_attributes
109
-
110
- scan(/\s*/)
111
-
112
- if scan(/\/>/)
113
- if begin_tag_type == CLOSED_TAG
114
- raise ScanError.new("Tag cannot be closed at both ends!", self)
115
- else
116
- @callback.finish_tag(begin_tag_type, CLOSED_TAG)
117
- end
118
- elsif scan(/>/)
119
- @callback.finish_tag(begin_tag_type, OPENED_TAG)
120
- else
121
- raise ScanError.new("Invalid characters in tag!", self)
122
- end
123
- else
124
- raise ScanError.new("Invalid tag!", self)
125
- end
126
- end
127
-
128
- def scan_tag_cdata
129
- if scan_until(/(.*?)\]\]>/m)
130
- @callback.cdata(self[1].to_html)
131
- else
132
- raise ScanError.new("CDATA tag is not closed!", self)
133
- end
134
- end
135
-
136
- def scan_tag_comment
137
- if scan(/--/)
138
- if scan_until(/(.*?)-->/m)
139
- @callback.comment("--" + self[1] + "--")
140
- else
141
- raise ScanError.new("Comment is not closed!", self)
142
- end
143
- else
144
- if scan_until(/(.*?)>/)
145
- @callback.comment(self[1])
146
- else
147
- raise ScanError.new("Comment is not closed!", self)
148
- end
149
- end
150
- end
151
-
152
- def scan_tag_instruction
153
- if scan_until(/(.*)\?>/)
154
- @callback.instruction(self[1])
155
- end
156
- end
157
- end
158
- end
159
- end
data/lib/utopia/xnode.rb DELETED
@@ -1,6 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is released under the MIT license.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- require 'utopia/xnode/scanner'
6
- require 'utopia/xnode/processor'