File Coverage

blib/lib/Wiki/Toolkit/Formatter/UseMod.pm
Criterion Covered Total %
statement 144 156 92.3
branch 31 44 70.4
condition 17 26 65.3
subroutine 23 24 95.8
pod 9 9 100.0
total 224 259 86.4


","");
line stmt bran cond sub pod time code
1             package Wiki::Toolkit::Formatter::UseMod;
2              
3 14     14   231962 use strict;
  14         29  
  14         588  
4              
5 14     14   73 use vars qw( $VERSION @_links_found );
  14         23  
  14         1312  
6             $VERSION = '0.25';
7              
8 14     14   11843 use URI::Escape;
  14         25792  
  14         1369  
9 14     14   10958 use Text::WikiFormat as => 'wikiformat';
  14         191383  
  14         115  
10 14     14   11716 use HTML::PullParser;
  14         119172  
  14         789  
11 14     14   11382 use URI::Find::Delimited;
  14         135077  
  14         35548  
12              
13             =head1 NAME
14              
15             Wiki::Toolkit::Formatter::UseMod - UseModWiki-style formatting for Wiki::Toolkit
16              
17             =head1 DESCRIPTION
18              
19             A formatter backend for L that supports UseMod-style formatting.
20              
21             =head1 SYNOPSIS
22              
23             use Wiki::Toolkit::Formatter::UseMod;
24              
25             # Instantiate - see below for parameter details.
26             my $formatter = Wiki::Toolkit::Formatter::UseMod->new( %config );
27              
28             # Format some text.
29             my $cooked = $formatter->format($raw);
30              
31             # Find out which other nodes that text would link to.
32             my @links_to = $formatter->find_internal_links($raw);
33              
34             =head1 METHODS
35              
36             =over 4
37              
38             =item B
39              
40             my $formatter = Wiki::Toolkit::Formatter::UseMod->new(
41             extended_links => 0, # $FreeLinks
42             implicit_links => 1, # $WikiLinks
43             force_ucfirst_nodes => 1, # $FreeUpper
44             use_headings => 1, # $UseHeadings
45             allowed_tags => [qw(b i)], # defaults to none
46             macros => {},
47             pass_wiki_to_macros => 0,
48             node_prefix => 'wiki.pl?',
49             node_suffix => '',
50             edit_prefix => 'wiki.pl?action=edit;id=',
51             edit_suffix => '',
52             munge_urls => 0,
53             external_link_class => 'external',
54             escape_url_commas => 1,
55             );
56              
57             Parameters will default to the values shown above (apart from
58             C, which defaults to allowing no tags, and
59             C, which defaults to false).
60              
61             =over 4
62              
63             =item B
64              
65             C, C, C and C
66             allow you to control the URLs generated for links to other wiki pages.
67             So for example with the defaults given above, a link to the Home node
68             will have the URL C and a link to the edit form for the
69             Home node will have the URL C
70              
71             (Note that of course the URLs that you wish to have generated will
72             depend on how your wiki application processes its CGI parameters - you
73             can't just put random stuff in there and hope it works!)
74              
75             By default, any commas in these URLs will be escaped to C<%2C>, in line
76             with the default behaviour of L. If you don't want this to
77             happen, pass a false value to C.
78              
79             =item B
80              
81             If you wish to have greater control over the links, you may use the
82             C parameter. The value of this should be a
83             subroutine reference. This sub will be called on each internal link
84             after all other formatting and munging I URL escaping has been
85             applied. It will be passed the node name as its first parameter and
86             should return a node name. Note that this will affect the URLs of
87             internal links, but not the link text.
88              
89             Example:
90              
91             # The formatter munges links so node names are ucfirst.
92             # Ensure 'state51' always appears in lower case in node names.
93             munge_node_name => sub {
94             my $node_name = shift;
95             $node_name =~ s/State51/state51/g;
96             return $node_name;
97             }
98              
99             B This is I usage and you should only do it if you
100             I know what you're doing. Consider in particular whether and
101             how your munged nodes are going to be treated by C.
102              
103             =item B
104              
105             By default, we emulate the UseModWiki behaviour of formatting external
106             links with hardcoded square brackets around them. If you would
107             instead prefer to control this with CSS, supply the
108             C parameter to C<< ->new >> - the value of this
109             parameter will be used as the class applied to the link (so it should
110             be a valid CSS class name). Controlling the appearance with CSS is
111             our recommended method, but the default is as described for reasons of
112             backward compatibility.
113              
114             =item B
115              
116             If you set C to true, then your URLs will be more
117             user-friendly, for example
118              
119             http://example.com/wiki.cgi?Mailing_List_Managers
120              
121             rather than
122              
123             http://example.com/wiki.cgi?Mailing%20List%20Managers
124              
125             The former behaviour is the actual UseMod behaviour, but requires a
126             little fiddling about in your code (see C),
127             so the default is to B munge URLs.
128              
129             =item B
130              
131             Be aware that macros are processed I filtering out disallowed
132             HTML tags and I transforming from wiki markup into HTML. They
133             are also not called in any particular order.
134              
135             The keys of macros should be either regexes or strings. The values can
136             be strings, or, if the corresponding key is a regex, can be coderefs.
137             The coderef will be called with the first nine substrings captured by
138             the regex as arguments. I would like to call it with all captured
139             substrings but apparently this is complicated.
140              
141             You may wish to have access to the overall wiki object in the subs
142             defined in your macro. To do this:
143              
144             =over
145              
146             =item *
147              
148             Pass the wiki object to the C<< ->formatter >> call as described below.
149              
150             =item *
151              
152             Pass a true value in the C parameter when calling
153             C<< ->new >>.
154              
155             =back
156              
157             If you do this, then I coderefs will be called with the wiki object
158             as the first parameter, followed by the first nine captured substrings
159             as described above. Note therefore that setting C
160             may cause backwards compatibility issues.
161              
162             =back
163              
164             Macro examples:
165              
166             # Simple example - substitute a little search box for '@SEARCHBOX'
167              
168             macros => {
169              
170             '@SEARCHBOX' =>
171             qq(
172            
173            
174             ),
175             }
176              
177             # More complex example - substitute a list of all nodes in a
178             # category for '@INDEX_LINK [[Category Foo]]'
179              
180             pass_wiki_to_macros => 1,
181             macros => {
182             qr/\@INDEX_LINK\s+\[\[Category\s+([^\]]+)]]/ =>
183             sub {
184             my ($wiki, $category) = @_;
185             my @nodes = $wiki->list_nodes_by_metadata(
186             metadata_type => "category",
187             metadata_value => $category,
188             ignore_case => 1,
189             );
190             my $return = "\n";
191             foreach my $node ( @nodes ) {
192             $return .= "* "
193             . $wiki->formatter->format_link(
194             wiki => $wiki,
195             link => $node,
196             )
197             . "\n";
198             }
199             return $return;
200             },
201             }
202              
203              
204             =cut
205              
206             sub new {
207 15     15 1 16862 my ($class, @args) = @_;
208 15         36 my $self = {};
209 15         40 bless $self, $class;
210 15 50       68 $self->_init(@args) or return undef;
211 15         52 return $self;
212             }
213              
214             sub _init {
215 15     15   44 my ($self, %args) = @_;
216              
217             # Store the parameters or their defaults.
218 15         245 my %defs = ( extended_links => 0,
219             implicit_links => 1,
220             force_ucfirst_nodes => 1,
221             use_headings => 1,
222             allowed_tags => [],
223             macros => {},
224             pass_wiki_to_macros => 0,
225             node_prefix => 'wiki.pl?',
226             node_suffix => '',
227             edit_prefix => 'wiki.pl?action=edit;id=',
228             edit_suffix => '',
229             munge_urls => 0,
230             munge_node_name => undef,
231             external_link_class => undef,
232             escape_url_commas => 1,
233             );
234              
235 15         133 my %collated = (%defs, %args);
236 15         79 foreach my $k (keys %defs) {
237 225         489 $self->{"_".$k} = $collated{$k};
238             }
239 15         137 return $self;
240             }
241              
242             =item B
243              
244             my $html = $formatter->format($submitted_content, $wiki);
245              
246             Escapes any tags which weren't specified as allowed on creation, then
247             interpolates any macros, then translates the raw Wiki language
248             supplied into HTML.
249              
250             A L object can be supplied as an optional second parameter.
251             This object will be used to determine whether a linked-to node exists
252             or not, and alter the presentation of the link accordingly. This is
253             only really in here for use when this method is being called from
254             within L.
255              
256             =cut
257              
258             sub format {
259 13     13 1 10553 my ($self, $raw, $wiki) = @_;
260 13         42 $raw =~ s/\r\n/\n/sg; # CGI newline is \r\n not \n
261 13         31 my $safe = "";
262              
263 13         25 my %allowed = map {lc($_) => 1, "/".lc($_) => 1} @{$self->{_allowed_tags}};
  4         26  
  13         53  
264              
265             # Parse the HTML - even if we're not allowing any tags, because we're
266             # using a custom escaping routine rather than CGI.pm
267 13         154 my $parser = HTML::PullParser->new(doc => $raw,
268             start => '"TAG", tag, text',
269             end => '"TAG", tag, text',
270             text => '"TEXT", tag, text');
271 13         1641 while (my $token = $parser->get_token) {
272 42         931 my ($flag, $tag, $text) = @$token;
273 42 100 100     184 if ($flag eq "TAG" and !defined $allowed{lc($tag)}) {
274 3         11 $safe .= $self->_escape_HTML($text);
275             } else {
276 39         154 $safe .= $text;
277             }
278             }
279              
280             # Now do any inline links.
281             my $callback = sub {
282 4     4   76184 my ($open, $close, $url, $title, $whitespace) = @_;
283 4   66     33 $title ||= $url;
284 4 100 66     24 if ( $open && $close ) {
285 2         12 return $self->make_external_link( title => $title, url => $url );
286             } else {
287 2         18 return $open
288             . $self->make_external_link( title => $title, url => $url )
289             . $close;
290             }
291 13         179 };
292            
293 13         148 my $finder = URI::Find::Delimited->new( ignore_quoted => 1, callback => $callback );
294 13         302 $finder->find(\$safe);
295              
296             # Now process any macros.
297 13         190520 my %macros = %{$self->{_macros}};
  13         101  
298 13         94 foreach my $key (keys %macros) {
299 6         30 my $value = $macros{$key};
300 6 100 66     26 if ( ref $value && ref $value eq 'CODE' ) {
301 4 50 33     13 if ( $self->{_pass_wiki_to_macros} and $wiki ) {
302 0         0 $safe=~ s/$key/$value->($wiki, $1, $2, $3, $4, $5, $6, $7, $8, $9)/eg;
  0         0  
303             } else {
304 4         65 $safe=~ s/$key/$value->($1, $2, $3, $4, $5, $6, $7, $8, $9)/eg;
  4         15  
305             }
306             } else {
307 2         21 $safe =~ s/$key/$value/g;
308             }
309             }
310              
311             # Finally set up config and call Text::WikiFormat.
312 13         72 my %format_opts = $self->_format_opts;
313             my %format_tags = (
314             # chromatic made most of the regex below. I will document it when
315             # I understand it properly.
316             indent => qr/^(?:\t+|\s{4,}|\s*\*?(?=\**\*+))/,
317             newline => "", # avoid bogus
318             paragraph => [ "

", "

\n", "", "\n", 1 ], # no bogus
319             extended_link_delimiters => [ '[[', ']]' ],
320             blocks => {
321             ordered => qr/^\s*([\d]+)\.\s*/,
322             unordered => qr/^\s*\*\s*/,
323             definition => qr/^:\s*/,
324             pre => qr/^\s+/,
325             table => qr/^\|\|/,
326             },
327             definition => [ "
\n", "
\n", "
 ", "
\n" ],
328             pre => [ "
\n", "
\n", "", "\n" ],
329             table => [ qq|\n|, "
\n",
330             sub {
331 4     4   1847 my $line = shift;
332 4         19 $line =~ s/\|\|$/<\/td>/;
333 4         13 $line =~ s/\|\|/<\/td>/g;
334 4         21 return ("
$line","
335             },
336             ],
337             # we don't label unordered lists as "not indented" so we can nest them.
338             indented => {
339             definition => 0,
340             ordered => 0,
341             pre => 0,
342             table => 0,
343             },
344             blockorder => [ qw( header line ordered unordered code definition pre table paragraph )],
345 26         245 nests => { map { $_ => 1} qw( ordered unordered ) },
346             link => sub {
347 3     3   3073 my $link = shift;
348 3         13 return $self->format_link(
349             link => $link,
350             wiki => $wiki,
351             );
352             },
353 13         523 );
354              
355 13         123 return wikiformat($safe, \%format_tags, \%format_opts );
356             }
357              
358             sub _format_opts {
359 22     22   48 my $self = shift;
360             return (
361             extended => $self->{_extended_links},
362             prefix => $self->{_node_prefix},
363             implicit_links => $self->{_implicit_links}
364 22         161 );
365             }
366              
367             =item B
368              
369             my $string = $formatter->format_link(
370             link => "Home Node",
371             wiki => $wiki,
372             );
373              
374             An internal method exposed to make it easy to go from eg
375              
376             * Foo
377             * Bar
378              
379             to
380              
381             * Foo
382             * Bar
383              
384             See Macro Examples above for why you might find this useful.
385              
386             C should be something that would go inside your extended link
387             delimiters. C is optional but should be a L object.
388             If you do supply C then the method will be able to check whether
389             the node exists yet or not and so will call C<< ->make_edit_link >>
390             instead of C<< ->make_internal_link >> where appropriate. If you don't
391             supply C then C<< ->make_internal_link >> will be called always.
392              
393             This method used to be private so may do unexpected things if you use
394             it in a way that I haven't tested yet.
395              
396             =cut
397              
398             sub format_link {
399 3     3 1 10 my ($self, %args) = @_;
400 3         7 my $link = $args{link};
401 3         8 my %opts = $self->_format_opts;
402 3         30 my $wiki = $args{wiki};
403              
404 3         4 my $title;
405 3 50       8 ($link, $title) = split(/\|/, $link, 2) if $opts{extended};
406 3 50       8 $title =~ s/^\s*// if $title; # strip leading whitespace
407 3   33     14 $title ||= $link;
408              
409 3 50       9 if ( $self->{_force_ucfirst_nodes} ) {
410 3         9 $link = $self->_do_freeupper($link);
411             }
412 3         8 $link = $self->_munge_spaces($link);
413              
414             $link = $self->{_munge_node_name}($link)
415 3 50       9 if $self->{_munge_node_name};
416              
417 3 50       7 if (!$link) {
418 0         0 return "[Undefined link '$title']";
419             }
420              
421 3         4 my $editlink_not_link = 0;
422             # See whether the linked-to node exists, if we can.
423 3 50 33     10 if ( $wiki && !$wiki->node_exists( $link ) ) {
424 0         0 $editlink_not_link = 1;
425             }
426              
427 3 50       8 $link =~ s/ /_/g if $self->{_munge_urls};
428 3         12 $link = uri_escape( $link );
429              
430 3 50       68 unless ( $self->{_escape_url_commas} ) {
431 0         0 $link =~ s/%2C/,/gs;
432             }
433              
434 3 50       7 if ( $editlink_not_link ) {
435 0         0 my $prefix = $self->{_edit_prefix};
436 0         0 my $suffix = $self->{_edit_suffix};
437 0         0 return $self->make_edit_link(
438             title => $title,
439             url => $prefix.$link.$suffix,
440             );
441             } else {
442 3         6 my $prefix = $self->{_node_prefix};
443 3         5 my $suffix = $self->{_node_suffix};
444 3         15 return $self->make_internal_link(
445             title => $title,
446             url => $prefix.$link.$suffix,
447             );
448             }
449             }
450              
451             # CGI.pm is sometimes awkward about actually performing CGI::escapeHTML
452             # if there's a previous instantiation - in the calling script, for example.
453             # So just do it here.
454             sub _escape_HTML {
455 3     3   5 my ($self, $text) = @_;
456 3         8 $text =~ s{&}{&}gso;
457 3         12 $text =~ s{<}{<}gso;
458 3         9 $text =~ s{>}{>}gso;
459 3         6 $text =~ s{"}{"}gso;
460 3         17 return $text;
461             }
462              
463             =item B
464            
465             my @links_to = $formatter->find_internal_links( $content );
466            
467             Returns a list of all nodes that the supplied content links to.
468            
469             =cut
470            
471             sub find_internal_links {
472 2     2 1 4067 my ($self, $raw) = @_;
473            
474 2         6 @_links_found = ();
475            
476 2         9 my %format_opts = $self->_format_opts;
477              
478             my %format_tags = ( extended_link_delimiters => [ '[[', ']]' ],
479             link => sub {
480 4     4   2775 my $link = shift;
481 4         14 my %opts = $self->_format_opts;
482 4         8 my $title;
483             ($link, $title) = split(/\|/, $link, 2)
484 4 100       16 if $opts{extended};
485 4 50       15 if ( $self->{_force_ucfirst_nodes} ) {
486 4         14 $link = $self->_do_freeupper($link);
487             }
488             $link = $self->{_munge_node_name}($link)
489 4 100       17 if $self->{_munge_node_name};
490 4         17 $link = $self->_munge_spaces($link);
491 4         9 push @Wiki::Toolkit::Formatter::UseMod::_links_found,
492             $link;
493 4         19 return ""; # don't care about output
494             }
495 2         18 );
496              
497 2         13 my $foo = wikiformat($raw, \%format_tags, \%format_opts);
498              
499 2         125 my @links = @_links_found;
500 2         5 @_links_found = ();
501 2         22 return @links;
502             }
503              
504              
505             =item B
506              
507             use URI::Escape;
508             $param = $formatter->node_name_to_node_param( "Recent Changes" );
509             my $url = "wiki.pl?" . uri_escape($param);
510              
511             In usemod, the node name is encoded prior to being used as part of the
512             URL. This method does this encoding (essentially, whitespace is munged
513             into underscores). In addition, if C is in action
514             then the node names will be forced ucfirst if they weren't already.
515              
516             Note that unless C was set to true when C was called,
517             this method will do nothing.
518              
519             =cut
520              
521             sub node_name_to_node_param {
522 3     3 1 22 my ($self, $node_name) = @_;
523 3 100       8 return $node_name unless $self->{_munge_urls};
524 2         3 my $param = $node_name;
525 2         5 $param = $self->_munge_spaces($param);
526 2 100       9 $param = $self->_do_freeupper($param) if $self->{_force_ucfirst_nodes};
527 2         3 $param =~ s/ /_/g;
528              
529 2         9 return $param;
530             }
531              
532             =item B
533              
534             my $node = $q->param('node') || "";
535             $node = $formatter->node_param_to_node_name( $node );
536              
537             In usemod, the node name is encoded prior to being used as part of the
538             URL, so we must decode it before we can get back the original node name.
539              
540             Note that unless C was set to true when C was called,
541             this method will do nothing.
542              
543             =cut
544              
545             sub node_param_to_node_name {
546 1     1 1 3 my ($self, $param) = @_;
547 1 50       5 return $param unless $self->{_munge_urls};
548              
549             # Note that this might not give us back exactly what we started with,
550             # since in the encoding we collapse and trim whitespace; but this is
551             # how usemod does it (as of 0.92) and usemod is what we're emulating.
552 0         0 $param =~ s/_/ /g;
553              
554 0         0 return $param;
555             }
556              
557             sub _do_freeupper {
558 8     8   12 my ($self, $node) = @_;
559              
560             # This is the FreeUpper usemod behaviour, slightly modified from
561             # their regexp, as we need to do it before we check whether the
562             # node exists ie before we substitute the spaces with underscores.
563 8         20 $node = ucfirst($node);
564 8         26 $node =~ s|([- _.,\(\)/])([a-z])|$1.uc($2)|ge;
  3         11  
565              
566 8         21 return $node;
567             }
568              
569             sub _munge_spaces {
570 9     9   13 my ($self, $node) = @_;
571              
572             # Yes, we really do only munge spaces, not all whitespace. This is
573             # how usemod does it (as of 0.92).
574 9         23 $node =~ s/ +/ /g;
575 9         14 $node =~ s/^ //;
576 9         12 $node =~ s/ $//;
577              
578 9         17 return $node
579             }
580              
581             =back
582              
583             =head1 SUBCLASSING
584              
585             The following methods can be overridden to provide custom behaviour.
586              
587             =over
588              
589             =item B
590              
591             my $link = $self->make_edit_link(
592             title => "Home Page",
593             url => "http://example.com/?id=Home",
594             );
595              
596             This method will be passed a title and a url and should return an HTML
597             snippet. For example, you can add a C attribute to the link </td> </tr> <tr> <td class="h" > <a name="598">598</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> like so: </td> </tr> <tr> <td class="h" > <a name="599">599</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="600">600</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_edit_link { </td> </tr> <tr> <td class="h" > <a name="601">601</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="602">602</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $title = $args{title}; </td> </tr> <tr> <td class="h" > <a name="603">603</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $url = $args{url}; </td> </tr> <tr> <td class="h" > <a name="604">604</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return qq|[$title]<a href="$url" title="create">?</a>|; </td> </tr> <tr> <td class="h" > <a name="605">605</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="606">606</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="607">607</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="608">608</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="609">609</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_edit_link { </td> </tr> <tr> <td class="h" > <a name="610">610</a> </td> <td class="c0" > <a href="#611"> 0 </a> </td> <td >   </td> <td >   </td> <td class="c0" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#610-1"> 0 </a> </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#610-1"> 1 </a> </td> <td > 0 </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="611">611</a> </td> <td class="c0" > 0 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 0 </td> <td class="s"> return qq|[$args{title}]<a href="$args{url}">?</a>|; </td> </tr> <tr> <td class="h" > <a name="612">612</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="613">613</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="614">614</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item B<make_internal_link> </td> </tr> <tr> <td class="h" > <a name="615">615</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="616">616</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $link = $self->make_internal_link( </td> </tr> <tr> <td class="h" > <a name="617">617</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> title => "Home Page", </td> </tr> <tr> <td class="h" > <a name="618">618</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> url => "http://example.com/?id=Home", </td> </tr> <tr> <td class="h" > <a name="619">619</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="620">620</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="621">621</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This method will be passed a title and a url and should return an HTML </td> </tr> <tr> <td class="h" > <a name="622">622</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> snippet. For example, you can add a C<class> attribute to the link </td> </tr> <tr> <td class="h" > <a name="623">623</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> like so: </td> </tr> <tr> <td class="h" > <a name="624">624</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="625">625</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_internal_link { </td> </tr> <tr> <td class="h" > <a name="626">626</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="627">627</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $title = $args{title}; </td> </tr> <tr> <td class="h" > <a name="628">628</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $url = $args{url}; </td> </tr> <tr> <td class="h" > <a name="629">629</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return qq|<a href="$url" class="internal">$title</a>|; </td> </tr> <tr> <td class="h" > <a name="630">630</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="631">631</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="632">632</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="633">633</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="634">634</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_internal_link { </td> </tr> <tr> <td class="h" > <a name="635">635</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#635-1"> 3 </a> </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#635-1"> 1 </a> </td> <td > 10 </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="636">636</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 28 </td> <td class="s"> return qq|<a href="$args{url}">$args{title}</a>|; </td> </tr> <tr> <td class="h" > <a name="637">637</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="638">638</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="639">639</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item B<make_external_link> </td> </tr> <tr> <td class="h" > <a name="640">640</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="641">641</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $link = $self->make_external_link( </td> </tr> <tr> <td class="h" > <a name="642">642</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> title => "London Perlmongers", </td> </tr> <tr> <td class="h" > <a name="643">643</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> url => "http://london.pm.org", </td> </tr> <tr> <td class="h" > <a name="644">644</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="645">645</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="646">646</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This method will be passed a title and a url and should return an HTML </td> </tr> <tr> <td class="h" > <a name="647">647</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> snippet. For example, you can add a little icon after each external </td> </tr> <tr> <td class="h" > <a name="648">648</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> link like so: </td> </tr> <tr> <td class="h" > <a name="649">649</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="650">650</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_external_link { </td> </tr> <tr> <td class="h" > <a name="651">651</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="652">652</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $title = $args{title}; </td> </tr> <tr> <td class="h" > <a name="653">653</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $url = $args{url}; </td> </tr> <tr> <td class="h" > <a name="654">654</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return qq|<a href="$url">$title</a> <img src="external.gif">|; </td> </tr> <tr> <td class="h" > <a name="655">655</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="656">656</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="657">657</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="658">658</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="659">659</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> sub make_external_link { </td> </tr> <tr> <td class="h" > <a name="660">660</a> </td> <td class="c3" > 4 </td> <td >   </td> <td >   </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#660-1"> 4 </a> </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--subroutine.html#660-1"> 1 </a> </td> <td > 21 </td> <td class="s"> my ($self, %args) = @_; </td> </tr> <tr> <td class="h" > <a name="661">661</a> </td> <td class="c3" > 4 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 9 </td> <td class="s"> my ($open, $close) = ( "[", "]" ); </td> </tr> <tr> <td class="h" > <a name="662">662</a> </td> <td class="c3" > 4 </td> <td >   </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--condition.html#662-1"> 100 </a> </td> <td >   </td> <td >   </td> <td > 23 </td> <td class="s"> my $link_class = $self->{_external_link_class} || ""; </td> </tr> <tr> <td class="h" > <a name="663">663</a> </td> <td class="c3" > 4 </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--branch.html#663-1"> 100 </a> </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--condition.html#663-1"> 100 </a> </td> <td >   </td> <td >   </td> <td > 148 </td> <td class="s"> if ( $args{title} eq $args{url} || $link_class ) { </td> </tr> <tr> <td class="h" > <a name="664">664</a> </td> <td class="c3" > 3 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 11 </td> <td class="s"> ($open, $close) = ( "", "" ); </td> </tr> <tr> <td class="h" > <a name="665">665</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="666">666</a> </td> <td class="c3" > 4 </td> <td class="c3" > <a href="blib-lib-Wiki-Toolkit-Formatter-UseMod-pm--branch.html#666-1"> 100 </a> </td> <td >   </td> <td >   </td> <td >   </td> <td > 35 </td> <td class="s"> my $ret = qq|$open<a href="$args{url}"| </td> </tr> <tr> <td class="h" > <a name="667">667</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> . ( $link_class ? qq| class="$link_class"| : "" ) </td> </tr> <tr> <td class="h" > <a name="668">668</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> . qq|>$args{title}</a>$close|; </td> </tr> <tr> <td class="h" > <a name="669">669</a> </td> <td class="c3" > 4 </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td > 60 </td> <td class="s"> return $ret; </td> </tr> <tr> <td class="h" > <a name="670">670</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="671">671</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="672">672</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =back </td> </tr> <tr> <td class="h" > <a name="673">673</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="674">674</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 AUTHOR </td> </tr> <tr> <td class="h" > <a name="675">675</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="676">676</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Kake Pugh (kake@earth.li) and the Wiki::Toolkit team. </td> </tr> <tr> <td class="h" > <a name="677">677</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="678">678</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 COPYRIGHT </td> </tr> <tr> <td class="h" > <a name="679">679</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="680">680</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Copyright (C) 2003-2004 Kake Pugh. All Rights Reserved. </td> </tr> <tr> <td class="h" > <a name="681">681</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> Copyright (C) 2006-2012 the Wiki::Toolkit team. All Rights Reserved. </td> </tr> <tr> <td class="h" > <a name="682">682</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="683">683</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This module is free software; you can redistribute it and/or modify it </td> </tr> <tr> <td class="h" > <a name="684">684</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> under the same terms as Perl itself. </td> </tr> <tr> <td class="h" > <a name="685">685</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="686">686</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 CREDITS </td> </tr> <tr> <td class="h" > <a name="687">687</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="688">688</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> The OpenGuides London team (L<http://openguides.org/london/>) sent </td> </tr> <tr> <td class="h" > <a name="689">689</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> some very helpful bug reports. A lot of the work of this module is </td> </tr> <tr> <td class="h" > <a name="690">690</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> done within chromatic's module, L<Text::WikiFormat>. </td> </tr> <tr> <td class="h" > <a name="691">691</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="692">692</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 CAVEATS </td> </tr> <tr> <td class="h" > <a name="693">693</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="694">694</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> This doesn't yet support all of UseMod's formatting features and </td> </tr> <tr> <td class="h" > <a name="695">695</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> options, by any means. This really truly I<is> a 0.* release. Please </td> </tr> <tr> <td class="h" > <a name="696">696</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> send bug reports, omissions, patches, and stuff, to me at </td> </tr> <tr> <td class="h" > <a name="697">697</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> C<kake@earth.li>. </td> </tr> <tr> <td class="h" > <a name="698">698</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="699">699</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 NOTE ON USEMOD COMPATIBILITY </td> </tr> <tr> <td class="h" > <a name="700">700</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="701">701</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> UseModWiki "encodes" node names before making them part of a URL, so </td> </tr> <tr> <td class="h" > <a name="702">702</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> for example a node about Wombat Defenestration will have a URL like </td> </tr> <tr> <td class="h" > <a name="703">703</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="704">704</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> http://example.com/wiki.cgi?Wombat_Defenestration </td> </tr> <tr> <td class="h" > <a name="705">705</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="706">706</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> So if we want to emulate a UseModWiki exactly, we need to munge back </td> </tr> <tr> <td class="h" > <a name="707">707</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> and forth between node names as titles, and node names as CGI params. </td> </tr> <tr> <td class="h" > <a name="708">708</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="709">709</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $formatter = Wiki::Toolkit::Formatter::UseMod->new( munge_urls => 1 ); </td> </tr> <tr> <td class="h" > <a name="710">710</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $node_param = $q->param('id') || $q->param('keywords') || ""; </td> </tr> <tr> <td class="h" > <a name="711">711</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $node_name = $formatter->node_param_to_node_name( $node_param ); </td> </tr> <tr> <td class="h" > <a name="712">712</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="713">713</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> use URI::Escape; </td> </tr> <tr> <td class="h" > <a name="714">714</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $url = "http://example.com/wiki.cgi?" </td> </tr> <tr> <td class="h" > <a name="715">715</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> . uri_escape( </td> </tr> <tr> <td class="h" > <a name="716">716</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> $formatter->node_name_to_node_param( "Wombat Defenestration" ) </td> </tr> <tr> <td class="h" > <a name="717">717</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ); </td> </tr> <tr> <td class="h" > <a name="718">718</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="719">719</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =head1 SEE ALSO </td> </tr> <tr> <td class="h" > <a name="720">720</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="721">721</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =over 4 </td> </tr> <tr> <td class="h" > <a name="722">722</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="723">723</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item * L<Wiki::Toolkit> </td> </tr> <tr> <td class="h" > <a name="724">724</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="725">725</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item * L<Text::WikiFormat> </td> </tr> <tr> <td class="h" > <a name="726">726</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="727">727</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =item * UseModWiki (L<http://www.usemod.com/cgi-bin/wiki.pl>) </td> </tr> <tr> <td class="h" > <a name="728">728</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="729">729</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =back </td> </tr> <tr> <td class="h" > <a name="730">730</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="731">731</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> =cut </td> </tr> <tr> <td class="h" > <a name="732">732</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="733">733</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 1; </td> </tr> </table> </body> </html>