#!/usr/bin/perl
#
#  This file is part of WebDyne.
#
#  This software is copyright (c) 2025 by Andrew Speer <andrew.speer@isolutions.com.au>.
#
#  This is free software; you can redistribute it and/or modify it under
#  the same terms as the Perl 5 programming language system itself.
#
#  Full license text is available at:
#
#  <http://dev.perl.org/licenses/>
#


#
#  Compile and/or show compiled version of WebDyne HTML scripts
#
package main;


#  Compiler pragma, load library path
#
sub BEGIN {

    #  Massage warnings and @INC path
    $^W=0;
    use File::Spec;
    use FindBin qw($RealBin $Script);
}
use strict qw(vars);
use vars   qw($VERSION);


#  Use the base modules
#
use WebDyne::Util;


#  External modules
#
use WebDyne::Compile;
use Getopt::Long;
use Pod::Usage;
use Data::Dumper;
$Data::Dumper::Indent=1;
$Data::Dumper::Terse=1;
$Data::Dumper::Sortkeys=1;
$Data::Dumper::Deepcopy=1;
$Data::Dumper::Purity=1;


#  Version Info, must be all one line for MakeMaker, CPAN.
#
$VERSION='2.029';


#  Run main
#
exit ${&main(\@ARGV) || die errdump()};


#===================================================================================================


sub main {


    #  Get argv array ref
    #
    my $argv_ar=shift();


    #  Base options will pass to compile
    #
    my %opt=(

        nofilter      => 1,    # don't run through any filters
        noperl        => 1,    # don't run perl code,
        notimestamp   => 1,
        manifest      => 1,

        #stage5   => 1,    # default

    );


    #  Now import command line options. Command line option compilation stages are different from
    #  internal stage numbers so maps are 0=>stage0, 1=>stage2, 2=>stage3, 3=>stage4, confusing ..
    #
    GetOptions(
        \%opt, qw(
            stage0|0
            stage1|1
            stage2|2
            stage3|3
            stage4|4
            stage5|5|final
            meta
            data
            manifest!
            dest|dest_fn:s
            all
            timestamp!
            perl!
            filter!
            version
            help|?
            man
            opt
        )) || pod2usage(2);
    pod2usage(-verbose => 99, -sections => 'SYNOPSIS|OPTIONS', -exitval => 1) if $opt{'help'};
    pod2usage(-verbose => 2)                                                  if $opt{'man'};
    $opt{'version'} && do {
        print "$Script version: $VERSION\n";
        print "WebDyne version: $WebDyne::VERSION\n";
        exit 0
    };


    #  Clunky, too hard to change module logic
    #
    map {$opt{"no${_}"}=!($opt{$_})} qw(perl filter timestamp manifest);


    #  Get srce file, add to options
    #
    my $srce_fn=$argv_ar->[0] ||
        pod2usage("$Script: no source file specified !");
    $opt{'srce'}=$srce_fn;


    #  Dump options for debugging
    #
    die Dumper(\%opt) if $opt{'opt'};


    #  Create and run compile object
    #
    my $compile_or=WebDyne::Compile->new(\%opt);
    my $data_ar=$compile_or->compile(\%opt) ||
        return err();


    #  Dump it
    #
    if ($opt{'all'}) {
        print Dumper($data_ar);
    }
    elsif ($opt{'meta'}) {
        print Dumper($data_ar->[0])
    }
    else {
        print Dumper($data_ar->[1])
    }

    #print Data::Dumper::Dumper(grep {$_} $opt{'meta'} ? $data_ar->[0] : undef, $data_ar->[1]);


    #  Return success
    #
    \undef;


}

__END__# https://github.com/aspeer/pl-markpod.git 





=pod

=head1 wdcompile(1)

=head1 NAME

C<<<< wdcompile >>>> - parse and compile WebDyne pages

=head1 SYNOPSIS

C<<<< wdcompile [OPTIONS] FILE >>>>

C<<<< wdcompile --stage0 time.psp >>>>

=head1 Description

The  C<<<< wdcompile >>>>  command displays the internal data structure used by WebDyne when compiling psp pages.

WebDyne uses the same parsing and compilation routines as C<<<< wdcompile >>>> . After compilation WebDyne optionally stores the resulting data structure to a cache directory using the Perl C<<<< Storable >>>>  module to speed up subsequent rendering operations.

If the tree structure does not appear correct when debugging with C<<<< wdcompile >>>>  then it will probably not display as expected when rendered with WebDyne. Missing end quotes, closing tags and general
 HTML syntax problems can all make the parse tree misplace (or omit
 completely) blocks of HTML/WebDyne code.

By default  C<<<< wdcompile >>>>  will show the data structure after all parsing and optimisation stages have been completed. You can
 display various intermediate stages using the options below.

=head1 Options

=over

=item * B<<< -h, --help >>>

Show brief help message.

=item * B<<< --stage0 | -0 >>>

Compile to stage 0. This the first parse of the source file and has no optimisations.

=item * B<<< --stage1 | -1 >>>

Compile to stage 1. Metadata is added to the data structure.

=item * B<<< --stage2 | -2 >>>

Compile to stage 2. Any WebDyne Filters are applied.

=item * B<<< --stage3 | -3 >>>

Compile to stage 3. First optimisation is performed.

=item * B<<< --stage4 | -4 >>>

Compile to stage 4. Second optimisation is run

=item * B<<< --stage5 | --final | -5 >>>

Compile to stage 5. Final data structure

=item * B<<< --meta | -m >>>

Only show the metadata of the compiled page. This is the manifest or attributes held in  C<<<< <meta> >>>>  sections with the name "WebDyne" (used to alter WebDyne behaviour). If found such meta data is removed from the resulting
 HTML parse tree and stored in a separate data structure. This
 option will show that data structure if it exists.

=item * B<<< --data >>>

Only show the data structure of the compiled page.

=item * B<<< --nomanifest >>>

Do not generate or store a manifest in the compiled page. The manifest contains the path to the source file(s), and is
 stored in the metadata area.

=item * B<<< --dest | --dest_fn >>>

Specify a destination file for the compiled page, with data stored in Perl Storable format. Once saved it can be reviewed
 later with the  C<<<< wddump >>>>  command

=item * B<<< --all >>>

Show all data in the compiled page

=item * B<<< --timestamp >>>

Include a timestamp

=item * B<<< --version >>>

Display the script version and exit

=item * B<<< --man >>>

Display this man page

=back

=head1 Examples

    # Show the compiled version of the time.psp page with all optimisations.
    wdcompile time.psp

Compile and display the completed internal WebDyne data structure of the file called time.psp. The resulting output shows the data structure
 after the file is parsed, then rebuilt around any dynamic WebDyne
 tags.

    #  Show the compiled version of time.psp as the early HTML tree
    wdcompile --stage0 widget.psp

Parse and display the very data structure of the time.psp file at the lowest level - as interpreted by the HTML::Treebuilder module, with no
 optimisation at all.

=head1 Notes

The wdcompile will not run any code in the  C<<<< __PERL__ >>>>  section of a psp file. It will also not execute any WebDyne filters that may be called by the source file.

=head1 Author

Written by Andrew Speer,  <andrew@webdyne.org>

=head1 LICENSE and COPYRIGHT

This file is part of WebDyne.

This software is copyright (c) 2025 by Andrew Speer L<mailto:andrew.speer@isolutions.com.au>.

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

Full license text is available at:

L<http://dev.perl.org/licenses/>

=cut