Pimki 1.0.092
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.
- data/README +158 -0
- data/README-PIMKI +87 -0
- data/app/controllers/wiki.rb +563 -0
- data/app/models/author.rb +4 -0
- data/app/models/chunks/category.rb +31 -0
- data/app/models/chunks/category_test.rb +21 -0
- data/app/models/chunks/chunk.rb +20 -0
- data/app/models/chunks/engines.rb +34 -0
- data/app/models/chunks/include.rb +29 -0
- data/app/models/chunks/literal.rb +19 -0
- data/app/models/chunks/match.rb +19 -0
- data/app/models/chunks/nowiki.rb +31 -0
- data/app/models/chunks/nowiki_test.rb +14 -0
- data/app/models/chunks/test.rb +18 -0
- data/app/models/chunks/todo.rb +22 -0
- data/app/models/chunks/uri.rb +97 -0
- data/app/models/chunks/uri_test.rb +92 -0
- data/app/models/chunks/wiki.rb +82 -0
- data/app/models/chunks/wiki_test.rb +36 -0
- data/app/models/page.rb +91 -0
- data/app/models/page_lock.rb +24 -0
- data/app/models/page_set.rb +73 -0
- data/app/models/page_test.rb +76 -0
- data/app/models/revision.rb +91 -0
- data/app/models/revision_test.rb +252 -0
- data/app/models/web.rb +277 -0
- data/app/models/web_test.rb +53 -0
- data/app/models/wiki_content.rb +113 -0
- data/app/models/wiki_service.rb +137 -0
- data/app/models/wiki_service_test.rb +15 -0
- data/app/models/wiki_words.rb +26 -0
- data/app/models/wiki_words_test.rb +12 -0
- data/app/views/bottom.rhtml +4 -0
- data/app/views/markdown_help.rhtml +16 -0
- data/app/views/menu.rhtml +20 -0
- data/app/views/navigation.rhtml +26 -0
- data/app/views/rdoc_help.rhtml +16 -0
- data/app/views/static_style_sheet.rhtml +231 -0
- data/app/views/style.rhtml +179 -0
- data/app/views/textile_help.rhtml +28 -0
- data/app/views/top.rhtml +52 -0
- data/app/views/wiki/authors.rhtml +15 -0
- data/app/views/wiki/bliki.rhtml +101 -0
- data/app/views/wiki/bliki_edit.rhtml +33 -0
- data/app/views/wiki/bliki_new.rhtml +61 -0
- data/app/views/wiki/bliki_revision.rhtml +51 -0
- data/app/views/wiki/edit.rhtml +34 -0
- data/app/views/wiki/edit_menu.rhtml +27 -0
- data/app/views/wiki/edit_web.rhtml +139 -0
- data/app/views/wiki/export.rhtml +14 -0
- data/app/views/wiki/feeds.rhtml +10 -0
- data/app/views/wiki/list.rhtml +164 -0
- data/app/views/wiki/locked.rhtml +14 -0
- data/app/views/wiki/login.rhtml +11 -0
- data/app/views/wiki/mind.rhtml +39 -0
- data/app/views/wiki/new.rhtml +27 -0
- data/app/views/wiki/new_system.rhtml +78 -0
- data/app/views/wiki/new_web.rhtml +64 -0
- data/app/views/wiki/page.rhtml +84 -0
- data/app/views/wiki/print.rhtml +16 -0
- data/app/views/wiki/published.rhtml +10 -0
- data/app/views/wiki/recently_revised.rhtml +31 -0
- data/app/views/wiki/revision.rhtml +87 -0
- data/app/views/wiki/rss_feed.rhtml +22 -0
- data/app/views/wiki/search.rhtml +26 -0
- data/app/views/wiki/tex.rhtml +23 -0
- data/app/views/wiki/tex_web.rhtml +35 -0
- data/app/views/wiki/todo.rhtml +39 -0
- data/app/views/wiki/web_list.rhtml +13 -0
- data/app/views/wiki_words_help.rhtml +8 -0
- data/libraries/action_controller_servlet.rb +177 -0
- data/libraries/bluecloth.rb +1127 -0
- data/libraries/diff/diff.rb +475 -0
- data/libraries/diff/diff_test.rb +80 -0
- data/libraries/erb.rb +490 -0
- data/libraries/madeleine/automatic.rb +357 -0
- data/libraries/madeleine/clock.rb +94 -0
- data/libraries/madeleine_service.rb +69 -0
- data/libraries/rdocsupport.rb +156 -0
- data/libraries/redcloth_for_tex.rb +869 -0
- data/libraries/redcloth_for_tex_test.rb +41 -0
- data/libraries/view_helper.rb +33 -0
- data/libraries/web_controller_server.rb +95 -0
- data/pimki.rb +97 -0
- metadata +169 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'diff'
|
3
|
+
|
4
|
+
include Diff
|
5
|
+
|
6
|
+
class DiffTest < Test::Unit::TestCase
|
7
|
+
def test_init
|
8
|
+
assert(1 == 1, "tests working")
|
9
|
+
assert_nothing_raised("object created") do
|
10
|
+
s = SequenceMatcher.new "private Thread currentThread;",
|
11
|
+
"private volatile Thread currentThread;",
|
12
|
+
proc { |x| x == ' ' }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_matching_blocks
|
17
|
+
s = SequenceMatcher.new "abxcd", "abcd"
|
18
|
+
assert(s.get_matching_blocks == [[0, 0, 2], [3, 2, 2], [5, 4, 0]],
|
19
|
+
"get_matching_blocks works")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_ratio
|
23
|
+
s = SequenceMatcher.new "abcd", "bcde"
|
24
|
+
assert(s.ratio == 0.75, "ratio works")
|
25
|
+
assert(s.quick_ratio == 0.75, "quick_ratio works")
|
26
|
+
assert(s.real_quick_ratio == 1.0, "real_quick_ratio works")
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_longest_match
|
30
|
+
s = SequenceMatcher.new(" abcd", "abcd abcd")
|
31
|
+
assert(s.find_longest_match(0, 5, 0, 9) == [0, 4, 5],
|
32
|
+
"find_longest_match works")
|
33
|
+
s = SequenceMatcher.new()
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_opcodes
|
37
|
+
s = SequenceMatcher.new("qabxcd", "abycdf")
|
38
|
+
assert(s.get_opcodes == [
|
39
|
+
[:delete, 0, 1, 0, 0],
|
40
|
+
[:equal, 1, 3, 0, 2],
|
41
|
+
[:replace, 3, 4, 2, 3],
|
42
|
+
[:equal, 4, 6, 3, 5],
|
43
|
+
[:insert, 6, 6, 5, 6]], "get_opcodes works")
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def test_count_leading
|
48
|
+
assert(Diff.count_leading(' abc', ' ') == 3,
|
49
|
+
"count_leading works")
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_html2list
|
53
|
+
a = "here is the original text"
|
54
|
+
#p HTMLDiff.html2list(a)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_html_diff
|
58
|
+
a = "this was the original string"
|
59
|
+
b = "this is the super string"
|
60
|
+
assert_equal 'this <del class="diffmod">was </del>' +
|
61
|
+
'<ins class="diffmod">is </ins>the ' +
|
62
|
+
'<del class="diffmod">original </del>' +
|
63
|
+
'<ins class="diffmod">super </ins>string',
|
64
|
+
HTMLDiff.diff(a, b)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_html_diff_with_multiple_paragraphs
|
68
|
+
a = "<p>this was the original string</p>"
|
69
|
+
b = "<p>this is</p>\r\n<p>the super string</p>\r\n<p>around the world</p>"
|
70
|
+
|
71
|
+
assert_equal(
|
72
|
+
"<p>this <del class=\"diffmod\">was </del>" +
|
73
|
+
"<ins class=\"diffmod\">is</ins></p>\r\n<p>the " +
|
74
|
+
"<del class=\"diffmod\">original </del>" +
|
75
|
+
"<ins class=\"diffmod\">super </ins>string</p>\r\n" +
|
76
|
+
"<p><ins class=\"diffins\">around the world</ins></p>",
|
77
|
+
HTMLDiff.diff(a, b)
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
data/libraries/erb.rb
ADDED
@@ -0,0 +1,490 @@
|
|
1
|
+
# Tiny eRuby --- ERB2
|
2
|
+
# Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI
|
3
|
+
# You can redistribute it and/or modify it under the same terms as Ruby.
|
4
|
+
|
5
|
+
class ERB
|
6
|
+
Revision = '$Date: 2004/11/09 02:03:12 $' #'
|
7
|
+
|
8
|
+
def self.version
|
9
|
+
"erb.rb [2.0.4 #{ERB::Revision.split[1]}]"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# ERB::Compiler
|
14
|
+
class ERB
|
15
|
+
class Compiler
|
16
|
+
class PercentLine
|
17
|
+
def initialize(str)
|
18
|
+
@value = str
|
19
|
+
end
|
20
|
+
attr_reader :value
|
21
|
+
alias :to_s :value
|
22
|
+
end
|
23
|
+
|
24
|
+
class Scanner
|
25
|
+
SplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/
|
26
|
+
|
27
|
+
@scanner_map = {}
|
28
|
+
def self.regist_scanner(klass, trim_mode, percent)
|
29
|
+
@scanner_map[[trim_mode, percent]] = klass
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.default_scanner=(klass)
|
33
|
+
@default_scanner = klass
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.make_scanner(src, trim_mode, percent)
|
37
|
+
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
38
|
+
klass.new(src, trim_mode, percent)
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(src, trim_mode, percent)
|
42
|
+
@src = src
|
43
|
+
@stag = nil
|
44
|
+
end
|
45
|
+
attr_accessor :stag
|
46
|
+
|
47
|
+
def scan; end
|
48
|
+
end
|
49
|
+
|
50
|
+
class TrimScanner < Scanner
|
51
|
+
TrimSplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>\n)|(%>)|(\n)/
|
52
|
+
|
53
|
+
def initialize(src, trim_mode, percent)
|
54
|
+
super
|
55
|
+
@trim_mode = trim_mode
|
56
|
+
@percent = percent
|
57
|
+
if @trim_mode == '>'
|
58
|
+
@scan_line = self.method(:trim_line1)
|
59
|
+
elsif @trim_mode == '<>'
|
60
|
+
@scan_line = self.method(:trim_line2)
|
61
|
+
elsif @trim_mode == '-'
|
62
|
+
@scan_line = self.method(:explicit_trim_line)
|
63
|
+
else
|
64
|
+
@scan_line = self.method(:scan_line)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
attr_accessor :stag
|
68
|
+
|
69
|
+
def scan(&block)
|
70
|
+
@stag = nil
|
71
|
+
if @percent
|
72
|
+
@src.each do |line|
|
73
|
+
percent_line(line, &block)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@src.each do |line|
|
77
|
+
@scan_line.call(line, &block)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def percent_line(line, &block)
|
84
|
+
if @stag || line[0] != ?%
|
85
|
+
return @scan_line.call(line, &block)
|
86
|
+
end
|
87
|
+
|
88
|
+
line[0] = ''
|
89
|
+
if line[0] == ?%
|
90
|
+
@scan_line.call(line, &block)
|
91
|
+
else
|
92
|
+
yield(PercentLine.new(line.chomp))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def scan_line(line)
|
97
|
+
line.split(SplitRegexp).each do |token|
|
98
|
+
next if token.empty?
|
99
|
+
yield(token)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def trim_line1(line)
|
104
|
+
line.split(TrimSplitRegexp).each do |token|
|
105
|
+
next if token.empty?
|
106
|
+
if token == "%>\n"
|
107
|
+
yield('%>')
|
108
|
+
yield(:cr)
|
109
|
+
break
|
110
|
+
end
|
111
|
+
yield(token)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def trim_line2(line)
|
116
|
+
head = nil
|
117
|
+
line.split(TrimSplitRegexp).each do |token|
|
118
|
+
next if token.empty?
|
119
|
+
head = token unless head
|
120
|
+
if token == "%>\n"
|
121
|
+
yield('%>')
|
122
|
+
if is_erb_stag?(head)
|
123
|
+
yield(:cr)
|
124
|
+
else
|
125
|
+
yield("\n")
|
126
|
+
end
|
127
|
+
break
|
128
|
+
end
|
129
|
+
yield(token)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
ExplicitTrimRegexp = /(^[ \t]*<%-)|(-%>\n?\z)|(<%-)|(-%>)|(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/
|
134
|
+
def explicit_trim_line(line)
|
135
|
+
line.split(ExplicitTrimRegexp).each do |token|
|
136
|
+
next if token.empty?
|
137
|
+
if @stag.nil? && /[ \t]*<%-/ =~ token
|
138
|
+
yield('<%')
|
139
|
+
elsif @stag && /-%>\n/ =~ token
|
140
|
+
yield('%>')
|
141
|
+
yield(:cr)
|
142
|
+
elsif @stag && token == '-%>'
|
143
|
+
yield('%>')
|
144
|
+
else
|
145
|
+
yield(token)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
ERB_STAG = %w(<%= <%# <%)
|
151
|
+
def is_erb_stag?(s)
|
152
|
+
ERB_STAG.member?(s)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
Scanner.default_scanner = TrimScanner
|
157
|
+
|
158
|
+
class SimpleScanner < Scanner
|
159
|
+
def scan
|
160
|
+
@src.each do |line|
|
161
|
+
line.split(SplitRegexp).each do |token|
|
162
|
+
next if token.empty?
|
163
|
+
yield(token)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
Scanner.regist_scanner(SimpleScanner, nil, false)
|
170
|
+
|
171
|
+
begin
|
172
|
+
require 'strscan'
|
173
|
+
class SimpleScanner2 < Scanner
|
174
|
+
def scan
|
175
|
+
stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|\z)/
|
176
|
+
etag_reg = /(.*?)(%%>|%>|\n|\z)/
|
177
|
+
scanner = StringScanner.new(@src)
|
178
|
+
while ! scanner.eos?
|
179
|
+
scanner.scan(@stag ? etag_reg : stag_reg)
|
180
|
+
text = scanner[1]
|
181
|
+
elem = scanner[2]
|
182
|
+
yield(text) unless text.empty?
|
183
|
+
yield(elem) unless elem.empty?
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
Scanner.regist_scanner(SimpleScanner2, nil, false)
|
188
|
+
|
189
|
+
class PercentScanner < Scanner
|
190
|
+
def scan
|
191
|
+
new_line = true
|
192
|
+
stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|\z)/
|
193
|
+
etag_reg = /(.*?)(%%>|%>|\n|\z)/
|
194
|
+
scanner = StringScanner.new(@src)
|
195
|
+
while ! scanner.eos?
|
196
|
+
if new_line && @stag.nil?
|
197
|
+
if scanner.scan(/%%/)
|
198
|
+
yield('%')
|
199
|
+
new_line = false
|
200
|
+
next
|
201
|
+
elsif scanner.scan(/%/)
|
202
|
+
yield(PercentLine.new(scanner.scan(/.*?(\n|\z)/).chomp))
|
203
|
+
next
|
204
|
+
end
|
205
|
+
end
|
206
|
+
scanner.scan(@stag ? etag_reg : stag_reg)
|
207
|
+
text = scanner[1]
|
208
|
+
elem = scanner[2]
|
209
|
+
yield(text) unless text.empty?
|
210
|
+
yield(elem) unless elem.empty?
|
211
|
+
new_line = (elem == "\n")
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
Scanner.regist_scanner(PercentScanner, nil, true)
|
216
|
+
|
217
|
+
class ExplicitScanner < Scanner
|
218
|
+
def scan
|
219
|
+
new_line = true
|
220
|
+
stag_reg = /(.*?)(<%%|<%=|<%#|<%-|<%|\n|\z)/
|
221
|
+
etag_reg = /(.*?)(%%>|-%>|%>|\n|\z)/
|
222
|
+
scanner = StringScanner.new(@src)
|
223
|
+
while ! scanner.eos?
|
224
|
+
if new_line && @stag.nil? && scanner.scan(/[ \t]*<%-/)
|
225
|
+
yield('<%')
|
226
|
+
new_line = false
|
227
|
+
next
|
228
|
+
end
|
229
|
+
scanner.scan(@stag ? etag_reg : stag_reg)
|
230
|
+
text = scanner[1]
|
231
|
+
elem = scanner[2]
|
232
|
+
new_line = (elem == "\n")
|
233
|
+
yield(text) unless text.empty?
|
234
|
+
if elem == '-%>'
|
235
|
+
yield('%>')
|
236
|
+
if scanner.scan(/(\n|\z)/)
|
237
|
+
yield(:cr)
|
238
|
+
new_line = true
|
239
|
+
end
|
240
|
+
elsif elem == '<%-'
|
241
|
+
yield('<%')
|
242
|
+
else
|
243
|
+
yield(elem) unless elem.empty?
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
Scanner.regist_scanner(ExplicitScanner, '-', false)
|
249
|
+
|
250
|
+
rescue LoadError
|
251
|
+
end
|
252
|
+
|
253
|
+
class Buffer
|
254
|
+
def initialize(compiler)
|
255
|
+
@compiler = compiler
|
256
|
+
@line = []
|
257
|
+
@script = ''
|
258
|
+
@compiler.pre_cmd.each do |x|
|
259
|
+
push(x)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
attr_reader :script
|
263
|
+
|
264
|
+
def push(cmd)
|
265
|
+
@line << cmd
|
266
|
+
end
|
267
|
+
|
268
|
+
def cr
|
269
|
+
@script << (@line.join('; '))
|
270
|
+
@line = []
|
271
|
+
@script << "\n"
|
272
|
+
end
|
273
|
+
|
274
|
+
def close
|
275
|
+
return unless @line
|
276
|
+
@compiler.post_cmd.each do |x|
|
277
|
+
push(x)
|
278
|
+
end
|
279
|
+
@script << (@line.join('; '))
|
280
|
+
@line = nil
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
class Buffer16 < Buffer
|
285
|
+
def initialize(compiler)
|
286
|
+
super(compiler)
|
287
|
+
@script = []
|
288
|
+
end
|
289
|
+
|
290
|
+
def script
|
291
|
+
@script.join('')
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def make_buffer
|
296
|
+
if RUBY_VERSION > '1.8'
|
297
|
+
Buffer.new(self)
|
298
|
+
else
|
299
|
+
Buffer16.new(self)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def compile(s)
|
304
|
+
out = make_buffer
|
305
|
+
|
306
|
+
content = ''
|
307
|
+
scanner = make_scanner(s)
|
308
|
+
scanner.scan do |token|
|
309
|
+
if scanner.stag.nil?
|
310
|
+
case token
|
311
|
+
when PercentLine
|
312
|
+
out.push("#{@put_cmd} #{content.dump}") if content.size > 0
|
313
|
+
content = ''
|
314
|
+
out.push(token.to_s)
|
315
|
+
out.cr
|
316
|
+
when :cr
|
317
|
+
out.cr
|
318
|
+
when '<%', '<%=', '<%#'
|
319
|
+
scanner.stag = token
|
320
|
+
out.push("#{@put_cmd} #{content.dump}") if content.size > 0
|
321
|
+
content = ''
|
322
|
+
when "\n"
|
323
|
+
content << "\n"
|
324
|
+
out.push("#{@put_cmd} #{content.dump}")
|
325
|
+
out.cr
|
326
|
+
content = ''
|
327
|
+
when '<%%'
|
328
|
+
content << '<%'
|
329
|
+
else
|
330
|
+
content << token
|
331
|
+
end
|
332
|
+
else
|
333
|
+
case token
|
334
|
+
when '%>'
|
335
|
+
case scanner.stag
|
336
|
+
when '<%'
|
337
|
+
if content[-1] == ?\n
|
338
|
+
content.chop!
|
339
|
+
out.push(content)
|
340
|
+
out.cr
|
341
|
+
else
|
342
|
+
out.push(content)
|
343
|
+
end
|
344
|
+
when '<%='
|
345
|
+
out.push("#{@put_cmd}((#{content}).to_s)")
|
346
|
+
when '<%#'
|
347
|
+
# out.push("# #{content.dump}")
|
348
|
+
end
|
349
|
+
scanner.stag = nil
|
350
|
+
content = ''
|
351
|
+
when '%%>'
|
352
|
+
content << '%>'
|
353
|
+
else
|
354
|
+
content << token
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
out.push("#{@put_cmd} #{content.dump}") if content.size > 0
|
359
|
+
out.close
|
360
|
+
out.script
|
361
|
+
end
|
362
|
+
|
363
|
+
def prepare_trim_mode(mode)
|
364
|
+
case mode
|
365
|
+
when 1
|
366
|
+
return [false, '>']
|
367
|
+
when 2
|
368
|
+
return [false, '<>']
|
369
|
+
when 0
|
370
|
+
return [false, nil]
|
371
|
+
when String
|
372
|
+
perc = mode.include?('%')
|
373
|
+
if mode.include?('-')
|
374
|
+
return [perc, '-']
|
375
|
+
elsif mode.include?('<>')
|
376
|
+
return [perc, '<>']
|
377
|
+
elsif mode.include?('>')
|
378
|
+
return [perc, '>']
|
379
|
+
else
|
380
|
+
[perc, nil]
|
381
|
+
end
|
382
|
+
else
|
383
|
+
return [false, nil]
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def make_scanner(src)
|
388
|
+
Scanner.make_scanner(src, @trim_mode, @percent)
|
389
|
+
end
|
390
|
+
|
391
|
+
def initialize(trim_mode)
|
392
|
+
@percent, @trim_mode = prepare_trim_mode(trim_mode)
|
393
|
+
@put_cmd = 'print'
|
394
|
+
@pre_cmd = []
|
395
|
+
@post_cmd = []
|
396
|
+
end
|
397
|
+
attr_reader :percent, :trim_mode
|
398
|
+
attr_accessor :put_cmd, :pre_cmd, :post_cmd
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
# ERB
|
403
|
+
class ERB
|
404
|
+
def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
|
405
|
+
@safe_level = safe_level
|
406
|
+
compiler = ERB::Compiler.new(trim_mode)
|
407
|
+
set_eoutvar(compiler, eoutvar)
|
408
|
+
@src = compiler.compile(str)
|
409
|
+
end
|
410
|
+
attr :src
|
411
|
+
|
412
|
+
def set_eoutvar(compiler, eoutvar = '_erbout')
|
413
|
+
compiler.put_cmd = "#{eoutvar}.concat"
|
414
|
+
|
415
|
+
cmd = []
|
416
|
+
cmd.push "#{eoutvar} = ''"
|
417
|
+
|
418
|
+
compiler.pre_cmd = cmd
|
419
|
+
|
420
|
+
cmd = []
|
421
|
+
cmd.push(eoutvar)
|
422
|
+
|
423
|
+
compiler.post_cmd = cmd
|
424
|
+
end
|
425
|
+
|
426
|
+
def run(b=TOPLEVEL_BINDING)
|
427
|
+
print self.result(b)
|
428
|
+
end
|
429
|
+
|
430
|
+
def result(b=TOPLEVEL_BINDING)
|
431
|
+
if @safe_level
|
432
|
+
th = Thread.start {
|
433
|
+
$SAFE = @safe_level
|
434
|
+
eval(@src, b)
|
435
|
+
}
|
436
|
+
return th.value
|
437
|
+
else
|
438
|
+
return eval(@src, b)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
def def_method(mod, methodname, fname='(ERB)')
|
443
|
+
mod.module_eval("def #{methodname}\n" + self.src + "\nend\n", fname, 0)
|
444
|
+
end
|
445
|
+
|
446
|
+
def def_module(methodname='erb')
|
447
|
+
mod = Module.new
|
448
|
+
def_method(mod, methodname)
|
449
|
+
mod
|
450
|
+
end
|
451
|
+
|
452
|
+
def def_class(superklass=Object, methodname='result')
|
453
|
+
cls = Class.new(superklass)
|
454
|
+
def_method(cls, methodname)
|
455
|
+
cls
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
# ERB::Util
|
460
|
+
class ERB
|
461
|
+
module Util
|
462
|
+
public
|
463
|
+
def html_escape(s)
|
464
|
+
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
465
|
+
end
|
466
|
+
alias h html_escape
|
467
|
+
|
468
|
+
def url_encode(s)
|
469
|
+
s.to_s.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
|
470
|
+
end
|
471
|
+
alias u url_encode
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
# ERB::DefMethod
|
476
|
+
class ERB
|
477
|
+
module DefMethod
|
478
|
+
public
|
479
|
+
def def_erb_method(methodname, erb)
|
480
|
+
if erb.kind_of? String
|
481
|
+
fname = erb
|
482
|
+
File.open(fname) {|f| erb = ERB.new(f.read) }
|
483
|
+
erb.def_method(self, methodname, fname)
|
484
|
+
else
|
485
|
+
erb.def_method(self, methodname)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
module_function :def_erb_method
|
489
|
+
end
|
490
|
+
end
|