Advertisement
cmhughes

indent.plx

Aug 25th, 2012
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 9.66 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. # scalar variables
  7. my $defaultindent="\t";     # $defaultindent: Default value of indentation
  8. my $line='';                # $line: takes the $line of the file
  9. my $delimeters=0;           # $delimeters: switch that governs if
  10.                             #              we need to check for & or not
  11. my $matchedbraces=0;        # $matchedbraces: counter to see if { }
  12.                             #               are matched; it will be
  13.                             #               positive if too many {
  14.                             #               negative if too many }
  15.                             #               0 if matched
  16. my $commandname='';         # $commandname: either \parbox, \marginpar,
  17.                             #               or anything else from %checkunmatched
  18.  
  19. # array variables
  20. my @indent=();              # @indent: stores indentation
  21. my @lines=();               # @lines: stores the newly indented lines
  22. my @block=();               # @block: stores blocks that have & delimeters
  23.  
  24. # hash lookup variables
  25. #
  26. # if you don't want to indent an environment
  27. # put it in this hash table
  28. my %noindent=("pccexample"=>1,
  29.                   "pccdefinition"=>1,
  30.                   "problem"=>1,
  31.                   "exercises"=>1,
  32.                   "pccsolution"=>1,
  33.                   "widepage"=>1,
  34.                   "comment"=>1,
  35.                   "document"=>1,
  36.                   );
  37.  
  38. # if you have indent rules for particular environments
  39. # put them in here
  40. my %indentrules=("axis"=>"   ");
  41.  
  42. # environments that have tab delimeters
  43. my %lookforaligndelims=("tabular"=>1,
  44.                         "align"=>1,
  45.                         "align*"=>1,
  46.                         "cases"=>1,
  47.                         "aligned"=>1);
  48.  
  49. # commands that might split {} across lines
  50. # such as \parbox, \marginpar, etc
  51. my %checkunmatched=("parbox"=>1,
  52.                     "marginpar"=>1);
  53.  
  54. # loop through the lines in the INPUT file
  55. while(<>)
  56. {
  57.     # remove all leading spaces and tabs
  58.     s/^\ *//;
  59.     s/^\t*//;
  60.  
  61.     # check to see if we have \end{something} or \]
  62.     # and make sure we're not working with %\end{something}
  63.     # which is commented
  64.     if( ($_ =~ m/\\end{(.*?)}/ or $_=~ m/(\\\])/)
  65.          and $_ !~ m/^%/)
  66.     {
  67.  
  68.        # check to see if we need to turn off alignment
  69.        # delimeters and output the current block
  70.        if($lookforaligndelims{$1})
  71.        {
  72.            $delimeters=0;
  73.  
  74.            # print the current FORMATTED block
  75.            @block = &format_block(@block);
  76.            foreach $line (@block)
  77.            {
  78.                 # add the indentation and add the
  79.                 # each line of the formatted block
  80.                 # to the output
  81.                 push(@lines,join("",@indent).$line);
  82.            }
  83.            # empty the @block, very important!
  84.            @block=();
  85.        }
  86.  
  87.        # DECREASE the indentation by 1 level
  88.        if(!$noindent{$1})
  89.        {
  90.             pop(@indent);
  91.         }
  92.     }
  93.  
  94.     # check to see if we're at the end of a \parbox, \marginpar
  95.     # or other split-across-lines command
  96.     if($matchedbraces != 0)
  97.     {
  98.        # match { but don't match \{
  99.        $matchedbraces++ while ($_ =~ /(?<!\\){/g);
  100.        # match } but don't match \}
  101.        $matchedbraces-- while ($_ =~ /(?<!\\)}/g);
  102.  
  103.        # if we've matched up the braces then
  104.        # we can decrease the indent
  105.        if($matchedbraces == 0)
  106.        {
  107.             # DECREASE the indentation by 1 level
  108.             if(!$noindent{$commandname})
  109.             {
  110.                  pop(@indent);
  111.              }
  112.        }
  113.      }
  114.  
  115.     # delimeter alignment block
  116.     if(!$delimeters)
  117.     {
  118.         # add current value of indentation to the current line
  119.         # and output it
  120.         $_ = join("",@indent).$_;
  121.         push(@lines,$_);
  122.     }
  123.     else
  124.     {
  125.         # output to block
  126.         push(@block,$_);
  127.     }
  128.  
  129.     # check to see if we have \begin{something} or \[
  130.     # and make sure we're not working with %\begin{something}
  131.     # which is commented
  132.     if( ($_ =~ m/\\begin{(.*?)}/ or $_=~ m/(^\\\[)/)
  133.         and $_ !~ m/^%/)
  134.     {
  135.        # INCREASE the indentation unless the environment
  136.        # is one that we don't want to indent
  137.        if(!$noindent{$1})
  138.        {
  139.          if(scalar($indentrules{$1}))
  140.          {
  141.             # if there's a rule for indentation for this environment
  142.             push(@indent, $indentrules{$1});
  143.           }
  144.           else
  145.           {
  146.             # default indentation
  147.             push(@indent, $defaultindent);
  148.           }
  149.        }
  150.  
  151.        # check to see if we need to look for alignment
  152.        # delimeters
  153.        if($lookforaligndelims{$1})
  154.        {
  155.            $delimeters=1;
  156.        }
  157.     }
  158.  
  159.     # check to see if we have \parbox, \marginpar, or
  160.     # something similar that might split {} across lines,
  161.     # specified in %checkunmatched hash table
  162.     if ($_ =~ m/^\\(.*?)(\[|{)/)
  163.     {
  164.         if(scalar($checkunmatched{$1}))
  165.         {
  166.             # store the command name, because $1
  167.             # will not exist after the next match
  168.             $commandname = $1;
  169.  
  170.             # match { but don't match \{
  171.             $matchedbraces++ while ($_ =~ /(?<!\\){/g);
  172.             # match } but don't match \}
  173.             $matchedbraces-- while ($_ =~ /(?<!\\)}/g);
  174.  
  175.             # set the indentation
  176.             if($matchedbraces != 0)
  177.             {
  178.                 if(!$noindent{$commandname})
  179.                 {
  180.                   if(scalar($indentrules{$commandname}))
  181.                   {
  182.                      # if there's a rule for indentation for this environment
  183.                      push(@indent, $indentrules{$commandname});
  184.                    }
  185.                    else
  186.                    {
  187.                      # default indentation
  188.                      push(@indent, $defaultindent);
  189.                    }
  190.                 }
  191.             }
  192.         }
  193.     }
  194. }
  195.  
  196. # output the formatted lines!
  197. print @lines;
  198.  
  199.  
  200. sub format_block{
  201.     # SUBROUTINE
  202.     #   INPUT: @block               array containing unformatted block
  203.     #                               from, for example, align, or tabular
  204.     #   OUTPUT: @formattedblock     array containing FORMATTED block
  205.  
  206.     # @block is the input
  207.     my @block=@_;
  208.  
  209.     # local array variables
  210.     my @formattedblock;
  211.     my @tmprow=();
  212.     my @tmpblock=();
  213.     my @maxmstringsize=();
  214.  
  215.     # local scalar variables
  216.     my $alignrowcounter=-1;
  217.     my $aligncolcounter=-1;
  218.     my $tmpstring='';
  219.     my $row='';
  220.     my $column='';
  221.     my $maxmcolstrlength='';
  222.     my $i='';
  223.     my $j='';
  224.     my $fmtstring='';
  225.     my $myline='';
  226.  
  227.     # local hash table
  228.     my %stringsize=();
  229.    
  230.     # loop through the lines in the @block
  231.     foreach $row (@block)
  232.     {
  233.         # increment row counter
  234.         $alignrowcounter++;
  235.  
  236.         # separate the row at each &
  237.         @tmprow = split("&",$row);
  238.    
  239.         if(scalar(@tmprow)>1)
  240.         {
  241.             # reset column counter
  242.             $aligncolcounter=-1;
  243.  
  244.             # loop through each column element
  245.             # removing leading and trailing space
  246.             foreach $column (@tmprow)
  247.             {
  248.                # increment column counter
  249.                $aligncolcounter++;
  250.    
  251.                # remove leading and trailing space from element
  252.                $column =~ s/^\s+//;
  253.                $column =~ s/\s+$//;
  254.    
  255.                # assign string size to the array
  256.                $stringsize{$alignrowcounter.$aligncolcounter}=length($column);
  257.    
  258.                # put the row back together
  259.                if ($aligncolcounter ==0)
  260.                {
  261.                  $tmpstring = $column;
  262.                }
  263.                else
  264.                {
  265.                  $tmpstring .= "&".$column;
  266.                }
  267.             }
  268.             push(@tmpblock,$tmpstring);
  269.         }
  270.         else
  271.         {
  272.                # if there are no & then use the
  273.                # NOFORMATTING token
  274.                # remove leading space
  275.                s/^\s+//;
  276.                push(@tmpblock,$row."NOFORMATTING");
  277.         }
  278.     }
  279.  
  280.     # calculate the maximum string size of each column
  281.     for($j=0;$j<=$aligncolcounter;$j++)
  282.     {
  283.         $maxmcolstrlength=0;
  284.         for($i=0; $i<=$alignrowcounter;$i++)
  285.         {
  286.             # make sure the stringsize is defined
  287.             if(defined $stringsize{$i.$j})
  288.             {
  289.                 if ($stringsize{$i.$j}>$maxmcolstrlength)
  290.                 {
  291.                     $maxmcolstrlength = $stringsize{$i.$j};
  292.                 }
  293.             }
  294.         }
  295.         push(@maxmstringsize,$maxmcolstrlength);
  296.     }
  297.  
  298.     # README: printf( formatting, expression)
  299.     #
  300.     #   formatting has the form %-50s & %-20s & %-19s
  301.     #   (the numbers have been made up for example)
  302.     #       the - symbols mean that each column should be left-aligned
  303.     #       the numbers represent how wide each column is
  304.     #       the s represents string
  305.     #       the & needs to be inserted
  306.    
  307.     # join up the maximum string lengths using "s %-"
  308.     $fmtstring = join("s & %-",@maxmstringsize);
  309.    
  310.     # add an s to the end, and a newline
  311.     $fmtstring .= "s \n";
  312.    
  313.     # add %- to the beginning
  314.     $fmtstring = "%-".$fmtstring;
  315.    
  316.     # process the @tmpblock of aligned material
  317.     foreach $myline (@tmpblock)
  318.     {
  319.         if($myline =~ m/NOFORMATTING/)
  320.         {
  321.             $myline =~ s/NOFORMATTING//;
  322.             $tmpstring=$myline;
  323.         }
  324.         else
  325.         {
  326.             $tmpstring = sprintf($fmtstring,split("&",$myline));
  327.         }
  328.         push(@formattedblock,$tmpstring);
  329.     }
  330.  
  331.     # return the formatted block
  332.     @formattedblock;
  333. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement