#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::RealBin/../blib/lib";
use Getopt::Long qw(:config no_ignore_case);
use Pod::Usage;
use Pod::LaTeX;

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Prepare LaTeX from various executable's and module's PODs
# These go into appendices of the manual
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
my $WORKDIR = $FindBin::RealBin;
my $SRCDIR  = $WORKDIR . "/../..";
my $GENDIR  = "$WORKDIR/pods";

my $identity = "genpods (part of LaTeXML)";
my ($force, $help) = (0, 0);
GetOptions("force!" => \$force,
  "help" => \$help,
) or pod2usage(-message => $identity, -exitval => 1, -verbose => 0, -output => \*STDERR);
pod2usage(-message => $identity, -exitval => 1, -verbose => 2, -output => \*STDOUT) if $help;

#======================================================================
my @exes = (qw(latexml latexmlpost latexmlc latexmlmath));
# would be nice to automatically discover documentable modules
# Actually, we Can, by looking in ../blib/man1 and ../blib/man3
# However, we'd still need to manually add them (in desired order) to the appropriate Appendx!
my @modules = (
  # Core modules
  qw(LaTeXML
    LaTeXML::Global

    LaTeXML::Common::Config
    LaTeXML::Common::Object
    LaTeXML::Common::Color
    LaTeXML::Common::Color::rgb
    LaTeXML::Common::Color::hsb
    LaTeXML::Common::Color::cmy
    LaTeXML::Common::Color::cmyk
    LaTeXML::Common::Color::gray
    LaTeXML::Common::Color::Derived
    LaTeXML::Common::Number
    LaTeXML::Common::Float
    LaTeXML::Common::Dimension
    LaTeXML::Common::Glue
    LaTeXML::Common::Font
    LaTeXML::Common::Locator
    LaTeXML::Common::Model
    LaTeXML::Common::Model::DTD
    LaTeXML::Common::Model::RelaxNG
    LaTeXML::Common::XML
    LaTeXML::Common::Error

    LaTeXML::Package
    LaTeXML::Core::State

    LaTeXML::Core::Mouth
    LaTeXML::Core::Gullet
    LaTeXML::Core::Stomach
    LaTeXML::Core::Document
    LaTeXML::Core::Rewrite

    LaTeXML::Core::Token
    LaTeXML::Core::Tokens
    LaTeXML::Core::Box
    LaTeXML::Core::List
    LaTeXML::Core::Comment
    LaTeXML::Core::Whatsit

    LaTeXML::Core::Alignment
    LaTeXML::Core::KeyVals
    LaTeXML::Core::MuDimension
    LaTeXML::Core::MuGlue
    LaTeXML::Core::Pair
    LaTeXML::Core::PairList

    LaTeXML::Core::Rewrite

    LaTeXML::Core::Definition
    LaTeXML::Core::Definition::Expandable
    LaTeXML::Core::Definition::Conditional
    LaTeXML::Core::Definition::Primitive
    LaTeXML::Core::Definition::Register
    LaTeXML::Core::Definition::CharDef
    LaTeXML::Core::Definition::Constructor

    LaTeXML::Core::Parameter
    LaTeXML::Core::Parameters

    LaTeXML::MathParser
    LaTeXML::Pre::BibTeX
  ),

  # Utility
  qw(LaTeXML::Util::Pathname
    LaTeXML::Util::WWW
    LaTeXML::Util::ObjectDB
    LaTeXML::Util::Pack
    LaTeXML::Util::Radix
  ),
  # Postprocessing
  qw(LaTeXML::Post
    LaTeXML::Post::MathML
    LaTeXML::Post::OpenMath
  ),
);

if (!-d $GENDIR) {
  mkdir($GENDIR) or die "Couldn't create directory for pods: $!"; }

foreach my $name (@exes) {
  my $src  = "$SRCDIR/bin/$name";
  my $dest = "$GENDIR/${name}_exe.tex";
  if ($force || (!-f $dest) || (-M $src < -M $dest)) {
    print "Converting POD for $name to LaTeX\n";
    local $::PODDOC = $name;    # $::PODDOC =~ s/::/_/g;
    my $podconverter = MyPodConverter->new();
    $podconverter->parse_from_file($src, $dest); } }

foreach my $name (@modules) {
  my $src = $name;
  $src =~ s|::|/|g;
  $src = "$SRCDIR/lib/$src.pm";
  my $dest = $name;
  $dest =~ s|::|_|g;
  $dest = "$GENDIR/$dest.tex";
  if ($force || (!-f $dest) || (-M $src < -M $dest)) {
    print "Converting POD for $name to LaTeX\n";
    local $::PODDOC = $name;    # $::PODDOC =~ s/::/_/g;
    my $podconverter = MyPodConverter->new();
    $podconverter->parse_from_file($src, $dest); } }

#======================================================================
package MyPodConverter;
use base qw(Pod::LaTeX);

sub new {
  my ($class, @args) = @_;
  my $self = $class->SUPER::new(@args);
##  $self->Head1Level(1);
##  $self->LevelNoNum(2);
  $self->Head1Level(2);
  $self->LevelNoNum(3);
  #  $self->LevelNoNum(1);
  #  $self->ReplaceNAMEwithSection(1);
  $self->ReplaceNAMEwithSection(2);
  $self->AddPreamble(0);
  $self->AddPostamble(0);
  $self->select('!AUTHOR|COPYRIGHT');
  return $self; }

our %titles;
our %ignore;

BEGIN {
  %titles = ("SYNOPSIS" => "Synopsis",
    "OPTIONS AND ARGUMENTS" => "Options \\& Arguments",
    "DESCRIPTION"           => "Description",
    "SEE ALSO"              => "See also",
    "METHODS"               => "Methods",
  );
}

# Redefined to beautify POD headings
sub head {
  my ($self, $level, $title, $parobj) = @_;
  my $newtitle = $titles{$title} || $title;
  return $self->SUPER::head($level, $newtitle, $parobj); }

# Redefined to translate links to our PODs
sub interior_sequence {
  my ($self, $seq_command, $seq_argument, $pod_seq) = @_;
  if (($seq_command eq 'L')
    && ($seq_argument =~ /^(?:LaTeXML|latexml|\/)/)) {   # A reference to somewhere within our own docs.
    my $text;
    my $label = $seq_argument;
    if ($seq_argument =~ /^(.*)\|(.*)$/) {               # Separate the text to use, if given
      $text = $1; $label = $2; }
    if ($label =~ /^\/(.*)$/) {                          # reference to section within THIS pod?
      my $link = $1;
      $link = $1 if ($link =~ /^"(.*)"$/);               # Strip quotes
      $text = $link unless defined $text;
      $link =~ s/\s+/_/g;
      $label = $::PODDOC . '_' . $link; }
    return ($text ? "\\pod[$text]{$label}" : "\\pod{$label}"); }
  elsif ($seq_command eq 'X') {
    return "\\index{$seq_argument\@{\\ttfamily $seq_argument}}"; }
  else {
    return $self->SUPER::interior_sequence($seq_command, $seq_argument, $pod_seq); } }

# Redefine to better sort indices.
# ALL packages start with LaTeXML:: !!!
sub _create_index {
  my $string  = $_[0]->SUPER::_create_index($_[1]);
  my $reftype = "command";
  my ($name, @rest) = split('!', $string);
  if ($name =~ /^LaTeXML/) {
    $reftype = "module";
    my @comp = split('::', $name);
    $name = $comp[-1]
      . (@comp > 1 ? '({\footnotesize ' . join('::', @comp[0 .. $#comp - 1]) . '::})' : ''); }
  return join('!', "$name\@{\\ttfamily $name}", $reftype, @rest); }

# Redefined to avoid unnecessary math.
sub _replace_special_chars_late {
  my ($self, $paragraph) = @_;
  $paragraph =~ s/<\s+/\\textless\\ /g;
  $paragraph =~ s/>\s+/\\textgreater\\ /g;
  $paragraph =~ s/\|\s+/\\textbar\\ /g;

  $paragraph =~ s/</\\textless /g;
  $paragraph =~ s/>/\\textgreater /g;
  $paragraph =~ s/\|/\\textbar /g;
  return $paragraph; }

#======================================================================
__END__

=head1 NAME

C<genpods> - convert LaTeXML POD documentation for manual.

=head1 SYNOPSIS

genpods [options]

 Options:
  --force        Force regeneration of LaTeX from POD documentation
                    (default: only if needed)
  --help            Shows this help.

=cut
