Re: Subclassing the formatter (was: Re: Introduction and Hyphen Problem)

[email protected] (Brian Ingerson) Sun, 28 Nov 2004 10:38:46 -0800
Newsgroups perl.kwiki
Message-ID <[email protected]>
On 28/11/04 09:34 +0000, Andrew McFarland wrote:
> Brian Ingerson wrote:
> 
> >The way to allow hyphens or anything else in wiki words is to subclass the
> >formatter. I won't go into detail here and now. Maybe someone else can.
> 
> I needed to change the formatter so I could add blockquotes. I 
> eventually go it working, but there were a couple of things about it I 
> didn't like. My source code is at 
> http://aamcf.co.uk/kwikimods/Formatter.2004-11-11.txt, and I'd 

Not bad at all. Here's my code review:

    #- package AAMcF::Kwiki::Formatter;
    #+ too many nodes for my taste :p
    package AAMcF::Formatter;
    #- use base 'Kwiki::Formatter';
    #- use strict; 
    #+ Use this form instead. In the next release of Spiffy, you don't need to
    #+ use warnings or use strict when you -Base
    use Kwiki::Formatter '-Base';

    # This is yuckky: if the base module adds anything to all_blocks,
    # my module won't pick it up 
    #- const all_blocks => [qw(blockquote wafl_block hr heading ul ol pre table p)];
    #+ all_blocks is really just a method. Subclass it, and take advantage of 
    #+ super.
    sub all_blocks {
        my $blocks = super;
        unshift @$blocks, 'blockquote';
`       return $blocks;
    }

    # This is also yukky, for more or less the same reason
    #- sub formatter_classes {             
    #-     qw(
    #-         Blockquote
    #-         Spoon::Formatter::WaflPhrase
    #-         Spoon::Formatter::WaflBlock
    #-         Line Heading Paragraph Preformatted Comment
    #-         Ulist Olist Item Table TableRow TableCell
    #-         Strong Emphasize Underline Delete Inline MDash NDash Asis
    #-         ForcedLink HyperLink TitledHyperLink TitledMailLink MailLink 
    #-         TitledWikiLink WikiLink
    #-     );
    #- }
    #+ Ditto more or less. The items that are not "fully qualified" above,
    #+ get the prefix 'Kwiki::Formatter::' added. I would call your new class
    #+ 'AAMcF::Formatter::Blockquote'.
    sub formatter_classes { ('AAMcF::Formatter::Blockquote', super) }

    ##########################################################################
    #- package Kwiki::Formatter::Blockquote;
    package AAMcF::Formatter::Blockquote;
    use base 'Spoon::Formatter::Block';
    const formatter_id => 'blockquote';
    const pattern_block => 
      qr/^> ((?:(?!(?:[\=\*\0]+ |[\#\|\s]|\.\w+\s*\n|-{4,}\s*\n)).*\S.*\n)+(^\s*\n)*)/m;

    const html_start => "<blockquote>\n";
    const html_end => "</blockquote>\n";

    #- 1;
    #+ The new Spiffy -Base does this for you too. :)

Even though I changed a quite a bit, you basically hit it right on the
head. This is the proper way to subclass the formatter.

Subclassing is an effective way to extend the formatter. But it really
doesn't scale well when a lot of different modules want to extend the
formatter at the same time. That's because you can only have one
formatter class installed at a time. So you need to decide a linear
order of subclassing. :(

There is a better way to do it. I'll explain it another time.

Cheers, Brian