[cgi-wiki-dev] Formatter API change proposal

Kake L Pugh cgi-wiki-dev@earth.li
Tue, 25 Jan 2005 09:35:41 +0000

On Mon 24 Jan 2005, Kjetil Kjernsmo <kjetil@kjernsmo.net> wrote:
> ->format($string) initialises the formatter and returns whatever, in
> the case where you don't care what you get.
> I think the real controversy here is actually the problem Justin brought 
> up: That you can't always rely on a fragment being returned. I presume 
> that it is very rare that you can't rely on a document being returned, 
> but such situations might exist.

Ahh, I get it now.  It's not clear from the name that ->format does
initialisation and leaves things behind in the formatter for
->document and ->fragment to act on.

It also seems possible that the ability to return a fragment rather
than a document (or vice versa) could depend on the input as well as
the class of the formatter.

And it feels wrong to me that information about the last input is
stored in the formatter.  If you want to format something else before
you're done with the last thing, either the work is lost or you need
to create a new formatter, and that feels very wrong.

Finally, it seems that there really should be some _programmatic_ way
to find out whether we can get a fragment (or a document) back from
our input.

With those points in mind, how about we change ->format to ->parse,
and return an object:

  my $parsed = $formatter->parse( $string );
  if ( $parsed->can( "document" ) ) {
      print $parsed->as_document;
  } else {
      print "<html><head><title>My Doc</title></head><body>",
            $parsed->as_fragment, "</body></html";

This allows expansion of the API like so:

  if ( $parsed->can( "interwiki_links" ) ) {
    @links = $parsed->interwiki_links;

$parsed would be of class something like Formatter::Parsed::UseMod.

The way this fits in with Wiki::Toolkit is that when a node is
created, its content is parsed by a Formatter, and the $parsed object
is stored in the node object.