App-Pinpp

 view release on metacpan or  search on metacpan

lib/App/Pinpp.pm  view on Meta::CPAN


our $VERSION = '0.03'; # VERSION: Generated by DZP::OurPkg:Version



sub run {
    my $class = shift;

    # Load our arguments into ARGV, so we can use getopts.
    local @ARGV = @_;

    my %opts = (
        o => '',          # Output to PDF
        I => 'topics'     # Includes directory
    );

    getopts("o:i:",\%opts);

    my ($file) = @ARGV;

    $file or die "Usage: $0 file.pinpp";

    # Okay code, you have just one job:
    # @include <foo.pin> -> includes $INCLUDE_DIR/foo.pin
    # NB: Everything after the @include on a line will be removed.

    my $content = $class->_slurp($file);

    # Remove // comments

    $content =~ s{^//[^\n]*\n}{}gsm;

    # Process includes

    $content =~ s{^\@include\s+<([^>]+)>[^\n]*\n}{$class->include($opts{I},$1)}gmse;

    # Remove blank slides

    $content =~ s{^--\n--}{--}gsm;

    # If a slide has no styling at all, and consists only of indented text,
    # reformat it as code.

    $content =~ s{
        ^--[ \t]*\n         # Start of slide
        (?:
            [ \t]+[^\n]*\n  # Lines starting with spaces/tabs
            |               # or...
            \n              # blank lines. They're cool, too.
        )+                  # And we can have a bunch of either.
        (?=^--)             # End of slide look-ahead.
    }{_codeify(${^MATCH})}gsmxpe;   # USE ALL THE FLAGS!

    if (my $outputfile = $opts{o}) {

        # Iff we're producing a PDF, then remove speaker comments
        $content =~ s{^#[^\n]*\n}{}gsm;

        my ($tmp_fh, $tmp_filename) = tempfile( DIR => '.' );

        say {$tmp_fh} $content;
        close($tmp_fh);

        system("pinpoint", "--output=$opts{o}", $tmp_filename);
    }
    else {
        # Otherwise just display our text
        say $content;
    }

    # And we're done!

    # Success!
    return 0;
}


sub include {
    my ($class, $dir, $include) = @_;
    return $class->_slurp(File::Spec->catdir($dir, $include))."--\n";
}

# Slurps in a file. Not as fancy as File::Slurp, but saves us a
# dependency.
sub _slurp {
    my ($class, $file) = @_;

    local $/;

    open(my $fh, '<', $file);

    return <$fh>;
}

# Trims out start/end of slide.
sub _trim_slide {
    my ($slide) = @_;

    $slide =~ s{^--[ \t]*\n}{};
    $slide =~ s{--[ \t]*\n?$}{};

    return $slide;
}

# Turns a slide into a code slide.
# Does not return trailing '--'
sub _codeify {
    my ($slide) = @_;

    $slide = _trim_slide($slide);

    my @lines = split(/\n/,$slide);

    # Initial count.
    my $min_spaces = _count_leading_spaces($lines[0]);

    # Find the minimum number of spaces on any line.
    # Double-checks the first line. Meh.
    foreach my $line (@lines) {
        my $spaces = _count_leading_spaces($line);

        next if $spaces == 0;   # Blank lines don't count.

        if ($spaces < $min_spaces) {
            $min_spaces = $spaces;
        }
    }



( run in 0.581 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )