rote 0.2.4.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTORS +3 -2
- data/DONE +22 -0
- data/README +11 -2
- data/Rakefile +25 -4
- data/TODO +7 -9
- data/doc/layouts/page.html +3 -0
- data/doc/pages/COMMON.rb +0 -11
- data/doc/pages/guide/COMMON.rb +5 -3
- data/doc/pages/guide/index.html +373 -120
- data/doc/res/stylesheets/normal.css +63 -0
- data/lib/rote.rb +2 -3
- data/lib/rote/app.rb +1 -1
- data/lib/rote/builtin.rf +3 -33
- data/lib/rote/filters.rb +10 -0
- data/lib/rote/filters/base.rb +135 -0
- data/lib/rote/filters/rdoc.rb +25 -0
- data/lib/rote/filters/redcloth.rb +40 -0
- data/lib/rote/filters/syntax.rb +38 -0
- data/lib/rote/filters/tidy.rb +55 -0
- data/lib/rote/filters/toc.rb +74 -0
- data/lib/rote/format.rb +9 -0
- data/lib/rote/format/html.rb +49 -0
- data/lib/rote/page.rb +194 -141
- data/lib/rote/project/Rakefile +26 -5
- data/lib/rote/rotetasks.rb +133 -20
- data/test/gem_tests.rb +3 -1
- data/test/layouts/simple.rb +1 -0
- data/test/pages/markdown.txt +5 -1
- data/test/pages/rdoc.txt +4 -1
- data/test/pages/textile.rb +2 -0
- data/test/test_formatting.rb +140 -0
- data/test/test_html_page.rb +33 -0
- data/test/test_page.rb +72 -50
- metadata +15 -2
data/lib/rote/project/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Standard Rakefile for custom Rote build
|
2
2
|
#
|
3
3
|
# Generated from:
|
4
|
-
# $Id: Rakefile,v 1.
|
4
|
+
# $Id: Rakefile,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
|
5
5
|
#
|
6
6
|
begin
|
7
7
|
require 'rubygems'
|
@@ -11,6 +11,7 @@ end
|
|
11
11
|
require 'rake'
|
12
12
|
require 'rake/clean'
|
13
13
|
require 'rote'
|
14
|
+
include Rote
|
14
15
|
|
15
16
|
# Create a set of tasks with the prefix 'doc' to build the
|
16
17
|
# documentation set. The directory layout is as for the
|
@@ -29,16 +30,36 @@ require 'rote'
|
|
29
30
|
#
|
30
31
|
# In addition to these tasks, you may also wish to define a 'doc_refresh' task
|
31
32
|
# to be run whenever modified resources are processed in monitor mode.
|
32
|
-
ws = Rote::DocTask.new(:doc)
|
33
|
+
ws = Rote::DocTask.new(:doc) do |site|
|
33
34
|
site.output_dir = 'html'
|
34
35
|
site.layout_dir = 'doc/layouts'
|
35
36
|
|
36
37
|
site.pages.dir = 'doc/pages'
|
37
|
-
site.pages.include('**/*')
|
38
|
-
|
38
|
+
site.pages.include('**/*')
|
39
|
+
|
39
40
|
site.res.dir = 'doc/res'
|
40
41
|
site.res.include('**/*')
|
41
|
-
|
42
|
+
|
43
|
+
# TODO need to figure out what default mappings should be
|
44
|
+
site.ext_mapping(/(thtml)/, 'html') do |page|
|
45
|
+
page.extend Format::HTML
|
46
|
+
page.page_filter Filters::RedCloth.new(:textile)
|
47
|
+
end
|
48
|
+
|
49
|
+
site.ext_mapping(/mhtml/, 'html') do |page|
|
50
|
+
page.extend Format::HTML
|
51
|
+
page.page_filter Filters::RedCloth.new(:markdown)
|
52
|
+
end
|
53
|
+
|
54
|
+
site.ext_mapping(/rdoc/, 'html') do |page|
|
55
|
+
page.extend Format::HTML
|
56
|
+
page.page_filter Filters::RDoc.new
|
57
|
+
end
|
58
|
+
|
59
|
+
site.ext_mapping(/html/, 'html') do |page|
|
60
|
+
page.extend Format::HTML
|
61
|
+
end
|
62
|
+
end
|
42
63
|
|
43
64
|
task :default => [:doc]
|
44
65
|
|
data/lib/rote/rotetasks.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
#--
|
1
2
|
# Rake tasklib for Rote
|
2
3
|
# (c)2005 Ross Bamford (and contributors)
|
3
4
|
#
|
4
5
|
# See 'rote.rb' or LICENSE for licence information.
|
5
|
-
# $Id: rotetasks.rb,v 1.
|
6
|
+
# $Id: rotetasks.rb,v 1.9 2005/12/12 02:45:24 roscopeco Exp $
|
7
|
+
#++
|
6
8
|
require 'rake'
|
7
9
|
require 'rake/tasklib'
|
8
10
|
|
@@ -53,6 +55,54 @@ module Rote
|
|
53
55
|
fl
|
54
56
|
end
|
55
57
|
end
|
58
|
+
|
59
|
+
# Special type of Hash that uses Regexp keys and maintains insertion order.
|
60
|
+
# When searching for a string, the first match (of either kind) is used.
|
61
|
+
# Allows backreferences from the key match to be used in the value with $1..$n
|
62
|
+
# notation in val str.
|
63
|
+
#
|
64
|
+
# Entries are kept in insertion order. Searches/insertion are slow, iteration
|
65
|
+
# is constant time. It's basically an unbucketed hash.
|
66
|
+
class ExtHash
|
67
|
+
class << self
|
68
|
+
alias :[] :new
|
69
|
+
end
|
70
|
+
|
71
|
+
# Create a new RxHash, copying the supplied
|
72
|
+
# map (in random order).
|
73
|
+
def initialize(map = nil)
|
74
|
+
@data = []
|
75
|
+
map.each { |k,v| self[k] = v } if map
|
76
|
+
end
|
77
|
+
|
78
|
+
# Insert the given regex key unless it already exists.
|
79
|
+
# You may use string representations for the keys, but
|
80
|
+
# they are converted as-is to regexps.
|
81
|
+
#
|
82
|
+
# Returns the value that was inserted, or nil.
|
83
|
+
def []=(key,value)
|
84
|
+
@data << [key,value] unless member?(key)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Fetch the first matching data.
|
88
|
+
def [](key)
|
89
|
+
md = nil
|
90
|
+
if v = @data.detect { |it| md = /^#{it[0]}$/.match(key.to_s) }
|
91
|
+
v[1][0].gsub!(/\$(\d)/) { md[$1.to_i] }
|
92
|
+
v[1]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Fetch a single entry based on key equality.
|
97
|
+
def fetch_entry(key)
|
98
|
+
@data.detect { |it| it[0] == key }
|
99
|
+
end
|
100
|
+
|
101
|
+
# Determine membership based on key equality.
|
102
|
+
def member?(key)
|
103
|
+
true if fetch_entry(key)
|
104
|
+
end
|
105
|
+
end
|
56
106
|
|
57
107
|
#####
|
58
108
|
## Rake task library that provides a set of tasks to transform documentation
|
@@ -95,8 +145,25 @@ module Rote
|
|
95
145
|
# +FileList+.
|
96
146
|
attr_reader :res
|
97
147
|
|
148
|
+
# Ordered +ExtHash+ that supplies mappings between input and output
|
149
|
+
# file extensions. Keys are regexps that are matched in order
|
150
|
+
# against the search key.
|
151
|
+
#
|
152
|
+
# The values are [extension, ({ |page| ...})] . If a mapping has a
|
153
|
+
# block, it is executed when pages with a matching extension are,
|
154
|
+
# instantiated (before common and page code). It can be used to apply
|
155
|
+
# filters, for example, on a per-extension basis.
|
156
|
+
attr_reader :ext_mappings
|
157
|
+
|
158
|
+
# Define an extension mapping for the specified regex, which will
|
159
|
+
# be replaced with the specified extension. If a block is supplied
|
160
|
+
# it will be called with each matching +Page+ as it's created.
|
161
|
+
def ext_mapping(match, extension, &block)
|
162
|
+
@ext_mappings[match] = [extension,block]
|
163
|
+
end
|
164
|
+
|
98
165
|
# If +show_page_tasks+ is +true+, then the file tasks created for each
|
99
|
-
#
|
166
|
+
# output file will be shown in the Rake task listing from the command line.
|
100
167
|
attr_accessor :show_file_tasks
|
101
168
|
alias :show_file_tasks? :show_file_tasks
|
102
169
|
alias :show_file_tasks= :show_file_tasks=
|
@@ -111,16 +178,17 @@ module Rote
|
|
111
178
|
|
112
179
|
# Create a new DocTask, using the supplied block for configuration,
|
113
180
|
# and define tasks with the specified base-name within Rake.
|
114
|
-
def initialize(name = :
|
181
|
+
def initialize(name = :doc) # :yield: self if block_given?
|
115
182
|
@name = name
|
116
183
|
@output_dir = '.'
|
117
184
|
@pages = FilePatterns.new('.')
|
118
185
|
@res = FilePatterns.new('.')
|
119
186
|
@monitor_interval = 1
|
120
|
-
|
121
|
-
|
187
|
+
@ext_mappings = ExtHash.new
|
122
188
|
@show_page_tasks = false
|
123
189
|
|
190
|
+
DEFAULT_SRC_EXCLUDES.each { |excl| @pages.exclude(excl) }
|
191
|
+
|
124
192
|
yield self if block_given?
|
125
193
|
|
126
194
|
define
|
@@ -135,16 +203,32 @@ module Rote
|
|
135
203
|
nil
|
136
204
|
end
|
137
205
|
|
206
|
+
# Get a target filename for a source filename. The dir_rx must
|
207
|
+
# match the portion of the directory that will be replaced
|
208
|
+
# with the target directory. The extension is mapped through
|
209
|
+
# ext_mappings. If a block is configured for this extension,
|
210
|
+
# it is returned too.
|
211
|
+
#
|
212
|
+
# Returns [target_fn, ({ |page| ...})]
|
213
|
+
def target_fn(dir_rx, fn)
|
214
|
+
tfn = fn.sub(dir_rx, output_dir)
|
215
|
+
ext = File.extname(tfn)
|
216
|
+
ext.sub!(/^\./,'') # strip leading dot
|
217
|
+
new_ext, blk = ext_mappings[ext] || [ext,nil]
|
218
|
+
[tfn.sub(/#{ext}$/,new_ext),blk]
|
219
|
+
end
|
220
|
+
|
138
221
|
# define a task for each resource, and 'all resources' task
|
139
222
|
def define_res_tasks
|
140
223
|
res_fl = res.to_filelist
|
141
224
|
tasks = res_fl.select { |fn| not File.directory?(fn) }.map do |fn|
|
142
|
-
tfn =
|
143
|
-
|
225
|
+
tfn, = target_fn(/^#{res.dir}/, fn)
|
226
|
+
|
227
|
+
desc "#{fn} => #{tfn}" #if show_file_tasks?
|
144
228
|
file tfn => [fn] do
|
145
229
|
dn = File.dirname(tfn)
|
146
230
|
mkdir_p dn unless File.exists?(dn)
|
147
|
-
cp fn, tfn
|
231
|
+
cp fn, tfn, :preserve => true
|
148
232
|
end
|
149
233
|
tfn
|
150
234
|
end
|
@@ -156,22 +240,52 @@ module Rote
|
|
156
240
|
# define a task for each page, and 'all pages' task
|
157
241
|
def define_page_tasks
|
158
242
|
pages_fl = pages.to_filelist
|
159
|
-
|
160
|
-
|
161
|
-
|
243
|
+
|
244
|
+
gen_files = pages_fl.select { |fn| not File.directory?(fn) }.map do |fn|
|
245
|
+
tfn, blk = target_fn(/^#{pages.dir}/, fn)
|
246
|
+
|
247
|
+
desc "#{fn} => #{tfn}" #if show_file_tasks?
|
162
248
|
file tfn => [fn] do
|
163
249
|
dn = File.dirname(tfn)
|
164
250
|
mkdir_p dn unless File.exists?(dn)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
251
|
+
puts "tr #{fn} => #{tfn}"
|
252
|
+
begin
|
253
|
+
File.open(tfn, 'w+') do |f|
|
254
|
+
# new page, run extension block, render out, throw away
|
255
|
+
f << Page.new(fn,pages.dir,layout_dir,&blk).render
|
256
|
+
end
|
257
|
+
rescue => e
|
258
|
+
# Oops... Unlink file and dump backtrace
|
259
|
+
File.unlink(tfn)
|
260
|
+
bt = e.backtrace
|
261
|
+
end_idx = bt.each_with_index do |entry, idx|
|
262
|
+
break idx if entry =~ /^#{File.dirname(__FILE__)}/
|
263
|
+
end
|
264
|
+
puts bt[0...end_idx]
|
265
|
+
raise
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Each page depends properly on source and common - thx again
|
270
|
+
# Jonathan :)
|
271
|
+
src_rb = Page::page_ruby_filename(fn)
|
272
|
+
if File.exists?(src_rb)
|
273
|
+
file tfn => [src_rb]
|
169
274
|
end
|
275
|
+
|
276
|
+
common_rbs = Page::resolve_common_rubys(File.dirname(fn))
|
277
|
+
file tfn => common_rbs unless common_rbs.empty?
|
278
|
+
|
170
279
|
tfn
|
171
280
|
end
|
172
281
|
|
173
282
|
desc "Render new/changed documentation pages"
|
174
|
-
task "#{name}_pages" =>
|
283
|
+
task "#{name}_pages" => gen_files
|
284
|
+
task "clobber_#{name}_pages" do
|
285
|
+
gen_files.each do |f|
|
286
|
+
rm_f f
|
287
|
+
end
|
288
|
+
end
|
175
289
|
end
|
176
290
|
|
177
291
|
def define_main_tasks
|
@@ -200,13 +314,12 @@ module Rote
|
|
200
314
|
|
201
315
|
end
|
202
316
|
|
203
|
-
end #class
|
204
|
-
|
317
|
+
end #class
|
205
318
|
end #module
|
206
319
|
|
207
|
-
## The
|
320
|
+
## The +monitor+ task requires a few mods to Rake to let us fire
|
208
321
|
## and reset task invocations in a loop.
|
209
|
-
module Rake
|
322
|
+
module Rake # :nodoc: all
|
210
323
|
class Task
|
211
324
|
def reset
|
212
325
|
@already_invoked = false
|
data/test/gem_tests.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
@layout_code_works = true
|
data/test/pages/markdown.txt
CHANGED
data/test/pages/rdoc.txt
CHANGED
data/test/pages/textile.rb
CHANGED
@@ -0,0 +1,140 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
rescue LoadError
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
require 'rote/page'
|
9
|
+
require 'rote/filters/redcloth'
|
10
|
+
require 'rote/filters/rdoc'
|
11
|
+
require 'rote/filters/proc'
|
12
|
+
require 'rote/filters/toc'
|
13
|
+
require 'rote/filters/syntax'
|
14
|
+
|
15
|
+
SYNTEST = <<-EOM
|
16
|
+
<p>Non-code</p>
|
17
|
+
#:code#ruby#
|
18
|
+
def amethod(arg)
|
19
|
+
puts arg
|
20
|
+
end
|
21
|
+
#:code#
|
22
|
+
<p>More non-code</p>
|
23
|
+
#:code#ruby#
|
24
|
+
def amethod_too(arg)
|
25
|
+
puts arg
|
26
|
+
end
|
27
|
+
#:code#
|
28
|
+
|
29
|
+
EOM
|
30
|
+
|
31
|
+
SYNEXPECT = <<-EOM
|
32
|
+
<p>Non-code</p>
|
33
|
+
<pre class='ruby'><code> <span class=\"keyword\">def </span><span class=\"method\">amethod</span><span class=\"punct\">(</span><span class=\"ident\">arg</span><span class=\"punct\">)</span>
|
34
|
+
<span class=\"ident\">puts</span> <span class=\"ident\">arg</span>
|
35
|
+
<span class=\"keyword\">end</span></code></pre>
|
36
|
+
<p>More non-code</p>
|
37
|
+
<pre class='ruby'><code> <span class=\"keyword\">def </span><span class=\"method\">amethod_too</span><span class=\"punct\">(</span><span class=\"ident\">arg</span><span class=\"punct\">)</span>
|
38
|
+
<span class=\"ident\">puts</span> <span class=\"ident\">arg</span>
|
39
|
+
<span class=\"keyword\">end</span></code></pre>
|
40
|
+
EOM
|
41
|
+
|
42
|
+
TOCTEST = <<-EOM
|
43
|
+
<h2>Section One</h2>
|
44
|
+
<p>This is section one</p>
|
45
|
+
<h3>Section Two</h3>
|
46
|
+
<p>This is section two</p>
|
47
|
+
EOM
|
48
|
+
|
49
|
+
TOCEXPECTH2 = <<-EOM
|
50
|
+
<a name='section_one'></a><h2>Section One</h2>
|
51
|
+
<p>This is section one</p>
|
52
|
+
<h3>Section Two</h3>
|
53
|
+
<p>This is section two</p>
|
54
|
+
EOM
|
55
|
+
|
56
|
+
TOCEXPECTALL = <<-EOM
|
57
|
+
<a name='section_one'></a><h2>Section One</h2>
|
58
|
+
<p>This is section one</p>
|
59
|
+
<a name='section_two'></a><h3>Section Two</h3>
|
60
|
+
<p>This is section two</p>
|
61
|
+
EOM
|
62
|
+
|
63
|
+
module Rote
|
64
|
+
class TestFormatting < Test::Unit::TestCase
|
65
|
+
############## filters/redcloth #################
|
66
|
+
def test_render_default # textile
|
67
|
+
t = Filters::RedCloth.new.filter('*Textile* _Test_', nil)
|
68
|
+
assert_equal '<p><strong>Textile</strong> <em>Test</em></p>', t
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_render_textile
|
72
|
+
t = Filters::RedCloth.new(:textile).filter('*Textile* _Test_', nil)
|
73
|
+
assert_equal '<p><strong>Textile</strong> <em>Test</em></p>', t
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_render_markdown
|
77
|
+
t = Filters::RedCloth.new(:markdown).filter("*this* is a _test_\n==================", nil)
|
78
|
+
assert_equal '<h1>*this* is a _test_</h1>', t
|
79
|
+
end
|
80
|
+
|
81
|
+
############## filters/rdoc #################
|
82
|
+
# FIXME Fails under Gem install, but passes when run normally (???)
|
83
|
+
unless defined?(TEST_FROM_GEM)
|
84
|
+
def test_render_rdoc
|
85
|
+
t = Filters::RDoc.new.filter("== RDoc\n=== Markup",nil)
|
86
|
+
assert_equal "<h2>RDoc</h2>\n<h3>Markup</h3>\n", t
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
############## filters/proc #################
|
91
|
+
# FIXME Fails under Gem install, but passes when run normally (???)
|
92
|
+
def test_proc_no_block
|
93
|
+
begin
|
94
|
+
Filters::Proc.new
|
95
|
+
rescue ArgumentError => ex
|
96
|
+
assert_equal 'No block given', ex.message
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_render_with_proc
|
101
|
+
f = Filters::Proc.new { |text, page| text + page }
|
102
|
+
assert_equal f.filter('some text ', 'fake page'), 'some text fake page'
|
103
|
+
|
104
|
+
# equivalent
|
105
|
+
f = Filters::Proc.with do |text, page|
|
106
|
+
text + page
|
107
|
+
end
|
108
|
+
assert_equal f.filter('some text ', 'fake page'), 'some text fake page'
|
109
|
+
end
|
110
|
+
|
111
|
+
# Toc filter is a non-output filter - it's used to get a list of links in
|
112
|
+
# the page, from layout code. It should output it's input directly, so
|
113
|
+
# that it doesn't matter where in the chain it is.
|
114
|
+
def test_toc_filter
|
115
|
+
# default RE
|
116
|
+
toc = Filters::TOC::new
|
117
|
+
assert_equal '<p>Has no sections</p>', toc.filter('<p>Has no sections</p>', nil)
|
118
|
+
assert toc.links.empty?
|
119
|
+
|
120
|
+
assert_equal TOCEXPECTALL, toc.filter(TOCTEST, nil)
|
121
|
+
assert_equal "<a href='#section_one'>Section One</a> - <a href='#section_two'>Section Two</a>", toc.links.join(' - ')
|
122
|
+
|
123
|
+
# custom RE
|
124
|
+
toc = Filters::TOC::new(/h2/)
|
125
|
+
assert_equal TOCEXPECTH2, toc.filter(TOCTEST, nil)
|
126
|
+
assert_equal "<a href='#section_one'>Section One</a>", toc.links.join(' - ')
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_syntax_filter
|
130
|
+
# bad
|
131
|
+
assert_equal '', Filters::Syntax.new.filter('', nil)
|
132
|
+
assert_equal 'Has no source', Filters::Syntax.new.filter('Has no source', nil)
|
133
|
+
|
134
|
+
# good
|
135
|
+
assert_equal SYNEXPECT.chomp, Filters::Syntax.new.filter(SYNTEST, nil)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|