App-PFT

 view release on metacpan or  search on metacpan

bin/pft-ls  view on Meta::CPAN

date). If this is the case the placeholder gets expanded with an empty
string.

The output is encoding depending on the locale.

=over

=item %t

Title

=item %p

Path (might be void if the node is virtual)

=item %g

Comma separated list of tags (possibly void)

=item %a

Author (possibly void)

=item %s

Slug (or name, if the node is virtual)

=item %D

Date in yyyy-mm-dd format (possibly void)

=item %y

Year (possibly void)

=item %m

Month (possibly void)

=item %d

Day (possibly void)

=item %o

Comma separated value of option=value pairs (possibly void)

=back

=back

=head1 SEE ALSO

L<pft(1)>

=cut

use strict;
use warnings;

use feature qw/say state/;

use Encode::Locale qw/$ENCODING_LOCALE/;
use App::PFT;
use PFT::Tree;

use Pod::Usage;
use Getopt::Long;
Getopt::Long::Configure qw/bundling/;

my %opts = (
    pretty => pretty_parse("%t : %p")
);

GetOptions(
    'pretty=s'      => sub { $opts{pretty} = pretty_parse($_[1]) },
    'locate!'       => sub { $opts{pretty} = pretty_parse("%t:%p") },
    'help|h!'       => sub {
        pod2usage
            -exitval => 1,
            -verbose => 2,
            -input => App::PFT::help_of 'ls',
    },
) or exit 1;

my %classes = (
    pages => \&list_pages,
    blog => \&list_blog,
    tags => \&list_tags,
);

my $tree = eval{ PFT::Tree->new } || do {
    say STDERR $@ =~ s/ at.*$//rs;
    exit 3
};

my $content = PFT::Tree->new->content;

my $cls = shift;
if (defined $cls and my $handle = $classes{$cls}) {
    # The selected handle is used to list the specific class of content objects.
    say &{$opts{pretty}} for $handle->()
}
else {
    say STDERR "Usage: $App::PFT::Name <class> [options]";
    say STDERR "Available classes:";
    say STDERR "  * $_" for keys %classes;
    exit 1;
}

sub pretty_parse {
    my $fmt = shift;
    my $align = qr/-?\d*/;

    sub {
        my $out = $fmt;

        # defined(hdr) implies $_->exists
        my $hdr = $_->header;
        my $date = $hdr ? $hdr->date : undef;

        $out =~ s/(?<!%)%($align)t/sprintf(
            "%$1s", $hdr ? $hdr->title : $_->name
        )/eg;
        $out =~ s/(?<!%)%($align)p/sprintf(
            "%$1s", $hdr ? $_->path : ''
        )/eg;
        $out =~ s/(?<!%)%($align)a/sprintf(
            "%$1s", $hdr ? $hdr->author : ''
        )/eg;
        $out =~ s/(?<!%)%($align)s/sprintf(
            "%$1s", $hdr ? $hdr->slug : $_->name
        )/eg;
        $out =~ s/(?<!%)%($align)D/sprintf(
            "%$1s", $date ? $date->repr('-') : ''
        )/eg;
        $out =~ s/(?<!%)%($align)y/sprintf(
            "%$1s", $date ? $date->y : ''
        )/eg;
        $out =~ s/(?<!%)%($align)m/sprintf(
            "%$1s", $date ? $date->m : ''
        )/eg;
        $out =~ s/(?<!%)%($align)d/sprintf(
            "%$1s", $date ? $date->d : ''
        )/eg;
        $out =~ s/(?<!%)%($align)o/sprintf("%$1s",
            !defined($hdr) ? '' : do {
                my $h = $hdr->opts();
                join(', ', map $_ .'='. ($h->{$_} || '>') => keys %$h )
            }
        )/eg;
        $out =~ s/(?<!%)%($align)g/sprintf(
            "%$1s", $hdr ? join(',', $hdr->tags_slug ) : ''
        )/eg;

        $out;
    }
}

sub list_tags {
    my %tags;
    for my $c ($content->entry_ls) {
        $tags{$_} ++ for $c->header->tags_slug
    }

    map $content->tag(PFT::Header->new(
        title => $_,



( run in 1.536 second using v1.01-cache-2.11-cpan-140bd7fdf52 )