palmtree 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.
- data/History.txt +4 -0
- data/Manifest.txt +20 -0
- data/README.txt +3 -0
- data/Rakefile +91 -0
- data/lib/palmtree/capistrano_extensions/configuration_extensions.rb +80 -0
- data/lib/palmtree/recipes/backgroundrb.rb +44 -0
- data/lib/palmtree/recipes/ferret.rb +69 -0
- data/lib/palmtree/recipes/mongrel_cluster.rb +95 -0
- data/lib/palmtree/recipes/tail.rb +39 -0
- data/lib/palmtree/recipes.rb +2 -0
- data/lib/palmtree/version.rb +9 -0
- data/lib/palmtree.rb +1 -0
- data/scripts/txt2html +67 -0
- data/setup.rb +1585 -0
- data/test/test_helper.rb +2 -0
- data/test/test_palmtree.rb +11 -0
- data/website/index.txt +30 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +129 -0
- data/website/template.rhtml +48 -0
- metadata +74 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/palmtree.rb
|
6
|
+
lib/palmtree/capistrano_extensions/configuration_extensions.rb
|
7
|
+
lib/palmtree/recipes.rb
|
8
|
+
lib/palmtree/recipes/backgroundrb.rb
|
9
|
+
lib/palmtree/recipes/ferret.rb
|
10
|
+
lib/palmtree/recipes/mongrel_cluster.rb
|
11
|
+
lib/palmtree/recipes/tail.rb
|
12
|
+
lib/palmtree/version.rb
|
13
|
+
scripts/txt2html
|
14
|
+
setup.rb
|
15
|
+
test/test_helper.rb
|
16
|
+
test/test_palmtree.rb
|
17
|
+
website/index.txt
|
18
|
+
website/javascripts/rounded_corners_lite.inc.js
|
19
|
+
website/stylesheets/screen.css
|
20
|
+
website/template.rhtml
|
data/README.txt
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'palmtree', 'version')
|
13
|
+
|
14
|
+
AUTHOR = 'ggarside' # can also be an array of Authors
|
15
|
+
EMAIL = "palmtree@geoffgarside.co.uk"
|
16
|
+
DESCRIPTION = "Collection of Capistrano recipes"
|
17
|
+
GEM_NAME = 'palmtree' # what ppl will type to install your gem
|
18
|
+
RUBYFORGE_PROJECT = 'palmtree' # The unix name for your project
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
21
|
+
|
22
|
+
NAME = "palmtree"
|
23
|
+
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
|
+
VERS = Palmtree::VERSION::STRING + (REV ? ".#{REV}" : "")
|
25
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
|
26
|
+
RDOC_OPTS = ['--quiet', '--title', 'palmtree documentation',
|
27
|
+
"--opname", "index.html",
|
28
|
+
"--line-numbers",
|
29
|
+
"--main", "README",
|
30
|
+
"--inline-source"]
|
31
|
+
|
32
|
+
class Hoe
|
33
|
+
def extra_deps
|
34
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Generate all the Rake tasks
|
39
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
40
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
41
|
+
p.author = AUTHOR
|
42
|
+
p.description = DESCRIPTION
|
43
|
+
p.email = EMAIL
|
44
|
+
p.summary = DESCRIPTION
|
45
|
+
p.url = HOMEPATH
|
46
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
47
|
+
p.test_globs = ["test/**/test_*.rb"]
|
48
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
49
|
+
|
50
|
+
# == Optional
|
51
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
52
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
53
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
54
|
+
|
55
|
+
p.extra_deps = ['capistrano', '>=1.99.0']
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
desc 'Generate website files'
|
60
|
+
task :website_generate do
|
61
|
+
Dir['website/**/*.txt'].each do |txt|
|
62
|
+
sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Upload website files to rubyforge'
|
67
|
+
task :website_upload do
|
68
|
+
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
69
|
+
host = "#{config["username"]}@rubyforge.org"
|
70
|
+
remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
|
71
|
+
# remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
72
|
+
local_dir = 'website'
|
73
|
+
sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Generate and upload website files'
|
77
|
+
task :website => [:website_generate, :website_upload]
|
78
|
+
|
79
|
+
desc 'Release the website and new gem version'
|
80
|
+
task :deploy => [:check_version, :website, :release]
|
81
|
+
|
82
|
+
task :check_version do
|
83
|
+
unless ENV['VERSION']
|
84
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
unless ENV['VERSION'] == VERS
|
88
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Extensions to the Capistrano::Configuration class which now
|
2
|
+
# includes the old Capistrano::Actor functionality.
|
3
|
+
#
|
4
|
+
# Original code by Mike Bailey in his deprec gem.
|
5
|
+
# URL: http://rubyforge.org/projects/deprec/
|
6
|
+
|
7
|
+
module Capistrano
|
8
|
+
class Configuration
|
9
|
+
# Run a command and ask for input when input_query is seen.
|
10
|
+
# Sends the response back to the server.
|
11
|
+
#
|
12
|
+
# +input_query+ is a regular expression that defaults to /^Password/.
|
13
|
+
#
|
14
|
+
# Can be used where +run+ would otherwise be used.
|
15
|
+
#
|
16
|
+
# run_with_input 'ssh-keygen ...', /^Are you sure you want to overwrite\?/
|
17
|
+
def run_with_input(shell_command, input_query=/^Password/)
|
18
|
+
handle_command_with_input(:run, shell_command, input_query)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Run a command using sudo and ask for input when a regular expression is seen.
|
22
|
+
# Sends the response back to the server.
|
23
|
+
#
|
24
|
+
# See also +run_with_input+
|
25
|
+
#
|
26
|
+
# +input_query+ is a regular expression
|
27
|
+
def sudo_with_input(shell_command, input_query=/^Password/)
|
28
|
+
handle_command_with_input(:sudo, shell_command, input_query)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Run a command using sudo and continuously pipe the results back to the console.
|
32
|
+
#
|
33
|
+
# Similar to the built-in +stream+, but for privileged users.
|
34
|
+
def sudo_stream(command, outfunc = :puts)
|
35
|
+
sudo(command) do |ch, stream, out|
|
36
|
+
self.send(outfunc, out) if stream == :out
|
37
|
+
if stream == :err
|
38
|
+
puts "[err : #{ch[:host]}] #{out}"
|
39
|
+
break
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Run a command using the root account.
|
45
|
+
#
|
46
|
+
# Some linux distros/VPS providers only give you a root login when you install.
|
47
|
+
def run_as_root(shell_command)
|
48
|
+
std.connect_as_root do |tempuser|
|
49
|
+
run shell_command
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Run a task using root account.
|
54
|
+
#
|
55
|
+
# Some linux distros/VPS providers only give you a root login when you install.
|
56
|
+
#
|
57
|
+
# tempuser: contains the value replaced by 'root' for the duration of this call
|
58
|
+
def as_root()
|
59
|
+
std.connect_as_root do |tempuser|
|
60
|
+
yield tempuser
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
# Does the actual capturing of the input and streaming of the output.
|
66
|
+
#
|
67
|
+
# local_run_method: run or sudo
|
68
|
+
# shell_command: The command to run
|
69
|
+
# input_query: A regular expression matching a request for input: /^Please enter your password/
|
70
|
+
def handle_command_with_input(local_run_method, shell_command, input_query)
|
71
|
+
send(local_run_method, shell_command) do |channel, stream, data|
|
72
|
+
logger.info data, channel[:host]
|
73
|
+
if data =~ input_query
|
74
|
+
pass = ::Capistrano::CLI.password_prompt "#{data}:"
|
75
|
+
channel.send_data "#{pass}\n"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(true).load do
|
4
|
+
set :backgroundrb_host, 'localhost'
|
5
|
+
set :backgroundrb_port, 2000
|
6
|
+
set :backgroundrb_env, 'production'
|
7
|
+
|
8
|
+
namespace :backgroundrb do
|
9
|
+
desc "Uses 'set' variables in deploy.rb to write the shared/config/backgroundrb.yml file"
|
10
|
+
task :configure, :role => :app do
|
11
|
+
config = {:host => backgroundrb_host, :port => backgroundrb_port, :rails_env => backgroundrb_env}
|
12
|
+
backgroundrb_yml = config.to_yaml
|
13
|
+
|
14
|
+
run "if [ ! -d #{shared_path}/config ]; then mkdir #{shared_path}/config; fi"
|
15
|
+
put(backgroundrb_yml, "#{shared_path}/config/backgroundrb.yml", :mode => 0644)
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Stops the backgroundrb server."
|
19
|
+
task :stop, :role => :app do
|
20
|
+
run "#{current_path}/script/backgroundrb stop"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Starts the backgroundrb server."
|
24
|
+
task :start, :role => :app do
|
25
|
+
run "#{current_path}/script/backgroundrb start"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Restarts a running backgroundrb server."
|
29
|
+
task :restart, :role => :app do
|
30
|
+
backgroundrb.stop
|
31
|
+
sleep(5) # sleep for 5 seconds to make sure the server has mopped up everything
|
32
|
+
backgroundrb.start
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Copies the shared/config/backgroundrb yaml to release/config/"
|
36
|
+
task :copy_config, :role => :app do
|
37
|
+
on_rollback {
|
38
|
+
puts "***** File shared/config/backgroundrb.yml is missing. Make sure you have run backgroundrb:configure first. *****"
|
39
|
+
}
|
40
|
+
|
41
|
+
run "cp #{shared_path}/config/backgroundrb.yml #{release_path}/config/"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(true).load do
|
4
|
+
set :ferret_host, ''
|
5
|
+
set :ferret_port, 9009
|
6
|
+
|
7
|
+
namespace :ferret do
|
8
|
+
namespace :index do
|
9
|
+
desc <<-DESC
|
10
|
+
An after_update_code task to symlink release/index to shared/index \
|
11
|
+
useful for maintaining a constant ferret index between deployments
|
12
|
+
DESC
|
13
|
+
task :symlink, :role => :app do
|
14
|
+
ferret.index.create
|
15
|
+
run <<-CMD
|
16
|
+
rm -rf #{release_path}/index &&
|
17
|
+
ln -nfs #{shared_path}/index #{release_path}/index
|
18
|
+
CMD
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Creates the shared/index directory for persistent ferret indexes"
|
22
|
+
task :create, :role => :app do
|
23
|
+
run "if [ ! -d #{shared_path}/index ]; then mkdir -p #{shared_path}/index ; fi"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Removes the contents of the shared/index directory"
|
27
|
+
task :purge, :role => :app do
|
28
|
+
run "if [ -d #{shared_path}/index ]; then rm -rf #{shared_path}/index/* ; fi"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :server do
|
33
|
+
desc "Configure ferret server"
|
34
|
+
task :configure, :role => :app do
|
35
|
+
config = {rails_env => {'port' => ferret_port, 'host' => ferret_host, 'pid_file' => "log/ferret-#{rails_env}.pid"}}
|
36
|
+
ferret_server_yml = config.to_yaml
|
37
|
+
|
38
|
+
run "if [ ! -d #{shared_path}/config ]; then mkdir #{shared_path}/config; fi"
|
39
|
+
put(ferret_server_yml, "#{shared_path}/config/ferret_server.yml", :mode => 0644)
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Copies the ferret_server.yml file to release_path/config"
|
43
|
+
task :copy_config, :role => :app do
|
44
|
+
on_rollback {
|
45
|
+
puts "***** File shared/config/ferret_server.yml is missing. Make sure you have run configure_ferret first. *****"
|
46
|
+
}
|
47
|
+
|
48
|
+
run "cp #{shared_path}/config/ferret_server.yml #{release_path}/config/"
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Start ferret server"
|
52
|
+
task :start, :role => :app do
|
53
|
+
run "RAILS_ENV=#{rails_env} #{current_path}/script/runner \"load '#{current_path}/script/ferret_start'\""
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Stop ferret server"
|
57
|
+
task :stop, :role => :app do
|
58
|
+
run "RAILS_ENV=#{rails_env} #{current_path}/script/runner \"load '#{current_path}/script/ferret_stop'\""
|
59
|
+
end
|
60
|
+
|
61
|
+
desc "Restart ferret server"
|
62
|
+
task :restart, :role => :app do
|
63
|
+
ferret.server.stop
|
64
|
+
sleep(5)
|
65
|
+
ferret.server.start
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
Capistrano::Configuration.instance(true).load do
|
2
|
+
set :mongrel_servers, 2
|
3
|
+
set :mongrel_port, 8000
|
4
|
+
set :mongrel_address, "127.0.0.1"
|
5
|
+
set :mongrel_environment, "production"
|
6
|
+
set :mongrel_conf, nil
|
7
|
+
set :mongrel_user, nil
|
8
|
+
set :mongrel_group, nil
|
9
|
+
set :mongrel_prefix, nil
|
10
|
+
|
11
|
+
namespace :mongrel do
|
12
|
+
namespace :cluster do
|
13
|
+
desc <<-DESC
|
14
|
+
Configure Mongrel processes on the app server. This uses the :use_sudo
|
15
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
16
|
+
set to true.
|
17
|
+
DESC
|
18
|
+
task :configure, :roles => :app do
|
19
|
+
set_mongrel_conf
|
20
|
+
|
21
|
+
argv = []
|
22
|
+
argv << "mongrel_rails cluster::configure"
|
23
|
+
argv << "-N #{mongrel_servers.to_s}"
|
24
|
+
argv << "-p #{mongrel_port.to_s}"
|
25
|
+
argv << "-e #{mongrel_environment}"
|
26
|
+
argv << "-a #{mongrel_address}"
|
27
|
+
argv << "-c #{current_path}"
|
28
|
+
argv << "-C #{mongrel_conf}"
|
29
|
+
argv << "--user #{mongrel_user}" if mongrel_user
|
30
|
+
argv << "--group #{mongrel_group}" if mongrel_group
|
31
|
+
argv << "--prefix #{mongrel_prefix}" if mongrel_prefix
|
32
|
+
cmd = argv.join " "
|
33
|
+
send(run_method, cmd)
|
34
|
+
end
|
35
|
+
|
36
|
+
desc <<-DESC
|
37
|
+
Start Mongrel processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
|
38
|
+
set to true.
|
39
|
+
DESC
|
40
|
+
task :start , :roles => :app do
|
41
|
+
set_mongrel_conf
|
42
|
+
send(run_method, "mongrel_rails cluster::start -C #{mongrel_conf}")
|
43
|
+
end
|
44
|
+
|
45
|
+
desc <<-DESC
|
46
|
+
Restart the Mongrel processes on the app server by starting and stopping the cluster. This uses the :use_sudo
|
47
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
|
48
|
+
DESC
|
49
|
+
task :restart , :roles => :app do
|
50
|
+
set_mongrel_conf
|
51
|
+
send(run_method, "mongrel_rails cluster::restart -C #{mongrel_conf}")
|
52
|
+
end
|
53
|
+
|
54
|
+
desc <<-DESC
|
55
|
+
Stop the Mongrel processes on the app server. This uses the :use_sudo
|
56
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
57
|
+
set to true.
|
58
|
+
DESC
|
59
|
+
task :stop , :roles => :app do
|
60
|
+
set_mongrel_conf
|
61
|
+
send(run_method, "mongrel_rails cluster::stop -C #{mongrel_conf}")
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_mongrel_conf
|
65
|
+
set :mongrel_conf, "etc/mongrel_cluster/#{application}.yml" unless mongrel_conf
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# We need to override the core deployment tasks so they use mongrel cluster instead.
|
71
|
+
namespace :deploy do
|
72
|
+
desc <<-DESC
|
73
|
+
Restart the Mongrel processes on the app server by calling mongrel:cluster:restart.
|
74
|
+
DESC
|
75
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
76
|
+
mongrel.cluster.restart
|
77
|
+
end
|
78
|
+
|
79
|
+
namespace :app do
|
80
|
+
desc <<-DESC
|
81
|
+
Start the application servers. Calls mongrel:cluster:start.
|
82
|
+
DESC
|
83
|
+
task :start, :roles => :app do
|
84
|
+
mongrel.cluster.start
|
85
|
+
end
|
86
|
+
|
87
|
+
desc <<-DESC
|
88
|
+
Stop the application servers. Calls mongrel:cluster:stop.
|
89
|
+
DESC
|
90
|
+
task :stop, :roles => :app do
|
91
|
+
mongrel.cluster.stop
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Capistrano::Configuration.instance(true).load do
|
2
|
+
set(:log_file) { rails_env }
|
3
|
+
|
4
|
+
namespace :tail do
|
5
|
+
desc <<-DESC
|
6
|
+
Streams a log file. \
|
7
|
+
you should set log_file to full path of the log file to tail.
|
8
|
+
DESC
|
9
|
+
task :file do
|
10
|
+
stream "tail -F #{log_file}"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc <<-DESC
|
14
|
+
Streams a log file from shared/log/. \
|
15
|
+
you should set log_file to name of the log file to tail.
|
16
|
+
DESC
|
17
|
+
task :log_file do
|
18
|
+
stream "tail -F #{shared_path}/log/#{log_file}.log"
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :log do
|
22
|
+
desc <<-DESC
|
23
|
+
Streams the shared/log/production.log file
|
24
|
+
DESC
|
25
|
+
task :production , :roles => :app do
|
26
|
+
set :log_file, "production"
|
27
|
+
tail.log_file
|
28
|
+
end
|
29
|
+
|
30
|
+
desc <<-DESC
|
31
|
+
Streams the shared/log/development.log file
|
32
|
+
DESC
|
33
|
+
task :development , :roles => :app do
|
34
|
+
set :log_file, "development"
|
35
|
+
tail.log_file
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/palmtree.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'palmtree/**/*.rb')].sort.each { |lib| require lib }
|
data/scripts/txt2html
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcloth'
|
5
|
+
require 'syntax/convertors/html'
|
6
|
+
require 'erb'
|
7
|
+
require File.dirname(__FILE__) + '/../lib/palmtree/version.rb'
|
8
|
+
|
9
|
+
version = Palmtree::VERSION::STRING
|
10
|
+
download = 'http://rubyforge.org/projects/palmtree'
|
11
|
+
|
12
|
+
class Fixnum
|
13
|
+
def ordinal
|
14
|
+
# teens
|
15
|
+
return 'th' if (10..19).include?(self % 100)
|
16
|
+
# others
|
17
|
+
case self % 10
|
18
|
+
when 1: return 'st'
|
19
|
+
when 2: return 'nd'
|
20
|
+
when 3: return 'rd'
|
21
|
+
else return 'th'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Time
|
27
|
+
def pretty
|
28
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def convert_syntax(syntax, source)
|
33
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
34
|
+
end
|
35
|
+
|
36
|
+
if ARGV.length >= 1
|
37
|
+
src, template = ARGV
|
38
|
+
template ||= File.dirname(__FILE__) + '/../website/template.rhtml'
|
39
|
+
|
40
|
+
else
|
41
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
42
|
+
exit!
|
43
|
+
end
|
44
|
+
|
45
|
+
template = ERB.new(File.open(template).read)
|
46
|
+
|
47
|
+
title = nil
|
48
|
+
body = nil
|
49
|
+
File.open(src) do |fsrc|
|
50
|
+
title_text = fsrc.readline
|
51
|
+
body_text = fsrc.read
|
52
|
+
syntax_items = []
|
53
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</>!m){
|
54
|
+
ident = syntax_items.length
|
55
|
+
element, syntax, source = $1, $2, $3
|
56
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
57
|
+
"syntax-temp-#{ident}"
|
58
|
+
}
|
59
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
60
|
+
body = RedCloth.new(body_text).to_html
|
61
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
62
|
+
end
|
63
|
+
stat = File.stat(src)
|
64
|
+
created = stat.ctime
|
65
|
+
modified = stat.mtime
|
66
|
+
|
67
|
+
$stdout << template.result(binding)
|