1*0Sstevel@tonic-gate############################################################################# 2*0Sstevel@tonic-gate# Pod/ParseUtils.pm -- helpers for POD parsing and conversion 3*0Sstevel@tonic-gate# 4*0Sstevel@tonic-gate# Copyright (C) 1999-2000 by Marek Rouchal. All rights reserved. 5*0Sstevel@tonic-gate# This file is part of "PodParser". PodParser is free software; 6*0Sstevel@tonic-gate# you can redistribute it and/or modify it under the same terms 7*0Sstevel@tonic-gate# as Perl itself. 8*0Sstevel@tonic-gate############################################################################# 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gatepackage Pod::ParseUtils; 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gateuse vars qw($VERSION); 13*0Sstevel@tonic-gate$VERSION = 0.30; ## Current version of this package 14*0Sstevel@tonic-gaterequire 5.005; ## requires this Perl version or later 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate=head1 NAME 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gatePod::ParseUtils - helpers for POD parsing and conversion 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate=head1 SYNOPSIS 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gate use Pod::ParseUtils; 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate my $list = new Pod::List; 25*0Sstevel@tonic-gate my $link = Pod::Hyperlink->new('Pod::Parser'); 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate=head1 DESCRIPTION 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gateB<Pod::ParseUtils> contains a few object-oriented helper packages for 30*0Sstevel@tonic-gatePOD parsing and processing (i.e. in POD formatters and translators). 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate=cut 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 35*0Sstevel@tonic-gate# Pod::List 36*0Sstevel@tonic-gate# 37*0Sstevel@tonic-gate# class to hold POD list info (=over, =item, =back) 38*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gatepackage Pod::List; 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gateuse Carp; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate=head2 Pod::List 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gateB<Pod::List> can be used to hold information about POD lists 47*0Sstevel@tonic-gate(written as =over ... =item ... =back) for further processing. 48*0Sstevel@tonic-gateThe following methods are available: 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate=over 4 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate=item Pod::List-E<gt>new() 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gateCreate a new list object. Properties may be specified through a hash 55*0Sstevel@tonic-gatereference like this: 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate my $list = Pod::List->new({ -start => $., -indent => 4 }); 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gateSee the individual methods/properties for details. 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate=cut 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gatesub new { 64*0Sstevel@tonic-gate my $this = shift; 65*0Sstevel@tonic-gate my $class = ref($this) || $this; 66*0Sstevel@tonic-gate my %params = @_; 67*0Sstevel@tonic-gate my $self = {%params}; 68*0Sstevel@tonic-gate bless $self, $class; 69*0Sstevel@tonic-gate $self->initialize(); 70*0Sstevel@tonic-gate return $self; 71*0Sstevel@tonic-gate} 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gatesub initialize { 74*0Sstevel@tonic-gate my $self = shift; 75*0Sstevel@tonic-gate $self->{-file} ||= 'unknown'; 76*0Sstevel@tonic-gate $self->{-start} ||= 'unknown'; 77*0Sstevel@tonic-gate $self->{-indent} ||= 4; # perlpod: "should be the default" 78*0Sstevel@tonic-gate $self->{_items} = []; 79*0Sstevel@tonic-gate $self->{-type} ||= ''; 80*0Sstevel@tonic-gate} 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate=item $list-E<gt>file() 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gateWithout argument, retrieves the file name the list is in. This must 85*0Sstevel@tonic-gatehave been set before by either specifying B<-file> in the B<new()> 86*0Sstevel@tonic-gatemethod or by calling the B<file()> method with a scalar argument. 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate=cut 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate# The POD file name the list appears in 91*0Sstevel@tonic-gatesub file { 92*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-file} = $_[1]) : $_[0]->{-file}; 93*0Sstevel@tonic-gate} 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate=item $list-E<gt>start() 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gateWithout argument, retrieves the line number where the list started. 98*0Sstevel@tonic-gateThis must have been set before by either specifying B<-start> in the 99*0Sstevel@tonic-gateB<new()> method or by calling the B<start()> method with a scalar 100*0Sstevel@tonic-gateargument. 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate=cut 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate# The line in the file the node appears 105*0Sstevel@tonic-gatesub start { 106*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-start} = $_[1]) : $_[0]->{-start}; 107*0Sstevel@tonic-gate} 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate=item $list-E<gt>indent() 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gateWithout argument, retrieves the indent level of the list as specified 112*0Sstevel@tonic-gatein C<=over n>. This must have been set before by either specifying 113*0Sstevel@tonic-gateB<-indent> in the B<new()> method or by calling the B<indent()> method 114*0Sstevel@tonic-gatewith a scalar argument. 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate=cut 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate# indent level 119*0Sstevel@tonic-gatesub indent { 120*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-indent} = $_[1]) : $_[0]->{-indent}; 121*0Sstevel@tonic-gate} 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate=item $list-E<gt>type() 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gateWithout argument, retrieves the list type, which can be an arbitrary value, 126*0Sstevel@tonic-gatee.g. C<OL>, C<UL>, ... when thinking the HTML way. 127*0Sstevel@tonic-gateThis must have been set before by either specifying 128*0Sstevel@tonic-gateB<-type> in the B<new()> method or by calling the B<type()> method 129*0Sstevel@tonic-gatewith a scalar argument. 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate=cut 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate# The type of the list (UL, OL, ...) 134*0Sstevel@tonic-gatesub type { 135*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-type} = $_[1]) : $_[0]->{-type}; 136*0Sstevel@tonic-gate} 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate=item $list-E<gt>rx() 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gateWithout argument, retrieves a regular expression for simplifying the 141*0Sstevel@tonic-gateindividual item strings once the list type has been determined. Usage: 142*0Sstevel@tonic-gateE.g. when converting to HTML, one might strip the leading number in 143*0Sstevel@tonic-gatean ordered list as C<E<lt>OLE<gt>> already prints numbers itself. 144*0Sstevel@tonic-gateThis must have been set before by either specifying 145*0Sstevel@tonic-gateB<-rx> in the B<new()> method or by calling the B<rx()> method 146*0Sstevel@tonic-gatewith a scalar argument. 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate=cut 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate# The regular expression to simplify the items 151*0Sstevel@tonic-gatesub rx { 152*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-rx} = $_[1]) : $_[0]->{-rx}; 153*0Sstevel@tonic-gate} 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate=item $list-E<gt>item() 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gateWithout argument, retrieves the array of the items in this list. 158*0Sstevel@tonic-gateThe items may be represented by any scalar. 159*0Sstevel@tonic-gateIf an argument has been given, it is pushed on the list of items. 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate=cut 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate# The individual =items of this list 164*0Sstevel@tonic-gatesub item { 165*0Sstevel@tonic-gate my ($self,$item) = @_; 166*0Sstevel@tonic-gate if(defined $item) { 167*0Sstevel@tonic-gate push(@{$self->{_items}}, $item); 168*0Sstevel@tonic-gate return $item; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate else { 171*0Sstevel@tonic-gate return @{$self->{_items}}; 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate} 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate=item $list-E<gt>parent() 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gateWithout argument, retrieves information about the parent holding this 178*0Sstevel@tonic-gatelist, which is represented as an arbitrary scalar. 179*0Sstevel@tonic-gateThis must have been set before by either specifying 180*0Sstevel@tonic-gateB<-parent> in the B<new()> method or by calling the B<parent()> method 181*0Sstevel@tonic-gatewith a scalar argument. 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate=cut 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate# possibility for parsers/translators to store information about the 186*0Sstevel@tonic-gate# lists's parent object 187*0Sstevel@tonic-gatesub parent { 188*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-parent} = $_[1]) : $_[0]->{-parent}; 189*0Sstevel@tonic-gate} 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate=item $list-E<gt>tag() 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gateWithout argument, retrieves information about the list tag, which can be 194*0Sstevel@tonic-gateany scalar. 195*0Sstevel@tonic-gateThis must have been set before by either specifying 196*0Sstevel@tonic-gateB<-tag> in the B<new()> method or by calling the B<tag()> method 197*0Sstevel@tonic-gatewith a scalar argument. 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate=back 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate=cut 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate# possibility for parsers/translators to store information about the 204*0Sstevel@tonic-gate# list's object 205*0Sstevel@tonic-gatesub tag { 206*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-tag} = $_[1]) : $_[0]->{-tag}; 207*0Sstevel@tonic-gate} 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 210*0Sstevel@tonic-gate# Pod::Hyperlink 211*0Sstevel@tonic-gate# 212*0Sstevel@tonic-gate# class to manipulate POD hyperlinks (L<>) 213*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gatepackage Pod::Hyperlink; 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate=head2 Pod::Hyperlink 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gateB<Pod::Hyperlink> is a class for manipulation of POD hyperlinks. Usage: 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate my $link = Pod::Hyperlink->new('alternative text|page/"section in page"'); 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gateThe B<Pod::Hyperlink> class is mainly designed to parse the contents of the 224*0Sstevel@tonic-gateC<LE<lt>...E<gt>> sequence, providing a simple interface for accessing the 225*0Sstevel@tonic-gatedifferent parts of a POD hyperlink for further processing. It can also be 226*0Sstevel@tonic-gateused to construct hyperlinks. 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate=over 4 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate=item Pod::Hyperlink-E<gt>new() 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gateThe B<new()> method can either be passed a set of key/value pairs or a single 233*0Sstevel@tonic-gatescalar value, namely the contents of a C<LE<lt>...E<gt>> sequence. An object 234*0Sstevel@tonic-gateof the class C<Pod::Hyperlink> is returned. The value C<undef> indicates a 235*0Sstevel@tonic-gatefailure, the error message is stored in C<$@>. 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate=cut 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gateuse Carp; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gatesub new { 242*0Sstevel@tonic-gate my $this = shift; 243*0Sstevel@tonic-gate my $class = ref($this) || $this; 244*0Sstevel@tonic-gate my $self = +{}; 245*0Sstevel@tonic-gate bless $self, $class; 246*0Sstevel@tonic-gate $self->initialize(); 247*0Sstevel@tonic-gate if(defined $_[0]) { 248*0Sstevel@tonic-gate if(ref($_[0])) { 249*0Sstevel@tonic-gate # called with a list of parameters 250*0Sstevel@tonic-gate %$self = %{$_[0]}; 251*0Sstevel@tonic-gate $self->_construct_text(); 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate else { 254*0Sstevel@tonic-gate # called with L<> contents 255*0Sstevel@tonic-gate return undef unless($self->parse($_[0])); 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate return $self; 259*0Sstevel@tonic-gate} 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gatesub initialize { 262*0Sstevel@tonic-gate my $self = shift; 263*0Sstevel@tonic-gate $self->{-line} ||= 'undef'; 264*0Sstevel@tonic-gate $self->{-file} ||= 'undef'; 265*0Sstevel@tonic-gate $self->{-page} ||= ''; 266*0Sstevel@tonic-gate $self->{-node} ||= ''; 267*0Sstevel@tonic-gate $self->{-alttext} ||= ''; 268*0Sstevel@tonic-gate $self->{-type} ||= 'undef'; 269*0Sstevel@tonic-gate $self->{_warnings} = []; 270*0Sstevel@tonic-gate} 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate=item $link-E<gt>parse($string) 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gateThis method can be used to (re)parse a (new) hyperlink, i.e. the contents 275*0Sstevel@tonic-gateof a C<LE<lt>...E<gt>> sequence. The result is stored in the current object. 276*0Sstevel@tonic-gateWarnings are stored in the B<warnings> property. 277*0Sstevel@tonic-gateE.g. sections like C<LE<lt>open(2)E<gt>> are deprecated, as they do not point 278*0Sstevel@tonic-gateto Perl documents. C<LE<lt>DBI::foo(3p)E<gt>> is wrong as well, the manpage 279*0Sstevel@tonic-gatesection can simply be dropped. 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate=cut 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gatesub parse { 284*0Sstevel@tonic-gate my $self = shift; 285*0Sstevel@tonic-gate local($_) = $_[0]; 286*0Sstevel@tonic-gate # syntax check the link and extract destination 287*0Sstevel@tonic-gate my ($alttext,$page,$node,$type,$quoted) = (undef,'','','',0); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate $self->{_warnings} = []; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate # collapse newlines with whitespace 292*0Sstevel@tonic-gate s/\s*\n+\s*/ /g; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate # strip leading/trailing whitespace 295*0Sstevel@tonic-gate if(s/^[\s\n]+//) { 296*0Sstevel@tonic-gate $self->warning("ignoring leading whitespace in link"); 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate if(s/[\s\n]+$//) { 299*0Sstevel@tonic-gate $self->warning("ignoring trailing whitespace in link"); 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate unless(length($_)) { 302*0Sstevel@tonic-gate _invalid_link("empty link"); 303*0Sstevel@tonic-gate return undef; 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate ## Check for different possibilities. This is tedious and error-prone 307*0Sstevel@tonic-gate # we match all possibilities (alttext, page, section/item) 308*0Sstevel@tonic-gate #warn "DEBUG: link=$_\n"; 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate # only page 311*0Sstevel@tonic-gate # problem: a lot of people use (), or (1) or the like to indicate 312*0Sstevel@tonic-gate # man page sections. But this collides with L<func()> that is supposed 313*0Sstevel@tonic-gate # to point to an internal funtion... 314*0Sstevel@tonic-gate my $page_rx = '[\w.-]+(?:::[\w.-]+)*(?:[(](?:\d\w*|)[)]|)'; 315*0Sstevel@tonic-gate # page name only 316*0Sstevel@tonic-gate if(m!^($page_rx)$!o) { 317*0Sstevel@tonic-gate $page = $1; 318*0Sstevel@tonic-gate $type = 'page'; 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate # alttext, page and "section" 321*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*($page_rx)\s*/\s*"(.+)"$!o) { 322*0Sstevel@tonic-gate ($alttext, $page, $node) = ($1, $2, $3); 323*0Sstevel@tonic-gate $type = 'section'; 324*0Sstevel@tonic-gate $quoted = 1; #... therefore | and / are allowed 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate # alttext and page 327*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*($page_rx)$!o) { 328*0Sstevel@tonic-gate ($alttext, $page) = ($1, $2); 329*0Sstevel@tonic-gate $type = 'page'; 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate # alttext and "section" 332*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*(?:/\s*|)"(.+)"$!) { 333*0Sstevel@tonic-gate ($alttext, $node) = ($1,$2); 334*0Sstevel@tonic-gate $type = 'section'; 335*0Sstevel@tonic-gate $quoted = 1; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate # page and "section" 338*0Sstevel@tonic-gate elsif(m!^($page_rx)\s*/\s*"(.+)"$!o) { 339*0Sstevel@tonic-gate ($page, $node) = ($1, $2); 340*0Sstevel@tonic-gate $type = 'section'; 341*0Sstevel@tonic-gate $quoted = 1; 342*0Sstevel@tonic-gate } 343*0Sstevel@tonic-gate # page and item 344*0Sstevel@tonic-gate elsif(m!^($page_rx)\s*/\s*(.+)$!o) { 345*0Sstevel@tonic-gate ($page, $node) = ($1, $2); 346*0Sstevel@tonic-gate $type = 'item'; 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate # only "section" 349*0Sstevel@tonic-gate elsif(m!^/?"(.+)"$!) { 350*0Sstevel@tonic-gate $node = $1; 351*0Sstevel@tonic-gate $type = 'section'; 352*0Sstevel@tonic-gate $quoted = 1; 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate # only item 355*0Sstevel@tonic-gate elsif(m!^\s*/(.+)$!) { 356*0Sstevel@tonic-gate $node = $1; 357*0Sstevel@tonic-gate $type = 'item'; 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate # non-standard: Hyperlink 360*0Sstevel@tonic-gate elsif(m!^((?:http|ftp|mailto|news):.+)$!i) { 361*0Sstevel@tonic-gate $node = $1; 362*0Sstevel@tonic-gate $type = 'hyperlink'; 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate # alttext, page and item 365*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*($page_rx)\s*/\s*(.+)$!o) { 366*0Sstevel@tonic-gate ($alttext, $page, $node) = ($1, $2, $3); 367*0Sstevel@tonic-gate $type = 'item'; 368*0Sstevel@tonic-gate } 369*0Sstevel@tonic-gate # alttext and item 370*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*/(.+)$!) { 371*0Sstevel@tonic-gate ($alttext, $node) = ($1,$2); 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate # nonstandard: alttext and hyperlink 374*0Sstevel@tonic-gate elsif(m!^(.*?)\s*[|]\s*((?:http|ftp|mailto|news):.+)$!) { 375*0Sstevel@tonic-gate ($alttext, $node) = ($1,$2); 376*0Sstevel@tonic-gate $type = 'hyperlink'; 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate # must be an item or a "malformed" section (without "") 379*0Sstevel@tonic-gate else { 380*0Sstevel@tonic-gate $node = $_; 381*0Sstevel@tonic-gate $type = 'item'; 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate # collapse whitespace in nodes 384*0Sstevel@tonic-gate $node =~ s/\s+/ /gs; 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate # empty alternative text expands to node name 387*0Sstevel@tonic-gate if(defined $alttext) { 388*0Sstevel@tonic-gate if(!length($alttext)) { 389*0Sstevel@tonic-gate $alttext = $node | $page; 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate else { 393*0Sstevel@tonic-gate $alttext = ''; 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate if($page =~ /[(]\w*[)]$/) { 397*0Sstevel@tonic-gate $self->warning("(section) in '$page' deprecated"); 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate if(!$quoted && $node =~ m:[|/]:) { 400*0Sstevel@tonic-gate $self->warning("node '$node' contains non-escaped | or /"); 401*0Sstevel@tonic-gate } 402*0Sstevel@tonic-gate if($alttext =~ m:[|/]:) { 403*0Sstevel@tonic-gate $self->warning("alternative text '$node' contains non-escaped | or /"); 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate $self->{-page} = $page; 406*0Sstevel@tonic-gate $self->{-node} = $node; 407*0Sstevel@tonic-gate $self->{-alttext} = $alttext; 408*0Sstevel@tonic-gate #warn "DEBUG: page=$page section=$section item=$item alttext=$alttext\n"; 409*0Sstevel@tonic-gate $self->{-type} = $type; 410*0Sstevel@tonic-gate $self->_construct_text(); 411*0Sstevel@tonic-gate 1; 412*0Sstevel@tonic-gate} 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gatesub _construct_text { 415*0Sstevel@tonic-gate my $self = shift; 416*0Sstevel@tonic-gate my $alttext = $self->alttext(); 417*0Sstevel@tonic-gate my $type = $self->type(); 418*0Sstevel@tonic-gate my $section = $self->node(); 419*0Sstevel@tonic-gate my $page = $self->page(); 420*0Sstevel@tonic-gate my $page_ext = ''; 421*0Sstevel@tonic-gate $page =~ s/([(]\w*[)])$// && ($page_ext = $1); 422*0Sstevel@tonic-gate if($alttext) { 423*0Sstevel@tonic-gate $self->{_text} = $alttext; 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate elsif($type eq 'hyperlink') { 426*0Sstevel@tonic-gate $self->{_text} = $section; 427*0Sstevel@tonic-gate } 428*0Sstevel@tonic-gate else { 429*0Sstevel@tonic-gate $self->{_text} = ($section || '') . 430*0Sstevel@tonic-gate (($page && $section) ? ' in ' : '') . 431*0Sstevel@tonic-gate "$page$page_ext"; 432*0Sstevel@tonic-gate } 433*0Sstevel@tonic-gate # for being marked up later 434*0Sstevel@tonic-gate # use the non-standard markers P<> and Q<>, so that the resulting 435*0Sstevel@tonic-gate # text can be parsed by the translators. It's their job to put 436*0Sstevel@tonic-gate # the correct hypertext around the linktext 437*0Sstevel@tonic-gate if($alttext) { 438*0Sstevel@tonic-gate $self->{_markup} = "Q<$alttext>"; 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate elsif($type eq 'hyperlink') { 441*0Sstevel@tonic-gate $self->{_markup} = "Q<$section>"; 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate else { 444*0Sstevel@tonic-gate $self->{_markup} = (!$section ? '' : "Q<$section>") . 445*0Sstevel@tonic-gate ($page ? ($section ? ' in ':'') . "P<$page>$page_ext" : ''); 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate} 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate=item $link-E<gt>markup($string) 450*0Sstevel@tonic-gate 451*0Sstevel@tonic-gateSet/retrieve the textual value of the link. This string contains special 452*0Sstevel@tonic-gatemarkers C<PE<lt>E<gt>> and C<QE<lt>E<gt>> that should be expanded by the 453*0Sstevel@tonic-gatetranslator's interior sequence expansion engine to the 454*0Sstevel@tonic-gateformatter-specific code to highlight/activate the hyperlink. The details 455*0Sstevel@tonic-gatehave to be implemented in the translator. 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate=cut 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate#' retrieve/set markuped text 460*0Sstevel@tonic-gatesub markup { 461*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{_markup} = $_[1]) : $_[0]->{_markup}; 462*0Sstevel@tonic-gate} 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate=item $link-E<gt>text() 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gateThis method returns the textual representation of the hyperlink as above, 467*0Sstevel@tonic-gatebut without markers (read only). Depending on the link type this is one of 468*0Sstevel@tonic-gatethe following alternatives (the + and * denote the portions of the text 469*0Sstevel@tonic-gatethat are marked up): 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate +perl+ L<perl> 472*0Sstevel@tonic-gate *$|* in +perlvar+ L<perlvar/$|> 473*0Sstevel@tonic-gate *OPTIONS* in +perldoc+ L<perldoc/"OPTIONS"> 474*0Sstevel@tonic-gate *DESCRIPTION* L<"DESCRIPTION"> 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate=cut 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate# The complete link's text 479*0Sstevel@tonic-gatesub text { 480*0Sstevel@tonic-gate $_[0]->{_text}; 481*0Sstevel@tonic-gate} 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate=item $link-E<gt>warning() 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gateAfter parsing, this method returns any warnings encountered during the 486*0Sstevel@tonic-gateparsing process. 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate=cut 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate# Set/retrieve warnings 491*0Sstevel@tonic-gatesub warning { 492*0Sstevel@tonic-gate my $self = shift; 493*0Sstevel@tonic-gate if(@_) { 494*0Sstevel@tonic-gate push(@{$self->{_warnings}}, @_); 495*0Sstevel@tonic-gate return @_; 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate return @{$self->{_warnings}}; 498*0Sstevel@tonic-gate} 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate=item $link-E<gt>file() 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate=item $link-E<gt>line() 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gateJust simple slots for storing information about the line and the file 505*0Sstevel@tonic-gatethe link was encountered in. Has to be filled in manually. 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate=cut 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate# The line in the file the link appears 510*0Sstevel@tonic-gatesub line { 511*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-line} = $_[1]) : $_[0]->{-line}; 512*0Sstevel@tonic-gate} 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate# The POD file name the link appears in 515*0Sstevel@tonic-gatesub file { 516*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-file} = $_[1]) : $_[0]->{-file}; 517*0Sstevel@tonic-gate} 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate=item $link-E<gt>page() 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gateThis method sets or returns the POD page this link points to. 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate=cut 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate# The POD page the link appears on 526*0Sstevel@tonic-gatesub page { 527*0Sstevel@tonic-gate if (@_ > 1) { 528*0Sstevel@tonic-gate $_[0]->{-page} = $_[1]; 529*0Sstevel@tonic-gate $_[0]->_construct_text(); 530*0Sstevel@tonic-gate } 531*0Sstevel@tonic-gate $_[0]->{-page}; 532*0Sstevel@tonic-gate} 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate=item $link-E<gt>node() 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gateAs above, but the destination node text of the link. 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate=cut 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate# The link destination 541*0Sstevel@tonic-gatesub node { 542*0Sstevel@tonic-gate if (@_ > 1) { 543*0Sstevel@tonic-gate $_[0]->{-node} = $_[1]; 544*0Sstevel@tonic-gate $_[0]->_construct_text(); 545*0Sstevel@tonic-gate } 546*0Sstevel@tonic-gate $_[0]->{-node}; 547*0Sstevel@tonic-gate} 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gate=item $link-E<gt>alttext() 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gateSets or returns an alternative text specified in the link. 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate=cut 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate# Potential alternative text 556*0Sstevel@tonic-gatesub alttext { 557*0Sstevel@tonic-gate if (@_ > 1) { 558*0Sstevel@tonic-gate $_[0]->{-alttext} = $_[1]; 559*0Sstevel@tonic-gate $_[0]->_construct_text(); 560*0Sstevel@tonic-gate } 561*0Sstevel@tonic-gate $_[0]->{-alttext}; 562*0Sstevel@tonic-gate} 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate=item $link-E<gt>type() 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gateThe node type, either C<section> or C<item>. As an unofficial type, 567*0Sstevel@tonic-gatethere is also C<hyperlink>, derived from e.g. C<LE<lt>http://perl.comE<gt>> 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate=cut 570*0Sstevel@tonic-gate 571*0Sstevel@tonic-gate# The type: item or headn 572*0Sstevel@tonic-gatesub type { 573*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-type} = $_[1]) : $_[0]->{-type}; 574*0Sstevel@tonic-gate} 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate=item $link-E<gt>link() 577*0Sstevel@tonic-gate 578*0Sstevel@tonic-gateReturns the link as contents of C<LE<lt>E<gt>>. Reciprocal to B<parse()>. 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate=back 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate=cut 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate# The link itself 585*0Sstevel@tonic-gatesub link { 586*0Sstevel@tonic-gate my $self = shift; 587*0Sstevel@tonic-gate my $link = $self->page() || ''; 588*0Sstevel@tonic-gate if($self->node()) { 589*0Sstevel@tonic-gate my $node = $self->node(); 590*0Sstevel@tonic-gate $text =~ s/\|/E<verbar>/g; 591*0Sstevel@tonic-gate $text =~ s:/:E<sol>:g; 592*0Sstevel@tonic-gate if($self->type() eq 'section') { 593*0Sstevel@tonic-gate $link .= ($link ? '/' : '') . '"' . $node . '"'; 594*0Sstevel@tonic-gate } 595*0Sstevel@tonic-gate elsif($self->type() eq 'hyperlink') { 596*0Sstevel@tonic-gate $link = $self->node(); 597*0Sstevel@tonic-gate } 598*0Sstevel@tonic-gate else { # item 599*0Sstevel@tonic-gate $link .= '/' . $node; 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate if($self->alttext()) { 603*0Sstevel@tonic-gate my $text = $self->alttext(); 604*0Sstevel@tonic-gate $text =~ s/\|/E<verbar>/g; 605*0Sstevel@tonic-gate $text =~ s:/:E<sol>:g; 606*0Sstevel@tonic-gate $link = "$text|$link"; 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate $link; 609*0Sstevel@tonic-gate} 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gatesub _invalid_link { 612*0Sstevel@tonic-gate my ($msg) = @_; 613*0Sstevel@tonic-gate # this sets @_ 614*0Sstevel@tonic-gate #eval { die "$msg\n" }; 615*0Sstevel@tonic-gate #chomp $@; 616*0Sstevel@tonic-gate $@ = $msg; # this seems to work, too! 617*0Sstevel@tonic-gate undef; 618*0Sstevel@tonic-gate} 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 621*0Sstevel@tonic-gate# Pod::Cache 622*0Sstevel@tonic-gate# 623*0Sstevel@tonic-gate# class to hold POD page details 624*0Sstevel@tonic-gate#----------------------------------------------------------------------------- 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gatepackage Pod::Cache; 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate=head2 Pod::Cache 629*0Sstevel@tonic-gate 630*0Sstevel@tonic-gateB<Pod::Cache> holds information about a set of POD documents, 631*0Sstevel@tonic-gateespecially the nodes for hyperlinks. 632*0Sstevel@tonic-gateThe following methods are available: 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gate=over 4 635*0Sstevel@tonic-gate 636*0Sstevel@tonic-gate=item Pod::Cache-E<gt>new() 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gateCreate a new cache object. This object can hold an arbitrary number of 639*0Sstevel@tonic-gatePOD documents of class Pod::Cache::Item. 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate=cut 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gatesub new { 644*0Sstevel@tonic-gate my $this = shift; 645*0Sstevel@tonic-gate my $class = ref($this) || $this; 646*0Sstevel@tonic-gate my $self = []; 647*0Sstevel@tonic-gate bless $self, $class; 648*0Sstevel@tonic-gate return $self; 649*0Sstevel@tonic-gate} 650*0Sstevel@tonic-gate 651*0Sstevel@tonic-gate=item $cache-E<gt>item() 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gateAdd a new item to the cache. Without arguments, this method returns a 654*0Sstevel@tonic-gatelist of all cache elements. 655*0Sstevel@tonic-gate 656*0Sstevel@tonic-gate=cut 657*0Sstevel@tonic-gate 658*0Sstevel@tonic-gatesub item { 659*0Sstevel@tonic-gate my ($self,%param) = @_; 660*0Sstevel@tonic-gate if(%param) { 661*0Sstevel@tonic-gate my $item = Pod::Cache::Item->new(%param); 662*0Sstevel@tonic-gate push(@$self, $item); 663*0Sstevel@tonic-gate return $item; 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate else { 666*0Sstevel@tonic-gate return @{$self}; 667*0Sstevel@tonic-gate } 668*0Sstevel@tonic-gate} 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate=item $cache-E<gt>find_page($name) 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gateLook for a POD document named C<$name> in the cache. Returns the 673*0Sstevel@tonic-gatereference to the corresponding Pod::Cache::Item object or undef if 674*0Sstevel@tonic-gatenot found. 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gate=back 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gate=cut 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gatesub find_page { 681*0Sstevel@tonic-gate my ($self,$page) = @_; 682*0Sstevel@tonic-gate foreach(@$self) { 683*0Sstevel@tonic-gate if($_->page() eq $page) { 684*0Sstevel@tonic-gate return $_; 685*0Sstevel@tonic-gate } 686*0Sstevel@tonic-gate } 687*0Sstevel@tonic-gate undef; 688*0Sstevel@tonic-gate} 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gatepackage Pod::Cache::Item; 691*0Sstevel@tonic-gate 692*0Sstevel@tonic-gate=head2 Pod::Cache::Item 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gateB<Pod::Cache::Item> holds information about individual POD documents, 695*0Sstevel@tonic-gatethat can be grouped in a Pod::Cache object. 696*0Sstevel@tonic-gateIt is intended to hold information about the hyperlink nodes of POD 697*0Sstevel@tonic-gatedocuments. 698*0Sstevel@tonic-gateThe following methods are available: 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate=over 4 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate=item Pod::Cache::Item-E<gt>new() 703*0Sstevel@tonic-gate 704*0Sstevel@tonic-gateCreate a new object. 705*0Sstevel@tonic-gate 706*0Sstevel@tonic-gate=cut 707*0Sstevel@tonic-gate 708*0Sstevel@tonic-gatesub new { 709*0Sstevel@tonic-gate my $this = shift; 710*0Sstevel@tonic-gate my $class = ref($this) || $this; 711*0Sstevel@tonic-gate my %params = @_; 712*0Sstevel@tonic-gate my $self = {%params}; 713*0Sstevel@tonic-gate bless $self, $class; 714*0Sstevel@tonic-gate $self->initialize(); 715*0Sstevel@tonic-gate return $self; 716*0Sstevel@tonic-gate} 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gatesub initialize { 719*0Sstevel@tonic-gate my $self = shift; 720*0Sstevel@tonic-gate $self->{-nodes} = [] unless(defined $self->{-nodes}); 721*0Sstevel@tonic-gate} 722*0Sstevel@tonic-gate 723*0Sstevel@tonic-gate=item $cacheitem-E<gt>page() 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gateSet/retrieve the POD document name (e.g. "Pod::Parser"). 726*0Sstevel@tonic-gate 727*0Sstevel@tonic-gate=cut 728*0Sstevel@tonic-gate 729*0Sstevel@tonic-gate# The POD page 730*0Sstevel@tonic-gatesub page { 731*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-page} = $_[1]) : $_[0]->{-page}; 732*0Sstevel@tonic-gate} 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gate=item $cacheitem-E<gt>description() 735*0Sstevel@tonic-gate 736*0Sstevel@tonic-gateSet/retrieve the POD short description as found in the C<=head1 NAME> 737*0Sstevel@tonic-gatesection. 738*0Sstevel@tonic-gate 739*0Sstevel@tonic-gate=cut 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate# The POD description, taken out of NAME if present 742*0Sstevel@tonic-gatesub description { 743*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-description} = $_[1]) : $_[0]->{-description}; 744*0Sstevel@tonic-gate} 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate=item $cacheitem-E<gt>path() 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gateSet/retrieve the POD file storage path. 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate=cut 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate# The file path 753*0Sstevel@tonic-gatesub path { 754*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-path} = $_[1]) : $_[0]->{-path}; 755*0Sstevel@tonic-gate} 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate=item $cacheitem-E<gt>file() 758*0Sstevel@tonic-gate 759*0Sstevel@tonic-gateSet/retrieve the POD file name. 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate=cut 762*0Sstevel@tonic-gate 763*0Sstevel@tonic-gate# The POD file name 764*0Sstevel@tonic-gatesub file { 765*0Sstevel@tonic-gate return (@_ > 1) ? ($_[0]->{-file} = $_[1]) : $_[0]->{-file}; 766*0Sstevel@tonic-gate} 767*0Sstevel@tonic-gate 768*0Sstevel@tonic-gate=item $cacheitem-E<gt>nodes() 769*0Sstevel@tonic-gate 770*0Sstevel@tonic-gateAdd a node (or a list of nodes) to the document's node list. Note that 771*0Sstevel@tonic-gatethe order is kept, i.e. start with the first node and end with the last. 772*0Sstevel@tonic-gateIf no argument is given, the current list of nodes is returned in the 773*0Sstevel@tonic-gatesame order the nodes have been added. 774*0Sstevel@tonic-gateA node can be any scalar, but usually is a pair of node string and 775*0Sstevel@tonic-gateunique id for the C<find_node> method to work correctly. 776*0Sstevel@tonic-gate 777*0Sstevel@tonic-gate=cut 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate# The POD nodes 780*0Sstevel@tonic-gatesub nodes { 781*0Sstevel@tonic-gate my ($self,@nodes) = @_; 782*0Sstevel@tonic-gate if(@nodes) { 783*0Sstevel@tonic-gate push(@{$self->{-nodes}}, @nodes); 784*0Sstevel@tonic-gate return @nodes; 785*0Sstevel@tonic-gate } 786*0Sstevel@tonic-gate else { 787*0Sstevel@tonic-gate return @{$self->{-nodes}}; 788*0Sstevel@tonic-gate } 789*0Sstevel@tonic-gate} 790*0Sstevel@tonic-gate 791*0Sstevel@tonic-gate=item $cacheitem-E<gt>find_node($name) 792*0Sstevel@tonic-gate 793*0Sstevel@tonic-gateLook for a node or index entry named C<$name> in the object. 794*0Sstevel@tonic-gateReturns the unique id of the node (i.e. the second element of the array 795*0Sstevel@tonic-gatestored in the node arry) or undef if not found. 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate=cut 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gatesub find_node { 800*0Sstevel@tonic-gate my ($self,$node) = @_; 801*0Sstevel@tonic-gate my @search; 802*0Sstevel@tonic-gate push(@search, @{$self->{-nodes}}) if($self->{-nodes}); 803*0Sstevel@tonic-gate push(@search, @{$self->{-idx}}) if($self->{-idx}); 804*0Sstevel@tonic-gate foreach(@search) { 805*0Sstevel@tonic-gate if($_->[0] eq $node) { 806*0Sstevel@tonic-gate return $_->[1]; # id 807*0Sstevel@tonic-gate } 808*0Sstevel@tonic-gate } 809*0Sstevel@tonic-gate undef; 810*0Sstevel@tonic-gate} 811*0Sstevel@tonic-gate 812*0Sstevel@tonic-gate=item $cacheitem-E<gt>idx() 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gateAdd an index entry (or a list of them) to the document's index list. Note that 815*0Sstevel@tonic-gatethe order is kept, i.e. start with the first node and end with the last. 816*0Sstevel@tonic-gateIf no argument is given, the current list of index entries is returned in the 817*0Sstevel@tonic-gatesame order the entries have been added. 818*0Sstevel@tonic-gateAn index entry can be any scalar, but usually is a pair of string and 819*0Sstevel@tonic-gateunique id. 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate=back 822*0Sstevel@tonic-gate 823*0Sstevel@tonic-gate=cut 824*0Sstevel@tonic-gate 825*0Sstevel@tonic-gate# The POD index entries 826*0Sstevel@tonic-gatesub idx { 827*0Sstevel@tonic-gate my ($self,@idx) = @_; 828*0Sstevel@tonic-gate if(@idx) { 829*0Sstevel@tonic-gate push(@{$self->{-idx}}, @idx); 830*0Sstevel@tonic-gate return @idx; 831*0Sstevel@tonic-gate } 832*0Sstevel@tonic-gate else { 833*0Sstevel@tonic-gate return @{$self->{-idx}}; 834*0Sstevel@tonic-gate } 835*0Sstevel@tonic-gate} 836*0Sstevel@tonic-gate 837*0Sstevel@tonic-gate=head1 AUTHOR 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gatePlease report bugs using L<http://rt.cpan.org>. 840*0Sstevel@tonic-gate 841*0Sstevel@tonic-gateMarek Rouchal E<lt>marekr@cpan.orgE<gt>, borrowing 842*0Sstevel@tonic-gatea lot of things from L<pod2man> and L<pod2roff> as well as other POD 843*0Sstevel@tonic-gateprocessing tools by Tom Christiansen, Brad Appleton and Russ Allbery. 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate=head1 SEE ALSO 846*0Sstevel@tonic-gate 847*0Sstevel@tonic-gateL<pod2man>, L<pod2roff>, L<Pod::Parser>, L<Pod::Checker>, 848*0Sstevel@tonic-gateL<pod2html> 849*0Sstevel@tonic-gate 850*0Sstevel@tonic-gate=cut 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate1; 853