hoe-manualgen 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.autotest +23 -0
  2. data/History.md +4 -0
  3. data/README.md +72 -0
  4. data/Rakefile +85 -0
  5. data/data/hoe-manualgen/layouts/default.erb.erb +87 -0
  6. data/data/hoe-manualgen/lib/api-filter.rb +76 -0
  7. data/data/hoe-manualgen/lib/editorial-filter.rb +59 -0
  8. data/data/hoe-manualgen/lib/examples-filter.rb +238 -0
  9. data/data/hoe-manualgen/lib/links-filter.rb +111 -0
  10. data/data/hoe-manualgen/resources/css/manual.css.erb +755 -0
  11. data/data/hoe-manualgen/resources/fonts/GraublauWeb.otf +0 -0
  12. data/data/hoe-manualgen/resources/fonts/GraublauWebBold.otf +0 -0
  13. data/data/hoe-manualgen/resources/fonts/Inconsolata.otf +0 -0
  14. data/data/hoe-manualgen/resources/images/arrow_225_small.png +0 -0
  15. data/data/hoe-manualgen/resources/images/arrow_315_small.png +0 -0
  16. data/data/hoe-manualgen/resources/images/arrow_skip.png +0 -0
  17. data/data/hoe-manualgen/resources/images/cc-by.png +0 -0
  18. data/data/hoe-manualgen/resources/images/dialog-error.png +0 -0
  19. data/data/hoe-manualgen/resources/images/dialog-information.png +0 -0
  20. data/data/hoe-manualgen/resources/images/dialog-warning.png +0 -0
  21. data/data/hoe-manualgen/resources/images/emblem-important.png +0 -0
  22. data/data/hoe-manualgen/resources/images/help.png +0 -0
  23. data/data/hoe-manualgen/resources/images/information.png +0 -0
  24. data/data/hoe-manualgen/resources/images/magnifier.png +0 -0
  25. data/data/hoe-manualgen/resources/images/magnifier_left.png +0 -0
  26. data/data/hoe-manualgen/resources/images/page_white_code.png +0 -0
  27. data/data/hoe-manualgen/resources/images/page_white_copy.png +0 -0
  28. data/data/hoe-manualgen/resources/images/printer.png +0 -0
  29. data/data/hoe-manualgen/resources/images/question.png +0 -0
  30. data/data/hoe-manualgen/resources/images/scripts_code.png +0 -0
  31. data/data/hoe-manualgen/resources/images/wrap.png +0 -0
  32. data/data/hoe-manualgen/resources/images/wrapping.png +0 -0
  33. data/data/hoe-manualgen/resources/js/jquery-1.4.4.min.js +167 -0
  34. data/data/hoe-manualgen/resources/js/manual.js +30 -0
  35. data/data/hoe-manualgen/resources/js/sh.js +580 -0
  36. data/data/hoe-manualgen/resources/swf/clipboard.swf +0 -0
  37. data/data/hoe-manualgen/src/index.page.erb +59 -0
  38. data/lib/hoe/manualgen.rb +804 -0
  39. data.tar.gz.sig +0 -0
  40. metadata +230 -0
  41. metadata.gz.sig +4 -0
data/.autotest ADDED
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
data/History.md ADDED
@@ -0,0 +1,4 @@
1
+ ## 0.0.1 [2011-01-31] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Initial release.
4
+
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # hoe-manualgen
2
+
3
+ * http://deveiate.org/hoe-manualgen.html
4
+
5
+ ## Description
6
+
7
+ A manual-generation plugin for Hoe.
8
+
9
+ This is a plugin for [Hoe][hoe] that adds tasks and resources for
10
+ generating a manual or cookbook.
11
+
12
+ It's self-documenting, so for more, see [the latest manual for hoe-manualgen itself][hoe-manualgen-manual].
13
+
14
+
15
+ ## Installation
16
+
17
+ gem install hoe-manualgen
18
+
19
+
20
+ ## Contributing
21
+
22
+ You can check out the current development source with Mercurial like so:
23
+
24
+ hg clone http://bitbucket.org/ged/hoe-manualgen
25
+
26
+ Or if you prefer Git, via its Github mirror:
27
+
28
+ https://github.com/ged/hoe-manualgen
29
+
30
+ After checking out the source, run:
31
+
32
+ $ rake newb
33
+
34
+ This task will install any missing dependencies, run the tests/specs,
35
+ and generate the API documentation.
36
+
37
+
38
+ ## License
39
+
40
+ Copyright (c) 2010, 2011, Michael Granger
41
+ All rights reserved.
42
+
43
+ Redistribution and use in source and binary forms, with or without
44
+ modification, are permitted provided that the following conditions are met:
45
+
46
+ * Redistributions of source code must retain the above copyright notice,
47
+ this list of conditions and the following disclaimer.
48
+
49
+ * Redistributions in binary form must reproduce the above copyright notice,
50
+ this list of conditions and the following disclaimer in the documentation
51
+ and/or other materials provided with the distribution.
52
+
53
+ * Neither the name of the author/s, nor the names of the project's
54
+ contributors may be used to endorse or promote products derived from this
55
+ software without specific prior written permission.
56
+
57
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
58
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
61
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
63
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
64
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
65
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
66
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67
+
68
+
69
+ [hoe]:http://seattlerb.rubyforge.org/hoe/
70
+ [hoe-manualgen-manual]:http://deveiate.org/code/hoe-manualgen/
71
+
72
+
data/Rakefile ADDED
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'hoe'
5
+ rescue LoadError
6
+ $stderr.puts "This Rakefile requires Hoe (gem install hoe)"
7
+ end
8
+
9
+ require 'rake/clean'
10
+
11
+ Hoe.add_include_dirs 'lib'
12
+
13
+ Hoe.plugin :mercurial
14
+ Hoe.plugin :signing
15
+ Hoe.plugin :manualgen
16
+
17
+ Hoe.plugins.delete :rubyforge
18
+
19
+ hoespec = Hoe.spec 'hoe-manualgen' do
20
+ self.readme_file = 'README.md'
21
+ self.history_file = 'History.md'
22
+
23
+ self.developer 'Michael Granger', 'ged@FaerieMUD.org'
24
+
25
+ self.extra_deps.push *{
26
+ 'RedCloth' => '~> 4.2.3',
27
+ 'rcodetools' => '~> 0.8.5.0',
28
+ }
29
+ self.extra_dev_deps.push *{
30
+ 'rspec' => '~> 2.4.0',
31
+ 'tidy-ext' => '~> 0.1.10',
32
+ }
33
+
34
+ self.spec_extras[:licenses] = ["BSD"]
35
+ self.spec_extras[:signing_key] = '/Volumes/Keys/ged-private_gem_key.pem'
36
+
37
+ self.require_ruby_version( '>=1.8.7' )
38
+
39
+ self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
40
+
41
+ self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
42
+ end
43
+
44
+ ENV['VERSION'] ||= hoespec.spec.version.to_s
45
+
46
+ begin
47
+ include Hoe::MercurialHelpers
48
+
49
+ ### Task: prerelease
50
+ desc "Append the package build number to package versions"
51
+ task :pre do
52
+ rev = get_numeric_rev()
53
+ trace "Current rev is: %p" % [ rev ]
54
+ hoespec.spec.version.version << "pre#{rev}"
55
+ Rake::Task[:gem].clear
56
+
57
+ Gem::PackageTask.new( hoespec.spec ) do |pkg|
58
+ pkg.need_zip = true
59
+ pkg.need_tar = true
60
+ end
61
+ end
62
+
63
+ ### Make the ChangeLog update if the repo has changed since it was last built
64
+ file '.hg/branch'
65
+ file 'ChangeLog' => '.hg/branch' do |task|
66
+ $stderr.puts "Updating the changelog..."
67
+ content = make_changelog()
68
+ File.open( task.name, 'w', 0644 ) do |fh|
69
+ fh.print( content )
70
+ end
71
+ end
72
+
73
+ # Rebuild the ChangeLog immediately before release
74
+ task :prerelease => 'ChangeLog'
75
+
76
+ rescue NameError => err
77
+ task :no_hg_helpers do
78
+ fail "Couldn't define the :pre task: %s: %s" % [ err.class.name, err.message ]
79
+ end
80
+
81
+ task :pre => :no_hg_helpers
82
+ task 'ChangeLog' => :no_hg_helpers
83
+
84
+ end
85
+
@@ -0,0 +1,87 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+
4
+ Main Manual Layout
5
+ $Id: default.erb.erb,v 8077c9cdbac9 2011/01/26 02:15:09 ged $
6
+
7
+ Author: Michael Granger <ged@FaerieMUD.org>
8
+ Two column fluid layout adapted from Matthew James Taylor's "Perfect 'Left Menu'
9
+ 2 Column Liquid Layout":
10
+ http://matthewjamestaylor.com/blog/perfect-2-column-left-menu.htm
11
+
12
+ -->
13
+ <html lang="en">
14
+ <head>
15
+ <meta charset="utf-8">
16
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
17
+
18
+ <title><%= name %> Manual — <%%= page.config['title'] || "untitled" %></title>
19
+
20
+ <link rel="stylesheet" href="css/manual.css">
21
+
22
+ <script src="js/jquery-1.4.4.min.js"></script>
23
+ <script src="js/sh.js"></script>
24
+ <script src="js/manual.js"></script>
25
+
26
+ </head>
27
+ <body>
28
+ <div id="page">
29
+
30
+ <header>
31
+ <hgroup>
32
+ <a href="/">
33
+ <h1><%= name %></h1>
34
+ </a>
35
+ <%% if metadata.version %><h2 class="version"><%%= metadata.version %></h2><%% end %>
36
+ <%% if page.config['tagline'] %><h2 class="tagline"><%%= page.config['tagline'] %></h2><%% end %>
37
+ </hgroup>
38
+ </header>
39
+
40
+ <div class="colmask leftmenu">
41
+ <div class="colleft">
42
+
43
+ <section id="content" class="col1">
44
+ <!-- Generated content -->
45
+ <%%= content %>
46
+ <!-- end of generated content -->
47
+ </section>
48
+
49
+ <aside id="sidebar" class="col2">
50
+ <nav>
51
+ <%%
52
+ @catalog.traverse_page_hierarchy( self ) do |type, title, path|
53
+ case type
54
+ when :section
55
+ %>
56
+ <div class="section">
57
+ <h3><a href="<%%= self.basepath + path %>/"><%%= title %></a></h3>
58
+ <ul class="index-section">
59
+ <%% when :current_section %>
60
+ <div class="section current-section">
61
+ <h3><a href="<%%= self.basepath + path %>/"><%%= title %></a></h3>
62
+ <ul class="index-section current-index-section">
63
+ <%% when :section_end, :current_section_end %>
64
+ </ul>
65
+ </div>
66
+ <%% when :entry %>
67
+ <li><a href="<%%= self.basepath + path %>.html"><%%= title %></a></li>
68
+ <%% when :current_entry %>
69
+ <li class="current-entry"><%%= title %></li>
70
+ <%% end
71
+ end
72
+ %>
73
+ </nav>
74
+ </aside>
75
+
76
+ </div>
77
+ </div>
78
+
79
+ <footer>
80
+ <div class="copyright">Copyright &copy; 2008-<%%= Time.now.year %> <%= author.join(', ') %>.</div>
81
+ <div class="vcsrev">Rev: $Revision: 8077c9cdbac9 $</div>
82
+ <div class="timestamp">Built: <%%= Time.now.strftime("%Y%m%d %H:%M:%S %Z") %></div>
83
+ </footer>
84
+
85
+ </body>
86
+ </html>
87
+
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # A manual filter to generate links from the Darkfish API.
4
+ #
5
+ # Authors:
6
+ # * Michael Granger <ged@FaerieMUD.org>
7
+ # * Mahlon E. Smith <mahlon@martini.nu>
8
+ #
9
+
10
+
11
+ ### A filter for generating links from the generated API documentation. This allows you to refer
12
+ ### to class documentation by simply referencing a class name.
13
+ ###
14
+ ### Links are XML processing instructions. Pages can be referenced as such:
15
+ ###
16
+ ### <?api Class::Name ?>
17
+ ### <?api "click here":Class::Name ?>
18
+ ###
19
+ class Hoe::ManualGen::APIFilter < Hoe::ManualGen::Page::Filter
20
+
21
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
22
+ ApiPI = %r{
23
+ <\?
24
+ api # Instruction Target
25
+ \s+
26
+ (?:"
27
+ (.*?) # Optional link text [$1]
28
+ ":)?
29
+ (.*?) # Class name [$2]
30
+ \s+
31
+ \?>
32
+ }x
33
+
34
+
35
+ ######
36
+ public
37
+ ######
38
+
39
+ ### Process the given +source+ for <?api ... ?> processing-instructions, calling out
40
+ def process( source, page, metadata )
41
+
42
+ apipath = metadata.api_dir or
43
+ raise "The API output directory is not defined in the manual task."
44
+
45
+ return source.gsub( ApiPI ) do |match|
46
+ # Grab the tag values
47
+ link_text = $1
48
+ classname = $2
49
+
50
+ self.generate_link( page, apipath, classname, link_text )
51
+ end
52
+ end
53
+
54
+
55
+ ### Create an HTML link fragment from the parsed ApiPI.
56
+ ###
57
+ def generate_link( current_page, apipath, classname, link_text=nil )
58
+
59
+ classpath = "%s.html" % [ classname.gsub('::', '/') ]
60
+ classfile = apipath + classpath
61
+ classuri = current_page.basepath + 'api' + classpath
62
+
63
+ if classfile.exist?
64
+ return %{<a href="%s">%s</a>} % [
65
+ classuri,
66
+ link_text || classname
67
+ ]
68
+ else
69
+ link_text ||= classname
70
+ error_message = "Could not find a link for class '%s'" % [ classname ]
71
+ $stderr.puts( error_message )
72
+ return %{<a href="#" title="#{error_message}" class="broken-link">#{link_text}</a>}
73
+ end
74
+ end
75
+ end
76
+
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # A manual filter to highlight content that needs editorial help.
4
+ #
5
+ # Authors:
6
+ # * Michael Granger <ged@FaerieMUD.org>
7
+ #
8
+ #
9
+
10
+
11
+
12
+ ### A filter for making editorial marks in manual content.
13
+ ###
14
+ ### Editorial marks are XML processing instructions. There are several available types of
15
+ ### marks:
16
+ ###
17
+ ### <?ed "This is an editor's note." ?>
18
+ ### <?ed verify:"this content needs checking or verification" ?>
19
+ ###
20
+ class Hoe::ManualGen::EditorialFilter < Hoe::ManualGen::Page::Filter
21
+
22
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
23
+ LinkPI = %r{
24
+ <\?
25
+ ed # Instruction Target
26
+ \s+
27
+ (\w+?) # type of editorial mark [$1]
28
+ :? # optional colon
29
+ "
30
+ (.*?) # content that should be edited [$2]
31
+ "
32
+ \s*
33
+ \?>
34
+ }x
35
+
36
+
37
+ ######
38
+ public
39
+ ######
40
+
41
+ ### Process the given +source+ for <?ed ... ?> processing-instructions
42
+ def process( source, page, metadata )
43
+ return source.gsub( LinkPI ) do |match|
44
+ # Grab the tag values
45
+ mark_type = $1
46
+ content = $2
47
+
48
+ self.generate_mark( page, mark_type, content )
49
+ end
50
+ end
51
+
52
+
53
+ ### Create an HTML fragment from the parsed LinkPI.
54
+ def generate_mark( current_page, mark_type, content )
55
+ return "%%(editorial %s-mark)%s%%" % [ mark_type, content ]
56
+ end
57
+
58
+
59
+ end
@@ -0,0 +1,238 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # A collection of standard filters for the manual generation tasklib.
4
+ #
5
+ # Authors:
6
+ # Michael Granger <ged@FaerieMUD.org>
7
+ #
8
+ #
9
+
10
+ # Dependencies deferred until #initialize
11
+
12
+
13
+
14
+ ### A filter for inline example code or command-line sessions -- does
15
+ ### syntax-checking for some languages and captioning.
16
+ ###
17
+ ### Examples are enclosed in XML processing instructions like so:
18
+ ###
19
+ ### <?example {language: ruby, testable: true, caption: "A fine example"} ?>
20
+ ### a = 1
21
+ ### puts a
22
+ ### <?end example ?>
23
+ ###
24
+ ### This will be pulled out into a preformatted section in the HTML,
25
+ ### highlighted as Ruby source, checked for valid syntax, and annotated with
26
+ ### the specified caption. Valid keys in the example PI are:
27
+ ###
28
+ ### language::
29
+ ### Specifies which (machine) language the example is in.
30
+ ### testable::
31
+ ### If set and there is a testing function for the given language, run it and append
32
+ ### any errors to the output.
33
+ ### caption::
34
+ ### A small blurb to put below the pulled-out example in the HTML.
35
+ class Hoe::ManualGen::ExamplesFilter < Hoe::ManualGen::Page::Filter
36
+
37
+ DEFAULTS = {
38
+ :language => :ruby,
39
+ :line_numbers => :inline,
40
+ :tab_width => 4,
41
+ :hint => :debug,
42
+ :testable => false,
43
+ }
44
+
45
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
46
+ ExamplePI = %r{
47
+ <\?
48
+ example # Instruction Target
49
+ (?: # Optional instruction body
50
+ \s+
51
+ ((?: # [$1]
52
+ [^?]* # Run of anything but a question mark
53
+ | # -or-
54
+ \?(?!>) # question mark not followed by a closing angle bracket
55
+ )*)
56
+ )?
57
+ \?>
58
+ }x
59
+
60
+ EndPI = %r{ <\? end (?: \s+ example )? \s* \?> }x
61
+
62
+
63
+ ### Defer loading of dependenies until the filter is loaded
64
+ def initialize( *args )
65
+ begin
66
+ require 'pathname'
67
+ require 'strscan'
68
+ require 'yaml'
69
+ require 'rcodetools/xmpfilter'
70
+ require 'digest/md5'
71
+ require 'tmpdir'
72
+ require 'erb'
73
+ rescue LoadError => err
74
+ unless Object.const_defined?( :Gem )
75
+ require 'rubygems'
76
+ retry
77
+ end
78
+
79
+ raise
80
+ end
81
+ end
82
+
83
+
84
+ ######
85
+ public
86
+ ######
87
+
88
+ ### Process the given +source+ for <?example ... ?> processing-instructions, calling out
89
+ def process( source, page, metadata )
90
+ scanner = StringScanner.new( source )
91
+
92
+ buffer = ''
93
+ until scanner.eos?
94
+ startpos = scanner.pos
95
+
96
+ # If we find an example
97
+ if scanner.skip_until( ExamplePI )
98
+ contents = ''
99
+
100
+ # Append the interstitial content to the buffer
101
+ if ( scanner.pos - startpos > scanner.matched.length )
102
+ offset = scanner.pos - scanner.matched.length - 1
103
+ buffer << scanner.string[ startpos..offset ]
104
+ end
105
+
106
+ # Append everything up to it to the buffer and save the contents of
107
+ # the tag
108
+ params = scanner[1]
109
+
110
+ # Now find the end of the example or complain
111
+ contentpos = scanner.pos
112
+ scanner.skip_until( EndPI ) or
113
+ raise "Unterminated example at line %d" %
114
+ [ scanner.string[0..scanner.pos].count("\n") ]
115
+
116
+ # Now build the example and append to the buffer
117
+ if ( scanner.pos - contentpos > scanner.matched.length )
118
+ offset = scanner.pos - scanner.matched.length - 1
119
+ contents = scanner.string[ contentpos..offset ]
120
+ end
121
+
122
+ trace "Processing with params: %p, contents: %p" % [ params, contents ]
123
+ buffer << self.process_example( params, contents, page )
124
+ else
125
+ break
126
+ end
127
+
128
+ end
129
+ buffer << scanner.rest
130
+ scanner.terminate
131
+
132
+ return buffer
133
+ end
134
+
135
+
136
+ ### Filter out 'example' macros, doing syntax highlighting, and running
137
+ ### 'testable' examples through a validation process appropriate to the
138
+ ### language the example is in.
139
+ def process_example( params, body, page )
140
+ options = self.parse_options( params )
141
+ caption = options.delete( :caption )
142
+ content = ''
143
+ lang = options.delete( :language ).to_s
144
+
145
+ # Test it if it's testable
146
+ if options[:testable]
147
+ content = test_content( body, lang, page )
148
+ else
149
+ content = body
150
+ end
151
+
152
+ # Strip trailing blank lines and syntax-highlight
153
+ content = highlight( content.strip, options, lang )
154
+ caption = %{<div class="caption">} + caption.to_s + %{</div>} if caption
155
+
156
+ return %{<notextile><div class="example #{lang}-example">%s%s</div></notextile>} %
157
+ [content, caption || '']
158
+ end
159
+
160
+
161
+ ### Parse an options hash for filtering from the given +args+, which can either
162
+ ### be a plain String, in which case it is assumed to be the name of the language the example
163
+ ### is in, or a Hash of configuration options.
164
+ def parse_options( args )
165
+ args = "{ #{args} }" unless args.strip[0] == ?{
166
+ args = YAML.load( args )
167
+
168
+ # Convert to Symbol keys and value
169
+ args.keys.each do |k|
170
+ newval = args.delete( k )
171
+ next if newval.nil? || (newval.respond_to?(:size) && newval.size == 0)
172
+ args[ k.to_sym ] = newval.respond_to?( :to_sym ) ? newval.to_sym : newval
173
+ end
174
+ return DEFAULTS.merge( args )
175
+ end
176
+
177
+
178
+ ### Test the given +content+ with a rule specific to the given +language+.
179
+ def test_content( body, language, page )
180
+ case language.to_sym
181
+ when :ruby
182
+ return self.test_ruby_content( body, page )
183
+
184
+ when :yaml
185
+ return self.test_yaml_content( body, page )
186
+
187
+ else
188
+ return body
189
+ end
190
+ end
191
+
192
+
193
+ ### Test the specified Ruby content for valid syntax
194
+ def test_ruby_content( source, page )
195
+ # $stderr.puts "Testing ruby content..."
196
+ libdir = Pathname.new( __FILE__ ).dirname.parent.parent.parent + 'lib'
197
+ extdir = Pathname.new( __FILE__ ).dirname.parent.parent.parent + 'ext'
198
+
199
+ options = Rcodetools::XMPFilter::INITIALIZE_OPTS.dup
200
+ options[:include_paths] |= [ libdir.to_s, extdir.to_s ]
201
+ options[:width] = 60
202
+
203
+ if page.config['example_prelude']
204
+ prelude = page.config['example_prelude']
205
+ trace " prepending prelude:\n#{prelude}"
206
+ source = prelude.strip + "\n" + source.strip
207
+ else
208
+ trace " no prelude; page config is: %p" % [ page.config ]
209
+ end
210
+
211
+ rval = Rcodetools::XMPFilter.run( source, options )
212
+
213
+ trace "test output: ", rval
214
+ return rval.join
215
+ rescue Exception => err
216
+ return "%s while testing: %s\n %s" %
217
+ [ err.class.name, err.message, err.backtrace.join("\n ") ]
218
+ end
219
+
220
+
221
+ ### Test the specified YAML content for valid syntax
222
+ def test_yaml_content( source, metadata )
223
+ YAML.load( source )
224
+ rescue YAML::Error => err
225
+ return "# Invalid YAML: " + err.message + "\n" + source
226
+ else
227
+ return source
228
+ end
229
+
230
+
231
+ ### Highlights the given +content+ in language +lang+.
232
+ def highlight( content, options, lang )
233
+ source = ERB::Util.html_escape( content )
234
+ return %Q{\n\n<pre class="brush:#{lang}">#{source}</pre>\n\n}
235
+ end
236
+
237
+ end
238
+