################################################################################### # # Embperl - Copyright (c) 1997-2005 Gerald Richter / ECOS # # You may distribute under the terms of either the GNU General Public # License or the Artistic License, as specified in the Perl README file. # # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # $Id: POD.pm 355574 2005-12-09 18:15:54Z richter $ # ################################################################################### package Embperl::Syntax::POD ; use Embperl::Syntax (':types') ; use Embperl::Syntax::EmbperlBlocks ; use strict ; use vars qw{@ISA %Tags %Format %Escape %Para %ParaItem %ParaTitle %List %Search %SearchInside %ListStart %CDATA %Skip} ; @ISA = qw(Embperl::Syntax::EmbperlBlocks) ; ################################################################################### # # Methods # ################################################################################### # --------------------------------------------------------------------------------- # # Create new Syntax Object # # --------------------------------------------------------------------------------- sub new { my $self = shift ; #$self = Embperl::Syntax::EmbperlBlocks::new ($self, 1) ; $self = Embperl::Syntax::new ($self, 1) ; if (!$self -> {-PODTags}) { $self -> {-PODTags} = $self -> CloneHash (\%Search) ; $self -> AddToRoot ($self -> {-PODTags}) ; $self -> AddInitCode (undef, '$escmode=0;$_ep_node=%$x%+1;print OUT ""; $escmode=15; ', undef) ; #$self -> AddToRoot ({'-defnodetype' => ntypText,}) ; #$self -> {-PODCmds} = $self -> {-PODTags}{'POD Command'}{'follow'} ; #Init ($self) ; } return $self ; } # --------------------------------------------------------------------------------- # # Add new POD command # # --------------------------------------------------------------------------------- sub AddPODCmd { my ($self, $cmdname, $name) = @_ ; my $ttfollow = $self -> {-PODCmds} ; my $tag = $ttfollow -> {$cmdname} = { 'text' => $cmdname, 'nodetype' => ntypStartEndTag, 'cdatatype' => ntypText, 'removespaces' => 72, 'inside' => \%Format, } ; $tag -> {nodename} = $name if ($name) ; return $tag ; } sub AddPODStartEnd { my ($self, $start, $end, $name) = @_ ; my $ttfollow = $self -> {-PODCmds} ; my $stag = $ttfollow -> {$start} = { 'text' => $start, 'nodetype' => ntypStartTag, 'cdatatype' => 0, 'removespaces' => 72, } ; $stag -> {nodename} = $name if ($name) ; my $etag = $ttfollow -> {$end} = { 'text' => $end, 'nodetype' => ntypEndTag, 'cdatatype' => 0, 'starttag' => $start, 'removespaces' => 72, } ; return $stag ; } ################################################################################### # # Definitions for POD # ################################################################################### sub Init { my ($self) = @_ ; #$self -> AddPODCmd ('head1') ; $self -> AddPODCmd ('head2') ; $self -> AddPODCmd ('head3') ; $self -> AddPODStartEnd ('over', 'back', 'list') ; $self -> AddPODStartEnd ('pod', 'cut') ; $self -> AddPODCmd ('item') ; $self -> AddPODCmd ('item *', 'bulletitem') ; } %Escape = ( '-lsearch' => 1, 'POD Escape' => { 'text' => '<', 'end' => '>', 'nodename' => ':::>:<', 'nodetype' => ntypStartEndTag, }, 'POD Escape &' => { 'text' => '&', 'nodename' => ':::&', 'nodetype' => ntypTag, }, ) ; my %Escape2 = ( 'POD Escape <' => { 'text' => '<', 'nodename' => ':::<', 'nodetype' => ntypTag, }, 'POD Escape >' => { 'text' => '>', 'nodename' => ':::>', 'nodetype' => ntypTag, }, 'POD Escape &' => { 'text' => '&', 'nodename' => ':::&', 'nodetype' => ntypTag, }, ) ; %Format = ( '-lsearch' => 1, '-defnodetype' => ntypText, 'POD Format B' => { 'text' => 'B<', 'end' => '>', 'nodename' => 'strong', 'nodetype' => ntypStartEndTag, }, 'POD Format C' => { 'text' => 'C<', 'end' => '>', 'nodename' => 'code', 'nodetype' => ntypStartEndTag, }, 'POD Format F' => { 'text' => 'F<', 'end' => '>', 'nodename' => 'code', 'nodetype' => ntypStartEndTag, }, 'POD Format I' => { 'text' => 'I<', 'end' => '>', 'nodename' => 'emphasis', 'nodetype' => ntypStartEndTag, }, 'POD Format U' => { 'text' => 'U<', 'end' => '>', 'nodename' => 'underline', 'nodetype' => ntypStartEndTag, }, 'POD Format L' => { 'text' => 'L<', 'end' => '>', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, 'inside' => { -lsearch => 1, '|' => { 'text' => '|', 'end' => '>', 'donteat' => 2, 'follow' => { 'Quote ""' => { 'text' => '"', 'end' => '"', 'nodename' => 'uri', 'nodetype' => ntypAttr, 'cdatatype' => ntypAttrValue, 'addflags' => aflgSingleQuote, }, 'Quote \'\'' => { 'text' => '\'', 'end' => '\'', 'nodename' => 'uri', 'nodetype' => ntypAttr, 'cdatatype' => ntypAttrValue, 'addflags' => aflgSingleQuote, }, 'all' => { 'matchall' => 1, 'nodename' => 'uri', 'nodetype' => ntypAttr, 'cdatatype' => ntypAttrValue, 'donteat' => 2, 'addflags' => aflgSingleQuote, }, }, }, 'Quote ""' => { 'text' => '"', 'end' => '"', 'nodetype' => 0, 'cdatatype' => ntypText, }, 'Quote \'\'' => { 'text' => '\'', 'end' => '\'', 'nodetype' => 0, 'cdatatype' => ntypText, }, '|1' => { 'text' => '|', 'end' => '>', 'nodename' => 'uri', 'nodetype' => ntypAttr, 'cdatatype' => ntypAttrValue, 'donteat' => 2, 'addflags' => aflgSingleQuote, }, }, }, 'POD Format L 2' => { 'text' => 'L<', 'end' => '>', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, }, 'POD Format #' => { 'text' => '#<', 'end' => '>', 'nodename' => 'id', 'nodetype' => ntypAttr, 'cdatatype' => ntypAttrValue, 'removespaces' => 72, }, 'http link' => { 'text' => 'http://', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, 'contains' => '/.-:~?&=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789', 'cdatatype' => ntypText, 'donteat' => 1, }, 'ftp link' => { 'text' => 'ftp://', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, 'contains' => '/.-:~?&=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789', 'cdatatype' => ntypText, 'donteat' => 1, }, ) ; my $paraend = "\n\n" ; %List = ( '-lsearch' => 1, '-defnodetype' => ntypText, 'liststart' => { 'text' => '=over', 'end' => '=back', 'nodetype' => ntypStartEndTag, 'cdatatype' => 0, 'removespaces' => 2, 'nodename' => 'list', 'inside' => \%List, }, 'listend' => { 'text' => '=back', 'end' => "\n", 'nodetype' => ntypEndTag, 'cdatatype' => 0, 'nodename' => 'list', 'removespaces' => 72, 'exitinside' => 1, }, 'item*' => { 'text' => '=item *', 'end' => '=item *', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'item', 'removespaces' => 2, 'inside' => \%ParaItem, }, 'item' => { 'text' => '=item', 'end' => '=item', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'item', 'removespaces' => 2, 'inside' => \%ParaItem, }, ) ; %ListStart = ( %List, 'title' => { 'matchall' => -1, # only match first time after =over 'text' => "\x02", # gives sort order 'end' => "\n", # eat until end of line 'cdatatype' => 0, 'nodetype' => 0, }, ) ; %CDATA = ( '-lsearch' => 1, 'http link' => { 'text' => 'http://', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, 'contains' => '/.-:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789', 'cdatatype' => ntypText, 'donteat' => 1, }, 'ftp link' => { 'text' => 'ftp://', 'nodename' => 'xlink', 'nodetype' => ntypStartEndTag, 'contains' => '/.-:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789', 'cdatatype' => ntypText, 'donteat' => 1, }, 'verbatim2' => { 'text' => " ", 'end' => $paraend, 'cdatatype' => ntypCDATA, 'nodename' => ':::', 'removespaces' => 0, #'inside' => { 'X' => { removespaces => 0, cdatatype => ntypCDATA }}, #'inside' => \%Format, 'nodetype' => ntypStartEndTag, 'donteat' => 3, }, ) ; %Skip = ( 'skip1' => { # 'text' => "\n", 'contains' => "\r\n", 'nodetype' => ntypTag, 'cdatatype' => 0, 'removespaces' => 0, 'nodename' => "!:\n", }, # 'skip2' => # { # 'text' => "\r", # 'contains' => "\r\n", # 'nodetype' => ntypTag, # 'cdatatype' => 0, # 'removespaces' => 0, # 'nodename' => "!:\n", # }, ) ; %Para = ( %List, 'skip' => { 'text' => "\n", 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 0, 'nodename' => "\n", }, 'skip2' => { 'text' => "\r", 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 0, 'nodename' => '', }, 'para' => { 'matchall' => 1, 'text' => "\0x01", # gives sort order 'end' => $paraend, 'cdatatype' => ntypText, 'nodename' => 'para', 'removespaces' => 72, 'inside' => \%Format, 'nodetype' => ntypStartEndTag, }, 'verbatim' => { 'text' => " ", 'end' => $paraend, 'cdatatype' => 0, 'nodename' => 'verbatim', 'removespaces' => 0, 'inside' => \%CDATA, 'nodetype' => ntypStartEndTag, 'donteat' => 1, }, 'pic' => { 'text' => '=pic', 'end' => $paraend, 'nodename' => 'pic', 'nodetype' => ntypStartEndTag, 'cdatatype' => ntypText, }, #%Skip, ) ; %ParaTitle = ( 'title' => { 'matchall' => -1, # only match first time after =head 'text' => "\x02", # gives sort order 'end' => $paraend, 'cdatatype' => ntypText, 'nodename' => 'title', 'removespaces' => 40, #72, 'inside' => \%Format, 'nodetype' => ntypStartEndTag, }, %Para, ) ; %ParaItem = ( %Para, 'itemtext' => { 'matchall' => -1, # only match first time after =head 'text' => "\x02", # gives sort order 'end' => $paraend, 'cdatatype' => ntypText, 'nodename' => 'itemtext', 'removespaces' => 72, 'inside' => \%Format, 'nodetype' => ntypStartEndTag, }, 'item*' => { 'text' => '=item *', 'nodename' => 'item', 'nodetype' => ntypEndTag, 'donteat' => 1, 'exitinside' => 1, }, 'item' => { 'text' => '=item', 'nodename' => 'item', 'nodetype' => ntypEndTag, 'donteat' => 1, 'exitinside' => 1, }, 'listend' => { 'text' => '=back', 'nodename' => 'item', 'nodetype' => ntypEndTag, 'donteat' => 1, 'exitinside' => 1, }, 'cut' => { 'text' => '=cut', 'nodetype' => 0, 'cdatatype' => 0, 'nodename' => '', 'inside' => \%SearchInside, }, ) ; %SearchInside = ( '-lsearch' => 1, '-defnodetype' => 0, 'start' => { 'text' => "\n=", 'donteat' => 1, 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 2, 'exitinside' => 1, }, ) ; %Tags = ( '-lsearch' => 1, '-defnodetype' => ntypText, 'head1name' => { 'text' => '=head1 NAME', 'end' => '=head1', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'head', 'removespaces' => 2, 'inside' => { '-lsearch' => 1, 'title' => { 'matchall' => -1, # only match first time after =head 'text' => "\x02", # gives sort order 'end' => $paraend, 'cdatatype' => ntypText, 'nodename' => 'title', 'removespaces' => 72, 'inside' => \%Format, 'nodetype' => ntypStartEndTag, }, }, }, 'head1' => { 'text' => '=head1', 'end' => '=head1', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'sect1', 'removespaces' => 2, 'inside' => { '-lsearch' => 1, %ParaTitle, 'head1' => { 'text' => '=head1', 'nodename' => 'sect1', 'nodetype' => ntypEndTag, 'donteat' => 1, 'exitinside' => 1, }, 'cut' => { 'text' => '=cut', 'nodename' => 'sect1', 'nodetype' => ntypEndTag, 'donteat' => 1, 'exitinside' => 1, }, 'head2' => { 'text' => '=head2', 'end' => '=head2', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'sect2', 'removespaces' => 2, 'inside' => { '-lsearch' => 1, %ParaTitle, 'head1' => { 'text' => '=head1', 'nodename' => 'sect2', 'nodetype' => ntypEndTag, 'cdatatype' => 0, 'donteat' => 1, 'exitinside' => 1, }, 'head2' => { 'text' => '=head2', 'nodetype' => ntypEndTag, 'nodename' => 'sect2', 'donteat' => 1, 'exitinside' => 1, }, 'cut' => { 'text' => '=cut', 'nodetype' => 0, 'cdatatype' => 0, 'nodename' => '', 'inside' => \%SearchInside, }, 'head3' => { 'text' => '=head3', 'end' => '=head3', 'donteat' => 2, 'nodetype' => ntypStartEndTag, 'nodename' => 'sect3', 'removespaces' => 2, 'inside' => { '-lsearch' => 1, %ParaTitle, 'head1' => { 'text' => '=head1', 'nodename' => 'sect3', 'nodetype' => ntypEndTag, 'cdatatype' => 0, 'donteat' => 1, 'exitinside' => 1, }, 'head2' => { 'text' => '=head2', 'nodetype' => ntypEndTag, 'cdatatype' => 0, 'nodename' => 'sect3', 'donteat' => 1, 'exitinside' => 1, }, 'head3' => { 'text' => '=head3', 'nodetype' => ntypEndTag, 'nodename' => 'sect3', 'donteat' => 1, 'exitinside' => 1, }, 'cut' => { 'text' => '=cut', 'nodetype' => 0, 'cdatatype' => 0, 'nodename' => '', 'inside' => \%SearchInside, }, }, }, }, }, }, }, 'cut' => { 'text' => '=cut', 'nodetype' => 0, 'cdatatype' => 0, 'exitinside' => 1, }, # %Para, ) ; %Search = ( '-lsearch' => 1, '-defnodetype' => 0, '-rootnode' => 'pod', 'start' => { 'text' => "\n=", 'donteat' => 1, 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 2, 'inside' => \%Tags }, 'startpod' => { 'text' => '=pod', 'end' => "\n", 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 2, 'inside' => \%Tags }, 'startpod2' => { 'text' => "\n=pod", 'end' => "\n", 'nodetype' => 0, 'cdatatype' => 0, 'removespaces' => 2, 'inside' => \%Tags }, ) ; 1; __END__ =pod =head1 NAME Embperl::Syntax::POD =head1 SYNOPSIS =head1 DESCRIPTION Class derived from Embperl::Syntax to convert Perl Plain Old Documentation (POD) files on the fly into XML. Used for generating the Embperl online documentation from the Embperl POD files. See to eg directory in the distribution for an example how to use it. =head1 TODO Documenation of the resulting XML format still has to be written... =head1 Methods I defines the following methods: =head2 Embperl::Syntax::POD -> new / $self -> new Create a new syntax class. This method should only be called inside a constructor of a derived class. =head2 AddPODCmd ($cmdname, $procinfo) Add a new POD command with name C<$cmdname> and use processor info from C<$procinfo>. See I for a definition of procinfo. =head2 AddPODCmdStartEnd ($cmdname, $endname, $procinfo) Add a new POD command with name C<$cmdname> and use processor info from C<$procinfo>. Addtionaly specify that a matching C<$endname> POD command must be found to end the block, that is started by this POD command. See I for a definition of procinfo. =head1 Author G. Richter (richter@dev.ecos.de) =head1 See Also Embperl::Syntax