Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- # scalar variables
- my $defaultindent="\t"; # $defaultindent: Default value of indentation
- my $line=''; # $line: takes the $line of the file
- my $delimeters=0; # $delimeters: switch that governs if
- # we need to check for & or not
- my $matchedbraces=0; # $matchedbraces: counter to see if { }
- # are matched; it will be
- # positive if too many {
- # negative if too many }
- # 0 if matched
- my $commandname=''; # $commandname: either \parbox, \marginpar,
- # or anything else from %checkunmatched
- # array variables
- my @indent=(); # @indent: stores indentation
- my @lines=(); # @lines: stores the newly indented lines
- my @block=(); # @block: stores blocks that have & delimeters
- # hash lookup variables
- #
- # if you don't want to indent an environment
- # put it in this hash table
- my %noindent=("pccexample"=>1,
- "pccdefinition"=>1,
- "problem"=>1,
- "exercises"=>1,
- "pccsolution"=>1,
- "widepage"=>1,
- "comment"=>1,
- "document"=>1,
- );
- # if you have indent rules for particular environments
- # put them in here
- my %indentrules=("axis"=>" ");
- # environments that have tab delimeters
- my %lookforaligndelims=("tabular"=>1,
- "align"=>1,
- "align*"=>1,
- "cases"=>1,
- "aligned"=>1);
- # commands that might split {} across lines
- # such as \parbox, \marginpar, etc
- my %checkunmatched=("parbox"=>1,
- "marginpar"=>1);
- # loop through the lines in the INPUT file
- while(<>)
- {
- # remove all leading spaces and tabs
- s/^\ *//;
- s/^\t*//;
- # check to see if we have \end{something} or \]
- # and make sure we're not working with %\end{something}
- # which is commented
- if( ($_ =~ m/\\end{(.*?)}/ or $_=~ m/(\\\])/)
- and $_ !~ m/^%/)
- {
- # check to see if we need to turn off alignment
- # delimeters and output the current block
- if($lookforaligndelims{$1})
- {
- $delimeters=0;
- # print the current FORMATTED block
- @block = &format_block(@block);
- foreach $line (@block)
- {
- # add the indentation and add the
- # each line of the formatted block
- # to the output
- push(@lines,join("",@indent).$line);
- }
- # empty the @block, very important!
- @block=();
- }
- # DECREASE the indentation by 1 level
- if(!$noindent{$1})
- {
- pop(@indent);
- }
- }
- # check to see if we're at the end of a \parbox, \marginpar
- # or other split-across-lines command
- if($matchedbraces != 0)
- {
- # match { but don't match \{
- $matchedbraces++ while ($_ =~ /(?<!\\){/g);
- # match } but don't match \}
- $matchedbraces-- while ($_ =~ /(?<!\\)}/g);
- # if we've matched up the braces then
- # we can decrease the indent
- if($matchedbraces == 0)
- {
- # DECREASE the indentation by 1 level
- if(!$noindent{$commandname})
- {
- pop(@indent);
- }
- }
- }
- # delimeter alignment block
- if(!$delimeters)
- {
- # add current value of indentation to the current line
- # and output it
- $_ = join("",@indent).$_;
- push(@lines,$_);
- }
- else
- {
- # output to block
- push(@block,$_);
- }
- # check to see if we have \begin{something} or \[
- # and make sure we're not working with %\begin{something}
- # which is commented
- if( ($_ =~ m/\\begin{(.*?)}/ or $_=~ m/(^\\\[)/)
- and $_ !~ m/^%/)
- {
- # INCREASE the indentation unless the environment
- # is one that we don't want to indent
- if(!$noindent{$1})
- {
- if(scalar($indentrules{$1}))
- {
- # if there's a rule for indentation for this environment
- push(@indent, $indentrules{$1});
- }
- else
- {
- # default indentation
- push(@indent, $defaultindent);
- }
- }
- # check to see if we need to look for alignment
- # delimeters
- if($lookforaligndelims{$1})
- {
- $delimeters=1;
- }
- }
- # check to see if we have \parbox, \marginpar, or
- # something similar that might split {} across lines,
- # specified in %checkunmatched hash table
- if ($_ =~ m/^\\(.*?)(\[|{)/)
- {
- if(scalar($checkunmatched{$1}))
- {
- # store the command name, because $1
- # will not exist after the next match
- $commandname = $1;
- # match { but don't match \{
- $matchedbraces++ while ($_ =~ /(?<!\\){/g);
- # match } but don't match \}
- $matchedbraces-- while ($_ =~ /(?<!\\)}/g);
- # set the indentation
- if($matchedbraces != 0)
- {
- if(!$noindent{$commandname})
- {
- if(scalar($indentrules{$commandname}))
- {
- # if there's a rule for indentation for this environment
- push(@indent, $indentrules{$commandname});
- }
- else
- {
- # default indentation
- push(@indent, $defaultindent);
- }
- }
- }
- }
- }
- }
- # output the formatted lines!
- print @lines;
- sub format_block{
- # SUBROUTINE
- # INPUT: @block array containing unformatted block
- # from, for example, align, or tabular
- # OUTPUT: @formattedblock array containing FORMATTED block
- # @block is the input
- my @block=@_;
- # local array variables
- my @formattedblock;
- my @tmprow=();
- my @tmpblock=();
- my @maxmstringsize=();
- # local scalar variables
- my $alignrowcounter=-1;
- my $aligncolcounter=-1;
- my $tmpstring='';
- my $row='';
- my $column='';
- my $maxmcolstrlength='';
- my $i='';
- my $j='';
- my $fmtstring='';
- my $myline='';
- # local hash table
- my %stringsize=();
- # loop through the lines in the @block
- foreach $row (@block)
- {
- # increment row counter
- $alignrowcounter++;
- # separate the row at each &
- @tmprow = split("&",$row);
- if(scalar(@tmprow)>1)
- {
- # reset column counter
- $aligncolcounter=-1;
- # loop through each column element
- # removing leading and trailing space
- foreach $column (@tmprow)
- {
- # increment column counter
- $aligncolcounter++;
- # remove leading and trailing space from element
- $column =~ s/^\s+//;
- $column =~ s/\s+$//;
- # assign string size to the array
- $stringsize{$alignrowcounter.$aligncolcounter}=length($column);
- # put the row back together
- if ($aligncolcounter ==0)
- {
- $tmpstring = $column;
- }
- else
- {
- $tmpstring .= "&".$column;
- }
- }
- push(@tmpblock,$tmpstring);
- }
- else
- {
- # if there are no & then use the
- # NOFORMATTING token
- # remove leading space
- s/^\s+//;
- push(@tmpblock,$row."NOFORMATTING");
- }
- }
- # calculate the maximum string size of each column
- for($j=0;$j<=$aligncolcounter;$j++)
- {
- $maxmcolstrlength=0;
- for($i=0; $i<=$alignrowcounter;$i++)
- {
- # make sure the stringsize is defined
- if(defined $stringsize{$i.$j})
- {
- if ($stringsize{$i.$j}>$maxmcolstrlength)
- {
- $maxmcolstrlength = $stringsize{$i.$j};
- }
- }
- }
- push(@maxmstringsize,$maxmcolstrlength);
- }
- # README: printf( formatting, expression)
- #
- # formatting has the form %-50s & %-20s & %-19s
- # (the numbers have been made up for example)
- # the - symbols mean that each column should be left-aligned
- # the numbers represent how wide each column is
- # the s represents string
- # the & needs to be inserted
- # join up the maximum string lengths using "s %-"
- $fmtstring = join("s & %-",@maxmstringsize);
- # add an s to the end, and a newline
- $fmtstring .= "s \n";
- # add %- to the beginning
- $fmtstring = "%-".$fmtstring;
- # process the @tmpblock of aligned material
- foreach $myline (@tmpblock)
- {
- if($myline =~ m/NOFORMATTING/)
- {
- $myline =~ s/NOFORMATTING//;
- $tmpstring=$myline;
- }
- else
- {
- $tmpstring = sprintf($fmtstring,split("&",$myline));
- }
- push(@formattedblock,$tmpstring);
- }
- # return the formatted block
- @formattedblock;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement