#!perl

our $DATE = '2016-03-24'; # DATE
our $VERSION = '0.38'; # VERSION

use 5.010;
use strict;
use warnings;
use open qw(:std :utf8);
use Log::Any::IfLOG qw($log);

use Code::Includable::Tree::NodeMethods;
use Data::CSel qw(parse_csel csel);
use Getopt::Long::EvenLess;
use Org::Parser;

my %Opts = (
    print => 'text',
);

GetOptions(
    'help|h|?' => sub {
        print <<'_';
Usage:
  select-org-elements [options] <expression> <input>
  select-org-elements --help (-h, -?)

Options:
  --print=s
  --count
_
        exit 0;
    },
    'print=s' => sub {
        $Opts{print} = $_[1];
    },
    'count' => sub {
        $Opts{count} = 1;
    },
) or die "Error in GetOptions\n";

my $expr = shift or die "Please specify CSel expression\n";

# parse first so we can exit early without having to read the input
parse_csel($expr) or die "Invalid CSel expression '$expr'\n";

my $input = [<>];
close STDIN; close ARGV; # so perl doesn't add ", <> line xx" upon dying

my $doc = Org::Parser->new->parse($input);

my @res = csel(
    {
        class_prefixes => ['Org::Element'],
    },
    $expr,
    Code::Includable::Tree::NodeMethods::descendants($doc));

if ($Opts{count}) {
    print ~~@res, "\n";
} elsif ($Opts{print} eq 'text-and-children-text') {
    print $_->as_string, $_->children_as_string for @res;
} elsif ($Opts{print} eq 'dump') {
    require Org::Dump;
    for (@res) {
        print Org::Dump::dump_element($_);
    }
} else {
    print $_->as_string for @res;
}

1;
# ABSTRACT: Select Org document elements using CSel
# PODNAME: select-org-elements

__END__

=pod

=encoding UTF-8

=head1 NAME

select-org-elements - Select Org document elements using CSel

=head1 VERSION

This document describes version 0.38 of select-org-elements (from Perl distribution App-OrgUtils), released on 2016-03-24.

=head1 SYNOPSIS

 % select-org-elements [options] 'Headline[level=2]' foo.org

=head1 DESCRIPTION

This script selects Org document nodes using CSel, much like how CSS selector
selects elements from HTML document. It then invokes

=head1 OPTIONS

=over

=item * --print=s

Specify how to print each matching element. The default is C<text>, which is to
print the result of each element's C<as_string()> method. Other valid values
include: C<text-and-children-text> (print the result of each element's
C<as_string()> as well as C<children_as_string()>), C<dump> (dump each element
using L<Org::Dump>).

See also: C<--count>.

=item * --count

Instead of printing each element, return the number of matching elements.

=back

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/App-OrgUtils>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-App-OrgUtils>.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-OrgUtils>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 SEE ALSO

L<Org::Parser>

L<Data::CSel>

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by perlancar@cpan.org.

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

=cut
