📄 parser.pm
字号:
############################################################################## Pod/Parser.pm -- package which defines a base class for parsing POD docs.## Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.# This file is part of "PodParser". PodParser is free software;# you can redistribute it and/or modify it under the same terms# as Perl itself.#############################################################################package Pod::Parser;use vars qw($VERSION);$VERSION = 1.12; ## Current version of this packagerequire 5.005; ## requires this Perl version or later#############################################################################=head1 NAMEPod::Parser - base class for creating POD filters and translators=head1 SYNOPSIS use Pod::Parser; package MyParser; @ISA = qw(Pod::Parser); sub command { my ($parser, $command, $paragraph, $line_num) = @_; ## Interpret the command and its text; sample actions might be: if ($command eq 'head1') { ... } elsif ($command eq 'head2') { ... } ## ... other commands and their actions my $out_fh = $parser->output_handle(); my $expansion = $parser->interpolate($paragraph, $line_num); print $out_fh $expansion; } sub verbatim { my ($parser, $paragraph, $line_num) = @_; ## Format verbatim paragraph; sample actions might be: my $out_fh = $parser->output_handle(); print $out_fh $paragraph; } sub textblock { my ($parser, $paragraph, $line_num) = @_; ## Translate/Format this block of text; sample actions might be: my $out_fh = $parser->output_handle(); my $expansion = $parser->interpolate($paragraph, $line_num); print $out_fh $expansion; } sub interior_sequence { my ($parser, $seq_command, $seq_argument) = @_; ## Expand an interior sequence; sample actions might be: return "*$seq_argument*" if ($seq_command eq 'B'); return "`$seq_argument'" if ($seq_command eq 'C'); return "_${seq_argument}_'" if ($seq_command eq 'I'); ## ... other sequence commands and their resulting text } package main; ## Create a parser object and have it parse file whose name was ## given on the command-line (use STDIN if no files were given). $parser = new MyParser(); $parser->parse_from_filehandle(\*STDIN) if (@ARGV == 0); for (@ARGV) { $parser->parse_from_file($_); }=head1 REQUIRESperl5.005, Pod::InputObjects, Exporter, Symbol, Carp=head1 EXPORTSNothing.=head1 DESCRIPTIONB<Pod::Parser> is a base class for creating POD filters and translators.It handles most of the effort involved with parsing the POD sectionsfrom an input stream, leaving subclasses free to be concerned only withperforming the actual translation of text.B<Pod::Parser> parses PODs, and makes method calls to handle the variouscomponents of the POD. Subclasses of B<Pod::Parser> override these methodsto translate the POD into whatever output format they desire.=head1 QUICK OVERVIEWTo create a POD filter for translating POD documentation into some otherformat, you create a subclass of B<Pod::Parser> which typically overridesjust the base class implementation for the following methods:=over 2=item *B<command()>=item *B<verbatim()>=item *B<textblock()>=item *B<interior_sequence()>=backYou may also want to override the B<begin_input()> and B<end_input()>methods for your subclass (to perform any needed per-file and/orper-document initialization or cleanup).If you need to perform any preprocesssing of input before it is parsedyou may want to override one or more of B<preprocess_line()> and/orB<preprocess_paragraph()>.Sometimes it may be necessary to make more than one pass over the inputfiles. If this is the case you have several options. You can make thefirst pass using B<Pod::Parser> and override your methods to store theintermediate results in memory somewhere for the B<end_pod()> method toprocess. You could use B<Pod::Parser> for several passes with anappropriate state variable to control the operation for each pass. Ifyour input source can't be reset to start at the beginning, you canstore it in some other structure as a string or an array and have thatstructure implement a B<getline()> method (which is all thatB<parse_from_filehandle()> uses to read input).Feel free to add any member data fields you need to keep track of thingslike current font, indentation, horizontal or vertical position, orwhatever else you like. Be sure to read L<"PRIVATE METHODS AND DATA">to avoid name collisions.For the most part, the B<Pod::Parser> base class should be able todo most of the input parsing for you and leave you free to worry abouthow to intepret the commands and translate the result.Note that all we have described here in this quick overview is thesimplest most straightforward use of B<Pod::Parser> to do stream-basedparsing. It is also possible to use the B<Pod::Parser::parse_text> functionto do more sophisticated tree-based parsing. See L<"TREE-BASED PARSING">.=head1 PARSING OPTIONSA I<parse-option> is simply a named option of B<Pod::Parser> with avalue that corresponds to a certain specified behavior. These variousbehaviors of B<Pod::Parser> may be enabled/disabled by setting oror unsetting one or more I<parse-options> using the B<parseopts()> method.The set of currently accepted parse-options is as follows:=over 3=item B<-want_nonPODs> (default: unset)Normally (by default) B<Pod::Parser> will only provide access tothe POD sections of the input. Input paragraphs that are not partof the POD-format documentation are not made available to the caller(not even using B<preprocess_paragraph()>). Setting this option to anon-empty, non-zero value will allow B<preprocess_paragraph()> to seenon-POD sections of the input as well as POD sections. The B<cutting()>method can be used to determine if the corresponding paragraph is a PODparagraph, or some other input paragraph.=item B<-process_cut_cmd> (default: unset)Normally (by default) B<Pod::Parser> handles the C<=cut> POD directiveby itself and does not pass it on to the caller for processing. Settingthis option to a non-empty, non-zero value will cause B<Pod::Parser> topass the C<=cut> directive to the caller just like any other POD command(and hence it may be processed by the B<command()> method).B<Pod::Parser> will still interpret the C<=cut> directive to mean that"cutting mode" has been (re)entered, but the caller will get a chanceto capture the actual C<=cut> paragraph itself for whatever purposeit desires.=item B<-warnings> (default: unset)Normally (by default) B<Pod::Parser> recognizes a bare minimum ofpod syntax errors and warnings and issues diagnostic messagesfor errors, but not for warnings. (Use B<Pod::Checker> to do morethorough checking of POD syntax.) Setting this option to a non-empty,non-zero value will cause B<Pod::Parser> to issue diagnostics forthe few warnings it recognizes as well as the errors.=backPlease see L<"parseopts()"> for a complete description of the interfacefor the setting and unsetting of parse-options.=cut#############################################################################use vars qw(@ISA);use strict;#use diagnostics;use Pod::InputObjects;use Carp;use Exporter;BEGIN { if ($] < 5.6) { require Symbol; import Symbol; }}@ISA = qw(Exporter);## These "variables" are used as local "glob aliases" for performanceuse vars qw(%myData %myOpts @input_stack);#############################################################################=head1 RECOMMENDED SUBROUTINE/METHOD OVERRIDESB<Pod::Parser> provides several methods which most subclasses will probablywant to override. These methods are as follows:=cut##---------------------------------------------------------------------------=head1 B<command()> $parser->command($cmd,$text,$line_num,$pod_para);This method should be overridden by subclasses to take the appropriateaction when a POD command paragraph (denoted by a line beginning with"=") is encountered. When such a POD directive is seen in the input,this method is called and is passed:=over 3=item C<$cmd>the name of the command for this POD paragraph=item C<$text>the paragraph text for the given POD paragraph command.=item C<$line_num>the line-number of the beginning of the paragraph=item C<$pod_para>a reference to a C<Pod::Paragraph> object which contains furtherinformation about the paragraph command (see L<Pod::InputObjects>for details).=backB<Note> that this method I<is> called for C<=pod> paragraphs.The base class implementation of this method simply treats the raw PODcommand as normal block of paragraph text (invoking the B<textblock()>method with the command paragraph).=cutsub command { my ($self, $cmd, $text, $line_num, $pod_para) = @_; ## Just treat this like a textblock $self->textblock($pod_para->raw_text(), $line_num, $pod_para);}##---------------------------------------------------------------------------=head1 B<verbatim()> $parser->verbatim($text,$line_num,$pod_para);This method may be overridden by subclasses to take the appropriateaction when a block of verbatim text is encountered. It is passed thefollowing parameters:=over 3=item C<$text>the block of text for the verbatim paragraph=item C<$line_num>the line-number of the beginning of the paragraph=item C<$pod_para>a reference to a C<Pod::Paragraph> object which contains furtherinformation about the paragraph (see L<Pod::InputObjects>for details).=backThe base class implementation of this method simply prints the textblock(unmodified) to the output filehandle.=cutsub verbatim { my ($self, $text, $line_num, $pod_para) = @_; my $out_fh = $self->{_OUTPUT}; print $out_fh $text;}##---------------------------------------------------------------------------=head1 B<textblock()> $parser->textblock($text,$line_num,$pod_para);This method may be overridden by subclasses to take the appropriateaction when a normal block of POD text is encountered (although the baseclass method will usually do what you want). It is passed the followingparameters:=over 3=item C<$text>the block of text for the a POD paragraph=item C<$line_num>the line-number of the beginning of the paragraph=item C<$pod_para>a reference to a C<Pod::Paragraph> object which contains furtherinformation about the paragraph (see L<Pod::InputObjects>for details).=backIn order to process interior sequences, subclasses implementations ofthis method will probably want to invoke either B<interpolate()> orB<parse_text()>, passing it the text block C<$text>, and the correspondingline number in C<$line_num>, and then perform any desired processing uponthe returned result.The base class implementation of this method simply prints the text blockas it occurred in the input stream).=cutsub textblock {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -