campfire-bot_alexchee 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +11 -0
- data/.gitignore +6 -0
- data/Gemfile +12 -0
- data/README.textile +62 -0
- data/TODO +72 -0
- data/bin/campfire-bot +59 -0
- data/campfire-bot.gemspec +24 -0
- data/cfbot-stop.sh +8 -0
- data/config.example.yml +32 -0
- data/lib/bot.rb +194 -0
- data/lib/event.rb +114 -0
- data/lib/message.rb +30 -0
- data/lib/plugin.rb +77 -0
- data/lib/version.rb +3 -0
- data/plugins-example/fun.rb +95 -0
- data/spec/command_spec.rb +96 -0
- data/spec/plugin_spec.rb +43 -0
- data/spec/spec.opts +1 -0
- data/tmp/.gitignore +0 -0
- data/vendor/escape/ChangeLog +30 -0
- data/vendor/escape/Makefile +5 -0
- data/vendor/escape/README +81 -0
- data/vendor/escape/VERSION +1 -0
- data/vendor/escape/escape.rb +302 -0
- data/vendor/escape/install.rb +109 -0
- data/vendor/escape/misc/README.erb +85 -0
- data/vendor/escape/rdoc/classes/Escape/HTMLAttrValue.html +113 -0
- data/vendor/escape/rdoc/classes/Escape/HTMLEscaped.html +113 -0
- data/vendor/escape/rdoc/classes/Escape/PercentEncoded.html +113 -0
- data/vendor/escape/rdoc/classes/Escape/ShellEscaped.html +113 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.html +242 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000029.html +18 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000030.html +18 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000031.html +18 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000032.html +18 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000033.html +18 -0
- data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000035.html +18 -0
- data/vendor/escape/rdoc/classes/Escape.html +427 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000022.html +19 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000023.html +32 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000024.html +24 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000025.html +19 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000026.html +48 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000027.html +19 -0
- data/vendor/escape/rdoc/classes/Escape.src/M000028.html +19 -0
- data/vendor/escape/rdoc/classes/TestEscapeHTML.html +182 -0
- data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000008.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000009.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000010.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000011.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.html +182 -0
- data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000012.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000013.html +19 -0
- data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000014.html +20 -0
- data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000015.html +22 -0
- data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.html +167 -0
- data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000016.html +18 -0
- data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000017.html +20 -0
- data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000018.html +20 -0
- data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.html +167 -0
- data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000019.html +20 -0
- data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000020.html +24 -0
- data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000021.html +22 -0
- data/vendor/escape/rdoc/files/escape_rb.html +136 -0
- data/vendor/escape/rdoc/files/install_rb.html +250 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000001.html +23 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000002.html +31 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000003.html +27 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000004.html +27 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000005.html +21 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000006.html +23 -0
- data/vendor/escape/rdoc/files/install_rb.src/M000007.html +21 -0
- data/vendor/escape/rdoc/files/test/test-escape_rb.html +109 -0
- data/vendor/escape/rdoc/fr_class_index.html +36 -0
- data/vendor/escape/rdoc/fr_file_index.html +29 -0
- data/vendor/escape/rdoc/fr_method_index.html +61 -0
- data/vendor/escape/rdoc/index.html +24 -0
- data/vendor/escape/rdoc/rdoc-style.css +208 -0
- data/vendor/escape/test/test-escape.rb +90 -0
- metadata +209 -0
@@ -0,0 +1,302 @@
|
|
1
|
+
# escape.rb - escape/unescape library for several formats
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006,2007 Tanaka Akira <akr@fsij.org>
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# 3. The name of the author may not be used to endorse or promote products
|
14
|
+
# derived from this software without specific prior written permission.
|
15
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
17
|
+
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
18
|
+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
19
|
+
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
21
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
24
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
25
|
+
# OF SUCH DAMAGE.
|
26
|
+
|
27
|
+
# Escape module provides several escape functions.
|
28
|
+
# * URI
|
29
|
+
# * HTML
|
30
|
+
# * shell command
|
31
|
+
module Escape
|
32
|
+
module_function
|
33
|
+
|
34
|
+
class StringWrapper
|
35
|
+
class << self
|
36
|
+
alias new_no_dup new
|
37
|
+
def new(str)
|
38
|
+
new_no_dup(str.dup)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(str)
|
43
|
+
@str = str
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
@str.dup
|
48
|
+
end
|
49
|
+
|
50
|
+
def inspect
|
51
|
+
"\#<#{self.class}: #{@str}>"
|
52
|
+
end
|
53
|
+
|
54
|
+
def ==(other)
|
55
|
+
other.class == self.class && @str == other.instance_variable_get(:@str)
|
56
|
+
end
|
57
|
+
alias eql? ==
|
58
|
+
|
59
|
+
def hash
|
60
|
+
@str.hash
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class ShellEscaped < StringWrapper
|
65
|
+
end
|
66
|
+
|
67
|
+
# Escape.shell_command composes
|
68
|
+
# a sequence of words to
|
69
|
+
# a single shell command line.
|
70
|
+
# All shell meta characters are quoted and
|
71
|
+
# the words are concatenated with interleaving space.
|
72
|
+
# It returns an instance of ShellEscaped.
|
73
|
+
#
|
74
|
+
# Escape.shell_command(["ls", "/"]) #=> #<Escape::ShellEscaped: ls />
|
75
|
+
# Escape.shell_command(["echo", "*"]) #=> #<Escape::ShellEscaped: echo '*'>
|
76
|
+
#
|
77
|
+
# Note that system(*command) and
|
78
|
+
# system(Escape.shell_command(command)) is roughly same.
|
79
|
+
# There are two exception as follows.
|
80
|
+
# * The first is that the later may invokes /bin/sh.
|
81
|
+
# * The second is an interpretation of an array with only one element:
|
82
|
+
# the element is parsed by the shell with the former but
|
83
|
+
# it is recognized as single word with the later.
|
84
|
+
# For example, system(*["echo foo"]) invokes echo command with an argument "foo".
|
85
|
+
# But system(Escape.shell_command(["echo foo"])) invokes "echo foo" command without arguments (and it probably fails).
|
86
|
+
def shell_command(command)
|
87
|
+
s = command.map {|word| shell_single_word(word) }.join(' ')
|
88
|
+
ShellEscaped.new_no_dup(s)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Escape.shell_single_word quotes shell meta characters.
|
92
|
+
# It returns an instance of ShellEscaped.
|
93
|
+
#
|
94
|
+
# The result string is always single shell word, even if
|
95
|
+
# the argument is "".
|
96
|
+
# Escape.shell_single_word("") returns #<Escape::ShellEscaped: ''>.
|
97
|
+
#
|
98
|
+
# Escape.shell_single_word("") #=> #<Escape::ShellEscaped: ''>
|
99
|
+
# Escape.shell_single_word("foo") #=> #<Escape::ShellEscaped: foo>
|
100
|
+
# Escape.shell_single_word("*") #=> #<Escape::ShellEscaped: '*'>
|
101
|
+
def shell_single_word(str)
|
102
|
+
if str.empty?
|
103
|
+
ShellEscaped.new_no_dup("''")
|
104
|
+
elsif %r{\A[0-9A-Za-z+,./:=@_-]+\z} =~ str
|
105
|
+
ShellEscaped.new(str)
|
106
|
+
else
|
107
|
+
result = ''
|
108
|
+
str.scan(/('+)|[^']+/) {
|
109
|
+
if $1
|
110
|
+
result << %q{\'} * $1.length
|
111
|
+
else
|
112
|
+
result << "'#{$&}'"
|
113
|
+
end
|
114
|
+
}
|
115
|
+
ShellEscaped.new_no_dup(result)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class PercentEncoded < StringWrapper
|
120
|
+
end
|
121
|
+
|
122
|
+
# Escape.uri_segment escapes URI segment using percent-encoding.
|
123
|
+
# It returns an instance of PercentEncoded.
|
124
|
+
#
|
125
|
+
# Escape.uri_segment("a/b") #=> #<Escape::PercentEncoded: a%2Fb>
|
126
|
+
#
|
127
|
+
# The segment is "/"-splitted element after authority before query in URI, as follows.
|
128
|
+
#
|
129
|
+
# scheme://authority/segment1/segment2/.../segmentN?query#fragment
|
130
|
+
#
|
131
|
+
# See RFC 3986 for details of URI.
|
132
|
+
def uri_segment(str)
|
133
|
+
# pchar - pct-encoded = unreserved / sub-delims / ":" / "@"
|
134
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
135
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
136
|
+
s = str.gsub(%r{[^A-Za-z0-9\-._~!$&'()*+,;=:@]}n) {
|
137
|
+
'%' + $&.unpack("H2")[0].upcase
|
138
|
+
}
|
139
|
+
PercentEncoded.new_no_dup(s)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Escape.uri_path escapes URI path using percent-encoding.
|
143
|
+
# The given path should be a sequence of (non-escaped) segments separated by "/".
|
144
|
+
# The segments cannot contains "/".
|
145
|
+
# It returns an instance of PercentEncoded.
|
146
|
+
#
|
147
|
+
# Escape.uri_path("a/b/c") #=> #<Escape::PercentEncoded: a/b/c>
|
148
|
+
# Escape.uri_path("a?b/c?d/e?f") #=> #<Escape::PercentEncoded: a%3Fb/c%3Fd/e%3Ff>
|
149
|
+
#
|
150
|
+
# The path is the part after authority before query in URI, as follows.
|
151
|
+
#
|
152
|
+
# scheme://authority/path#fragment
|
153
|
+
#
|
154
|
+
# See RFC 3986 for details of URI.
|
155
|
+
#
|
156
|
+
# Note that this function is not appropriate to convert OS path to URI.
|
157
|
+
def uri_path(str)
|
158
|
+
s = str.gsub(%r{[^/]+}n) { uri_segment($&) }
|
159
|
+
PercentEncoded.new_no_dup(s)
|
160
|
+
end
|
161
|
+
|
162
|
+
# :stopdoc:
|
163
|
+
def html_form_fast(pairs, sep='&')
|
164
|
+
s = pairs.map {|k, v|
|
165
|
+
# query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
|
166
|
+
# unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
|
167
|
+
# query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
|
168
|
+
# query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
|
169
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
170
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
171
|
+
# x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
|
172
|
+
k = k.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
|
173
|
+
'%' + $&.unpack("H2")[0].upcase
|
174
|
+
}
|
175
|
+
v = v.gsub(%r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n) {
|
176
|
+
'%' + $&.unpack("H2")[0].upcase
|
177
|
+
}
|
178
|
+
"#{k}=#{v}"
|
179
|
+
}.join(sep)
|
180
|
+
PercentEncoded.new_no_dup(s)
|
181
|
+
end
|
182
|
+
# :startdoc:
|
183
|
+
|
184
|
+
# Escape.html_form composes HTML form key-value pairs as a x-www-form-urlencoded encoded string.
|
185
|
+
# It returns an instance of PercentEncoded.
|
186
|
+
#
|
187
|
+
# Escape.html_form takes an array of pair of strings or
|
188
|
+
# an hash from string to string.
|
189
|
+
#
|
190
|
+
# Escape.html_form([["a","b"], ["c","d"]]) #=> #<Escape::PercentEncoded: a=b&c=d>
|
191
|
+
# Escape.html_form({"a"=>"b", "c"=>"d"}) #=> #<Escape::PercentEncoded: a=b&c=d>
|
192
|
+
#
|
193
|
+
# In the array form, it is possible to use same key more than once.
|
194
|
+
# (It is required for a HTML form which contains
|
195
|
+
# checkboxes and select element with multiple attribute.)
|
196
|
+
#
|
197
|
+
# Escape.html_form([["k","1"], ["k","2"]]) #=> #<Escape::PercentEncoded: k=1&k=2>
|
198
|
+
#
|
199
|
+
# If the strings contains characters which must be escaped in x-www-form-urlencoded,
|
200
|
+
# they are escaped using %-encoding.
|
201
|
+
#
|
202
|
+
# Escape.html_form([["k=","&;="]]) #=> #<Escape::PercentEncoded: k%3D=%26%3B%3D>
|
203
|
+
#
|
204
|
+
# The separator can be specified by the optional second argument.
|
205
|
+
#
|
206
|
+
# Escape.html_form([["a","b"], ["c","d"]], ";") #=> #<Escape::PercentEncoded: a=b;c=d>
|
207
|
+
#
|
208
|
+
# See HTML 4.01 for details.
|
209
|
+
def html_form(pairs, sep='&')
|
210
|
+
r = ''
|
211
|
+
first = true
|
212
|
+
pairs.each {|k, v|
|
213
|
+
# query-chars - pct-encoded - x-www-form-urlencoded-delimiters =
|
214
|
+
# unreserved / "!" / "$" / "'" / "(" / ")" / "*" / "," / ":" / "@" / "/" / "?"
|
215
|
+
# query-char - pct-encoded = unreserved / sub-delims / ":" / "@" / "/" / "?"
|
216
|
+
# query-char = pchar / "/" / "?" = unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?"
|
217
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
218
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
219
|
+
# x-www-form-urlencoded-delimiters = "&" / "+" / ";" / "="
|
220
|
+
r << sep if !first
|
221
|
+
first = false
|
222
|
+
k.each_byte {|byte|
|
223
|
+
ch = byte.chr
|
224
|
+
if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
|
225
|
+
r << "%" << ch.unpack("H2")[0].upcase
|
226
|
+
else
|
227
|
+
r << ch
|
228
|
+
end
|
229
|
+
}
|
230
|
+
r << '='
|
231
|
+
v.each_byte {|byte|
|
232
|
+
ch = byte.chr
|
233
|
+
if %r{[^0-9A-Za-z\-\._~:/?@!\$'()*,]}n =~ ch
|
234
|
+
r << "%" << ch.unpack("H2")[0].upcase
|
235
|
+
else
|
236
|
+
r << ch
|
237
|
+
end
|
238
|
+
}
|
239
|
+
}
|
240
|
+
PercentEncoded.new_no_dup(r)
|
241
|
+
end
|
242
|
+
|
243
|
+
class HTMLEscaped < StringWrapper
|
244
|
+
end
|
245
|
+
|
246
|
+
# :stopdoc:
|
247
|
+
HTML_TEXT_ESCAPE_HASH = {
|
248
|
+
'&' => '&',
|
249
|
+
'<' => '<',
|
250
|
+
'>' => '>',
|
251
|
+
}
|
252
|
+
# :startdoc:
|
253
|
+
|
254
|
+
# Escape.html_text escapes a string appropriate for HTML text using character references.
|
255
|
+
# It returns an instance of HTMLEscaped.
|
256
|
+
#
|
257
|
+
# It escapes 3 characters:
|
258
|
+
# * '&' to '&'
|
259
|
+
# * '<' to '<'
|
260
|
+
# * '>' to '>'
|
261
|
+
#
|
262
|
+
# Escape.html_text("abc") #=> #<Escape::HTMLEscaped: abc>
|
263
|
+
# Escape.html_text("a & b < c > d") #=> #<Escape::HTMLEscaped: a & b < c > d>
|
264
|
+
#
|
265
|
+
# This function is not appropriate for escaping HTML element attribute
|
266
|
+
# because quotes are not escaped.
|
267
|
+
def html_text(str)
|
268
|
+
s = str.gsub(/[&<>]/) {|ch| HTML_TEXT_ESCAPE_HASH[ch] }
|
269
|
+
HTMLEscaped.new_no_dup(s)
|
270
|
+
end
|
271
|
+
|
272
|
+
# :stopdoc:
|
273
|
+
HTML_ATTR_ESCAPE_HASH = {
|
274
|
+
'&' => '&',
|
275
|
+
'<' => '<',
|
276
|
+
'>' => '>',
|
277
|
+
'"' => '"',
|
278
|
+
}
|
279
|
+
# :startdoc:
|
280
|
+
|
281
|
+
class HTMLAttrValue < StringWrapper
|
282
|
+
end
|
283
|
+
|
284
|
+
# Escape.html_attr_value encodes a string as a double-quoted HTML attribute using character references.
|
285
|
+
# It returns an instance of HTMLAttrValue.
|
286
|
+
#
|
287
|
+
# Escape.html_attr_value("abc") #=> #<Escape::HTMLAttrValue: "abc">
|
288
|
+
# Escape.html_attr_value("a&b") #=> #<Escape::HTMLAttrValue: "a&b">
|
289
|
+
# Escape.html_attr_value("ab&<>\"c") #=> #<Escape::HTMLAttrValue: "ab&<>"c">
|
290
|
+
# Escape.html_attr_value("a'c") #=> #<Escape::HTMLAttrValue: "a'c">
|
291
|
+
#
|
292
|
+
# It escapes 4 characters:
|
293
|
+
# * '&' to '&'
|
294
|
+
# * '<' to '<'
|
295
|
+
# * '>' to '>'
|
296
|
+
# * '"' to '"'
|
297
|
+
#
|
298
|
+
def html_attr_value(str)
|
299
|
+
s = '"' + str.gsub(/[&<>"]/) {|ch| HTML_ATTR_ESCAPE_HASH[ch] } + '"'
|
300
|
+
HTMLAttrValue.new_no_dup(s)
|
301
|
+
end
|
302
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# usage: ruby install.rb [-n]
|
4
|
+
# options:
|
5
|
+
# -n : don't install
|
6
|
+
#
|
7
|
+
# Author: Tanaka Akira <akr@m17n.org>
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
require 'fileutils'
|
11
|
+
|
12
|
+
def target_directory
|
13
|
+
$:.each {|loc|
|
14
|
+
if %r{/site_ruby/[\d.]+\z} =~ loc
|
15
|
+
return loc
|
16
|
+
end
|
17
|
+
}
|
18
|
+
raise "could not find target install directory"
|
19
|
+
end
|
20
|
+
|
21
|
+
CVS_FILES = {}
|
22
|
+
def cvs_files(dir)
|
23
|
+
return CVS_FILES[dir] if CVS_FILES.include? dir
|
24
|
+
if File.directory? "#{dir}/CVS"
|
25
|
+
result = {}
|
26
|
+
File.foreach("#{dir}/CVS/Entries") {|line|
|
27
|
+
case line
|
28
|
+
when %r{\A/([^/]+)/} then result[$1] = true
|
29
|
+
when %r{\AD/([^/]+)/} then result[$1] = true
|
30
|
+
end
|
31
|
+
}
|
32
|
+
else
|
33
|
+
result = nil
|
34
|
+
end
|
35
|
+
CVS_FILES[dir] = result
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
def each_target(&block)
|
40
|
+
target_set = {}
|
41
|
+
cvs = cvs_files('.')
|
42
|
+
Dir.glob("*.rb") {|filename|
|
43
|
+
next if /\Atest-/ =~ filename
|
44
|
+
next if /\Ainstall/ =~ filename
|
45
|
+
next if cvs && !cvs.include?(filename)
|
46
|
+
target_set[filename] = true
|
47
|
+
yield filename
|
48
|
+
each_require(filename, target_set, &block)
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def each_require(file, target_set, &block)
|
53
|
+
File.foreach(file) {|line|
|
54
|
+
next if /\A\s*require\s+['"]([^'"]+)['"]/ !~ line
|
55
|
+
feature = $1
|
56
|
+
filename = "#{feature}.rb"
|
57
|
+
next if target_set.include? filename
|
58
|
+
next if !File.exist?(filename)
|
59
|
+
target_set[filename] = true
|
60
|
+
yield filename
|
61
|
+
each_require(filename, target_set, &block)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def collect_target
|
66
|
+
result = []
|
67
|
+
each_target {|filename| result << filename }
|
68
|
+
result.sort!
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def install_file(src, dst)
|
73
|
+
ignore_exc(Errno::ENOENT) { return if FileUtils.compare_file src, dst }
|
74
|
+
# check shadow
|
75
|
+
ignore_exc(Errno::ENOENT) { File.unlink dst }
|
76
|
+
FileUtils.mkdir_p(File.dirname(dst), :mode=>0755)
|
77
|
+
FileUtils.cp(src, dst, :verbose => true)
|
78
|
+
File.chmod(0644, dst)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ignore_exc(exc)
|
82
|
+
begin
|
83
|
+
yield
|
84
|
+
rescue exc
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
$opt_n = false
|
89
|
+
ARGV.options {|q|
|
90
|
+
q.banner = 'ruby install.rb [opts]'
|
91
|
+
q.def_option('--help', 'show this message') {puts q; exit(0)}
|
92
|
+
q.def_option('-n', "don't install") { $opt_n = true }
|
93
|
+
q.parse!
|
94
|
+
}
|
95
|
+
|
96
|
+
if $opt_n
|
97
|
+
dir = target_directory
|
98
|
+
collect_target.each {|filename|
|
99
|
+
puts "-> #{dir}/#{filename}"
|
100
|
+
}
|
101
|
+
exit
|
102
|
+
else
|
103
|
+
File.umask 022
|
104
|
+
dir = target_directory
|
105
|
+
collect_target.each {|filename|
|
106
|
+
install_file filename, "#{dir}/#{filename}"
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
= escape - HTML/URI/shell escaping utilities
|
2
|
+
<%
|
3
|
+
def version
|
4
|
+
File.read("VERSION").chomp
|
5
|
+
end
|
6
|
+
%>
|
7
|
+
|
8
|
+
escape library provides several HTML/URI/shell escaping functions.
|
9
|
+
|
10
|
+
== Author
|
11
|
+
|
12
|
+
Tanaka Akira <akr@fsij.org>
|
13
|
+
|
14
|
+
== Home Page
|
15
|
+
|
16
|
+
((<URL:http://www.a-k-r.org/escape/>))
|
17
|
+
|
18
|
+
== Feature
|
19
|
+
|
20
|
+
* several escaping/composing functions
|
21
|
+
* HTML text
|
22
|
+
* HTML attribute value
|
23
|
+
* HTML form (x-www-form-urlencoded)
|
24
|
+
* URI path
|
25
|
+
* shell command line
|
26
|
+
* dedicated classes for escaped strings
|
27
|
+
* escape and compose strongly related strings at once
|
28
|
+
|
29
|
+
== Usage
|
30
|
+
|
31
|
+
require 'escape'
|
32
|
+
|
33
|
+
Escape.shell_command(["echo", "*"]) #=> #<Escape::ShellEscaped: echo '*'>
|
34
|
+
Escape.uri_path("a?b/c?d/e?f") #=> #<Escape::PercentEncoded: a%3Fb/c%3Fd/e%3Ff>
|
35
|
+
Escape.html_form([["a","b"], ["c","d"]]) #=> #<Escape::PercentEncoded: a=b&c=d>
|
36
|
+
Escape.html_form({"a"=>"b", "c"=>"d"}) #=> #<Escape::PercentEncoded: a=b&c=d>
|
37
|
+
Escape.html_text("a & b < c > d") #=> #<Escape::HTMLEscaped: a & b < c > d>
|
38
|
+
Escape.html_attr_value("ab&<>\"c") #=> #<Escape::HTMLAttrValue: "ab&<>"c">
|
39
|
+
|
40
|
+
== Requirements
|
41
|
+
|
42
|
+
* ruby : http://www.ruby-lang.org/
|
43
|
+
|
44
|
+
== Download
|
45
|
+
|
46
|
+
* latest release: ((<escape-<%=version%>.tar.gz|URL:escape-<%=version%>.tar.gz>))
|
47
|
+
|
48
|
+
* development version in Subversion repository:
|
49
|
+
|
50
|
+
% svn co svn://svn@svn.a-k-r.org/akr/escape/trunk escape
|
51
|
+
|
52
|
+
== Install
|
53
|
+
|
54
|
+
% ruby install.rb
|
55
|
+
|
56
|
+
== Reference Manual
|
57
|
+
|
58
|
+
See rdoc/classes/Escape.html or
|
59
|
+
((<URL:http://www.a-k-r.org/escape/rdoc/classes/Escape.html>))
|
60
|
+
|
61
|
+
== License
|
62
|
+
|
63
|
+
The modified BSD licence
|
64
|
+
|
65
|
+
Redistribution and use in source and binary forms, with or without
|
66
|
+
modification, are permitted provided that the following conditions are met:
|
67
|
+
|
68
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
69
|
+
list of conditions and the following disclaimer.
|
70
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
71
|
+
this list of conditions and the following disclaimer in the documentation
|
72
|
+
and/or other materials provided with the distribution.
|
73
|
+
3. The name of the author may not be used to endorse or promote products
|
74
|
+
derived from this software without specific prior written permission.
|
75
|
+
|
76
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
77
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
78
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
79
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
80
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
81
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
82
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
83
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
84
|
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
85
|
+
OF SUCH DAMAGE.
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>Class: Escape::HTMLAttrValue</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
11
|
+
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
12
|
+
<script type="text/javascript">
|
13
|
+
// <![CDATA[
|
14
|
+
|
15
|
+
function popupCode( url ) {
|
16
|
+
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
17
|
+
}
|
18
|
+
|
19
|
+
function toggleCode( id ) {
|
20
|
+
if ( document.getElementById )
|
21
|
+
elem = document.getElementById( id );
|
22
|
+
else if ( document.all )
|
23
|
+
elem = eval( "document.all." + id );
|
24
|
+
else
|
25
|
+
return false;
|
26
|
+
|
27
|
+
elemStyle = elem.style;
|
28
|
+
|
29
|
+
if ( elemStyle.display != "block" ) {
|
30
|
+
elemStyle.display = "block"
|
31
|
+
} else {
|
32
|
+
elemStyle.display = "none"
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Make codeblocks hidden by default
|
39
|
+
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
40
|
+
|
41
|
+
// ]]>
|
42
|
+
</script>
|
43
|
+
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
<div id="classHeader">
|
50
|
+
<table class="header-table">
|
51
|
+
<tr class="top-aligned-row">
|
52
|
+
<td><strong>Class</strong></td>
|
53
|
+
<td class="class-name-in-header">Escape::HTMLAttrValue</td>
|
54
|
+
</tr>
|
55
|
+
<tr class="top-aligned-row">
|
56
|
+
<td><strong>In:</strong></td>
|
57
|
+
<td>
|
58
|
+
<a href="../../files/escape_rb.html">
|
59
|
+
escape.rb
|
60
|
+
</a>
|
61
|
+
<br />
|
62
|
+
</td>
|
63
|
+
</tr>
|
64
|
+
|
65
|
+
<tr class="top-aligned-row">
|
66
|
+
<td><strong>Parent:</strong></td>
|
67
|
+
<td>
|
68
|
+
<a href="StringWrapper.html">
|
69
|
+
StringWrapper
|
70
|
+
</a>
|
71
|
+
</td>
|
72
|
+
</tr>
|
73
|
+
</table>
|
74
|
+
</div>
|
75
|
+
<!-- banner header -->
|
76
|
+
|
77
|
+
<div id="bodyContent">
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
<div id="contextContent">
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
</div>
|
86
|
+
|
87
|
+
|
88
|
+
</div>
|
89
|
+
|
90
|
+
|
91
|
+
<!-- if includes -->
|
92
|
+
|
93
|
+
<div id="section">
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
<!-- if method_list -->
|
103
|
+
|
104
|
+
|
105
|
+
</div>
|
106
|
+
|
107
|
+
|
108
|
+
<div id="validator-badges">
|
109
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</body>
|
113
|
+
</html>
|