#!/usr/bin/env perl
# vim:ts=8 sw=4 sts=4 ai
require v5.6.1;
use strict;
use warnings;

=head1 NAME

posy_one - Script which uses the Posy engine to generate one file from an input file.

=head1 VERSION

This describes version B<0.93> of posy_one.

=cut

our $VERSION = '0.93';

=head1 SYNOPSIS

posy_one --help | --manpage | --version

posy_one { --actions I<action> } ( --base_dir I<dirname> | --config_dir
I<dirname> --flavour_dir I<dirname> --state_dir I<dirname> )
[ --data_dir I<dirname> { --DayWeek2Name I<num>=I<name> }
[ --debug_level I<num> ] { --entry_actions I<action> }
{ --file_extensions I<extension>=I<type> } --flavour I<flavour>
[ --libdir I<dirname> ] { --MonthNum2Name I<num>=I<name> }
{ --plugins I<plugin> } --url I<url> infile outfile

=head1 DESCRIPTION

This is a script which uses the Posy engine to generate one output file
from one input file -- where the input file doesn't have to be under
your usual data directory.

Instead, you can give another data directory; and if you give none,
it defaults to the current directory.

This can be used to generate template files for other CGI scripts, where
you want them to keep the same look-and-feel as the other pages in your
site.

=head1 OPTIONS

=over

=item --actions I<action>

The list of actions which Posy will perform.  Only use this if you're using
a plugin which requires inserting a new action.  Note that if you do,
you must specify I<every> action to be performed; once the default
actions are not being used, they must be replaced completely.

--actions init_params --actions parse_path --actions process_path_error
--actions set_config --actions index_entries --actions select_entries
--actions filter_by_date --actions sort_entries --actions content_type
--actions head_template --actions dynamic_css_set --actions theme_css_set
--actions flavour_menu_set --actions head_render --actions do_entry_actions
--actions foot_template --actions foot_render --actions render_page

=item --base_dir I<dirname>

The base directory to use to set the flavour and config data directories if
they are not explicitly set.  This does not set the default for the data_dir.

=item --config_dir I<dirname>

The directory where the config files are.  Either set this or
you can set --base_dir if your config files are in I<base_dir>/config.

=item --data_dir I<dirname>

The directory you wish to use as your input data directory.  This
is not supposed to be the same as your normal data directory, but
I suppose it could be.  If not given, it defaults to the current
directory.

=item --DayWeek2Name I<num>=I<name>

This is a hash which sets how a day-of-the-week number will be
converted into a name.  Set this if you want, for example,
all weekdays to be truncated.  Most of the time one can leave it
at the default.

    --DayWeek2Name 0=Sunday --DayWeek2Name 1=Monday
    --DayWeek2Name 2=Tuesday --DayWeek2Name 3=Wednesday
    --DayWeek2Name 4=Thursday --DayWeek2Name 5=Friday
    --DayWeek2Name 6=Saturday

=item --debug_level I<number>

Turn on debugging.  The larger the number, the more verbose the output.
(don't do this unless you're a developer)

=item --entry_actions I<action>

The list of actions which Posy will perform on each entry.  Only use this
if you're using a plugin which requires inserting a new action.  Note that
if you do, you must specify I<every> action to be performed; once the
default actions are not being used, they must be replaced completely.

--entry_actions header --entry_actions entry_template
--entry_actions read_entry --entry_actions parse_entry
--entry_actions short_body --entry_actions render_entry
--entry_actions append_entry

=item --file_extensions I<ext>=I<type>

If you wish to change the default file extensions, then use this argument.
Generally one would only do this if one had added a plugin to deal
with a new kind of file.  Or if one wanted to give a different extension
to a standard type of file.  Note that if you use this option, you must
specify I<every> file extension setting you want to use; the defaults
are overridden.
 
    --file_extensions txt=text --file_extensions html=html --file_extensions blx=blosxom

=item --flavour I<flavour>

What flavour do you want the output to be?

=item --flavour_dir I<dirname>

The directory where the flavour files are.  Either set this or
you can set --base_dir if your flavour files are in I<base_dir>/flavours.

--flavour_dir /files/www/posy/data/flavours

=item --help

Print help message and exit.

=item --libdir I<dirname>

If you installed the Posy modules in your home directory (or some other
non-global place), then you need to tell this script where to look for them.
Set --libdir to that directory.

For example, if you installed the Posy modules in /home/fred/perl
(and thus the Posy.pm module file is in /home/fred/perl/lib)
then

    --libdir '/home/fred/perl/lib'

This assumes that any Posy plugins are also under the same directory.

=item --manpage

Print the full help documentation (manual page) and exit.

=item --MonthNum2Name

This is a hash which sets how a month-number will be
converted into a name.  Use this if you want, for example,
all month-names to be truncated.

--MonthNum2Name 1=January --MonthNum2Name 2=February
--MonthNum2Name 3=March --MonthNum2Name 4=April
--MonthNum2Name 5=May --MonthNum2Name 6=June
--MonthNum2Name 7=July --MonthNum2Name 8=August
--MonthNum2Name 9=September --MonthNum2Name 10=October
--MonthNum2Name 11=November --MonthNum2Name 12=December

=item --plugins I<plugin>

If you wish to use any plugins, you must put them in the plugins list,
as well as installing the actual plugin modules.

For example, if you are using the Posy::Plugin::TextTemplate module,
then the TextTemplate module should be installed in the same way
that you installed the core Posy modules.

Then you add the name of the plugin to this plugins list.

    --plugins Posy::Plugin::TextTemplate --plugins Posy::Plugin::TextToHTML

Remember that the order of plugins in the list is important if two
plugins override the same function.

Note that this will always use the Posy::Core plugin.

=item --state_dir I<dirname>

The directory where "state" information is put.

=item --url I<url>

What is my preferred base URL for this site/blog?  (needs to be
set for static generation, even if you didn't need to set it
for dynamic generation).

=item --verbose

Print informational messages.

=item --version

Print version information and exit.

=back

=head1 REQUIRES

    Getopt::Long
    Pod::Usage
    Getopt::ArgvFile
    Posy
    Cwd

=head1 SEE ALSO

perl(1)
Getopt::Long
Getopt::ArgvFile
Pod::Usage

=cut

use Getopt::Long 2.34;
use Getopt::ArgvFile qw(argvFile);
use Pod::Usage;
use File::Spec;
use Cwd;

#========================================================
# Subroutines

sub init_data ($) {
    my $data_ref = shift;

    $data_ref->{manpage} = 0;
    $data_ref->{verbose} = 0;
    # disable caching
    $data_ref->{config}->{use_caching} = 0;
    # set the data_dir
    $data_ref->{data_dir} = getcwd;
} # init_data

sub process_args ($) {
    my $data_ref = shift;

    my $ok = 1;

    argvFile(home=>1,current=>1,startupFilename=>'.posy_onerc');

    pod2usage(2) unless @ARGV;

    my $op = new Getopt::Long::Parser;
    $op->configure(qw(auto_version auto_help));
    $op->getoptions($data_ref,
	       'verbose!',
	       'manpage',
	       'actions=s@',
	       'base_dir=s',
	       'config_dir=s',
	       'data_dir=s',
	       'DayWeek2Name=s%',
	       'entry_actions=s@',
	       'file_extensions=s%',
	       'flavour=s',
	       'flavour_dir=s',
	       'debug_level=n',
	       'libdir=s',
	       'MonthNum2Name=s%',
	       'plugins=s@',
	       'state_dir=s',
	       'url=s',
	      ) or pod2usage(2);

    if ($data_ref->{'manpage'})
    {
	pod2usage({ -message => "$0 version $VERSION",
		    -exitval => 0,
		    -verbose => 2,
	    });
    }

} # process_args

#========================================================
# Main

MAIN: {
    my %data = ();

    init_data(\%data);
    process_args(\%data);
    my $libdir = $data{libdir};
    delete $data{libdir};

    eval "use lib '$libdir'" if $libdir;
    die "invalid libdir $libdir: $@" if $@;
    my $class='Posy';
    eval "require $class;";
    die "invalid starter class $class: $@" if $@;

    my @plugins = qw(Posy::Core);
    push @plugins, @{$data{plugins}} if ($data{plugins});
    delete $data{plugins};

    $class->import(@plugins);

    # which flavour?
    my $flavour = $data{flavour};
    $data{params}->{flav} = $flavour;
    delete $data{flavour};

    # set the path to be the infile without its suffix
    my $path = shift @ARGV;
    $path =~ s/\.\w+$//;
    $data{params}->{path} = $path;
    
    # set the outfile to be the outfile
    my $outfile = shift @ARGV;
    $data{outfile} = $outfile;

    $class->run(%data);
}

=head1 BUGS

Please report any bugs or feature requests to the author.

=head1 AUTHOR

    Kathryn Andersen (RUBYKAT)
    perlkat AT katspace dot com
    http://www.katspace.com

=head1 COPYRIGHT AND LICENCE

Copyright (c) 2004 by Kathryn Andersen

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

=cut

__END__
