kitchensink 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +24 -0
- data/README.txt +8 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/kitchensink.rb +200 -0
- data/lib/kitchensink/version.rb +9 -0
- data/log/debug.log +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_helper.rb +2 -0
- data/test/test_kitchensink.rb +11 -0
- data/website/index.html +11 -0
- data/website/index.txt +39 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +83 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 FIXME full name
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
lib/kitchensink.rb
|
9
|
+
lib/kitchensink/version.rb
|
10
|
+
log/debug.log
|
11
|
+
script/destroy
|
12
|
+
script/generate
|
13
|
+
script/txt2html
|
14
|
+
setup.rb
|
15
|
+
tasks/deployment.rake
|
16
|
+
tasks/environment.rake
|
17
|
+
tasks/website.rake
|
18
|
+
test/test_helper.rb
|
19
|
+
test/test_kitchensink.rb
|
20
|
+
website/index.html
|
21
|
+
website/index.txt
|
22
|
+
website/javascripts/rounded_corners_lite.inc.js
|
23
|
+
website/stylesheets/screen.css
|
24
|
+
website/template.rhtml
|
data/README.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
= Kitchen Sink
|
2
|
+
|
3
|
+
Kitchen Sink is a collection of hopefully-useful methods and tweaks, little things that I think should be in Ruby Standard Library but currently aren't.
|
4
|
+
|
5
|
+
My experience has been that just about every Ruby programmer I have worked with has independently created some of these tweaks. As a result, I can claim no great personal originality in this gem other than finally collecting them all together.
|
6
|
+
|
7
|
+
Because it is likely that you or some of the libraries you are using already have one or more of these tweaks, every tweak in Kitchen Sink first checks to see if the tweak has already been defined, and politely refuses to overwrite your existing tweaks.
|
8
|
+
|
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'kitchensink/version'
|
2
|
+
|
3
|
+
AUTHOR = 'FIXME full name' # can also be an array of Authors
|
4
|
+
EMAIL = "FIXME email"
|
5
|
+
DESCRIPTION = "description of gem"
|
6
|
+
GEM_NAME = 'kitchensink' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'kitchensink' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
|
11
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
12
|
+
@config = nil
|
13
|
+
RUBYFORGE_USERNAME = "unknown"
|
14
|
+
def rubyforge_username
|
15
|
+
unless @config
|
16
|
+
begin
|
17
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
18
|
+
rescue
|
19
|
+
puts <<-EOS
|
20
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
21
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
22
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
23
|
+
EOS
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
REV = nil
|
32
|
+
# UNCOMMENT IF REQUIRED:
|
33
|
+
# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
|
34
|
+
VERS = Kitchensink::VERSION::STRING + (REV ? ".#{REV}" : "")
|
35
|
+
RDOC_OPTS = ['--quiet', '--title', 'kitchensink documentation',
|
36
|
+
"--opname", "index.html",
|
37
|
+
"--line-numbers",
|
38
|
+
"--main", "README",
|
39
|
+
"--inline-source"]
|
40
|
+
|
41
|
+
class Hoe
|
42
|
+
def extra_deps
|
43
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
44
|
+
@extra_deps
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Generate all the Rake tasks
|
49
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
50
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
51
|
+
p.developer(AUTHOR, EMAIL)
|
52
|
+
p.description = DESCRIPTION
|
53
|
+
p.summary = DESCRIPTION
|
54
|
+
p.url = HOMEPATH
|
55
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
56
|
+
p.test_globs = ["test/**/test_*.rb"]
|
57
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
58
|
+
|
59
|
+
# == Optional
|
60
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
61
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
62
|
+
|
63
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
68
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
69
|
+
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
70
|
+
hoe.rsync_args = '-av --delete --ignore-errors'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
16
|
+
|
17
|
+
require 'kitchensink'
|
data/lib/kitchensink.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
unless Enumerable.method_defined? :rest
|
4
|
+
module Enumerable
|
5
|
+
# Returns all elements after the first.
|
6
|
+
def rest
|
7
|
+
self[1..-1]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
unless Enumerable.method_defined? :rrest
|
13
|
+
module Enumerable
|
14
|
+
# Returns a new collection containing all elements except for the last
|
15
|
+
#--
|
16
|
+
# This has a very PHPesque name and needs a better one. (PHP has an idiom
|
17
|
+
# where array methods that work in one direction can be reversed by
|
18
|
+
# prepending r to them. See sort=>rsort, ksort=>krsort, and asort=>arsort.
|
19
|
+
# Problem is, what's a good word meaning "everything but the last"? I
|
20
|
+
# briefly toyed with "lizard" since it's the Enumeration "with the tail
|
21
|
+
# cut off" but that's not very intuitive to somebody looking at the method
|
22
|
+
# for the first time. I need a word that suggests to the reader what it
|
23
|
+
# means, and that with a little context the reader could determine the
|
24
|
+
# meaning correctly almost all every time.
|
25
|
+
def rrest
|
26
|
+
self[0..-2]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
unless Array.method_defined? :sum
|
32
|
+
class Array
|
33
|
+
# Adds all elements of an array together:
|
34
|
+
# * [1,2,3].sum => 6
|
35
|
+
# * [1.0, 2.0, 3.0].sum => 6.0
|
36
|
+
# * %w{a b c}.sum => "abc"
|
37
|
+
# * [Vector[1,0,0], Vector[0,2,0], Vector[0,0,3]].sum => Vector[1,2,3]
|
38
|
+
def sum
|
39
|
+
inject {|sum,element| sum+element}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
unless Array.method_defined? :product
|
45
|
+
class Array
|
46
|
+
# Multiplies all elements of an array together:
|
47
|
+
# * [2,3,4].product => 24
|
48
|
+
# * [2.0, 3.0, 4.0].product => 24.0
|
49
|
+
# * ["NO", 3, 2].product => "NONONONONONO"
|
50
|
+
def product
|
51
|
+
inject {|product,element| product*element}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
unless Array.method_defined? :hash_by
|
57
|
+
class Array
|
58
|
+
# Construct a hash of objects, keyed by some object attribute.
|
59
|
+
#
|
60
|
+
# Original idea and code by Brian Dainton. Taken from his blog, The Budding Rubyist.
|
61
|
+
# http://buddingrubyist.wordpress.com/2008/02/05/why-i-like-to-inject/
|
62
|
+
def hash_by(attribute)
|
63
|
+
inject({}) do |results, obj|
|
64
|
+
results[obj.send(attribute)] = obj
|
65
|
+
results
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
unless Object.respond_to? :class_method
|
73
|
+
class Object
|
74
|
+
# Returns an +UnboundMethod+ representing a given class method in a class.
|
75
|
+
#
|
76
|
+
# See Also: instance_method
|
77
|
+
#
|
78
|
+
# Examples:
|
79
|
+
# sc = String.class_method(:superclass)
|
80
|
+
# sc.bind(String).call()
|
81
|
+
# => Object
|
82
|
+
#--
|
83
|
+
# Note that here we use the "class << self; self; end.send" trick, which
|
84
|
+
# gives us access to the singleton class rather than the class itself.
|
85
|
+
# Setting instance methods here causes the subclass to receive class
|
86
|
+
# methods. Yay!
|
87
|
+
def self.class_method(name)
|
88
|
+
class << self; self; end.send :instance_method, name
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
unless Object.respond_to? :remove_class_method
|
94
|
+
class Object
|
95
|
+
# Removes a class method.
|
96
|
+
def self.remove_class_method(name)
|
97
|
+
class << self; self; end.send :remove_method, name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
unless Object.respond_to? :define_class_method
|
103
|
+
class Object
|
104
|
+
# Works like define_method, only creates a class method.
|
105
|
+
# * <tt>define_class_method(symbol, method)</tt> => new_method
|
106
|
+
# * <tt>define_class_method(symbol) {block}</tt> => proc
|
107
|
+
#
|
108
|
+
# Examples:
|
109
|
+
# String.define_class_method :get_parent_class, String.class_method(:superclass)
|
110
|
+
# String.define_class_method :make_runon do |str, num|
|
111
|
+
# String.new(str) * num
|
112
|
+
# end
|
113
|
+
# String.make_runon "abc", 3
|
114
|
+
# => "abcabcabc"
|
115
|
+
def self.define_class_method(name, method=nil, &block)
|
116
|
+
if method
|
117
|
+
class << self; self; end.send :define_method, name, method
|
118
|
+
else
|
119
|
+
class << self; self; end.send :define_method, name, &block
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
unless Object.method_defined? :included_in?
|
126
|
+
class Object
|
127
|
+
# True if a collection includes this object.
|
128
|
+
#
|
129
|
+
# Note: I wrote this because
|
130
|
+
# sometimes <tt>collection.include?(object)</tt> violates left-to-right reading
|
131
|
+
# order, such as when +object+ is more important than the +collection+.
|
132
|
+
def included_in?(collection)
|
133
|
+
collection.include? self
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
unless Symbol.method_defined? :to_proc
|
139
|
+
class Symbol
|
140
|
+
# Convert a Symbol to proc.
|
141
|
+
#
|
142
|
+
# This is already in Ruby CVS, and should appear in Ruby 1.9
|
143
|
+
def to_proc
|
144
|
+
Proc.new { |obj, *args| obj.send(self, *args) }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
unless Hash.method_defined? :except
|
150
|
+
class Hash
|
151
|
+
# Filter keys out of a Hash.
|
152
|
+
#
|
153
|
+
# >> {:a=>1, :b=>2, :c=>3}.except(:a)
|
154
|
+
# => {:b=>2, :c=>3}
|
155
|
+
#
|
156
|
+
# Source:
|
157
|
+
# * http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F
|
158
|
+
# * Neil Rahilly
|
159
|
+
# * Peepcode episode 11. Geoffrey Grosenbach alludes to this being a
|
160
|
+
# common idiom among rSpec coders.
|
161
|
+
def except(*keys)
|
162
|
+
self.reject { |k,v| keys.include?(k || k.to_sym) }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
unless Hash.method_defined? :only
|
168
|
+
class Hash
|
169
|
+
# Returns a hash with only the pairs identified by +keys+
|
170
|
+
#
|
171
|
+
# Source:
|
172
|
+
# * http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F
|
173
|
+
# * Neil Rahilly
|
174
|
+
# * Peepcode episode 11. Geoffrey Grosenbach alludes to this being a
|
175
|
+
# common idiom among rSpec coders.
|
176
|
+
def only(*keys)
|
177
|
+
self.reject { |k,v| !keys.include?(k || k.to_sym) }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
unless Hash.method_defined? :with
|
183
|
+
class Hash
|
184
|
+
# Merge keys into a Hash.
|
185
|
+
#
|
186
|
+
# >> {:a=>1, :b=>2, :c=>3}.with({:a=>4,:b=>5})
|
187
|
+
# => {:a=>4, :b=>5, :c=>3}
|
188
|
+
#
|
189
|
+
# Source:
|
190
|
+
# * http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F
|
191
|
+
# * Neil Rahilly
|
192
|
+
# * Peepcode episode 11. Geoffrey Grosenbach alludes to this being a
|
193
|
+
# common idiom among rSpec coders.
|
194
|
+
#
|
195
|
+
# Known Issue: This method conflicts with utility_belt's with statement.
|
196
|
+
def with(overrides = {})
|
197
|
+
self.merge overrides
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
data/log/debug.log
ADDED
File without changes
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
begin
|
5
|
+
require 'newgem'
|
6
|
+
rescue LoadError
|
7
|
+
puts "\n\nGenerating the website requires the newgem RubyGem"
|
8
|
+
puts "Install: gem install newgem\n\n"
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
require 'redcloth'
|
12
|
+
require 'syntax/convertors/html'
|
13
|
+
require 'erb'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/kitchensink/version.rb'
|
15
|
+
|
16
|
+
version = Kitchensink::VERSION::STRING
|
17
|
+
download = 'http://rubyforge.org/projects/kitchensink'
|
18
|
+
|
19
|
+
class Fixnum
|
20
|
+
def ordinal
|
21
|
+
# teens
|
22
|
+
return 'th' if (10..19).include?(self % 100)
|
23
|
+
# others
|
24
|
+
case self % 10
|
25
|
+
when 1: return 'st'
|
26
|
+
when 2: return 'nd'
|
27
|
+
when 3: return 'rd'
|
28
|
+
else return 'th'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Time
|
34
|
+
def pretty
|
35
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_syntax(syntax, source)
|
40
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
41
|
+
end
|
42
|
+
|
43
|
+
if ARGV.length >= 1
|
44
|
+
src, template = ARGV
|
45
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
|
46
|
+
|
47
|
+
else
|
48
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
49
|
+
exit!
|
50
|
+
end
|
51
|
+
|
52
|
+
template = ERB.new(File.open(template).read)
|
53
|
+
|
54
|
+
title = nil
|
55
|
+
body = nil
|
56
|
+
File.open(src) do |fsrc|
|
57
|
+
title_text = fsrc.readline
|
58
|
+
body_text = fsrc.read
|
59
|
+
syntax_items = []
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
61
|
+
ident = syntax_items.length
|
62
|
+
element, syntax, source = $1, $2, $3
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
64
|
+
"syntax-temp-#{ident}"
|
65
|
+
}
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
67
|
+
body = RedCloth.new(body_text).to_html
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
69
|
+
end
|
70
|
+
stat = File.stat(src)
|
71
|
+
created = stat.ctime
|
72
|
+
modified = stat.mtime
|
73
|
+
|
74
|
+
$stdout << template.result(binding)
|