Pod-Abstract

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

bin/paf
Changes
lib/Pod/Abstract.pm
lib/Pod/Abstract/BuildNode.pm
lib/Pod/Abstract/Filter.pm
lib/Pod/Abstract/Filter/add_podcmds.pm
lib/Pod/Abstract/Filter/clear_podcmds.pm
lib/Pod/Abstract/Filter/cut.pm
lib/Pod/Abstract/Filter/uncut.pm
lib/Pod/Abstract/Filter/overlay.pm
lib/Pod/Abstract/Filter/unoverlay.pm
lib/Pod/Abstract/Filter/sort.pm
lib/Pod/Abstract/Filter/summary.pm
lib/Pod/Abstract/Filter/find.pm
lib/Pod/Abstract/Filter/number_sections.pm
lib/Pod/Abstract/Node.pm
lib/Pod/Abstract/Parser.pm
lib/Pod/Abstract/Path.pm
lib/Pod/Abstract/Serial.pm
lib/Pod/Abstract/Tree.pm
Makefile.PL

bin/paf  view on Meta::CPAN

paf - Pod Abstract Filter. Transform Pod documents from the command line.

=head1 SYNOPSIS

 sh$>
  paf summary /usr/bin/paf
  paf add_podcmds SomeModule.pm
  paf sort -heading=METHODS Pod/Abstract/Node.pm # METHODS is default
  paf sort summary Pod/Abstract/Node.pm
  
  # See Pod::Abstract::Filter::overlay
  paf overlay sort cut clear_podcmds SomeClass.pm
  
  # -p will emit pod source, instead of spawning perldoc.
  paf -p sort Pod::Abstract::Node
  paf -p find hoist Pod::Abstract::Node

=head1 DESCRIPTION

Paf is a small but powerful, modular Pod filter and transformation
tool. It allows full round-trip transformation of Pod documents using
the Pod::Abstract library, with multiple filter chains without having

bin/paf  view on Meta::CPAN


=head2 clear_podcmds

Remove all =pod commands that are not ending cut blocks. This will
clean up documents that have been reduced using the C<cut> filter too.

=head2 cut

Remove all cut nodes, so that only the pod remains.

=head2 overlay

 paf overlay Source.pm

For overlay to work, there must be a C<begin :overlay/end :overlay>
section in the Source file, with C<=overlay SECTION Module>
definitions inside. The net effect is that any missing subheadings in
SECTION are added from the same section in the specified Modules.

Note that this will overlay the whole subheading, INCLUDING CUT NODES,
so it can add code to the source document. Use C<cut> if you don't
want this.

Each overlaid section will include a C<=for overlay from> marker, so
that it can be replaced by a subsequent overlay from the same
file/module. These sections will be replaced in-place, so ordering of
sections once first overlaid will be preserved.

=head2 unoverlay

 paf unoverlay Source.pm

Strips B<all> sections marked as overlaid and matching the overlay
spec from the source.

=head2 sort

 paf sort [-heading=METHODS] Source.pm

Sort all of the subheadings in the named heading (METHODS if not
provided).

This will move cut nodes around with their headings, so your code will

lib/Pod/Abstract/BuildNode.pm  view on Meta::CPAN

        close_element => Pod::Abstract::Node->new(
            type => 'end',
            body => $cmd,
        ),
        );
    return $begin;
}

=head2 for

 my $for = node->for('overlay from <class>');

Create a =for node. The argument is the literal body of the for node,
no parsing will be performed.

=cut

sub for {
    my $class = shift;
    my $str = shift;

lib/Pod/Abstract/Filter/overlay.pm  view on Meta::CPAN

package Pod::Abstract::Filter::overlay;
use strict;
use warnings;

use base qw(Pod::Abstract::Filter);
use Pod::Abstract;
use Pod::Abstract::BuildNode qw(node);

our $VERSION = '0.20';

=head1 NAME

Pod::Abstract::Filter::overlay - paf command to perform a method
documentation overlay on a Pod document.

=begin :overlay

=overlay METHODS Pod::Abstract::Filter

=end :overlay

=head1 METHODS

=head2 filter

Inspects the source document for a begin/end block named
":overlay". The overlay block will be inspected for "=overlay"
commands, which should be structured like:

 =begin :overlay
 
 =overlay METHODS Some::Class::Or::File
 
 =end :overlay

Each overlay is processed in order. It will add any headings for the
matched sections in the current document from the named source, for
any heading that is not already present in the given section.

If that doesn't make sense just try it and it will!

The main utility of this is to specify a superclass, so that all the
methods that are not documented in your subclass become documented by
the overlay. The C<sort> filter makes a good follow up.

The start of overlaid sections will include:

 =for overlay from <class-or-file>

You can use these markers to set sections to be replaced by some other
document, or to repeat an overlay on an already processed Pod
file. Changes to existing marked sections are made in-place without
changing document order.

=cut

sub filter {
    my $self = shift;
    my $pa = shift;
    
    my ($overlay_list) = $pa->select("//begin[. =~ {^:overlay}](0)");
    unless($overlay_list) {
        die "No overlay defined in document\n";
    }
    my @overlays = $overlay_list->select("/overlay");
    foreach my $overlay (@overlays) {
        my $o_def = $overlay->body;
        my ($section, $module) = split " ", $o_def;

        # This should be factored into a method.
        my $ovr_module = $module; # Keep original value
        unless(-r $module) {
            # Maybe a module name?
            $module =~ s/::/\//g;
            $module .= '.pm' unless $module =~ m/.pm$/;
            foreach my $path (@INC) {
                if(-r "$path/$module") {

lib/Pod/Abstract/Filter/overlay.pm  view on Meta::CPAN

        my @t_headings = $t->select("/[\@heading]");
        my @o_headings = $o->select("/[\@heading]");
        
        my %t_heading = map { 
            $_->param('heading')->pod => $_ 
        } @t_headings;
        
        foreach my $hdg (@o_headings) {
            my $hdg_text = $hdg->param('heading')->pod;
            if($t_heading{$hdg_text}) {
                my @overlay_from = 
                    $t_heading{$hdg_text}->select(
                        "/for[. =~ {^overlay from }]");
                my @from_current = grep {
                    substr($_->body, -(length $ovr_module)) eq $ovr_module
                } @overlay_from;
                
                if(@from_current) {
                    my $dup = $hdg->duplicate;
                    my @overlay_from = 
                        $hdg->select("/for[. =~ {^overlay from }]");
                    $_->detach foreach @overlay_from;
                    
                    $dup->unshift(node->for("overlay from $ovr_module"));
                    
                    $dup->insert_after($t_heading{$hdg_text});
                    $t_heading{$hdg_text}->detach;
                    $t_heading{$hdg_text} = $dup;
                }
            } else {
                my $dup = $hdg->duplicate;
                
                # Remove existing overlay markers;
                my @overlay_from = 
                    $hdg->select("/for[. =~ {^overlay from }]");
                $_->detach foreach @overlay_from;

                $dup->unshift(node->for("overlay from $ovr_module"));

                $t->push($dup);
                $t_heading{$hdg_text} = $dup;
            }
        }
    }
    return $pa;
}

=head1 AUTHOR

lib/Pod/Abstract/Filter/unoverlay.pm  view on Meta::CPAN

package Pod::Abstract::Filter::unoverlay;
use strict;
use warnings;

use base qw(Pod::Abstract::Filter);

our $VERSION = '0.20';

=head1 NAME

Pod::Abstract::Filter::unoverlay - paf command to remove "overlay" blocks
from a Pod document, as created by the paf overlay command.

=begin :overlay

=overlay METHODS Pod::Abstract::Filter

=end :overlay

=head1 METHODS

=head2 new

=for overlay from Pod::Abstract::Filter

=head2 filter

Strips any sections marked C<=for overlay> from the listed overlay
specification from the target document. This will expunge everything
that has been previously overlaid or marked for overlay from the
specified documents.

=cut

sub filter {
    my $self = shift;
    my $pa = shift;
    
    my ($overlay_list) = $pa->select("//begin[. =~ {^:overlay}](0)");
    unless($overlay_list) {
        die "No overlay defined in document\n";
    }
    my @overlays = $overlay_list->select("/overlay");
    foreach my $overlay (@overlays) {
        my $o_def = $overlay->body;
        my ($section, $module) = split " ", $o_def;
        
        my ($t) = $pa->select("//[\@heading =~ {$section}](0)");
        my @t_headings = $t->select("/[\@heading]");
        foreach my $hdg (@t_headings) {
            my @overlay_from = 
                $hdg->select(
                    "/for[. =~ {^overlay from }]");
            my @from_current = grep {
                substr($_->body, -(length $module)) eq $module
            } @overlay_from;
            if(@from_current) {
                $hdg->detach;
            }
        }
    }
    return $pa;
}

=head1 AUTHOR

t/01_compile.t  view on Meta::CPAN

Pod::Abstract
Pod::Abstract::Node
Pod::Abstract::Tree
Pod::Abstract::BuildNode
Pod::Abstract::Path
Pod::Abstract::Parser
Pod::Abstract::Filter
Pod::Abstract::Filter::cut
Pod::Abstract::Filter::uncut
Pod::Abstract::Filter::sort
Pod::Abstract::Filter::overlay
Pod::Abstract::Filter::unoverlay
Pod::Abstract::Filter::add_podcmds
Pod::Abstract::Filter::clear_podcmds
Pod::Abstract::Filter::summary
Pod::Abstract::Filter::find
Pod::Abstract::Filter::number_sections
);

foreach my $module (@modules) {
    eval " use $module ";
    ok(!$@, "$module compiles");



( run in 1.135 second using v1.01-cache-2.11-cpan-49f99fa48dc )