Pimki 1.3.092 → 1.4.092

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README +145 -131
  2. data/README-PIMKI +15 -5
  3. data/app/controllers/wiki.rb +167 -54
  4. data/app/models/author.rb +3 -3
  5. data/app/models/chunks/chunk.rb +3 -3
  6. data/app/models/chunks/engines.rb +18 -21
  7. data/app/models/chunks/include.rb +29 -29
  8. data/app/models/chunks/literal.rb +20 -20
  9. data/app/models/chunks/match.rb +19 -19
  10. data/app/models/chunks/nowiki.rb +31 -31
  11. data/app/models/chunks/nowiki_test.rb +14 -14
  12. data/app/models/chunks/test.rb +18 -18
  13. data/app/models/chunks/todo.rb +44 -23
  14. data/app/models/chunks/uri.rb +97 -97
  15. data/app/models/chunks/uri_test.rb +92 -92
  16. data/app/models/chunks/wiki.rb +4 -4
  17. data/app/models/chunks/wiki_symbols.rb +22 -22
  18. data/app/models/chunks/wiki_test.rb +36 -36
  19. data/app/models/page.rb +39 -7
  20. data/app/models/page_lock.rb +23 -23
  21. data/app/models/page_set.rb +72 -72
  22. data/app/models/page_test.rb +75 -75
  23. data/app/models/revision.rb +1 -1
  24. data/app/models/revision_test.rb +251 -251
  25. data/app/models/web.rb +19 -6
  26. data/app/models/web_test.rb +52 -52
  27. data/app/models/wiki_content.rb +131 -119
  28. data/app/models/wiki_service.rb +31 -16
  29. data/app/models/wiki_service_test.rb +15 -15
  30. data/app/models/wiki_words.rb +1 -1
  31. data/app/models/wiki_words_test.rb +12 -12
  32. data/app/views/bottom.rhtml +3 -3
  33. data/app/views/markdown_help.rhtml +15 -15
  34. data/app/views/menu.rhtml +20 -20
  35. data/app/views/navigation.rhtml +26 -26
  36. data/app/views/rdoc_help.rhtml +15 -15
  37. data/app/views/static_style_sheet.rhtml +237 -237
  38. data/app/views/style.rhtml +178 -178
  39. data/app/views/textile_help.rhtml +27 -27
  40. data/app/views/top.rhtml +7 -2
  41. data/app/views/wiki/authors.rhtml +15 -15
  42. data/app/views/wiki/bliki.rhtml +101 -101
  43. data/app/views/wiki/bliki_edit.rhtml +3 -0
  44. data/app/views/wiki/bliki_new.rhtml +3 -0
  45. data/app/views/wiki/bliki_revision.rhtml +90 -90
  46. data/app/views/wiki/edit.rhtml +12 -3
  47. data/app/views/wiki/edit_menu.rhtml +64 -47
  48. data/app/views/wiki/edit_web.rhtml +65 -18
  49. data/app/views/wiki/export.rhtml +14 -14
  50. data/app/views/wiki/feeds.rhtml +10 -10
  51. data/app/views/wiki/list.rhtml +17 -15
  52. data/app/views/wiki/locked.rhtml +13 -13
  53. data/app/views/wiki/login.rhtml +10 -10
  54. data/app/views/wiki/mind.rhtml +0 -1
  55. data/app/views/wiki/new.rhtml +8 -3
  56. data/app/views/wiki/new_system.rhtml +77 -77
  57. data/app/views/wiki/new_web.rhtml +63 -63
  58. data/app/views/wiki/page.rhtml +88 -82
  59. data/app/views/wiki/print.rhtml +15 -15
  60. data/app/views/wiki/published.rhtml +2 -1
  61. data/app/views/wiki/recently_revised.rhtml +31 -31
  62. data/app/views/wiki/revision.rhtml +1 -7
  63. data/app/views/wiki/rollback.rhtml +31 -0
  64. data/app/views/wiki/rss_feed.rhtml +21 -21
  65. data/app/views/wiki/search.rhtml +48 -48
  66. data/app/views/wiki/tex.rhtml +22 -22
  67. data/app/views/wiki/tex_web.rhtml +34 -34
  68. data/app/views/wiki/todo.rhtml +90 -67
  69. data/app/views/wiki/web_list.rhtml +12 -12
  70. data/app/views/wiki_words_help.rhtml +1 -1
  71. data/favicon.png +0 -0
  72. data/libraries/action_controller_servlet.rb +17 -2
  73. data/libraries/bluecloth.rb +1127 -1127
  74. data/libraries/diff/diff.rb +474 -474
  75. data/libraries/diff/diff_test.rb +79 -79
  76. data/libraries/erb.rb +490 -490
  77. data/libraries/madeleine/automatic.rb +418 -357
  78. data/libraries/madeleine/clock.rb +94 -94
  79. data/libraries/madeleine/files.rb +19 -0
  80. data/libraries/madeleine/zmarshal.rb +60 -0
  81. data/libraries/madeleine_service.rb +14 -15
  82. data/libraries/rdocsupport.rb +155 -155
  83. data/libraries/redcloth_for_tex.rb +869 -869
  84. data/libraries/redcloth_for_tex_test.rb +40 -40
  85. data/libraries/view_helper.rb +32 -32
  86. data/libraries/web_controller_server.rb +96 -94
  87. data/pimki.rb +47 -6
  88. metadata +18 -4
@@ -1,80 +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
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
80
  end
@@ -1,490 +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(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
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
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(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
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