From: Eric Hodel Date: 2011-07-21T09:18:13+09:00 Subject: Re: [RDoc internals] Changing the RDoc formatter On Jul 20, 2011, at 8:44 AM, Quintus wrote: > I'm currently writing on a PDF generator for RDoc based on LaTeX. I'm > already achieving my first readable results, but now I wanted to add > that nice cross-referencing support we see in the Darkfish-generated > pages. I know the responsible class is RDoc::Markup::ToHtmlCrossref and > wrote a class RDoc::Markup::ToLaTeXCrossref that basicly does the same > thing as the ToHtmlCrossref class, just using \href instead of and a > labeling mechanism. However, I can't figure out how to make RDoc use the > formatter *correctly*. At the moment, I'm doing it by hand using an ugly > monkeypatch of RDoc: > > ================================================== > class RDoc::CodeObject > > LATEX_FORMATTER = RDoc::Markup::ToLaTeX.new > > #... > > def latex_description > LATEX_FORMATTER.convert(comment) > end > > end > ================================================== > > This allows me in my LaTeX ERB templates to just call the > #latex_description method of a CodeObject (instead of #description, > which seems to default always to the ToHtmlCrossref formatter) to get > the fully formatted comment. Do I really have to do this monkeypatch? > Isn't there another way, like, say, setting the wanted formatter on an > instance of the generator class (in my case RDoc::Generator::PDF_LaTeX)? In RDoc this happens using rdoc/generator/markup.rb (The code is in a separate module to allow smaller parts of RDoc to be loaded depending upon what you're doing. For example `ri` shouldn't need to load all the generators and markup parsers). I think it's just fine to create a separate module for Latex formatting and cross-referencing and including it in the same places that RDoc::Generator::Markup is used. I would do it this way: require 'rdoc/generator/markup' module RDoc::Generator::LatexMarkup def formatter # make latex formatter like RDoc::Generator::Markup#formatter end end class RDoc::CodeObject include RDoc::Generator::LatexMarkup end class RDoc::Context::Section include RDoc::Generator::LatexMarkup end While this allows only HTML or only LaTeX output per run of RDoc I don't think that's much of a problem. I should be able to allow RDoc to support a preferred formatter per generator in a future release. Cross-reference formatters require a context object so I'm not sure what the API will look like. > And btw, why do we need a separate Generator and Formatter class? Nearly > the whole work of processing the parsed input is done in the formatter, > the generator then just writes it out to a file or whereever. Is this > really the sole purpose of a generator? A Generator turns an RDoc::CodeObject tree into some kind of output. That output may be a set of HTML files, an ri data store, a PDF or records in a database. A Formatter turns a parsed block of text into another form of output. In the case of ri, RDoc::Generator::RI turns the RDoc::CodeObject tree into a set of Marshal files and a cache file describing the data. When ri runs it examines the cache file, loads the correct data files, extracts the comment and uses the appropriate RDoc::Markup::Formatter to display the pre-parsed data. (There's also `rdoc --pipe` which uses the HTML formatter.) Since formatters get used in various different places they need to be separate from the generators. > If so, why is there a such small amount of documentation of adding new subclasses of RDoc::Markup::Formatter? I haven't had time to write it and few people have expressed interest in needing it. I'm also not sure what I should write about it. Using the visitor pattern makes the formatters rather simple to write. Please take a look at RDoc::Markup::FormatterTestCase. Subclassing it should help you immensely as it provides tests for everything you need to implement. (There's also RDoc::markup::TextFormatterTestCase) If I had an idea of what things you wish you'd know I can use that to write documentation. Also, where is your project hosted? I'd like to take a look at it.