#!/usr/bin/perl
#
# Copyright 2014 - Giovanni Simoni
#
# This file is part of PFT.
#
# PFT is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# PFT is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with PFT.  If not, see <http://www.gnu.org/licenses/>.
#

=encoding utf-8

=head1 NAME

pft - Hacker friendly static blog generator

=head1 SYNOPSIS

B<pft> E<lt>commandE<gt> [options]

=head1 DESCRIPTION

I<PFT> It is a static website generator written in Perl.  PFT stands for
I<Plain F. Text>, where the meaning of I<F> is up to personal
interpretation. Like I<Fancy> or I<Fantastic>.

Static means that your content is compiled once and the result can be
served by a simple HTTP server, without need of server-side dynamic
content generation. Actually it doesn't need a server either: you can use
it as note-taking application and browse trough your local files.

I<PFT> is designed to be Hacker Friendly: it's a command-line application
with unicode support, which handles your website's boilerplate, but stays
out of the way. It comes with number of subcommands:

=over

=item *

B<init>: Initialize a B<pft> site in the current directory;

=item *

B<edit>: Create a content text (e.g. page or blog entry);

=item *

B<make>: Build the website;

=item *

B<gen-rss>: Generate RSS feed XML;

=item *

B<pub>: Publish the website;

=item *

B<clean>: Clear built tree;

=item *

B<grab>: Grab a file as attachment or picture;

=item *

B<ls>: List content and properties;

=item *

B<show>: Show the compiled site in a web browser;

=item *

B<help>: Show this manual.

=back

The manual of each sub-command is available in form of manpages or by
invoking it with the C<--help> flag.

=head1 FILES

A new site can be initialized by running the C<pft init> command inside a
directory. In this document such directory will be called I<ROOT>.

The initialization command produces the following filesystem structure:

    ROOT
    |-- pft.yaml            - Configuration file
    |-- content
    |   |-- attachments     - Location for attachments
    |   |-- blog            - Root location for blog entries source files
    |   |-- pages           - Location for pages source files
    |   |-- pics            - Location for pictures lookup
    |   `-- tags            - Location for tag pages source files
    |-- build               - Location of the built website
    |-- inject              - Content to bulk inject the online site root
    `-- templates           - Location for templates

=head2 C<pft.yaml>: configuration file

The configuration file is created automatically by the L<pft-init(1)>
command, and populated with sensible defaults.  It is expected to be in
I<YAML> format. For more information consult the manual of C<pft init>.

=head2 C<content>: files generated by the user

This is where your content is stored. The L<pft-edit(1)> and L<pft-grab(1)>
commands will add text and binary files respectively in the appropriate
subdirectories. The L<pft-make(1)> command will scan the C<content>
directory while building the website.

=head2 C<build>: where the built website is placed

The L<pft-make(1)> command will place the HTML pages resulting from the
compilation in this directory. The L<pft-pub(1)> command will publish what
here is contained. The L<pft-clean(1)> command will erase it.

=head2 C<inject>: a place for auxiliary files

It's common practice to add files in the root directory of your online
website. The L<pft-make(1)> command will add any arbitrary file which is
found in the C<inject> directory to the C<build> directory after
compilation.

A good use case for this feature is the C<.htaccess> file used by the
Apache webserver.

=head2 C<templates>: HTML templates for compilation

Each text entry in your C<content> directory will be mapped by
L<pft-make(1)> to an HTML file. The output is created by expanding the
content into the structure defined by a template file.

Multiple template files can be stored in the C<template> directory. Some
default files installed by L<pft-init(1)>.

Among other things, the C<pft.yaml> configuration defines which default
template page should be used for the site. Single content entries can
override this setting by declaring a different template name in their
header. More details about the header can be found in the L<pft-edit(1)>
manual page. Templates are documented in the L<pft-make(1)> manual page.

=head1 SEE ALSO

L<pft-clean(1)>, L<pft-edit(1)>, L<pft-gen-rss(1)>, L<pft-grab(1)>,
L<pft-help(1)>, L<pft-init(1)>, L<pft-ls(1)>, L<pft-make(1)>, L<pft-pub(1)>,
L<pft-show(1)>

=cut

use strict;
use warnings;
use warnings qw(FATAL utf8);

use utf8;
use v5.16;

use App::PFT;

use FindBin;
use File::Spec::Functions;
use File::Basename qw/basename/;

use Pod::Usage;
use Pod::Find qw/pod_where/;

use Encode;
use Encode::Locale;

$_ = decode(locale => $_) foreach @ARGV;
binmode STDIN, ':encoding(console_in)';
binmode STDOUT, ':encoding(console_out)';
binmode STDERR, ':encoding(console_out)';
$0 = basename $0;

my $subcmd = shift @ARGV;
unless (defined $subcmd) {
    print STDERR "Usage: $0 <command> [<args>]\n",
                 "Usage: $0 --help\n";
    exit 1;
} elsif ($subcmd =~ /^(?:version|-v|--version)$/) {
    say STDERR $App::PFT::VersionString;
    exit 0
} elsif ($subcmd =~ /^(?:help|-h|--help)$/) {
    @ARGV and do {
        print STDERR "Did you mean `$0 $ARGV[0] --help`?\n";
        exit 1
    };
    pod2usage
        -exitval => 1,
        -verbose => 2,
        -input => pod_where({-inc => 1}, __PACKAGE__)
}
my $return = do catfile $FindBin::RealBin, $App::PFT::Name . '-' . $subcmd;
unless (defined $return) {
    print STDERR 'pft: ', $@, "\n" if $@;
    print STDERR 'pft: cannot run command ', $subcmd, ': ', $!, "\n" if $!;
    exit 1
}
