integrator 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 +7 -0
- data/License.txt +5 -0
- data/Manifest.txt +27 -0
- data/README.txt +3 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/integrator/adaptive.rb +109 -0
- data/lib/integrator/rkck.rb +113 -0
- data/lib/integrator/rkqs.rb +51 -0
- data/lib/integrator/version.rb +9 -0
- data/lib/integrator.rb +63 -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 +27 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +21 -0
- data/test/test_helper.rb +2 -0
- data/test/test_integrator.rb +11 -0
- data/website/index.html +87 -0
- data/website/index.txt +37 -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 +77 -0
data/History.txt
ADDED
data/License.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
lib/integrator.rb
|
9
|
+
lib/integrator/adaptive.rb
|
10
|
+
lib/integrator/rkck.rb
|
11
|
+
lib/integrator/rkqs.rb
|
12
|
+
lib/integrator/version.rb
|
13
|
+
log/debug.log
|
14
|
+
script/destroy
|
15
|
+
script/generate
|
16
|
+
script/txt2html
|
17
|
+
setup.rb
|
18
|
+
tasks/deployment.rake
|
19
|
+
tasks/environment.rake
|
20
|
+
tasks/website.rake
|
21
|
+
test/test_helper.rb
|
22
|
+
test/test_integrator.rb
|
23
|
+
website/index.html
|
24
|
+
website/index.txt
|
25
|
+
website/javascripts/rounded_corners_lite.inc.js
|
26
|
+
website/stylesheets/screen.css
|
27
|
+
website/template.rhtml
|
data/README.txt
ADDED
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'integrator/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Noah Gibbs'
|
4
|
+
EMAIL = "angelbob@nospam.users.sourceforge.net"
|
5
|
+
DESCRIPTION = "Numerical integration framework"
|
6
|
+
GEM_NAME = 'integrator' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'diffeq' # 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 = Integrator::VERSION::STRING + (REV ? ".#{REV}" : "")
|
35
|
+
RDOC_OPTS = ['--quiet', '--title', 'integrator 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.author = AUTHOR
|
52
|
+
p.description = DESCRIPTION
|
53
|
+
p.email = EMAIL
|
54
|
+
p.summary = DESCRIPTION
|
55
|
+
p.url = HOMEPATH
|
56
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
57
|
+
p.test_globs = ["test/**/test_*.rb"]
|
58
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
59
|
+
|
60
|
+
# == Optional
|
61
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\\n\\n")
|
62
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
63
|
+
|
64
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
69
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
|
+
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
@@ -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 'integrator'
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#
|
2
|
+
# Integrator library
|
3
|
+
# Copyright (C) 2007 Noah Gibbs
|
4
|
+
#
|
5
|
+
# This library is in the public domain, and may be redistributed in any
|
6
|
+
# way.
|
7
|
+
#
|
8
|
+
|
9
|
+
require "matrix"
|
10
|
+
|
11
|
+
require "rubygems"
|
12
|
+
require "integrator"
|
13
|
+
|
14
|
+
require "integrator/rkqs.rb"
|
15
|
+
|
16
|
+
# This is the top-level driver, with logging, for Cash-Karp adaptive
|
17
|
+
# Runge-Kutta fourth-order integration with error checking. The
|
18
|
+
# algorithm is from "Numerical Methods in C", second edition.
|
19
|
+
|
20
|
+
class Adaptive_Cash_Karp_RK45 < OneStep_Cash_Karp_RK45
|
21
|
+
include Integrator
|
22
|
+
|
23
|
+
MAXSTP = 10000
|
24
|
+
TINY = 1.0e-30
|
25
|
+
|
26
|
+
def initialize()
|
27
|
+
Integrator_initialize()
|
28
|
+
end
|
29
|
+
|
30
|
+
def adaptive_integrate(ystart, x1, x2, eps, h1, hmin, derivs)
|
31
|
+
|
32
|
+
x = x1
|
33
|
+
h1 = -h1 unless h1 >= 0
|
34
|
+
x2 - x1 >= 0 ? h = h1 : h = -h1
|
35
|
+
@nok = @nbad = @count = 0
|
36
|
+
|
37
|
+
y = ystart
|
38
|
+
xsav = x - @dxsav * 2.0 if @kmax > 0
|
39
|
+
|
40
|
+
nstp = 1
|
41
|
+
while nstp <= MAXSTP
|
42
|
+
dydx = derivs.call(x, y)
|
43
|
+
#yscal = y.abs + (dydx * h).abs + Vector( [TINY] * y.length)
|
44
|
+
yscal = y.collect2(dydx) { |yi, dyi| yi.abs + (dyi * h).abs + TINY }
|
45
|
+
|
46
|
+
if @kmax > 0 and @count < @kmax - 1 and (x-xsav).abs > @dxsav.abs
|
47
|
+
@count += 1
|
48
|
+
@xp[@count] = x
|
49
|
+
@yp[@count] = y
|
50
|
+
xsav = x
|
51
|
+
end
|
52
|
+
|
53
|
+
h = x2 - x if ((x + h - x2)*(x + h - x1) > 0.0)
|
54
|
+
x, y, hdid, hnext = integrate_ad_step(y, dydx, x, h, eps,
|
55
|
+
yscal, derivs)
|
56
|
+
if hdid == h
|
57
|
+
@nok += 1
|
58
|
+
else
|
59
|
+
@nbad += 1
|
60
|
+
end
|
61
|
+
|
62
|
+
if (x-x2)*(x2-x1) >= 0.0
|
63
|
+
if @kmax != 0
|
64
|
+
@count += 1
|
65
|
+
@xp[@count] = x
|
66
|
+
@yp[@count] = y
|
67
|
+
end
|
68
|
+
return y
|
69
|
+
end
|
70
|
+
|
71
|
+
raise "Step size too small!" if hnext.abs <= hmin
|
72
|
+
h = hnext
|
73
|
+
|
74
|
+
nstp += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
raise "Too many steps in integration!"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
if __FILE__ == $0
|
83
|
+
|
84
|
+
rk45 = Adaptive_Cash_Karp_RK45.new()
|
85
|
+
|
86
|
+
def assert_within_epsilon(actual, expected)
|
87
|
+
if expected.kind_of?(Vector)
|
88
|
+
actual.collect2(expected) { |x, y|
|
89
|
+
assert_within_epsilon(x, y)
|
90
|
+
}
|
91
|
+
else
|
92
|
+
(actual - expected).abs / expected < 0.001 or
|
93
|
+
raise "Values don't match! Actual was #{actual}, not #{expected}!"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
assert_within_epsilon(10000.0, 10001)
|
97
|
+
|
98
|
+
# This takes the derivative of e^x for each vector element.
|
99
|
+
# The derivative of e^x is just e^x again.
|
100
|
+
exp_deriv = proc { |x, y| y.collect { |yi| yi } }
|
101
|
+
|
102
|
+
exp_start = Vector.elements([1.0] * 100)
|
103
|
+
|
104
|
+
y = rk45.adaptive_integrate(exp_start, 0.0, 1.0, 0.001, 0.01, 0.0001,
|
105
|
+
exp_deriv)
|
106
|
+
assert_within_epsilon(y, Vector.elements( [ Math::E ] * 100 ))
|
107
|
+
|
108
|
+
print "All tests completed...\n"
|
109
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
#
|
4
|
+
# Integrator library
|
5
|
+
# Copyright (C) 2007 Noah Gibbs
|
6
|
+
#
|
7
|
+
# This library is in the public domain, and may be redistributed in any
|
8
|
+
# way.
|
9
|
+
#
|
10
|
+
|
11
|
+
# Cash-Karp embedded Runge-Kutta integration This algorithm is taken
|
12
|
+
# from "Numerical Recipes in C", second edition, though the ruby
|
13
|
+
# translation is my own. This is the fixed step-size version.
|
14
|
+
|
15
|
+
require "matrix"
|
16
|
+
|
17
|
+
class Cash_Karp_RK4
|
18
|
+
A2 = 0.2
|
19
|
+
A3 = 0.3
|
20
|
+
A4 = 0.6
|
21
|
+
A5 = 1.0
|
22
|
+
A6 = 0.875
|
23
|
+
B21 = 0.2
|
24
|
+
B31 = 3.0/40.0
|
25
|
+
B32 = 9.0/40.0
|
26
|
+
B41 = 0.3
|
27
|
+
B42 = -0.9
|
28
|
+
B43 = 1.2
|
29
|
+
B51 = -11.0/54.0
|
30
|
+
B52 = 2.5
|
31
|
+
B53 = -70.0/27.0
|
32
|
+
B54 = 35.0/27.0
|
33
|
+
B61 = 1631.0/55296.0
|
34
|
+
B62 = 175.0/512.0
|
35
|
+
B63 = 575.0/13824.0
|
36
|
+
B64 = 44275.0/110592.0
|
37
|
+
B65 = 253.0/4096.0
|
38
|
+
C1 = 37.0/378.0
|
39
|
+
C3 = 250.0/621.0
|
40
|
+
C4 = 125.0/594.0
|
41
|
+
C6 = 512.0/1771.0
|
42
|
+
DC1 = C1-2825.0/27648.0
|
43
|
+
DC3 = C3-18575.0/48384.0
|
44
|
+
DC4 = C4-13525.0/55296.0
|
45
|
+
DC5 = -277.00/14336.0
|
46
|
+
DC6 = C6-0.25
|
47
|
+
|
48
|
+
def integrate_fixed_step(y, dydx, x, h, derivs)
|
49
|
+
raise "Bad type!" unless [y, dydx].all? { |var| var.kind_of?(Vector) }
|
50
|
+
raise "Bad type!" unless [x, h].all? { |var| var.kind_of?(Float) }
|
51
|
+
raise "Bad method!" unless derivs.kind_of?(Proc)
|
52
|
+
|
53
|
+
ytemp = y + dydx * B21 * h
|
54
|
+
ak2 = derivs.call(x + A2*h, ytemp)
|
55
|
+
ytemp = y + (dydx * B31 + ak2 * B32) * h
|
56
|
+
ak3 = derivs.call(x + A3*h, ytemp)
|
57
|
+
ytemp = y + (dydx * B41 + ak2 * B42 + ak3 * B43) * h
|
58
|
+
ak4 = derivs.call(x + A4*h, ytemp)
|
59
|
+
ytemp = y + (dydx * B51 + ak2 * B52 + ak3 * B53 + ak4 * B54) * h
|
60
|
+
ak5 = derivs.call(x + A5*h, ytemp)
|
61
|
+
ytemp = y + (dydx * B61 + ak2 * B62 + ak3 * B63 + ak4 * B64 +
|
62
|
+
ak5 * B65) * h
|
63
|
+
ak6 = derivs.call(x + A6*h, ytemp)
|
64
|
+
yout = y + (dydx * C1 + ak3 * C3 + ak4 * C4 + ak6 * C6) * h
|
65
|
+
yerr = (dydx * DC1 + ak3 * DC3 + ak4 * DC4 + ak5 * DC5 + ak6 * DC6) * h
|
66
|
+
|
67
|
+
# Return new values and error terms
|
68
|
+
[yout, yerr]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if __FILE__ == $0
|
73
|
+
|
74
|
+
def assert_within_epsilon(actual, expected)
|
75
|
+
if expected.kind_of?(Vector)
|
76
|
+
expected.collect2(actual) { |x, y|
|
77
|
+
assert_within_epsilon(x, y)
|
78
|
+
}
|
79
|
+
else
|
80
|
+
(actual - expected).abs / expected < 0.001 or
|
81
|
+
raise "Values don't match! Actual was #{actual}, not #{expected}!"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
assert_within_epsilon(10000.0, 10000.00001)
|
85
|
+
|
86
|
+
const_deriv = proc do |x, y|
|
87
|
+
y.collect { |yi| 0.1 }
|
88
|
+
end
|
89
|
+
|
90
|
+
exp_deriv = proc do |x, y|
|
91
|
+
y.collect { |yi| yi }
|
92
|
+
end
|
93
|
+
|
94
|
+
integ = Cash_Karp_RK4.new()
|
95
|
+
|
96
|
+
constvec = Vector.elements([1.0] * 100)
|
97
|
+
constderiv = const_deriv.call(0, constvec)
|
98
|
+
|
99
|
+
# Integrate a constant derivative over a distance of 1.0
|
100
|
+
yout, yerr = integ.integrate_fixed_step(constvec, constderiv, 0.0, 1.0,
|
101
|
+
const_deriv)
|
102
|
+
assert_within_epsilon(yout, Vector.elements([ 1.1 ] * 100))
|
103
|
+
|
104
|
+
onevec = Vector.elements([1.0] * 100)
|
105
|
+
expderiv = exp_deriv.call(0, onevec)
|
106
|
+
dist = 0.01 # Keep this small because we only make one integration step
|
107
|
+
# Integrate e^x over a distance of 1.0, starting at e^0 == 1.0
|
108
|
+
yout, yerr = integ.integrate_fixed_step(onevec, expderiv, 0.0, dist,
|
109
|
+
exp_deriv)
|
110
|
+
assert_within_epsilon(yout, Vector.elements([ Math::E ** dist ] * 100))
|
111
|
+
|
112
|
+
print "Tests completed...\n"
|
113
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
#
|
4
|
+
# Integrator library
|
5
|
+
# Copyright (C) 2007 Noah Gibbs
|
6
|
+
#
|
7
|
+
# This library is in the public domain, and may be redistributed in any
|
8
|
+
# way.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "matrix"
|
12
|
+
require "integrator/rkck.rb"
|
13
|
+
|
14
|
+
class OneStep_Cash_Karp_RK45 < Cash_Karp_RK4
|
15
|
+
SAFETY = 0.9
|
16
|
+
PGROW = -0.2
|
17
|
+
PSHRNK = -0.25
|
18
|
+
ERRCON = 1.89e-4
|
19
|
+
|
20
|
+
def integrate_ad_step(y, dydx, x, htry, eps, yscal, derivs)
|
21
|
+
h = htry
|
22
|
+
|
23
|
+
while(true) do
|
24
|
+
ytemp, yerr = integrate_fixed_step(y, dydx, x, h, derivs)
|
25
|
+
errmax = yerr.collect2(yscal) { |err, scal| (err/scal).abs }.max
|
26
|
+
errmax /= eps
|
27
|
+
break if errmax <= 1.0
|
28
|
+
htemp = SAFETY * h * (errmax ** PSHRNK)
|
29
|
+
h = h >= 0.0 ? [htemp, 0.1 * h].max : [htemp, 0.1 * h].min
|
30
|
+
xnew = x + h
|
31
|
+
raise "Step underflow!" if xnew == x
|
32
|
+
end
|
33
|
+
|
34
|
+
if errmax > ERRCON
|
35
|
+
hnext = SAFETY * h * (errmax ** PGROW)
|
36
|
+
else
|
37
|
+
hnext = 5 * h
|
38
|
+
end
|
39
|
+
|
40
|
+
hdid = h
|
41
|
+
x += h
|
42
|
+
y = ytemp
|
43
|
+
|
44
|
+
[x, y, hdid, hnext]
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
if __FILE__ == $0
|
50
|
+
|
51
|
+
end
|
data/lib/integrator.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
#
|
4
|
+
# Integrator library
|
5
|
+
# Copyright (C) 2007 Noah Gibbs
|
6
|
+
#
|
7
|
+
# This library is in the public domain, and may be redistributed in any
|
8
|
+
# way.
|
9
|
+
#
|
10
|
+
|
11
|
+
$:.unshift File.dirname(__FILE__)
|
12
|
+
|
13
|
+
module Integrator
|
14
|
+
|
15
|
+
def Integrator_initialize()
|
16
|
+
@kmax = 0 # Max steps to save
|
17
|
+
@dxsav = 0.01 # Minimum step size to save data
|
18
|
+
@xp = nil # Array to save X coords
|
19
|
+
@yp = nil # Array to save Y vectors
|
20
|
+
|
21
|
+
# Stats from most recent integrate call
|
22
|
+
@nok = 0
|
23
|
+
@nbad = 0
|
24
|
+
@count = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def set_adaptive_sample_count(count, num_ok)
|
30
|
+
@count = count
|
31
|
+
@nok = num_ok
|
32
|
+
@nbad = count - num_ok
|
33
|
+
end
|
34
|
+
|
35
|
+
public
|
36
|
+
|
37
|
+
# Set sample logging. Num_max is the maximum number of
|
38
|
+
# samples to log, and min_x_save is the minimum distance
|
39
|
+
# between x samples to bother to log.
|
40
|
+
#
|
41
|
+
def set_max_samples(num_max, min_x_save = 0.01)
|
42
|
+
@kmax = num_max
|
43
|
+
@xp = []
|
44
|
+
@yp = []
|
45
|
+
@dxsav = min_x_save
|
46
|
+
end
|
47
|
+
|
48
|
+
# Integrate from time t_start to t_end, starting from initial
|
49
|
+
# value y0. Use the 'derivs' proc to evaluate derivatives at
|
50
|
+
# a given point. Start by taking a step of size step_start,
|
51
|
+
# take steps no smaller than step_min, and attempt to keep the
|
52
|
+
# error per step down to a maximum of epsilon.
|
53
|
+
#
|
54
|
+
def integrate(y0, t_start, t_end, derivs, step_start = 0.1,
|
55
|
+
step_min = 0.0001, epsilon = 0.01)
|
56
|
+
raise "y0 must be a vector!" unless y0.kind_of?(Vector)
|
57
|
+
raise "Must give derivative proc!" unless derivs.kind_of?(Proc)
|
58
|
+
|
59
|
+
adaptive_integrate(y0, t_start, t_end, epsilon,
|
60
|
+
step_start, step_min, derivs)
|
61
|
+
end
|
62
|
+
|
63
|
+
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.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]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = 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]
|
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/integrator/version.rb'
|
15
|
+
|
16
|
+
version = Integrator::VERSION::STRING
|
17
|
+
download = 'http://rubyforge.org/projects/integrator'
|
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)
|