File: Filter.pm

package info (click to toggle)
libpod-abstract-perl 0.26-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 340 kB
  • sloc: perl: 2,373; makefile: 2
file content (211 lines) | stat: -rw-r--r-- 4,382 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package Pod::Abstract::Filter;
use strict;
use warnings;

use Pod::Abstract;

use Module::Pluggable require => 1, search_path => ['Pod::Abstract::Filter'];

our $VERSION = '0.26';

=head1 NAME

Pod::Abstract::Filter - Generic Pod-in to Pod-out filter.

=head1 DESCRIPTION

This is a superclass for filter modules using
Pod::Abstract. Subclasses should override the C<filter>
sub. Pod::Abstract::Filter classes in the Pod::Abstract::Filter
namespace will be used by the C<paf> utility.

To create a filter, you need to implement:

=over

=item filter

Takes a Pod::Abstract::Node tree, and returns either another tree, or
a string. If a string is returned, it will be re-parsed to be input to
any following filter, or output directly if it is the last filter in
the list.

It is recommended your filter method produce a Node tree if you are able
to, as this will improve interoperability with other C<Pod::Abstract>
based software.

=item require_params

If you want positional arguments following your filter in the style of:

 paf find [thing] Pod::Abstract

then override require_params to list the named arguments that are to
be accepted after the filter name.

=back

=head1 METHODS

=head2 new

Create a new filter with the specified arguments.

=cut

sub new {
    my $class = shift;
    my %args = @_;
    
    return bless { %args }, $class;
}

=head2 plugins_info

 my $info = Pod::Abstract::Filter->plugins_info;

Gets information for each paf command/plugin.

=cut

sub plugins_info {
    my $class = shift;

    my @plugins = $class->plugins;
    my $info = {};
    foreach my $p (@plugins) {
        $p =~ m/^Pod::Abstract::Filter::(.*)$/;
        my $cmd = $1;

        $info->{$cmd} = {
            class => $p,
            command => $cmd,
            summary => $class->summarise( $p ),
        };
    }

    return $info;
}

sub summarise {
    my $class = shift;
    my $mod = shift;
    
    $mod =~ s/::/\//g;
    $mod .= '.pm';
    my $filepath = '';
    foreach my $path (@INC) {
        if(-r "$path/$mod") {
            $filepath = "$path/$mod";
            last;
        }
    }

    my $pa = Pod::Abstract->load_file($filepath);
    my @texts = $pa->select('/head1[@heading eq \'NAME\']/:paragraph');
    return [] unless @texts;
    
    my $pt = join '', map { $_->pod } @texts;
    $pt =~ s/^Pod::Abstract::Filter:://;
    my ($command, $rest) = split / - /, $pt, 2;
    return [ ] unless $command && $rest; # Never mind if the module doesn't follow standard

    $rest =~ s/[\r\n]//g;


    # Reflow to max 72 chars.
    my $out = '';
    while( $rest ) {
        if( length $rest <= 72 ) {
            $out .= '    '.$rest;
            $rest = '';
        } else {
            my $i = 72;
            while( substr($rest, $i, 1) !~ /^\s$/ && $i > 0 ) {
                $i --;
            }
            if( $i == 0 ) {
                # Give up and finish the string.
                $out .= '    '.$rest;
            } else {
                $out .= '    '.substr( $rest, 0, $i, '')."\n";
                $rest =~ s/^\s*//;
            }
        }

    }

    return [ $command, $out ];
}

=head2 require_params

Override to return a list of parameters that must be provided. This
will be accepted in order on the command line, unless they are first
set using the C<-flag=xxx> notation.

=cut

sub require_params {
    return ( );
}

=head2 param

Get the named param. Read only.

=cut

sub param {
    my $self = shift;
    my $param_name = shift;
    return $self->{$param_name};
}

=head2 filter

Stub method. Does nothing, just returns the original tree.

=cut

sub filter {
    my $self = shift;
    my $pa = shift;
    
    return $pa;
}

=head2 run

Run the filter. If $arg is a string, it will be parsed
first. Otherwise, the Abstract tree will be used. Returns either a
string or an abstract tree (which may be the original tree, modified).

=cut

sub run {
    my $self = shift;
    my $arg = shift;
    
    if( eval { $arg->isa( 'Pod::Abstract::Node' ) } ) {
        return $self->filter($arg);
    } else {
        my $pa = Pod::Abstract->load_string($arg);
        return $self->filter($pa);
    }
}

=head1 AUTHOR

Ben Lilburne <bnej80@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2009-2025 Ben Lilburne

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;