class RDoc::Generator::Emerald
This is the main generator class that is instanciated by RDoc
when you order it to use the emerald generator. It mainly works on ERB template files you can find in the data/templates directory, where each major component (read: classes and toplevel files) has a template file that is evaluated for it. The result is then injected into the layout template, data/templates/layout.html.erb, which is then evaluated as well.
About relative paths¶ ↑
As the output generated by RDoc
is supposed to be viewable by both visiting the doc/ directory with a browser and providing the doc/ directory to an HTTP server, effectively making it the root directory, care has been taken to only use relative links in all the static HTML files. The key component for this to work is the root_path
method, which is called to set the relative path to the root directory (i.e. the output directory). When called without an argument, root_path
returns the value previously remembered (usually it contains a good number of ../ entries). This way, the root directory can be set whenever a new HTML file is going to be outputted and can then be referenced from the ERB template.
Darkfish compatibility¶ ↑
RDoc’s HTML formatter has a good number of helper methods that have a strong hint regarding “where what belongs”. By using these helper methods itself when creating cross-references, the HTML formatter enforces both the directory structure of the output directory and the anchor names used for references inside a single HTML file. The only way to circumvent this is to write another formatter, which I don’t intend to as the standard HTML formatter does a good job for HTML stuff. A nice side effect is that Emerald’s documentation is compatible with Darkfish’s one when it comes to links to specific elements. For example, you can create a link to a method called Foo::Bar#baz somewhere on the web, and if the destinatinon website chooses to switch from Darkfish output to Emerald
(which I hope!), the link will continue to work.
Constants
- DATA_DIR
Where to find the non-code stuff.
- DESCRIPTION
Description displayed in RDoc’s help.
- DummyStartPage
Minimal RDoc::Toplevel-alike object (i.e. it responds to the two methods required for rendering it,
full_name
anddescription
) that is used to create the index page if none was set. I really recommend to manually set a useful index page!- LAYOUT_TEMPLATE
Main template used as the general layout.
- ROOT_DIR
Root directory of this project.
- TEMPLATES
Subtemplates injected into the main template.
- VERSION
The version number.
Public Class Methods
Add additional options to RDoc
(see the RDoc::Generator::Emerald::Options
module).
# File lib/rdoc/generator/emerald.rb, line 119 def self.setup_options(options) options.extend(RDoc::Generator::Emerald::Options) end
Public Instance Methods
Darkfish returns nil
, hence we do this as well.
# File lib/rdoc/generator/emerald.rb, line 169 def class_dir nil end
Outputs a string on standard output, but only if RDoc
was invoked with the --debug
switch.
# File lib/rdoc/generator/emerald.rb, line 136 def debug(str) puts(str) if $DEBUG_RDOC end
Darkfish returns nil
, hence we do this as well.
# File lib/rdoc/generator/emerald.rb, line 164 def file_dir nil end
Main hook method called by RDoc
, triggers the generation process.
# File lib/rdoc/generator/emerald.rb, line 141 def generate debug "Sorting classes, modules, and methods..." @toplevels = @store.all_files @classes_and_modules = @store.all_classes_and_modules.sort_by{|klass| klass.full_name} @methods = @classes_and_modules.map{|mod| mod.method_list}.flatten.sort # Create the output directory mkdir @op_dir unless @op_dir.exist? copy_base_files evaluate_toplevels evaluate_classes_and_modules unless @options.main_page # If set, #evaluate_toplevels creates the index.html for us toplevel = DummyStartPage.new root_path "./" # This *is* in the toplevel File.open(@op_dir + "index.html", "w") do |file| file.write(render(:toplevel, binding)) end end end
Protected Instance Methods
Takes a RDoc::ClassModule and transforms it into a complete pathname relative to the output directory. Filename alterations done by RDoc’s crossref-HTML formatter are honoured. Note you have to prepend root_path
to get a complete href.
# File lib/rdoc/generator/emerald.rb, line 222 def rdocize_classmod(classmod) Pathname.new("#{classmod.full_name.split("::").join("/")}.html") end
Takes a RDoc::TopLevel and transforms it into a complete pathname relative to the output directory. Filename alterations done by RDoc’s crossref-HTML formatter are honoured. Note you have to prepend root_path
to get a complete href.
# File lib/rdoc/generator/emerald.rb, line 214 def rdocize_toplevel(toplevel) Pathname.new("#{toplevel.relative_name.gsub(".", "_")}.html") end
Set/get the root directory.
Parameter¶ ↑
- set_to (nil)
-
If passed, this method sets the root directory rather than returning it.
Return value¶ ↑
The current relative path to the root directory.
Remarks¶ ↑
See the class’ introductory text for more information on this.
# File lib/rdoc/generator/emerald.rb, line 185 def root_path(set_to = nil) if set_to @root_path = Pathname.new(set_to) else @root_path ||= Pathname.new("./") end end
Set/get the page title.
Parameter¶ ↑
- set_to (nil)
-
If passed, this method sets the title rather than returning it.
Return value¶ ↑
The current page title.
Remarks¶ ↑
Works the same way as root_path
.
# File lib/rdoc/generator/emerald.rb, line 202 def title(set_to = nil) if set_to @title = set_to else @title ||= "" end end
Private Instance Methods
# File lib/rdoc/generator/emerald.rb, line 228 def copy_base_files debug "Copying base base files..." mkdir @op_dir + "stylesheets" unless File.directory?(@op_dir + "stylesheets") cp Dir[DATA_DIR + "stylesheets" + "*.css"], @op_dir + "stylesheets" cp_r DATA_DIR + "javascripts", @op_dir cp_r DATA_DIR + "images", @op_dir end
# File lib/rdoc/generator/emerald.rb, line 268 def evaluate_classes_and_modules @classes_and_modules.each do |classmod| debug "Processing class/module #{classmod.full_name} (#{classmod.method_list.count} methods)..." path = @op_dir + rdocize_classmod(classmod) mkdir_p path.parent unless path.parent.directory? title classmod.full_name root_path "../" * (classmod.full_name.split("::").count - 1) # Last element is a file File.open(path, "w") do |file| debug " => #{path}" file.write(render(:classmodule, binding)) end end end
# File lib/rdoc/generator/emerald.rb, line 237 def evaluate_toplevels @toplevels.each do |toplevel| debug "Processing toplevel #{toplevel.name}..." root_path("../" * (toplevel.relative_name.split("/").count - 1)) # Last component is a filename title toplevel.relative_name # Create the path to the file if necessary path = @op_dir + rdocize_toplevel(toplevel) mkdir_p path.parent unless path.parent.exist? # Evaluate the actual file documentation File.open(path, "w") do |file| debug " => #{path}" file.write(render(:toplevel, binding)) end # If this toplevel is supposed to be the main file, # copy it’s content to the index.html file. if toplevel.relative_name == @options.main_page debug " => This is the main page. Writing index.html." root_path "./" # We *are* at the top here File.open(@op_dir + "index.html", "w") do |file| file.write(render(:toplevel, binding)) end end end end
Renders the subtemplate template_name
in the context
of the given binding, then injects it into the main template (which is evaluated in the same context
).
Returns the resulting string.
# File lib/rdoc/generator/emerald.rb, line 291 def render(template_name, context) render_into_layout{TEMPLATES[template_name].result(context)} end
Renders into the main layout. The return value of the block passed to this method will be placed in the layout in place of the yield
expression.
# File lib/rdoc/generator/emerald.rb, line 298 def render_into_layout LAYOUT_TEMPLATE.result(binding) end