Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine


by DamnDirtyApe (Curate)
on Jul 29, 2002 at 05:44 UTC ( #185891=sourcecode: print w/replies, xml ) Need Help??
Category: Text Processing
Author/Contact Info DamnDirtyApe <>
Description: This program generates a skeleton LaTeX file from a simple text file. This allows a large document to be `prototyped', with the LaTeX tags later generated automatically. See the POD for a more detailed explanation.
#! /usr/bin/perl

use strict ;
use warnings ;
use Getopt::Long ;
use Pod::Usage ;

=head1 NAME

genlatex - Generate a LaTeX skeleton file from a plaintext outline.


genlatex [OPTIONS...] [-f] FILE

=head1 OPTIONS

=over 4

=item B<FILE, -f FILE, --file=FILE>

Specify the input file to use.

=item B<-o FILE, --out=FILE>

Specify the output file.

=item B<-c CLASS, --class=CLASS>

Specify the documentclass for the LaTeX file.  Options are 'article',
'report' and 'book'.  Default is 'article'.

=item B<-i NUM, --indent=NUM>

Specify the indent used to denote a change in document level in the
input file.  Default is 4.

=item B<-m, --maketitle>

Add a title to the LaTeX file.

=item B<-t TITLE, --title=TITLE>

if -m is set, specifies the title to use for the LaTeX file.
Default is `Untitled Document'.

=item B<-a AUTHOR, --author=AUTHOR>

if -m is set, specifies the author to use for the LaTeX file.
Default is the user's name from their finger info, or
`Unknown Author'.

=item B<-d DATE, --date=DATE>

if -m is set, specifies the date to use for the LaTeX file.
Default is localtime().

=item B<-p PACKAGE, --package=PACKAGE>

Specify a LaTeX package to be used in the LaTeX file.
Multiple packages can be specified.

=item B<--secnum, --nosecnum>

Specify whether or not to use section numbers in the LaTeX file.
if --nosecnum is specified, headings will be printed in the form
`\section*{..}' instead of the default `\section{..}'.

=item B<--part, --nopart>

If the documentclass is `book', this will change the highest level
of section from `chapter' to `part', and shift all the other levels
down.  The default is --nopart.

=item B<->

Read the input from STDIN, rather than an input file.

=item B<-h, --help>

Display this help message.

=item B<--man>

Display the complete documentation for this program.



While LaTeX is a great language for composing documents, it's not alwa
that easy to follow.  It can be quite easy to lose one's place in the
document structure when section headers may be spaced several screens

Enter I<genlatex>.  This program will allow you to create am outline o

your document in plaintext, then generate a LaTeX skeleton based on yo
outline.  Here's an example of an outline file:

    % My Report
        The Project
        The People
        The Tools
        The Meetings
        The Schedule
        The Timeline
        The Obstacles
        The Accomplishments
        The shortcomings

Note the indenting used to indicate the change in document level.
Any comments (lines beginning with %) at the beginning of the file
will show up at the beginning of the LaTeX document.  Any other commen
will show up where they appear in the outline.

Here is the LaTeX skeleton generated using the default parameters:

    % My Report
    \subsection{The Project}
    \subsection{The People}
    \subsection{The Tools}
    \subsection{The Meetings}
    \subsection{The Schedule}
    \subsection{The Timeline}
    \subsection{The Obstacles}
    \subsection{The Accomplishments}
    \subsection{The shortcomings}

=head1 TO-DO

=over 4

=item * Add support for passing options to \documentclass.

=item * Add support for \frontmatter, \backmatter, etc.

=item * Add support for arguments to packages.

=item * Add support for \tableofcontents, \listoffigures, etc.


=head1 AUTHOR

Doug Gorley C<< <> >>


my $in_file   = '' ;
my $out_file  = '' ;
my $doc_class = 'article' ;
my $indent    = 4 ;
my $maketitle = 0 ;
my $title     = 'Untitled Document' ;
my $author    = (getpwuid( $< ) )[6] || 'Unknown Author' ;
my $date      = scalar localtime ;
my @packages  = () ;
my $sec_nums  = 1 ;
my $use_part  = 0 ;
my $filter    = 0 ;
my $help      = 0 ;
my $man       = 0 ;

GetOptions( 'file|f=s'                => \$in_file,
            'out|o=s'                 => \$out_file,
            'class|c=s'               => \$doc_class,
            'indent|i=i'              => \$indent,
            'maketitle|m'             => \$maketitle,
            'title|t=s'               => \$title,
            'author|a=s'              => \$author,
            'date|d=s'                => \$date,
            'package|p=s'             => \@packages,
            'secnum!'                 => \$sec_nums,
            'part!'                   => \$use_part,
            ''                        => \$filter,
            'help|h'                  => \$help,
            'man'                     => \$man
          ) ;

$in_file ||= shift @ARGV ;

pod2usage( -verbose => 2 ) if $man ;
pod2usage( -verbose => 1 ) if $help ;

my @levels = (
         ) ;

unshift @levels, '\part' if ( $use_part && ( $doc_class eq 'book' ) ) 
shift @levels if $doc_class eq 'article' ;

my ( $fh_in, $fh_out ) ;

my @rows = () ;
if ( $in_file )
    open $fh_in, "$in_file" or die "Couldn't open $in_file: $!" ;
    @rows = <$fh_in> ;
    close $fh_in ;
elsif ( $filter )
    @rows = <STDIN> ;
    pod2usage( -verbose => 1 ) ;

if ( $out_file )
    open $fh_out, ">$out_file" or die "Couldn't open $out_file: $!" ;
    $fh_out = *STDOUT ;

my $header_flag = 0 ;
foreach ( @rows )
    chomp ;
    my $spaces = 0 ;
    if ( /^\s*$/ ) { next }

    # Print comments as-is.
    if ( /\s*%/ )
        print $fh_out "$_\n" ;
        next ;
        $header_flag++ ;

    # If this is the first non-comment line with content,
    # insert the preamble here.
    if ( $header_flag == 1 )
        print $fh_out "\n\\documentclass{$doc_class}\n" ;
        if ( @packages ) { print $fh_out "\n" }
        foreach ( @packages )
            print $fh_out "\\usepackage{$_}\n" ;
        if ( $maketitle )
            print $fh_out "\n\\title{$title}\n" ;
            print $fh_out "\\author{$author}\n" ;
            print $fh_out "\\date{$date}\n" ;
        print $fh_out "\n\\begin{document}\n\n" ;
        if ( $maketitle )
            print $fh_out "\\maketitle\n\n" ;
        $header_flag++ ;
    s/&/\\&/g ;
    s/\s*$// ;
    $spaces++ while s/^\s// ;
    print $fh_out $levels[$spaces/$indent] .
                  ( $sec_nums ? '' : '*' ) . "{$_}\n\n" ;
print $fh_out "\\end{document}\n\n" ;
close $fh_out ;

exit 0 ;
Replies are listed 'Best First'.
Re: genlatex
by bruno (Friar) on Aug 15, 2008 at 16:19 UTC
    Thanks for this neat little script! I donwloaded it and gave it a try, it works perfectly. I'll probably be using it in the near future!
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://185891]
[robby_dobby]: Corion: Oh, that's awesome! Your timing is perfect enough to see all hell break loose when you get back at work :P
[marto]: well, let me know in advance, I'll buy you a pint :)
[Corion]: robby_dobby: No, I'm returning in the second workweek of January. The main hectic parts are in the first days after the start of the new year
[robby_dobby]: marto: and, I'm not sure I'd be around here long enough for YAPC::EU
[marto]: Corion nice, what are you plans for Christmas?
[robby_dobby]: Corion: Nice, you just won't be around to deal with the mess - enjoy your vacation :-)
[robby_dobby]: marto: Sure, will do. Thanks!
[Corion]: marto: No great plans - I'll meet with my sister, my brother and my mother, but that's all :)
[Corion]: ... and also a visit to my godson+family of course :)

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2017-12-15 10:41 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (431 votes). Check out past polls.