ua 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.settings/settings.json +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/lib/missing/erb.rb +720 -0
- data/lib/missing/ostruct.rb +284 -0
- data/lib/ua/uadb.rb +42 -0
- data/lib/ua/version.rb +3 -0
- data/lib/ua.rb +375 -0
- data/test/Hello.cpp +5 -0
- data/test/a.db +0 -0
- data/test/com.win32.cpp +39 -0
- data/test/m.html +88 -0
- data/test/temp.2.cpp +5 -0
- data/test/temp.4.cpp +5 -0
- data/test/test.js +13 -0
- data/test/test.rb +74 -0
- data/test/test2.rb +41 -0
- data/test/test3.rb +111 -0
- data/test/test4.rb +9 -0
- data/test/test5.rb +142 -0
- data/ua.gemspec +23 -0
- metadata +108 -0
data/lib/missing/erb.rb
ADDED
@@ -0,0 +1,720 @@
|
|
1
|
+
#--
|
2
|
+
# ERB::Compiler
|
3
|
+
class ERB
|
4
|
+
# = ERB::Compiler
|
5
|
+
#
|
6
|
+
# Compiles ERB templates into Ruby code; the compiled code produces the
|
7
|
+
# template result when evaluated. ERB::Compiler provides hooks to define how
|
8
|
+
# generated output is handled.
|
9
|
+
#
|
10
|
+
# Internally ERB does something like this to generate the code returned by
|
11
|
+
# ERB#src:
|
12
|
+
#
|
13
|
+
# compiler = ERB::Compiler.new('<>')
|
14
|
+
# compiler.pre_cmd = ["_erbout=''"]
|
15
|
+
# compiler.put_cmd = "_erbout.concat"
|
16
|
+
# compiler.insert_cmd = "_erbout.concat"
|
17
|
+
# compiler.post_cmd = ["_erbout"]
|
18
|
+
#
|
19
|
+
# code, enc = compiler.compile("Got <%= obj %>!\n")
|
20
|
+
# puts code
|
21
|
+
#
|
22
|
+
# <i>Generates</i>:
|
23
|
+
#
|
24
|
+
# #coding:UTF-8
|
25
|
+
# _erbout=''; _erbout.concat "Got "; _erbout.concat(( obj ).to_s); _erbout.concat "!\n"; _erbout
|
26
|
+
#
|
27
|
+
# By default the output is sent to the print method. For example:
|
28
|
+
#
|
29
|
+
# compiler = ERB::Compiler.new('<>')
|
30
|
+
# code, enc = compiler.compile("Got <%= obj %>!\n")
|
31
|
+
# puts code
|
32
|
+
#
|
33
|
+
# <i>Generates</i>:
|
34
|
+
#
|
35
|
+
# #coding:UTF-8
|
36
|
+
# print "Got "; print(( obj ).to_s); print "!\n"
|
37
|
+
#
|
38
|
+
# == Evaluation
|
39
|
+
#
|
40
|
+
# The compiled code can be used in any context where the names in the code
|
41
|
+
# correctly resolve. Using the last example, each of these print 'Got It!'
|
42
|
+
#
|
43
|
+
# Evaluate using a variable:
|
44
|
+
#
|
45
|
+
# obj = 'It'
|
46
|
+
# eval code
|
47
|
+
#
|
48
|
+
# Evaluate using an input:
|
49
|
+
#
|
50
|
+
# mod = Module.new
|
51
|
+
# mod.module_eval %{
|
52
|
+
# def get(obj)
|
53
|
+
# #{code}
|
54
|
+
# end
|
55
|
+
# }
|
56
|
+
# extend mod
|
57
|
+
# get('It')
|
58
|
+
#
|
59
|
+
# Evaluate using an accessor:
|
60
|
+
#
|
61
|
+
# klass = Class.new Object
|
62
|
+
# klass.class_eval %{
|
63
|
+
# attr_accessor :obj
|
64
|
+
# def initialize(obj)
|
65
|
+
# @obj = obj
|
66
|
+
# end
|
67
|
+
# def get_it
|
68
|
+
# #{code}
|
69
|
+
# end
|
70
|
+
# }
|
71
|
+
# klass.new('It').get_it
|
72
|
+
#
|
73
|
+
# Good! See also ERB#def_method, ERB#def_module, and ERB#def_class.
|
74
|
+
class Compiler # :nodoc:
|
75
|
+
class PercentLine # :nodoc:
|
76
|
+
def initialize(str)
|
77
|
+
@value = str
|
78
|
+
end
|
79
|
+
attr_reader :value
|
80
|
+
alias :to_s :value
|
81
|
+
|
82
|
+
def empty?
|
83
|
+
@value.empty?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Scanner # :nodoc:
|
88
|
+
@scanner_map = {}
|
89
|
+
def self.regist_scanner(klass, trim_mode, percent)
|
90
|
+
@scanner_map[[trim_mode, percent]] = klass
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.default_scanner=(klass)
|
94
|
+
@default_scanner = klass
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.make_scanner(src, trim_mode, percent)
|
98
|
+
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
99
|
+
klass.new(src, trim_mode, percent)
|
100
|
+
end
|
101
|
+
|
102
|
+
def initialize(src, trim_mode, percent)
|
103
|
+
@src = src
|
104
|
+
@stag = nil
|
105
|
+
end
|
106
|
+
attr_accessor :stag
|
107
|
+
|
108
|
+
def scan; end
|
109
|
+
end
|
110
|
+
|
111
|
+
class TrimScanner < Scanner # :nodoc:
|
112
|
+
def initialize(src, trim_mode, percent)
|
113
|
+
super
|
114
|
+
@trim_mode = trim_mode
|
115
|
+
@percent = percent
|
116
|
+
if @trim_mode == '>'
|
117
|
+
@scan_line = self.method(:trim_line1)
|
118
|
+
elsif @trim_mode == '<>'
|
119
|
+
@scan_line = self.method(:trim_line2)
|
120
|
+
elsif @trim_mode == '-'
|
121
|
+
@scan_line = self.method(:explicit_trim_line)
|
122
|
+
else
|
123
|
+
@scan_line = self.method(:scan_line)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
attr_accessor :stag
|
127
|
+
|
128
|
+
def scan(&block)
|
129
|
+
@stag = nil
|
130
|
+
if @percent
|
131
|
+
@src.each_line do |line|
|
132
|
+
percent_line(line, &block)
|
133
|
+
end
|
134
|
+
else
|
135
|
+
@scan_line.call(@src, &block)
|
136
|
+
end
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def percent_line(line, &block)
|
141
|
+
if @stag || line[0] != ?%
|
142
|
+
return @scan_line.call(line, &block)
|
143
|
+
end
|
144
|
+
|
145
|
+
line[0] = ''
|
146
|
+
if line[0] == ?%
|
147
|
+
@scan_line.call(line, &block)
|
148
|
+
else
|
149
|
+
yield(PercentLine.new(line.chomp))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def scan_line(line)
|
154
|
+
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
|
155
|
+
tokens.each do |token|
|
156
|
+
next if token.empty?
|
157
|
+
yield(token)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def trim_line1(line)
|
163
|
+
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
|
164
|
+
tokens.each do |token|
|
165
|
+
next if token.empty?
|
166
|
+
if token == "%>\n"
|
167
|
+
yield('%>')
|
168
|
+
yield(:cr)
|
169
|
+
else
|
170
|
+
yield(token)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def trim_line2(line)
|
177
|
+
head = nil
|
178
|
+
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
|
179
|
+
tokens.each do |token|
|
180
|
+
next if token.empty?
|
181
|
+
head = token unless head
|
182
|
+
if token == "%>\n"
|
183
|
+
yield('%>')
|
184
|
+
if is_erb_stag?(head)
|
185
|
+
yield(:cr)
|
186
|
+
else
|
187
|
+
yield("\n")
|
188
|
+
end
|
189
|
+
head = nil
|
190
|
+
else
|
191
|
+
yield(token)
|
192
|
+
head = nil if token == "\n"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def explicit_trim_line(line)
|
199
|
+
line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
|
200
|
+
tokens.each do |token|
|
201
|
+
next if token.empty?
|
202
|
+
if @stag.nil? && /[ \t]*<%-/ =~ token
|
203
|
+
yield('<%')
|
204
|
+
elsif @stag && token == "-%>\n"
|
205
|
+
yield('%>')
|
206
|
+
yield(:cr)
|
207
|
+
elsif @stag && token == '-%>'
|
208
|
+
yield('%>')
|
209
|
+
else
|
210
|
+
yield(token)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
ERB_STAG = %w(<%= <%# <%)
|
217
|
+
def is_erb_stag?(s)
|
218
|
+
ERB_STAG.member?(s)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
Scanner.default_scanner = TrimScanner
|
223
|
+
|
224
|
+
class SimpleScanner < Scanner # :nodoc:
|
225
|
+
def scan
|
226
|
+
@src.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
|
227
|
+
tokens.each do |token|
|
228
|
+
next if token.empty?
|
229
|
+
yield(token)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
Scanner.regist_scanner(SimpleScanner, nil, false)
|
236
|
+
|
237
|
+
begin
|
238
|
+
require 'strscan.rb'
|
239
|
+
class SimpleScanner2 < Scanner # :nodoc:
|
240
|
+
def scan
|
241
|
+
stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
|
242
|
+
etag_reg = /(.*?)(%%>|%>|\z)/m
|
243
|
+
scanner = StringScanner.new(@src)
|
244
|
+
while ! scanner.eos?
|
245
|
+
scanner.scan(@stag ? etag_reg : stag_reg)
|
246
|
+
yield(scanner[1])
|
247
|
+
yield(scanner[2])
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
Scanner.regist_scanner(SimpleScanner2, nil, false)
|
252
|
+
|
253
|
+
class ExplicitScanner < Scanner # :nodoc:
|
254
|
+
def scan
|
255
|
+
stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
|
256
|
+
etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
|
257
|
+
scanner = StringScanner.new(@src)
|
258
|
+
while ! scanner.eos?
|
259
|
+
scanner.scan(@stag ? etag_reg : stag_reg)
|
260
|
+
yield(scanner[1])
|
261
|
+
|
262
|
+
elem = scanner[2]
|
263
|
+
if /[ \t]*<%-/ =~ elem
|
264
|
+
yield('<%')
|
265
|
+
elsif elem == '-%>'
|
266
|
+
yield('%>')
|
267
|
+
yield(:cr) if scanner.scan(/(\n|\z)/)
|
268
|
+
else
|
269
|
+
yield(elem)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
Scanner.regist_scanner(ExplicitScanner, '-', false)
|
275
|
+
|
276
|
+
rescue LoadError
|
277
|
+
end
|
278
|
+
|
279
|
+
class Buffer # :nodoc:
|
280
|
+
def initialize(compiler, enc=nil)
|
281
|
+
@compiler = compiler
|
282
|
+
@line = []
|
283
|
+
@script = enc ? "#coding:#{enc.to_s}\n" : ""
|
284
|
+
@compiler.pre_cmd.each do |x|
|
285
|
+
push(x)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
attr_reader :script
|
289
|
+
|
290
|
+
def push(cmd)
|
291
|
+
@line << cmd
|
292
|
+
end
|
293
|
+
|
294
|
+
def cr
|
295
|
+
@script << (@line.join('; '))
|
296
|
+
@line = []
|
297
|
+
@script << "\n"
|
298
|
+
end
|
299
|
+
|
300
|
+
def close
|
301
|
+
return unless @line
|
302
|
+
@compiler.post_cmd.each do |x|
|
303
|
+
push(x)
|
304
|
+
end
|
305
|
+
@script << (@line.join('; '))
|
306
|
+
@line = nil
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def content_dump(s) # :nodoc:
|
311
|
+
n = s.count("\n")
|
312
|
+
if n > 0
|
313
|
+
s.dump + "\n" * n
|
314
|
+
else
|
315
|
+
s.dump
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Compiles an ERB template into Ruby code. Returns an array of the code
|
320
|
+
# and encoding like ["code", Encoding].
|
321
|
+
def compile(s)
|
322
|
+
out = Buffer.new(self)
|
323
|
+
content = ''
|
324
|
+
scanner = make_scanner(s)
|
325
|
+
scanner.scan do |token|
|
326
|
+
next if token.nil?
|
327
|
+
next if token == ''
|
328
|
+
if scanner.stag.nil?
|
329
|
+
case token
|
330
|
+
when PercentLine
|
331
|
+
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
332
|
+
content = ''
|
333
|
+
out.push(token.to_s)
|
334
|
+
out.cr
|
335
|
+
when :cr
|
336
|
+
out.cr
|
337
|
+
when '<%', '<%=', '<%#'
|
338
|
+
scanner.stag = token
|
339
|
+
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
340
|
+
content = ''
|
341
|
+
when "\n"
|
342
|
+
content << "\n"
|
343
|
+
out.push("#{@put_cmd} #{content_dump(content)}")
|
344
|
+
content = ''
|
345
|
+
when '<%%'
|
346
|
+
content << '<%'
|
347
|
+
else
|
348
|
+
content << token
|
349
|
+
end
|
350
|
+
else
|
351
|
+
case token
|
352
|
+
when '%>'
|
353
|
+
case scanner.stag
|
354
|
+
when '<%'
|
355
|
+
if content[-1] == ?\n
|
356
|
+
content.chop!
|
357
|
+
out.push(content)
|
358
|
+
out.cr
|
359
|
+
else
|
360
|
+
out.push(content)
|
361
|
+
end
|
362
|
+
when '<%='
|
363
|
+
out.push("#{@insert_cmd}((#{content}).to_s)")
|
364
|
+
when '<%#'
|
365
|
+
# out.push("# #{content_dump(content)}")
|
366
|
+
end
|
367
|
+
scanner.stag = nil
|
368
|
+
content = ''
|
369
|
+
when '%%>'
|
370
|
+
content << '%>'
|
371
|
+
else
|
372
|
+
content << token
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
377
|
+
out.close
|
378
|
+
return out.script
|
379
|
+
end
|
380
|
+
|
381
|
+
def prepare_trim_mode(mode) # :nodoc:
|
382
|
+
case mode
|
383
|
+
when 1
|
384
|
+
return [false, '>']
|
385
|
+
when 2
|
386
|
+
return [false, '<>']
|
387
|
+
when 0
|
388
|
+
return [false, nil]
|
389
|
+
when String
|
390
|
+
perc = mode.include?('%')
|
391
|
+
if mode.include?('-')
|
392
|
+
return [perc, '-']
|
393
|
+
elsif mode.include?('<>')
|
394
|
+
return [perc, '<>']
|
395
|
+
elsif mode.include?('>')
|
396
|
+
return [perc, '>']
|
397
|
+
else
|
398
|
+
[perc, nil]
|
399
|
+
end
|
400
|
+
else
|
401
|
+
return [false, nil]
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
def make_scanner(src) # :nodoc:
|
406
|
+
Scanner.make_scanner(src, @trim_mode, @percent)
|
407
|
+
end
|
408
|
+
|
409
|
+
# Construct a new compiler using the trim_mode. See ERB#new for available
|
410
|
+
# trim modes.
|
411
|
+
def initialize(trim_mode)
|
412
|
+
@percent, @trim_mode = prepare_trim_mode(trim_mode)
|
413
|
+
@put_cmd = 'print'
|
414
|
+
@insert_cmd = @put_cmd
|
415
|
+
@pre_cmd = []
|
416
|
+
@post_cmd = []
|
417
|
+
end
|
418
|
+
attr_reader :percent, :trim_mode
|
419
|
+
|
420
|
+
# The command to handle text that ends with a newline
|
421
|
+
attr_accessor :put_cmd
|
422
|
+
|
423
|
+
# The command to handle text that is inserted prior to a newline
|
424
|
+
attr_accessor :insert_cmd
|
425
|
+
|
426
|
+
# An array of commands prepended to compiled code
|
427
|
+
attr_accessor :pre_cmd
|
428
|
+
|
429
|
+
# An array of commands appended to compiled code
|
430
|
+
attr_accessor :post_cmd
|
431
|
+
|
432
|
+
private
|
433
|
+
def detect_magic_comment(s)
|
434
|
+
if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s)
|
435
|
+
comment = $1
|
436
|
+
comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
|
437
|
+
if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
|
438
|
+
enc = $1.sub(/-(?:mac|dos|unix)/i, '')
|
439
|
+
enc = Encoding.find(enc)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
#--
|
447
|
+
# ERB
|
448
|
+
class ERB
|
449
|
+
#
|
450
|
+
# Constructs a new ERB object with the template specified in _str_.
|
451
|
+
#
|
452
|
+
# An ERB object works by building a chunk of Ruby code that will output
|
453
|
+
# the completed template when run. If _safe_level_ is set to a non-nil value,
|
454
|
+
# ERB code will be run in a separate thread with <b>$SAFE</b> set to the
|
455
|
+
# provided level.
|
456
|
+
#
|
457
|
+
# If _trim_mode_ is passed a String containing one or more of the following
|
458
|
+
# modifiers, ERB will adjust its code generation as listed:
|
459
|
+
#
|
460
|
+
# % enables Ruby code processing for lines beginning with %
|
461
|
+
# <> omit newline for lines starting with <% and ending in %>
|
462
|
+
# > omit newline for lines ending in %>
|
463
|
+
#
|
464
|
+
# _eoutvar_ can be used to set the name of the variable ERB will build up
|
465
|
+
# its output in. This is useful when you need to run multiple ERB
|
466
|
+
# templates through the same binding and/or when you want to control where
|
467
|
+
# output ends up. Pass the name of the variable to be used inside a String.
|
468
|
+
#
|
469
|
+
# === Example
|
470
|
+
#
|
471
|
+
# require "erb"
|
472
|
+
#
|
473
|
+
# # build data class
|
474
|
+
# class Listings
|
475
|
+
# PRODUCT = { :name => "Chicken Fried Steak",
|
476
|
+
# :desc => "A well messages pattie, breaded and fried.",
|
477
|
+
# :cost => 9.95 }
|
478
|
+
#
|
479
|
+
# attr_reader :product, :price
|
480
|
+
#
|
481
|
+
# def initialize( product = "", price = "" )
|
482
|
+
# @product = product
|
483
|
+
# @price = price
|
484
|
+
# end
|
485
|
+
#
|
486
|
+
# def build
|
487
|
+
# b = binding
|
488
|
+
# # create and run templates, filling member data variables
|
489
|
+
# ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
|
490
|
+
# <%= PRODUCT[:name] %>
|
491
|
+
# <%= PRODUCT[:desc] %>
|
492
|
+
# END_PRODUCT
|
493
|
+
# ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
|
494
|
+
# <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
|
495
|
+
# <%= PRODUCT[:desc] %>
|
496
|
+
# END_PRICE
|
497
|
+
# end
|
498
|
+
# end
|
499
|
+
#
|
500
|
+
# # setup template data
|
501
|
+
# listings = Listings.new
|
502
|
+
# listings.build
|
503
|
+
#
|
504
|
+
# puts listings.product + "\n" + listings.price
|
505
|
+
#
|
506
|
+
# _Generates_
|
507
|
+
#
|
508
|
+
# Chicken Fried Steak
|
509
|
+
# A well messages pattie, breaded and fried.
|
510
|
+
#
|
511
|
+
# Chicken Fried Steak -- 9.95
|
512
|
+
# A well messages pattie, breaded and fried.
|
513
|
+
#
|
514
|
+
def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
|
515
|
+
@safe_level = safe_level
|
516
|
+
compiler = ERB::Compiler.new(trim_mode)
|
517
|
+
set_eoutvar(compiler, eoutvar)
|
518
|
+
*@src = *compiler.compile(str)
|
519
|
+
@src.push(";" + eoutvar)
|
520
|
+
@src = @src.join
|
521
|
+
@filename = nil
|
522
|
+
end
|
523
|
+
|
524
|
+
# The Ruby code generated by ERB
|
525
|
+
attr_reader :src
|
526
|
+
|
527
|
+
# The optional _filename_ argument passed to Kernel#eval when the ERB code
|
528
|
+
# is run
|
529
|
+
attr_accessor :filename
|
530
|
+
|
531
|
+
#
|
532
|
+
# Can be used to set _eoutvar_ as described in ERB#new. It's probably easier
|
533
|
+
# to just use the constructor though, since calling this method requires the
|
534
|
+
# setup of an ERB _compiler_ object.
|
535
|
+
#
|
536
|
+
def set_eoutvar(compiler, eoutvar = '_erbout')
|
537
|
+
compiler.put_cmd = "#{eoutvar}.concat"
|
538
|
+
compiler.insert_cmd = "#{eoutvar}.concat"
|
539
|
+
|
540
|
+
cmd = []
|
541
|
+
cmd.push "#{eoutvar} = ''"
|
542
|
+
|
543
|
+
compiler.pre_cmd = cmd
|
544
|
+
|
545
|
+
cmd = []
|
546
|
+
|
547
|
+
compiler.post_cmd = cmd
|
548
|
+
end
|
549
|
+
|
550
|
+
# Generate results and print them. (see ERB#result)
|
551
|
+
def run(b=TOPLEVEL_BINDING)
|
552
|
+
print self.result(b)
|
553
|
+
end
|
554
|
+
|
555
|
+
#
|
556
|
+
# Executes the generated ERB code to produce a completed template, returning
|
557
|
+
# the results of that code. (See ERB#new for details on how this process can
|
558
|
+
# be affected by _safe_level_.)
|
559
|
+
#
|
560
|
+
# _b_ accepts a Binding or Proc object which is used to set the context of
|
561
|
+
# code evaluation.
|
562
|
+
#
|
563
|
+
def result(b=TOPLEVEL_BINDING)
|
564
|
+
if @safe_level
|
565
|
+
proc {
|
566
|
+
$SAFE = @safe_level
|
567
|
+
eval(@src, b, (@filename || '(erb)'), 0)
|
568
|
+
}.call
|
569
|
+
else
|
570
|
+
eval(@src, b, (@filename || '(erb)'), 0)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# Define _methodname_ as instance method of _mod_ from compiled ruby source.
|
575
|
+
#
|
576
|
+
# example:
|
577
|
+
# filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml
|
578
|
+
# erb = ERB.new(File.read(filename))
|
579
|
+
# erb.def_method(MyClass, 'render(arg1, arg2)', filename)
|
580
|
+
# print MyClass.new.render('foo', 123)
|
581
|
+
def def_method(mod, methodname, fname='(ERB)')
|
582
|
+
src = self.src
|
583
|
+
magic_comment = "#coding:#{@enc}\n"
|
584
|
+
mod.module_eval do
|
585
|
+
eval(magic_comment + "def #{methodname}\n" + src + "\nend\n", binding, fname, -2)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
# Create unnamed module, define _methodname_ as instance method of it, and return it.
|
590
|
+
#
|
591
|
+
# example:
|
592
|
+
# filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml
|
593
|
+
# erb = ERB.new(File.read(filename))
|
594
|
+
# erb.filename = filename
|
595
|
+
# MyModule = erb.def_module('render(arg1, arg2)')
|
596
|
+
# class MyClass
|
597
|
+
# include MyModule
|
598
|
+
# end
|
599
|
+
def def_module(methodname='erb')
|
600
|
+
mod = Module.new
|
601
|
+
def_method(mod, methodname, @filename || '(ERB)')
|
602
|
+
mod
|
603
|
+
end
|
604
|
+
|
605
|
+
# Define unnamed class which has _methodname_ as instance method, and return it.
|
606
|
+
#
|
607
|
+
# example:
|
608
|
+
# class MyClass_
|
609
|
+
# def initialize(arg1, arg2)
|
610
|
+
# @arg1 = arg1; @arg2 = arg2
|
611
|
+
# end
|
612
|
+
# end
|
613
|
+
# filename = 'example.rhtml' # @arg1 and @arg2 are used in example.rhtml
|
614
|
+
# erb = ERB.new(File.read(filename))
|
615
|
+
# erb.filename = filename
|
616
|
+
# MyClass = erb.def_class(MyClass_, 'render()')
|
617
|
+
# print MyClass.new('foo', 123).render()
|
618
|
+
def def_class(superklass=Object, methodname='result')
|
619
|
+
cls = Class.new(superklass)
|
620
|
+
def_method(cls, methodname, @filename || '(ERB)')
|
621
|
+
cls
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
625
|
+
#--
|
626
|
+
# ERB::Util
|
627
|
+
class ERB
|
628
|
+
# A utility module for conversion routines, often handy in HTML generation.
|
629
|
+
module Util
|
630
|
+
public
|
631
|
+
#
|
632
|
+
# A utility method for escaping HTML tag characters in _s_.
|
633
|
+
#
|
634
|
+
# require "erb"
|
635
|
+
# include ERB::Util
|
636
|
+
#
|
637
|
+
# puts html_escape("is a > 0 & a < 10?")
|
638
|
+
#
|
639
|
+
# _Generates_
|
640
|
+
#
|
641
|
+
# is a > 0 & a < 10?
|
642
|
+
#
|
643
|
+
def html_escape(s)
|
644
|
+
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
645
|
+
end
|
646
|
+
alias h html_escape
|
647
|
+
module_function :h
|
648
|
+
module_function :html_escape
|
649
|
+
|
650
|
+
#
|
651
|
+
# A utility method for encoding the String _s_ as a URL.
|
652
|
+
#
|
653
|
+
# require "erb"
|
654
|
+
# include ERB::Util
|
655
|
+
#
|
656
|
+
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
657
|
+
#
|
658
|
+
# _Generates_
|
659
|
+
#
|
660
|
+
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
661
|
+
#
|
662
|
+
def url_encode(s)
|
663
|
+
s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
|
664
|
+
sprintf("%%%02X", $&.unpack("C")[0])
|
665
|
+
}
|
666
|
+
end
|
667
|
+
alias u url_encode
|
668
|
+
module_function :u
|
669
|
+
module_function :url_encode
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
#--
|
674
|
+
# ERB::DefMethod
|
675
|
+
class ERB
|
676
|
+
# Utility module to define eRuby script as instance method.
|
677
|
+
#
|
678
|
+
# === Example
|
679
|
+
#
|
680
|
+
# example.rhtml:
|
681
|
+
# <% for item in @items %>
|
682
|
+
# <b><%= item %></b>
|
683
|
+
# <% end %>
|
684
|
+
#
|
685
|
+
# example.rb:
|
686
|
+
# require 'erb'
|
687
|
+
# class MyClass
|
688
|
+
# extend ERB::DefMethod
|
689
|
+
# def_erb_method('render()', 'example.rhtml')
|
690
|
+
# def initialize(items)
|
691
|
+
# @items = items
|
692
|
+
# end
|
693
|
+
# end
|
694
|
+
# print MyClass.new([10,20,30]).render()
|
695
|
+
#
|
696
|
+
# result:
|
697
|
+
#
|
698
|
+
# <b>10</b>
|
699
|
+
#
|
700
|
+
# <b>20</b>
|
701
|
+
#
|
702
|
+
# <b>30</b>
|
703
|
+
#
|
704
|
+
module DefMethod
|
705
|
+
public
|
706
|
+
# define _methodname_ as instance method of current module, using ERB
|
707
|
+
# object or eRuby file
|
708
|
+
def def_erb_method(methodname, erb_or_fname)
|
709
|
+
if erb_or_fname.kind_of? String
|
710
|
+
fname = erb_or_fname
|
711
|
+
erb = ERB.new(File.read(fname))
|
712
|
+
erb.def_method(self, methodname, fname)
|
713
|
+
else
|
714
|
+
erb = erb_or_fname
|
715
|
+
erb.def_method(self, methodname, erb.filename || '(ERB)')
|
716
|
+
end
|
717
|
+
end
|
718
|
+
module_function :def_erb_method
|
719
|
+
end
|
720
|
+
end
|