On Sun, Aug 05, 2001 at 03:26:25AM -0700, Russ Allbery wrote:
> Sean M Burke <[EMAIL PROTECTED]> writes:
> 
> > I know there must be a /simple/ way to make a Pod::ParseTree parse tree,
> > but I'm not seeing it.  In the 5,000 words of Pod::Parser's POD, there's
> > a long tractatus about ways to make subclasses that elaborate
> > (inarborate?) a Pod::ParseTree.  But in the end, it sort of handwaves
> > off to Pod::InputObjects -- whose documentation is, to put it
> > diplomatically, too much and yet not enough.
> 
> Er, not in the version that I have.  It specifically tells you how to do
> this up to and including giving you code to do it.  You override the key
> methods (command, verbatim, and textblock) to generate and set
> Pod::ParseTree options and then stash your tree somewhere.

Russ speaks the truth :-)

Also, see the following reply of mine to an earlier message
to this list back in April with similar example code:

| Date: Tue, 17 Apr 2001 17:29:46 -0500
| From: Brad Appleton <[EMAIL PROTECTED]>
| To: Matt Sergeant <[EMAIL PROTECTED]>
| Cc: "Sean M. Burke" <[EMAIL PROTECTED]>,
|       "[EMAIL PROTECTED]" <[EMAIL PROTECTED]>
| Subject: Re: pod2xml/xml2pod (Pod::PXML)
| Message-ID: <[EMAIL PROTECTED]>

On Tue, Apr 17, 2001 at 09:38:46PM +0100, Matt Sergeant wrote:
> There's a few things that I really hate about POD::Parser, the most
> significant thing is that it's impossible (or at least very difficult)
> to output the results to anything other than a file.

See the section "TREE-BASED PARSING" in the Pod::Parser PODs
where it describes this and gives some code snippets for a few
different high-level examples of how to do this. It doesn't
use print at all. It only uses "print" if you override the
command(), textblock(), and verbatim() methods to invoke print.
But Pod::Parse does not call print directly for standard output
(unless you use the raw defaults for those routines - which you
usually don't want). The TREE-BASED PARSING section in the PODs
gives a few simple examples for how to do this:

    package MyPodParserTree;

    @ISA = qw( Pod::Parser );

    my %ptopts = ( ... );  ## options for parse_text

    ...

    sub begin_pod {
        my $self = shift;
        $self->{'-paragraphs'} = [];  ## initialize paragraph list
    }

    sub command {
        my ($parser, $command, $paragraph, $line_num, $pod_para) = @_;
        my $ptree = $parser->parse_text({%ptopts}, $paragraph, ...);
        $pod_para->parse_tree( $ptree );  ## set parse-tree for this para
        push @{ $self->{'-paragraphs'} }, $pod_para;
    }

    sub verbatim {
        my ($parser, $paragraph, $line_num, $pod_para) = @_;
        push @{ $self->{'-paragraphs'} }, $pod_para;
    }

    sub textblock {
        my ($parser, $paragraph, $line_num, $pod_para) = @_;
        my $ptree = $parser->parse_text({%ptopts}, $paragraph, ...);
        $pod_para->parse_tree( $ptree );  ## set parse-tree for this para
        push @{ $self->{'-paragraphs'} }, $pod_para;
    }

    ...

    package main;
    ...
    my $parser = new MyPodParserTree(...);
    $parser->parse_from_file(...);
    my $paragraphs_ref = $parser->{'-paragraphs'};

If you want something more tree-like than an array to gather
your output, you can use the existing ParseTree object:

    package MyPodParserTree2;

    my %ptopts = ( ... );  ## options for parse_text

    ...

    sub begin_pod {
        my $self = shift;
        $self->{'-ptree'} = new Pod::ParseTree;  ## initialize parse-tree
    }

    sub parse_tree {
        ## convenience method to get/set the parse-tree for the entire POD
        ## and store it in this PodParser subclass instance
        (@_ > 1)  and  $_[0]->{'-ptree'} = $_[1];
        return $_[0]->{'-ptree'};
    }

    sub command {
        my ($parser, $command, $paragraph, $line_num, $pod_para) = @_;
        my $ptree = $parser->parse_text({%ptopts}, $paragraph, ...);
        $pod_para->parse_tree( $ptree );  ## set parse-tree for this para
        $parser->parse_tree()->append( $pod_para );
    }

    sub verbatim {
        my ($parser, $paragraph, $line_num, $pod_para) = @_;
        $parser->parse_tree()->append( $pod_para );
    }

    sub textblock {
        my ($parser, $paragraph, $line_num, $pod_para) = @_;
        my $ptree = $parser->parse_text({%ptopts}, $paragraph, ...);
        $pod_para->parse_tree( $ptree );  ## set parse-tree for this para
        $parser->parse_tree()->append( $pod_para );
    }

    ...
    package main;
    ...
    my $parser = new MyPodParserTree2(...);
    $parser->parse_from_file(...);
    my $ptree = $parser->parse_tree;
    ...

Now you have the entire POD document as one great big
parse-tree.  If desired, you can use the "-expand_seq"
to parse_text() to insert whole different kinds of objects
of your own choosing rather than parse-tree objects. Just
don't expect Pod::Parser to know what to do with them after
that. That will need to be in your code. Or, alternatively,
you can insert any object you like so long as it conforms to
the Pod::ParseTree interface.

So avoiding printing to a filehandle altogether shouldn't be so
bad in Pod::Parser if you are willing to build up the entire
parse-tree. If you still want to do it in "streaming style"
then I suppose you could do that on a paragraph by paragraph
basis.

Again, It all depends entirely on what you put into the
command(), verbatim(), and textblock() methods that you
override. If those don't call "print", than neither will
Pod::Parser (except for errors, but that can be overridden
too). You just need to define those methods to call either
parse_text (to return a parse-tree) or to call interporale
(to return a string) at your desire and decide what to do with
the result for that paragraph.

Granted - I'm sure you will probably still prefer Pod::Tree
to Pod::Parser, but do know that more support does exist
in Pod::Parser for what you are trying to do (if you can
manage to stick with reading the PODs long enough to get
to the last-section on tree-based parsing :-)

-- 
Brad Appleton <[EMAIL PROTECTED]>  http://www.bradapp.net/
  "And miles to go before I sleep." -- Robert Frost

Reply via email to