utopia 0.9.43 → 0.9.45

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,10 @@ class String
10
10
  gsub(HTML_ESCAPE_PATTERN){|c| HTML_ESCAPE[c]}
11
11
  end
12
12
 
13
+ def to_quoted_string
14
+ '"' + self.gsub('"', '\\"').gsub(/\r/, "\\r").gsub(/\n/, "\\n") + '"'
15
+ end
16
+
13
17
  def to_title
14
18
  (" " + self).gsub(/[ \-_](.)/){" " + $1.upcase}.strip
15
19
  end
@@ -8,7 +8,7 @@ require 'utopia/path'
8
8
  require 'utopia/tags'
9
9
 
10
10
  require 'utopia/middleware/content/node'
11
- require 'utopia/etanni'
11
+ require 'utopia/trenni'
12
12
 
13
13
  module Utopia
14
14
  module Middleware
@@ -32,7 +32,7 @@ module Utopia
32
32
  attr :passthrough
33
33
 
34
34
  def fetch_xml(path)
35
- read_file = lambda { TemplateCache.new(path, Etanni) }
35
+ read_file = lambda { Trenni.new(File.read(path), path) }
36
36
 
37
37
  if @files
38
38
  @files.fetch(path) do
@@ -0,0 +1,127 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
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
+ class Buffer
10
+ def initialize
11
+ @parts = []
12
+ end
13
+
14
+ attr :parts
15
+
16
+ def text(text)
17
+ text = text.gsub('\\', '\\\\\\').gsub('@', '\\@')
18
+
19
+ @parts << "_out << %q@#{text}@ ; "
20
+ end
21
+
22
+ def expression(text)
23
+ @parts << "#{text} ; "
24
+ end
25
+
26
+ def output(text)
27
+ @parts << "_out << #{text} ; "
28
+ end
29
+
30
+ def code
31
+ parts = ['_out = [] ; '] + @parts + ['_out.join']
32
+
33
+ code = parts.join
34
+ end
35
+ end
36
+
37
+ class Scanner < StringScanner
38
+ def initialize(callback, string)
39
+ @callback = callback
40
+ super(string)
41
+ end
42
+
43
+ def parse
44
+ until eos?
45
+ pos = self.pos
46
+
47
+ scan_text
48
+ scan_expression
49
+
50
+ if pos == self.pos
51
+ raise StandardError.new "Could not scan current input #{self.pos} #{eos?}!"
52
+ end
53
+ end
54
+ end
55
+
56
+ def scan_text
57
+ if scan_until(/(.*?)(?=\#\{|<\?r)/m) || scan(/(.*)\Z/m)
58
+ @callback.text(self[1]) if self[1].size > 0
59
+ end
60
+ end
61
+
62
+ def scan_expression
63
+ if scan(/\#\{/)
64
+ done = false
65
+ code = ""
66
+
67
+ until eos? || done
68
+ if scan(/[^"'\{\}]+/m)
69
+ code << matched
70
+ end
71
+
72
+ if scan(/"(\\"|[^"])*"/m)
73
+ code << matched
74
+ end
75
+
76
+ if scan(/'(\\'|[^'])*'/m)
77
+ code << matched
78
+ end
79
+
80
+ if scan(/\{[^\}]*\}/m)
81
+ code << matched
82
+ end
83
+
84
+ if scan(/\}/)
85
+ done = true
86
+ end
87
+ end
88
+
89
+ if done
90
+ @callback.output(code)
91
+ else
92
+ raise StandardError.new "Could not find end of expression #{self}!"
93
+ end
94
+ elsif scan(/<\?r/)
95
+ if scan_until(/(.*?)\?>/m)
96
+ @callback.expression(self[1])
97
+ else
98
+ raise StandardError.new "Could not find end of expression #{self}!"
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ def self.load(path)
105
+ return self.new(File.read(path), path)
106
+ end
107
+
108
+ def initialize(template, filename = '<Trenni>')
109
+ @template = template
110
+ @filename = filename
111
+ compile!
112
+ end
113
+
114
+ def compile!(filename = @filename)
115
+ buffer = Buffer.new
116
+ scanner = Scanner.new(buffer, @template)
117
+
118
+ scanner.parse
119
+
120
+ @code = buffer.code
121
+ end
122
+
123
+ def result(binding)
124
+ eval(@code, binding, @filename)
125
+ end
126
+ end
127
+ end
@@ -6,7 +6,7 @@ module Utopia
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 9
9
- TINY = 43
9
+ TINY = 45
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
  end
@@ -74,6 +74,8 @@ module Utopia
74
74
  if scan(/</)
75
75
  if scan(/\//)
76
76
  scan_tag_normal(CLOSED_TAG)
77
+ elsif scan(/!\[CDATA\[/)
78
+ scan_tag_cdata
77
79
  elsif scan(/!/)
78
80
  scan_tag_comment
79
81
  elsif scan(/\?/)
@@ -115,7 +117,15 @@ module Utopia
115
117
  raise ScanError.new("Invalid tag!", self)
116
118
  end
117
119
  end
118
-
120
+
121
+ def scan_tag_cdata
122
+ if scan_until(/(.*?)\]\]>/m)
123
+ @callback.cdata(self[1].to_html)
124
+ else
125
+ raise ScanError.new("CDATA tag is not closed!", self)
126
+ end
127
+ end
128
+
119
129
  def scan_tag_comment
120
130
  if scan(/--/)
121
131
  if scan_until(/(.*?)-->/m)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: utopia
3
3
  version: !ruby/object:Gem::Version
4
- hash: 109
4
+ hash: 97
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 43
10
- version: 0.9.43
9
+ - 45
10
+ version: 0.9.45
11
11
  platform: ruby
12
12
  authors:
13
13
  - Samuel Williams
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-26 00:00:00 +13:00
18
+ date: 2011-02-09 00:00:00 +13:00
19
19
  default_executable: utopia
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -99,7 +99,6 @@ extra_rdoc_files: []
99
99
  files:
100
100
  - ext/utopia/xnode/fast_scanner/extconf.rb
101
101
  - ext/utopia/xnode/fast_scanner/parser.c
102
- - lib/utopia/etanni.rb
103
102
  - lib/utopia/extensions/array.rb
104
103
  - lib/utopia/extensions/date.rb
105
104
  - lib/utopia/extensions/hash.rb
@@ -147,6 +146,7 @@ files:
147
146
  - lib/utopia/tags/override.rb
148
147
  - lib/utopia/tags.rb
149
148
  - lib/utopia/time_store.rb
149
+ - lib/utopia/trenni.rb
150
150
  - lib/utopia/version.rb
151
151
  - lib/utopia/xnode/processor.rb
152
152
  - lib/utopia/xnode/scanner.rb
@@ -1,85 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- # [Etanni] Copyright (c) 2008 Michael Fellinger <m.fellinger@gmail.com>
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining a copy
8
- # of this software and associated documentation files (the "Software"), to
9
- # deal in the Software without restriction, including without limitation the
10
- # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11
- # sell copies of the Software, and to permit persons to whom the Software is
12
- # furnished to do so, subject to the following conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be included in
15
- # all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
- # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
- # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- require 'digest/md5'
25
-
26
- module Utopia
27
-
28
- class Etanni
29
- SEPARATOR = Digest::MD5.hexdigest(Time.new.to_s)
30
- START = "\n_out_ << <<#{SEPARATOR}.chomp!\n"
31
- STOP = "\n#{SEPARATOR}\n"
32
- REPLACEMENT = "#{STOP}\\1#{START}"
33
-
34
- def initialize(template, compiled = false)
35
- if compiled
36
- @compiled = template
37
- else
38
- @template = template
39
- compile!
40
- end
41
- end
42
-
43
- def compile!
44
- temp = @template.dup
45
- temp.strip!
46
- temp.gsub!(/<\?r\s+(.*?)\s+\?>/m, REPLACEMENT)
47
- @compiled = "_out_ = [<<#{SEPARATOR}.chomp!]\n#{temp}#{STOP}_out_"
48
- end
49
-
50
- def result(binding, filename = '<Etanni>')
51
- eval(@compiled, binding, filename).join
52
- end
53
-
54
- attr :compiled
55
- end
56
-
57
- class TemplateCache
58
- CACHE_PREFIX = ".cache."
59
- CACHE_ENABLED = true
60
-
61
- def self.cache_path(path)
62
- File.join(File.dirname(path), CACHE_PREFIX + File.basename(path))
63
- end
64
-
65
- def self.mtime(path)
66
- File.symlink?(path) ? File.lstat(file_name).mtime : File.mtime(path)
67
- end
68
-
69
- def initialize(path, template_class = Etanni)
70
- @path = path
71
- @cache_path = TemplateCache.cache_path(@path)
72
-
73
- if !File.exist?(@cache_path) || (TemplateCache.mtime(@path) > TemplateCache.mtime(@cache_path))
74
- @template = template_class.new(File.read(@path))
75
- File.open(@cache_path, "w") { |f| f.write(@template.compiled) }
76
- else
77
- @template = template_class.new(File.read(@cache_path), true)
78
- end
79
- end
80
-
81
- def result(binding)
82
- @template.result(binding, @cache_path)
83
- end
84
- end
85
- end