rote 0.3.0.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: rdoc.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: rdoc.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  require 'rdoc/markup/simple_markup'
@@ -1,9 +1,9 @@
1
1
  #--
2
2
  # Rote filter for RedCloth
3
- # (c)2005 Ross Bamford (and contributors)
3
+ # (c)2005, 2006 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: redcloth.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: redcloth.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  require 'redcloth'
@@ -12,20 +12,22 @@ require 'rote/filters/base'
12
12
  module Rote
13
13
  module Filters
14
14
  #####
15
- ## Page filter that converts plain-text formatting to HTML using
16
- ## RedCloth. This allows both Textile and Markdown formatting
17
- ## to be used with any page.
15
+ ## Page filter that converts Textile formatting to HTML using
16
+ ## RedCloth.
17
+ ##
18
+ ## *Note* that, although RedCloth provides partial Markdown
19
+ ## support, it is *highly recommended* that the BlueCloth
20
+ ## filter be applied to markdown pages instead of this one.
18
21
  class RedCloth < TextFilter
19
22
 
20
23
  # Create a new filter instance. The supplied options are passed
21
- # directly to RedCloth. The most common are :textile and
22
- # :markdown - See RedCloth docs for a full list.
24
+ # directly to RedCloth. See RedCloth docs for a full list.
23
25
  #
24
- # If no options are supplied, :textile is assumed.
26
+ # If no options are supplied, full textile support is
27
+ # provided.
25
28
  def initialize(*redcloth_opts)
26
29
  super()
27
30
  @redcloth_opts = redcloth_opts
28
- raise "RedCloth is not available" unless defined?(RedCloth)
29
31
  end
30
32
 
31
33
  def handler(text,page)
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: syntax.rb,v 1.3 2005/12/14 19:17:21 roscopeco Exp $
6
+ # $Id: syntax.rb 144 2005-12-14 19:17:21 +0000 (Wed, 14 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  require 'syntax'
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: tidy.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: tidy.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  module Rote
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: toc.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: toc.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  module Rote
data/lib/rote/format.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: format.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: format.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  Dir[File.join(File.dirname(__FILE__), 'format/*.rb')].each { |f| require f }
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: html.rb,v 1.2 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: html.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
  require 'erb'
9
9
 
data/lib/rote/page.rb CHANGED
@@ -1,15 +1,13 @@
1
1
  #--
2
2
  # Rote page class
3
- # (c)2005 Ross Bamford (and contributors)
3
+ # (c)2005, 2006 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: page.rb,v 1.11 2005/12/14 19:01:05 roscopeco Exp $
6
+ # $Id: page.rb 143 2005-12-14 19:01:05 +0000 (Wed, 14 Dec 2005) roscopeco $
7
7
  #++
8
8
 
9
9
  require 'erb'
10
-
11
- # Don't want user to have to require these in their pagecode.
12
- require 'rote/format/html'
10
+ require 'rote/cache'
13
11
 
14
12
  module Rote
15
13
  STRIP_SLASHES = /^\/?(.*?)\/?$/
@@ -69,11 +67,18 @@ module Rote
69
67
 
70
68
  # The text of the layout to use for this page. This is read in
71
69
  # when (if) the page source calls layout(basename).
72
- attr_reader :layout_text
70
+ #
71
+ # *Deprecated* This has no knowledge of nested layout,
72
+ # and operates only on the innermost layout.
73
+ attr_reader :layout_text # Deprecated vv0.3.2 v-0.4
73
74
 
74
75
  # The names from which this page's template and layout (if any)
75
- # were read, relative to the +base_path+.
76
- attr_reader :template_name, :layout_name
76
+ # are read, relative to the +base_path+.
77
+ attr_reader :template_name, :layout_names
78
+
79
+ # Convenience accessor for the first queued layout. This is the
80
+ # innermost layout, usually specified by the page itself.
81
+ def layout_name; layout_names.first; end
77
82
 
78
83
  # The base paths for this page's template and layout. These point
79
84
  # to the directories configured in the Rake tasks.
@@ -100,12 +105,12 @@ module Rote
100
105
  def initialize(template_name, pages_dir = '.', layout_dir = pages_dir, &blk)
101
106
  @template_text = nil
102
107
  @template_name = nil
103
- @layout_text = nil
104
- @layout_name = nil
108
+ @layout_names = []
105
109
  @content_for_layout = nil
106
110
  @result = nil
107
111
  @layout_defext = File.extname(template_name)
108
112
  @layout_path = layout_dir[STRIP_SLASHES,1]
113
+ @layout_text = nil
109
114
  @base_path = pages_dir[STRIP_SLASHES,1]
110
115
 
111
116
  @page_filters, @post_filters = [], []
@@ -130,13 +135,13 @@ module Rote
130
135
  # Returns the full filename of this Page's template. This is obtained by
131
136
  # joining the base path with template name.
132
137
  def template_filename
133
- template_name ? File.join(base_path,template_name) : nil
138
+ File.join(base_path,template_name) if template_name
134
139
  end
135
140
 
136
- # Returns the full filename of this Page's template. This is obtained by
137
- # joining the base path with template name.
141
+ # Returns the full filename of the first queued layout. This is
142
+ # the innermost layout, usually specified by the page itself.
138
143
  def layout_filename
139
- layout_name ? File.join(layout_path,layout_name) : nil
144
+ layout_fn(layout_name)
140
145
  end
141
146
 
142
147
  # Returns the full filename of this Page's ruby source. If no source is
@@ -179,11 +184,11 @@ module Rote
179
184
  @result or do_render! # sets up result for next time...
180
185
  end
181
186
 
182
- alias to_s render
187
+ alias :to_s :render
183
188
 
184
- # Sets the layout from the specified file, or disables layout if
185
- # +nil+ is passed in. The specified basename should be the name
186
- # of the layout file relative to the +layout_dir+, with no extension.
189
+ # Adds the specified layout to those that will be rendered. The specified
190
+ # basename should be the name of the layout file relative to the
191
+ # +layout_dir+, with no extension.
187
192
  #
188
193
  # *The* *layout* *is* *not* *read* *by* *this* *method*. It, and
189
194
  # it's source, are loaded only at rendering time. This prevents
@@ -194,10 +199,7 @@ module Rote
194
199
  # that the instance is frozen.
195
200
  def layout(basename)
196
201
  if basename
197
- # layout text
198
- @layout_name = "#{basename}#{@layout_defext if File.extname(basename).empty?}"
199
- else
200
- @layout_name = nil
202
+ self.layout_names << "#{basename}#{@layout_defext if File.extname(basename).empty?}"
201
203
  end
202
204
  end
203
205
 
@@ -224,17 +226,28 @@ module Rote
224
226
  end
225
227
  end
226
228
 
227
- def load_layout
228
- if fn = layout_filename
229
- raise "Layout #{fn} not found" unless File.exists?(fn)
230
- @layout_text = File.read(fn)
229
+ def layout_fn(fn)
230
+ File.join(layout_path,fn) if fn
231
+ end
232
+
233
+ # Loads the layout. This method evaluates the layout code
234
+ # and returns it's text. The layout (and code if found)
235
+ # are also registered as cached deps.
236
+ def load_layout(fn)
237
+ if fn = layout_fn(fn)
238
+ raise "Layout #{fn} not found" unless File.exists?(fn)
231
239
 
232
240
  # layout code
233
241
  cfn = Page::page_ruby_filename(fn)
234
- instance_eval(File.read(cfn), cfn) if File.exists?(cfn)
242
+ if File.exists?(cfn)
243
+ instance_eval(File.read(cfn), cfn)
244
+ Rake.register_dependency(cfn)
245
+ end
246
+
247
+ Rake.register_dependency(fn)
248
+ File.read(fn)
235
249
  end
236
- end
237
-
250
+ end
238
251
 
239
252
  def render_page_filters(text)
240
253
  page_filters.inject(text) { |s, f| f.filter(s, self) }
@@ -254,19 +267,33 @@ module Rote
254
267
  @content_for_layout = render_page_filters( erb.result(binding) )
255
268
  end
256
269
 
257
- # Load layout _after_ page eval, allowing page to override layout.
258
- load_layout
259
-
260
- # render into the layout if supplied.
261
- @result = if !@layout_text.nil?
262
- erb = ERB.new(@layout_text)
263
- erb.filename = layout_filename
264
- erb.result(binding)
265
- else
266
- @content_for_layout
267
- end
270
+ # Do layout _after_ page eval. As we go through this, the layouts
271
+ # we load may add to the end of the layout names array, so nested
272
+ # layout is supported by just chasing the end of the array until
273
+ # it's empty. The process is basically
274
+ #
275
+ # Page is loaded, calls 'layout' with it's layout.
276
+ # During render, that fn is taken, and loaded. Layout code
277
+ # again calls 'layout'.
278
+ # On next loop iteration, that new filename is loaded, and it's
279
+ # code is executed ... and so on.
280
+ #
281
+ # Each loop puts the result into @content_for_layout, so that
282
+ # nested layouts can work just the same as regular.
283
+ @layout_names.each do |fn|
284
+ txt = load_layout(fn)
285
+
286
+ @layout_text ||= txt # legacy support vv0.3.2 v-0.4
287
+
288
+ # render into the layout if supplied.
289
+ if txt
290
+ erb = ERB.new(txt)
291
+ erb.filename = fn
292
+ @content_for_layout = erb.result(binding)
293
+ end
294
+ end
268
295
 
269
- @result = render_post_filters(@result)
296
+ @result = render_post_filters(@content_for_layout)
270
297
  freeze
271
298
 
272
299
  @result
@@ -1,7 +1,7 @@
1
1
  # Standard Rakefile for custom Rote build
2
2
  #
3
3
  # Generated from:
4
- # $Id: Rakefile,v 1.3 2005/12/14 19:01:05 roscopeco Exp $
4
+ # $Id: Rakefile 143 2005-12-14 19:01:05 +0000 (Wed, 14 Dec 2005) roscopeco $
5
5
  #
6
6
  begin
7
7
  require 'rubygems'
@@ -12,8 +12,7 @@ end
12
12
  require 'rake'
13
13
  require 'rake/clean'
14
14
  require 'rote'
15
- require 'rote/filters/redcloth'
16
- require 'rote/filters/rdoc'
15
+ require 'rote/filters'
17
16
  require 'rote/format/html'
18
17
 
19
18
  include Rote
@@ -47,12 +46,12 @@ ws = Rote::DocTask.new(:doc) do |site|
47
46
 
48
47
  site.ext_mapping(/thtml|textile/, 'html') do |page|
49
48
  page.extend Format::HTML
50
- page.page_filter Filters::RedCloth.new(:textile)
49
+ page.page_filter Filters::RedCloth.new
51
50
  end
52
51
 
53
52
  site.ext_mapping(/mhtml|markdown/, 'html') do |page|
54
53
  page.extend Format::HTML
55
- page.page_filter Filters::RedCloth.new(:markdown)
54
+ page.page_filter Filters::BlueCloth.new
56
55
  end
57
56
 
58
57
  site.ext_mapping(/rdhtml|rdoc/, 'html') do |page|
@@ -3,7 +3,7 @@
3
3
  # (c)2005 Ross Bamford (and contributors)
4
4
  #
5
5
  # See 'rote.rb' or LICENSE for licence information.
6
- # $Id: rotetasks.rb,v 1.9 2005/12/12 02:45:24 roscopeco Exp $
6
+ # $Id: rotetasks.rb 128 2005-12-12 02:45:24 +0000 (Mon, 12 Dec 2005) roscopeco $
7
7
  #++
8
8
  require 'rake'
9
9
  require 'rake/tasklib'
@@ -0,0 +1,2 @@
1
+ # try nesting this layout in 'simple'
2
+ layout 'simple'
@@ -0,0 +1 @@
1
+ this: '<%= @content_for_layout %>'
@@ -0,0 +1,5 @@
1
+ # config
2
+ layout 'nestme'
3
+
4
+ # custom stuff
5
+ @myvar = 'some text'
@@ -0,0 +1 @@
1
+ <%= @myvar %> and <%= @global %>
@@ -0,0 +1,67 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue LoadError
4
+ nil
5
+ end
6
+
7
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__),'../lib'))
8
+
9
+ require 'rake'
10
+ require 'rote/cache'
11
+
12
+ module Rote
13
+ class TestCache < Test::Unit::TestCase
14
+
15
+ def test_rake_cache_dir
16
+ assert_equal '.rake_cache', Rake.cache_dir
17
+ Rake.cache_dir = './.cache'
18
+ assert_equal './.cache', Rake.cache_dir
19
+ Rake.cache_dir = nil
20
+ assert_equal '.rake_cache', Rake.cache_dir
21
+ end
22
+
23
+ def test_rake_dependencies_file
24
+ assert_equal '.rake_cache/dependencies.yaml', Rake.dependencies_file
25
+ Rake.cache_dir = './.cache'
26
+ assert_equal './.cache/dependencies.yaml', Rake.dependencies_file
27
+ Rake.cache_dir = nil
28
+ assert_equal '.rake_cache/dependencies.yaml', Rake.dependencies_file
29
+ end
30
+
31
+ def test_rake_task_stack
32
+ assert_equal [], Rake.task_stack
33
+
34
+ outertask = task :outertask do
35
+ assert_equal ['outertask'], Rake.task_stack
36
+
37
+ innertask = task :innertask do
38
+ assert_equal ['outertask', 'innertask'], Rake.task_stack
39
+ end
40
+
41
+ assert_equal ['outertask'], Rake.task_stack
42
+ end
43
+
44
+ assert_equal [], Rake.task_stack
45
+ end
46
+
47
+ def test_rake_register_dep_cached_deps
48
+ assert_equal({}, Rake.cached_dependencies)
49
+
50
+ # should fail here, return nil, do nothing.
51
+ # there's no current task
52
+ assert_nil Rake.register_dependency('dep')
53
+ assert_equal({}, Rake.cached_dependencies)
54
+
55
+ testtask = task :test_register_dep do
56
+ assert_equal(['dep'], Rake.register_dependency('dep'))
57
+ end
58
+
59
+ testtask.invoke(false)
60
+
61
+ assert_equal({'test_register_dep' => ['dep']}, Rake.cached_dependencies)
62
+ end
63
+
64
+ # TODO need to test load / save
65
+
66
+ end
67
+ end
@@ -4,12 +4,18 @@ rescue LoadError
4
4
  nil
5
5
  end
6
6
 
7
+ # make sure we're testing this version, not an installed Gem!
8
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__),'../lib'))
9
+
7
10
  require 'test/unit'
8
11
  require 'rote/page'
9
12
  require 'rote/filters/redcloth'
13
+ require 'rote/filters/bluecloth'
10
14
  require 'rote/filters/rdoc'
11
15
  require 'rote/filters/toc'
12
16
  require 'rote/filters/syntax'
17
+ require 'rote/filters/exec'
18
+ require 'rote/filters/eval'
13
19
 
14
20
  SYNTEST = <<-EOM
15
21
  <p>Non-code</p>
@@ -27,6 +33,38 @@ SYNTEST = <<-EOM
27
33
 
28
34
  EOM
29
35
 
36
+ EXECTEST = <<-EOM
37
+ <p>Non-eval</p>
38
+ #:exec#ruby#
39
+ def amethod(arg)
40
+ puts arg
41
+ end
42
+
43
+ amethod('Hello, World')
44
+ #:exec#
45
+ <p>More non-code</p>
46
+ #:exec#ruby#
47
+ puts "Hello again!"
48
+ #:exec#
49
+
50
+ EOM
51
+
52
+ EVALTEST = <<-EOM
53
+ <p>Non-eval</p>
54
+ #:eval#one#
55
+ def amethod(arg)
56
+ puts arg
57
+ end
58
+
59
+ amethod('Hello, World')
60
+ #:eval#
61
+ <p>More non-code</p>
62
+ #:eval#one#
63
+ puts "Hello again!"
64
+ #:eval#
65
+
66
+ EOM
67
+
30
68
  SYNEXPECT = <<-EOM
31
69
  <p>Non-code</p>
32
70
  <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>
@@ -38,6 +76,11 @@ SYNEXPECT = <<-EOM
38
76
  <span class=\"keyword\">end</span></code></pre>
39
77
  EOM
40
78
 
79
+ EXECEXPECT = " <p>Non-eval</p>\nHello, World\n\n <p>More non-code</p>\nHello again!\n"
80
+
81
+ EVALEXPECT = " <p>Non-eval</p>\nHello, World\n\n <p>More non-code</p>\nHello again!\n"
82
+
83
+
41
84
  TOCTEST = <<-EOM
42
85
  <h2>Section One</h2>
43
86
  <p>This is section one</p>
@@ -60,7 +103,8 @@ TOCEXPECTALL = <<-EOM
60
103
  EOM
61
104
 
62
105
  module Rote
63
- class TestFormatting < Test::Unit::TestCase
106
+ class TestFilters < Test::Unit::TestCase
107
+
64
108
  ############## filters/redcloth #################
65
109
  def test_render_default # textile
66
110
  t = Filters::RedCloth.new.filter('*Textile* _Test_', nil)
@@ -68,13 +112,28 @@ module Rote
68
112
  end
69
113
 
70
114
  def test_render_textile
115
+ t = Filters::RedCloth.new.filter('*Textile* _Test_', nil)
116
+ assert_equal '<p><strong>Textile</strong> <em>Test</em></p>', t
117
+
71
118
  t = Filters::RedCloth.new(:textile).filter('*Textile* _Test_', nil)
72
119
  assert_equal '<p><strong>Textile</strong> <em>Test</em></p>', t
73
120
  end
74
121
 
75
122
  def test_render_markdown
76
- t = Filters::RedCloth.new(:markdown).filter("*this* is a _test_\n==================", nil)
77
- assert_equal '<h1>*this* is a _test_</h1>', t
123
+ t = Filters::BlueCloth.new.filter("__this__ is a _test_\n==================", nil)
124
+ assert_equal '<h1><strong>this</strong> is a <em>test</em></h1>', t
125
+ end
126
+
127
+ def test_render_markdown_custom
128
+ f = Filters::BlueCloth.new do |bluecloth, page|
129
+ assert_not_nil bluecloth
130
+ assert_nil page # we pass in nil below
131
+
132
+ bluecloth.to_html
133
+ end
134
+
135
+ t = f.filter("__this__ is a _test_\n==================", nil)
136
+ assert_equal '<h1><strong>this</strong> is a <em>test</em></h1>', t
78
137
  end
79
138
 
80
139
  ############## filters/rdoc #################
@@ -111,8 +170,27 @@ module Rote
111
170
  # good
112
171
  assert_equal SYNEXPECT.chomp, Filters::Syntax.new.filter(SYNTEST,nil)
113
172
  end
114
- # TODO test macro stuff etc.
115
173
 
174
+ def test_exec_filter
175
+ # bad
176
+ assert_equal '', Filters::Exec.new.filter('',nil)
177
+ assert_equal 'Has no source', Filters::Exec.new.filter('Has no source',nil)
178
+
179
+ # good
180
+ assert_equal EXECEXPECT, Filters::Exec.new.filter(EXECTEST,nil)
181
+ end
182
+
183
+ def test_eval_filter
184
+ # bad
185
+ assert_equal '', Filters::Eval.new.filter('',nil)
186
+ assert_equal 'Has no source', Filters::Eval.new.filter('Has no source',nil)
187
+
188
+ # good
189
+ assert_equal EVALEXPECT, Filters::Eval.new.filter(EVALTEST,nil)
190
+
191
+ # Make sure Stdout was returned to normal
192
+ assert $stdout.class != StringIO
193
+ end
116
194
  end
117
195
 
118
196