rote 0.2.4.1 → 0.3.0
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/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
|
+
|