Home | Download | User guide | RDoc | Issue tracker | Source Code | Mailing lists | Licence

User guide

It is assumed that you have installed Rote already. If not, please consult the README for installation instructions.


Task names – Rote’s standard tasks are always referred to with the base-name doc , e.g. doc_pages, doc_clean, and just plain doc. This is the prefix used by the built-in Rakefile, but since it can be changed when using Rote in your own Rake builds you should of course substitute whatever is appropriate if you have chosen to modify it.


Starting out with Rote

Creating a project

To get started quickly, we’ll use the built-in project template, which provides a standard Rote directory tree with a single page, and Rakefile ready for customisation. The template gives a convenient way to get started on a new Rote project. To invoke it, just type:

       rote create someproject

If all goes well, you should see a single line (cp_r ...) indicating that Rote copied the template to your specified directory (someproject in this case). This directory will have the following layout:

  |--> Rakefile
  |--> doc
  |    |--> res
  |    |    |--> images
  |    |    |--> rote-tiny.png
  |    |
  |    |--> layouts
  |    |    |--> normal.thtml
  |    | 
  |    |--> pages
  |         |--> COMMON.rb
  |         |--> index.thtml
  |         |--> index.rb

Template sources under the ‘pages’ directory may have any extension (except rb), and will be rendered to the same base-name under the output directory, with their file extension supplied by the original, possible via an extension mapping
See the section on Layouts below for details on layout name resolution.

Ruby source is optional, and allows you to define instance variables and methods on a Page instance. COMMON.rb is applied to all pages in a given
directory. See the section on templates for more information on the specifics.

To build the sample page, simply type rote or rake from the top-level directory. This will start the default doc task to transform all
modified pages / resources (everything, in this case).

The README included with the project template has further information about build options and available tasks, as well as pointers to possible
next steps.


From the command-line

If you are generating a standalone documentation set (i.e. not as part of some wider build) and you don’t want to worry maintaining a Rakefile,
you can use the built-in build via the rote command. This works with the standard directory layout above, and wraps invocation of rake on a
built-in version of the standard Rakefile.

Given the above layout, you can generate the documentation set by running:


from the top-level directory (project in the example above), you should get a ‘html’ directory created with the (transformed) templates, and any
resources should be copied as necessary.

Being based on Rake, Rote supports last-modified checking, and provides an individual file task for each page in your doc set. For example, running
the ‘rote’ command again with no options will cause it to exit almost immediately, since all output is up to date. If you change a file, and run
rote again, then just that file will be updated. Even dependencies that are determined dynamically (such as layout files) can be tracked for incremental build purposes.

The file tasks are named for the target files, so for example to generate just the top-level index.html (regardless of whether it’s been modified)
you’d run:

       rote html/index.html

The clobber task supports deleting all output files to start from scratch:

       rote clobber

Of course, multiple file or task names (or a mixture) can be specified.
You can get a list of valid tasks in the current context with:

       rote --tasks

Further command-line usage information is available with:

       rote --usage

and Unix installations performed with install.rb should also make a manpage available for the rote command.

Note That, for most purposes, you should prefer to use a Rakefile based build, as created by the rote create command. The command-wrapper functionality in Rote is maintained only as a quick start option, and is not guaranteed to remain supported in 1.0.

If you do choose to use a Rakefile approach, do not use the ‘rote’ command to build documentation, since it will ignore your local Rakefile and can result in inconsistent behaviour.


From your Rakefile

If you are wanting to build documentation as part of a larger build process, or commandline setup, then you’ll want to get started on integrating Rote with your own (existing) Rakefile. If you bootstrap a project with the rote create command, you’ll get a Rakefile which you can modify to suit your requirements.

There is nothing special about this Rakefile, and it can use any of the other Rake tasks, or indeed any other Ruby code. It is run with a command like:

       rake doc

If all goes well, you should see each command and transformation output to your console as Rote runs.

See the main Rote Rakefile for an example of integrating Rote with your software project, including linking to Rdoc generation and so on. The
Rake task configuration section has more information on the options supported by Rote’s task library.


Creating templates

Wherever directories and files are mentioned, they refer to the appropriate path/name/etc supplied during rake task configuration.
In all cases the default settings can be seen in the layout created by the rote create foo command.

The Basics

As mentioned, templates are simply files in the specifed pages directory (doc/pages by default) that match the supplied glob (default: all files,
though ruby source is implicitly excluded). The directory layout beneath the page root is retained when transforming pages, and is also used to provide hierarchical structure to the common page code.

The default behaviour is to transform all matched templates pages with ERB, and optionally apply a second render pass with a layout, before writing to the same base filename beneath the output directory. You can customise this behaviour by specifying extension mappings for specific file extensions – see the Rake task configuration section for details.

Each page and layout template used by Rote may have associated with it an optional Ruby source file, allowing variables to be defined for use in ERB code, and supporting interaction with Rote via the methods of the Rote::Page class. Page and layout code is loaded from a rb file alongside the template itself.

Code can also be applied across multiple pages based on filesystem hierarchy by placing it in COMMON.rb files in the pages tree. The order of evaluation of these files travels down from the most remote COMMON.rb to the page code itself, and this provides a simple yet fairly powerful way to apply various configuration options, filtering, and user variables across your pages.

See template code and erb for more information on the search path and evaluation order for page code.

Rote additionally allows a variety of formatting and postprocessing options thanks to it’s support for filters – little bits of Ruby that perform some text transformation, macro expansion, or postprocessing during page rendering. Rote provides standard filters to support Textile and Markdown formatting, syntax highlighting, processing with HTMLTidy, and more.


Template code and ERB

All templates may contain embedded Ruby code (ERB), delimited by the standard <% … %> (for executed code) and <%= … %> (for output) tags. Any (valid) Ruby code may be placed in the templates, and variables may be defined to allow information to be passed into templates. There are four places where you might define such variables. The following is in order of evaluation:

When a Page instance is created, Rote looks for these, and if found evaluates them, in order, in the same binding as the template is later rendered in (i.e. the Page instance binding). Therefore, you can define instance variables to pass data around, or even helper methods if you wish.

Additionally, when layout is used the following evaluation takes place after rendering the template text and can be used to make variables available for the layout pass(es):

Template code is used to support a great deal of flexibility in Rote, from selecting layouts to mixing in format helpers to controlling the filter chain. You can find details of the methods available in the Rote::Page RDoc


Plaintext Formatting

If you are using Rote to generate HTML, you’ll probably want to utilise some kind of plain-text formatting. Rote has out-of-the-box support for
Textile, Markdown, and RDoc formatting, which can be applied to any page using standard filters.

These filters can be applied to any page directly from page or common code, and if you are using the built-in Rakefile (either using the rote command to build, or with a rake build created with the rote create command) then the following extension mappings are defined by default, allowing the filters to be applied without resorting to page code:

.mhtml or .markdown => Markdown formatting, .html output .thtml or .textile => Textile formatting, .html output .rdhtml or .rdoc => RDoc formatting, .html output

Each of these filters is covered (along with further usage instructions) in the filters section.



Layouts allow common template to be applied across several pages. This is handled via multiple render passes, with each layout responsible
for including the previously rendered content (via ERB).

Layouts are stored under the doc/layouts directory (by default). They may be organised into subdirectories, but this hierarchy is not connected to
the hierarchy in pages. To apply a layout to a page, simply call the Rote::Page.layout method from code applied to that page, passing the
base-name (and path, relative to layouts, if used). If no extension is specified, then the same extension as the page itself is assumed. Examples:

Note the absence of the = sign in the ERB tag in the last example, indicating that this is code to be executed rather than code that should generate output.

With that done, Rote would first render the template text (including textile) and set the Page instance variable \content_for_layout@ before rendering the layout (in which textile is currently not supported). The layout is responsible for inserting the rendered template where appropriate, with e.g.:

This pattern shouldn’t be unfamiliar. Again, note that Rote doesn’t mandate HTML, despite the appearance from the ERB tags – any (textual) format can
be templated and laid out.

Layout code

Like page templates, each layout may have associated with it some layout code, which is executed just prior to rendering the layout, in the same
way as the page code.

There is no equivalent of COMMON.rb for layout templates, however.

Nested layout

Layout code (see above) may call the Page#layout method (i.e. to apply a layout). This will result in the result of the current rendering being
passed (via @content_for_layout) to the specified layout in a further render pass. In all respects this is no different from the initial layout pass – layout code is executed, and rendering performed. Obviously, this may result in additional layouts being applied to the page.

Layouts can only be nested by calling layout again from layout code (or ERB in the layout template itself). Multiple calls to layout from
COMMON.rb or page code will result in consistent page code behaviour, i.e. any previously-specified layout will be overriden.

There are no special requirements for layouts that are used in this way – from the user point of view a layout simply needs to include the @content_for_layout where appropriate.

All layouts are rendered prior to post filtering.



As well as rendering ERB and applying layout (both universal features of Page), Rote provides the ability to apply custom filters to a page or set of pages. Along with this ability, a number of filters are provided as standard:

For example If you’re generating HTML, you’ll probably want to use some plaintext formatting, rather than writing HTML by hand. Rote directly supports this (thanks to RedCloth and BlueCloth) via filters_, with Textile, RDoc and Markdown support out of the box (assuming those libraries are available on your machine). See the plaintext formattingformatting for more details on this.

Filter chaining

In order to filter a given page, filter instances are added to that page’s filter chain. There are actually two separate chains, for page filtering
and post filtering.

* Page filtering takes place on the page content itself, after any ERB is executed, but before the layout pass is applied. Most of the standard filters are pre-filters.

* Post filtering takes place on the final output of the render pass, after layout is applied. The Filters::Tidy filter is a post filter.

Adding filters to a page’s chain can be done anywhere you can call that page’s filter-chain methods. This could be page code, COMMON.rb, or even inside the template itself. Filters can also be applied to all files with a matching extension by adding filters inside an extension mapping block. Bear in mind that the order in which filters are added is important, since each filters output becomes input for the next. You must ensure that filters are applied in a compatible order – should you need to prepend filters or otherwise modify the chain prior to rendering you may do so by directly accessing the page_filters and post_filters array attributes.

See the section on template code for more information on adding code to your pages.

Standard filters

Rote supplies the following filters ‘out of the box’:

Filters::BlueCloth – Supports conversion of plain-text (Markdown) formatting to HTML.

This is a text filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::BlueCloth.new
Filters::Exec – Pipes the macro body to an external command, and replaces the macro with the output of that command.

This is a macro filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::Exec.new

Code can then be inserted in the page like:

    print "Hello, World"
Filters::Eval – Evaluates the macro body as Ruby code, capturing standard output and using it as the macro replacement.

This is a macro filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::Eval.new

Code can then be inserted in the page like:

    puts "Hello, World"
Filters::RDoc – Supports RDoc formatting with optional custom markup, to any supported output format (defaults to HTML).

This is a text filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::RDoc.new
Filters::RedCloth – Supports conversion of plain-text (Textile) formatting to HTML.

This is a text filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::RedCloth.new
Filters::Syntax – Supports code macros with pluggable syntax highlighting (via the Syntax library) and Ruby-code support out of the box.

This is a macro filter, and should be applied in the page filter chain:

  # in page code or common.rb
  page_filter Filters::Syntax.new

This filter uses the Syntax library, passing the macro argument as the language (‘ruby’, ‘xml’ and ‘yaml’ are supported out of the box). The output is wrapped in <pre class=‘[language]’><code> … </code></pre> for output, with highlighting handled by <span> tags, allowing syntax colours and styles to be applied via CSS. You can find a full list of the Ruby highlight classes
in the Syntax documentation but you will need to experiment with the highlighter to find the XML and YAML classes.

Code to be highlighted is inserted into pages like so:

    def amethod
      "some code"		

Note that the closing tag in the above example is missing a closing ‘#’ – this works around a limitation of the current Syntax filter (and macro implementation in general), which means that a macro cannot contain it’s own end-tag.

Since macros are rendered separately from the page text, you don’t have to worry much about spacing and so forth – your code will not be touched by any of the formatting filters.

Filters::Tidy – Post filter that corrects markup and semantic errors in HTML markup to produce valid HTML or XHTML using the HTML Tidy command-line tool.

This is a post filter. It should be applied in the appropriate filter chain:

  # in page code or common.rb
  post_filter Filters::Tidy.new
Filters::TOC – Supports automatic generation of basic navigation from headings in documents. See the RDoc for more details. It should be applied as a page filter, and a reference is usually required for use in the layout:
  # in page code or common.rb
  post_filter @toc = Filters::TOC.new

Some of the filters support various options to change the way they operate, and many support different arguments (the second part of the #macro#args# tags) to those shown above – see the RDoc for the individual macros (linked from the headings above) for more details.

Filters are of course very simple to write. See the ‘Writing filters’ subsection (in Extending Rote) for details, including how to implement your own macro filters.


Format helpers

TODO This section is under construction.
Please see Rote::Format::HTML for currently available information.



Of course, you’re likely to have resources for your site (images, sounds, etc) and you’ll need to copy them over to the target too. Such resources should be placed under doc/res (with the commandline setup) or in your specified res directory (from a Rakefile).

As you’d expect, the directory layout beneath res should mirror that of the output, and will be preserved during the copy. Resources are copied only if necessary (determined by existence and last-modified timestamp), in a similar way to pages.


Rake task configuration


Reference Rakefile

The following Rakefile demonstrates most of the methods you can use to customise Rote’s rake task configuration.

# Rakefile
require 'rote'
include Rote

# This defines all our Rake tasks. The symbol we supply here (:doc is 
# default) gives the base-prefix for the tasks that are generated.
ws = Rote::DocTask.new(:doc) do |doc| 
	# Output directory and layout sources
  doc.output_dir = 'html'
  doc.layout_dir = 'doc/layouts'
	# Page directory and include globs.
  doc.pages.dir = 'doc/pages'
	# Resource directory and include globs. This directory
	# could be the same as the pages directory.
  doc.res.dir = 'doc/res/'
  # Define an extension mapping
  doc.ext_mapping(/(html)/, '$1') do |page|
    # Let's use the HTML helpers everywhere ...
    page.extend Format::HTML
    # use 'page' layout on all html files
    # This can also be set from COMMON.rb
    page.layout 'page'

		# textile formatting, ruby syntax
    page.page_filter Filters::RedCloth.new(:textile)
    page.page_filter Filters::Syntax.new
    # To valid xhtml with Tidy postfilter
    page.post_filter Filters::Tidy

Please refer to the RDoc for specific information on each method.


Extension mappings

The default behaviour when transforming pages is to make each filename matched by the pages.include glob relative to the output directory, using the same extension as the input file.

If you want to change this behaviour, you may supply an extension mapping as demonstrated above. The general form is:

# Define an extension mapping
doc.ext_mapping(/regexp/, 'replacement') do |page|

  # call page methods 


The regexp is matched against processed page extensions (not resources) and the replacement supplies the output extension. The optional block is executed for each matching page during instantiation, before any COMMON or page code. Note that you must not include the leading ‘.’ in either the regexp or replacement – doing so will fail to match the desired extensions.

For more advanced mappings, you can supply a capturing regexp, and use the $n notation in the replacement to extract the captures. As shown in the
(contrived) example below:

doc.ext_mapping(/(html)/, '$1') do |page|

  # do stuff

Extension mappings also support per-extension output directories, which can be supplied as a third parameter to the ext_mapping method:

doc.output_dir = ‘html’

doc.ext_mapping(/ttxt/, 'txt', 'plaintext') do |page|

  # do stuff

Where no output directory is supplied, the default output directory will be used.


Defining additional tasks

The command-line build will automatically look for a file in the top-level directory (above doc) named local.rf. If found, this file will be
evaluated by Rake, making any tasks defined within it available to your build. This can be used to define an auto refresh task
for the monitor feature, for example, or to define tasks to publish your site (most likely using one of Rake’s directory publishers).


Source monitoring

When making changes to a documentation set, you frequently need to render out your changes to check formatting or ensure something works correctly. In this situation it’s inconvenient to keep dropping out to your shell to run rote (or rake) manually, particularly when making a lot of incremental changes.

Fortunately, Rote provides a simple mechanism for monitoring your documentation source and automatically performing updates as needed. Simply specify the doc_monitor task and Rote will go into a loop, periodically running the top-level doc task which will transform / copy any pages or resources that have been modified. It will of course take notice of any custom file or directory dependencies you add to the doc task (e.g. to generate RDoc as part of a website), and in turn monitor their dependent files too (for example rebuilding the RDoc if you modify a source file). It does not however attempt to track format-specific dependencies between resources (such as which pages use which CSS), since this would imply some knowledge of the format in use. In practice this means that you may need to trigger a clean build after updating such resources, although it is actually fairly easy to set up this kind of relationship by specifying that certain file-tasks relating to pages depend on the appropriate file-tasks representing the resources (for instance).

By default, monitor checks for updates approximately once per second, but you can specify a custom value when using a Rakefile by setting monitor_interval in the block passed to DocTask.new.

Note that the monitor functionality is deliberately kept simple with respect to IO and concurrency, reflecting the fact that output files are rarely anything more than that – it would be almost pointless to complicate the way monitoring works with any kind of semaphore or file-locking scheme. Of course if this does cause problems in your particular scenario, let me know because it just might make me reconsider.

When you’re done with Rote simply hit CTRL-C (or use kill) to stop monitoring and exit.


Auto refresh task

When using Source monitoring, it’s often handy to be able to inform some other program that something has changed. For example, you may want to automatically refresh your browser after changed HTML is rendered. Rote supports this via the doc_refresh task, which is triggered whenever doc_monitor finds changes in your source set (after rendering, of course).

The following (Mac) example uses OSA script to refresh the Safari browser when your rendered documentation changes:

  require 'osx/aeosa'
  task :doc_refresh do 
    OSX.do_osascript('tell application "Safari" to do javascript "window.location.reload();" in document 1')	

As with all rake tasks, multiple actions can be associated, and you can of course add prerequisites to the refresh task as with any other Rake task.



Rote does not provide any direct support for publishing your site at present, relying on you to configure an appropriate publish task if required, using the publishers supplied with Rake (in rake/contrib), or your own. This allows maximum flexibility, and allows Rote to concentrate on creating your documents.

See the section Defining additional tasks for details on how to supply your publish tasks.

See the rake task configuration section for more details.


Extending Rote

Although Rote is designed to be as quick and easy to use as possible, with sensible default configuration and reasonable convention throughout, it also has ample flexibility when it comes to generating more complex documentation sets. Thanks to it’s ‘option for every default’ and simple extension points, Rote should scale to even complex documentation sets quite easily.


Writing filters

Filters do exactly what they say on the tin – they filter the output of a page, perhaps rendering markup or inserting additional text. Filters can be divided into two general categories: Text filters and Macro filters. Either type can be a page or post filter – it depends only on the design of the filter and the job it will perform as to which chain it should be used with.

Text Filters

Text filters process the text in a page, with all macros replaced by a standard plain-text marker. The purpose of this is to allow macros to coexist with plain-text formatting without causing markup clashes.

Most of the standard filters are text filters. The RedCloth filter is representative:

class RedCloth < TextFilter
  def initialize(*redcloth_opts)
    @redcloth_opts = redcloth_opts
  def handler(text,page)
    rc = ::RedCloth.new(text)        
    # hack around a RedCloth warning
    rc.instance_eval { @lite_mode = false }  

(again, this example is slightly simplified with respect to auxiliary functionality for the sake of clarity).

As mentioned above, TextFilter also provides help with writing non-macro filters that removes much of the headache of working around macros (which must not be modified by any filter except that which handles the macro).

Text filters can optionally access the macro data using the macros array.

If you want to implement a one-off filter quickly, there’s no need to create a new subclass – you can supply a block directly to TextFilter, which is executed to render the textual content:

page.page_filter Rote::Filters::TextFilter.new { |page, text|

For text filters, a convenience in the implementation of page_filter allows the above to be shortened to:

page.page_filter do |page, text|

Note the curly braces in the first example, which cause the block to bind to the filter rather than the method. If do..end were used, the second form would actually be called and a new filter created. The block filter you supplied would be discarded.

The post_filter method supports the same convenience.

Macro Filters

The standard Syntax filter is a typical macro filter. The following is slightly simplified for brevity (the actual one allows custom macro tags to be supplied):

class Syntax < MacroFilter
  def macro_code(lang, body)
    converter = ::Syntax::Convertors::HTML.for_syntax(lang)
    "<pre class='#{lang}'><code>#{converter.convert(body,false)}</code></pre>"

As you can see, a macro filter simply inherits Rote::Filters::MacroFilter and implements one or more macro_XXXX methods, which is passed the arguments supplied to the macro (used here to indicate the code language) and the raw macro body.

If you want to implement a macro quickly, perhaps across a section or set of pages, you can use MacroFilter itself, supplying a block:

page.page_filter Rote::Filters::MacroFilter.new([:foomacro]) { |tag, args, body
  "FooMacro Replacement!"

This can be done from any page code, a COMMON.rb (see Template code and ERB), or on a per-extension basis with extension mappings.

Note that macro data is passed raw, and excluded from rendering by text filters. The output, however, will be processed by any filters that follow the macro filter in the chain.

Duck Filters

This being Ruby, you don’t have to inherit one of the above filters to create your own – a filter is just an object with a filter(text,page) method.

The standard TOC filter takes this route.


Rake Extensions

Rote supplies a number of non-intrusive extensions a number of the Rake classes, in order to support dynamic dependency caching, caching dependency-based block memoize, and task reset for use in monitor mode. These features are very new, and only lightly documented at present. You are advised to see the RDoc and source if you want to find out more.

These extensions were almost exclusively contributed by Jonathan Paisley.

Dynamic dependency caching

Since layout files are specified in Ruby code, and may be calculated dynamically, it’s not possible to determine the layout files upon which a given page depends without running that page’s code (including all COMMON.rb files that apply to it, extension mapping blocks, and so forth). This would have (or, had) an adverse impact on Rote’s incremental build functionality, especially from the point of view of source monitoring.

This problem is addressed by a small Rake extension that adds the ability to dynamically register dependencies on the current task, and to have those dependencies cached when Rake exits. Internally, Rote automatically registers any layouts loaded by a page, and you can easily register additional dependencies from any Ruby code, by calling methods on the Rake module.

Note that this extension is intended, and tested, for Rote – it is not designed to be a general extension (though one could easily be extracted from it). In particular it takes advantage of other extended functionality provided by Rote, and takes no account, for example, of parallel task execution.

By default, the cache is maintained in the project root, in a directory named .rake_cache. This is managed by Rote, so for the most part can be ignored, though you can of course supply an alternate path if you wish (via Rake.cache_dir=).

Caching and clean builds

When performing a clean build, the cache will also be removed (as part of the clobber task), and all dependencies will be re-evaluated and cached afresh. Caching exists only to allow accurate dependency resolution during incremental builds.

Disabling the cache

There may be occasions when you want to disable use of the cache (for example when diagnosing unexpected dependency chains). This can be accomplished by setting an environment variable, NO_RAKE_CACHE prior to invoking Rote (or Rake). For a single invocation, the easiest way to do this is from the command-line:

	rake clobber doc NO_RAKE_CACHE=true

Specifying this option (or setting the variable) will completely disable use of the cache, causing any existing cache to be ignored and all dependencies determined during the run to be discarded.

Dependency-based block memoize

Somewhat related to dependency caching, Rote also provides the ability to memoize Ruby block results, caching them to disk, and only execute the block during incremental builds. This is handy if, for example, you want to incorporate information derived from external commands, for example, or index large files in your documentation.

The following (OSX-specific) example illustrates usage of this feature:

  def image_size(fn)
    Rake::Task.memoize "image_size" => fn do
      # This code only runs if the cache is out-of-date with
      # respect to the file
      puts "image_size for #{fn}"
      # OSX-specific stuff here
      s = `sips -g pixelWidth -g pixelHeight #{fn}`
      [s[/pixelWidth: (\d+)/,1], s[/pixelHeight: (\d+)/,1]]


Final notes

Rake is a very flexible tool, and supports a wide variety of configuration options and advanced features you can use to fit Rote to your needs. Such configuration is (far) beyond the scope of this manual – see Rake’s Documentation for information on the features supported by Rake.