POSTS

How I write Perl

Blog

When I write Perl, on my own, it looks like the following. This is Perl written in the “functional” style I advocate.

The code takes a listing of simple definitions:

    tree
    noun
    something organic with leaves

        _etc._

and turns it into LaTeX Beamer–class slide markup.

    
    \frame{
        \frametitle{tree       }
        \begin{itemize}
            \item tree
              \pause
        \item noun
        \pause
        \item
    something organic with leaves
        \end{itemize}
    }
    

When the Beamer LaTeX code is complied with pdflatex it produces a slide show.

You can see how something like this is handy for someone studying their GRE Vocabulary builder. Code after the jump.


#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use vars qw/$end_of_document $word $part $meaning/;

=head1 NAME

wordlst_to_beamer.pl - A plaintext to LaTeX-Beamer dialect converter

=head1 SYNOPSIS

wordlst_to_beamer definition_file
	
=head1 DESCRIPTION

This program takes a simply formatted text file that contains a series of "
blocks".  Each block is equivalent to one definition ( see SOURCE DEFINITION ).  
Each definition is then taken to be a "slide" in LaTeX Beamer style.

The purpose of doing so is to make each slide, effectively, a flash card.  
The word is printed, pause, part of speech given, pause, and then the 
definition given.
 
=head1 SOURCE DEFINITION

The text file that is given as an argument to the program should be a collection
of definitions separated by a double carriage return.

 tree
 noun
 a living thing with leaves

 happy
 adjective
 a feeling like you want to dance Charleston

I<etc.>

=head1 SUBROUTINES

Given the beautiful functional style in which this code was written and the
relative brevity of each routine, the code serves as sufficient documentation.

=cut

&main();

########################################################################
# Subroutines
########################################################################

sub main 
{
  &report_status(
    &produce_beamer_body(
      &test_contents_integrity (
        &load_contents_of_file(
          &test_validity_of_file ( 
            &get_file_to_operate_on(
              &load_environment()
              ))))));
}

########################################################################

sub report_status
{
	unless ( $_[0] )
	{
		print "Successfully ran.\n"
	}
	else
	{
		die "Error!\n"
	}
}

########################################################################

sub produce_beamer_body
{
	(my $latex_output_file = $_[0]->{file} ) =~ s/\..*$// ;

	open (LATEX, ">$latex_output_file.tex");
	
	# A technique to tell Perl not to paginate
	# ( i.e. re-print LATEX_TOP format ) again
	
	my $ltx = select LATEX;
	$= = 9990;
	select $ltx;
	
	my ($ds) = $_[0]->{data_structure};
	
	my @order = sort { $a  <=> $b } ( keys ( %$ds ) );
	for ( @order )
	{
		$word    = $ds->{$_}[0];
		$part    = $ds->{$_}[1];
		$meaning = $ds->{$_}[2];
		chomp($word, $part, $meaning);
		write (LATEX);
	}

	print LATEX $end_of_document;
	close LATEX;

  return $?
}

########################################################################

sub test_contents_integrity
{
	my $content_string         = join ('', @{+ $_[0]->{contents} } );
	my @clustered_contents_ray = split ( /\n\n/, $content_string);

	my $counter      = 0;
	my $cell_counter = 0;
	
	my %data_structure;
	
	for ( @clustered_contents_ray )
	{
		$counter++;
		my @temp_array = split ( /\n/, $_);
		
		if ( scalar ( @temp_array ) != 3 )
		{
			print "There was something amiss with entry:\n$_";
			exit 1;
		}
		else
		{
			$cell_counter +=3;
		}
		$data_structure{$counter} = \@temp_array;
	}
	
  if ( ($cell_counter % 3) == 0 )
	{
		$_[0]->{'data_structure'} = \%data_structure;
		return $_[0];
	}
	else
	{
		die "Data structure was anomalous."
	}
}

########################################################################

sub load_contents_of_file
{
	my $f = $_[0]->{file_fullpath};
	open ( IN, $f ) or die ("Could not open $f because [$!]");
	my @contents = <IN>;
	close IN;
	$_[0]->{contents} = \@contents;
	return $_[0];
}

#########################################################################

sub test_validity_of_file
{
	my $f = $_[0]->{file_fullpath};
	die ("Could not read file [$f][$!]") unless ( -r $f );
	return $_[0];
}

#########################################################################

sub get_file_to_operate_on
{
	my $filename = shift( @ARGV ) || '';
	my $default_filename='hit_parade_list_1.txt';
	
	my $payload = {};
	
	if ( $filename =~ /\w/)
	{
		chomp $filename;
		$payload->{file} = $filename
	}
	else
	{
		$payload->{file} = $default_filename
	}
	
	$payload->{file_fullpath} = 
	 	 join ( "/", (`pwd` =~ /(.*)\n/), 
		 $filename ? $filename : $default_filename);
		
	return $payload;
}

########################################################################

sub load_environment
{
	
format LATEX_TOP=
\documentclass{beamer}
\begin{document}
.

format LATEX =
\frame{
    \frametitle{@<<<<<<<<<<<<<<}
$word
    \begin{itemize}
  	\item @<<<<<<<<<<<<<<<
$word
	  \pause
    \item @<<<<<<<<<<<<
$part
    \pause
    \item
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$meaning
    \end{itemize}
}
.

$end_of_document = <<EOF

\\end{document};

EOF
;
	
}