hoe-manualgen 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.
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
+