#!/usr/bin/perl

#
# $Id: hilitep6 26710 2009-05-07 08:50:06Z azawawi $
#

# Core modules
use 5.010;
use strict;
use warnings;
use utf8;
use feature qw(say switch);
use Carp;

# And finally our modules
#use STD;
#use Syntax::Highlight::Perl6;

#CPAN version
our $VERSION = '0.54';

# my variables
my ($clean_html,$help) = (0,0);
my ($full_html,$simple_html,$snippet_html,$ansi_text) = (0,0,0,0);
my $file;

#
# Your standard main method
#
sub main {
    #process the command line
    require Getopt::Long;
    Getopt::Long::GetOptions(
        'clean-html'=>\$clean_html,
        'full-html=s'=>\$full_html,
        'simple-html=s'=>\$simple_html,
        'snippet-html=s'=>\$snippet_html,
        'ansi-text=s'=>\$ansi_text,
        'help'=>\$help
    );

    if ($help) {
        say <<"HELP";
USAGE:
    $0 [options] [file] [rule]

    where 'file' is optional; if omitted or is '-' then
    STDIN will be used. And 'options' can be one of the following:

    --clean-html
        generates separate html,css and javascript

    --full-html=filename
        write full-mode html to filename (- for STDOUT)

    --simple-html=filename
        write simple-mode html to filename (- for STDOUT)

    --snippet-html=filename
        This is typically ideal for inline html code. (- for STDOUT)

    --ansi-text=filename
        write simple-mode ansi color text to filename (- for STDOUT)
HELP
        return; #exit
    }

    #default is --simple-html=- if no option is selected
    if(!($simple_html || $full_html || $snippet_html) && !$ansi_text) {
        $ansi_text = q{-};
    }

    #start parsing...
    $file = shift @ARGV;
    my $what = shift @ARGV // 'comp_unit';

    #what is the meaning of your input file?
    if(!$file || $file eq q{-}) {
        # i think you mean standard input
        binmode STDIN;
        $file = \*STDIN;
    } else {
        # no it is should be a file, let me check
        if(! -r $file) {
            croak "Could not open '$file' for reading\n";
        }
    }

    # and finally print out the html code
    highlight_match($file);

    return;
}

#
# Writes the output to a file or STDOUT
#
sub write_output {
    my ($file, $output) = @_;
    if($file eq q{-}) {
        say $output;
    } else {
        use open OUT => ':utf8';
        require IO::File;
        my $fh = IO::File->new(">$file") or
            croak "Cannot open $file for writing: $!\n";
        say $fh $output;
        close $fh
            or croak "Cannot close $file\n";
    }

    return;
}

#-----------------------------------------------------
# Load file into a scalar without File::Slurp
# see perlfaq5
#-----------------------------------------------------
sub _slurp_special {
    my $filename = shift;
    my $fh;
    if(ref $filename) {
        $fh = $filename;
    } else {
        $fh = IO::File->new($filename)
            or croak "Could not open $filename for reading";
    }
    local $/ = undef;   #enable localized slurp mode
    my $contents = <$fh>;
    if(! ref $filename) {
        close $fh
            or croak "Could not close $filename";
    }
    return $contents;
}

#
# Reads the filename and writes to output the generated
# Perl6 highlighted format.
#
sub highlight_match {
    my $filename = shift;

    use STD;
    require Syntax::Highlight::Perl6;
    my $p = new Syntax::Highlight::Perl6(
        text => _slurp_special($filename),
        inline_resources => ! $clean_html,
    );
    if($full_html) {
        write_output $full_html, $p->full_html;
    }
    if($simple_html) {
        write_output $simple_html, $p->simple_html;
    }
    if($snippet_html) {
        write_output $snippet_html, $p->snippet_html;
    }
    if($ansi_text) {
        write_output $ansi_text, $p->ansi_text;
    }

    return;
}

# exectution start here
main @ARGV;

__END__

=head1 NAME

hilitep6 - command-line interface to highlight Perl 6 code

=head1 USAGE

    # read from standard input
    hilitep6

    # print ansi-escaped text for 'comp_unit'
    hilitep6 foo.pl

    # print separate html, css and javascript files
    hilitep6 --full-html=foo.full.html --clean-html foo.pl

    # print ansi-escaped text for with 'statementlist' as the top-level rule
    hilitep6 foo.pl statementlist

    # write simple html output to foo.pl.html
    hilitep6 --simple-html=foo.pl.html foo.pl

    # write simple snippet html output to foo.pl.html
    hilitep6 --snippet-html=foo.pl.html foo.pl

    # write simple ansi-colored output to STDOUT
    hilitep6 --ansi-text=- foo.pl

=head1 DESCRIPTION

The tool uses L<Syntax::Highlight::Perl6> to highlight perl 6 source
code into html, and ansi escape color sequences.

=head1 SEE ALSO

See L<Syntax::Highlight::Perl6>

=head1 AUTHOR

Written by Ahmad M. Zawawi C<< <ahmad.zawawi at gmail.com> >>

=head1 LICENSE AND COPYRIGHT

The same license as L<Syntax::Highlight::Perl6>
